parent.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481
  1. /* parent.c -- ARMulator RDP comms code: ARM6 Instruction Emulator.
  2. Copyright (C) 1994 Advanced RISC Machines Ltd.
  3. This program is free software; you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation; either version 3 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; if not, see <http://www.gnu.org/licenses/>. */
  13. /*****************************************************************/
  14. /* The Parent process continues here... */
  15. /* It waits on the socket and passes on RDP messages down a pipe */
  16. /* to the ARMulator RDP to RDI interpreter. */
  17. /*****************************************************************/
  18. #include <stdio.h>
  19. #include <sys/types.h>
  20. #include <signal.h>
  21. #include "time.h"
  22. #include "armdefs.h"
  23. #include "dbg_rdi.h"
  24. #include "communicate.h"
  25. /* The socket to the debugger */
  26. extern int debugsock;
  27. /* The pipes between the two processes */
  28. extern int mumkid[2];
  29. extern int kidmum[2];
  30. /* A pipe for handling SWI return values that goes straight from the */
  31. /* parent to the ARMulator host interface, bypassing the child's RDP */
  32. /* to RDI interpreter */
  33. extern int DebuggerARMul[2];
  34. /* The maximum number of file descriptors */
  35. extern int nfds;
  36. /* The child process id. */
  37. extern pid_t child;
  38. void
  39. parent ()
  40. {
  41. int i, j, k;
  42. unsigned char message, CPnum, exreturn;
  43. ARMword mask, nbytes, messagetype;
  44. unsigned char c, d;
  45. ARMword x, y;
  46. int virgin = 1;
  47. struct fd_set readfds;
  48. #ifdef DEBUG
  49. fprintf (stderr, "parent ()...\n");
  50. #endif
  51. panic_error:
  52. if (!virgin)
  53. {
  54. #ifdef DEBUG
  55. fprintf (stderr, "Arghh! What is going on?\n");
  56. #endif
  57. kill (child, SIGHUP);
  58. MYwrite_char (debugsock, RDP_Reset);
  59. }
  60. virgin = 0;
  61. while (1)
  62. {
  63. /* Wait either for the ARMulator or the debugger */
  64. FD_ZERO (&readfds);
  65. FD_SET (kidmum[0], &readfds); /* Wait for messages from ARMulator */
  66. FD_SET (debugsock, &readfds); /* Wait for messages from debugger */
  67. #ifdef DEBUG
  68. fprintf (stderr, "Waiting for ARMulator or debugger... ");
  69. #endif
  70. while ((i = select (nfds, &readfds, (fd_set *) 0, (fd_set *) 0, 0)) < 0)
  71. {
  72. perror ("select");
  73. }
  74. #ifdef DEBUG
  75. fprintf (stderr, "(%d/2)", i);
  76. #endif
  77. if (FD_ISSET (debugsock, &readfds))
  78. {
  79. #ifdef DEBUG
  80. fprintf (stderr, "->debugger\n");
  81. #endif
  82. /* Inside this rather large if statement with simply pass on a complete
  83. message to the ARMulator. The reason we need to pass messages on one
  84. at a time is that we have to know whether the message is an OSOpReply
  85. or an info(stop), so that we can take different action in those
  86. cases. */
  87. if (MYread_char (debugsock, &message))
  88. goto panic_error;
  89. switch (message)
  90. {
  91. case RDP_Start:
  92. /* Open and/or Initialise */
  93. #ifdef DEBUG
  94. fprintf (stderr, "RDP Open\n");
  95. #endif
  96. if (MYread_char (debugsock, &c)) /* type */
  97. goto panic_error;
  98. if (MYread_word (debugsock, &x)) /* memory size */
  99. goto panic_error;
  100. MYwrite_char (mumkid[1], message);
  101. MYwrite_char (mumkid[1], c);
  102. MYwrite_word (mumkid[1], x);
  103. if (c & 0x2)
  104. {
  105. passon (debugsock, mumkid[1], 1); /* speed */
  106. }
  107. break;
  108. case RDP_End:
  109. /* Close and Finalise */
  110. #ifdef DEBUG
  111. fprintf (stderr, "RDP Close\n");
  112. #endif
  113. MYwrite_char (mumkid[1], message);
  114. break;
  115. case RDP_Read:
  116. /* Read Memory Address */
  117. #ifdef DEBUG
  118. fprintf (stderr, "RDP Read Memory\n");
  119. #endif
  120. MYwrite_char (mumkid[1], message);
  121. if (passon (debugsock, mumkid[1], 4))
  122. goto panic_error; /* address */
  123. if (MYread_word (debugsock, &nbytes))
  124. goto panic_error; /* nbytes */
  125. MYwrite_word (mumkid[1], nbytes);
  126. break;
  127. case RDP_Write:
  128. /* Write Memory Address */
  129. #ifdef DEBUG
  130. fprintf (stderr, "RDP Write Memory\n");
  131. #endif
  132. if (MYread_word (debugsock, &x))
  133. goto panic_error; /* address */
  134. if (MYread_word (debugsock, &y))
  135. goto panic_error; /* nbytes */
  136. MYwrite_char (mumkid[1], message);
  137. MYwrite_word (mumkid[1], x);
  138. MYwrite_word (mumkid[1], y);
  139. passon (debugsock, mumkid[1], y); /* actual data */
  140. break;
  141. case RDP_CPUread:
  142. /* Read CPU State */
  143. #ifdef DEBUG
  144. fprintf (stderr, "RDP Read CPU\n");
  145. #endif
  146. if (MYread_char (debugsock, &c))
  147. goto panic_error; /* mode */
  148. if (MYread_word (debugsock, &mask))
  149. goto panic_error; /* mask */
  150. MYwrite_char (mumkid[1], message);
  151. MYwrite_char (mumkid[1], c);
  152. MYwrite_word (mumkid[1], mask);
  153. break;
  154. case RDP_CPUwrite:
  155. /* Write CPU State */
  156. #ifdef DEBUG
  157. fprintf (stderr, "RDP Write CPU\n");
  158. #endif
  159. if (MYread_char (debugsock, &c))
  160. goto panic_error; /* mode */
  161. if (MYread_word (debugsock, &x))
  162. goto panic_error; /* mask */
  163. MYwrite_char (mumkid[1], message);
  164. MYwrite_char (mumkid[1], c);
  165. MYwrite_word (mumkid[1], x);
  166. for (k = 1, j = 0; k != 0x80000000; k *= 2, j++)
  167. if ((k & x) && passon (debugsock, mumkid[1], 4))
  168. goto panic_error;
  169. break;
  170. case RDP_CPread:
  171. /* Read Co-Processor State */
  172. #ifdef DEBUG
  173. fprintf (stderr, "RDP Read CP state\n");
  174. #endif
  175. if (MYread_char (debugsock, &CPnum))
  176. goto panic_error;
  177. if (MYread_word (debugsock, &mask))
  178. goto panic_error;
  179. MYwrite_char (mumkid[1], message);
  180. MYwrite_char (mumkid[1], CPnum);
  181. MYwrite_word (mumkid[1], mask);
  182. break;
  183. case RDP_CPwrite:
  184. /* Write Co-Processor State */
  185. #ifdef DEBUG
  186. fprintf (stderr, "RDP Write CP state\n");
  187. #endif
  188. if (MYread_char (debugsock, &CPnum))
  189. goto panic_error;
  190. if (MYread_word (debugsock, &mask))
  191. goto panic_error;
  192. MYwrite_char (mumkid[1], message);
  193. MYwrite_char (mumkid[1], c);
  194. MYwrite_char (mumkid[1], x);
  195. for (k = 1, j = 0; k != 0x80000000; k *= 2, j++)
  196. if (k & x)
  197. {
  198. if ((c == 1 || c == 2) && k <= 128)
  199. {
  200. /* FP register = 12 bytes + 4 bytes format */
  201. if (passon (debugsock, mumkid[1], 16))
  202. goto panic_error;
  203. }
  204. else
  205. {
  206. /* Normal register = 4 bytes */
  207. if (passon (debugsock, mumkid[1], 4))
  208. goto panic_error;
  209. }
  210. }
  211. break;
  212. case RDP_SetBreak:
  213. /* Set Breakpoint */
  214. #ifdef DEBUG
  215. fprintf (stderr, "RDP Set Breakpoint\n");
  216. #endif
  217. if (MYread_word (debugsock, &x))
  218. goto panic_error; /* address */
  219. if (MYread_char (debugsock, &c))
  220. goto panic_error; /* type */
  221. MYwrite_char (mumkid[1], message);
  222. MYwrite_word (mumkid[1], x);
  223. MYwrite_char (mumkid[1], c);
  224. if (((c & 0xf) >= 5) && passon (debugsock, mumkid[1], 4))
  225. goto panic_error; /* bound */
  226. break;
  227. case RDP_ClearBreak:
  228. /* Clear Breakpoint */
  229. #ifdef DEBUG
  230. fprintf (stderr, "RDP Clear Breakpoint\n");
  231. #endif
  232. MYwrite_char (mumkid[1], message);
  233. if (passon (debugsock, mumkid[1], 4))
  234. goto panic_error; /* point */
  235. break;
  236. case RDP_SetWatch:
  237. /* Set Watchpoint */
  238. #ifdef DEBUG
  239. fprintf (stderr, "RDP Set Watchpoint\n");
  240. #endif
  241. if (MYread_word (debugsock, &x))
  242. goto panic_error; /* address */
  243. if (MYread_char (debugsock, &c))
  244. goto panic_error; /* type */
  245. if (MYread_char (debugsock, &d))
  246. goto panic_error; /* datatype */
  247. MYwrite_char (mumkid[1], message);
  248. MYwrite_word (mumkid[1], x);
  249. MYwrite_char (mumkid[1], c);
  250. MYwrite_char (mumkid[1], d);
  251. if (((c & 0xf) >= 5) && passon (debugsock, mumkid[1], 4))
  252. goto panic_error; /* bound */
  253. break;
  254. case RDP_ClearWatch:
  255. /* Clear Watchpoint */
  256. #ifdef DEBUG
  257. fprintf (stderr, "RDP Clear Watchpoint\n");
  258. #endif
  259. MYwrite_char (mumkid[1], message);
  260. if (passon (debugsock, mumkid[1], 4))
  261. goto panic_error; /* point */
  262. break;
  263. case RDP_Execute:
  264. /* Excecute */
  265. #ifdef DEBUG
  266. fprintf (stderr, "RDP Execute\n");
  267. #endif
  268. /* LEAVE THIS ONE 'TIL LATER... */
  269. /* NEED TO WORK THINGS OUT */
  270. /* NO ASCYNCHROUS RUNNING */
  271. if (MYread_char (debugsock, &c))
  272. goto panic_error; /* return */
  273. /* Remember incase bit 7 is set and we have to send back a word */
  274. exreturn = c;
  275. MYwrite_char (mumkid[1], message);
  276. MYwrite_char (mumkid[1], c);
  277. break;
  278. case RDP_Step:
  279. /* Step */
  280. #ifdef DEBUG
  281. fprintf (stderr, "RDP Step\n");
  282. #endif
  283. if (MYread_char (debugsock, &c))
  284. goto panic_error; /* return */
  285. if (MYread_word (debugsock, &x))
  286. goto panic_error; /* ninstr */
  287. MYwrite_char (mumkid[1], message);
  288. MYwrite_char (mumkid[1], c);
  289. MYwrite_word (mumkid[1], x);
  290. break;
  291. case RDP_Info:
  292. /* Info */
  293. #ifdef DEBUG
  294. fprintf (stderr, "RDP Info\n");
  295. #endif
  296. /* INFO TARGET, SET RDI LEVEL */
  297. if (MYread_word (debugsock, &messagetype))
  298. goto panic_error; /* info */
  299. switch (messagetype)
  300. {
  301. case RDIInfo_Target:
  302. MYwrite_char (mumkid[1], message);
  303. MYwrite_word (mumkid[1], messagetype);
  304. break;
  305. case RDISet_RDILevel:
  306. MYwrite_char (mumkid[1], message);
  307. MYwrite_word (mumkid[1], messagetype);
  308. if (passon (debugsock, mumkid[1], 1))
  309. goto panic_error; /* argument */
  310. break;
  311. case RDISet_Cmdline:
  312. /* Got to pass on a string argument */
  313. MYwrite_char (mumkid[1], message);
  314. MYwrite_word (mumkid[1], messagetype);
  315. do
  316. {
  317. if (MYread_char (debugsock, &c))
  318. goto panic_error;
  319. MYwrite_char (mumkid[1], c);
  320. }
  321. while (c);
  322. break;
  323. case RDISignal_Stop:
  324. kill (child, SIGUSR1);
  325. MYwrite_char (debugsock, RDP_Return);
  326. MYwrite_char (debugsock, RDIError_UserInterrupt);
  327. break;
  328. case RDIVector_Catch:
  329. MYread_word (debugsock, &x);
  330. MYwrite_char (mumkid[1], message);
  331. MYwrite_word (mumkid[1], messagetype);
  332. MYwrite_word (mumkid[1], x);
  333. break;
  334. case RDIInfo_Step:
  335. MYwrite_char (mumkid[1], message);
  336. MYwrite_word (mumkid[1], messagetype);
  337. break;
  338. case RDIInfo_Points:
  339. MYwrite_char (mumkid[1], message);
  340. MYwrite_word (mumkid[1], messagetype);
  341. break;
  342. default:
  343. fprintf (stderr, "Unrecognized RDIInfo request %d\n",
  344. messagetype);
  345. goto panic_error;
  346. }
  347. break;
  348. case RDP_OSOpReply:
  349. /* OS Operation Reply */
  350. #ifdef DEBUG
  351. fprintf (stderr, "RDP OS Reply\n");
  352. #endif
  353. MYwrite_char (mumkid[1], message);
  354. if (MYread_char (debugsock, &message))
  355. goto panic_error;
  356. MYwrite_char (mumkid[1], message);
  357. switch (message)
  358. {
  359. case 0: /* return value i.e. nothing else. */
  360. break;
  361. case 1: /* returns a byte... */
  362. if (MYread_char (debugsock, &c))
  363. goto panic_error;
  364. MYwrite_char (mumkid[1], c);
  365. break;
  366. case 2: /* returns a word... */
  367. if (MYread_word (debugsock, &x))
  368. goto panic_error;
  369. MYwrite_word (mumkid[1], x);
  370. break;
  371. }
  372. break;
  373. case RDP_Reset:
  374. /* Reset */
  375. #ifdef DEBUG
  376. fprintf (stderr, "RDP Reset\n");
  377. #endif
  378. MYwrite_char (mumkid[1], message);
  379. break;
  380. default:
  381. /* Hmm.. bad RDP operation */
  382. fprintf (stderr, "RDP Bad RDP request (%d)\n", message);
  383. MYwrite_char (debugsock, RDP_Return);
  384. MYwrite_char (debugsock, RDIError_UnimplementedMessage);
  385. break;
  386. }
  387. }
  388. if (FD_ISSET (kidmum[0], &readfds))
  389. {
  390. #ifdef DEBUG
  391. fprintf (stderr, "->ARMulator\n");
  392. #endif
  393. /* Anything we get from the ARMulator has to go to the debugger... */
  394. /* It is that simple! */
  395. passon (kidmum[0], debugsock, 1);
  396. }
  397. }
  398. }