📄 armrdi.c
字号:
/* armrdi.c -- ARMulator RDI interface: ARM6 Instruction Emulator. Copyright (C) 1994 Advanced RISC Machines Ltd. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#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"/***************************************************************************\* Declarations *\***************************************************************************/#define Watch_AnyRead (RDIWatch_ByteRead+RDIWatch_HalfRead+RDIWatch_WordRead)#define Watch_AnyWrite (RDIWatch_ByteWrite+RDIWatch_HalfWrite+RDIWatch_WordWrite)static unsigned FPRegsAddr; /* last known address of FPE regs */#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)#endifstatic ARMul_State *state = NULL;static unsigned BreaksSet; /* The number of breakpoints set */static int rdi_log = 0; /* debugging ? */#define LOWEST_RDI_LEVEL 0#define HIGHEST_RDI_LEVEL 1static int MYrdi_level = LOWEST_RDI_LEVEL;typedef struct BreakNode BreakNode;typedef struct WatchNode WatchNode;struct BreakNode{ /* A breakpoint list node */ BreakNode *next; ARMword address; /* The address of this breakpoint */ unsigned type; /* The type of comparison */ ARMword bound; /* The other address for a range */ ARMword inst;};struct WatchNode{ /* A watchpoint list node */ WatchNode *next; ARMword address; /* The address of this watchpoint */ unsigned type; /* The type of comparison */ unsigned datatype; /* The type of access to watch for */ ARMword bound; /* The other address for a range */};BreakNode *BreakList = NULL;WatchNode *WatchList = NULL;voidARMul_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);}voidARMul_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 128voidARMul_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++); /* The string is i chars long */ 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); /* Send string 32bytes at a time */ 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); /* Send remainder of string */ for (j = 0; j < i; j++, str++) MYwrite_char (kidmum[1], *str); wait_for_osreply (&junk); } va_end (ap); return;/* str = buf; *//* while ((ch=*str++) != 0) *//* state->hostif->writec(state->hostif->hostosarg, ch); */}voidARMul_DebugPause (ARMul_State * state){ if (!(rdi_log & 8)) state->hostif->dbgpause (state->hostif->dbgarg);}/***************************************************************************\* RDI_open *\***************************************************************************/static voidInitFail (int exitcode, char const *which){ ARMul_ConsolePrint (state, "%s interface failed to initialise. Exiting\n", which); exit (exitcode);}static voidRDIInit (unsigned type){ if (type == 0) { /* cold start */ state->CallDebug = state->MemReadDebug = state->MemWriteDebug = 0; BreaksSet = 0; }}#define UNKNOWNPROC 0typedef 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, /* default: must come first */ &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 intRDI_open (unsigned type, const Dbg_ConfigBlock * config, const Dbg_HostosInterface * hostif, struct Dbg_MCState *dbg_state)/* Initialise everything */{ 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) { /* Warm start */ 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) { /* Reset the comms link */ /* what comms link ? */ } if (virgin && (type & 1) == 0) /* Cold start */ 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);}/***************************************************************************\* RDI_close *\***************************************************************************/static intRDI_close (void){ TracePrint ((state, "RDI_close\n")); ARMul_OSExit (state); ARMul_CoProExit (state); ARMul_MemoryExit (state); return (RDIError_NoError);}/***************************************************************************\* RDI_read *\***************************************************************************/static intRDI_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);}/***************************************************************************\* RDI_write *\***************************************************************************/static intRDI_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);}/***************************************************************************\* RDI_CPUread *\***************************************************************************/static intRDI_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);}/***************************************************************************\* RDI_CPUwrite *\***************************************************************************/static intRDI_CPUwrite (unsigned mode, unsigned long mask, ARMword const buffer[]){ int i, upto; TracePrint ((state, "RDI_CPUwrite: mode=%.8x mask=%.8lx", mode, mask));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -