12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247 |
- #include <string.h>
- #include <ctype.h>
- #include "armdefs.h"
- #include "armemu.h"
- #include "armos.h"
- #include "dbg_cp.h"
- #include "dbg_conf.h"
- #include "dbg_rdi.h"
- #include "dbg_hif.h"
- #include "communicate.h"
- #define Watch_AnyRead (RDIWatch_ByteRead+RDIWatch_HalfRead+RDIWatch_WordRead)
- #define Watch_AnyWrite (RDIWatch_ByteWrite+RDIWatch_HalfWrite+RDIWatch_WordWrite)
- static unsigned FPRegsAddr;
- #define FPESTART 0x2000L
- #define FPEEND 0x8000L
- #define IGNORE(d) (d = d)
- #ifdef RDI_VERBOSE
- #define TracePrint(s) \
- if (rdi_log & 1) ARMul_DebugPrint s
- #else
- #define TracePrint(s)
- #endif
- static ARMul_State *state = NULL;
- static unsigned BreaksSet;
- static int rdi_log = 0;
- #define LOWEST_RDI_LEVEL 0
- #define HIGHEST_RDI_LEVEL 1
- static int MYrdi_level = LOWEST_RDI_LEVEL;
- typedef struct BreakNode BreakNode;
- typedef struct WatchNode WatchNode;
- struct BreakNode
- {
- BreakNode *next;
- ARMword address;
- unsigned type;
- ARMword bound;
- ARMword inst;
- };
- struct WatchNode
- {
- WatchNode *next;
- ARMword address;
- unsigned type;
- unsigned datatype;
- ARMword bound;
- };
- BreakNode *BreakList = NULL;
- WatchNode *WatchList = NULL;
- void
- ARMul_DebugPrint_i (const Dbg_HostosInterface * hostif, const char *format,
- ...)
- {
- va_list ap;
- va_start (ap, format);
- hostif->dbgprint (hostif->dbgarg, format, ap);
- va_end (ap);
- }
- void
- ARMul_DebugPrint (ARMul_State * state, const char *format, ...)
- {
- va_list ap;
- va_start (ap, format);
- if (!(rdi_log & 8))
- state->hostif->dbgprint (state->hostif->dbgarg, format, ap);
- va_end (ap);
- }
- #define CONSOLE_PRINT_MAX_LEN 128
- void
- ARMul_ConsolePrint (ARMul_State * state, const char *format, ...)
- {
- va_list ap;
- int ch;
- char *str, buf[CONSOLE_PRINT_MAX_LEN];
- int i, j;
- ARMword junk;
- va_start (ap, format);
- vsprintf (buf, format, ap);
- for (i = 0; buf[i]; i++);
- str = buf;
- while (i >= 32)
- {
- MYwrite_char (kidmum[1], RDP_OSOp);
- MYwrite_word (kidmum[1], SWI_Write0);
- MYwrite_char (kidmum[1], OS_SendString);
- MYwrite_char (kidmum[1], 32);
- for (j = 0; j < 32; j++, str++)
- MYwrite_char (kidmum[1], *str);
- wait_for_osreply (&junk);
- i -= 32;
- }
- if (i > 0)
- {
- MYwrite_char (kidmum[1], RDP_OSOp);
- MYwrite_word (kidmum[1], SWI_Write0);
- MYwrite_char (kidmum[1], OS_SendString);
- MYwrite_char (kidmum[1], (unsigned char) i);
- for (j = 0; j < i; j++, str++)
- MYwrite_char (kidmum[1], *str);
- wait_for_osreply (&junk);
- }
- va_end (ap);
- return;
- }
- void
- ARMul_DebugPause (ARMul_State * state)
- {
- if (!(rdi_log & 8))
- state->hostif->dbgpause (state->hostif->dbgarg);
- }
- static void
- InitFail (int exitcode, char const *which)
- {
- ARMul_ConsolePrint (state, "%s interface failed to initialise. Exiting\n",
- which);
- exit (exitcode);
- }
- static void
- RDIInit (unsigned type)
- {
- if (type == 0)
- {
- state->CallDebug = state->MemReadDebug = state->MemWriteDebug = 0;
- BreaksSet = 0;
- }
- }
- #define UNKNOWNPROC 0
- typedef struct
- {
- char name[16];
- unsigned properties;
- }
- Processor;
- Processor const p_arm2 = { "ARM2", ARM_Fix26_Prop };
- Processor const p_arm2as = { "ARM2AS", ARM_Fix26_Prop };
- Processor const p_arm61 = { "ARM61", ARM_Fix26_Prop };
- Processor const p_arm3 = { "ARM3", ARM_Fix26_Prop };
- Processor const p_arm6 = { "ARM6", ARM_Lock_Prop };
- Processor const p_arm60 = { "ARM60", ARM_Lock_Prop };
- Processor const p_arm600 = { "ARM600", ARM_Lock_Prop };
- Processor const p_arm610 = { "ARM610", ARM_Lock_Prop };
- Processor const p_arm620 = { "ARM620", ARM_Lock_Prop };
- Processor const p_unknown = { "", 0 };
- Processor const *const processors[] =
- {
- &p_arm6,
- &p_arm2,
- &p_arm2as,
- &p_arm61,
- &p_arm3,
- &p_arm60,
- &p_arm600,
- &p_arm610,
- &p_arm620,
- &p_unknown
- };
- typedef struct ProcessorConfig ProcessorConfig;
- struct ProcessorConfig
- {
- long id[2];
- ProcessorConfig const *self;
- long count;
- Processor const *const *processors;
- };
- ProcessorConfig const processorconfig = {
- {((((((long) 'x' << 8) | ' ') << 8) | 'c') << 8) | 'p',
- ((((((long) 'u' << 8) | 's') << 8) | ' ') << 8) | 'x'},
- &processorconfig,
- 16,
- processors
- };
- static int
- RDI_open (unsigned type, const Dbg_ConfigBlock * config,
- const Dbg_HostosInterface * hostif, struct Dbg_MCState *dbg_state)
- {
- int virgin = (state == NULL);
- IGNORE (dbg_state);
- #ifdef RDI_VERBOSE
- if (rdi_log & 1)
- {
- if (virgin)
- ARMul_DebugPrint_i (hostif, "RDI_open: type = %d\n", type);
- else
- ARMul_DebugPrint (state, "RDI_open: type = %d\n", type);
- }
- #endif
- if (type & 1)
- {
- ARMul_Reset (state);
- RDIInit (1);
- }
- else
- {
- if (virgin)
- {
- ARMul_EmulateInit ();
- state = ARMul_NewState ();
- state->hostif = hostif;
- {
- int req = config->processor;
- unsigned processor = processors[req]->val;
- ARMul_SelectProcessor (state, processor);
- ARMul_Reset (state);
- ARMul_ConsolePrint (state, "ARMulator V1.50, %s",
- processors[req]->name);
- }
- if (ARMul_MemoryInit (state, config->memorysize) == FALSE)
- InitFail (1, "Memory");
- if (config->bytesex != RDISex_DontCare)
- state->bigendSig = config->bytesex;
- if (ARMul_CoProInit (state) == FALSE)
- InitFail (2, "Co-Processor");
- if (ARMul_OSInit (state) == FALSE)
- InitFail (3, "Operating System");
- }
- ARMul_Reset (state);
- RDIInit (0);
- }
- if (type & 2)
- {
-
- }
- if (virgin && (type & 1) == 0)
- ARMul_ConsolePrint (state, ", %s endian.\n",
- state->bigendSig ? "Big" : "Little");
- if (config->bytesex == RDISex_DontCare)
- return (state->bigendSig ? RDIError_BigEndian : RDIError_LittleEndian);
- else
- return (RDIError_NoError);
- }
- static int
- RDI_close (void)
- {
- TracePrint ((state, "RDI_close\n"));
- ARMul_OSExit (state);
- ARMul_CoProExit (state);
- ARMul_MemoryExit (state);
- return (RDIError_NoError);
- }
- static int
- RDI_read (ARMword source, void *dest, unsigned *nbytes)
- {
- unsigned i;
- char *memptr = (char *) dest;
- TracePrint ((state, "RDI_read: source=%.8lx dest=%p nbytes=%.8x\n",
- source, dest, *nbytes));
- for (i = 0; i < *nbytes; i++)
- *memptr++ = (char) ARMul_ReadByte (state, source++);
- if (state->abortSig)
- {
- state->abortSig = LOW;
- return (RDIError_DataAbort);
- }
- return (RDIError_NoError);
- }
- static int
- RDI_write (const void *source, ARMword dest, unsigned *nbytes)
- {
- unsigned i;
- char *memptr = (char *) source;
- TracePrint ((state, "RDI_write: source=%p dest=%.8lx nbytes=%.8x\n",
- source, dest, *nbytes));
- for (i = 0; i < *nbytes; i++)
- ARMul_WriteByte (state, (ARMword) dest++, (ARMword) * memptr++);
- if (state->abortSig)
- {
- state->abortSig = LOW;
- return (RDIError_DataAbort);
- }
- return (RDIError_NoError);
- }
- static int
- RDI_CPUread (unsigned mode, unsigned long mask, ARMword buffer[])
- {
- unsigned i, upto;
- if (mode == RDIMode_Curr)
- mode = (unsigned) (ARMul_GetCPSR (state) & MODEBITS);
- for (upto = 0, i = 0; i < 15; i++)
- if (mask & (1L << i))
- {
- buffer[upto++] = ARMul_GetReg (state, mode, i);
- }
- if (mask & RDIReg_R15)
- {
- buffer[upto++] = ARMul_GetR15 (state);
- }
- if (mask & RDIReg_PC)
- {
- buffer[upto++] = ARMul_GetPC (state);
- }
- if (mask & RDIReg_CPSR)
- buffer[upto++] = ARMul_GetCPSR (state);
- if (mask & RDIReg_SPSR)
- buffer[upto++] = ARMul_GetSPSR (state, mode);
- TracePrint ((state, "RDI_CPUread: mode=%.8x mask=%.8lx", mode, mask));
- #ifdef RDI_VERBOSE
- if (rdi_log & 1)
- {
- for (upto = 0, i = 0; i <= 20; i++)
- if (mask & (1L << i))
- {
- ARMul_DebugPrint (state, "%c%.8lx", upto % 4 == 0 ? '\n' : ' ',
- buffer[upto]);
- upto++;
- }
- ARMul_DebugPrint (state, "\n");
- }
- #endif
- return (RDIError_NoError);
- }
- static int
- RDI_CPUwrite (unsigned mode, unsigned long mask, ARMword const buffer[])
- {
- int i, upto;
- TracePrint ((state, "RDI_CPUwrite: mode=%.8x mask=%.8lx", mode, mask));
- #ifdef RDI_VERBOSE
- if (rdi_log & 1)
- {
- for (upto = 0, i = 0; i <= 20; i++)
- if (mask & (1L << i))
- {
- ARMul_DebugPrint (state, "%c%.8lx", upto % 4 == 0 ? '\n' : ' ',
- buffer[upto]);
- upto++;
- }
- ARMul_DebugPrint (state, "\n");
- }
- #endif
- if (mode == RDIMode_Curr)
- mode = (unsigned) (ARMul_GetCPSR (state) & MODEBITS);
- for (upto = 0, i = 0; i < 15; i++)
- if (mask & (1L << i))
- ARMul_SetReg (state, mode, i, buffer[upto++]);
- if (mask & RDIReg_R15)
- ARMul_SetR15 (state, buffer[upto++]);
- if (mask & RDIReg_PC)
- {
- ARMul_SetPC (state, buffer[upto++]);
- }
- if (mask & RDIReg_CPSR)
- ARMul_SetCPSR (state, buffer[upto++]);
- if (mask & RDIReg_SPSR)
- ARMul_SetSPSR (state, mode, buffer[upto++]);
- return (RDIError_NoError);
- }
- static int
- RDI_CPread (unsigned CPnum, unsigned long mask, ARMword buffer[])
- {
- ARMword fpregsaddr, word[4];
- unsigned r, w;
- unsigned upto;
- if (CPnum != 1 && CPnum != 2)
- {
- unsigned char const *rmap = state->CPRegWords[CPnum];
- if (rmap == NULL)
- return (RDIError_UnknownCoPro);
- for (upto = 0, r = 0; r < rmap[-1]; r++)
- if (mask & (1L << r))
- {
- (void) state->CPRead[CPnum] (state, r, &buffer[upto]);
- upto += rmap[r];
- }
- TracePrint ((state, "RDI_CPread: CPnum=%d mask=%.8lx", CPnum, mask));
- #ifdef RDI_VERBOSE
- if (rdi_log & 1)
- {
- w = 0;
- for (upto = 0, r = 0; r < rmap[-1]; r++)
- if (mask & (1L << r))
- {
- int words = rmap[r];
- ARMul_DebugPrint (state, "%c%2d",
- (w >= 4 ? (w = 0, '\n') : ' '), r);
- while (--words >= 0)
- {
- ARMul_DebugPrint (state, " %.8lx", buffer[upto++]);
- w++;
- }
- }
- ARMul_DebugPrint (state, "\n");
- }
- #endif
- return RDIError_NoError;
- }
- #ifdef NOFPE
- return RDIError_UnknownCoPro;
- #else
- if (FPRegsAddr == 0)
- {
- fpregsaddr = ARMul_ReadWord (state, 4L);
- if ((fpregsaddr & 0xff800000) != 0xea000000)
- return RDIError_UnknownCoPro;
- fpregsaddr = ((fpregsaddr & 0xffffff) << 2) + 8;
- if ((fpregsaddr < FPESTART) || (fpregsaddr >= FPEEND))
- return RDIError_UnknownCoPro;
- fpregsaddr = ARMul_ReadWord (state, fpregsaddr);
- FPRegsAddr = fpregsaddr;
- }
- else
- fpregsaddr = FPRegsAddr;
- if (fpregsaddr == 0)
- return RDIError_UnknownCoPro;
- for (upto = 0, r = 0; r < 8; r++)
- if (mask & (1L << r))
- {
- for (w = 0; w < 4; w++)
- word[w] =
- ARMul_ReadWord (state,
- fpregsaddr + (ARMword) r * 16 + (ARMword) w * 4);
- switch ((int) (word[3] >> 29))
- {
- case 0:
- case 2:
- case 4:
- case 6:
- buffer[upto++] = 2;
- buffer[upto++] = (word[3] & 0x7fff) | (word[0] & 0x80000000);
- buffer[upto++] = word[1];
- buffer[upto++] = word[2];
- break;
- case 1:
- buffer[upto++] = 0;
- buffer[upto++] = word[0];
- buffer[upto++] = word[1];
- buffer[upto++] = word[2];
- break;
- case 3:
- buffer[upto++] = 1;
- buffer[upto++] = word[0];
- buffer[upto++] = word[1];
- buffer[upto++] = word[2];
- break;
- case 5:
- buffer[upto++] = 2;
- buffer[upto++] = word[0];
- buffer[upto++] = word[1];
- buffer[upto++] = word[2];
- break;
- case 7:
- buffer[upto++] = 3;
- buffer[upto++] = word[0];
- buffer[upto++] = word[1];
- buffer[upto++] = word[2];
- break;
- }
- }
- if (mask & (1L << r))
- buffer[upto++] = ARMul_ReadWord (state, fpregsaddr + 128);
- if (mask & (1L << (r + 1)))
- buffer[upto++] = 0;
- TracePrint ((state, "RDI_CPread: CPnum=%d mask=%.8lx\n", CPnum, mask));
- #ifdef RDI_VERBOSE
- if (rdi_log & 1)
- {
- for (upto = 0, r = 0; r < 9; r++)
- if (mask & (1L << r))
- {
- if (r != 8)
- {
- ARMul_DebugPrint (state, "%08lx ", buffer[upto++]);
- ARMul_DebugPrint (state, "%08lx ", buffer[upto++]);
- ARMul_DebugPrint (state, "%08lx ", buffer[upto++]);
- }
- ARMul_DebugPrint (state, "%08lx\n", buffer[upto++]);
- }
- ARMul_DebugPrint (state, "\n");
- }
- #endif
- return (RDIError_NoError);
- #endif
- }
- static int
- RDI_CPwrite (unsigned CPnum, unsigned long mask, ARMword const buffer[])
- {
- unsigned r;
- unsigned upto;
- ARMword fpregsaddr;
- if (CPnum != 1 && CPnum != 2)
- {
- unsigned char const *rmap = state->CPRegWords[CPnum];
- if (rmap == NULL)
- return (RDIError_UnknownCoPro);
- TracePrint ((state, "RDI_CPwrite: CPnum=%d mask=%.8lx", CPnum, mask));
- #ifdef RDI_VERBOSE
- if (rdi_log & 1)
- {
- int w = 0;
- for (upto = 0, r = 0; r < rmap[-1]; r++)
- if (mask & (1L << r))
- {
- int words = rmap[r];
- ARMul_DebugPrint (state, "%c%2d",
- (w >= 4 ? (w = 0, '\n') : ' '), r);
- while (--words >= 0)
- {
- ARMul_DebugPrint (state, " %.8lx", buffer[upto++]);
- w++;
- }
- }
- ARMul_DebugPrint (state, "\n");
- }
- #endif
- for (upto = 0, r = 0; r < rmap[-1]; r++)
- if (mask & (1L << r))
- {
- (void) state->CPWrite[CPnum] (state, r, &buffer[upto]);
- upto += rmap[r];
- }
- return RDIError_NoError;
- }
- #ifdef NOFPE
- return RDIError_UnknownCoPro;
- #else
- TracePrint ((state, "RDI_CPwrite: CPnum=%d mask=%.8lx", CPnum, mask));
- #ifdef RDI_VERBOSE
- if (rdi_log & 1)
- {
- for (upto = 0, r = 0; r < 9; r++)
- if (mask & (1L << r))
- {
- if (r != 8)
- {
- ARMul_DebugPrint (state, "%08lx ", buffer[upto++]);
- ARMul_DebugPrint (state, "%08lx ", buffer[upto++]);
- ARMul_DebugPrint (state, "%08lx ", buffer[upto++]);
- }
- ARMul_DebugPrint (state, "%08lx\n", buffer[upto++]);
- }
- ARMul_DebugPrint (state, "\n");
- }
- #endif
- if (FPRegsAddr == 0)
- {
- fpregsaddr = ARMul_ReadWord (state, 4L);
- if ((fpregsaddr & 0xff800000) != 0xea000000)
- return RDIError_UnknownCoPro;
- fpregsaddr = ((fpregsaddr & 0xffffff) << 2) + 8;
- if ((fpregsaddr < FPESTART) || (fpregsaddr >= FPEEND))
- return RDIError_UnknownCoPro;
- fpregsaddr = ARMul_ReadWord (state, fpregsaddr);
- FPRegsAddr = fpregsaddr;
- }
- else
- fpregsaddr = FPRegsAddr;
- if (fpregsaddr == 0)
- return RDIError_UnknownCoPro;
- for (upto = 0, r = 0; r < 8; r++)
- if (mask & (1L << r))
- {
- ARMul_WriteWord (state, fpregsaddr + (ARMword) r * 16,
- buffer[upto + 1]);
- ARMul_WriteWord (state, fpregsaddr + (ARMword) r * 16 + 4,
- buffer[upto + 2]);
- ARMul_WriteWord (state, fpregsaddr + (ARMword) r * 16 + 8,
- buffer[upto + 3]);
- ARMul_WriteWord (state, fpregsaddr + (ARMword) r * 16 + 12,
- (buffer[upto] * 2 + 1) << 29);
- upto += 4;
- }
- if (mask & (1L << r))
- ARMul_WriteWord (state, fpregsaddr + 128, buffer[upto++]);
- return (RDIError_NoError);
- #endif
- }
- static void
- deletebreaknode (BreakNode ** prevp)
- {
- BreakNode *p = *prevp;
- *prevp = p->next;
- ARMul_WriteWord (state, p->address, p->inst);
- free ((char *) p);
- BreaksSet--;
- state->CallDebug--;
- }
- static int
- removebreak (ARMword address, unsigned type)
- {
- BreakNode *p, **prevp = &BreakList;
- for (; (p = *prevp) != NULL; prevp = &p->next)
- if (p->address == address && p->type == type)
- {
- deletebreaknode (prevp);
- return TRUE;
- }
- return FALSE;
- }
- static BreakNode *
- installbreak (ARMword address, unsigned type, ARMword bound)
- {
- BreakNode *p = (BreakNode *) malloc (sizeof (BreakNode));
- p->next = BreakList;
- BreakList = p;
- p->address = address;
- p->type = type;
- p->bound = bound;
- p->inst = ARMul_ReadWord (state, address);
- ARMul_WriteWord (state, address, 0xee000000L);
- return p;
- }
- static int
- RDI_setbreak (ARMword address, unsigned type, ARMword bound,
- PointHandle * handle)
- {
- BreakNode *p;
- TracePrint ((state, "RDI_setbreak: address=%.8lx type=%d bound=%.8lx\n",
- address, type, bound));
- removebreak (address, type);
- p = installbreak (address, type, bound);
- BreaksSet++;
- state->CallDebug++;
- *handle = (PointHandle) p;
- TracePrint ((state, " returns %.8lx\n", *handle));
- return RDIError_NoError;
- }
- static int
- RDI_clearbreak (PointHandle handle)
- {
- TracePrint ((state, "RDI_clearbreak: address=%.8lx\n", handle));
- {
- BreakNode *p, **prevp = &BreakList;
- for (; (p = *prevp) != NULL; prevp = &p->next)
- if (p == (BreakNode *) handle)
- break;
- if (p == NULL)
- return RDIError_NoSuchPoint;
- deletebreaknode (prevp);
- return RDIError_NoError;
- }
- }
- static void
- deletewatchnode (WatchNode ** prevp)
- {
- WatchNode *p = *prevp;
- if (p->datatype & Watch_AnyRead)
- state->MemReadDebug--;
- if (p->datatype & Watch_AnyWrite)
- state->MemWriteDebug--;
- *prevp = p->next;
- free ((char *) p);
- }
- int
- removewatch (ARMword address, unsigned type)
- {
- WatchNode *p, **prevp = &WatchList;
- for (; (p = *prevp) != NULL; prevp = &p->next)
- if (p->address == address && p->type == type)
- {
- deletewatchnode (prevp);
- return TRUE;
- }
- return FALSE;
- }
- static WatchNode *
- installwatch (ARMword address, unsigned type, unsigned datatype,
- ARMword bound)
- {
- WatchNode *p = (WatchNode *) malloc (sizeof (WatchNode));
- p->next = WatchList;
- WatchList = p;
- p->address = address;
- p->type = type;
- p->datatype = datatype;
- p->bound = bound;
- return p;
- }
- static int
- RDI_setwatch (ARMword address, unsigned type, unsigned datatype,
- ARMword bound, PointHandle * handle)
- {
- WatchNode *p;
- TracePrint (
- (state,
- "RDI_setwatch: address=%.8lx type=%d datatype=%d bound=%.8lx",
- address, type, datatype, bound));
- if (!state->CanWatch)
- return RDIError_UnimplementedMessage;
- removewatch (address, type);
- p = installwatch (address, type, datatype, bound);
- if (datatype & Watch_AnyRead)
- state->MemReadDebug++;
- if (datatype & Watch_AnyWrite)
- state->MemWriteDebug++;
- *handle = (PointHandle) p;
- TracePrint ((state, " returns %.8lx\n", *handle));
- return RDIError_NoError;
- }
- static int
- RDI_clearwatch (PointHandle handle)
- {
- TracePrint ((state, "RDI_clearwatch: address=%.8lx\n", handle));
- {
- WatchNode *p, **prevp = &WatchList;
- for (; (p = *prevp) != NULL; prevp = &p->next)
- if (p == (WatchNode *) handle)
- break;
- if (p == NULL)
- return RDIError_NoSuchPoint;
- deletewatchnode (prevp);
- return RDIError_NoError;
- }
- }
- static int
- RDI_execute (PointHandle * handle)
- {
- TracePrint ((state, "RDI_execute\n"));
- if (rdi_log & 4)
- {
- state->CallDebug++;
- state->Debug = TRUE;
- }
- state->EndCondition = RDIError_NoError;
- state->StopHandle = 0;
- ARMul_DoProg (state);
- *handle = state->StopHandle;
- state->Reg[15] -= 8;
- if (rdi_log & 4)
- {
- state->CallDebug--;
- state->Debug = FALSE;
- }
- return (state->EndCondition);
- }
- static int
- RDI_step (unsigned ninstr, PointHandle * handle)
- {
- TracePrint ((state, "RDI_step\n"));
- if (ninstr != 1)
- return RDIError_UnimplementedMessage;
- if (rdi_log & 4)
- {
- state->CallDebug++;
- state->Debug = TRUE;
- }
- state->EndCondition = RDIError_NoError;
- state->StopHandle = 0;
- ARMul_DoInstr (state);
- *handle = state->StopHandle;
- state->Reg[15] -= 8;
- if (rdi_log & 4)
- {
- state->CallDebug--;
- state->Debug = FALSE;
- }
- return (state->EndCondition);
- }
- static int
- RDI_info (unsigned type, ARMword * arg1, ARMword * arg2)
- {
- switch (type)
- {
- case RDIInfo_Target:
- TracePrint ((state, "RDI_Info_Target\n"));
-
- *arg1 = 5 | HIGHEST_RDI_LEVEL << 5 | LOWEST_RDI_LEVEL << 8;
- *arg2 = 1298224434;
- return RDIError_NoError;
- case RDIInfo_Points:
- {
- ARMword n = RDIPointCapability_Comparison | RDIPointCapability_Range |
- RDIPointCapability_Mask | RDIPointCapability_Status;
- TracePrint ((state, "RDI_Info_Points\n"));
- if (state->CanWatch)
- n |= (Watch_AnyRead + Watch_AnyWrite) << 2;
- *arg1 = n;
- return RDIError_NoError;
- }
- case RDIInfo_Step:
- TracePrint ((state, "RDI_Info_Step\n"));
- *arg1 = RDIStep_Single;
- return RDIError_NoError;
- case RDIInfo_MMU:
- TracePrint ((state, "RDI_Info_MMU\n"));
- *arg1 = 1313820229;
- return RDIError_NoError;
- case RDISignal_Stop:
- TracePrint ((state, "RDISignal_Stop\n"));
- state->CallDebug++;
- state->EndCondition = RDIError_UserInterrupt;
- return RDIError_NoError;
- case RDIVector_Catch:
- TracePrint ((state, "RDIVector_Catch %.8lx\n", *arg1));
- state->VectorCatch = (unsigned) *arg1;
- return RDIError_NoError;
- case RDISet_Cmdline:
- TracePrint ((state, "RDI_Set_Cmdline %s\n", (char *) arg1));
- state->CommandLine =
- (char *) malloc ((unsigned) strlen ((char *) arg1) + 1);
- (void) strcpy (state->CommandLine, (char *) arg1);
- return RDIError_NoError;
- case RDICycles:
- TracePrint ((state, "RDI_Info_Cycles\n"));
- arg1[0] = 0;
- arg1[1] = state->NumInstrs;
- arg1[2] = 0;
- arg1[3] = state->NumScycles;
- arg1[4] = 0;
- arg1[5] = state->NumNcycles;
- arg1[6] = 0;
- arg1[7] = state->NumIcycles;
- arg1[8] = 0;
- arg1[9] = state->NumCcycles;
- arg1[10] = 0;
- arg1[11] = state->NumFcycles;
- return RDIError_NoError;
- case RDIErrorP:
- *arg1 = ARMul_OSLastErrorP (state);
- TracePrint ((state, "RDI_ErrorP returns %ld\n", *arg1));
- return RDIError_NoError;
- case RDIInfo_DescribeCoPro:
- {
- int cpnum = *(int *) arg1;
- struct Dbg_CoProDesc *cpd = (struct Dbg_CoProDesc *) arg2;
- int i;
- unsigned char const *map = state->CPRegWords[cpnum];
- if (map == NULL)
- return RDIError_UnknownCoPro;
- for (i = 0; i < cpd->entries; i++)
- {
- unsigned r, w = cpd->regdesc[i].nbytes / sizeof (ARMword);
- for (r = cpd->regdesc[i].rmin; r <= cpd->regdesc[i].rmax; r++)
- if (map[r] != w)
- return RDIError_BadCoProState;
- }
- return RDIError_NoError;
- }
- case RDIInfo_RequestCoProDesc:
- {
- int cpnum = *(int *) arg1;
- struct Dbg_CoProDesc *cpd = (struct Dbg_CoProDesc *) arg2;
- int i = -1, lastw = -1, r;
- unsigned char const *map;
- if ((unsigned) cpnum >= 16)
- return RDIError_UnknownCoPro;
- map = state->CPRegWords[cpnum];
- if (map == NULL)
- return RDIError_UnknownCoPro;
- for (r = 0; r < map[-1]; r++)
- {
- int words = map[r];
- if (words == lastw)
- cpd->regdesc[i].rmax = r;
- else
- {
- if (++i >= cpd->entries)
- return RDIError_BufferFull;
- cpd->regdesc[i].rmax = cpd->regdesc[i].rmin = r;
- cpd->regdesc[i].nbytes = words * sizeof (ARMword);
- cpd->regdesc[i].access =
- Dbg_Access_Readable + Dbg_Access_Writable;
- }
- }
- cpd->entries = i + 1;
- return RDIError_NoError;
- }
- case RDIInfo_Log:
- *arg1 = (ARMword) rdi_log;
- return RDIError_NoError;
- case RDIInfo_SetLog:
- rdi_log = (int) *arg1;
- return RDIError_NoError;
- case RDIInfo_CoPro:
- return RDIError_NoError;
- case RDIPointStatus_Watch:
- {
- WatchNode *p, *handle = (WatchNode *) * arg1;
- for (p = WatchList; p != NULL; p = p->next)
- if (p == handle)
- {
- *arg1 = -1;
- *arg2 = 1;
- return RDIError_NoError;
- }
- return RDIError_NoSuchPoint;
- }
- case RDIPointStatus_Break:
- {
- BreakNode *p, *handle = (BreakNode *) * arg1;
- for (p = BreakList; p != NULL; p = p->next)
- if (p == handle)
- {
- *arg1 = -1;
- *arg2 = 1;
- return RDIError_NoError;
- }
- return RDIError_NoSuchPoint;
- }
- case RDISet_RDILevel:
- if (*arg1 < LOWEST_RDI_LEVEL || *arg1 > HIGHEST_RDI_LEVEL)
- return RDIError_IncompatibleRDILevels;
- MYrdi_level = *arg1;
- return RDIError_NoError;
- default:
- return RDIError_UnimplementedMessage;
- }
- }
- ARMword
- ARMul_Debug (ARMul_State * state, ARMword pc, ARMword instr)
- {
- if (state->EndCondition == RDIError_UserInterrupt)
- {
- TracePrint ((state, "User interrupt at %.8lx\n", pc));
- state->CallDebug--;
- state->Emulate = STOP;
- }
- else
- {
- BreakNode *p = BreakList;
- for (; p != NULL; p = p->next)
- {
- switch (p->type)
- {
- case RDIPoint_EQ:
- if (pc == p->address)
- break;
- continue;
- case RDIPoint_GT:
- if (pc > p->address)
- break;
- continue;
- case RDIPoint_GE:
- if (pc >= p->address)
- break;
- continue;
- case RDIPoint_LT:
- if (pc < p->address)
- break;
- continue;
- case RDIPoint_LE:
- if (pc <= p->address)
- break;
- continue;
- case RDIPoint_IN:
- if (p->address <= pc && pc < p->address + p->bound)
- break;
- continue;
- case RDIPoint_OUT:
- if (p->address > pc || pc >= p->address + p->bound)
- break;
- continue;
- case RDIPoint_MASK:
- if ((pc & p->bound) == p->address)
- break;
- continue;
- }
-
- TracePrint ((state, "Breakpoint reached at %.8lx\n", pc));
- state->EndCondition = RDIError_BreakpointReached;
- state->Emulate = STOP;
- state->StopHandle = (ARMword) p;
- break;
- }
- }
- return instr;
- }
- void
- ARMul_CheckWatch (ARMul_State * state, ARMword addr, int access)
- {
- WatchNode *p;
- for (p = WatchList; p != NULL; p = p->next)
- if (p->datatype & access)
- {
- switch (p->type)
- {
- case RDIPoint_EQ:
- if (addr == p->address)
- break;
- continue;
- case RDIPoint_GT:
- if (addr > p->address)
- break;
- continue;
- case RDIPoint_GE:
- if (addr >= p->address)
- break;
- continue;
- case RDIPoint_LT:
- if (addr < p->address)
- break;
- continue;
- case RDIPoint_LE:
- if (addr <= p->address)
- break;
- continue;
- case RDIPoint_IN:
- if (p->address <= addr && addr < p->address + p->bound)
- break;
- continue;
- case RDIPoint_OUT:
- if (p->address > addr || addr >= p->address + p->bound)
- break;
- continue;
- case RDIPoint_MASK:
- if ((addr & p->bound) == p->address)
- break;
- continue;
- }
-
- TracePrint ((state, "Watchpoint at %.8lx accessed\n", addr));
- state->EndCondition = RDIError_WatchpointAccessed;
- state->Emulate = STOP;
- state->StopHandle = (ARMword) p;
- return;
- }
- }
- static RDI_NameList const *
- RDI_cpunames ()
- {
- return (RDI_NameList const *) &processorconfig.count;
- }
- const struct RDIProcVec armul_rdi = {
- "ARMUL",
- RDI_open,
- RDI_close,
- RDI_read,
- RDI_write,
- RDI_CPUread,
- RDI_CPUwrite,
- RDI_CPread,
- RDI_CPwrite,
- RDI_setbreak,
- RDI_clearbreak,
- RDI_setwatch,
- RDI_clearwatch,
- RDI_execute,
- RDI_step,
- RDI_info,
- 0,
- 0,
- 0,
- 0,
- 0,
- RDI_cpunames
- };
|