armrdi.c 33 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247
  1. /* armrdi.c -- ARMulator RDI interface: 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. #include <string.h>
  14. #include <ctype.h>
  15. #include "armdefs.h"
  16. #include "armemu.h"
  17. #include "armos.h"
  18. #include "dbg_cp.h"
  19. #include "dbg_conf.h"
  20. #include "dbg_rdi.h"
  21. #include "dbg_hif.h"
  22. #include "communicate.h"
  23. /***************************************************************************\
  24. * Declarations *
  25. \***************************************************************************/
  26. #define Watch_AnyRead (RDIWatch_ByteRead+RDIWatch_HalfRead+RDIWatch_WordRead)
  27. #define Watch_AnyWrite (RDIWatch_ByteWrite+RDIWatch_HalfWrite+RDIWatch_WordWrite)
  28. static unsigned FPRegsAddr; /* last known address of FPE regs */
  29. #define FPESTART 0x2000L
  30. #define FPEEND 0x8000L
  31. #define IGNORE(d) (d = d)
  32. #ifdef RDI_VERBOSE
  33. #define TracePrint(s) \
  34. if (rdi_log & 1) ARMul_DebugPrint s
  35. #else
  36. #define TracePrint(s)
  37. #endif
  38. static ARMul_State *state = NULL;
  39. static unsigned BreaksSet; /* The number of breakpoints set */
  40. static int rdi_log = 0; /* debugging ? */
  41. #define LOWEST_RDI_LEVEL 0
  42. #define HIGHEST_RDI_LEVEL 1
  43. static int MYrdi_level = LOWEST_RDI_LEVEL;
  44. typedef struct BreakNode BreakNode;
  45. typedef struct WatchNode WatchNode;
  46. struct BreakNode
  47. { /* A breakpoint list node */
  48. BreakNode *next;
  49. ARMword address; /* The address of this breakpoint */
  50. unsigned type; /* The type of comparison */
  51. ARMword bound; /* The other address for a range */
  52. ARMword inst;
  53. };
  54. struct WatchNode
  55. { /* A watchpoint list node */
  56. WatchNode *next;
  57. ARMword address; /* The address of this watchpoint */
  58. unsigned type; /* The type of comparison */
  59. unsigned datatype; /* The type of access to watch for */
  60. ARMword bound; /* The other address for a range */
  61. };
  62. BreakNode *BreakList = NULL;
  63. WatchNode *WatchList = NULL;
  64. void
  65. ARMul_DebugPrint_i (const Dbg_HostosInterface * hostif, const char *format,
  66. ...)
  67. {
  68. va_list ap;
  69. va_start (ap, format);
  70. hostif->dbgprint (hostif->dbgarg, format, ap);
  71. va_end (ap);
  72. }
  73. void
  74. ARMul_DebugPrint (ARMul_State * state, const char *format, ...)
  75. {
  76. va_list ap;
  77. va_start (ap, format);
  78. if (!(rdi_log & 8))
  79. state->hostif->dbgprint (state->hostif->dbgarg, format, ap);
  80. va_end (ap);
  81. }
  82. #define CONSOLE_PRINT_MAX_LEN 128
  83. void
  84. ARMul_ConsolePrint (ARMul_State * state, const char *format, ...)
  85. {
  86. va_list ap;
  87. int ch;
  88. char *str, buf[CONSOLE_PRINT_MAX_LEN];
  89. int i, j;
  90. ARMword junk;
  91. va_start (ap, format);
  92. vsprintf (buf, format, ap);
  93. for (i = 0; buf[i]; i++); /* The string is i chars long */
  94. str = buf;
  95. while (i >= 32)
  96. {
  97. MYwrite_char (kidmum[1], RDP_OSOp);
  98. MYwrite_word (kidmum[1], SWI_Write0);
  99. MYwrite_char (kidmum[1], OS_SendString);
  100. MYwrite_char (kidmum[1], 32); /* Send string 32bytes at a time */
  101. for (j = 0; j < 32; j++, str++)
  102. MYwrite_char (kidmum[1], *str);
  103. wait_for_osreply (&junk);
  104. i -= 32;
  105. }
  106. if (i > 0)
  107. {
  108. MYwrite_char (kidmum[1], RDP_OSOp);
  109. MYwrite_word (kidmum[1], SWI_Write0);
  110. MYwrite_char (kidmum[1], OS_SendString);
  111. MYwrite_char (kidmum[1], (unsigned char) i); /* Send remainder of string */
  112. for (j = 0; j < i; j++, str++)
  113. MYwrite_char (kidmum[1], *str);
  114. wait_for_osreply (&junk);
  115. }
  116. va_end (ap);
  117. return;
  118. /* str = buf; */
  119. /* while ((ch=*str++) != 0) */
  120. /* state->hostif->writec(state->hostif->hostosarg, ch); */
  121. }
  122. void
  123. ARMul_DebugPause (ARMul_State * state)
  124. {
  125. if (!(rdi_log & 8))
  126. state->hostif->dbgpause (state->hostif->dbgarg);
  127. }
  128. /***************************************************************************\
  129. * RDI_open *
  130. \***************************************************************************/
  131. static void
  132. InitFail (int exitcode, char const *which)
  133. {
  134. ARMul_ConsolePrint (state, "%s interface failed to initialise. Exiting\n",
  135. which);
  136. exit (exitcode);
  137. }
  138. static void
  139. RDIInit (unsigned type)
  140. {
  141. if (type == 0)
  142. { /* cold start */
  143. state->CallDebug = state->MemReadDebug = state->MemWriteDebug = 0;
  144. BreaksSet = 0;
  145. }
  146. }
  147. #define UNKNOWNPROC 0
  148. typedef struct
  149. {
  150. char name[16];
  151. unsigned properties;
  152. }
  153. Processor;
  154. Processor const p_arm2 = { "ARM2", ARM_Fix26_Prop };
  155. Processor const p_arm2as = { "ARM2AS", ARM_Fix26_Prop };
  156. Processor const p_arm61 = { "ARM61", ARM_Fix26_Prop };
  157. Processor const p_arm3 = { "ARM3", ARM_Fix26_Prop };
  158. Processor const p_arm6 = { "ARM6", ARM_Lock_Prop };
  159. Processor const p_arm60 = { "ARM60", ARM_Lock_Prop };
  160. Processor const p_arm600 = { "ARM600", ARM_Lock_Prop };
  161. Processor const p_arm610 = { "ARM610", ARM_Lock_Prop };
  162. Processor const p_arm620 = { "ARM620", ARM_Lock_Prop };
  163. Processor const p_unknown = { "", 0 };
  164. Processor const *const processors[] =
  165. {
  166. &p_arm6, /* default: must come first */
  167. &p_arm2,
  168. &p_arm2as,
  169. &p_arm61,
  170. &p_arm3,
  171. &p_arm60,
  172. &p_arm600,
  173. &p_arm610,
  174. &p_arm620,
  175. &p_unknown
  176. };
  177. typedef struct ProcessorConfig ProcessorConfig;
  178. struct ProcessorConfig
  179. {
  180. long id[2];
  181. ProcessorConfig const *self;
  182. long count;
  183. Processor const *const *processors;
  184. };
  185. ProcessorConfig const processorconfig = {
  186. {((((((long) 'x' << 8) | ' ') << 8) | 'c') << 8) | 'p',
  187. ((((((long) 'u' << 8) | 's') << 8) | ' ') << 8) | 'x'},
  188. &processorconfig,
  189. 16,
  190. processors
  191. };
  192. static int
  193. RDI_open (unsigned type, const Dbg_ConfigBlock * config,
  194. const Dbg_HostosInterface * hostif, struct Dbg_MCState *dbg_state)
  195. /* Initialise everything */
  196. {
  197. int virgin = (state == NULL);
  198. IGNORE (dbg_state);
  199. #ifdef RDI_VERBOSE
  200. if (rdi_log & 1)
  201. {
  202. if (virgin)
  203. ARMul_DebugPrint_i (hostif, "RDI_open: type = %d\n", type);
  204. else
  205. ARMul_DebugPrint (state, "RDI_open: type = %d\n", type);
  206. }
  207. #endif
  208. if (type & 1)
  209. { /* Warm start */
  210. ARMul_Reset (state);
  211. RDIInit (1);
  212. }
  213. else
  214. {
  215. if (virgin)
  216. {
  217. ARMul_EmulateInit ();
  218. state = ARMul_NewState ();
  219. state->hostif = hostif;
  220. {
  221. int req = config->processor;
  222. unsigned processor = processors[req]->val;
  223. ARMul_SelectProcessor (state, processor);
  224. ARMul_Reset (state);
  225. ARMul_ConsolePrint (state, "ARMulator V1.50, %s",
  226. processors[req]->name);
  227. }
  228. if (ARMul_MemoryInit (state, config->memorysize) == FALSE)
  229. InitFail (1, "Memory");
  230. if (config->bytesex != RDISex_DontCare)
  231. state->bigendSig = config->bytesex;
  232. if (ARMul_CoProInit (state) == FALSE)
  233. InitFail (2, "Co-Processor");
  234. if (ARMul_OSInit (state) == FALSE)
  235. InitFail (3, "Operating System");
  236. }
  237. ARMul_Reset (state);
  238. RDIInit (0);
  239. }
  240. if (type & 2)
  241. { /* Reset the comms link */
  242. /* what comms link ? */
  243. }
  244. if (virgin && (type & 1) == 0) /* Cold start */
  245. ARMul_ConsolePrint (state, ", %s endian.\n",
  246. state->bigendSig ? "Big" : "Little");
  247. if (config->bytesex == RDISex_DontCare)
  248. return (state->bigendSig ? RDIError_BigEndian : RDIError_LittleEndian);
  249. else
  250. return (RDIError_NoError);
  251. }
  252. /***************************************************************************\
  253. * RDI_close *
  254. \***************************************************************************/
  255. static int
  256. RDI_close (void)
  257. {
  258. TracePrint ((state, "RDI_close\n"));
  259. ARMul_OSExit (state);
  260. ARMul_CoProExit (state);
  261. ARMul_MemoryExit (state);
  262. return (RDIError_NoError);
  263. }
  264. /***************************************************************************\
  265. * RDI_read *
  266. \***************************************************************************/
  267. static int
  268. RDI_read (ARMword source, void *dest, unsigned *nbytes)
  269. {
  270. unsigned i;
  271. char *memptr = (char *) dest;
  272. TracePrint ((state, "RDI_read: source=%.8lx dest=%p nbytes=%.8x\n",
  273. source, dest, *nbytes));
  274. for (i = 0; i < *nbytes; i++)
  275. *memptr++ = (char) ARMul_ReadByte (state, source++);
  276. if (state->abortSig)
  277. {
  278. state->abortSig = LOW;
  279. return (RDIError_DataAbort);
  280. }
  281. return (RDIError_NoError);
  282. }
  283. /***************************************************************************\
  284. * RDI_write *
  285. \***************************************************************************/
  286. static int
  287. RDI_write (const void *source, ARMword dest, unsigned *nbytes)
  288. {
  289. unsigned i;
  290. char *memptr = (char *) source;
  291. TracePrint ((state, "RDI_write: source=%p dest=%.8lx nbytes=%.8x\n",
  292. source, dest, *nbytes));
  293. for (i = 0; i < *nbytes; i++)
  294. ARMul_WriteByte (state, (ARMword) dest++, (ARMword) * memptr++);
  295. if (state->abortSig)
  296. {
  297. state->abortSig = LOW;
  298. return (RDIError_DataAbort);
  299. }
  300. return (RDIError_NoError);
  301. }
  302. /***************************************************************************\
  303. * RDI_CPUread *
  304. \***************************************************************************/
  305. static int
  306. RDI_CPUread (unsigned mode, unsigned long mask, ARMword buffer[])
  307. {
  308. unsigned i, upto;
  309. if (mode == RDIMode_Curr)
  310. mode = (unsigned) (ARMul_GetCPSR (state) & MODEBITS);
  311. for (upto = 0, i = 0; i < 15; i++)
  312. if (mask & (1L << i))
  313. {
  314. buffer[upto++] = ARMul_GetReg (state, mode, i);
  315. }
  316. if (mask & RDIReg_R15)
  317. {
  318. buffer[upto++] = ARMul_GetR15 (state);
  319. }
  320. if (mask & RDIReg_PC)
  321. {
  322. buffer[upto++] = ARMul_GetPC (state);
  323. }
  324. if (mask & RDIReg_CPSR)
  325. buffer[upto++] = ARMul_GetCPSR (state);
  326. if (mask & RDIReg_SPSR)
  327. buffer[upto++] = ARMul_GetSPSR (state, mode);
  328. TracePrint ((state, "RDI_CPUread: mode=%.8x mask=%.8lx", mode, mask));
  329. #ifdef RDI_VERBOSE
  330. if (rdi_log & 1)
  331. {
  332. for (upto = 0, i = 0; i <= 20; i++)
  333. if (mask & (1L << i))
  334. {
  335. ARMul_DebugPrint (state, "%c%.8lx", upto % 4 == 0 ? '\n' : ' ',
  336. buffer[upto]);
  337. upto++;
  338. }
  339. ARMul_DebugPrint (state, "\n");
  340. }
  341. #endif
  342. return (RDIError_NoError);
  343. }
  344. /***************************************************************************\
  345. * RDI_CPUwrite *
  346. \***************************************************************************/
  347. static int
  348. RDI_CPUwrite (unsigned mode, unsigned long mask, ARMword const buffer[])
  349. {
  350. int i, upto;
  351. TracePrint ((state, "RDI_CPUwrite: mode=%.8x mask=%.8lx", mode, mask));
  352. #ifdef RDI_VERBOSE
  353. if (rdi_log & 1)
  354. {
  355. for (upto = 0, i = 0; i <= 20; i++)
  356. if (mask & (1L << i))
  357. {
  358. ARMul_DebugPrint (state, "%c%.8lx", upto % 4 == 0 ? '\n' : ' ',
  359. buffer[upto]);
  360. upto++;
  361. }
  362. ARMul_DebugPrint (state, "\n");
  363. }
  364. #endif
  365. if (mode == RDIMode_Curr)
  366. mode = (unsigned) (ARMul_GetCPSR (state) & MODEBITS);
  367. for (upto = 0, i = 0; i < 15; i++)
  368. if (mask & (1L << i))
  369. ARMul_SetReg (state, mode, i, buffer[upto++]);
  370. if (mask & RDIReg_R15)
  371. ARMul_SetR15 (state, buffer[upto++]);
  372. if (mask & RDIReg_PC)
  373. {
  374. ARMul_SetPC (state, buffer[upto++]);
  375. }
  376. if (mask & RDIReg_CPSR)
  377. ARMul_SetCPSR (state, buffer[upto++]);
  378. if (mask & RDIReg_SPSR)
  379. ARMul_SetSPSR (state, mode, buffer[upto++]);
  380. return (RDIError_NoError);
  381. }
  382. /***************************************************************************\
  383. * RDI_CPread *
  384. \***************************************************************************/
  385. static int
  386. RDI_CPread (unsigned CPnum, unsigned long mask, ARMword buffer[])
  387. {
  388. ARMword fpregsaddr, word[4];
  389. unsigned r, w;
  390. unsigned upto;
  391. if (CPnum != 1 && CPnum != 2)
  392. {
  393. unsigned char const *rmap = state->CPRegWords[CPnum];
  394. if (rmap == NULL)
  395. return (RDIError_UnknownCoPro);
  396. for (upto = 0, r = 0; r < rmap[-1]; r++)
  397. if (mask & (1L << r))
  398. {
  399. (void) state->CPRead[CPnum] (state, r, &buffer[upto]);
  400. upto += rmap[r];
  401. }
  402. TracePrint ((state, "RDI_CPread: CPnum=%d mask=%.8lx", CPnum, mask));
  403. #ifdef RDI_VERBOSE
  404. if (rdi_log & 1)
  405. {
  406. w = 0;
  407. for (upto = 0, r = 0; r < rmap[-1]; r++)
  408. if (mask & (1L << r))
  409. {
  410. int words = rmap[r];
  411. ARMul_DebugPrint (state, "%c%2d",
  412. (w >= 4 ? (w = 0, '\n') : ' '), r);
  413. while (--words >= 0)
  414. {
  415. ARMul_DebugPrint (state, " %.8lx", buffer[upto++]);
  416. w++;
  417. }
  418. }
  419. ARMul_DebugPrint (state, "\n");
  420. }
  421. #endif
  422. return RDIError_NoError;
  423. }
  424. #ifdef NOFPE
  425. return RDIError_UnknownCoPro;
  426. #else
  427. if (FPRegsAddr == 0)
  428. {
  429. fpregsaddr = ARMul_ReadWord (state, 4L);
  430. if ((fpregsaddr & 0xff800000) != 0xea000000) /* Must be a forward branch */
  431. return RDIError_UnknownCoPro;
  432. fpregsaddr = ((fpregsaddr & 0xffffff) << 2) + 8; /* address in __fp_decode - 4 */
  433. if ((fpregsaddr < FPESTART) || (fpregsaddr >= FPEEND))
  434. return RDIError_UnknownCoPro;
  435. fpregsaddr = ARMul_ReadWord (state, fpregsaddr); /* pointer to fp registers */
  436. FPRegsAddr = fpregsaddr;
  437. }
  438. else
  439. fpregsaddr = FPRegsAddr;
  440. if (fpregsaddr == 0)
  441. return RDIError_UnknownCoPro;
  442. for (upto = 0, r = 0; r < 8; r++)
  443. if (mask & (1L << r))
  444. {
  445. for (w = 0; w < 4; w++)
  446. word[w] =
  447. ARMul_ReadWord (state,
  448. fpregsaddr + (ARMword) r * 16 + (ARMword) w * 4);
  449. switch ((int) (word[3] >> 29))
  450. {
  451. case 0:
  452. case 2:
  453. case 4:
  454. case 6: /* its unpacked, convert to extended */
  455. buffer[upto++] = 2; /* mark as extended */
  456. buffer[upto++] = (word[3] & 0x7fff) | (word[0] & 0x80000000); /* exp and sign */
  457. buffer[upto++] = word[1]; /* mantissa 1 */
  458. buffer[upto++] = word[2]; /* mantissa 2 */
  459. break;
  460. case 1: /* packed single */
  461. buffer[upto++] = 0; /* mark as single */
  462. buffer[upto++] = word[0]; /* sign, exp and mantissa */
  463. buffer[upto++] = word[1]; /* padding */
  464. buffer[upto++] = word[2]; /* padding */
  465. break;
  466. case 3: /* packed double */
  467. buffer[upto++] = 1; /* mark as double */
  468. buffer[upto++] = word[0]; /* sign, exp and mantissa1 */
  469. buffer[upto++] = word[1]; /* mantissa 2 */
  470. buffer[upto++] = word[2]; /* padding */
  471. break;
  472. case 5: /* packed extended */
  473. buffer[upto++] = 2; /* mark as extended */
  474. buffer[upto++] = word[0]; /* sign and exp */
  475. buffer[upto++] = word[1]; /* mantissa 1 */
  476. buffer[upto++] = word[2]; /* mantissa 2 */
  477. break;
  478. case 7: /* packed decimal */
  479. buffer[upto++] = 3; /* mark as packed decimal */
  480. buffer[upto++] = word[0]; /* sign, exp and mantissa1 */
  481. buffer[upto++] = word[1]; /* mantissa 2 */
  482. buffer[upto++] = word[2]; /* mantissa 3 */
  483. break;
  484. }
  485. }
  486. if (mask & (1L << r))
  487. buffer[upto++] = ARMul_ReadWord (state, fpregsaddr + 128); /* fpsr */
  488. if (mask & (1L << (r + 1)))
  489. buffer[upto++] = 0; /* fpcr */
  490. TracePrint ((state, "RDI_CPread: CPnum=%d mask=%.8lx\n", CPnum, mask));
  491. #ifdef RDI_VERBOSE
  492. if (rdi_log & 1)
  493. {
  494. for (upto = 0, r = 0; r < 9; r++)
  495. if (mask & (1L << r))
  496. {
  497. if (r != 8)
  498. {
  499. ARMul_DebugPrint (state, "%08lx ", buffer[upto++]);
  500. ARMul_DebugPrint (state, "%08lx ", buffer[upto++]);
  501. ARMul_DebugPrint (state, "%08lx ", buffer[upto++]);
  502. }
  503. ARMul_DebugPrint (state, "%08lx\n", buffer[upto++]);
  504. }
  505. ARMul_DebugPrint (state, "\n");
  506. }
  507. #endif
  508. return (RDIError_NoError);
  509. #endif /* NOFPE */
  510. }
  511. /***************************************************************************\
  512. * RDI_CPwrite *
  513. \***************************************************************************/
  514. static int
  515. RDI_CPwrite (unsigned CPnum, unsigned long mask, ARMword const buffer[])
  516. {
  517. unsigned r;
  518. unsigned upto;
  519. ARMword fpregsaddr;
  520. if (CPnum != 1 && CPnum != 2)
  521. {
  522. unsigned char const *rmap = state->CPRegWords[CPnum];
  523. if (rmap == NULL)
  524. return (RDIError_UnknownCoPro);
  525. TracePrint ((state, "RDI_CPwrite: CPnum=%d mask=%.8lx", CPnum, mask));
  526. #ifdef RDI_VERBOSE
  527. if (rdi_log & 1)
  528. {
  529. int w = 0;
  530. for (upto = 0, r = 0; r < rmap[-1]; r++)
  531. if (mask & (1L << r))
  532. {
  533. int words = rmap[r];
  534. ARMul_DebugPrint (state, "%c%2d",
  535. (w >= 4 ? (w = 0, '\n') : ' '), r);
  536. while (--words >= 0)
  537. {
  538. ARMul_DebugPrint (state, " %.8lx", buffer[upto++]);
  539. w++;
  540. }
  541. }
  542. ARMul_DebugPrint (state, "\n");
  543. }
  544. #endif
  545. for (upto = 0, r = 0; r < rmap[-1]; r++)
  546. if (mask & (1L << r))
  547. {
  548. (void) state->CPWrite[CPnum] (state, r, &buffer[upto]);
  549. upto += rmap[r];
  550. }
  551. return RDIError_NoError;
  552. }
  553. #ifdef NOFPE
  554. return RDIError_UnknownCoPro;
  555. #else
  556. TracePrint ((state, "RDI_CPwrite: CPnum=%d mask=%.8lx", CPnum, mask));
  557. #ifdef RDI_VERBOSE
  558. if (rdi_log & 1)
  559. {
  560. for (upto = 0, r = 0; r < 9; r++)
  561. if (mask & (1L << r))
  562. {
  563. if (r != 8)
  564. {
  565. ARMul_DebugPrint (state, "%08lx ", buffer[upto++]);
  566. ARMul_DebugPrint (state, "%08lx ", buffer[upto++]);
  567. ARMul_DebugPrint (state, "%08lx ", buffer[upto++]);
  568. }
  569. ARMul_DebugPrint (state, "%08lx\n", buffer[upto++]);
  570. }
  571. ARMul_DebugPrint (state, "\n");
  572. }
  573. #endif
  574. if (FPRegsAddr == 0)
  575. {
  576. fpregsaddr = ARMul_ReadWord (state, 4L);
  577. if ((fpregsaddr & 0xff800000) != 0xea000000) /* Must be a forward branch */
  578. return RDIError_UnknownCoPro;
  579. fpregsaddr = ((fpregsaddr & 0xffffff) << 2) + 8; /* address in __fp_decode - 4 */
  580. if ((fpregsaddr < FPESTART) || (fpregsaddr >= FPEEND))
  581. return RDIError_UnknownCoPro;
  582. fpregsaddr = ARMul_ReadWord (state, fpregsaddr); /* pointer to fp registers */
  583. FPRegsAddr = fpregsaddr;
  584. }
  585. else
  586. fpregsaddr = FPRegsAddr;
  587. if (fpregsaddr == 0)
  588. return RDIError_UnknownCoPro;
  589. for (upto = 0, r = 0; r < 8; r++)
  590. if (mask & (1L << r))
  591. {
  592. ARMul_WriteWord (state, fpregsaddr + (ARMword) r * 16,
  593. buffer[upto + 1]);
  594. ARMul_WriteWord (state, fpregsaddr + (ARMword) r * 16 + 4,
  595. buffer[upto + 2]);
  596. ARMul_WriteWord (state, fpregsaddr + (ARMword) r * 16 + 8,
  597. buffer[upto + 3]);
  598. ARMul_WriteWord (state, fpregsaddr + (ARMword) r * 16 + 12,
  599. (buffer[upto] * 2 + 1) << 29); /* mark type */
  600. upto += 4;
  601. }
  602. if (mask & (1L << r))
  603. ARMul_WriteWord (state, fpregsaddr + 128, buffer[upto++]); /* fpsr */
  604. return (RDIError_NoError);
  605. #endif /* NOFPE */
  606. }
  607. static void
  608. deletebreaknode (BreakNode ** prevp)
  609. {
  610. BreakNode *p = *prevp;
  611. *prevp = p->next;
  612. ARMul_WriteWord (state, p->address, p->inst);
  613. free ((char *) p);
  614. BreaksSet--;
  615. state->CallDebug--;
  616. }
  617. static int
  618. removebreak (ARMword address, unsigned type)
  619. {
  620. BreakNode *p, **prevp = &BreakList;
  621. for (; (p = *prevp) != NULL; prevp = &p->next)
  622. if (p->address == address && p->type == type)
  623. {
  624. deletebreaknode (prevp);
  625. return TRUE;
  626. }
  627. return FALSE;
  628. }
  629. /* This routine installs a breakpoint into the breakpoint table */
  630. static BreakNode *
  631. installbreak (ARMword address, unsigned type, ARMword bound)
  632. {
  633. BreakNode *p = (BreakNode *) malloc (sizeof (BreakNode));
  634. p->next = BreakList;
  635. BreakList = p;
  636. p->address = address;
  637. p->type = type;
  638. p->bound = bound;
  639. p->inst = ARMul_ReadWord (state, address);
  640. ARMul_WriteWord (state, address, 0xee000000L);
  641. return p;
  642. }
  643. /***************************************************************************\
  644. * RDI_setbreak *
  645. \***************************************************************************/
  646. static int
  647. RDI_setbreak (ARMword address, unsigned type, ARMword bound,
  648. PointHandle * handle)
  649. {
  650. BreakNode *p;
  651. TracePrint ((state, "RDI_setbreak: address=%.8lx type=%d bound=%.8lx\n",
  652. address, type, bound));
  653. removebreak (address, type);
  654. p = installbreak (address, type, bound);
  655. BreaksSet++;
  656. state->CallDebug++;
  657. *handle = (PointHandle) p;
  658. TracePrint ((state, " returns %.8lx\n", *handle));
  659. return RDIError_NoError;
  660. }
  661. /***************************************************************************\
  662. * RDI_clearbreak *
  663. \***************************************************************************/
  664. static int
  665. RDI_clearbreak (PointHandle handle)
  666. {
  667. TracePrint ((state, "RDI_clearbreak: address=%.8lx\n", handle));
  668. {
  669. BreakNode *p, **prevp = &BreakList;
  670. for (; (p = *prevp) != NULL; prevp = &p->next)
  671. if (p == (BreakNode *) handle)
  672. break;
  673. if (p == NULL)
  674. return RDIError_NoSuchPoint;
  675. deletebreaknode (prevp);
  676. return RDIError_NoError;
  677. }
  678. }
  679. /***************************************************************************\
  680. * Internal functions for breakpoint table manipulation *
  681. \***************************************************************************/
  682. static void
  683. deletewatchnode (WatchNode ** prevp)
  684. {
  685. WatchNode *p = *prevp;
  686. if (p->datatype & Watch_AnyRead)
  687. state->MemReadDebug--;
  688. if (p->datatype & Watch_AnyWrite)
  689. state->MemWriteDebug--;
  690. *prevp = p->next;
  691. free ((char *) p);
  692. }
  693. int
  694. removewatch (ARMword address, unsigned type)
  695. {
  696. WatchNode *p, **prevp = &WatchList;
  697. for (; (p = *prevp) != NULL; prevp = &p->next)
  698. if (p->address == address && p->type == type)
  699. { /* found a match */
  700. deletewatchnode (prevp);
  701. return TRUE;
  702. }
  703. return FALSE; /* never found a match */
  704. }
  705. static WatchNode *
  706. installwatch (ARMword address, unsigned type, unsigned datatype,
  707. ARMword bound)
  708. {
  709. WatchNode *p = (WatchNode *) malloc (sizeof (WatchNode));
  710. p->next = WatchList;
  711. WatchList = p;
  712. p->address = address;
  713. p->type = type;
  714. p->datatype = datatype;
  715. p->bound = bound;
  716. return p;
  717. }
  718. /***************************************************************************\
  719. * RDI_setwatch *
  720. \***************************************************************************/
  721. static int
  722. RDI_setwatch (ARMword address, unsigned type, unsigned datatype,
  723. ARMword bound, PointHandle * handle)
  724. {
  725. WatchNode *p;
  726. TracePrint (
  727. (state,
  728. "RDI_setwatch: address=%.8lx type=%d datatype=%d bound=%.8lx",
  729. address, type, datatype, bound));
  730. if (!state->CanWatch)
  731. return RDIError_UnimplementedMessage;
  732. removewatch (address, type);
  733. p = installwatch (address, type, datatype, bound);
  734. if (datatype & Watch_AnyRead)
  735. state->MemReadDebug++;
  736. if (datatype & Watch_AnyWrite)
  737. state->MemWriteDebug++;
  738. *handle = (PointHandle) p;
  739. TracePrint ((state, " returns %.8lx\n", *handle));
  740. return RDIError_NoError;
  741. }
  742. /***************************************************************************\
  743. * RDI_clearwatch *
  744. \***************************************************************************/
  745. static int
  746. RDI_clearwatch (PointHandle handle)
  747. {
  748. TracePrint ((state, "RDI_clearwatch: address=%.8lx\n", handle));
  749. {
  750. WatchNode *p, **prevp = &WatchList;
  751. for (; (p = *prevp) != NULL; prevp = &p->next)
  752. if (p == (WatchNode *) handle)
  753. break;
  754. if (p == NULL)
  755. return RDIError_NoSuchPoint;
  756. deletewatchnode (prevp);
  757. return RDIError_NoError;
  758. }
  759. }
  760. /***************************************************************************\
  761. * RDI_execute *
  762. \***************************************************************************/
  763. static int
  764. RDI_execute (PointHandle * handle)
  765. {
  766. TracePrint ((state, "RDI_execute\n"));
  767. if (rdi_log & 4)
  768. {
  769. state->CallDebug++;
  770. state->Debug = TRUE;
  771. }
  772. state->EndCondition = RDIError_NoError;
  773. state->StopHandle = 0;
  774. ARMul_DoProg (state);
  775. *handle = state->StopHandle;
  776. state->Reg[15] -= 8; /* undo the pipeline */
  777. if (rdi_log & 4)
  778. {
  779. state->CallDebug--;
  780. state->Debug = FALSE;
  781. }
  782. return (state->EndCondition);
  783. }
  784. /***************************************************************************\
  785. * RDI_step *
  786. \***************************************************************************/
  787. static int
  788. RDI_step (unsigned ninstr, PointHandle * handle)
  789. {
  790. TracePrint ((state, "RDI_step\n"));
  791. if (ninstr != 1)
  792. return RDIError_UnimplementedMessage;
  793. if (rdi_log & 4)
  794. {
  795. state->CallDebug++;
  796. state->Debug = TRUE;
  797. }
  798. state->EndCondition = RDIError_NoError;
  799. state->StopHandle = 0;
  800. ARMul_DoInstr (state);
  801. *handle = state->StopHandle;
  802. state->Reg[15] -= 8; /* undo the pipeline */
  803. if (rdi_log & 4)
  804. {
  805. state->CallDebug--;
  806. state->Debug = FALSE;
  807. }
  808. return (state->EndCondition);
  809. }
  810. /***************************************************************************\
  811. * RDI_info *
  812. \***************************************************************************/
  813. static int
  814. RDI_info (unsigned type, ARMword * arg1, ARMword * arg2)
  815. {
  816. switch (type)
  817. {
  818. case RDIInfo_Target:
  819. TracePrint ((state, "RDI_Info_Target\n"));
  820. /* Emulator, speed 10**5 IPS */
  821. *arg1 = 5 | HIGHEST_RDI_LEVEL << 5 | LOWEST_RDI_LEVEL << 8;
  822. *arg2 = 1298224434;
  823. return RDIError_NoError;
  824. case RDIInfo_Points:
  825. {
  826. ARMword n = RDIPointCapability_Comparison | RDIPointCapability_Range |
  827. RDIPointCapability_Mask | RDIPointCapability_Status;
  828. TracePrint ((state, "RDI_Info_Points\n"));
  829. if (state->CanWatch)
  830. n |= (Watch_AnyRead + Watch_AnyWrite) << 2;
  831. *arg1 = n;
  832. return RDIError_NoError;
  833. }
  834. case RDIInfo_Step:
  835. TracePrint ((state, "RDI_Info_Step\n"));
  836. *arg1 = RDIStep_Single;
  837. return RDIError_NoError;
  838. case RDIInfo_MMU:
  839. TracePrint ((state, "RDI_Info_MMU\n"));
  840. *arg1 = 1313820229;
  841. return RDIError_NoError;
  842. case RDISignal_Stop:
  843. TracePrint ((state, "RDISignal_Stop\n"));
  844. state->CallDebug++;
  845. state->EndCondition = RDIError_UserInterrupt;
  846. return RDIError_NoError;
  847. case RDIVector_Catch:
  848. TracePrint ((state, "RDIVector_Catch %.8lx\n", *arg1));
  849. state->VectorCatch = (unsigned) *arg1;
  850. return RDIError_NoError;
  851. case RDISet_Cmdline:
  852. TracePrint ((state, "RDI_Set_Cmdline %s\n", (char *) arg1));
  853. state->CommandLine =
  854. (char *) malloc ((unsigned) strlen ((char *) arg1) + 1);
  855. (void) strcpy (state->CommandLine, (char *) arg1);
  856. return RDIError_NoError;
  857. case RDICycles:
  858. TracePrint ((state, "RDI_Info_Cycles\n"));
  859. arg1[0] = 0;
  860. arg1[1] = state->NumInstrs;
  861. arg1[2] = 0;
  862. arg1[3] = state->NumScycles;
  863. arg1[4] = 0;
  864. arg1[5] = state->NumNcycles;
  865. arg1[6] = 0;
  866. arg1[7] = state->NumIcycles;
  867. arg1[8] = 0;
  868. arg1[9] = state->NumCcycles;
  869. arg1[10] = 0;
  870. arg1[11] = state->NumFcycles;
  871. return RDIError_NoError;
  872. case RDIErrorP:
  873. *arg1 = ARMul_OSLastErrorP (state);
  874. TracePrint ((state, "RDI_ErrorP returns %ld\n", *arg1));
  875. return RDIError_NoError;
  876. case RDIInfo_DescribeCoPro:
  877. {
  878. int cpnum = *(int *) arg1;
  879. struct Dbg_CoProDesc *cpd = (struct Dbg_CoProDesc *) arg2;
  880. int i;
  881. unsigned char const *map = state->CPRegWords[cpnum];
  882. if (map == NULL)
  883. return RDIError_UnknownCoPro;
  884. for (i = 0; i < cpd->entries; i++)
  885. {
  886. unsigned r, w = cpd->regdesc[i].nbytes / sizeof (ARMword);
  887. for (r = cpd->regdesc[i].rmin; r <= cpd->regdesc[i].rmax; r++)
  888. if (map[r] != w)
  889. return RDIError_BadCoProState;
  890. }
  891. return RDIError_NoError;
  892. }
  893. case RDIInfo_RequestCoProDesc:
  894. {
  895. int cpnum = *(int *) arg1;
  896. struct Dbg_CoProDesc *cpd = (struct Dbg_CoProDesc *) arg2;
  897. int i = -1, lastw = -1, r;
  898. unsigned char const *map;
  899. if ((unsigned) cpnum >= 16)
  900. return RDIError_UnknownCoPro;
  901. map = state->CPRegWords[cpnum];
  902. if (map == NULL)
  903. return RDIError_UnknownCoPro;
  904. for (r = 0; r < map[-1]; r++)
  905. {
  906. int words = map[r];
  907. if (words == lastw)
  908. cpd->regdesc[i].rmax = r;
  909. else
  910. {
  911. if (++i >= cpd->entries)
  912. return RDIError_BufferFull;
  913. cpd->regdesc[i].rmax = cpd->regdesc[i].rmin = r;
  914. cpd->regdesc[i].nbytes = words * sizeof (ARMword);
  915. cpd->regdesc[i].access =
  916. Dbg_Access_Readable + Dbg_Access_Writable;
  917. }
  918. }
  919. cpd->entries = i + 1;
  920. return RDIError_NoError;
  921. }
  922. case RDIInfo_Log:
  923. *arg1 = (ARMword) rdi_log;
  924. return RDIError_NoError;
  925. case RDIInfo_SetLog:
  926. rdi_log = (int) *arg1;
  927. return RDIError_NoError;
  928. case RDIInfo_CoPro:
  929. return RDIError_NoError;
  930. case RDIPointStatus_Watch:
  931. {
  932. WatchNode *p, *handle = (WatchNode *) * arg1;
  933. for (p = WatchList; p != NULL; p = p->next)
  934. if (p == handle)
  935. {
  936. *arg1 = -1;
  937. *arg2 = 1;
  938. return RDIError_NoError;
  939. }
  940. return RDIError_NoSuchPoint;
  941. }
  942. case RDIPointStatus_Break:
  943. {
  944. BreakNode *p, *handle = (BreakNode *) * arg1;
  945. for (p = BreakList; p != NULL; p = p->next)
  946. if (p == handle)
  947. {
  948. *arg1 = -1;
  949. *arg2 = 1;
  950. return RDIError_NoError;
  951. }
  952. return RDIError_NoSuchPoint;
  953. }
  954. case RDISet_RDILevel:
  955. if (*arg1 < LOWEST_RDI_LEVEL || *arg1 > HIGHEST_RDI_LEVEL)
  956. return RDIError_IncompatibleRDILevels;
  957. MYrdi_level = *arg1;
  958. return RDIError_NoError;
  959. default:
  960. return RDIError_UnimplementedMessage;
  961. }
  962. }
  963. /***************************************************************************\
  964. * The emulator calls this routine at the beginning of every cycle when the *
  965. * CallDebug flag is set. The second parameter passed is the address of the *
  966. * currently executing instruction (i.e Program Counter - 8), the third *
  967. * parameter is the instruction being executed. *
  968. \***************************************************************************/
  969. ARMword
  970. ARMul_Debug (ARMul_State * state, ARMword pc, ARMword instr)
  971. {
  972. if (state->EndCondition == RDIError_UserInterrupt)
  973. {
  974. TracePrint ((state, "User interrupt at %.8lx\n", pc));
  975. state->CallDebug--;
  976. state->Emulate = STOP;
  977. }
  978. else
  979. {
  980. BreakNode *p = BreakList;
  981. for (; p != NULL; p = p->next)
  982. {
  983. switch (p->type)
  984. {
  985. case RDIPoint_EQ:
  986. if (pc == p->address)
  987. break;
  988. continue;
  989. case RDIPoint_GT:
  990. if (pc > p->address)
  991. break;
  992. continue;
  993. case RDIPoint_GE:
  994. if (pc >= p->address)
  995. break;
  996. continue;
  997. case RDIPoint_LT:
  998. if (pc < p->address)
  999. break;
  1000. continue;
  1001. case RDIPoint_LE:
  1002. if (pc <= p->address)
  1003. break;
  1004. continue;
  1005. case RDIPoint_IN:
  1006. if (p->address <= pc && pc < p->address + p->bound)
  1007. break;
  1008. continue;
  1009. case RDIPoint_OUT:
  1010. if (p->address > pc || pc >= p->address + p->bound)
  1011. break;
  1012. continue;
  1013. case RDIPoint_MASK:
  1014. if ((pc & p->bound) == p->address)
  1015. break;
  1016. continue;
  1017. }
  1018. /* found a match */
  1019. TracePrint ((state, "Breakpoint reached at %.8lx\n", pc));
  1020. state->EndCondition = RDIError_BreakpointReached;
  1021. state->Emulate = STOP;
  1022. state->StopHandle = (ARMword) p;
  1023. break;
  1024. }
  1025. }
  1026. return instr;
  1027. }
  1028. void
  1029. ARMul_CheckWatch (ARMul_State * state, ARMword addr, int access)
  1030. {
  1031. WatchNode *p;
  1032. for (p = WatchList; p != NULL; p = p->next)
  1033. if (p->datatype & access)
  1034. {
  1035. switch (p->type)
  1036. {
  1037. case RDIPoint_EQ:
  1038. if (addr == p->address)
  1039. break;
  1040. continue;
  1041. case RDIPoint_GT:
  1042. if (addr > p->address)
  1043. break;
  1044. continue;
  1045. case RDIPoint_GE:
  1046. if (addr >= p->address)
  1047. break;
  1048. continue;
  1049. case RDIPoint_LT:
  1050. if (addr < p->address)
  1051. break;
  1052. continue;
  1053. case RDIPoint_LE:
  1054. if (addr <= p->address)
  1055. break;
  1056. continue;
  1057. case RDIPoint_IN:
  1058. if (p->address <= addr && addr < p->address + p->bound)
  1059. break;
  1060. continue;
  1061. case RDIPoint_OUT:
  1062. if (p->address > addr || addr >= p->address + p->bound)
  1063. break;
  1064. continue;
  1065. case RDIPoint_MASK:
  1066. if ((addr & p->bound) == p->address)
  1067. break;
  1068. continue;
  1069. }
  1070. /* found a match */
  1071. TracePrint ((state, "Watchpoint at %.8lx accessed\n", addr));
  1072. state->EndCondition = RDIError_WatchpointAccessed;
  1073. state->Emulate = STOP;
  1074. state->StopHandle = (ARMword) p;
  1075. return;
  1076. }
  1077. }
  1078. static RDI_NameList const *
  1079. RDI_cpunames ()
  1080. {
  1081. return (RDI_NameList const *) &processorconfig.count;
  1082. }
  1083. const struct RDIProcVec armul_rdi = {
  1084. "ARMUL",
  1085. RDI_open,
  1086. RDI_close,
  1087. RDI_read,
  1088. RDI_write,
  1089. RDI_CPUread,
  1090. RDI_CPUwrite,
  1091. RDI_CPread,
  1092. RDI_CPwrite,
  1093. RDI_setbreak,
  1094. RDI_clearbreak,
  1095. RDI_setwatch,
  1096. RDI_clearwatch,
  1097. RDI_execute,
  1098. RDI_step,
  1099. RDI_info,
  1100. 0, /*pointinq */
  1101. 0, /*addconfig */
  1102. 0, /*loadconfigdata */
  1103. 0, /*selectconfig */
  1104. 0, /*drivernames */
  1105. RDI_cpunames
  1106. };