/CPU/SRCS/cadcdev/dcload/dcload-ip/target-src/dcload/syscalls.c

https://github.com/Kochise/dreamcast-docs · C · 382 lines · 254 code · 99 blank · 29 comment · 5 complexity · aae56c7fbb220dd8478ec3f0580aa140 MD5 · raw file

  1. /*
  2. * This file is part of the dcload Dreamcast ethernet loader
  3. *
  4. * Copyright (C) 2001 Andrew Kieschnick <andrewk@austin.rr.com>
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, write to the Free Software
  18. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19. *
  20. */
  21. #include <unistd.h>
  22. #include <sys/types.h>
  23. #include <sys/stat.h>
  24. #include <fcntl.h>
  25. #include <utime.h>
  26. #include <stdarg.h>
  27. #include <dirent.h>
  28. #include "syscalls.h"
  29. #include "packet.h"
  30. #include "net.h"
  31. #include "commands.h"
  32. #include "scif.h"
  33. #include "adapter.h"
  34. unsigned int syscall_retval;
  35. unsigned char* syscall_data;
  36. ether_header_t * ether = (ether_header_t *)pkt_buf;
  37. ip_header_t * ip = (ip_header_t *)(pkt_buf + ETHER_H_LEN);
  38. udp_header_t * udp = (udp_header_t *)(pkt_buf + ETHER_H_LEN + IP_H_LEN);
  39. /* send command, enable bb, bb_loop(), then return */
  40. int strlen(const char *s)
  41. {
  42. int c = 0;
  43. while (s[c] != 0)
  44. c++;
  45. return c;
  46. }
  47. void build_send_packet(int command_len)
  48. {
  49. unsigned char * command = pkt_buf + ETHER_H_LEN + IP_H_LEN + UDP_H_LEN;
  50. /*
  51. scif_puts("build_send_packet\n");
  52. scif_putchar(command[0]);
  53. scif_putchar(command[1]);
  54. scif_putchar(command[2]);
  55. scif_putchar(command[3]);
  56. scif_puts("\n");
  57. */
  58. make_ether(tool_mac, bb->mac, ether);
  59. make_ip(tool_ip, our_ip, UDP_H_LEN + command_len, 17, ip);
  60. make_udp(tool_port, 31313, command, command_len, ip, udp);
  61. bb->start();
  62. bb->tx(pkt_buf, ETHER_H_LEN + IP_H_LEN + UDP_H_LEN + command_len);
  63. }
  64. void dcexit(void)
  65. {
  66. command_t * command = (command_t *)(pkt_buf + ETHER_H_LEN + IP_H_LEN + UDP_H_LEN);
  67. memcpy(command->id, CMD_EXIT, 4);
  68. command->address = htonl(0);
  69. command->size = htonl(0);
  70. build_send_packet(COMMAND_LEN);
  71. bb->stop();
  72. }
  73. int read(int fd, void *buf, size_t count)
  74. {
  75. command_3int_t * command = (command_3int_t *)(pkt_buf + ETHER_H_LEN + IP_H_LEN + UDP_H_LEN);
  76. memcpy(command->id, CMD_READ, 4);
  77. command->value0 = htonl(fd);
  78. command->value1 = htonl(buf);
  79. command->value2 = htonl(count);
  80. build_send_packet(sizeof(command_3int_t));
  81. bb->loop();
  82. return syscall_retval;
  83. }
  84. int write(int fd, const void *buf, size_t count)
  85. {
  86. command_3int_t * command = (command_3int_t *)(pkt_buf + ETHER_H_LEN + IP_H_LEN + UDP_H_LEN);
  87. memcpy(command->id, CMD_WRITE, 4);
  88. command->value0 = htonl(fd);
  89. command->value1 = htonl(buf);
  90. command->value2 = htonl(count);
  91. build_send_packet(sizeof(command_3int_t));
  92. bb->loop();
  93. return syscall_retval;
  94. }
  95. int open(const char *pathname, int flags, ...)
  96. {
  97. va_list ap;
  98. command_2int_string_t * command = (command_2int_string_t *)(pkt_buf + ETHER_H_LEN + IP_H_LEN + UDP_H_LEN);
  99. int namelen = strlen(pathname);
  100. memcpy(command->id, CMD_OPEN, 4);
  101. va_start(ap, flags);
  102. command->value0 = htonl(flags);
  103. command->value1 = htonl(va_arg(ap, int));
  104. va_end(ap);
  105. memcpy(command->string, pathname, namelen+1);
  106. build_send_packet(sizeof(command_2int_string_t)+namelen);
  107. bb->loop();
  108. return syscall_retval;
  109. }
  110. int close(int fd)
  111. {
  112. command_int_t * command = (command_int_t *)(pkt_buf + ETHER_H_LEN + IP_H_LEN + UDP_H_LEN);
  113. memcpy(command->id, CMD_CLOSE, 4);
  114. command->value0 = htonl(fd);
  115. build_send_packet(sizeof(command_int_t));
  116. bb->loop();
  117. return syscall_retval;
  118. }
  119. int creat(const char *pathname, mode_t mode)
  120. {
  121. command_int_string_t * command = (command_int_string_t *)(pkt_buf + ETHER_H_LEN + IP_H_LEN + UDP_H_LEN);
  122. int namelen = strlen(pathname);
  123. memcpy(command->id, CMD_CREAT, 4);
  124. command->value0 = htonl(mode);
  125. memcpy(command->string, pathname, namelen+1);
  126. build_send_packet(sizeof(command_int_string_t)+namelen);
  127. bb->loop();
  128. return syscall_retval;
  129. }
  130. int link(const char *oldpath, const char *newpath)
  131. {
  132. command_string_t * command = (command_string_t *)(pkt_buf + ETHER_H_LEN + IP_H_LEN + UDP_H_LEN);
  133. int namelen1 = strlen(oldpath);
  134. int namelen2 = strlen(newpath);
  135. memcpy(command->id, CMD_LINK, 4);
  136. memcpy(command->string, oldpath, namelen1 + 1);
  137. memcpy(command->string + namelen1 + 1, newpath, namelen2 + 1);
  138. build_send_packet(sizeof(command_string_t)+namelen1+namelen2+1);
  139. bb->loop();
  140. return syscall_retval;
  141. }
  142. int unlink(const char *pathname)
  143. {
  144. command_string_t * command = (command_string_t *)(pkt_buf + ETHER_H_LEN + IP_H_LEN + UDP_H_LEN);
  145. int namelen = strlen(pathname);
  146. memcpy(command->id, CMD_UNLINK, 4);
  147. memcpy(command->string, pathname, namelen + 1);
  148. build_send_packet(sizeof(command_string_t)+namelen);
  149. bb->loop();
  150. return syscall_retval;
  151. }
  152. int chdir(const char *path)
  153. {
  154. command_string_t * command = (command_string_t *)(pkt_buf + ETHER_H_LEN + IP_H_LEN + UDP_H_LEN);
  155. int namelen = strlen(path);
  156. memcpy(command->id, CMD_CHDIR, 4);
  157. memcpy(command->string, path, namelen + 1);
  158. build_send_packet(sizeof(command_string_t)+namelen);
  159. bb->loop();
  160. return syscall_retval;
  161. }
  162. int chmod(const char *path, mode_t mode)
  163. {
  164. command_int_string_t * command = (command_int_string_t *)(pkt_buf + ETHER_H_LEN + IP_H_LEN + UDP_H_LEN);
  165. int namelen = strlen(path);
  166. memcpy(command->id, CMD_CHMOD, 4);
  167. command->value0 = htonl(mode);
  168. memcpy(command->string, path, namelen+1);
  169. build_send_packet(sizeof(command_int_string_t)+namelen);
  170. bb->loop();
  171. return syscall_retval;
  172. }
  173. off_t lseek(int fildes, off_t offset, int whence)
  174. {
  175. command_3int_t * command = (command_3int_t *)(pkt_buf + ETHER_H_LEN + IP_H_LEN + UDP_H_LEN);
  176. memcpy(command->id, CMD_LSEEK, 4);
  177. command->value0 = htonl(fildes);
  178. command->value1 = htonl(offset);
  179. command->value2 = htonl(whence);
  180. build_send_packet(sizeof(command_3int_t));
  181. bb->loop();
  182. return syscall_retval;
  183. }
  184. int fstat(int filedes, struct stat *buf)
  185. {
  186. command_3int_t * command = (command_3int_t *)(pkt_buf + ETHER_H_LEN + IP_H_LEN + UDP_H_LEN);
  187. memcpy(command->id, CMD_FSTAT, 4);
  188. command->value0 = htonl(filedes);
  189. command->value1 = htonl(buf);
  190. command->value2 = htonl(sizeof(struct stat));
  191. build_send_packet(sizeof(command_3int_t));
  192. bb->loop();
  193. return syscall_retval;
  194. }
  195. time_t time(time_t * t)
  196. {
  197. command_int_t * command = (command_int_t *)(pkt_buf + ETHER_H_LEN + IP_H_LEN + UDP_H_LEN);
  198. memcpy(command->id, CMD_TIME, 4);
  199. build_send_packet(sizeof(command_int_t));
  200. bb->loop();
  201. return syscall_retval;
  202. }
  203. int stat(const char *file_name, struct stat *buf)
  204. {
  205. command_2int_string_t * command = (command_2int_string_t *)(pkt_buf + ETHER_H_LEN + IP_H_LEN + UDP_H_LEN);
  206. int namelen = strlen(file_name);
  207. memcpy(command->id, CMD_STAT, 4);
  208. memcpy(command->string, file_name, namelen+1);
  209. command->value0 = htonl(buf);
  210. command->value1 = htonl(sizeof(struct stat));
  211. build_send_packet(sizeof(command_2int_string_t)+namelen);
  212. bb->loop();
  213. return syscall_retval;
  214. }
  215. int utime(const char *filename, struct utimbuf *buf)
  216. {
  217. command_3int_string_t * command = (command_3int_string_t *)(pkt_buf + ETHER_H_LEN + IP_H_LEN + UDP_H_LEN);
  218. int namelen = strlen(filename);
  219. memcpy(command->id, CMD_UTIME, 4);
  220. memcpy(command->string, filename, namelen+1);
  221. command->value0 = htonl(buf);
  222. if (!buf) {
  223. command->value1 = htonl(buf->actime);
  224. command->value2 = htonl(buf->modtime);
  225. }
  226. build_send_packet(sizeof(command_3int_string_t)+namelen);
  227. bb->loop();
  228. return syscall_retval;
  229. }
  230. DIR * opendir(const char *name)
  231. {
  232. command_string_t * command = (command_string_t *)(pkt_buf + ETHER_H_LEN + IP_H_LEN + UDP_H_LEN);
  233. int namelen = strlen(name);
  234. memcpy(command->id, CMD_OPENDIR, 4);
  235. memcpy(command->string, name, namelen+1);
  236. build_send_packet(sizeof(command_string_t)+namelen);
  237. bb->loop();
  238. return (DIR *)syscall_retval;
  239. }
  240. int closedir(DIR *dir)
  241. {
  242. command_int_t * command = (command_int_t *)(pkt_buf + ETHER_H_LEN + IP_H_LEN + UDP_H_LEN);
  243. memcpy(command->id, CMD_CLOSEDIR, 4);
  244. command->value0 = htonl(dir);
  245. build_send_packet(sizeof(command_int_t));
  246. bb->loop();
  247. return syscall_retval;
  248. }
  249. struct dirent our_dir;
  250. struct dirent *readdir(DIR *dir)
  251. {
  252. command_3int_t * command = (command_3int_t *)(pkt_buf + ETHER_H_LEN + IP_H_LEN + UDP_H_LEN);
  253. memcpy(command->id, CMD_READDIR, 4);
  254. command->value0 = htonl(dir);
  255. command->value1 = htonl(&our_dir);
  256. command->value2 = htonl(sizeof(struct dirent));
  257. build_send_packet(sizeof(command_3int_t));
  258. bb->loop();
  259. if (syscall_retval)
  260. return &our_dir;
  261. else
  262. return 0;
  263. }
  264. int gethostinfo(unsigned int *ip, unsigned int *port)
  265. {
  266. *ip = tool_ip;
  267. *port = tool_port;
  268. return our_ip;
  269. }
  270. size_t gdbpacket(const char *in_buf, unsigned int size_pack, char* out_buf)
  271. {
  272. size_t in_size = size_pack >> 16, out_size = size_pack & 0xffff;
  273. command_2int_string_t * command = (command_2int_string_t *)(pkt_buf + ETHER_H_LEN + IP_H_LEN + UDP_H_LEN);
  274. memcpy(command->id, CMD_GDBPACKET, 4);
  275. command->value0 = htonl(in_size);
  276. command->value1 = htonl(out_size);
  277. memcpy(command->string, in_buf, in_size);
  278. build_send_packet(sizeof(command_2int_string_t)-1 + in_size);
  279. bb->loop();
  280. if (syscall_retval <= out_size)
  281. memcpy(out_buf, syscall_data, syscall_retval);
  282. return syscall_retval;
  283. }