mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-12-27 09:38:57 +00:00
import gdb-2000-02-04 snapshot
This commit is contained in:
@@ -1,3 +1,7 @@
|
||||
2000-02-02 Bernd Schmidt <bernds@cygnus.co.uk>
|
||||
|
||||
* *.[ch]: Use indent to make readable.
|
||||
|
||||
1999-11-22 Nick Clifton <nickc@cygnus.com>
|
||||
|
||||
* armos.c (SWIread): Generate an error message if a huge read is
|
||||
|
||||
@@ -17,24 +17,24 @@
|
||||
|
||||
#include "armdefs.h"
|
||||
|
||||
extern unsigned ARMul_CoProInit(ARMul_State *state) ;
|
||||
extern void ARMul_CoProExit(ARMul_State *state) ;
|
||||
extern void ARMul_CoProAttach(ARMul_State *state, unsigned number,
|
||||
ARMul_CPInits *init, ARMul_CPExits *exit,
|
||||
ARMul_LDCs *ldc, ARMul_STCs *stc,
|
||||
ARMul_MRCs *mrc, ARMul_MCRs *mcr,
|
||||
ARMul_CDPs *cdp,
|
||||
ARMul_CPReads *read, ARMul_CPWrites *write) ;
|
||||
extern void ARMul_CoProDetach(ARMul_State *state, unsigned number) ;
|
||||
extern unsigned ARMul_CoProInit (ARMul_State * state);
|
||||
extern void ARMul_CoProExit (ARMul_State * state);
|
||||
extern void ARMul_CoProAttach (ARMul_State * state, unsigned number,
|
||||
ARMul_CPInits * init, ARMul_CPExits * exit,
|
||||
ARMul_LDCs * ldc, ARMul_STCs * stc,
|
||||
ARMul_MRCs * mrc, ARMul_MCRs * mcr,
|
||||
ARMul_CDPs * cdp,
|
||||
ARMul_CPReads * read, ARMul_CPWrites * write);
|
||||
extern void ARMul_CoProDetach (ARMul_State * state, unsigned number);
|
||||
|
||||
|
||||
/***************************************************************************\
|
||||
* Dummy Co-processors *
|
||||
\***************************************************************************/
|
||||
|
||||
static unsigned NoCoPro3R(ARMul_State *state,unsigned,ARMword) ;
|
||||
static unsigned NoCoPro4R(ARMul_State *state,unsigned,ARMword,ARMword) ;
|
||||
static unsigned NoCoPro4W(ARMul_State *state,unsigned,ARMword,ARMword *) ;
|
||||
static unsigned NoCoPro3R (ARMul_State * state, unsigned, ARMword);
|
||||
static unsigned NoCoPro4R (ARMul_State * state, unsigned, ARMword, ARMword);
|
||||
static unsigned NoCoPro4W (ARMul_State * state, unsigned, ARMword, ARMword *);
|
||||
|
||||
/***************************************************************************\
|
||||
* Define Co-Processor instruction handlers here *
|
||||
@@ -49,62 +49,72 @@ controls 32/26 bit program space, bit 5 controls 32/26 bit data space,
|
||||
bit 6 controls late abort timimg and bit 7 controls big/little endian.
|
||||
*/
|
||||
|
||||
static ARMword MMUReg[8] ;
|
||||
static ARMword MMUReg[8];
|
||||
|
||||
static unsigned MMUInit(ARMul_State *state)
|
||||
{MMUReg[1] = state->prog32Sig << 4 |
|
||||
state->data32Sig << 5 |
|
||||
state->lateabtSig << 6 |
|
||||
state->bigendSig << 7 ;
|
||||
ARMul_ConsolePrint (state, ", MMU present") ;
|
||||
return(TRUE) ;
|
||||
static unsigned
|
||||
MMUInit (ARMul_State * state)
|
||||
{
|
||||
MMUReg[1] = state->prog32Sig << 4 |
|
||||
state->data32Sig << 5 | state->lateabtSig << 6 | state->bigendSig << 7;
|
||||
ARMul_ConsolePrint (state, ", MMU present");
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
static unsigned MMUMRC(ARMul_State *state, unsigned type, ARMword instr,ARMword *value)
|
||||
{int reg = BITS(16,19) & 7 ;
|
||||
static unsigned
|
||||
MMUMRC (ARMul_State * state, unsigned type, ARMword instr, ARMword * value)
|
||||
{
|
||||
int reg = BITS (16, 19) & 7;
|
||||
|
||||
if (reg == 0)
|
||||
*value = 0x41440110 ;
|
||||
else
|
||||
*value = MMUReg[reg] ;
|
||||
return(ARMul_DONE) ;
|
||||
}
|
||||
if (reg == 0)
|
||||
*value = 0x41440110;
|
||||
else
|
||||
*value = MMUReg[reg];
|
||||
return (ARMul_DONE);
|
||||
}
|
||||
|
||||
static unsigned MMUMCR(ARMul_State *state, unsigned type, ARMword instr, ARMword value)
|
||||
{int reg = BITS(16,19) & 7 ;
|
||||
static unsigned
|
||||
MMUMCR (ARMul_State * state, unsigned type, ARMword instr, ARMword value)
|
||||
{
|
||||
int reg = BITS (16, 19) & 7;
|
||||
|
||||
MMUReg[reg] = value ;
|
||||
if (reg == 1) {
|
||||
state->prog32Sig = value >> 4 & 1 ;
|
||||
state->data32Sig = value >> 5 & 1 ;
|
||||
state->lateabtSig = value >> 6 & 1 ;
|
||||
state->bigendSig = value >> 7 & 1 ;
|
||||
state->Emulate = TRUE ; /* force ARMulator to notice these now !*/
|
||||
MMUReg[reg] = value;
|
||||
if (reg == 1)
|
||||
{
|
||||
state->prog32Sig = value >> 4 & 1;
|
||||
state->data32Sig = value >> 5 & 1;
|
||||
state->lateabtSig = value >> 6 & 1;
|
||||
state->bigendSig = value >> 7 & 1;
|
||||
state->Emulate = TRUE; /* force ARMulator to notice these now ! */
|
||||
}
|
||||
return(ARMul_DONE) ;
|
||||
}
|
||||
return (ARMul_DONE);
|
||||
}
|
||||
|
||||
|
||||
static unsigned MMURead(ARMul_State *state, unsigned reg, ARMword *value)
|
||||
{if (reg == 0)
|
||||
*value = 0x41440110 ;
|
||||
else if (reg < 8)
|
||||
*value = MMUReg[reg] ;
|
||||
return(TRUE) ;
|
||||
}
|
||||
static unsigned
|
||||
MMURead (ARMul_State * state, unsigned reg, ARMword * value)
|
||||
{
|
||||
if (reg == 0)
|
||||
*value = 0x41440110;
|
||||
else if (reg < 8)
|
||||
*value = MMUReg[reg];
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
static unsigned MMUWrite(ARMul_State *state, unsigned reg, ARMword value)
|
||||
{if (reg < 8)
|
||||
MMUReg[reg] = value ;
|
||||
if (reg == 1) {
|
||||
state->prog32Sig = value >> 4 & 1 ;
|
||||
state->data32Sig = value >> 5 & 1 ;
|
||||
state->lateabtSig = value >> 6 & 1 ;
|
||||
state->bigendSig = value >> 7 & 1 ;
|
||||
state->Emulate = TRUE ; /* force ARMulator to notice these now !*/
|
||||
static unsigned
|
||||
MMUWrite (ARMul_State * state, unsigned reg, ARMword value)
|
||||
{
|
||||
if (reg < 8)
|
||||
MMUReg[reg] = value;
|
||||
if (reg == 1)
|
||||
{
|
||||
state->prog32Sig = value >> 4 & 1;
|
||||
state->data32Sig = value >> 5 & 1;
|
||||
state->lateabtSig = value >> 6 & 1;
|
||||
state->bigendSig = value >> 7 & 1;
|
||||
state->Emulate = TRUE; /* force ARMulator to notice these now ! */
|
||||
}
|
||||
return(TRUE) ;
|
||||
}
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
|
||||
/* What follows is the Validation Suite Coprocessor. It uses two
|
||||
@@ -118,240 +128,283 @@ way, CDP 3 and 4 turn of the FIQ and IRQ source, and CDP 5 stores a 32
|
||||
bit time value in a CP register (actually it's the total number of N, S,
|
||||
I, C and F cyles) */
|
||||
|
||||
static ARMword ValReg[16] ;
|
||||
static ARMword ValReg[16];
|
||||
|
||||
static unsigned ValLDC(ARMul_State *state, unsigned type,
|
||||
ARMword instr, ARMword data)
|
||||
{static unsigned words ;
|
||||
|
||||
if (type != ARMul_DATA) {
|
||||
words = 0 ;
|
||||
return(ARMul_DONE) ;
|
||||
}
|
||||
if (BIT(22)) { /* it's a long access, get two words */
|
||||
ValReg[BITS(12,15)] = data ;
|
||||
if (words++ == 4)
|
||||
return(ARMul_DONE) ;
|
||||
else
|
||||
return(ARMul_INC) ;
|
||||
}
|
||||
else { /* get just one word */
|
||||
ValReg[BITS(12,15)] = data ;
|
||||
return(ARMul_DONE) ;
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned ValSTC(ARMul_State *state, unsigned type,
|
||||
ARMword instr, ARMword *data)
|
||||
{static unsigned words ;
|
||||
|
||||
if (type != ARMul_DATA) {
|
||||
words = 0 ;
|
||||
return(ARMul_DONE) ;
|
||||
}
|
||||
if (BIT(22)) { /* it's a long access, get two words */
|
||||
*data = ValReg[BITS(12,15)] ;
|
||||
if (words++ == 4)
|
||||
return(ARMul_DONE) ;
|
||||
else
|
||||
return(ARMul_INC) ;
|
||||
}
|
||||
else { /* get just one word */
|
||||
*data = ValReg[BITS(12,15)] ;
|
||||
return(ARMul_DONE) ;
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned ValMRC(ARMul_State *state, unsigned type, ARMword instr,ARMword *value)
|
||||
static unsigned
|
||||
ValLDC (ARMul_State * state, unsigned type, ARMword instr, ARMword data)
|
||||
{
|
||||
*value = ValReg[BITS(16,19)] ;
|
||||
return(ARMul_DONE) ;
|
||||
}
|
||||
static unsigned words;
|
||||
|
||||
static unsigned ValMCR(ARMul_State *state, unsigned type, ARMword instr, ARMword value)
|
||||
{
|
||||
ValReg[BITS(16,19)] = value ;
|
||||
return(ARMul_DONE) ;
|
||||
}
|
||||
|
||||
static unsigned ValCDP(ARMul_State *state, unsigned type, ARMword instr)
|
||||
{
|
||||
static unsigned long finish = 0 ;
|
||||
ARMword howlong ;
|
||||
|
||||
howlong = ValReg[BITS(0,3)] ;
|
||||
if (BITS(20,23)==0) {
|
||||
if (type == ARMul_FIRST) { /* First cycle of a busy wait */
|
||||
finish = ARMul_Time(state) + howlong ;
|
||||
if (howlong == 0)
|
||||
return(ARMul_DONE) ;
|
||||
else
|
||||
return(ARMul_BUSY) ;
|
||||
}
|
||||
else if (type == ARMul_BUSY) {
|
||||
if (ARMul_Time(state) >= finish)
|
||||
return(ARMul_DONE) ;
|
||||
else
|
||||
return(ARMul_BUSY) ;
|
||||
}
|
||||
if (type != ARMul_DATA)
|
||||
{
|
||||
words = 0;
|
||||
return (ARMul_DONE);
|
||||
}
|
||||
if (BIT (22))
|
||||
{ /* it's a long access, get two words */
|
||||
ValReg[BITS (12, 15)] = data;
|
||||
if (words++ == 4)
|
||||
return (ARMul_DONE);
|
||||
else
|
||||
return (ARMul_INC);
|
||||
}
|
||||
else
|
||||
{ /* get just one word */
|
||||
ValReg[BITS (12, 15)] = data;
|
||||
return (ARMul_DONE);
|
||||
}
|
||||
return(ARMul_CANT) ;
|
||||
}
|
||||
|
||||
static unsigned DoAFIQ(ARMul_State *state)
|
||||
{state->NfiqSig = LOW ;
|
||||
state->Exception++ ;
|
||||
return(0) ;
|
||||
}
|
||||
|
||||
static unsigned DoAIRQ(ARMul_State *state)
|
||||
{state->NirqSig = LOW ;
|
||||
state->Exception++ ;
|
||||
return(0) ;
|
||||
static unsigned
|
||||
ValSTC (ARMul_State * state, unsigned type, ARMword instr, ARMword * data)
|
||||
{
|
||||
static unsigned words;
|
||||
|
||||
if (type != ARMul_DATA)
|
||||
{
|
||||
words = 0;
|
||||
return (ARMul_DONE);
|
||||
}
|
||||
if (BIT (22))
|
||||
{ /* it's a long access, get two words */
|
||||
*data = ValReg[BITS (12, 15)];
|
||||
if (words++ == 4)
|
||||
return (ARMul_DONE);
|
||||
else
|
||||
return (ARMul_INC);
|
||||
}
|
||||
else
|
||||
{ /* get just one word */
|
||||
*data = ValReg[BITS (12, 15)];
|
||||
return (ARMul_DONE);
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned IntCDP(ARMul_State *state, unsigned type, ARMword instr)
|
||||
{static unsigned long finish ;
|
||||
ARMword howlong ;
|
||||
static unsigned
|
||||
ValMRC (ARMul_State * state, unsigned type, ARMword instr, ARMword * value)
|
||||
{
|
||||
*value = ValReg[BITS (16, 19)];
|
||||
return (ARMul_DONE);
|
||||
}
|
||||
|
||||
howlong = ValReg[BITS(0,3)] ;
|
||||
switch((int)BITS(20,23)) {
|
||||
case 0 : if (type == ARMul_FIRST) { /* First cycle of a busy wait */
|
||||
finish = ARMul_Time(state) + howlong ;
|
||||
if (howlong == 0)
|
||||
return(ARMul_DONE) ;
|
||||
else
|
||||
return(ARMul_BUSY) ;
|
||||
}
|
||||
else if (type == ARMul_BUSY) {
|
||||
if (ARMul_Time(state) >= finish)
|
||||
return(ARMul_DONE) ;
|
||||
else
|
||||
return(ARMul_BUSY) ;
|
||||
}
|
||||
return(ARMul_DONE) ;
|
||||
case 1 : if (howlong == 0)
|
||||
ARMul_Abort(state,ARMul_FIQV) ;
|
||||
else
|
||||
ARMul_ScheduleEvent(state,howlong,DoAFIQ) ;
|
||||
return(ARMul_DONE) ;
|
||||
case 2 : if (howlong == 0)
|
||||
ARMul_Abort(state,ARMul_IRQV) ;
|
||||
else
|
||||
ARMul_ScheduleEvent(state,howlong,DoAIRQ) ;
|
||||
return(ARMul_DONE) ;
|
||||
case 3 : state->NfiqSig = HIGH ;
|
||||
state->Exception-- ;
|
||||
return(ARMul_DONE) ;
|
||||
case 4 : state->NirqSig = HIGH ;
|
||||
state->Exception-- ;
|
||||
return(ARMul_DONE) ;
|
||||
case 5 : ValReg[BITS(0,3)] = ARMul_Time(state) ;
|
||||
return(ARMul_DONE) ;
|
||||
static unsigned
|
||||
ValMCR (ARMul_State * state, unsigned type, ARMword instr, ARMword value)
|
||||
{
|
||||
ValReg[BITS (16, 19)] = value;
|
||||
return (ARMul_DONE);
|
||||
}
|
||||
|
||||
static unsigned
|
||||
ValCDP (ARMul_State * state, unsigned type, ARMword instr)
|
||||
{
|
||||
static unsigned long finish = 0;
|
||||
ARMword howlong;
|
||||
|
||||
howlong = ValReg[BITS (0, 3)];
|
||||
if (BITS (20, 23) == 0)
|
||||
{
|
||||
if (type == ARMul_FIRST)
|
||||
{ /* First cycle of a busy wait */
|
||||
finish = ARMul_Time (state) + howlong;
|
||||
if (howlong == 0)
|
||||
return (ARMul_DONE);
|
||||
else
|
||||
return (ARMul_BUSY);
|
||||
}
|
||||
else if (type == ARMul_BUSY)
|
||||
{
|
||||
if (ARMul_Time (state) >= finish)
|
||||
return (ARMul_DONE);
|
||||
else
|
||||
return (ARMul_BUSY);
|
||||
}
|
||||
}
|
||||
return(ARMul_CANT) ;
|
||||
}
|
||||
return (ARMul_CANT);
|
||||
}
|
||||
|
||||
static unsigned
|
||||
DoAFIQ (ARMul_State * state)
|
||||
{
|
||||
state->NfiqSig = LOW;
|
||||
state->Exception++;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static unsigned
|
||||
DoAIRQ (ARMul_State * state)
|
||||
{
|
||||
state->NirqSig = LOW;
|
||||
state->Exception++;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static unsigned
|
||||
IntCDP (ARMul_State * state, unsigned type, ARMword instr)
|
||||
{
|
||||
static unsigned long finish;
|
||||
ARMword howlong;
|
||||
|
||||
howlong = ValReg[BITS (0, 3)];
|
||||
switch ((int) BITS (20, 23))
|
||||
{
|
||||
case 0:
|
||||
if (type == ARMul_FIRST)
|
||||
{ /* First cycle of a busy wait */
|
||||
finish = ARMul_Time (state) + howlong;
|
||||
if (howlong == 0)
|
||||
return (ARMul_DONE);
|
||||
else
|
||||
return (ARMul_BUSY);
|
||||
}
|
||||
else if (type == ARMul_BUSY)
|
||||
{
|
||||
if (ARMul_Time (state) >= finish)
|
||||
return (ARMul_DONE);
|
||||
else
|
||||
return (ARMul_BUSY);
|
||||
}
|
||||
return (ARMul_DONE);
|
||||
case 1:
|
||||
if (howlong == 0)
|
||||
ARMul_Abort (state, ARMul_FIQV);
|
||||
else
|
||||
ARMul_ScheduleEvent (state, howlong, DoAFIQ);
|
||||
return (ARMul_DONE);
|
||||
case 2:
|
||||
if (howlong == 0)
|
||||
ARMul_Abort (state, ARMul_IRQV);
|
||||
else
|
||||
ARMul_ScheduleEvent (state, howlong, DoAIRQ);
|
||||
return (ARMul_DONE);
|
||||
case 3:
|
||||
state->NfiqSig = HIGH;
|
||||
state->Exception--;
|
||||
return (ARMul_DONE);
|
||||
case 4:
|
||||
state->NirqSig = HIGH;
|
||||
state->Exception--;
|
||||
return (ARMul_DONE);
|
||||
case 5:
|
||||
ValReg[BITS (0, 3)] = ARMul_Time (state);
|
||||
return (ARMul_DONE);
|
||||
}
|
||||
return (ARMul_CANT);
|
||||
}
|
||||
|
||||
/***************************************************************************\
|
||||
* Install co-processor instruction handlers in this routine *
|
||||
\***************************************************************************/
|
||||
|
||||
unsigned ARMul_CoProInit(ARMul_State *state)
|
||||
{register unsigned i ;
|
||||
unsigned
|
||||
ARMul_CoProInit (ARMul_State * state)
|
||||
{
|
||||
register unsigned i;
|
||||
|
||||
for (i = 0 ; i < 16 ; i++) /* initialise tham all first */
|
||||
ARMul_CoProDetach(state, i) ;
|
||||
for (i = 0; i < 16; i++) /* initialise tham all first */
|
||||
ARMul_CoProDetach (state, i);
|
||||
|
||||
/* Install CoPro Instruction handlers here
|
||||
The format is
|
||||
ARMul_CoProAttach(state, CP Number, Init routine, Exit routine
|
||||
LDC routine, STC routine, MRC routine, MCR routine,
|
||||
CDP routine, Read Reg routine, Write Reg routine) ;
|
||||
/* Install CoPro Instruction handlers here
|
||||
The format is
|
||||
ARMul_CoProAttach(state, CP Number, Init routine, Exit routine
|
||||
LDC routine, STC routine, MRC routine, MCR routine,
|
||||
CDP routine, Read Reg routine, Write Reg routine) ;
|
||||
*/
|
||||
|
||||
ARMul_CoProAttach(state, 4, NULL, NULL,
|
||||
ValLDC, ValSTC, ValMRC, ValMCR,
|
||||
ValCDP, NULL, NULL) ;
|
||||
ARMul_CoProAttach (state, 4, NULL, NULL,
|
||||
ValLDC, ValSTC, ValMRC, ValMCR, ValCDP, NULL, NULL);
|
||||
|
||||
ARMul_CoProAttach(state, 5, NULL, NULL,
|
||||
NULL, NULL, ValMRC, ValMCR,
|
||||
IntCDP, NULL, NULL) ;
|
||||
ARMul_CoProAttach (state, 5, NULL, NULL,
|
||||
NULL, NULL, ValMRC, ValMCR, IntCDP, NULL, NULL);
|
||||
|
||||
ARMul_CoProAttach(state, 15, MMUInit, NULL,
|
||||
NULL, NULL, MMUMRC, MMUMCR,
|
||||
NULL, MMURead, MMUWrite) ;
|
||||
ARMul_CoProAttach (state, 15, MMUInit, NULL,
|
||||
NULL, NULL, MMUMRC, MMUMCR, NULL, MMURead, MMUWrite);
|
||||
|
||||
|
||||
/* No handlers below here */
|
||||
/* No handlers below here */
|
||||
|
||||
for (i = 0 ; i < 16 ; i++) /* Call all the initialisation routines */
|
||||
if (state->CPInit[i])
|
||||
(state->CPInit[i])(state) ;
|
||||
return(TRUE) ;
|
||||
}
|
||||
for (i = 0; i < 16; i++) /* Call all the initialisation routines */
|
||||
if (state->CPInit[i])
|
||||
(state->CPInit[i]) (state);
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
/***************************************************************************\
|
||||
* Install co-processor finalisation routines in this routine *
|
||||
\***************************************************************************/
|
||||
|
||||
void ARMul_CoProExit(ARMul_State *state)
|
||||
{register unsigned i ;
|
||||
void
|
||||
ARMul_CoProExit (ARMul_State * state)
|
||||
{
|
||||
register unsigned i;
|
||||
|
||||
for (i = 0 ; i < 16 ; i++)
|
||||
for (i = 0; i < 16; i++)
|
||||
if (state->CPExit[i])
|
||||
(state->CPExit[i])(state) ;
|
||||
for (i = 0 ; i < 16 ; i++) /* Detach all handlers */
|
||||
ARMul_CoProDetach(state, i) ;
|
||||
}
|
||||
(state->CPExit[i]) (state);
|
||||
for (i = 0; i < 16; i++) /* Detach all handlers */
|
||||
ARMul_CoProDetach (state, i);
|
||||
}
|
||||
|
||||
/***************************************************************************\
|
||||
* Routines to hook Co-processors into ARMulator *
|
||||
\***************************************************************************/
|
||||
|
||||
void ARMul_CoProAttach(ARMul_State *state, unsigned number,
|
||||
ARMul_CPInits *init, ARMul_CPExits *exit,
|
||||
ARMul_LDCs *ldc, ARMul_STCs *stc,
|
||||
ARMul_MRCs *mrc, ARMul_MCRs *mcr, ARMul_CDPs *cdp,
|
||||
ARMul_CPReads *read, ARMul_CPWrites *write)
|
||||
{if (init != NULL)
|
||||
state->CPInit[number] = init ;
|
||||
if (exit != NULL)
|
||||
state->CPExit[number] = exit ;
|
||||
if (ldc != NULL)
|
||||
state->LDC[number] = ldc ;
|
||||
if (stc != NULL)
|
||||
state->STC[number] = stc ;
|
||||
if (mrc != NULL)
|
||||
state->MRC[number] = mrc ;
|
||||
if (mcr != NULL)
|
||||
state->MCR[number] = mcr ;
|
||||
if (cdp != NULL)
|
||||
state->CDP[number] = cdp ;
|
||||
if (read != NULL)
|
||||
state->CPRead[number] = read ;
|
||||
if (write != NULL)
|
||||
state->CPWrite[number] = write ;
|
||||
void
|
||||
ARMul_CoProAttach (ARMul_State * state, unsigned number,
|
||||
ARMul_CPInits * init, ARMul_CPExits * exit,
|
||||
ARMul_LDCs * ldc, ARMul_STCs * stc,
|
||||
ARMul_MRCs * mrc, ARMul_MCRs * mcr, ARMul_CDPs * cdp,
|
||||
ARMul_CPReads * read, ARMul_CPWrites * write)
|
||||
{
|
||||
if (init != NULL)
|
||||
state->CPInit[number] = init;
|
||||
if (exit != NULL)
|
||||
state->CPExit[number] = exit;
|
||||
if (ldc != NULL)
|
||||
state->LDC[number] = ldc;
|
||||
if (stc != NULL)
|
||||
state->STC[number] = stc;
|
||||
if (mrc != NULL)
|
||||
state->MRC[number] = mrc;
|
||||
if (mcr != NULL)
|
||||
state->MCR[number] = mcr;
|
||||
if (cdp != NULL)
|
||||
state->CDP[number] = cdp;
|
||||
if (read != NULL)
|
||||
state->CPRead[number] = read;
|
||||
if (write != NULL)
|
||||
state->CPWrite[number] = write;
|
||||
}
|
||||
|
||||
void ARMul_CoProDetach(ARMul_State *state, unsigned number)
|
||||
{ARMul_CoProAttach(state, number, NULL, NULL,
|
||||
NoCoPro4R, NoCoPro4W, NoCoPro4W, NoCoPro4R,
|
||||
NoCoPro3R, NULL, NULL) ;
|
||||
state->CPInit[number] = NULL ;
|
||||
state->CPExit[number] = NULL ;
|
||||
state->CPRead[number] = NULL ;
|
||||
state->CPWrite[number] = NULL ;
|
||||
void
|
||||
ARMul_CoProDetach (ARMul_State * state, unsigned number)
|
||||
{
|
||||
ARMul_CoProAttach (state, number, NULL, NULL,
|
||||
NoCoPro4R, NoCoPro4W, NoCoPro4W, NoCoPro4R,
|
||||
NoCoPro3R, NULL, NULL);
|
||||
state->CPInit[number] = NULL;
|
||||
state->CPExit[number] = NULL;
|
||||
state->CPRead[number] = NULL;
|
||||
state->CPWrite[number] = NULL;
|
||||
}
|
||||
|
||||
/***************************************************************************\
|
||||
* There is no CoPro around, so Undefined Instruction trap *
|
||||
\***************************************************************************/
|
||||
|
||||
static unsigned NoCoPro3R(ARMul_State *state,unsigned a,ARMword b)
|
||||
{return(ARMul_CANT) ;}
|
||||
static unsigned
|
||||
NoCoPro3R (ARMul_State * state, unsigned a, ARMword b)
|
||||
{
|
||||
return (ARMul_CANT);
|
||||
}
|
||||
|
||||
static unsigned NoCoPro4R(ARMul_State *state, unsigned a,ARMword b,ARMword c)
|
||||
{return(ARMul_CANT) ;}
|
||||
static unsigned
|
||||
NoCoPro4R (ARMul_State * state, unsigned a, ARMword b, ARMword c)
|
||||
{
|
||||
return (ARMul_CANT);
|
||||
}
|
||||
|
||||
static unsigned NoCoPro4W(ARMul_State *state, unsigned a,ARMword b,ARMword *c)
|
||||
{return(ARMul_CANT) ;}
|
||||
static unsigned
|
||||
NoCoPro4W (ARMul_State * state, unsigned a, ARMword b, ARMword * c)
|
||||
{
|
||||
return (ARMul_CANT);
|
||||
}
|
||||
|
||||
@@ -26,101 +26,105 @@
|
||||
#define HIGHLOW 2
|
||||
|
||||
#ifndef __STDC__
|
||||
typedef char * VoidStar ;
|
||||
typedef char *VoidStar;
|
||||
#endif
|
||||
|
||||
typedef unsigned long ARMword ; /* must be 32 bits wide */
|
||||
typedef struct ARMul_State ARMul_State ;
|
||||
typedef unsigned long ARMword; /* must be 32 bits wide */
|
||||
typedef struct ARMul_State ARMul_State;
|
||||
|
||||
typedef unsigned ARMul_CPInits(ARMul_State *state) ;
|
||||
typedef unsigned ARMul_CPExits(ARMul_State *state) ;
|
||||
typedef unsigned ARMul_LDCs(ARMul_State *state,unsigned type,ARMword instr,ARMword value) ;
|
||||
typedef unsigned ARMul_STCs(ARMul_State *state,unsigned type,ARMword instr,ARMword *value) ;
|
||||
typedef unsigned ARMul_MRCs(ARMul_State *state,unsigned type,ARMword instr,ARMword *value) ;
|
||||
typedef unsigned ARMul_MCRs(ARMul_State *state,unsigned type,ARMword instr,ARMword value) ;
|
||||
typedef unsigned ARMul_CDPs(ARMul_State *state,unsigned type,ARMword instr) ;
|
||||
typedef unsigned ARMul_CPReads(ARMul_State *state,unsigned reg,ARMword *value) ;
|
||||
typedef unsigned ARMul_CPWrites(ARMul_State *state,unsigned reg,ARMword value) ;
|
||||
typedef unsigned ARMul_CPInits (ARMul_State * state);
|
||||
typedef unsigned ARMul_CPExits (ARMul_State * state);
|
||||
typedef unsigned ARMul_LDCs (ARMul_State * state, unsigned type,
|
||||
ARMword instr, ARMword value);
|
||||
typedef unsigned ARMul_STCs (ARMul_State * state, unsigned type,
|
||||
ARMword instr, ARMword * value);
|
||||
typedef unsigned ARMul_MRCs (ARMul_State * state, unsigned type,
|
||||
ARMword instr, ARMword * value);
|
||||
typedef unsigned ARMul_MCRs (ARMul_State * state, unsigned type,
|
||||
ARMword instr, ARMword value);
|
||||
typedef unsigned ARMul_CDPs (ARMul_State * state, unsigned type,
|
||||
ARMword instr);
|
||||
typedef unsigned ARMul_CPReads (ARMul_State * state, unsigned reg,
|
||||
ARMword * value);
|
||||
typedef unsigned ARMul_CPWrites (ARMul_State * state, unsigned reg,
|
||||
ARMword value);
|
||||
|
||||
struct ARMul_State {
|
||||
ARMword Emulate ; /* to start and stop emulation */
|
||||
unsigned EndCondition ; /* reason for stopping */
|
||||
unsigned ErrorCode ; /* type of illegal instruction */
|
||||
ARMword Reg[16] ; /* the current register file */
|
||||
ARMword RegBank[7][16] ; /* all the registers */
|
||||
ARMword Cpsr ; /* the current psr */
|
||||
ARMword Spsr[7] ; /* the exception psr's */
|
||||
ARMword NFlag, ZFlag, CFlag, VFlag, IFFlags ; /* dummy flags for speed */
|
||||
struct ARMul_State
|
||||
{
|
||||
ARMword Emulate; /* to start and stop emulation */
|
||||
unsigned EndCondition; /* reason for stopping */
|
||||
unsigned ErrorCode; /* type of illegal instruction */
|
||||
ARMword Reg[16]; /* the current register file */
|
||||
ARMword RegBank[7][16]; /* all the registers */
|
||||
ARMword Cpsr; /* the current psr */
|
||||
ARMword Spsr[7]; /* the exception psr's */
|
||||
ARMword NFlag, ZFlag, CFlag, VFlag, IFFlags; /* dummy flags for speed */
|
||||
#ifdef MODET
|
||||
ARMword TFlag ; /* Thumb state */
|
||||
ARMword TFlag; /* Thumb state */
|
||||
#endif
|
||||
ARMword Bank ; /* the current register bank */
|
||||
ARMword Mode ; /* the current mode */
|
||||
ARMword instr, pc, temp ; /* saved register state */
|
||||
ARMword loaded, decoded ; /* saved pipeline state */
|
||||
unsigned long NumScycles,
|
||||
NumNcycles,
|
||||
NumIcycles,
|
||||
NumCcycles,
|
||||
NumFcycles ; /* emulated cycles used */
|
||||
unsigned long NumInstrs ; /* the number of instructions executed */
|
||||
unsigned NextInstr ;
|
||||
unsigned VectorCatch ; /* caught exception mask */
|
||||
unsigned CallDebug ; /* set to call the debugger */
|
||||
unsigned CanWatch ; /* set by memory interface if its willing to suffer the
|
||||
overhead of checking for watchpoints on each memory
|
||||
access */
|
||||
unsigned MemReadDebug, MemWriteDebug ;
|
||||
unsigned long StopHandle ;
|
||||
ARMword Bank; /* the current register bank */
|
||||
ARMword Mode; /* the current mode */
|
||||
ARMword instr, pc, temp; /* saved register state */
|
||||
ARMword loaded, decoded; /* saved pipeline state */
|
||||
unsigned long NumScycles, NumNcycles, NumIcycles, NumCcycles, NumFcycles; /* emulated cycles used */
|
||||
unsigned long NumInstrs; /* the number of instructions executed */
|
||||
unsigned NextInstr;
|
||||
unsigned VectorCatch; /* caught exception mask */
|
||||
unsigned CallDebug; /* set to call the debugger */
|
||||
unsigned CanWatch; /* set by memory interface if its willing to suffer the
|
||||
overhead of checking for watchpoints on each memory
|
||||
access */
|
||||
unsigned MemReadDebug, MemWriteDebug;
|
||||
unsigned long StopHandle;
|
||||
|
||||
unsigned char *MemDataPtr ; /* admin data */
|
||||
unsigned char *MemInPtr ; /* the Data In bus */
|
||||
unsigned char *MemOutPtr ; /* the Data Out bus (which you may not need */
|
||||
unsigned char *MemSparePtr ; /* extra space */
|
||||
ARMword MemSize ;
|
||||
unsigned char *MemDataPtr; /* admin data */
|
||||
unsigned char *MemInPtr; /* the Data In bus */
|
||||
unsigned char *MemOutPtr; /* the Data Out bus (which you may not need */
|
||||
unsigned char *MemSparePtr; /* extra space */
|
||||
ARMword MemSize;
|
||||
|
||||
unsigned char *OSptr ; /* OS Handle */
|
||||
char *CommandLine ; /* Command Line from ARMsd */
|
||||
unsigned char *OSptr; /* OS Handle */
|
||||
char *CommandLine; /* Command Line from ARMsd */
|
||||
|
||||
ARMul_CPInits *CPInit[16] ; /* coprocessor initialisers */
|
||||
ARMul_CPExits *CPExit[16] ; /* coprocessor finalisers */
|
||||
ARMul_LDCs *LDC[16] ; /* LDC instruction */
|
||||
ARMul_STCs *STC[16] ; /* STC instruction */
|
||||
ARMul_MRCs *MRC[16] ; /* MRC instruction */
|
||||
ARMul_MCRs *MCR[16] ; /* MCR instruction */
|
||||
ARMul_CDPs *CDP[16] ; /* CDP instruction */
|
||||
ARMul_CPReads *CPRead[16] ; /* Read CP register */
|
||||
ARMul_CPWrites *CPWrite[16] ; /* Write CP register */
|
||||
unsigned char *CPData[16] ; /* Coprocessor data */
|
||||
unsigned char const *CPRegWords[16] ; /* map of coprocessor register sizes */
|
||||
ARMul_CPInits *CPInit[16]; /* coprocessor initialisers */
|
||||
ARMul_CPExits *CPExit[16]; /* coprocessor finalisers */
|
||||
ARMul_LDCs *LDC[16]; /* LDC instruction */
|
||||
ARMul_STCs *STC[16]; /* STC instruction */
|
||||
ARMul_MRCs *MRC[16]; /* MRC instruction */
|
||||
ARMul_MCRs *MCR[16]; /* MCR instruction */
|
||||
ARMul_CDPs *CDP[16]; /* CDP instruction */
|
||||
ARMul_CPReads *CPRead[16]; /* Read CP register */
|
||||
ARMul_CPWrites *CPWrite[16]; /* Write CP register */
|
||||
unsigned char *CPData[16]; /* Coprocessor data */
|
||||
unsigned char const *CPRegWords[16]; /* map of coprocessor register sizes */
|
||||
|
||||
unsigned EventSet ; /* the number of events in the queue */
|
||||
unsigned long Now ; /* time to the nearest cycle */
|
||||
struct EventNode **EventPtr ; /* the event list */
|
||||
unsigned EventSet; /* the number of events in the queue */
|
||||
unsigned long Now; /* time to the nearest cycle */
|
||||
struct EventNode **EventPtr; /* the event list */
|
||||
|
||||
unsigned Exception ; /* enable the next four values */
|
||||
unsigned Debug ; /* show instructions as they are executed */
|
||||
unsigned NresetSig ; /* reset the processor */
|
||||
unsigned NfiqSig ;
|
||||
unsigned NirqSig ;
|
||||
unsigned Exception; /* enable the next four values */
|
||||
unsigned Debug; /* show instructions as they are executed */
|
||||
unsigned NresetSig; /* reset the processor */
|
||||
unsigned NfiqSig;
|
||||
unsigned NirqSig;
|
||||
|
||||
unsigned abortSig ;
|
||||
unsigned NtransSig ;
|
||||
unsigned bigendSig ;
|
||||
unsigned prog32Sig ;
|
||||
unsigned data32Sig ;
|
||||
unsigned lateabtSig ;
|
||||
ARMword Vector ; /* synthesize aborts in cycle modes */
|
||||
ARMword Aborted ; /* sticky flag for aborts */
|
||||
ARMword Reseted ; /* sticky flag for Reset */
|
||||
ARMword Inted, LastInted ; /* sticky flags for interrupts */
|
||||
ARMword Base ; /* extra hand for base writeback */
|
||||
ARMword AbortAddr ; /* to keep track of Prefetch aborts */
|
||||
unsigned abortSig;
|
||||
unsigned NtransSig;
|
||||
unsigned bigendSig;
|
||||
unsigned prog32Sig;
|
||||
unsigned data32Sig;
|
||||
unsigned lateabtSig;
|
||||
ARMword Vector; /* synthesize aborts in cycle modes */
|
||||
ARMword Aborted; /* sticky flag for aborts */
|
||||
ARMword Reseted; /* sticky flag for Reset */
|
||||
ARMword Inted, LastInted; /* sticky flags for interrupts */
|
||||
ARMword Base; /* extra hand for base writeback */
|
||||
ARMword AbortAddr; /* to keep track of Prefetch aborts */
|
||||
|
||||
const struct Dbg_HostosInterface *hostif;
|
||||
const struct Dbg_HostosInterface *hostif;
|
||||
|
||||
int verbose; /* non-zero means print various messages like the banner */
|
||||
} ;
|
||||
int verbose; /* non-zero means print various messages like the banner */
|
||||
};
|
||||
|
||||
#define ResetPin NresetSig
|
||||
#define FIQPin NfiqSig
|
||||
@@ -135,21 +139,21 @@ struct ARMul_State {
|
||||
/***************************************************************************\
|
||||
* Types of ARM we know about *
|
||||
\***************************************************************************/
|
||||
|
||||
|
||||
/* The bitflags */
|
||||
#define ARM_Fix26_Prop 0x01
|
||||
#define ARM_Nexec_Prop 0x02
|
||||
#define ARM_Debug_Prop 0x10
|
||||
#define ARM_Isync_Prop ARM_Debug_Prop
|
||||
#define ARM_Lock_Prop 0x20
|
||||
|
||||
|
||||
/* ARM2 family */
|
||||
#define ARM2 (ARM_Fix26_Prop)
|
||||
#define ARM2as ARM2
|
||||
#define ARM61 ARM2
|
||||
#define ARM3 ARM2
|
||||
|
||||
#ifdef ARM60 /* previous definition in armopts.h */
|
||||
#ifdef ARM60 /* previous definition in armopts.h */
|
||||
#undef ARM60
|
||||
#endif
|
||||
|
||||
@@ -159,15 +163,15 @@ struct ARMul_State {
|
||||
#define ARM600 ARM6
|
||||
#define ARM610 ARM6
|
||||
#define ARM620 ARM6
|
||||
|
||||
|
||||
|
||||
/***************************************************************************\
|
||||
* Macros to extract instruction fields *
|
||||
\***************************************************************************/
|
||||
|
||||
#define BIT(n) ( (ARMword)(instr>>(n))&1) /* bit n of instruction */
|
||||
#define BITS(m,n) ( (ARMword)(instr<<(31-(n))) >> ((31-(n))+(m)) ) /* bits m to n of instr */
|
||||
#define TOPBITS(n) (instr >> (n)) /* bits 31 to n of instr */
|
||||
#define BIT(n) ( (ARMword)(instr>>(n))&1) /* bit n of instruction */
|
||||
#define BITS(m,n) ( (ARMword)(instr<<(31-(n))) >> ((31-(n))+(m)) ) /* bits m to n of instr */
|
||||
#define TOPBITS(n) (instr >> (n)) /* bits 31 to n of instr */
|
||||
|
||||
/***************************************************************************\
|
||||
* The hardware vector addresses *
|
||||
@@ -181,7 +185,7 @@ struct ARMul_State {
|
||||
#define ARMAddrExceptnV 20L
|
||||
#define ARMIRQV 24L
|
||||
#define ARMFIQV 28L
|
||||
#define ARMErrorV 32L /* This is an offset, not an address ! */
|
||||
#define ARMErrorV 32L /* This is an offset, not an address ! */
|
||||
|
||||
#define ARMul_ResetV ARMResetV
|
||||
#define ARMul_UndefinedInstrV ARMUndefinedInstrV
|
||||
@@ -226,43 +230,46 @@ struct ARMul_State {
|
||||
* Definitons of things in the emulator *
|
||||
\***************************************************************************/
|
||||
|
||||
extern void ARMul_EmulateInit(void) ;
|
||||
extern ARMul_State *ARMul_NewState(void) ;
|
||||
extern void ARMul_Reset(ARMul_State *state) ;
|
||||
extern ARMword ARMul_DoProg(ARMul_State *state) ;
|
||||
extern ARMword ARMul_DoInstr(ARMul_State *state) ;
|
||||
extern void ARMul_EmulateInit (void);
|
||||
extern ARMul_State *ARMul_NewState (void);
|
||||
extern void ARMul_Reset (ARMul_State * state);
|
||||
extern ARMword ARMul_DoProg (ARMul_State * state);
|
||||
extern ARMword ARMul_DoInstr (ARMul_State * state);
|
||||
|
||||
/***************************************************************************\
|
||||
* Definitons of things for event handling *
|
||||
\***************************************************************************/
|
||||
|
||||
extern void ARMul_ScheduleEvent(ARMul_State *state, unsigned long delay, unsigned (*func)() ) ;
|
||||
extern void ARMul_EnvokeEvent(ARMul_State *state) ;
|
||||
extern unsigned long ARMul_Time(ARMul_State *state) ;
|
||||
extern void ARMul_ScheduleEvent (ARMul_State * state, unsigned long delay,
|
||||
unsigned (*func) ());
|
||||
extern void ARMul_EnvokeEvent (ARMul_State * state);
|
||||
extern unsigned long ARMul_Time (ARMul_State * state);
|
||||
|
||||
/***************************************************************************\
|
||||
* Useful support routines *
|
||||
\***************************************************************************/
|
||||
|
||||
extern ARMword ARMul_GetReg(ARMul_State *state, unsigned mode, unsigned reg) ;
|
||||
extern void ARMul_SetReg(ARMul_State *state, unsigned mode, unsigned reg, ARMword value) ;
|
||||
extern ARMword ARMul_GetPC(ARMul_State *state) ;
|
||||
extern ARMword ARMul_GetNextPC(ARMul_State *state) ;
|
||||
extern void ARMul_SetPC(ARMul_State *state, ARMword value) ;
|
||||
extern ARMword ARMul_GetR15(ARMul_State *state) ;
|
||||
extern void ARMul_SetR15(ARMul_State *state, ARMword value) ;
|
||||
extern ARMword ARMul_GetReg (ARMul_State * state, unsigned mode,
|
||||
unsigned reg);
|
||||
extern void ARMul_SetReg (ARMul_State * state, unsigned mode, unsigned reg,
|
||||
ARMword value);
|
||||
extern ARMword ARMul_GetPC (ARMul_State * state);
|
||||
extern ARMword ARMul_GetNextPC (ARMul_State * state);
|
||||
extern void ARMul_SetPC (ARMul_State * state, ARMword value);
|
||||
extern ARMword ARMul_GetR15 (ARMul_State * state);
|
||||
extern void ARMul_SetR15 (ARMul_State * state, ARMword value);
|
||||
|
||||
extern ARMword ARMul_GetCPSR(ARMul_State *state) ;
|
||||
extern void ARMul_SetCPSR(ARMul_State *state, ARMword value) ;
|
||||
extern ARMword ARMul_GetSPSR(ARMul_State *state, ARMword mode) ;
|
||||
extern void ARMul_SetSPSR(ARMul_State *state, ARMword mode, ARMword value) ;
|
||||
extern ARMword ARMul_GetCPSR (ARMul_State * state);
|
||||
extern void ARMul_SetCPSR (ARMul_State * state, ARMword value);
|
||||
extern ARMword ARMul_GetSPSR (ARMul_State * state, ARMword mode);
|
||||
extern void ARMul_SetSPSR (ARMul_State * state, ARMword mode, ARMword value);
|
||||
|
||||
/***************************************************************************\
|
||||
* Definitons of things to handle aborts *
|
||||
\***************************************************************************/
|
||||
|
||||
extern void ARMul_Abort(ARMul_State *state, ARMword address) ;
|
||||
#define ARMul_ABORTWORD 0xefffffff /* SWI -1 */
|
||||
extern void ARMul_Abort (ARMul_State * state, ARMword address);
|
||||
#define ARMul_ABORTWORD 0xefffffff /* SWI -1 */
|
||||
#define ARMul_PREFETCHABORT(address) if (state->AbortAddr == 1) \
|
||||
state->AbortAddr = (address & ~3L)
|
||||
#define ARMul_DATAABORT(address) state->abortSig = HIGH ; \
|
||||
@@ -273,36 +280,51 @@ extern void ARMul_Abort(ARMul_State *state, ARMword address) ;
|
||||
* Definitons of things in the memory interface *
|
||||
\***************************************************************************/
|
||||
|
||||
extern unsigned ARMul_MemoryInit(ARMul_State *state,unsigned long initmemsize) ;
|
||||
extern void ARMul_MemoryExit(ARMul_State *state) ;
|
||||
extern unsigned ARMul_MemoryInit (ARMul_State * state,
|
||||
unsigned long initmemsize);
|
||||
extern void ARMul_MemoryExit (ARMul_State * state);
|
||||
|
||||
extern ARMword ARMul_LoadInstrS(ARMul_State *state,ARMword address,ARMword isize) ;
|
||||
extern ARMword ARMul_LoadInstrN(ARMul_State *state,ARMword address,ARMword isize) ;
|
||||
extern ARMword ARMul_ReLoadInstr(ARMul_State *state,ARMword address,ARMword isize) ;
|
||||
extern ARMword ARMul_LoadInstrS (ARMul_State * state, ARMword address,
|
||||
ARMword isize);
|
||||
extern ARMword ARMul_LoadInstrN (ARMul_State * state, ARMword address,
|
||||
ARMword isize);
|
||||
extern ARMword ARMul_ReLoadInstr (ARMul_State * state, ARMword address,
|
||||
ARMword isize);
|
||||
|
||||
extern ARMword ARMul_LoadWordS(ARMul_State *state,ARMword address) ;
|
||||
extern ARMword ARMul_LoadWordN(ARMul_State *state,ARMword address) ;
|
||||
extern ARMword ARMul_LoadHalfWord(ARMul_State *state,ARMword address) ;
|
||||
extern ARMword ARMul_LoadByte(ARMul_State *state,ARMword address) ;
|
||||
extern ARMword ARMul_LoadWordS (ARMul_State * state, ARMword address);
|
||||
extern ARMword ARMul_LoadWordN (ARMul_State * state, ARMword address);
|
||||
extern ARMword ARMul_LoadHalfWord (ARMul_State * state, ARMword address);
|
||||
extern ARMword ARMul_LoadByte (ARMul_State * state, ARMword address);
|
||||
|
||||
extern void ARMul_StoreWordS(ARMul_State *state,ARMword address, ARMword data) ;
|
||||
extern void ARMul_StoreWordN(ARMul_State *state,ARMword address, ARMword data) ;
|
||||
extern void ARMul_StoreHalfWord(ARMul_State *state,ARMword address, ARMword data) ;
|
||||
extern void ARMul_StoreByte(ARMul_State *state,ARMword address, ARMword data) ;
|
||||
extern void ARMul_StoreWordS (ARMul_State * state, ARMword address,
|
||||
ARMword data);
|
||||
extern void ARMul_StoreWordN (ARMul_State * state, ARMword address,
|
||||
ARMword data);
|
||||
extern void ARMul_StoreHalfWord (ARMul_State * state, ARMword address,
|
||||
ARMword data);
|
||||
extern void ARMul_StoreByte (ARMul_State * state, ARMword address,
|
||||
ARMword data);
|
||||
|
||||
extern ARMword ARMul_SwapWord(ARMul_State *state,ARMword address, ARMword data) ;
|
||||
extern ARMword ARMul_SwapByte(ARMul_State *state,ARMword address, ARMword data) ;
|
||||
extern ARMword ARMul_SwapWord (ARMul_State * state, ARMword address,
|
||||
ARMword data);
|
||||
extern ARMword ARMul_SwapByte (ARMul_State * state, ARMword address,
|
||||
ARMword data);
|
||||
|
||||
extern void ARMul_Icycles(ARMul_State *state,unsigned number, ARMword address) ;
|
||||
extern void ARMul_Ccycles(ARMul_State *state,unsigned number, ARMword address) ;
|
||||
extern void ARMul_Icycles (ARMul_State * state, unsigned number,
|
||||
ARMword address);
|
||||
extern void ARMul_Ccycles (ARMul_State * state, unsigned number,
|
||||
ARMword address);
|
||||
|
||||
extern ARMword ARMul_ReadWord(ARMul_State *state,ARMword address) ;
|
||||
extern ARMword ARMul_ReadByte(ARMul_State *state,ARMword address) ;
|
||||
extern void ARMul_WriteWord(ARMul_State *state,ARMword address, ARMword data) ;
|
||||
extern void ARMul_WriteByte(ARMul_State *state,ARMword address, ARMword data) ;
|
||||
extern ARMword ARMul_ReadWord (ARMul_State * state, ARMword address);
|
||||
extern ARMword ARMul_ReadByte (ARMul_State * state, ARMword address);
|
||||
extern void ARMul_WriteWord (ARMul_State * state, ARMword address,
|
||||
ARMword data);
|
||||
extern void ARMul_WriteByte (ARMul_State * state, ARMword address,
|
||||
ARMword data);
|
||||
|
||||
extern ARMword ARMul_MemAccess(ARMul_State *state,ARMword,ARMword,ARMword,
|
||||
ARMword,ARMword,ARMword,ARMword,ARMword,ARMword,ARMword) ;
|
||||
extern ARMword ARMul_MemAccess (ARMul_State * state, ARMword, ARMword,
|
||||
ARMword, ARMword, ARMword, ARMword, ARMword,
|
||||
ARMword, ARMword, ARMword);
|
||||
|
||||
/***************************************************************************\
|
||||
* Definitons of things in the co-processor interface *
|
||||
@@ -317,36 +339,36 @@ extern ARMword ARMul_MemAccess(ARMul_State *state,ARMword,ARMword,ARMword,
|
||||
#define ARMul_CANT 1
|
||||
#define ARMul_INC 3
|
||||
|
||||
extern unsigned ARMul_CoProInit(ARMul_State *state) ;
|
||||
extern void ARMul_CoProExit(ARMul_State *state) ;
|
||||
extern void ARMul_CoProAttach(ARMul_State *state, unsigned number,
|
||||
ARMul_CPInits *init, ARMul_CPExits *exit,
|
||||
ARMul_LDCs *ldc, ARMul_STCs *stc,
|
||||
ARMul_MRCs *mrc, ARMul_MCRs *mcr,
|
||||
ARMul_CDPs *cdp,
|
||||
ARMul_CPReads *read, ARMul_CPWrites *write) ;
|
||||
extern void ARMul_CoProDetach(ARMul_State *state, unsigned number) ;
|
||||
extern unsigned ARMul_CoProInit (ARMul_State * state);
|
||||
extern void ARMul_CoProExit (ARMul_State * state);
|
||||
extern void ARMul_CoProAttach (ARMul_State * state, unsigned number,
|
||||
ARMul_CPInits * init, ARMul_CPExits * exit,
|
||||
ARMul_LDCs * ldc, ARMul_STCs * stc,
|
||||
ARMul_MRCs * mrc, ARMul_MCRs * mcr,
|
||||
ARMul_CDPs * cdp,
|
||||
ARMul_CPReads * read, ARMul_CPWrites * write);
|
||||
extern void ARMul_CoProDetach (ARMul_State * state, unsigned number);
|
||||
|
||||
/***************************************************************************\
|
||||
* Definitons of things in the host environment *
|
||||
\***************************************************************************/
|
||||
|
||||
extern unsigned ARMul_OSInit(ARMul_State *state) ;
|
||||
extern void ARMul_OSExit(ARMul_State *state) ;
|
||||
extern unsigned ARMul_OSHandleSWI(ARMul_State *state,ARMword number) ;
|
||||
extern ARMword ARMul_OSLastErrorP(ARMul_State *state) ;
|
||||
extern unsigned ARMul_OSInit (ARMul_State * state);
|
||||
extern void ARMul_OSExit (ARMul_State * state);
|
||||
extern unsigned ARMul_OSHandleSWI (ARMul_State * state, ARMword number);
|
||||
extern ARMword ARMul_OSLastErrorP (ARMul_State * state);
|
||||
|
||||
extern ARMword ARMul_Debug(ARMul_State *state, ARMword pc, ARMword instr) ;
|
||||
extern unsigned ARMul_OSException(ARMul_State *state, ARMword vector, ARMword pc) ;
|
||||
extern int rdi_log ;
|
||||
extern ARMword ARMul_Debug (ARMul_State * state, ARMword pc, ARMword instr);
|
||||
extern unsigned ARMul_OSException (ARMul_State * state, ARMword vector,
|
||||
ARMword pc);
|
||||
extern int rdi_log;
|
||||
|
||||
/***************************************************************************\
|
||||
* Host-dependent stuff *
|
||||
\***************************************************************************/
|
||||
|
||||
#ifdef macintosh
|
||||
pascal void SpinCursor(short increment); /* copied from CursorCtl.h */
|
||||
pascal void SpinCursor (short increment); /* copied from CursorCtl.h */
|
||||
# define HOURGLASS SpinCursor( 1 )
|
||||
# define HOURGLASS_RATE 1023 /* 2^n - 1 */
|
||||
# define HOURGLASS_RATE 1023 /* 2^n - 1 */
|
||||
#endif
|
||||
|
||||
|
||||
5382
sim/arm/armemu.c
5382
sim/arm/armemu.c
File diff suppressed because it is too large
Load Diff
@@ -65,7 +65,7 @@ extern ARMword isize;
|
||||
#define POS(i) ( (~(i)) >> 31 )
|
||||
#define NEG(i) ( (i) >> 31 )
|
||||
|
||||
#ifdef MODET /* Thumb support */
|
||||
#ifdef MODET /* Thumb support */
|
||||
/* ??? This bit is actually in the low order bit of the PC in the hardware.
|
||||
It isn't clear if the simulator needs to model that or not. */
|
||||
#define TBIT (1L << 5)
|
||||
@@ -215,7 +215,7 @@ extern ARMword isize;
|
||||
#define RESUME 8
|
||||
|
||||
#define NORMALCYCLE state->NextInstr = 0
|
||||
#define BUSUSEDN state->NextInstr |= 1 /* the next fetch will be an N cycle */
|
||||
#define BUSUSEDN state->NextInstr |= 1 /* the next fetch will be an N cycle */
|
||||
#define BUSUSEDINCPCS state->Reg[15] += isize ; /* a standard PC inc and an S cycle */ \
|
||||
state->NextInstr = (state->NextInstr & 0xff) | 2
|
||||
#define BUSUSEDINCPCN state->Reg[15] += isize ; /* a standard PC inc and an N cycle */ \
|
||||
@@ -348,53 +348,62 @@ extern ARMword isize;
|
||||
* Values for Emulate *
|
||||
\***************************************************************************/
|
||||
|
||||
#define STOP 0 /* stop */
|
||||
#define CHANGEMODE 1 /* change mode */
|
||||
#define ONCE 2 /* execute just one interation */
|
||||
#define RUN 3 /* continuous execution */
|
||||
#define STOP 0 /* stop */
|
||||
#define CHANGEMODE 1 /* change mode */
|
||||
#define ONCE 2 /* execute just one interation */
|
||||
#define RUN 3 /* continuous execution */
|
||||
|
||||
/***************************************************************************\
|
||||
* Stuff that is shared across modes *
|
||||
\***************************************************************************/
|
||||
|
||||
extern ARMword ARMul_Emulate26(ARMul_State *state) ;
|
||||
extern ARMword ARMul_Emulate32(ARMul_State *state) ;
|
||||
extern unsigned ARMul_MultTable[] ; /* Number of I cycles for a mult */
|
||||
extern ARMword ARMul_ImmedTable[] ; /* immediate DP LHS values */
|
||||
extern char ARMul_BitList[] ; /* number of bits in a byte table */
|
||||
extern void ARMul_Abort26(ARMul_State *state, ARMword) ;
|
||||
extern void ARMul_Abort32(ARMul_State *state, ARMword) ;
|
||||
extern unsigned ARMul_NthReg(ARMword instr,unsigned number) ;
|
||||
extern void ARMul_MSRCpsr(ARMul_State *state, ARMword instr, ARMword rhs) ;
|
||||
extern void ARMul_NegZero(ARMul_State *state, ARMword result) ;
|
||||
extern void ARMul_AddCarry(ARMul_State *state, ARMword a, ARMword b, ARMword result) ;
|
||||
extern int AddOverflow(ARMword a, ARMword b, ARMword result) ;
|
||||
extern int SubOverflow(ARMword a, ARMword b, ARMword result) ;
|
||||
extern void ARMul_AddOverflow(ARMul_State *state, ARMword a, ARMword b, ARMword result) ;
|
||||
extern void ARMul_SubCarry(ARMul_State *state, ARMword a, ARMword b, ARMword result) ;
|
||||
extern void ARMul_SubOverflow(ARMul_State *state, ARMword a, ARMword b, ARMword result) ;
|
||||
extern void ARMul_CPSRAltered(ARMul_State *state) ;
|
||||
extern void ARMul_R15Altered(ARMul_State *state) ;
|
||||
extern ARMword ARMul_SwitchMode(ARMul_State *state,ARMword oldmode, ARMword newmode) ;
|
||||
extern unsigned ARMul_NthReg(ARMword instr, unsigned number) ;
|
||||
extern void ARMul_LDC(ARMul_State *state,ARMword instr,ARMword address) ;
|
||||
extern void ARMul_STC(ARMul_State *state,ARMword instr,ARMword address) ;
|
||||
extern void ARMul_MCR(ARMul_State *state,ARMword instr, ARMword source) ;
|
||||
extern ARMword ARMul_MRC(ARMul_State *state,ARMword instr) ;
|
||||
extern void ARMul_CDP(ARMul_State *state,ARMword instr) ;
|
||||
extern unsigned IntPending(ARMul_State *state) ;
|
||||
extern ARMword ARMul_Align(ARMul_State *state, ARMword address, ARMword data) ;
|
||||
extern ARMword ARMul_Emulate26 (ARMul_State * state);
|
||||
extern ARMword ARMul_Emulate32 (ARMul_State * state);
|
||||
extern unsigned ARMul_MultTable[]; /* Number of I cycles for a mult */
|
||||
extern ARMword ARMul_ImmedTable[]; /* immediate DP LHS values */
|
||||
extern char ARMul_BitList[]; /* number of bits in a byte table */
|
||||
extern void ARMul_Abort26 (ARMul_State * state, ARMword);
|
||||
extern void ARMul_Abort32 (ARMul_State * state, ARMword);
|
||||
extern unsigned ARMul_NthReg (ARMword instr, unsigned number);
|
||||
extern void ARMul_MSRCpsr (ARMul_State * state, ARMword instr, ARMword rhs);
|
||||
extern void ARMul_NegZero (ARMul_State * state, ARMword result);
|
||||
extern void ARMul_AddCarry (ARMul_State * state, ARMword a, ARMword b,
|
||||
ARMword result);
|
||||
extern int AddOverflow (ARMword a, ARMword b, ARMword result);
|
||||
extern int SubOverflow (ARMword a, ARMword b, ARMword result);
|
||||
extern void ARMul_AddOverflow (ARMul_State * state, ARMword a, ARMword b,
|
||||
ARMword result);
|
||||
extern void ARMul_SubCarry (ARMul_State * state, ARMword a, ARMword b,
|
||||
ARMword result);
|
||||
extern void ARMul_SubOverflow (ARMul_State * state, ARMword a, ARMword b,
|
||||
ARMword result);
|
||||
extern void ARMul_CPSRAltered (ARMul_State * state);
|
||||
extern void ARMul_R15Altered (ARMul_State * state);
|
||||
extern ARMword ARMul_SwitchMode (ARMul_State * state, ARMword oldmode,
|
||||
ARMword newmode);
|
||||
extern unsigned ARMul_NthReg (ARMword instr, unsigned number);
|
||||
extern void ARMul_LDC (ARMul_State * state, ARMword instr, ARMword address);
|
||||
extern void ARMul_STC (ARMul_State * state, ARMword instr, ARMword address);
|
||||
extern void ARMul_MCR (ARMul_State * state, ARMword instr, ARMword source);
|
||||
extern ARMword ARMul_MRC (ARMul_State * state, ARMword instr);
|
||||
extern void ARMul_CDP (ARMul_State * state, ARMword instr);
|
||||
extern unsigned IntPending (ARMul_State * state);
|
||||
extern ARMword ARMul_Align (ARMul_State * state, ARMword address,
|
||||
ARMword data);
|
||||
#define EVENTLISTSIZE 1024L
|
||||
|
||||
/* Thumb support: */
|
||||
|
||||
typedef enum {
|
||||
t_undefined, /* undefined Thumb instruction */
|
||||
t_decoded, /* instruction decoded to ARM equivalent */
|
||||
t_branch /* Thumb branch (already processed) */
|
||||
} tdstate;
|
||||
typedef enum
|
||||
{
|
||||
t_undefined, /* undefined Thumb instruction */
|
||||
t_decoded, /* instruction decoded to ARM equivalent */
|
||||
t_branch /* Thumb branch (already processed) */
|
||||
}
|
||||
tdstate;
|
||||
|
||||
extern tdstate ARMul_ThumbDecode(ARMul_State *state,ARMword pc,ARMword tinstr, ARMword *ainstr);
|
||||
extern tdstate ARMul_ThumbDecode (ARMul_State * state, ARMword pc,
|
||||
ARMword tinstr, ARMword * ainstr);
|
||||
|
||||
/***************************************************************************\
|
||||
* Macros to scrutinize instructions *
|
||||
@@ -425,4 +434,3 @@ extern tdstate ARMul_ThumbDecode(ARMul_State *state,ARMword pc,ARMword tinstr, A
|
||||
#define UNDEF_IllegalMode
|
||||
#define UNDEF_Prog32SigChange
|
||||
#define UNDEF_Data32SigChange
|
||||
|
||||
|
||||
2659
sim/arm/armfpe.h
2659
sim/arm/armfpe.h
File diff suppressed because it is too large
Load Diff
@@ -22,115 +22,129 @@
|
||||
* Definitions for the emulator architecture *
|
||||
\***************************************************************************/
|
||||
|
||||
void ARMul_EmulateInit(void) ;
|
||||
ARMul_State *ARMul_NewState(void) ;
|
||||
void ARMul_Reset(ARMul_State *state) ;
|
||||
ARMword ARMul_DoCycle(ARMul_State *state) ;
|
||||
unsigned ARMul_DoCoPro(ARMul_State *state) ;
|
||||
ARMword ARMul_DoProg(ARMul_State *state) ;
|
||||
ARMword ARMul_DoInstr(ARMul_State *state) ;
|
||||
void ARMul_Abort(ARMul_State *state, ARMword address) ;
|
||||
void ARMul_EmulateInit (void);
|
||||
ARMul_State *ARMul_NewState (void);
|
||||
void ARMul_Reset (ARMul_State * state);
|
||||
ARMword ARMul_DoCycle (ARMul_State * state);
|
||||
unsigned ARMul_DoCoPro (ARMul_State * state);
|
||||
ARMword ARMul_DoProg (ARMul_State * state);
|
||||
ARMword ARMul_DoInstr (ARMul_State * state);
|
||||
void ARMul_Abort (ARMul_State * state, ARMword address);
|
||||
|
||||
unsigned ARMul_MultTable[32] = {1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,
|
||||
10,10,11,11,12,12,13,13,14,14,15,15,16,16,16} ;
|
||||
ARMword ARMul_ImmedTable[4096] ; /* immediate DP LHS values */
|
||||
char ARMul_BitList[256] ; /* number of bits in a byte table */
|
||||
unsigned ARMul_MultTable[32] =
|
||||
{ 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9,
|
||||
10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 16
|
||||
};
|
||||
ARMword ARMul_ImmedTable[4096]; /* immediate DP LHS values */
|
||||
char ARMul_BitList[256]; /* number of bits in a byte table */
|
||||
|
||||
/***************************************************************************\
|
||||
* Call this routine once to set up the emulator's tables. *
|
||||
\***************************************************************************/
|
||||
|
||||
void ARMul_EmulateInit(void)
|
||||
{unsigned long i, j ;
|
||||
void
|
||||
ARMul_EmulateInit (void)
|
||||
{
|
||||
unsigned long i, j;
|
||||
|
||||
for (i = 0 ; i < 4096 ; i++) { /* the values of 12 bit dp rhs's */
|
||||
ARMul_ImmedTable[i] = ROTATER(i & 0xffL,(i >> 7L) & 0x1eL) ;
|
||||
for (i = 0; i < 4096; i++)
|
||||
{ /* the values of 12 bit dp rhs's */
|
||||
ARMul_ImmedTable[i] = ROTATER (i & 0xffL, (i >> 7L) & 0x1eL);
|
||||
}
|
||||
|
||||
for (i = 0 ; i < 256 ; ARMul_BitList[i++] = 0 ) ; /* how many bits in LSM */
|
||||
for (j = 1 ; j < 256 ; j <<= 1)
|
||||
for (i = 0 ; i < 256 ; i++)
|
||||
if ((i & j) > 0 )
|
||||
ARMul_BitList[i]++ ;
|
||||
for (i = 0; i < 256; ARMul_BitList[i++] = 0); /* how many bits in LSM */
|
||||
for (j = 1; j < 256; j <<= 1)
|
||||
for (i = 0; i < 256; i++)
|
||||
if ((i & j) > 0)
|
||||
ARMul_BitList[i]++;
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
ARMul_BitList[i] *= 4; /* you always need 4 times these values */
|
||||
|
||||
for (i = 0 ; i < 256 ; i++)
|
||||
ARMul_BitList[i] *= 4 ; /* you always need 4 times these values */
|
||||
|
||||
}
|
||||
|
||||
/***************************************************************************\
|
||||
* Returns a new instantiation of the ARMulator's state *
|
||||
\***************************************************************************/
|
||||
|
||||
ARMul_State *ARMul_NewState(void)
|
||||
{ARMul_State *state ;
|
||||
unsigned i, j ;
|
||||
ARMul_State *
|
||||
ARMul_NewState (void)
|
||||
{
|
||||
ARMul_State *state;
|
||||
unsigned i, j;
|
||||
|
||||
state = (ARMul_State *)malloc(sizeof(ARMul_State)) ;
|
||||
memset (state, 0, sizeof (ARMul_State));
|
||||
state = (ARMul_State *) malloc (sizeof (ARMul_State));
|
||||
memset (state, 0, sizeof (ARMul_State));
|
||||
|
||||
state->Emulate = RUN ;
|
||||
for (i = 0 ; i < 16 ; i++) {
|
||||
state->Reg[i] = 0 ;
|
||||
for (j = 0 ; j < 7 ; j++)
|
||||
state->RegBank[j][i] = 0 ;
|
||||
state->Emulate = RUN;
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
state->Reg[i] = 0;
|
||||
for (j = 0; j < 7; j++)
|
||||
state->RegBank[j][i] = 0;
|
||||
}
|
||||
for (i = 0 ; i < 7 ; i++)
|
||||
state->Spsr[i] = 0 ;
|
||||
state->Mode = 0 ;
|
||||
for (i = 0; i < 7; i++)
|
||||
state->Spsr[i] = 0;
|
||||
state->Mode = 0;
|
||||
|
||||
state->CallDebug = FALSE ;
|
||||
state->Debug = FALSE ;
|
||||
state->VectorCatch = 0 ;
|
||||
state->Aborted = FALSE ;
|
||||
state->Reseted = FALSE ;
|
||||
state->Inted = 3 ;
|
||||
state->LastInted = 3 ;
|
||||
state->CallDebug = FALSE;
|
||||
state->Debug = FALSE;
|
||||
state->VectorCatch = 0;
|
||||
state->Aborted = FALSE;
|
||||
state->Reseted = FALSE;
|
||||
state->Inted = 3;
|
||||
state->LastInted = 3;
|
||||
|
||||
state->MemDataPtr = NULL ;
|
||||
state->MemInPtr = NULL ;
|
||||
state->MemOutPtr = NULL ;
|
||||
state->MemSparePtr = NULL ;
|
||||
state->MemSize = 0 ;
|
||||
state->MemDataPtr = NULL;
|
||||
state->MemInPtr = NULL;
|
||||
state->MemOutPtr = NULL;
|
||||
state->MemSparePtr = NULL;
|
||||
state->MemSize = 0;
|
||||
|
||||
state->OSptr = NULL ;
|
||||
state->CommandLine = NULL ;
|
||||
state->OSptr = NULL;
|
||||
state->CommandLine = NULL;
|
||||
|
||||
state->EventSet = 0 ;
|
||||
state->Now = 0 ;
|
||||
state->EventPtr = (struct EventNode **)malloc((unsigned)EVENTLISTSIZE *
|
||||
sizeof(struct EventNode *)) ;
|
||||
for (i = 0 ; i < EVENTLISTSIZE ; i++)
|
||||
*(state->EventPtr + i) = NULL ;
|
||||
state->EventSet = 0;
|
||||
state->Now = 0;
|
||||
state->EventPtr = (struct EventNode **) malloc ((unsigned) EVENTLISTSIZE *
|
||||
sizeof (struct EventNode
|
||||
*));
|
||||
for (i = 0; i < EVENTLISTSIZE; i++)
|
||||
*(state->EventPtr + i) = NULL;
|
||||
|
||||
#ifdef ARM61
|
||||
state->prog32Sig = LOW ;
|
||||
state->data32Sig = LOW ;
|
||||
state->prog32Sig = LOW;
|
||||
state->data32Sig = LOW;
|
||||
#else
|
||||
state->prog32Sig = HIGH ;
|
||||
state->data32Sig = HIGH ;
|
||||
state->prog32Sig = HIGH;
|
||||
state->data32Sig = HIGH;
|
||||
#endif
|
||||
|
||||
state->lateabtSig = LOW ;
|
||||
state->bigendSig = LOW ;
|
||||
state->lateabtSig = LOW;
|
||||
state->bigendSig = LOW;
|
||||
|
||||
ARMul_Reset(state) ;
|
||||
return(state) ;
|
||||
}
|
||||
ARMul_Reset (state);
|
||||
return (state);
|
||||
}
|
||||
|
||||
/***************************************************************************\
|
||||
* Call this routine to set ARMulator to model a certain processor *
|
||||
\***************************************************************************/
|
||||
|
||||
void ARMul_SelectProcessor(ARMul_State *state, unsigned processor) {
|
||||
if (processor & ARM_Fix26_Prop) {
|
||||
state->prog32Sig = LOW;
|
||||
state->data32Sig = LOW;
|
||||
}else{
|
||||
state->prog32Sig = HIGH;
|
||||
state->data32Sig = HIGH;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ARMul_SelectProcessor (ARMul_State * state, unsigned processor)
|
||||
{
|
||||
if (processor & ARM_Fix26_Prop)
|
||||
{
|
||||
state->prog32Sig = LOW;
|
||||
state->data32Sig = LOW;
|
||||
}
|
||||
else
|
||||
{
|
||||
state->prog32Sig = HIGH;
|
||||
state->data32Sig = HIGH;
|
||||
}
|
||||
|
||||
state->lateabtSig = LOW;
|
||||
}
|
||||
|
||||
@@ -138,41 +152,45 @@ void ARMul_SelectProcessor(ARMul_State *state, unsigned processor) {
|
||||
* Call this routine to set up the initial machine state (or perform a RESET *
|
||||
\***************************************************************************/
|
||||
|
||||
void ARMul_Reset(ARMul_State *state)
|
||||
{state->NextInstr = 0 ;
|
||||
if (state->prog32Sig) {
|
||||
state->Reg[15] = 0 ;
|
||||
state->Cpsr = INTBITS | SVC32MODE ;
|
||||
void
|
||||
ARMul_Reset (ARMul_State * state)
|
||||
{
|
||||
state->NextInstr = 0;
|
||||
if (state->prog32Sig)
|
||||
{
|
||||
state->Reg[15] = 0;
|
||||
state->Cpsr = INTBITS | SVC32MODE;
|
||||
}
|
||||
else {
|
||||
state->Reg[15] = R15INTBITS | SVC26MODE ;
|
||||
state->Cpsr = INTBITS | SVC26MODE ;
|
||||
else
|
||||
{
|
||||
state->Reg[15] = R15INTBITS | SVC26MODE;
|
||||
state->Cpsr = INTBITS | SVC26MODE;
|
||||
}
|
||||
ARMul_CPSRAltered(state) ;
|
||||
state->Bank = SVCBANK ;
|
||||
FLUSHPIPE ;
|
||||
ARMul_CPSRAltered (state);
|
||||
state->Bank = SVCBANK;
|
||||
FLUSHPIPE;
|
||||
|
||||
state->EndCondition = 0 ;
|
||||
state->ErrorCode = 0 ;
|
||||
state->EndCondition = 0;
|
||||
state->ErrorCode = 0;
|
||||
|
||||
state->Exception = FALSE ;
|
||||
state->NresetSig = HIGH ;
|
||||
state->NfiqSig = HIGH ;
|
||||
state->NirqSig = HIGH ;
|
||||
state->NtransSig = (state->Mode & 3)?HIGH:LOW ;
|
||||
state->abortSig = LOW ;
|
||||
state->AbortAddr = 1 ;
|
||||
state->Exception = FALSE;
|
||||
state->NresetSig = HIGH;
|
||||
state->NfiqSig = HIGH;
|
||||
state->NirqSig = HIGH;
|
||||
state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
|
||||
state->abortSig = LOW;
|
||||
state->AbortAddr = 1;
|
||||
|
||||
state->NumInstrs = 0 ;
|
||||
state->NumNcycles = 0 ;
|
||||
state->NumScycles = 0 ;
|
||||
state->NumIcycles = 0 ;
|
||||
state->NumCcycles = 0 ;
|
||||
state->NumFcycles = 0 ;
|
||||
#ifdef ASIM
|
||||
(void)ARMul_MemoryInit() ;
|
||||
ARMul_OSInit(state) ;
|
||||
#endif
|
||||
state->NumInstrs = 0;
|
||||
state->NumNcycles = 0;
|
||||
state->NumScycles = 0;
|
||||
state->NumIcycles = 0;
|
||||
state->NumCcycles = 0;
|
||||
state->NumFcycles = 0;
|
||||
#ifdef ASIM
|
||||
(void) ARMul_MemoryInit ();
|
||||
ARMul_OSInit (state);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -182,19 +200,22 @@ void ARMul_Reset(ARMul_State *state)
|
||||
* address of the last instruction that is executed. *
|
||||
\***************************************************************************/
|
||||
|
||||
ARMword ARMul_DoProg(ARMul_State *state)
|
||||
{ARMword pc = 0 ;
|
||||
ARMword
|
||||
ARMul_DoProg (ARMul_State * state)
|
||||
{
|
||||
ARMword pc = 0;
|
||||
|
||||
state->Emulate = RUN ;
|
||||
while (state->Emulate != STOP) {
|
||||
state->Emulate = RUN ;
|
||||
if (state->prog32Sig && ARMul_MODE32BIT)
|
||||
pc = ARMul_Emulate32(state) ;
|
||||
else
|
||||
pc = ARMul_Emulate26(state) ;
|
||||
state->Emulate = RUN;
|
||||
while (state->Emulate != STOP)
|
||||
{
|
||||
state->Emulate = RUN;
|
||||
if (state->prog32Sig && ARMul_MODE32BIT)
|
||||
pc = ARMul_Emulate32 (state);
|
||||
else
|
||||
pc = ARMul_Emulate26 (state);
|
||||
}
|
||||
return(pc) ;
|
||||
}
|
||||
return (pc);
|
||||
}
|
||||
|
||||
/***************************************************************************\
|
||||
* Emulate the execution of one instruction. Start the correct emulator *
|
||||
@@ -202,17 +223,19 @@ ARMword ARMul_DoProg(ARMul_State *state)
|
||||
* address of the instruction that is executed. *
|
||||
\***************************************************************************/
|
||||
|
||||
ARMword ARMul_DoInstr(ARMul_State *state)
|
||||
{ARMword pc = 0 ;
|
||||
ARMword
|
||||
ARMul_DoInstr (ARMul_State * state)
|
||||
{
|
||||
ARMword pc = 0;
|
||||
|
||||
state->Emulate = ONCE ;
|
||||
if (state->prog32Sig && ARMul_MODE32BIT)
|
||||
pc = ARMul_Emulate32(state) ;
|
||||
else
|
||||
pc = ARMul_Emulate26(state) ;
|
||||
state->Emulate = ONCE;
|
||||
if (state->prog32Sig && ARMul_MODE32BIT)
|
||||
pc = ARMul_Emulate32 (state);
|
||||
else
|
||||
pc = ARMul_Emulate26 (state);
|
||||
|
||||
return(pc) ;
|
||||
}
|
||||
return (pc);
|
||||
}
|
||||
|
||||
/***************************************************************************\
|
||||
* This routine causes an Abort to occur, including selecting the correct *
|
||||
@@ -220,75 +243,78 @@ ARMword ARMul_DoInstr(ARMul_State *state)
|
||||
* appropriate vector's memory address (0,4,8 ....) *
|
||||
\***************************************************************************/
|
||||
|
||||
void ARMul_Abort(ARMul_State *state, ARMword vector)
|
||||
{ARMword temp ;
|
||||
void
|
||||
ARMul_Abort (ARMul_State * state, ARMword vector)
|
||||
{
|
||||
ARMword temp;
|
||||
|
||||
state->Aborted = FALSE ;
|
||||
state->Aborted = FALSE;
|
||||
|
||||
if (ARMul_OSException(state,vector,ARMul_GetPC(state)))
|
||||
return ;
|
||||
if (ARMul_OSException (state, vector, ARMul_GetPC (state)))
|
||||
return;
|
||||
|
||||
if (state->prog32Sig)
|
||||
if (state->prog32Sig)
|
||||
if (ARMul_MODE26BIT)
|
||||
temp = R15PC ;
|
||||
temp = R15PC;
|
||||
else
|
||||
temp = state->Reg[15] ;
|
||||
else
|
||||
temp = R15PC | ECC | ER15INT | EMODE ;
|
||||
temp = state->Reg[15];
|
||||
else
|
||||
temp = R15PC | ECC | ER15INT | EMODE;
|
||||
|
||||
switch (vector) {
|
||||
case ARMul_ResetV : /* RESET */
|
||||
state->Spsr[SVCBANK] = CPSR ;
|
||||
SETABORT(INTBITS,state->prog32Sig?SVC32MODE:SVC26MODE) ;
|
||||
ARMul_CPSRAltered(state) ;
|
||||
state->Reg[14] = temp ;
|
||||
break ;
|
||||
case ARMul_UndefinedInstrV : /* Undefined Instruction */
|
||||
state->Spsr[state->prog32Sig?UNDEFBANK:SVCBANK] = CPSR ;
|
||||
SETABORT(IBIT,state->prog32Sig?UNDEF32MODE:SVC26MODE) ;
|
||||
ARMul_CPSRAltered(state) ;
|
||||
state->Reg[14] = temp - 4 ;
|
||||
break ;
|
||||
case ARMul_SWIV : /* Software Interrupt */
|
||||
state->Spsr[SVCBANK] = CPSR ;
|
||||
SETABORT(IBIT,state->prog32Sig?SVC32MODE:SVC26MODE) ;
|
||||
ARMul_CPSRAltered(state) ;
|
||||
state->Reg[14] = temp - 4 ;
|
||||
break ;
|
||||
case ARMul_PrefetchAbortV : /* Prefetch Abort */
|
||||
state->AbortAddr = 1 ;
|
||||
state->Spsr[state->prog32Sig?ABORTBANK:SVCBANK] = CPSR ;
|
||||
SETABORT(IBIT,state->prog32Sig?ABORT32MODE:SVC26MODE) ;
|
||||
ARMul_CPSRAltered(state) ;
|
||||
state->Reg[14] = temp - 4 ;
|
||||
break ;
|
||||
case ARMul_DataAbortV : /* Data Abort */
|
||||
state->Spsr[state->prog32Sig?ABORTBANK:SVCBANK] = CPSR ;
|
||||
SETABORT(IBIT,state->prog32Sig?ABORT32MODE:SVC26MODE) ;
|
||||
ARMul_CPSRAltered(state) ;
|
||||
state->Reg[14] = temp - 4 ; /* the PC must have been incremented */
|
||||
break ;
|
||||
case ARMul_AddrExceptnV : /* Address Exception */
|
||||
state->Spsr[SVCBANK] = CPSR ;
|
||||
SETABORT(IBIT,SVC26MODE) ;
|
||||
ARMul_CPSRAltered(state) ;
|
||||
state->Reg[14] = temp - 4 ;
|
||||
break ;
|
||||
case ARMul_IRQV : /* IRQ */
|
||||
state->Spsr[IRQBANK] = CPSR ;
|
||||
SETABORT(IBIT,state->prog32Sig?IRQ32MODE:IRQ26MODE) ;
|
||||
ARMul_CPSRAltered(state) ;
|
||||
state->Reg[14] = temp - 4 ;
|
||||
break ;
|
||||
case ARMul_FIQV : /* FIQ */
|
||||
state->Spsr[FIQBANK] = CPSR ;
|
||||
SETABORT(INTBITS,state->prog32Sig?FIQ32MODE:FIQ26MODE) ;
|
||||
ARMul_CPSRAltered(state) ;
|
||||
state->Reg[14] = temp - 4 ;
|
||||
break ;
|
||||
switch (vector)
|
||||
{
|
||||
case ARMul_ResetV: /* RESET */
|
||||
state->Spsr[SVCBANK] = CPSR;
|
||||
SETABORT (INTBITS, state->prog32Sig ? SVC32MODE : SVC26MODE);
|
||||
ARMul_CPSRAltered (state);
|
||||
state->Reg[14] = temp;
|
||||
break;
|
||||
case ARMul_UndefinedInstrV: /* Undefined Instruction */
|
||||
state->Spsr[state->prog32Sig ? UNDEFBANK : SVCBANK] = CPSR;
|
||||
SETABORT (IBIT, state->prog32Sig ? UNDEF32MODE : SVC26MODE);
|
||||
ARMul_CPSRAltered (state);
|
||||
state->Reg[14] = temp - 4;
|
||||
break;
|
||||
case ARMul_SWIV: /* Software Interrupt */
|
||||
state->Spsr[SVCBANK] = CPSR;
|
||||
SETABORT (IBIT, state->prog32Sig ? SVC32MODE : SVC26MODE);
|
||||
ARMul_CPSRAltered (state);
|
||||
state->Reg[14] = temp - 4;
|
||||
break;
|
||||
case ARMul_PrefetchAbortV: /* Prefetch Abort */
|
||||
state->AbortAddr = 1;
|
||||
state->Spsr[state->prog32Sig ? ABORTBANK : SVCBANK] = CPSR;
|
||||
SETABORT (IBIT, state->prog32Sig ? ABORT32MODE : SVC26MODE);
|
||||
ARMul_CPSRAltered (state);
|
||||
state->Reg[14] = temp - 4;
|
||||
break;
|
||||
case ARMul_DataAbortV: /* Data Abort */
|
||||
state->Spsr[state->prog32Sig ? ABORTBANK : SVCBANK] = CPSR;
|
||||
SETABORT (IBIT, state->prog32Sig ? ABORT32MODE : SVC26MODE);
|
||||
ARMul_CPSRAltered (state);
|
||||
state->Reg[14] = temp - 4; /* the PC must have been incremented */
|
||||
break;
|
||||
case ARMul_AddrExceptnV: /* Address Exception */
|
||||
state->Spsr[SVCBANK] = CPSR;
|
||||
SETABORT (IBIT, SVC26MODE);
|
||||
ARMul_CPSRAltered (state);
|
||||
state->Reg[14] = temp - 4;
|
||||
break;
|
||||
case ARMul_IRQV: /* IRQ */
|
||||
state->Spsr[IRQBANK] = CPSR;
|
||||
SETABORT (IBIT, state->prog32Sig ? IRQ32MODE : IRQ26MODE);
|
||||
ARMul_CPSRAltered (state);
|
||||
state->Reg[14] = temp - 4;
|
||||
break;
|
||||
case ARMul_FIQV: /* FIQ */
|
||||
state->Spsr[FIQBANK] = CPSR;
|
||||
SETABORT (INTBITS, state->prog32Sig ? FIQ32MODE : FIQ26MODE);
|
||||
ARMul_CPSRAltered (state);
|
||||
state->Reg[14] = temp - 4;
|
||||
break;
|
||||
}
|
||||
if (ARMul_MODE32BIT)
|
||||
ARMul_SetR15(state,vector) ;
|
||||
else
|
||||
ARMul_SetR15(state,R15CCINTMODE | vector) ;
|
||||
if (ARMul_MODE32BIT)
|
||||
ARMul_SetR15 (state, vector);
|
||||
else
|
||||
ARMul_SetR15 (state, R15CCINTMODE | vector);
|
||||
}
|
||||
|
||||
1381
sim/arm/armos.c
1381
sim/arm/armos.c
File diff suppressed because it is too large
Load Diff
@@ -19,12 +19,12 @@
|
||||
* Define the initial layout of memory *
|
||||
\***************************************************************************/
|
||||
|
||||
#define ADDRSUPERSTACK 0x800L /* supervisor stack space */
|
||||
#define ADDRUSERSTACK 0x80000L /* default user stack start */
|
||||
#define ADDRSOFTVECTORS 0x840L /* soft vectors are here */
|
||||
#define ADDRCMDLINE 0xf00L /* command line is here after a SWI GetEnv */
|
||||
#define ADDRSOFHANDLERS 0xad0L /* address and workspace for installed handlers */
|
||||
#define SOFTVECTORCODE 0xb80L /* default handlers */
|
||||
#define ADDRSUPERSTACK 0x800L /* supervisor stack space */
|
||||
#define ADDRUSERSTACK 0x80000L /* default user stack start */
|
||||
#define ADDRSOFTVECTORS 0x840L /* soft vectors are here */
|
||||
#define ADDRCMDLINE 0xf00L /* command line is here after a SWI GetEnv */
|
||||
#define ADDRSOFHANDLERS 0xad0L /* address and workspace for installed handlers */
|
||||
#define SOFTVECTORCODE 0xb80L /* default handlers */
|
||||
|
||||
/***************************************************************************\
|
||||
* SWI numbers *
|
||||
@@ -56,7 +56,7 @@
|
||||
#define SWI_InstallHandler 0x70
|
||||
#define SWI_GenerateError 0x71
|
||||
|
||||
#define SWI_Breakpoint 0x180000 /* see gdb's tm-arm.h */
|
||||
#define SWI_Breakpoint 0x180000 /* see gdb's tm-arm.h */
|
||||
|
||||
#define AngelSWI_ARM 0x123456
|
||||
#define AngelSWI_Thumb 0xAB
|
||||
@@ -88,8 +88,8 @@
|
||||
|
||||
#define FPESTART 0x2000L
|
||||
#define FPEEND 0x8000L
|
||||
#define FPEOLDVECT FPESTART + 0x100L + 8L * 16L + 4L /* stack + 8 regs + fpsr */
|
||||
#define FPENEWVECT(addr) 0xea000000L + ((addr) >> 2) - 3L /* branch from 4 to 0x2400 */
|
||||
#define FPEOLDVECT FPESTART + 0x100L + 8L * 16L + 4L /* stack + 8 regs + fpsr */
|
||||
#define FPENEWVECT(addr) 0xea000000L + ((addr) >> 2) - 3L /* branch from 4 to 0x2400 */
|
||||
|
||||
extern unsigned long fpecode[] ;
|
||||
extern unsigned long fpesize ;
|
||||
extern unsigned long fpecode[];
|
||||
extern unsigned long fpesize;
|
||||
|
||||
1586
sim/arm/armrdi.c
1586
sim/arm/armrdi.c
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -26,14 +26,14 @@ defined to generate aborts. */
|
||||
#include "armopts.h"
|
||||
#include "armdefs.h"
|
||||
|
||||
#ifdef VALIDATE /* for running the validate suite */
|
||||
#define TUBE 48 * 1024 * 1024 /* write a char on the screen */
|
||||
#ifdef VALIDATE /* for running the validate suite */
|
||||
#define TUBE 48 * 1024 * 1024 /* write a char on the screen */
|
||||
#define ABORTS 1
|
||||
#endif
|
||||
|
||||
#define ABORTS
|
||||
|
||||
#ifdef ABORTS /* the memory system will abort */
|
||||
#ifdef ABORTS /* the memory system will abort */
|
||||
/* For the old test suite Abort between 32 Kbytes and 32 Mbytes
|
||||
For the new test suite Abort between 8 Mbytes and 26 Mbytes */
|
||||
/* #define LOWABORT 32 * 1024
|
||||
@@ -55,29 +55,29 @@ defined to generate aborts. */
|
||||
static ARMword
|
||||
GetWord (ARMul_State * state, ARMword address)
|
||||
{
|
||||
ARMword page;
|
||||
ARMword offset;
|
||||
ARMword ** pagetable;
|
||||
ARMword * pageptr;
|
||||
ARMword page;
|
||||
ARMword offset;
|
||||
ARMword **pagetable;
|
||||
ARMword *pageptr;
|
||||
|
||||
page = address >> PAGEBITS;
|
||||
offset = (address & OFFSETBITS) >> 2;
|
||||
page = address >> PAGEBITS;
|
||||
offset = (address & OFFSETBITS) >> 2;
|
||||
pagetable = (ARMword **) state->MemDataPtr;
|
||||
pageptr = *(pagetable + page);
|
||||
|
||||
pageptr = *(pagetable + page);
|
||||
|
||||
if (pageptr == NULL)
|
||||
{
|
||||
pageptr = (ARMword *) malloc (PAGESIZE);
|
||||
|
||||
|
||||
if (pageptr == NULL)
|
||||
{
|
||||
perror ("ARMulator can't allocate VM page");
|
||||
exit (12);
|
||||
}
|
||||
|
||||
|
||||
*(pagetable + page) = pageptr;
|
||||
}
|
||||
|
||||
|
||||
return *(pageptr + offset);
|
||||
}
|
||||
|
||||
@@ -88,28 +88,28 @@ GetWord (ARMul_State * state, ARMword address)
|
||||
static void
|
||||
PutWord (ARMul_State * state, ARMword address, ARMword data)
|
||||
{
|
||||
ARMword page;
|
||||
ARMword offset;
|
||||
ARMword ** pagetable;
|
||||
ARMword * pageptr;
|
||||
|
||||
page = address >> PAGEBITS;
|
||||
offset = (address & OFFSETBITS) >> 2;
|
||||
pagetable = (ARMword **)state->MemDataPtr;
|
||||
pageptr = *(pagetable + page);
|
||||
|
||||
ARMword page;
|
||||
ARMword offset;
|
||||
ARMword **pagetable;
|
||||
ARMword *pageptr;
|
||||
|
||||
page = address >> PAGEBITS;
|
||||
offset = (address & OFFSETBITS) >> 2;
|
||||
pagetable = (ARMword **) state->MemDataPtr;
|
||||
pageptr = *(pagetable + page);
|
||||
|
||||
if (pageptr == NULL)
|
||||
{
|
||||
pageptr = (ARMword *) malloc (PAGESIZE);
|
||||
if (pageptr == NULL)
|
||||
{
|
||||
perror ("ARMulator can't allocate VM page");
|
||||
exit(13);
|
||||
exit (13);
|
||||
}
|
||||
|
||||
|
||||
*(pagetable + page) = pageptr;
|
||||
}
|
||||
|
||||
|
||||
*(pageptr + offset) = data;
|
||||
}
|
||||
|
||||
@@ -120,25 +120,25 @@ PutWord (ARMul_State * state, ARMword address, ARMword data)
|
||||
unsigned
|
||||
ARMul_MemoryInit (ARMul_State * state, unsigned long initmemsize)
|
||||
{
|
||||
ARMword ** pagetable;
|
||||
unsigned page;
|
||||
ARMword **pagetable;
|
||||
unsigned page;
|
||||
|
||||
if (initmemsize)
|
||||
state->MemSize = initmemsize;
|
||||
|
||||
|
||||
pagetable = (ARMword **) malloc (sizeof (ARMword) * NUMPAGES);
|
||||
|
||||
|
||||
if (pagetable == NULL)
|
||||
return FALSE;
|
||||
|
||||
for (page = 0 ; page < NUMPAGES ; page++)
|
||||
|
||||
for (page = 0; page < NUMPAGES; page++)
|
||||
*(pagetable + page) = NULL;
|
||||
|
||||
state->MemDataPtr = (unsigned char *)pagetable;
|
||||
|
||||
state->MemDataPtr = (unsigned char *) pagetable;
|
||||
|
||||
ARMul_ConsolePrint (state, ", 4 Gb memory");
|
||||
|
||||
return TRUE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/***************************************************************************\
|
||||
@@ -148,18 +148,18 @@ ARMul_MemoryInit (ARMul_State * state, unsigned long initmemsize)
|
||||
void
|
||||
ARMul_MemoryExit (ARMul_State * state)
|
||||
{
|
||||
ARMword page;
|
||||
ARMword ** pagetable;
|
||||
ARMword * pageptr;
|
||||
ARMword page;
|
||||
ARMword **pagetable;
|
||||
ARMword *pageptr;
|
||||
|
||||
pagetable = (ARMword **)state->MemDataPtr;
|
||||
for (page = 0 ; page < NUMPAGES ; page++)
|
||||
pagetable = (ARMword **) state->MemDataPtr;
|
||||
for (page = 0; page < NUMPAGES; page++)
|
||||
{
|
||||
pageptr = *(pagetable + page);
|
||||
if (pageptr != NULL)
|
||||
free ((char *)pageptr);
|
||||
free ((char *) pageptr);
|
||||
}
|
||||
free ((char *)pagetable);
|
||||
free ((char *) pagetable);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -171,28 +171,28 @@ ARMword
|
||||
ARMul_ReLoadInstr (ARMul_State * state, ARMword address, ARMword isize)
|
||||
{
|
||||
#ifdef ABORTS
|
||||
if (address >= LOWABORT && address < HIGHABORT)
|
||||
if (address >= LOWABORT && address < HIGHABORT)
|
||||
{
|
||||
ARMul_PREFETCHABORT (address);
|
||||
return ARMul_ABORTWORD;
|
||||
}
|
||||
else
|
||||
{
|
||||
ARMul_CLEARABORT;
|
||||
}
|
||||
else
|
||||
{
|
||||
ARMul_CLEARABORT;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((isize == 2) && (address & 0x2))
|
||||
{
|
||||
/* We return the next two halfwords: */
|
||||
ARMword lo = GetWord (state, address);
|
||||
ARMword hi = GetWord (state, address + 4);
|
||||
if ((isize == 2) && (address & 0x2))
|
||||
{
|
||||
/* We return the next two halfwords: */
|
||||
ARMword lo = GetWord (state, address);
|
||||
ARMword hi = GetWord (state, address + 4);
|
||||
|
||||
if (state->bigendSig == HIGH)
|
||||
return (lo << 16) | (hi >> 16);
|
||||
else
|
||||
return ((hi & 0xFFFF) << 16) | (lo >> 16);
|
||||
}
|
||||
if (state->bigendSig == HIGH)
|
||||
return (lo << 16) | (hi >> 16);
|
||||
else
|
||||
return ((hi & 0xFFFF) << 16) | (lo >> 16);
|
||||
}
|
||||
|
||||
return GetWord (state, address);
|
||||
}
|
||||
@@ -201,13 +201,12 @@ ARMul_ReLoadInstr (ARMul_State * state, ARMword address, ARMword isize)
|
||||
* Load Instruction, Sequential Cycle *
|
||||
\***************************************************************************/
|
||||
|
||||
ARMword
|
||||
ARMul_LoadInstrS (ARMul_State * state, ARMword address, ARMword isize)
|
||||
ARMword ARMul_LoadInstrS (ARMul_State * state, ARMword address, ARMword isize)
|
||||
{
|
||||
state->NumScycles ++;
|
||||
state->NumScycles++;
|
||||
|
||||
#ifdef HOURGLASS
|
||||
if (( state->NumScycles & HOURGLASS_RATE ) == 0)
|
||||
if ((state->NumScycles & HOURGLASS_RATE) == 0)
|
||||
{
|
||||
HOURGLASS;
|
||||
}
|
||||
@@ -220,10 +219,9 @@ ARMul_LoadInstrS (ARMul_State * state, ARMword address, ARMword isize)
|
||||
* Load Instruction, Non Sequential Cycle *
|
||||
\***************************************************************************/
|
||||
|
||||
ARMword
|
||||
ARMul_LoadInstrN (ARMul_State * state, ARMword address, ARMword isize)
|
||||
ARMword ARMul_LoadInstrN (ARMul_State * state, ARMword address, ARMword isize)
|
||||
{
|
||||
state->NumNcycles ++;
|
||||
state->NumNcycles++;
|
||||
|
||||
return ARMul_ReLoadInstr (state, address, isize);
|
||||
}
|
||||
@@ -232,8 +230,7 @@ ARMul_LoadInstrN (ARMul_State * state, ARMword address, ARMword isize)
|
||||
* Read Word (but don't tell anyone!) *
|
||||
\***************************************************************************/
|
||||
|
||||
ARMword
|
||||
ARMul_ReadWord (ARMul_State * state, ARMword address)
|
||||
ARMword ARMul_ReadWord (ARMul_State * state, ARMword address)
|
||||
{
|
||||
#ifdef ABORTS
|
||||
if (address >= LOWABORT && address < HIGHABORT)
|
||||
@@ -254,10 +251,9 @@ ARMul_ReadWord (ARMul_State * state, ARMword address)
|
||||
* Load Word, Sequential Cycle *
|
||||
\***************************************************************************/
|
||||
|
||||
ARMword
|
||||
ARMul_LoadWordS (ARMul_State * state, ARMword address)
|
||||
ARMword ARMul_LoadWordS (ARMul_State * state, ARMword address)
|
||||
{
|
||||
state->NumScycles ++;
|
||||
state->NumScycles++;
|
||||
|
||||
return ARMul_ReadWord (state, address);
|
||||
}
|
||||
@@ -266,11 +262,10 @@ ARMul_LoadWordS (ARMul_State * state, ARMword address)
|
||||
* Load Word, Non Sequential Cycle *
|
||||
\***************************************************************************/
|
||||
|
||||
ARMword
|
||||
ARMul_LoadWordN (ARMul_State * state, ARMword address)
|
||||
ARMword ARMul_LoadWordN (ARMul_State * state, ARMword address)
|
||||
{
|
||||
state->NumNcycles ++;
|
||||
|
||||
state->NumNcycles++;
|
||||
|
||||
return ARMul_ReadWord (state, address);
|
||||
}
|
||||
|
||||
@@ -278,15 +273,14 @@ ARMul_LoadWordN (ARMul_State * state, ARMword address)
|
||||
* Load Halfword, (Non Sequential Cycle) *
|
||||
\***************************************************************************/
|
||||
|
||||
ARMword
|
||||
ARMul_LoadHalfWord (ARMul_State * state, ARMword address)
|
||||
ARMword ARMul_LoadHalfWord (ARMul_State * state, ARMword address)
|
||||
{
|
||||
ARMword temp, offset;
|
||||
|
||||
state->NumNcycles ++;
|
||||
state->NumNcycles++;
|
||||
|
||||
temp = ARMul_ReadWord (state, address);
|
||||
offset = (((ARMword)state->bigendSig * 2) ^ (address & 2)) << 3; /* bit offset into the word */
|
||||
temp = ARMul_ReadWord (state, address);
|
||||
offset = (((ARMword) state->bigendSig * 2) ^ (address & 2)) << 3; /* bit offset into the word */
|
||||
|
||||
return (temp >> offset) & 0xffff;
|
||||
}
|
||||
@@ -295,25 +289,23 @@ ARMul_LoadHalfWord (ARMul_State * state, ARMword address)
|
||||
* Read Byte (but don't tell anyone!) *
|
||||
\***************************************************************************/
|
||||
|
||||
ARMword
|
||||
ARMul_ReadByte (ARMul_State * state, ARMword address)
|
||||
ARMword ARMul_ReadByte (ARMul_State * state, ARMword address)
|
||||
{
|
||||
ARMword temp, offset;
|
||||
|
||||
temp = ARMul_ReadWord (state, address);
|
||||
offset = (((ARMword)state->bigendSig * 3) ^ (address & 3)) << 3; /* bit offset into the word */
|
||||
temp = ARMul_ReadWord (state, address);
|
||||
offset = (((ARMword) state->bigendSig * 3) ^ (address & 3)) << 3; /* bit offset into the word */
|
||||
|
||||
return (temp >> offset & 0xffL);
|
||||
return (temp >> offset & 0xffL);
|
||||
}
|
||||
|
||||
/***************************************************************************\
|
||||
* Load Byte, (Non Sequential Cycle) *
|
||||
\***************************************************************************/
|
||||
|
||||
ARMword
|
||||
ARMul_LoadByte (ARMul_State * state, ARMword address)
|
||||
ARMword ARMul_LoadByte (ARMul_State * state, ARMword address)
|
||||
{
|
||||
state->NumNcycles ++;
|
||||
state->NumNcycles++;
|
||||
|
||||
return ARMul_ReadByte (state, address);
|
||||
}
|
||||
@@ -347,7 +339,7 @@ ARMul_WriteWord (ARMul_State * state, ARMword address, ARMword data)
|
||||
void
|
||||
ARMul_StoreWordS (ARMul_State * state, ARMword address, ARMword data)
|
||||
{
|
||||
state->NumScycles ++;
|
||||
state->NumScycles++;
|
||||
|
||||
ARMul_WriteWord (state, address, data);
|
||||
}
|
||||
@@ -359,7 +351,7 @@ ARMul_StoreWordS (ARMul_State * state, ARMword address, ARMword data)
|
||||
void
|
||||
ARMul_StoreWordN (ARMul_State * state, ARMword address, ARMword data)
|
||||
{
|
||||
state->NumNcycles ++;
|
||||
state->NumNcycles++;
|
||||
|
||||
ARMul_WriteWord (state, address, data);
|
||||
}
|
||||
@@ -373,23 +365,24 @@ ARMul_StoreHalfWord (ARMul_State * state, ARMword address, ARMword data)
|
||||
{
|
||||
ARMword temp, offset;
|
||||
|
||||
state->NumNcycles ++;
|
||||
|
||||
state->NumNcycles++;
|
||||
|
||||
#ifdef VALIDATE
|
||||
if (address == TUBE)
|
||||
{
|
||||
if (data == 4)
|
||||
state->Emulate = FALSE;
|
||||
else
|
||||
(void) putc ((char)data, stderr); /* Write Char */
|
||||
(void) putc ((char) data, stderr); /* Write Char */
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
temp = ARMul_ReadWord (state, address);
|
||||
offset = (((ARMword)state->bigendSig * 2) ^ (address & 2)) << 3; /* bit offset into the word */
|
||||
|
||||
PutWord (state, address, (temp & ~(0xffffL << offset)) | ((data & 0xffffL) << offset));
|
||||
temp = ARMul_ReadWord (state, address);
|
||||
offset = (((ARMword) state->bigendSig * 2) ^ (address & 2)) << 3; /* bit offset into the word */
|
||||
|
||||
PutWord (state, address,
|
||||
(temp & ~(0xffffL << offset)) | ((data & 0xffffL) << offset));
|
||||
}
|
||||
|
||||
/***************************************************************************\
|
||||
@@ -401,10 +394,11 @@ ARMul_WriteByte (ARMul_State * state, ARMword address, ARMword data)
|
||||
{
|
||||
ARMword temp, offset;
|
||||
|
||||
temp = ARMul_ReadWord (state, address);
|
||||
offset = (((ARMword)state->bigendSig * 3) ^ (address & 3)) << 3; /* bit offset into the word */
|
||||
|
||||
PutWord (state, address, (temp & ~(0xffL << offset)) | ((data & 0xffL) << offset));
|
||||
temp = ARMul_ReadWord (state, address);
|
||||
offset = (((ARMword) state->bigendSig * 3) ^ (address & 3)) << 3; /* bit offset into the word */
|
||||
|
||||
PutWord (state, address,
|
||||
(temp & ~(0xffL << offset)) | ((data & 0xffL) << offset));
|
||||
}
|
||||
|
||||
/***************************************************************************\
|
||||
@@ -414,7 +408,7 @@ ARMul_WriteByte (ARMul_State * state, ARMword address, ARMword data)
|
||||
void
|
||||
ARMul_StoreByte (ARMul_State * state, ARMword address, ARMword data)
|
||||
{
|
||||
state->NumNcycles ++;
|
||||
state->NumNcycles++;
|
||||
|
||||
#ifdef VALIDATE
|
||||
if (address == TUBE)
|
||||
@@ -422,7 +416,7 @@ ARMul_StoreByte (ARMul_State * state, ARMword address, ARMword data)
|
||||
if (data == 4)
|
||||
state->Emulate = FALSE;
|
||||
else
|
||||
(void) putc ((char)data,stderr); /* Write Char */
|
||||
(void) putc ((char) data, stderr); /* Write Char */
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
@@ -434,19 +428,18 @@ ARMul_StoreByte (ARMul_State * state, ARMword address, ARMword data)
|
||||
* Swap Word, (Two Non Sequential Cycles) *
|
||||
\***************************************************************************/
|
||||
|
||||
ARMword
|
||||
ARMul_SwapWord (ARMul_State * state, ARMword address, ARMword data)
|
||||
ARMword ARMul_SwapWord (ARMul_State * state, ARMword address, ARMword data)
|
||||
{
|
||||
ARMword temp;
|
||||
|
||||
state->NumNcycles ++;
|
||||
state->NumNcycles++;
|
||||
|
||||
temp = ARMul_ReadWord (state, address);
|
||||
|
||||
state->NumNcycles ++;
|
||||
|
||||
|
||||
state->NumNcycles++;
|
||||
|
||||
PutWord (state, address, data);
|
||||
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
@@ -454,14 +447,13 @@ ARMul_SwapWord (ARMul_State * state, ARMword address, ARMword data)
|
||||
* Swap Byte, (Two Non Sequential Cycles) *
|
||||
\***************************************************************************/
|
||||
|
||||
ARMword
|
||||
ARMul_SwapByte (ARMul_State * state, ARMword address, ARMword data)
|
||||
ARMword ARMul_SwapByte (ARMul_State * state, ARMword address, ARMword data)
|
||||
{
|
||||
ARMword temp;
|
||||
|
||||
temp = ARMul_LoadByte (state, address);
|
||||
ARMul_StoreByte (state, address, data);
|
||||
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
@@ -486,6 +478,3 @@ ARMul_Ccycles (ARMul_State * state, unsigned number, ARMword address)
|
||||
state->NumCcycles += number;
|
||||
ARMul_CLEARABORT;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
150
sim/arm/bag.c
150
sim/arm/bag.c
@@ -29,113 +29,137 @@
|
||||
#define HASH_TABLE_SIZE 256
|
||||
#define hash(x) (((x)&0xff)^(((x)>>8)&0xff)^(((x)>>16)&0xff)^(((x)>>24)&0xff))
|
||||
|
||||
typedef struct hashentry {
|
||||
typedef struct hashentry
|
||||
{
|
||||
struct hashentry *next;
|
||||
int first;
|
||||
int second;
|
||||
} Hashentry;
|
||||
}
|
||||
Hashentry;
|
||||
|
||||
Hashentry *lookupbyfirst[HASH_TABLE_SIZE];
|
||||
Hashentry *lookupbysecond[HASH_TABLE_SIZE];
|
||||
|
||||
void addtolist(Hashentry **add, long first, long second) {
|
||||
while (*add) add = &((*add)->next);
|
||||
void
|
||||
addtolist (Hashentry ** add, long first, long second)
|
||||
{
|
||||
while (*add)
|
||||
add = &((*add)->next);
|
||||
/* Malloc will never fail? :o( */
|
||||
(*add) = (Hashentry *) malloc(sizeof(Hashentry));
|
||||
(*add) = (Hashentry *) malloc (sizeof (Hashentry));
|
||||
(*add)->next = (Hashentry *) 0;
|
||||
(*add)->first = first;
|
||||
(*add)->second = second;
|
||||
}
|
||||
|
||||
void killwholelist(Hashentry *p) {
|
||||
void
|
||||
killwholelist (Hashentry * p)
|
||||
{
|
||||
Hashentry *q;
|
||||
|
||||
while (p) {
|
||||
q = p;
|
||||
p = p->next;
|
||||
free(q);
|
||||
}
|
||||
}
|
||||
|
||||
void removefromlist(Hashentry **p, long first, long second) {
|
||||
Hashentry *q;
|
||||
|
||||
while (*p) {
|
||||
if ((*p)->first == first) {
|
||||
q = (*p)->next;
|
||||
free(*p);
|
||||
*p = q;
|
||||
return;
|
||||
while (p)
|
||||
{
|
||||
q = p;
|
||||
p = p->next;
|
||||
free (q);
|
||||
}
|
||||
p = &((*p)->next);
|
||||
}
|
||||
}
|
||||
|
||||
void BAG_putpair(long first, long second) {
|
||||
void
|
||||
removefromlist (Hashentry ** p, long first, long second)
|
||||
{
|
||||
Hashentry *q;
|
||||
|
||||
while (*p)
|
||||
{
|
||||
if ((*p)->first == first)
|
||||
{
|
||||
q = (*p)->next;
|
||||
free (*p);
|
||||
*p = q;
|
||||
return;
|
||||
}
|
||||
p = &((*p)->next);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
BAG_putpair (long first, long second)
|
||||
{
|
||||
long junk;
|
||||
|
||||
if (BAG_getfirst(&junk, second) != NO_SUCH_PAIR)
|
||||
BAG_killpair_bysecond(second);
|
||||
addtolist(&lookupbyfirst[hash(first)], first, second);
|
||||
addtolist(&lookupbysecond[hash(second)], first, second);
|
||||
if (BAG_getfirst (&junk, second) != NO_SUCH_PAIR)
|
||||
BAG_killpair_bysecond (second);
|
||||
addtolist (&lookupbyfirst[hash (first)], first, second);
|
||||
addtolist (&lookupbysecond[hash (second)], first, second);
|
||||
}
|
||||
|
||||
Bag_error BAG_getfirst(long *first, long second) {
|
||||
Bag_error
|
||||
BAG_getfirst (long *first, long second)
|
||||
{
|
||||
Hashentry *look;
|
||||
|
||||
look = lookupbysecond[hash(second)];
|
||||
while(look) if (look->second == second) {
|
||||
*first = look->first;
|
||||
return NO_ERROR;
|
||||
}
|
||||
look = lookupbysecond[hash (second)];
|
||||
while (look)
|
||||
if (look->second == second)
|
||||
{
|
||||
*first = look->first;
|
||||
return NO_ERROR;
|
||||
}
|
||||
return NO_SUCH_PAIR;
|
||||
}
|
||||
|
||||
Bag_error BAG_getsecond(long first, long *second) {
|
||||
Bag_error
|
||||
BAG_getsecond (long first, long *second)
|
||||
{
|
||||
Hashentry *look;
|
||||
|
||||
look = lookupbyfirst[hash(first)];
|
||||
while(look) {
|
||||
if (look->first == first) {
|
||||
*second = look->second;
|
||||
return NO_ERROR;
|
||||
look = lookupbyfirst[hash (first)];
|
||||
while (look)
|
||||
{
|
||||
if (look->first == first)
|
||||
{
|
||||
*second = look->second;
|
||||
return NO_ERROR;
|
||||
}
|
||||
look = look->next;
|
||||
}
|
||||
look = look->next;
|
||||
}
|
||||
return NO_SUCH_PAIR;
|
||||
}
|
||||
|
||||
Bag_error BAG_killpair_byfirst(long first) {
|
||||
Bag_error
|
||||
BAG_killpair_byfirst (long first)
|
||||
{
|
||||
long second;
|
||||
|
||||
if (BAG_getsecond(first, &second) == NO_SUCH_PAIR)
|
||||
if (BAG_getsecond (first, &second) == NO_SUCH_PAIR)
|
||||
return NO_SUCH_PAIR;
|
||||
removefromlist(&lookupbyfirst[hash(first)], first, second);
|
||||
removefromlist(&lookupbysecond[hash(second)], first, second);
|
||||
removefromlist (&lookupbyfirst[hash (first)], first, second);
|
||||
removefromlist (&lookupbysecond[hash (second)], first, second);
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
Bag_error BAG_killpair_bysecond(long second) {
|
||||
Bag_error
|
||||
BAG_killpair_bysecond (long second)
|
||||
{
|
||||
long first;
|
||||
|
||||
if (BAG_getfirst(&first, second) == NO_SUCH_PAIR)
|
||||
|
||||
if (BAG_getfirst (&first, second) == NO_SUCH_PAIR)
|
||||
return NO_SUCH_PAIR;
|
||||
removefromlist(&lookupbyfirst[hash(first)], first, second);
|
||||
removefromlist(&lookupbysecond[hash(second)], first, second);
|
||||
removefromlist (&lookupbyfirst[hash (first)], first, second);
|
||||
removefromlist (&lookupbysecond[hash (second)], first, second);
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
void BAG_newbag() {
|
||||
void
|
||||
BAG_newbag ()
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
killwholelist(lookupbyfirst[i]);
|
||||
killwholelist(lookupbysecond[i]);
|
||||
lookupbyfirst[i] = lookupbysecond[i] = (Hashentry *) 0;
|
||||
}
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
killwholelist (lookupbyfirst[i]);
|
||||
killwholelist (lookupbysecond[i]);
|
||||
lookupbyfirst[i] = lookupbysecond[i] = (Hashentry *) 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -25,18 +25,19 @@
|
||||
/* is deleted. */
|
||||
/********************************************************************/
|
||||
|
||||
typedef enum {
|
||||
typedef enum
|
||||
{
|
||||
NO_ERROR,
|
||||
DELETED_OLD_PAIR,
|
||||
NO_SUCH_PAIR,
|
||||
} Bag_error;
|
||||
}
|
||||
Bag_error;
|
||||
|
||||
void BAG_putpair(long first, long second);
|
||||
void BAG_putpair (long first, long second);
|
||||
|
||||
void BAG_newbag(void);
|
||||
Bag_error BAG_killpair_byfirst(long first);
|
||||
Bag_error BAG_killpair_bysecond(long second);
|
||||
|
||||
Bag_error BAG_getfirst(long *first, long second);
|
||||
Bag_error BAG_getsecond(long first, long *second);
|
||||
void BAG_newbag (void);
|
||||
Bag_error BAG_killpair_byfirst (long first);
|
||||
Bag_error BAG_killpair_bysecond (long second);
|
||||
|
||||
Bag_error BAG_getfirst (long *first, long second);
|
||||
Bag_error BAG_getsecond (long first, long *second);
|
||||
|
||||
@@ -45,57 +45,62 @@ extern int sockethandle;
|
||||
/* It waits 15 seconds until there is a character available: if */
|
||||
/* no character is available, then it timeouts and returns -1. */
|
||||
/****************************************************************/
|
||||
int MYread_char(int sock, unsigned char *c) {
|
||||
int
|
||||
MYread_char (int sock, unsigned char *c)
|
||||
{
|
||||
int i;
|
||||
fd_set readfds;
|
||||
struct timeval timeout= {15, 0};
|
||||
struct timeval timeout = { 15, 0 };
|
||||
struct sockaddr_in isa;
|
||||
|
||||
retry:
|
||||
retry:
|
||||
|
||||
FD_ZERO(&readfds);
|
||||
FD_SET(sock, &readfds);
|
||||
|
||||
i = select(nfds, &readfds,
|
||||
(fd_set *) 0,
|
||||
(fd_set *) 0,
|
||||
&timeout);
|
||||
FD_ZERO (&readfds);
|
||||
FD_SET (sock, &readfds);
|
||||
|
||||
if (i < 0) {
|
||||
perror("select");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!i) {
|
||||
fprintf(stderr, "read: Timeout\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((i = read(sock, c, 1)) < 1) {
|
||||
if (!i && sock == debugsock) {
|
||||
fprintf(stderr, "Connection with debugger severed.\n");
|
||||
/* This shouldn't be necessary for a detached armulator, but
|
||||
the armulator cannot be cold started a second time, so
|
||||
this is probably preferable to locking up. */
|
||||
return -1;
|
||||
fprintf(stderr, "Waiting for connection from debugger...");
|
||||
debugsock = accept(sockethandle, &isa, &i);
|
||||
if (debugsock < 0) { /* Now we are in serious trouble... */
|
||||
perror("accept");
|
||||
return -1;
|
||||
}
|
||||
fprintf(stderr, " done.\nConnection Established.\n");
|
||||
sock = debugsock;
|
||||
goto retry;
|
||||
i = select (nfds, &readfds, (fd_set *) 0, (fd_set *) 0, &timeout);
|
||||
|
||||
if (i < 0)
|
||||
{
|
||||
perror ("select");
|
||||
exit (1);
|
||||
}
|
||||
perror("read");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if (!i)
|
||||
{
|
||||
fprintf (stderr, "read: Timeout\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((i = read (sock, c, 1)) < 1)
|
||||
{
|
||||
if (!i && sock == debugsock)
|
||||
{
|
||||
fprintf (stderr, "Connection with debugger severed.\n");
|
||||
/* This shouldn't be necessary for a detached armulator, but
|
||||
the armulator cannot be cold started a second time, so
|
||||
this is probably preferable to locking up. */
|
||||
return -1;
|
||||
fprintf (stderr, "Waiting for connection from debugger...");
|
||||
debugsock = accept (sockethandle, &isa, &i);
|
||||
if (debugsock < 0)
|
||||
{ /* Now we are in serious trouble... */
|
||||
perror ("accept");
|
||||
return -1;
|
||||
}
|
||||
fprintf (stderr, " done.\nConnection Established.\n");
|
||||
sock = debugsock;
|
||||
goto retry;
|
||||
}
|
||||
perror ("read");
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
if (sock == debugsock) fprintf(stderr, "<%02x ", *c);
|
||||
if (sock == debugsock)
|
||||
fprintf (stderr, "<%02x ", *c);
|
||||
#endif
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -104,118 +109,147 @@ int MYread_char(int sock, unsigned char *c) {
|
||||
/* It waits until there is a character available. Returns -1 if */
|
||||
/* an error occurs. */
|
||||
/****************************************************************/
|
||||
int MYread_charwait(int sock, unsigned char *c) {
|
||||
int
|
||||
MYread_charwait (int sock, unsigned char *c)
|
||||
{
|
||||
int i;
|
||||
fd_set readfds;
|
||||
struct sockaddr_in isa;
|
||||
|
||||
retry:
|
||||
|
||||
FD_ZERO(&readfds);
|
||||
FD_SET(sock, &readfds);
|
||||
|
||||
i = select(nfds, &readfds,
|
||||
(fd_set *) 0,
|
||||
(fd_set *) 0,
|
||||
(struct timeval *) 0);
|
||||
retry:
|
||||
|
||||
if (i < 0) {
|
||||
perror("select");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if ((i = read(sock, c, 1)) < 1) {
|
||||
if (!i && sock == debugsock) {
|
||||
fprintf(stderr, "Connection with debugger severed.\n");
|
||||
return -1;
|
||||
fprintf(stderr, "Waiting for connection from debugger...");
|
||||
debugsock = accept(sockethandle, &isa, &i);
|
||||
if (debugsock < 0) { /* Now we are in serious trouble... */
|
||||
perror("accept");
|
||||
return -1;
|
||||
}
|
||||
fprintf(stderr, " done.\nConnection Established.\n");
|
||||
sock = debugsock;
|
||||
goto retry;
|
||||
FD_ZERO (&readfds);
|
||||
FD_SET (sock, &readfds);
|
||||
|
||||
i = select (nfds, &readfds,
|
||||
(fd_set *) 0, (fd_set *) 0, (struct timeval *) 0);
|
||||
|
||||
if (i < 0)
|
||||
{
|
||||
perror ("select");
|
||||
exit (-1);
|
||||
}
|
||||
perror("read");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if ((i = read (sock, c, 1)) < 1)
|
||||
{
|
||||
if (!i && sock == debugsock)
|
||||
{
|
||||
fprintf (stderr, "Connection with debugger severed.\n");
|
||||
return -1;
|
||||
fprintf (stderr, "Waiting for connection from debugger...");
|
||||
debugsock = accept (sockethandle, &isa, &i);
|
||||
if (debugsock < 0)
|
||||
{ /* Now we are in serious trouble... */
|
||||
perror ("accept");
|
||||
return -1;
|
||||
}
|
||||
fprintf (stderr, " done.\nConnection Established.\n");
|
||||
sock = debugsock;
|
||||
goto retry;
|
||||
}
|
||||
perror ("read");
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
if (sock == debugsock) fprintf(stderr, "<%02x ", *c);
|
||||
if (sock == debugsock)
|
||||
fprintf (stderr, "<%02x ", *c);
|
||||
#endif
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void MYwrite_char(int sock, unsigned char c) {
|
||||
void
|
||||
MYwrite_char (int sock, unsigned char c)
|
||||
{
|
||||
|
||||
if (write(sock, &c, 1) < 1)
|
||||
perror("write");
|
||||
if (write (sock, &c, 1) < 1)
|
||||
perror ("write");
|
||||
#ifdef DEBUG
|
||||
if (sock == debugsock) fprintf(stderr, ">%02x ", c);
|
||||
if (sock == debugsock)
|
||||
fprintf (stderr, ">%02x ", c);
|
||||
#endif
|
||||
}
|
||||
|
||||
int MYread_word(int sock, ARMword *here) {
|
||||
int
|
||||
MYread_word (int sock, ARMword * here)
|
||||
{
|
||||
unsigned char a, b, c, d;
|
||||
|
||||
if (MYread_char(sock, &a) < 0) return -1;
|
||||
if (MYread_char(sock, &b) < 0) return -1;
|
||||
if (MYread_char(sock, &c) < 0) return -1;
|
||||
if (MYread_char(sock, &d) < 0) return -1;
|
||||
|
||||
if (MYread_char (sock, &a) < 0)
|
||||
return -1;
|
||||
if (MYread_char (sock, &b) < 0)
|
||||
return -1;
|
||||
if (MYread_char (sock, &c) < 0)
|
||||
return -1;
|
||||
if (MYread_char (sock, &d) < 0)
|
||||
return -1;
|
||||
*here = a | b << 8 | c << 16 | d << 24;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void MYwrite_word(int sock, ARMword i) {
|
||||
MYwrite_char(sock, i & 0xff);
|
||||
MYwrite_char(sock, (i & 0xff00) >> 8);
|
||||
MYwrite_char(sock, (i & 0xff0000) >> 16);
|
||||
MYwrite_char(sock, (i & 0xff000000) >> 24);
|
||||
void
|
||||
MYwrite_word (int sock, ARMword i)
|
||||
{
|
||||
MYwrite_char (sock, i & 0xff);
|
||||
MYwrite_char (sock, (i & 0xff00) >> 8);
|
||||
MYwrite_char (sock, (i & 0xff0000) >> 16);
|
||||
MYwrite_char (sock, (i & 0xff000000) >> 24);
|
||||
}
|
||||
|
||||
void MYwrite_string(int sock, char *s) {
|
||||
int i;
|
||||
for (i = 0; MYwrite_char(sock, s[i]), s[i]; i++);
|
||||
void
|
||||
MYwrite_string (int sock, char *s)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; MYwrite_char (sock, s[i]), s[i]; i++);
|
||||
}
|
||||
|
||||
int MYread_FPword(int sock, char *putinhere) {
|
||||
int
|
||||
MYread_FPword (int sock, char *putinhere)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 16; i++)
|
||||
if (MYread_char(sock, &putinhere[i]) < 0) return -1;
|
||||
if (MYread_char (sock, &putinhere[i]) < 0)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void MYwrite_FPword(int sock, char *fromhere) {
|
||||
void
|
||||
MYwrite_FPword (int sock, char *fromhere)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 16; i++)
|
||||
MYwrite_char(sock, fromhere[i]);
|
||||
MYwrite_char (sock, fromhere[i]);
|
||||
}
|
||||
|
||||
/* Takes n bytes from source and those n bytes */
|
||||
/* down to dest */
|
||||
int passon(int source, int dest, int n) {
|
||||
int
|
||||
passon (int source, int dest, int n)
|
||||
{
|
||||
char *p;
|
||||
int i;
|
||||
|
||||
p = (char *) malloc(n);
|
||||
if (!p) {
|
||||
perror("Out of memory\n");
|
||||
exit(1);
|
||||
}
|
||||
if (n) {
|
||||
for (i = 0; i < n; i++)
|
||||
if (MYread_char(source, &p[i]) < 0) return -1;
|
||||
|
||||
|
||||
p = (char *) malloc (n);
|
||||
if (!p)
|
||||
{
|
||||
perror ("Out of memory\n");
|
||||
exit (1);
|
||||
}
|
||||
if (n)
|
||||
{
|
||||
for (i = 0; i < n; i++)
|
||||
if (MYread_char (source, &p[i]) < 0)
|
||||
return -1;
|
||||
|
||||
#ifdef DEBUG
|
||||
if (dest == debugsock)
|
||||
for (i = 0; i < n; i++) fprintf(stderr, ")%02x ", (unsigned char) p[i]);
|
||||
if (dest == debugsock)
|
||||
for (i = 0; i < n; i++)
|
||||
fprintf (stderr, ")%02x ", (unsigned char) p[i]);
|
||||
#endif
|
||||
|
||||
write(dest, p, n);
|
||||
}
|
||||
free(p);
|
||||
|
||||
write (dest, p, n);
|
||||
}
|
||||
free (p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -15,16 +15,16 @@
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
int MYread_char(int sock, unsigned char *c);
|
||||
void MYwrite_char(int sock, unsigned char c);
|
||||
int MYread_word(int sock, ARMword *here);
|
||||
void MYwrite_word(int sock, ARMword i);
|
||||
void MYwrite_string(int sock, char *s);
|
||||
int MYread_FPword(int sock, char *putinhere);
|
||||
void MYwrite_FPword(int sock, char *fromhere);
|
||||
int passon(int source, int dest, int n);
|
||||
int MYread_char (int sock, unsigned char *c);
|
||||
void MYwrite_char (int sock, unsigned char c);
|
||||
int MYread_word (int sock, ARMword * here);
|
||||
void MYwrite_word (int sock, ARMword i);
|
||||
void MYwrite_string (int sock, char *s);
|
||||
int MYread_FPword (int sock, char *putinhere);
|
||||
void MYwrite_FPword (int sock, char *fromhere);
|
||||
int passon (int source, int dest, int n);
|
||||
|
||||
int wait_for_osreply(ARMword *reply); /* from kid.c */
|
||||
int wait_for_osreply (ARMword * reply); /* from kid.c */
|
||||
|
||||
#define OS_SendNothing 0x0
|
||||
#define OS_SendChar 0x1
|
||||
@@ -34,4 +34,3 @@ int wait_for_osreply(ARMword *reply); /* from kid.c */
|
||||
/* The pipes between the two processes */
|
||||
extern int mumkid[2];
|
||||
extern int kidmum[2];
|
||||
|
||||
|
||||
@@ -19,19 +19,21 @@
|
||||
|
||||
#define Dbg_Conf__h
|
||||
|
||||
typedef struct Dbg_ConfigBlock {
|
||||
int bytesex;
|
||||
long memorysize;
|
||||
int serialport; /*) remote connection parameters */
|
||||
int seriallinespeed; /*) (serial connection) */
|
||||
int parallelport; /*) ditto */
|
||||
int parallellinespeed; /*) (parallel connection) */
|
||||
int processor; /* processor the armulator is to emulate (eg ARM60) */
|
||||
int rditype; /* armulator / remote processor */
|
||||
int drivertype; /* parallel / serial / etc */
|
||||
char const *configtoload;
|
||||
int flags;
|
||||
} Dbg_ConfigBlock;
|
||||
typedef struct Dbg_ConfigBlock
|
||||
{
|
||||
int bytesex;
|
||||
long memorysize;
|
||||
int serialport; /*) remote connection parameters */
|
||||
int seriallinespeed; /*) (serial connection) */
|
||||
int parallelport; /*) ditto */
|
||||
int parallellinespeed; /*) (parallel connection) */
|
||||
int processor; /* processor the armulator is to emulate (eg ARM60) */
|
||||
int rditype; /* armulator / remote processor */
|
||||
int drivertype; /* parallel / serial / etc */
|
||||
char const *configtoload;
|
||||
int flags;
|
||||
}
|
||||
Dbg_ConfigBlock;
|
||||
|
||||
#define Dbg_ConfigFlag_Reset 1
|
||||
|
||||
|
||||
@@ -21,40 +21,48 @@
|
||||
|
||||
#define Dbg_Access_Readable 1
|
||||
#define Dbg_Access_Writable 2
|
||||
#define Dbg_Access_CPDT 4 /* else CPRT */
|
||||
#define Dbg_Access_CPDT 4 /* else CPRT */
|
||||
|
||||
typedef struct {
|
||||
unsigned short rmin, rmax;
|
||||
/* a single description can be used for a range of registers with
|
||||
the same properties *accessed via CPDT instructions*
|
||||
*/
|
||||
unsigned char nbytes; /* size of register */
|
||||
unsigned char access; /* see above (Access_xxx) */
|
||||
union {
|
||||
struct { /* CPDT instructions do not allow the coprocessor much freedom:
|
||||
only bit 22 ('N') and 12-15 ('CRd') are free for the
|
||||
coprocessor to use as it sees fit.
|
||||
*/
|
||||
unsigned char nbit;
|
||||
unsigned char rdbits;
|
||||
} cpdt;
|
||||
struct { /* CPRT instructions have much more latitude. The bits fixed
|
||||
by the ARM are 24..31 (condition mask & opcode)
|
||||
20 (direction)
|
||||
8..15 (cpnum, arm register)
|
||||
4 (CPRT not CPDO)
|
||||
leaving 14 bits free to the coprocessor (fortunately
|
||||
falling within two bytes).
|
||||
*/
|
||||
unsigned char read_b0, read_b1,
|
||||
write_b0, write_b1;
|
||||
} cprt;
|
||||
} accessinst;
|
||||
} Dbg_CoProRegDesc;
|
||||
typedef struct
|
||||
{
|
||||
unsigned short rmin, rmax;
|
||||
/* a single description can be used for a range of registers with
|
||||
the same properties *accessed via CPDT instructions*
|
||||
*/
|
||||
unsigned char nbytes; /* size of register */
|
||||
unsigned char access; /* see above (Access_xxx) */
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
/* CPDT instructions do not allow the coprocessor much freedom:
|
||||
only bit 22 ('N') and 12-15 ('CRd') are free for the
|
||||
coprocessor to use as it sees fit. */
|
||||
unsigned char nbit;
|
||||
unsigned char rdbits;
|
||||
}
|
||||
cpdt;
|
||||
struct
|
||||
{
|
||||
/* CPRT instructions have much more latitude. The bits fixed
|
||||
by the ARM are 24..31 (condition mask & opcode)
|
||||
20 (direction)
|
||||
8..15 (cpnum, arm register)
|
||||
4 (CPRT not CPDO)
|
||||
leaving 14 bits free to the coprocessor (fortunately
|
||||
falling within two bytes). */
|
||||
unsigned char read_b0, read_b1, write_b0, write_b1;
|
||||
}
|
||||
cprt;
|
||||
}
|
||||
accessinst;
|
||||
}
|
||||
Dbg_CoProRegDesc;
|
||||
|
||||
struct Dbg_CoProDesc {
|
||||
int entries;
|
||||
Dbg_CoProRegDesc regdesc[1/* really nentries */];
|
||||
struct Dbg_CoProDesc
|
||||
{
|
||||
int entries;
|
||||
Dbg_CoProRegDesc regdesc[1 /* really nentries */ ];
|
||||
};
|
||||
|
||||
#define Dbg_CoProDesc_Size(n) (sizeof(struct Dbg_CoProDesc) + (n-1)*sizeof(Dbg_CoProRegDesc))
|
||||
|
||||
@@ -21,27 +21,28 @@
|
||||
# include <varargs.h>
|
||||
#endif
|
||||
|
||||
typedef void Hif_DbgPrint(void *arg, const char *format, va_list ap);
|
||||
typedef void Hif_DbgPause(void *arg);
|
||||
typedef void Hif_DbgPrint (void *arg, const char *format, va_list ap);
|
||||
typedef void Hif_DbgPause (void *arg);
|
||||
|
||||
typedef void Hif_WriteC(void *arg, int c);
|
||||
typedef int Hif_ReadC(void *arg);
|
||||
typedef int Hif_Write(void *arg, char const *buffer, int len);
|
||||
typedef char *Hif_GetS(void *arg, char *buffer, int len);
|
||||
typedef void Hif_WriteC (void *arg, int c);
|
||||
typedef int Hif_ReadC (void *arg);
|
||||
typedef int Hif_Write (void *arg, char const *buffer, int len);
|
||||
typedef char *Hif_GetS (void *arg, char *buffer, int len);
|
||||
|
||||
typedef void Hif_RDIResetProc(void *arg);
|
||||
typedef void Hif_RDIResetProc (void *arg);
|
||||
|
||||
struct Dbg_HostosInterface {
|
||||
Hif_DbgPrint *dbgprint;
|
||||
Hif_DbgPause *dbgpause;
|
||||
void *dbgarg;
|
||||
struct Dbg_HostosInterface
|
||||
{
|
||||
Hif_DbgPrint *dbgprint;
|
||||
Hif_DbgPause *dbgpause;
|
||||
void *dbgarg;
|
||||
|
||||
Hif_WriteC *writec;
|
||||
Hif_ReadC *readc;
|
||||
Hif_Write *write;
|
||||
Hif_GetS *gets;
|
||||
void *hostosarg;
|
||||
Hif_WriteC *writec;
|
||||
Hif_ReadC *readc;
|
||||
Hif_Write *write;
|
||||
Hif_GetS *gets;
|
||||
void *hostosarg;
|
||||
|
||||
Hif_RDIResetProc *reset;
|
||||
void *resetarg;
|
||||
Hif_RDIResetProc *reset;
|
||||
void *resetarg;
|
||||
};
|
||||
|
||||
@@ -112,11 +112,11 @@
|
||||
* Other RDI values *
|
||||
\***************************************************************************/
|
||||
|
||||
#define RDISex_Little 0 /* the byte sex of the debuggee */
|
||||
#define RDISex_Little 0 /* the byte sex of the debuggee */
|
||||
#define RDISex_Big 1
|
||||
#define RDISex_DontCare 2
|
||||
|
||||
#define RDIPoint_EQ 0 /* the different types of break/watchpoints */
|
||||
#define RDIPoint_EQ 0 /* the different types of break/watchpoints */
|
||||
#define RDIPoint_GT 1
|
||||
#define RDIPoint_GE 2
|
||||
#define RDIPoint_LT 3
|
||||
@@ -125,29 +125,29 @@
|
||||
#define RDIPoint_OUT 6
|
||||
#define RDIPoint_MASK 7
|
||||
|
||||
#define RDIPoint_Inquiry 64 /* ORRed with point type in extended RDP */
|
||||
#define RDIPoint_Handle 128 /* messages */
|
||||
#define RDIPoint_Inquiry 64 /* ORRed with point type in extended RDP */
|
||||
#define RDIPoint_Handle 128 /* messages */
|
||||
|
||||
#define RDIWatch_ByteRead 1 /* types of data accesses to watch for */
|
||||
#define RDIWatch_ByteRead 1 /* types of data accesses to watch for */
|
||||
#define RDIWatch_HalfRead 2
|
||||
#define RDIWatch_WordRead 4
|
||||
#define RDIWatch_ByteWrite 8
|
||||
#define RDIWatch_HalfWrite 16
|
||||
#define RDIWatch_WordWrite 32
|
||||
|
||||
#define RDIReg_R15 (1L << 15) /* mask values for CPU */
|
||||
#define RDIReg_R15 (1L << 15) /* mask values for CPU */
|
||||
#define RDIReg_PC (1L << 16)
|
||||
#define RDIReg_CPSR (1L << 17)
|
||||
#define RDIReg_SPSR (1L << 18)
|
||||
#define RDINumCPURegs 19
|
||||
|
||||
#define RDINumCPRegs 10 /* current maximum */
|
||||
#define RDINumCPRegs 10 /* current maximum */
|
||||
|
||||
#define RDIMode_Curr 255
|
||||
|
||||
/* Bits set in return value from RDIInfo_Target */
|
||||
#define RDITarget_LogSpeed 0x0f
|
||||
#define RDITarget_HW 0x10 /* else emulator */
|
||||
#define RDITarget_HW 0x10 /* else emulator */
|
||||
#define RDITarget_AgentMaxLevel 0xe0
|
||||
#define RDITarget_AgentLevelShift 5
|
||||
#define RDITarget_DebuggerMinLevel 0x700
|
||||
@@ -165,22 +165,22 @@
|
||||
#define RDIPointCapability_Range 2
|
||||
/* 4 to 128 are RDIWatch_xx{Read,Write} left-shifted by two */
|
||||
#define RDIPointCapability_Mask 256
|
||||
#define RDIPointCapability_Status 512 /* Point status enquiries available */
|
||||
#define RDIPointCapability_Status 512 /* Point status enquiries available */
|
||||
|
||||
/* RDI_Info subcodes */
|
||||
#define RDIInfo_Target 0
|
||||
#define RDIInfo_Points 1
|
||||
#define RDIInfo_Step 2
|
||||
#define RDIInfo_MMU 3
|
||||
#define RDIInfo_DownLoad 4 /* Inquires whether configuration download
|
||||
and selection is available.
|
||||
*/
|
||||
#define RDIInfo_SemiHosting 5 /* Inquires whether RDISemiHosting_* RDI_Info
|
||||
calls are available.
|
||||
*/
|
||||
#define RDIInfo_CoPro 6 /* Inquires whether CoPro RDI_Info calls are
|
||||
available.
|
||||
*/
|
||||
#define RDIInfo_DownLoad 4 /* Inquires whether configuration download
|
||||
and selection is available.
|
||||
*/
|
||||
#define RDIInfo_SemiHosting 5 /* Inquires whether RDISemiHosting_* RDI_Info
|
||||
calls are available.
|
||||
*/
|
||||
#define RDIInfo_CoPro 6 /* Inquires whether CoPro RDI_Info calls are
|
||||
available.
|
||||
*/
|
||||
#define RDIInfo_Icebreaker 7
|
||||
|
||||
/* The next two are only to be used if the value returned by RDIInfo_Points */
|
||||
@@ -228,96 +228,105 @@ typedef unsigned long ThreadHandle;
|
||||
struct Dbg_ConfigBlock;
|
||||
struct Dbg_HostosInterface;
|
||||
struct Dbg_MCState;
|
||||
typedef int rdi_open_proc(unsigned type, struct Dbg_ConfigBlock const *config,
|
||||
struct Dbg_HostosInterface const *i,
|
||||
struct Dbg_MCState *dbg_state);
|
||||
typedef int rdi_close_proc(void);
|
||||
typedef int rdi_read_proc(ARMword source, void *dest, unsigned *nbytes);
|
||||
typedef int rdi_write_proc(const void *source, ARMword dest, unsigned *nbytes);
|
||||
typedef int rdi_CPUread_proc(unsigned mode, unsigned long mask, ARMword *state);
|
||||
typedef int rdi_CPUwrite_proc(unsigned mode, unsigned long mask, ARMword const *state);
|
||||
typedef int rdi_CPread_proc(unsigned CPnum, unsigned long mask, ARMword *state);
|
||||
typedef int rdi_CPwrite_proc(unsigned CPnum, unsigned long mask, ARMword const *state);
|
||||
typedef int rdi_setbreak_proc(ARMword address, unsigned type, ARMword bound,
|
||||
PointHandle *handle);
|
||||
typedef int rdi_clearbreak_proc(PointHandle handle);
|
||||
typedef int rdi_setwatch_proc(ARMword address, unsigned type, unsigned datatype,
|
||||
ARMword bound, PointHandle *handle);
|
||||
typedef int rdi_clearwatch_proc(PointHandle handle);
|
||||
typedef int rdi_execute_proc(PointHandle *handle);
|
||||
typedef int rdi_step_proc(unsigned ninstr, PointHandle *handle);
|
||||
typedef int rdi_info_proc(unsigned type, ARMword *arg1, ARMword *arg2);
|
||||
typedef int rdi_pointinq_proc(ARMword *address, unsigned type,
|
||||
unsigned datatype, ARMword *bound);
|
||||
typedef int rdi_open_proc (unsigned type,
|
||||
struct Dbg_ConfigBlock const *config,
|
||||
struct Dbg_HostosInterface const *i,
|
||||
struct Dbg_MCState *dbg_state);
|
||||
typedef int rdi_close_proc (void);
|
||||
typedef int rdi_read_proc (ARMword source, void *dest, unsigned *nbytes);
|
||||
typedef int rdi_write_proc (const void *source, ARMword dest,
|
||||
unsigned *nbytes);
|
||||
typedef int rdi_CPUread_proc (unsigned mode, unsigned long mask,
|
||||
ARMword * state);
|
||||
typedef int rdi_CPUwrite_proc (unsigned mode, unsigned long mask,
|
||||
ARMword const *state);
|
||||
typedef int rdi_CPread_proc (unsigned CPnum, unsigned long mask,
|
||||
ARMword * state);
|
||||
typedef int rdi_CPwrite_proc (unsigned CPnum, unsigned long mask,
|
||||
ARMword const *state);
|
||||
typedef int rdi_setbreak_proc (ARMword address, unsigned type, ARMword bound,
|
||||
PointHandle * handle);
|
||||
typedef int rdi_clearbreak_proc (PointHandle handle);
|
||||
typedef int rdi_setwatch_proc (ARMword address, unsigned type,
|
||||
unsigned datatype, ARMword bound,
|
||||
PointHandle * handle);
|
||||
typedef int rdi_clearwatch_proc (PointHandle handle);
|
||||
typedef int rdi_execute_proc (PointHandle * handle);
|
||||
typedef int rdi_step_proc (unsigned ninstr, PointHandle * handle);
|
||||
typedef int rdi_info_proc (unsigned type, ARMword * arg1, ARMword * arg2);
|
||||
typedef int rdi_pointinq_proc (ARMword * address, unsigned type,
|
||||
unsigned datatype, ARMword * bound);
|
||||
|
||||
typedef enum {
|
||||
RDI_ConfigCPU,
|
||||
RDI_ConfigSystem
|
||||
} RDI_ConfigAspect;
|
||||
typedef enum
|
||||
{
|
||||
RDI_ConfigCPU,
|
||||
RDI_ConfigSystem
|
||||
}
|
||||
RDI_ConfigAspect;
|
||||
|
||||
typedef enum {
|
||||
RDI_MatchAny,
|
||||
RDI_MatchExactly,
|
||||
RDI_MatchNoEarlier
|
||||
} RDI_ConfigMatchType;
|
||||
typedef enum
|
||||
{
|
||||
RDI_MatchAny,
|
||||
RDI_MatchExactly,
|
||||
RDI_MatchNoEarlier
|
||||
}
|
||||
RDI_ConfigMatchType;
|
||||
|
||||
typedef int rdi_addconfig_proc(unsigned long nbytes);
|
||||
typedef int rdi_loadconfigdata_proc(unsigned long nbytes, char const *data);
|
||||
typedef int rdi_selectconfig_proc(RDI_ConfigAspect aspect, char const *name,
|
||||
RDI_ConfigMatchType matchtype, unsigned versionreq,
|
||||
unsigned *versionp);
|
||||
typedef int rdi_addconfig_proc (unsigned long nbytes);
|
||||
typedef int rdi_loadconfigdata_proc (unsigned long nbytes, char const *data);
|
||||
typedef int rdi_selectconfig_proc (RDI_ConfigAspect aspect, char const *name,
|
||||
RDI_ConfigMatchType matchtype,
|
||||
unsigned versionreq, unsigned *versionp);
|
||||
|
||||
typedef char *getbufferproc(void *getbarg, unsigned long *sizep);
|
||||
typedef int rdi_loadagentproc(ARMword dest, unsigned long size, getbufferproc *getb, void *getbarg);
|
||||
typedef char *getbufferproc (void *getbarg, unsigned long *sizep);
|
||||
typedef int rdi_loadagentproc (ARMword dest, unsigned long size,
|
||||
getbufferproc * getb, void *getbarg);
|
||||
|
||||
typedef struct {
|
||||
int itemmax;
|
||||
char const * const *names;
|
||||
} RDI_NameList;
|
||||
typedef struct
|
||||
{
|
||||
int itemmax;
|
||||
char const *const *names;
|
||||
}
|
||||
RDI_NameList;
|
||||
|
||||
typedef RDI_NameList const *rdi_namelistproc(void);
|
||||
typedef RDI_NameList const *rdi_namelistproc (void);
|
||||
|
||||
typedef int rdi_errmessproc(char *buf, int buflen, int errno);
|
||||
typedef int rdi_errmessproc (char *buf, int buflen, int errno);
|
||||
|
||||
struct RDIProcVec {
|
||||
char rditypename[12];
|
||||
struct RDIProcVec
|
||||
{
|
||||
char rditypename[12];
|
||||
|
||||
rdi_open_proc *open;
|
||||
rdi_close_proc *close;
|
||||
rdi_read_proc *read;
|
||||
rdi_write_proc *write;
|
||||
rdi_CPUread_proc *CPUread;
|
||||
rdi_CPUwrite_proc *CPUwrite;
|
||||
rdi_CPread_proc *CPread;
|
||||
rdi_CPwrite_proc *CPwrite;
|
||||
rdi_setbreak_proc *setbreak;
|
||||
rdi_clearbreak_proc *clearbreak;
|
||||
rdi_setwatch_proc *setwatch;
|
||||
rdi_clearwatch_proc *clearwatch;
|
||||
rdi_execute_proc *execute;
|
||||
rdi_step_proc *step;
|
||||
rdi_info_proc *info;
|
||||
/* V2 RDI */
|
||||
rdi_pointinq_proc *pointinquiry;
|
||||
rdi_open_proc *open;
|
||||
rdi_close_proc *close;
|
||||
rdi_read_proc *read;
|
||||
rdi_write_proc *write;
|
||||
rdi_CPUread_proc *CPUread;
|
||||
rdi_CPUwrite_proc *CPUwrite;
|
||||
rdi_CPread_proc *CPread;
|
||||
rdi_CPwrite_proc *CPwrite;
|
||||
rdi_setbreak_proc *setbreak;
|
||||
rdi_clearbreak_proc *clearbreak;
|
||||
rdi_setwatch_proc *setwatch;
|
||||
rdi_clearwatch_proc *clearwatch;
|
||||
rdi_execute_proc *execute;
|
||||
rdi_step_proc *step;
|
||||
rdi_info_proc *info;
|
||||
/* V2 RDI */
|
||||
rdi_pointinq_proc *pointinquiry;
|
||||
|
||||
/* These three useable only if RDIInfo_DownLoad returns no error */
|
||||
rdi_addconfig_proc *addconfig;
|
||||
rdi_loadconfigdata_proc *loadconfigdata;
|
||||
rdi_selectconfig_proc *selectconfig;
|
||||
/* These three useable only if RDIInfo_DownLoad returns no error */
|
||||
rdi_addconfig_proc *addconfig;
|
||||
rdi_loadconfigdata_proc *loadconfigdata;
|
||||
rdi_selectconfig_proc *selectconfig;
|
||||
|
||||
rdi_namelistproc *drivernames;
|
||||
rdi_namelistproc *cpunames;
|
||||
rdi_namelistproc *drivernames;
|
||||
rdi_namelistproc *cpunames;
|
||||
|
||||
rdi_errmessproc *errmess;
|
||||
rdi_errmessproc *errmess;
|
||||
|
||||
/* Only if RDIInfo_Target returns a value with RDITarget_LoadAgent set */
|
||||
rdi_loadagentproc *loadagent;
|
||||
/* Only if RDIInfo_Target returns a value with RDITarget_LoadAgent set */
|
||||
rdi_loadagentproc *loadagent;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
#define OS_SendString 0x3
|
||||
|
||||
/* Defined in kid.c */
|
||||
extern int wait_for_osreply(ARMword *reply);
|
||||
extern int wait_for_osreply (ARMword * reply);
|
||||
|
||||
/* A pipe for handling SWI return values that goes straight from the */
|
||||
/* parent to the ARMulator host interface, bypassing the childs RDP */
|
||||
@@ -43,7 +43,8 @@ int DebuggerARMul[2];
|
||||
int mumkid[2];
|
||||
int kidmum[2];
|
||||
|
||||
void myprint (void *arg, const char *format, va_list ap)
|
||||
void
|
||||
myprint (void *arg, const char *format, va_list ap)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr, "Host: myprint\n");
|
||||
@@ -53,55 +54,60 @@ void myprint (void *arg, const char *format, va_list ap)
|
||||
|
||||
|
||||
/* Waits for a keypress on the debuggers' keyboard */
|
||||
void mypause (void *arg)
|
||||
void
|
||||
mypause (void *arg)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr, "Host: mypause\n");
|
||||
#endif
|
||||
} /* I do love exciting functions */
|
||||
} /* I do love exciting functions */
|
||||
|
||||
void mywritec(void *arg, int c)
|
||||
void
|
||||
mywritec (void *arg, int c)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "Mywrite : %c\n", c);
|
||||
fprintf (stderr, "Mywrite : %c\n", c);
|
||||
#endif
|
||||
MYwrite_char(kidmum[1], RDP_OSOp); /* OS Operation Request Message */
|
||||
MYwrite_word(kidmum[1], SWI_WriteC); /* Print... */
|
||||
MYwrite_char(kidmum[1], OS_SendChar); /* ...a single character */
|
||||
MYwrite_char(kidmum[1], (unsigned char) c);
|
||||
|
||||
wait_for_osreply((ARMword *) 0);
|
||||
MYwrite_char (kidmum[1], RDP_OSOp); /* OS Operation Request Message */
|
||||
MYwrite_word (kidmum[1], SWI_WriteC); /* Print... */
|
||||
MYwrite_char (kidmum[1], OS_SendChar); /* ...a single character */
|
||||
MYwrite_char (kidmum[1], (unsigned char) c);
|
||||
|
||||
wait_for_osreply ((ARMword *) 0);
|
||||
}
|
||||
|
||||
int myreadc(void *arg)
|
||||
int
|
||||
myreadc (void *arg)
|
||||
{
|
||||
char c;
|
||||
ARMword x;
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "Host: myreadc\n");
|
||||
fprintf (stderr, "Host: myreadc\n");
|
||||
#endif
|
||||
MYwrite_char(kidmum[1], RDP_OSOp); /* OS Operation Request Message */
|
||||
MYwrite_word(kidmum[1], SWI_ReadC); /* Read... */
|
||||
MYwrite_char(kidmum[1], OS_SendNothing);
|
||||
|
||||
c = wait_for_osreply(&x);
|
||||
MYwrite_char (kidmum[1], RDP_OSOp); /* OS Operation Request Message */
|
||||
MYwrite_word (kidmum[1], SWI_ReadC); /* Read... */
|
||||
MYwrite_char (kidmum[1], OS_SendNothing);
|
||||
|
||||
c = wait_for_osreply (&x);
|
||||
return (x);
|
||||
}
|
||||
|
||||
|
||||
int mywrite(void *arg, char const *buffer, int len)
|
||||
int
|
||||
mywrite (void *arg, char const *buffer, int len)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "Host: mywrite\n");
|
||||
fprintf (stderr, "Host: mywrite\n");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *mygets(void *arg, char *buffer, int len)
|
||||
char *
|
||||
mygets (void *arg, char *buffer, int len)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "Host: mygets\n");
|
||||
fprintf (stderr, "Host: mygets\n");
|
||||
#endif
|
||||
return buffer;
|
||||
}
|
||||
|
||||
@@ -15,9 +15,9 @@
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
void myprint(void *arg, const char *format, va_list ap);
|
||||
void mypause(void *arg);
|
||||
void mywritec(void *arg, int c);
|
||||
int myreadc(void *arg);
|
||||
int mywrite(void *arg, char const *buffer, int len);
|
||||
char *mygets(void *arg, char *buffer, int len);
|
||||
void myprint (void *arg, const char *format, va_list ap);
|
||||
void mypause (void *arg);
|
||||
void mywritec (void *arg, int c);
|
||||
int myreadc (void *arg);
|
||||
int mywrite (void *arg, char const *buffer, int len);
|
||||
char *mygets (void *arg, char *buffer, int len);
|
||||
|
||||
772
sim/arm/kid.c
772
sim/arm/kid.c
@@ -56,22 +56,27 @@ static int rdi_state = 0;
|
||||
/**************************************************************/
|
||||
/* Signal handler that terminates excecution in the ARMulator */
|
||||
/**************************************************************/
|
||||
void kid_handlesignal(int sig) {
|
||||
void
|
||||
kid_handlesignal (int sig)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "Terminate ARMulator excecution\n");
|
||||
fprintf (stderr, "Terminate ARMulator excecution\n");
|
||||
#endif
|
||||
if (sig != SIGUSR1) {
|
||||
fprintf(stderr, "Unsupported signal.\n");
|
||||
return;
|
||||
}
|
||||
armul_rdi.info(RDISignal_Stop, (unsigned long *) 0, (unsigned long *) 0);
|
||||
if (sig != SIGUSR1)
|
||||
{
|
||||
fprintf (stderr, "Unsupported signal.\n");
|
||||
return;
|
||||
}
|
||||
armul_rdi.info (RDISignal_Stop, (unsigned long *) 0, (unsigned long *) 0);
|
||||
}
|
||||
|
||||
/********************************************************************/
|
||||
/* Waits on a pipe from the socket demon for RDP and */
|
||||
/* acts as an RDP to RDI interpreter on the front of the ARMulator. */
|
||||
/********************************************************************/
|
||||
void kid() {
|
||||
void
|
||||
kid ()
|
||||
{
|
||||
char *p, *q;
|
||||
int i, j, k;
|
||||
long outofthebag;
|
||||
@@ -84,342 +89,363 @@ void kid() {
|
||||
struct Dbg_MCState *MCState;
|
||||
char command_line[256];
|
||||
struct fd_set readfds;
|
||||
|
||||
|
||||
/* Setup a signal handler for SIGUSR1 */
|
||||
action.sa_handler = kid_handlesignal;
|
||||
action.sa_mask = 0;
|
||||
action.sa_flags = 0;
|
||||
|
||||
sigaction(SIGUSR1, &action, (struct sigaction *) 0);
|
||||
|
||||
|
||||
sigaction (SIGUSR1, &action, (struct sigaction *) 0);
|
||||
|
||||
while (1)
|
||||
{
|
||||
/* Wait for ever */
|
||||
FD_ZERO(&readfds);
|
||||
FD_SET(mumkid[0], &readfds);
|
||||
|
||||
i = select(nfds, &readfds,
|
||||
(fd_set *) 0,
|
||||
(fd_set *) 0,
|
||||
(struct timeval *) 0);
|
||||
|
||||
if (i < 0) {
|
||||
perror("select");
|
||||
}
|
||||
|
||||
if (read(mumkid[0], &message, 1) < 1) {
|
||||
perror("read");
|
||||
}
|
||||
{
|
||||
/* Wait for ever */
|
||||
FD_ZERO (&readfds);
|
||||
FD_SET (mumkid[0], &readfds);
|
||||
|
||||
switch (message) {
|
||||
case RDP_Start :
|
||||
/* Open and/or Initialise */
|
||||
BAG_newbag();
|
||||
i = select (nfds, &readfds,
|
||||
(fd_set *) 0, (fd_set *) 0, (struct timeval *) 0);
|
||||
|
||||
MYread_char(mumkid[0], &c); /* type */
|
||||
MYread_word(mumkid[0], &x); /* memorysize */
|
||||
if (c & 0x2) MYread_char(mumkid[0], &d); /* speed */
|
||||
config.processor = 0;
|
||||
config.memorysize = x;
|
||||
config.bytesex = (c & 0x4) ? RDISex_Big : RDISex_Little;
|
||||
if (c & 0x8) config.bytesex = RDISex_DontCare;
|
||||
|
||||
hostif.dbgprint = myprint;
|
||||
hostif.dbgpause = mypause;
|
||||
hostif.dbgarg = stdout;
|
||||
hostif.writec = mywritec;
|
||||
hostif.readc = myreadc;
|
||||
hostif.write = mywrite;
|
||||
hostif.gets = mygets;
|
||||
hostif.reset = mypause; /* do nothing */
|
||||
hostif.resetarg = "Do I love resetting or what!\n";
|
||||
|
||||
if (rdi_state)
|
||||
{
|
||||
/* we have restarted, so kill off the existing run. */
|
||||
/* armul_rdi.close(); */
|
||||
}
|
||||
i = armul_rdi.open(c & 0x3, &config, &hostif, MCState);
|
||||
rdi_state = 1;
|
||||
|
||||
MYwrite_char(kidmum[1], RDP_Return);
|
||||
MYwrite_char(kidmum[1], (unsigned char) i);
|
||||
|
||||
x = ~0x4;
|
||||
armul_rdi.info(RDIVector_Catch, &x, 0);
|
||||
|
||||
break;
|
||||
|
||||
case RDP_End :
|
||||
/* Close and Finalise */
|
||||
i = armul_rdi.close();
|
||||
rdi_state = 0;
|
||||
MYwrite_char(kidmum[1], RDP_Return);
|
||||
MYwrite_char(kidmum[1], (unsigned char) i);
|
||||
break;
|
||||
|
||||
case RDP_Read :
|
||||
/* Read Memory Address */
|
||||
MYread_word(mumkid[0], &x); /* address */
|
||||
MYread_word(mumkid[0], &y); /* nbytes */
|
||||
p = (char *) malloc(y);
|
||||
i = armul_rdi.read(x, p, (unsigned *) &y);
|
||||
MYwrite_char(kidmum[1], RDP_Return);
|
||||
for (k = 0; k < y; k++)
|
||||
MYwrite_char(kidmum[1], p[k]);
|
||||
free(p);
|
||||
MYwrite_char(kidmum[1], (unsigned char) i);
|
||||
if (i)
|
||||
MYwrite_word(kidmum[1], y); /* number of bytes sent without error */
|
||||
break;
|
||||
|
||||
case RDP_Write :
|
||||
/* Write Memory Address */
|
||||
MYread_word(mumkid[0], &x); /* address */
|
||||
MYread_word(mumkid[0], &y); /* nbytes */
|
||||
p = (char *) malloc(y);
|
||||
for (k = 0; k < y; k++)
|
||||
MYread_char(mumkid[0], &p[k]);
|
||||
i = armul_rdi.write(p, x, (unsigned *) &y);
|
||||
free(p);
|
||||
MYwrite_char(kidmum[1], RDP_Return);
|
||||
MYwrite_char(kidmum[1], (unsigned char) i);
|
||||
if (i)
|
||||
MYwrite_word(kidmum[1], y); /* number of bytes sent without error */
|
||||
break;
|
||||
|
||||
case RDP_CPUread :
|
||||
/* Read CPU State */
|
||||
MYread_char(mumkid[0], &c); /* mode */
|
||||
MYread_word(mumkid[0], &x); /* mask */
|
||||
p = (char *) malloc(4 * RDINumCPURegs);
|
||||
i = armul_rdi.CPUread(c, x, (ARMword *) p);
|
||||
MYwrite_char(kidmum[1], RDP_Return);
|
||||
for (k = 1, j = 0; k != 0x80000000; k *= 2)
|
||||
if (k & x) MYwrite_word(kidmum[1], ((ARMword *) p)[j++]);
|
||||
free(p);
|
||||
if (i) MYwrite_char(kidmum[1], (unsigned char) j);
|
||||
MYwrite_char(kidmum[1], (unsigned char) i);
|
||||
break;
|
||||
|
||||
case RDP_CPUwrite :
|
||||
/* Write CPU State */
|
||||
MYread_char(mumkid[0], &c); /* mode */
|
||||
MYread_word(mumkid[0], &x); /* mask */
|
||||
|
||||
p = (char *) malloc(4 * RDINumCPURegs);
|
||||
for (k = 1, j = 0; k != 0x80000000; k *= 2)
|
||||
if (k & x) MYread_word(mumkid[0], &(((ARMword *) p)[j++]));
|
||||
i = armul_rdi.CPUwrite(c, x, (ARMword *) p);
|
||||
MYwrite_char(kidmum[1], RDP_Return);
|
||||
MYwrite_char(kidmum[1], (unsigned char) i);
|
||||
free(p);
|
||||
break;
|
||||
|
||||
case RDP_CPread :
|
||||
/* Read Co-Processor State */
|
||||
MYread_char(mumkid[0], &c); /* CPnum */
|
||||
MYread_word(mumkid[0], &x); /* mask */
|
||||
p = q = (char *) malloc(16 * RDINumCPRegs);
|
||||
i = armul_rdi.CPread(c, x, (ARMword *) p);
|
||||
MYwrite_char(kidmum[1], RDP_Return);
|
||||
for (k = 1, j = 0; k != 0x80000000; k *= 2, j++)
|
||||
if (k & x) {
|
||||
if ((c == 1 || c == 2) && k <= 128) {
|
||||
MYwrite_FPword(kidmum[1], q);
|
||||
q += 16;
|
||||
}
|
||||
else {
|
||||
MYwrite_word(kidmum[1], *q);
|
||||
q += 4;
|
||||
}
|
||||
}
|
||||
free(p);
|
||||
if (i) MYwrite_char(kidmum[1], (unsigned char) j);
|
||||
MYwrite_char(kidmum[1], (unsigned char) i);
|
||||
break;
|
||||
|
||||
case RDP_CPwrite :
|
||||
/* Write Co-Processor State */
|
||||
MYread_char(mumkid[0], &c); /* CPnum */
|
||||
MYread_word(mumkid[0], &x); /* mask */
|
||||
p = q = (char *) malloc(16 * RDINumCPURegs);
|
||||
for (k = 1, j = 0; k != 0x80000000; k *= 2, j++)
|
||||
if (k & x) {
|
||||
if ((c == 1 || c == 2) && k <= 128) {
|
||||
MYread_FPword(kidmum[1], q);
|
||||
q += 16;
|
||||
}
|
||||
else {
|
||||
MYread_word(mumkid[0], (ARMword *) q);
|
||||
q += 4;
|
||||
}
|
||||
}
|
||||
i = armul_rdi.CPwrite(c, x, (ARMword *) p);
|
||||
MYwrite_char(kidmum[1], RDP_Return);
|
||||
MYwrite_char(kidmum[1], (unsigned char) i);
|
||||
free(p);
|
||||
break;
|
||||
|
||||
case RDP_SetBreak :
|
||||
/* Set Breakpoint */
|
||||
MYread_word(mumkid[0], &x); /* address */
|
||||
MYread_char(mumkid[0], &c); /* type */
|
||||
if ((c & 0xf) >= 5) MYread_word(mumkid[0], &y); /* bound */
|
||||
i = armul_rdi.setbreak(x, c, y, &point);
|
||||
if (!MYrdp_level) BAG_putpair((long) x, (long) point);
|
||||
MYwrite_char(kidmum[1], RDP_Return);
|
||||
if (MYrdp_level) MYwrite_word(kidmum[1], point);
|
||||
MYwrite_char(kidmum[1], (unsigned char) i);
|
||||
break;
|
||||
|
||||
case RDP_ClearBreak :
|
||||
/* Clear Breakpoint */
|
||||
MYread_word(mumkid[0], &point); /* PointHandle */
|
||||
if (!MYrdp_level) {
|
||||
BAG_getsecond((long) point, &outofthebag); /* swap pointhandle for address */
|
||||
BAG_killpair_byfirst(outofthebag);
|
||||
point = outofthebag;
|
||||
}
|
||||
i = armul_rdi.clearbreak(point);
|
||||
MYwrite_char(kidmum[1], RDP_Return);
|
||||
MYwrite_char(kidmum[1], (unsigned char) i);
|
||||
break;
|
||||
|
||||
case RDP_SetWatch :
|
||||
/* Set Watchpoint */
|
||||
MYread_word(mumkid[0], &x); /* address */
|
||||
MYread_char(mumkid[0], &c); /* type */
|
||||
MYread_char(mumkid[0], &d); /* datatype */
|
||||
if ((c & 0xf) >= 5) MYread_word(mumkid[0], &y); /* bound */
|
||||
i = armul_rdi.setwatch(x, c, d, y, &point);
|
||||
MYwrite_char(kidmum[1], RDP_Return);
|
||||
MYwrite_word(kidmum[1], point);
|
||||
MYwrite_char(kidmum[1], (unsigned char) i);
|
||||
break;
|
||||
|
||||
case RDP_ClearWatch :
|
||||
/* Clear Watchpoint */
|
||||
MYread_word(mumkid[0], &point); /* PointHandle */
|
||||
i = armul_rdi.clearwatch(point);
|
||||
MYwrite_char(kidmum[1], RDP_Return);
|
||||
MYwrite_char(kidmum[1], (unsigned char) i);
|
||||
break;
|
||||
|
||||
case RDP_Execute :
|
||||
/* Excecute */
|
||||
|
||||
MYread_char(mumkid[0], &c); /* return */
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "Starting execution\n");
|
||||
#endif
|
||||
i = armul_rdi.execute(&point);
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "Completed execution\n");
|
||||
#endif
|
||||
MYwrite_char(kidmum[1], RDP_Return);
|
||||
if (c & 0x80) MYwrite_word(kidmum[1], point);
|
||||
MYwrite_char(kidmum[1], (unsigned char) i);
|
||||
break;
|
||||
|
||||
case RDP_Step :
|
||||
/* Step */
|
||||
MYread_char(mumkid[0], &c); /* return */
|
||||
MYread_word(mumkid[0], &x); /* ninstr */
|
||||
point = 0x87654321;
|
||||
i = armul_rdi.step(x, &point);
|
||||
MYwrite_char(kidmum[1], RDP_Return);
|
||||
if (c & 0x80) MYwrite_word(kidmum[1], point);
|
||||
MYwrite_char(kidmum[1], (unsigned char) i);
|
||||
break;
|
||||
|
||||
case RDP_Info:
|
||||
/* Info */
|
||||
MYread_word (mumkid[0], &x);
|
||||
switch (x)
|
||||
if (i < 0)
|
||||
{
|
||||
case RDIInfo_Target:
|
||||
i = armul_rdi.info (RDIInfo_Target, &y, &z);
|
||||
perror ("select");
|
||||
}
|
||||
|
||||
if (read (mumkid[0], &message, 1) < 1)
|
||||
{
|
||||
perror ("read");
|
||||
}
|
||||
|
||||
switch (message)
|
||||
{
|
||||
case RDP_Start:
|
||||
/* Open and/or Initialise */
|
||||
BAG_newbag ();
|
||||
|
||||
MYread_char (mumkid[0], &c); /* type */
|
||||
MYread_word (mumkid[0], &x); /* memorysize */
|
||||
if (c & 0x2)
|
||||
MYread_char (mumkid[0], &d); /* speed */
|
||||
config.processor = 0;
|
||||
config.memorysize = x;
|
||||
config.bytesex = (c & 0x4) ? RDISex_Big : RDISex_Little;
|
||||
if (c & 0x8)
|
||||
config.bytesex = RDISex_DontCare;
|
||||
|
||||
hostif.dbgprint = myprint;
|
||||
hostif.dbgpause = mypause;
|
||||
hostif.dbgarg = stdout;
|
||||
hostif.writec = mywritec;
|
||||
hostif.readc = myreadc;
|
||||
hostif.write = mywrite;
|
||||
hostif.gets = mygets;
|
||||
hostif.reset = mypause; /* do nothing */
|
||||
hostif.resetarg = "Do I love resetting or what!\n";
|
||||
|
||||
if (rdi_state)
|
||||
{
|
||||
/* we have restarted, so kill off the existing run. */
|
||||
/* armul_rdi.close(); */
|
||||
}
|
||||
i = armul_rdi.open (c & 0x3, &config, &hostif, MCState);
|
||||
rdi_state = 1;
|
||||
|
||||
MYwrite_char (kidmum[1], RDP_Return);
|
||||
MYwrite_word (kidmum[1], y); /* Loads of info... */
|
||||
MYwrite_word (kidmum[1], z); /* Model */
|
||||
MYwrite_char (kidmum[1], (unsigned char) i);
|
||||
|
||||
x = ~0x4;
|
||||
armul_rdi.info (RDIVector_Catch, &x, 0);
|
||||
|
||||
break;
|
||||
|
||||
case RDISet_RDILevel:
|
||||
MYread_word (mumkid[0], &x); /* arg1, debug level */
|
||||
i = armul_rdi.info (RDISet_RDILevel, &x, 0);
|
||||
if (i == RDIError_NoError)
|
||||
MYrdp_level = x;
|
||||
case RDP_End:
|
||||
/* Close and Finalise */
|
||||
i = armul_rdi.close ();
|
||||
rdi_state = 0;
|
||||
MYwrite_char (kidmum[1], RDP_Return);
|
||||
MYwrite_char (kidmum[1], (unsigned char) i);
|
||||
break;
|
||||
|
||||
case RDISet_Cmdline:
|
||||
for (p = command_line; MYread_char (mumkid[0], p), *p; p++)
|
||||
; /* String */
|
||||
i = armul_rdi.info (RDISet_Cmdline,
|
||||
(unsigned long *) command_line, 0);
|
||||
case RDP_Read:
|
||||
/* Read Memory Address */
|
||||
MYread_word (mumkid[0], &x); /* address */
|
||||
MYread_word (mumkid[0], &y); /* nbytes */
|
||||
p = (char *) malloc (y);
|
||||
i = armul_rdi.read (x, p, (unsigned *) &y);
|
||||
MYwrite_char (kidmum[1], RDP_Return);
|
||||
for (k = 0; k < y; k++)
|
||||
MYwrite_char (kidmum[1], p[k]);
|
||||
free (p);
|
||||
MYwrite_char (kidmum[1], (unsigned char) i);
|
||||
if (i)
|
||||
MYwrite_word (kidmum[1], y); /* number of bytes sent without error */
|
||||
break;
|
||||
|
||||
case RDP_Write:
|
||||
/* Write Memory Address */
|
||||
MYread_word (mumkid[0], &x); /* address */
|
||||
MYread_word (mumkid[0], &y); /* nbytes */
|
||||
p = (char *) malloc (y);
|
||||
for (k = 0; k < y; k++)
|
||||
MYread_char (mumkid[0], &p[k]);
|
||||
i = armul_rdi.write (p, x, (unsigned *) &y);
|
||||
free (p);
|
||||
MYwrite_char (kidmum[1], RDP_Return);
|
||||
MYwrite_char (kidmum[1], (unsigned char) i);
|
||||
if (i)
|
||||
MYwrite_word (kidmum[1], y); /* number of bytes sent without error */
|
||||
break;
|
||||
|
||||
case RDP_CPUread:
|
||||
/* Read CPU State */
|
||||
MYread_char (mumkid[0], &c); /* mode */
|
||||
MYread_word (mumkid[0], &x); /* mask */
|
||||
p = (char *) malloc (4 * RDINumCPURegs);
|
||||
i = armul_rdi.CPUread (c, x, (ARMword *) p);
|
||||
MYwrite_char (kidmum[1], RDP_Return);
|
||||
for (k = 1, j = 0; k != 0x80000000; k *= 2)
|
||||
if (k & x)
|
||||
MYwrite_word (kidmum[1], ((ARMword *) p)[j++]);
|
||||
free (p);
|
||||
if (i)
|
||||
MYwrite_char (kidmum[1], (unsigned char) j);
|
||||
MYwrite_char (kidmum[1], (unsigned char) i);
|
||||
break;
|
||||
|
||||
case RDP_CPUwrite:
|
||||
/* Write CPU State */
|
||||
MYread_char (mumkid[0], &c); /* mode */
|
||||
MYread_word (mumkid[0], &x); /* mask */
|
||||
|
||||
p = (char *) malloc (4 * RDINumCPURegs);
|
||||
for (k = 1, j = 0; k != 0x80000000; k *= 2)
|
||||
if (k & x)
|
||||
MYread_word (mumkid[0], &(((ARMword *) p)[j++]));
|
||||
i = armul_rdi.CPUwrite (c, x, (ARMword *) p);
|
||||
MYwrite_char (kidmum[1], RDP_Return);
|
||||
MYwrite_char (kidmum[1], (unsigned char) i);
|
||||
free (p);
|
||||
break;
|
||||
|
||||
case RDP_CPread:
|
||||
/* Read Co-Processor State */
|
||||
MYread_char (mumkid[0], &c); /* CPnum */
|
||||
MYread_word (mumkid[0], &x); /* mask */
|
||||
p = q = (char *) malloc (16 * RDINumCPRegs);
|
||||
i = armul_rdi.CPread (c, x, (ARMword *) p);
|
||||
MYwrite_char (kidmum[1], RDP_Return);
|
||||
for (k = 1, j = 0; k != 0x80000000; k *= 2, j++)
|
||||
if (k & x)
|
||||
{
|
||||
if ((c == 1 || c == 2) && k <= 128)
|
||||
{
|
||||
MYwrite_FPword (kidmum[1], q);
|
||||
q += 16;
|
||||
}
|
||||
else
|
||||
{
|
||||
MYwrite_word (kidmum[1], *q);
|
||||
q += 4;
|
||||
}
|
||||
}
|
||||
free (p);
|
||||
if (i)
|
||||
MYwrite_char (kidmum[1], (unsigned char) j);
|
||||
MYwrite_char (kidmum[1], (unsigned char) i);
|
||||
break;
|
||||
|
||||
case RDP_CPwrite:
|
||||
/* Write Co-Processor State */
|
||||
MYread_char (mumkid[0], &c); /* CPnum */
|
||||
MYread_word (mumkid[0], &x); /* mask */
|
||||
p = q = (char *) malloc (16 * RDINumCPURegs);
|
||||
for (k = 1, j = 0; k != 0x80000000; k *= 2, j++)
|
||||
if (k & x)
|
||||
{
|
||||
if ((c == 1 || c == 2) && k <= 128)
|
||||
{
|
||||
MYread_FPword (kidmum[1], q);
|
||||
q += 16;
|
||||
}
|
||||
else
|
||||
{
|
||||
MYread_word (mumkid[0], (ARMword *) q);
|
||||
q += 4;
|
||||
}
|
||||
}
|
||||
i = armul_rdi.CPwrite (c, x, (ARMword *) p);
|
||||
MYwrite_char (kidmum[1], RDP_Return);
|
||||
MYwrite_char (kidmum[1], (unsigned char) i);
|
||||
free (p);
|
||||
break;
|
||||
|
||||
case RDP_SetBreak:
|
||||
/* Set Breakpoint */
|
||||
MYread_word (mumkid[0], &x); /* address */
|
||||
MYread_char (mumkid[0], &c); /* type */
|
||||
if ((c & 0xf) >= 5)
|
||||
MYread_word (mumkid[0], &y); /* bound */
|
||||
i = armul_rdi.setbreak (x, c, y, &point);
|
||||
if (!MYrdp_level)
|
||||
BAG_putpair ((long) x, (long) point);
|
||||
MYwrite_char (kidmum[1], RDP_Return);
|
||||
if (MYrdp_level)
|
||||
MYwrite_word (kidmum[1], point);
|
||||
MYwrite_char (kidmum[1], (unsigned char) i);
|
||||
break;
|
||||
|
||||
case RDP_ClearBreak:
|
||||
/* Clear Breakpoint */
|
||||
MYread_word (mumkid[0], &point); /* PointHandle */
|
||||
if (!MYrdp_level)
|
||||
{
|
||||
BAG_getsecond ((long) point, &outofthebag); /* swap pointhandle for address */
|
||||
BAG_killpair_byfirst (outofthebag);
|
||||
point = outofthebag;
|
||||
}
|
||||
i = armul_rdi.clearbreak (point);
|
||||
MYwrite_char (kidmum[1], RDP_Return);
|
||||
MYwrite_char (kidmum[1], (unsigned char) i);
|
||||
break;
|
||||
|
||||
case RDIInfo_Step:
|
||||
i = armul_rdi.info (RDIInfo_Step, &x, 0);
|
||||
case RDP_SetWatch:
|
||||
/* Set Watchpoint */
|
||||
MYread_word (mumkid[0], &x); /* address */
|
||||
MYread_char (mumkid[0], &c); /* type */
|
||||
MYread_char (mumkid[0], &d); /* datatype */
|
||||
if ((c & 0xf) >= 5)
|
||||
MYread_word (mumkid[0], &y); /* bound */
|
||||
i = armul_rdi.setwatch (x, c, d, y, &point);
|
||||
MYwrite_char (kidmum[1], RDP_Return);
|
||||
MYwrite_word (kidmum[1], x);
|
||||
MYwrite_word (kidmum[1], point);
|
||||
MYwrite_char (kidmum[1], (unsigned char) i);
|
||||
break;
|
||||
|
||||
case RDIVector_Catch:
|
||||
case RDP_ClearWatch:
|
||||
/* Clear Watchpoint */
|
||||
MYread_word (mumkid[0], &point); /* PointHandle */
|
||||
i = armul_rdi.clearwatch (point);
|
||||
MYwrite_char (kidmum[1], RDP_Return);
|
||||
MYwrite_char (kidmum[1], (unsigned char) i);
|
||||
break;
|
||||
|
||||
case RDP_Execute:
|
||||
/* Excecute */
|
||||
|
||||
MYread_char (mumkid[0], &c); /* return */
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr, "Starting execution\n");
|
||||
#endif
|
||||
i = armul_rdi.execute (&point);
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr, "Completed execution\n");
|
||||
#endif
|
||||
MYwrite_char (kidmum[1], RDP_Return);
|
||||
if (c & 0x80)
|
||||
MYwrite_word (kidmum[1], point);
|
||||
MYwrite_char (kidmum[1], (unsigned char) i);
|
||||
break;
|
||||
|
||||
case RDP_Step:
|
||||
/* Step */
|
||||
MYread_char (mumkid[0], &c); /* return */
|
||||
MYread_word (mumkid[0], &x); /* ninstr */
|
||||
point = 0x87654321;
|
||||
i = armul_rdi.step (x, &point);
|
||||
MYwrite_char (kidmum[1], RDP_Return);
|
||||
if (c & 0x80)
|
||||
MYwrite_word (kidmum[1], point);
|
||||
MYwrite_char (kidmum[1], (unsigned char) i);
|
||||
break;
|
||||
|
||||
case RDP_Info:
|
||||
/* Info */
|
||||
MYread_word (mumkid[0], &x);
|
||||
i = armul_rdi.info (RDIVector_Catch, &x, 0);
|
||||
MYwrite_char (kidmum[1], RDP_Return);
|
||||
MYwrite_char (kidmum[1], i);
|
||||
switch (x)
|
||||
{
|
||||
case RDIInfo_Target:
|
||||
i = armul_rdi.info (RDIInfo_Target, &y, &z);
|
||||
MYwrite_char (kidmum[1], RDP_Return);
|
||||
MYwrite_word (kidmum[1], y); /* Loads of info... */
|
||||
MYwrite_word (kidmum[1], z); /* Model */
|
||||
MYwrite_char (kidmum[1], (unsigned char) i);
|
||||
break;
|
||||
|
||||
case RDISet_RDILevel:
|
||||
MYread_word (mumkid[0], &x); /* arg1, debug level */
|
||||
i = armul_rdi.info (RDISet_RDILevel, &x, 0);
|
||||
if (i == RDIError_NoError)
|
||||
MYrdp_level = x;
|
||||
MYwrite_char (kidmum[1], RDP_Return);
|
||||
MYwrite_char (kidmum[1], (unsigned char) i);
|
||||
break;
|
||||
|
||||
case RDISet_Cmdline:
|
||||
for (p = command_line; MYread_char (mumkid[0], p), *p; p++)
|
||||
; /* String */
|
||||
i = armul_rdi.info (RDISet_Cmdline,
|
||||
(unsigned long *) command_line, 0);
|
||||
MYwrite_char (kidmum[1], RDP_Return);
|
||||
MYwrite_char (kidmum[1], (unsigned char) i);
|
||||
break;
|
||||
|
||||
case RDIInfo_Step:
|
||||
i = armul_rdi.info (RDIInfo_Step, &x, 0);
|
||||
MYwrite_char (kidmum[1], RDP_Return);
|
||||
MYwrite_word (kidmum[1], x);
|
||||
MYwrite_char (kidmum[1], (unsigned char) i);
|
||||
break;
|
||||
|
||||
case RDIVector_Catch:
|
||||
MYread_word (mumkid[0], &x);
|
||||
i = armul_rdi.info (RDIVector_Catch, &x, 0);
|
||||
MYwrite_char (kidmum[1], RDP_Return);
|
||||
MYwrite_char (kidmum[1], i);
|
||||
break;
|
||||
|
||||
case RDIInfo_Points:
|
||||
i = armul_rdi.info (RDIInfo_Points, &x, 0);
|
||||
MYwrite_char (kidmum[1], RDP_Return);
|
||||
MYwrite_word (kidmum[1], x);
|
||||
MYwrite_char (kidmum[1], (unsigned char) i);
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf (stderr, "Unsupported info code %d\n", x);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case RDIInfo_Points:
|
||||
i = armul_rdi.info (RDIInfo_Points, &x, 0);
|
||||
MYwrite_char (kidmum[1], RDP_Return);
|
||||
MYwrite_word (kidmum[1], x);
|
||||
MYwrite_char (kidmum[1], (unsigned char) i);
|
||||
case RDP_OSOpReply:
|
||||
/* OS Operation Reply */
|
||||
MYwrite_char (kidmum[1], RDP_Fatal);
|
||||
break;
|
||||
|
||||
case RDP_Reset:
|
||||
/* Reset */
|
||||
for (i = 0; i < 50; i++)
|
||||
MYwrite_char (kidmum[1], RDP_Reset);
|
||||
p = (char *) malloc (MAXHOSTNAMELENGTH + 5 + 20);
|
||||
sprintf (p, "Running on %s:%d\n", localhost, socketnumber);
|
||||
MYwrite_string (kidmum[1], p);
|
||||
free (p);
|
||||
|
||||
break;
|
||||
default:
|
||||
fprintf (stderr, "Unsupported info code %d\n", x);
|
||||
fprintf (stderr, "Oh dear: Something is seriously wrong :-(\n");
|
||||
/* Hmm.. bad RDP operation */
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case RDP_OSOpReply:
|
||||
/* OS Operation Reply */
|
||||
MYwrite_char (kidmum[1], RDP_Fatal);
|
||||
break;
|
||||
|
||||
case RDP_Reset:
|
||||
/* Reset */
|
||||
for (i = 0; i < 50; i++)
|
||||
MYwrite_char(kidmum[1], RDP_Reset);
|
||||
p = (char *) malloc(MAXHOSTNAMELENGTH + 5 + 20);
|
||||
sprintf(p, "Running on %s:%d\n", localhost, socketnumber);
|
||||
MYwrite_string(kidmum[1], p);
|
||||
free(p);
|
||||
|
||||
break;
|
||||
default:
|
||||
fprintf (stderr, "Oh dear: Something is seriously wrong :-(\n");
|
||||
/* Hmm.. bad RDP operation */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Handles memory read operations until an OS Operation Reply Message is */
|
||||
/* encounterd. It then returns the byte info value (0, 1, or 2) and fills */
|
||||
/* in 'putinr0' with the data if appropriate. */
|
||||
int wait_for_osreply(ARMword *reply)
|
||||
int
|
||||
wait_for_osreply (ARMword * reply)
|
||||
{
|
||||
char *p, *q;
|
||||
int i, j, k;
|
||||
@@ -432,79 +458,83 @@ int wait_for_osreply(ARMword *reply)
|
||||
struct Dbg_MCState *MCState;
|
||||
char command_line[256];
|
||||
struct fd_set readfds;
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "wait_for_osreply ().\n");
|
||||
fprintf (stderr, "wait_for_osreply ().\n");
|
||||
#endif
|
||||
|
||||
/* Setup a signal handler for SIGUSR1 */
|
||||
action.sa_handler = kid_handlesignal;
|
||||
action.sa_mask = 0;
|
||||
action.sa_flags = 0;
|
||||
|
||||
sigaction(SIGUSR1, &action, (struct sigaction *) 0);
|
||||
|
||||
while (1)
|
||||
{
|
||||
/* Wait for ever */
|
||||
FD_ZERO(&readfds);
|
||||
FD_SET(mumkid[0], &readfds);
|
||||
|
||||
i = select(nfds, &readfds,
|
||||
(fd_set *) 0,
|
||||
(fd_set *) 0,
|
||||
(struct timeval *) 0);
|
||||
|
||||
if (i < 0) {
|
||||
perror("select");
|
||||
}
|
||||
|
||||
if (read(mumkid[0], &message, 1) < 1) {
|
||||
perror("read");
|
||||
}
|
||||
|
||||
switch (message) {
|
||||
case RDP_Read :
|
||||
/* Read Memory Address */
|
||||
MYread_word(mumkid[0], &x); /* address */
|
||||
MYread_word(mumkid[0], &y); /* nbytes */
|
||||
p = (char *) malloc(y);
|
||||
i = armul_rdi.read(x, p, (unsigned *) &y);
|
||||
MYwrite_char(kidmum[1], RDP_Return);
|
||||
for (k = 0; k < y; k++)
|
||||
MYwrite_char(kidmum[1], p[k]);
|
||||
free(p);
|
||||
MYwrite_char(kidmum[1], (unsigned char) i);
|
||||
if (i)
|
||||
MYwrite_word(kidmum[1], y); /* number of bytes sent without error */
|
||||
break;
|
||||
|
||||
case RDP_Write :
|
||||
/* Write Memory Address */
|
||||
MYread_word(mumkid[0], &x); /* address */
|
||||
MYread_word(mumkid[0], &y); /* nbytes */
|
||||
p = (char *) malloc(y);
|
||||
for (k = 0; k < y; k++)
|
||||
MYread_char(mumkid[0], &p[k]);
|
||||
i = armul_rdi.write(p, x, (unsigned *) &y);
|
||||
free(p);
|
||||
MYwrite_char(kidmum[1], RDP_Return);
|
||||
MYwrite_char(kidmum[1], (unsigned char) i);
|
||||
if (i)
|
||||
MYwrite_word(kidmum[1], y); /* number of bytes sent without error */
|
||||
break;
|
||||
|
||||
case RDP_OSOpReply :
|
||||
/* OS Operation Reply */
|
||||
MYread_char(mumkid[0], &c);
|
||||
if (c == 1) MYread_char(mumkid[0], (char *) reply);
|
||||
if (c == 2) MYread_word(mumkid[0], reply);
|
||||
return c;
|
||||
break;
|
||||
|
||||
default :
|
||||
fprintf(stderr, "HELP! Unaccounted-for message during OS request. \n");
|
||||
MYwrite_char(kidmum[1], RDP_Fatal);
|
||||
sigaction (SIGUSR1, &action, (struct sigaction *) 0);
|
||||
|
||||
while (1)
|
||||
{
|
||||
/* Wait for ever */
|
||||
FD_ZERO (&readfds);
|
||||
FD_SET (mumkid[0], &readfds);
|
||||
|
||||
i = select (nfds, &readfds,
|
||||
(fd_set *) 0, (fd_set *) 0, (struct timeval *) 0);
|
||||
|
||||
if (i < 0)
|
||||
{
|
||||
perror ("select");
|
||||
}
|
||||
|
||||
if (read (mumkid[0], &message, 1) < 1)
|
||||
{
|
||||
perror ("read");
|
||||
}
|
||||
|
||||
switch (message)
|
||||
{
|
||||
case RDP_Read:
|
||||
/* Read Memory Address */
|
||||
MYread_word (mumkid[0], &x); /* address */
|
||||
MYread_word (mumkid[0], &y); /* nbytes */
|
||||
p = (char *) malloc (y);
|
||||
i = armul_rdi.read (x, p, (unsigned *) &y);
|
||||
MYwrite_char (kidmum[1], RDP_Return);
|
||||
for (k = 0; k < y; k++)
|
||||
MYwrite_char (kidmum[1], p[k]);
|
||||
free (p);
|
||||
MYwrite_char (kidmum[1], (unsigned char) i);
|
||||
if (i)
|
||||
MYwrite_word (kidmum[1], y); /* number of bytes sent without error */
|
||||
break;
|
||||
|
||||
case RDP_Write:
|
||||
/* Write Memory Address */
|
||||
MYread_word (mumkid[0], &x); /* address */
|
||||
MYread_word (mumkid[0], &y); /* nbytes */
|
||||
p = (char *) malloc (y);
|
||||
for (k = 0; k < y; k++)
|
||||
MYread_char (mumkid[0], &p[k]);
|
||||
i = armul_rdi.write (p, x, (unsigned *) &y);
|
||||
free (p);
|
||||
MYwrite_char (kidmum[1], RDP_Return);
|
||||
MYwrite_char (kidmum[1], (unsigned char) i);
|
||||
if (i)
|
||||
MYwrite_word (kidmum[1], y); /* number of bytes sent without error */
|
||||
break;
|
||||
|
||||
case RDP_OSOpReply:
|
||||
/* OS Operation Reply */
|
||||
MYread_char (mumkid[0], &c);
|
||||
if (c == 1)
|
||||
MYread_char (mumkid[0], (char *) reply);
|
||||
if (c == 2)
|
||||
MYread_word (mumkid[0], reply);
|
||||
return c;
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf (stderr,
|
||||
"HELP! Unaccounted-for message during OS request. \n");
|
||||
MYwrite_char (kidmum[1], RDP_Fatal);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
165
sim/arm/main.c
165
sim/arm/main.c
@@ -37,22 +37,22 @@
|
||||
|
||||
/* Read and write routines down sockets and pipes */
|
||||
|
||||
void MYread_chars(int sock, void *p, int n);
|
||||
unsigned char MYread_char(int sock);
|
||||
ARMword MYread_word(int sock);
|
||||
void MYread_FPword(int sock, char *putinhere);
|
||||
void MYread_chars (int sock, void *p, int n);
|
||||
unsigned char MYread_char (int sock);
|
||||
ARMword MYread_word (int sock);
|
||||
void MYread_FPword (int sock, char *putinhere);
|
||||
|
||||
void MYwrite_word(int sock, ARMword i);
|
||||
void MYwrite_string(int sock, char *s);
|
||||
void MYwrite_FPword(int sock, char *fromhere);
|
||||
void MYwrite_char(int sock, unsigned char c);
|
||||
void MYwrite_word (int sock, ARMword i);
|
||||
void MYwrite_string (int sock, char *s);
|
||||
void MYwrite_FPword (int sock, char *fromhere);
|
||||
void MYwrite_char (int sock, unsigned char c);
|
||||
|
||||
void passon(int source, int dest, int n);
|
||||
void passon (int source, int dest, int n);
|
||||
|
||||
|
||||
/* Mother and child processes */
|
||||
void parent (void);
|
||||
void kid(void);
|
||||
void kid (void);
|
||||
|
||||
/* The child process id. */
|
||||
pid_t child;
|
||||
@@ -86,98 +86,109 @@ unsigned int socketnumber;
|
||||
/* Opens a socket to the debugger, and once opened spawns the */
|
||||
/* ARMulator and sets up a couple of pipes. */
|
||||
/**************************************************************/
|
||||
int main(int argc, char *argv[]) {
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
int i;
|
||||
struct sockaddr_in devil, isa;
|
||||
struct hostent *hp;
|
||||
|
||||
|
||||
if (argc == 1) {
|
||||
fprintf(stderr, "No socket number\n");
|
||||
return 1;
|
||||
}
|
||||
if (argc == 1)
|
||||
{
|
||||
fprintf (stderr, "No socket number\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
sscanf(argv[1], "%d", &socketnumber);
|
||||
if (!socketnumber || socketnumber > 0xffff) {
|
||||
fprintf(stderr, "Invalid socket number: %d\n", socketnumber);
|
||||
return 1;
|
||||
}
|
||||
sscanf (argv[1], "%d", &socketnumber);
|
||||
if (!socketnumber || socketnumber > 0xffff)
|
||||
{
|
||||
fprintf (stderr, "Invalid socket number: %d\n", socketnumber);
|
||||
return 1;
|
||||
}
|
||||
|
||||
gethostname(localhost, MAXHOSTNAMELENGTH);
|
||||
hp = gethostbyname(localhost);
|
||||
if (!hp) {
|
||||
fprintf(stderr, "Cannot get local host info\n");
|
||||
return 1;
|
||||
}
|
||||
gethostname (localhost, MAXHOSTNAMELENGTH);
|
||||
hp = gethostbyname (localhost);
|
||||
if (!hp)
|
||||
{
|
||||
fprintf (stderr, "Cannot get local host info\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Open a socket */
|
||||
sockethandle = socket(hp->h_addrtype, SOCK_STREAM, 0);
|
||||
if (sockethandle < 0) {
|
||||
perror("socket");
|
||||
return 1;
|
||||
}
|
||||
sockethandle = socket (hp->h_addrtype, SOCK_STREAM, 0);
|
||||
if (sockethandle < 0)
|
||||
{
|
||||
perror ("socket");
|
||||
return 1;
|
||||
}
|
||||
|
||||
devil.sin_family = hp->h_addrtype;
|
||||
devil.sin_port = htons(socketnumber);
|
||||
devil.sin_port = htons (socketnumber);
|
||||
devil.sin_addr.s_addr = 0;
|
||||
for(i = 0; i < sizeof(devil.sin_zero); i++) devil.sin_zero[i] = '\000';
|
||||
memcpy(&devil.sin_addr, hp->h_addr_list[0], hp->h_length);
|
||||
for (i = 0; i < sizeof (devil.sin_zero); i++)
|
||||
devil.sin_zero[i] = '\000';
|
||||
memcpy (&devil.sin_addr, hp->h_addr_list[0], hp->h_length);
|
||||
|
||||
if (bind(sockethandle, &devil, sizeof(devil)) < 0) {
|
||||
perror("bind");
|
||||
return 1;
|
||||
}
|
||||
if (bind (sockethandle, &devil, sizeof (devil)) < 0)
|
||||
{
|
||||
perror ("bind");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* May only accept one debugger at once */
|
||||
|
||||
if (listen(sockethandle, 0)) {
|
||||
perror("listen");
|
||||
return 1;
|
||||
}
|
||||
if (listen (sockethandle, 0))
|
||||
{
|
||||
perror ("listen");
|
||||
return 1;
|
||||
}
|
||||
|
||||
fprintf(stderr, "Waiting for connection from debugger...");
|
||||
fprintf (stderr, "Waiting for connection from debugger...");
|
||||
|
||||
debugsock = accept(sockethandle, &isa, &i);
|
||||
if (debugsock < 0) {
|
||||
perror("accept");
|
||||
return 1;
|
||||
}
|
||||
|
||||
fprintf(stderr, " done.\nConnection Established.\n");
|
||||
debugsock = accept (sockethandle, &isa, &i);
|
||||
if (debugsock < 0)
|
||||
{
|
||||
perror ("accept");
|
||||
return 1;
|
||||
}
|
||||
|
||||
nfds = getdtablesize();
|
||||
fprintf (stderr, " done.\nConnection Established.\n");
|
||||
|
||||
if (pipe(mumkid)) {
|
||||
perror("pipe");
|
||||
return 1;
|
||||
}
|
||||
if (pipe(kidmum)) {
|
||||
perror("pipe");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (pipe(DebuggerARMul)) {
|
||||
perror("pipe");
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "Created pipes ok\n");
|
||||
#endif
|
||||
nfds = getdtablesize ();
|
||||
|
||||
child = fork();
|
||||
if (pipe (mumkid))
|
||||
{
|
||||
perror ("pipe");
|
||||
return 1;
|
||||
}
|
||||
if (pipe (kidmum))
|
||||
{
|
||||
perror ("pipe");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (pipe (DebuggerARMul))
|
||||
{
|
||||
perror ("pipe");
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "fork() ok\n");
|
||||
fprintf (stderr, "Created pipes ok\n");
|
||||
#endif
|
||||
|
||||
if (child == 0) kid ();
|
||||
if (child != -1) parent ();
|
||||
child = fork ();
|
||||
|
||||
perror("fork");
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr, "fork() ok\n");
|
||||
#endif
|
||||
|
||||
if (child == 0)
|
||||
kid ();
|
||||
if (child != -1)
|
||||
parent ();
|
||||
|
||||
perror ("fork");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
752
sim/arm/parent.c
752
sim/arm/parent.c
@@ -61,423 +61,421 @@ parent ()
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr, "parent ()...\n");
|
||||
#endif
|
||||
|
||||
panic_error:
|
||||
|
||||
panic_error:
|
||||
|
||||
if (!virgin)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "Arghh! What is going on?\n");
|
||||
fprintf (stderr, "Arghh! What is going on?\n");
|
||||
#endif
|
||||
kill (child, SIGHUP);
|
||||
MYwrite_char(debugsock, RDP_Reset);
|
||||
MYwrite_char (debugsock, RDP_Reset);
|
||||
}
|
||||
|
||||
|
||||
virgin = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
|
||||
/* Wait either for the ARMulator or the debugger */
|
||||
|
||||
FD_ZERO (&readfds);
|
||||
FD_SET (kidmum[0], &readfds); /* Wait for messages from ARMulator */
|
||||
FD_SET (debugsock, &readfds); /* Wait for messages from debugger */
|
||||
|
||||
/* Wait either for the ARMulator or the debugger */
|
||||
|
||||
FD_ZERO (&readfds);
|
||||
FD_SET (kidmum[0], &readfds); /* Wait for messages from ARMulator */
|
||||
FD_SET (debugsock, &readfds); /* Wait for messages from debugger */
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr, "Waiting for ARMulator or debugger... ");
|
||||
#endif
|
||||
|
||||
while ((i = select (nfds, &readfds, (fd_set *) 0, (fd_set *) 0, 0)) < 0)
|
||||
{
|
||||
perror ("select");
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "(%d/2)", i);
|
||||
fprintf (stderr, "Waiting for ARMulator or debugger... ");
|
||||
#endif
|
||||
|
||||
if (FD_ISSET (debugsock, &readfds)) {
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr, "->debugger\n");
|
||||
#endif
|
||||
|
||||
/* Inside this rather large if statement with simply pass on a complete
|
||||
message to the ARMulator. The reason we need to pass messages on one
|
||||
at a time is that we have to know whether the message is an OSOpReply
|
||||
or an info(stop), so that we can take different action in those
|
||||
cases. */
|
||||
|
||||
if (MYread_char (debugsock, &message))
|
||||
goto panic_error;
|
||||
|
||||
switch (message)
|
||||
while ((i = select (nfds, &readfds, (fd_set *) 0, (fd_set *) 0, 0)) < 0)
|
||||
{
|
||||
case RDP_Start:
|
||||
/* Open and/or Initialise */
|
||||
perror ("select");
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr, "RDP Open\n");
|
||||
fprintf (stderr, "(%d/2)", i);
|
||||
#endif
|
||||
if (MYread_char(debugsock, &c)) /* type */
|
||||
|
||||
if (FD_ISSET (debugsock, &readfds))
|
||||
{
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr, "->debugger\n");
|
||||
#endif
|
||||
|
||||
/* Inside this rather large if statement with simply pass on a complete
|
||||
message to the ARMulator. The reason we need to pass messages on one
|
||||
at a time is that we have to know whether the message is an OSOpReply
|
||||
or an info(stop), so that we can take different action in those
|
||||
cases. */
|
||||
|
||||
if (MYread_char (debugsock, &message))
|
||||
goto panic_error;
|
||||
|
||||
if (MYread_word(debugsock, &x)) /* memory size */
|
||||
goto panic_error;
|
||||
|
||||
MYwrite_char (mumkid[1], message);
|
||||
MYwrite_char (mumkid[1], c);
|
||||
MYwrite_word (mumkid[1], x);
|
||||
if (c & 0x2)
|
||||
switch (message)
|
||||
{
|
||||
passon (debugsock, mumkid[1], 1); /* speed */
|
||||
}
|
||||
break;
|
||||
|
||||
case RDP_End:
|
||||
/* Close and Finalise */
|
||||
case RDP_Start:
|
||||
/* Open and/or Initialise */
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "RDP Close\n");
|
||||
fprintf (stderr, "RDP Open\n");
|
||||
#endif
|
||||
MYwrite_char (mumkid[1], message);
|
||||
break;
|
||||
|
||||
case RDP_Read:
|
||||
/* Read Memory Address */
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr, "RDP Read Memory\n");
|
||||
#endif
|
||||
MYwrite_char (mumkid[1], message);
|
||||
if (passon (debugsock, mumkid[1], 4))
|
||||
goto panic_error; /* address */
|
||||
if (MYread_word(debugsock, &nbytes))
|
||||
goto panic_error; /* nbytes */
|
||||
MYwrite_word (mumkid[1], nbytes);
|
||||
break;
|
||||
|
||||
case RDP_Write :
|
||||
/* Write Memory Address */
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr, "RDP Write Memory\n");
|
||||
#endif
|
||||
if (MYread_word (debugsock, &x))
|
||||
goto panic_error; /* address */
|
||||
if (MYread_char (debugsock, &c)) /* type */
|
||||
goto panic_error;
|
||||
|
||||
if (MYread_word (debugsock, &y))
|
||||
goto panic_error; /* nbytes */
|
||||
if (MYread_word (debugsock, &x)) /* memory size */
|
||||
goto panic_error;
|
||||
|
||||
MYwrite_char (mumkid[1], message);
|
||||
MYwrite_word (mumkid[1], x);
|
||||
MYwrite_word (mumkid[1], y);
|
||||
passon (debugsock, mumkid[1], y); /* actual data */
|
||||
break;
|
||||
|
||||
case RDP_CPUread:
|
||||
/* Read CPU State */
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr, "RDP Read CPU\n");
|
||||
#endif
|
||||
if (MYread_char(debugsock, &c))
|
||||
goto panic_error; /* mode */
|
||||
|
||||
if (MYread_word (debugsock, &mask))
|
||||
goto panic_error; /* mask */
|
||||
|
||||
MYwrite_char (mumkid[1], message);
|
||||
MYwrite_char (mumkid[1], c);
|
||||
MYwrite_word (mumkid[1], mask);
|
||||
break;
|
||||
|
||||
case RDP_CPUwrite :
|
||||
/* Write CPU State */
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr, "RDP Write CPU\n");
|
||||
#endif
|
||||
if (MYread_char (debugsock, &c))
|
||||
goto panic_error; /* mode */
|
||||
|
||||
if (MYread_word (debugsock, &x))
|
||||
goto panic_error; /* mask */
|
||||
|
||||
MYwrite_char (mumkid[1], message);
|
||||
MYwrite_char (mumkid[1], c);
|
||||
MYwrite_word (mumkid[1], x);
|
||||
for (k = 1, j = 0; k != 0x80000000; k *= 2, j++)
|
||||
if ((k & x)
|
||||
&& passon(debugsock, mumkid[1], 4))
|
||||
goto panic_error;
|
||||
break;
|
||||
|
||||
case RDP_CPread:
|
||||
/* Read Co-Processor State */
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr, "RDP Read CP state\n");
|
||||
#endif
|
||||
if (MYread_char (debugsock, &CPnum))
|
||||
goto panic_error;
|
||||
|
||||
if (MYread_word (debugsock, &mask))
|
||||
goto panic_error;
|
||||
|
||||
MYwrite_char (mumkid[1], message);
|
||||
MYwrite_char (mumkid[1], CPnum);
|
||||
MYwrite_word (mumkid[1], mask);
|
||||
break;
|
||||
|
||||
case RDP_CPwrite:
|
||||
/* Write Co-Processor State */
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "RDP Write CP state\n");
|
||||
#endif
|
||||
if (MYread_char (debugsock, &CPnum))
|
||||
goto panic_error;
|
||||
|
||||
if (MYread_word (debugsock, &mask))
|
||||
goto panic_error;
|
||||
|
||||
MYwrite_char (mumkid[1], message);
|
||||
MYwrite_char (mumkid[1], c);
|
||||
MYwrite_char (mumkid[1], x);
|
||||
for (k = 1, j = 0; k != 0x80000000; k *= 2, j++)
|
||||
if (k & x)
|
||||
{
|
||||
if ((c == 1 || c == 2) && k <= 128)
|
||||
{
|
||||
/* FP register = 12 bytes + 4 bytes format */
|
||||
if (passon(debugsock, mumkid[1], 16))
|
||||
goto panic_error;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Normal register = 4 bytes */
|
||||
if (passon(debugsock, mumkid[1], 4))
|
||||
goto panic_error;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case RDP_SetBreak:
|
||||
/* Set Breakpoint */
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr, "RDP Set Breakpoint\n");
|
||||
#endif
|
||||
if (MYread_word (debugsock, &x))
|
||||
goto panic_error; /* address */
|
||||
|
||||
if (MYread_char (debugsock, &c))
|
||||
goto panic_error; /* type */
|
||||
|
||||
MYwrite_char (mumkid[1], message);
|
||||
MYwrite_word (mumkid[1], x);
|
||||
MYwrite_char (mumkid[1], c);
|
||||
if (((c & 0xf) >= 5)
|
||||
&& passon(debugsock, mumkid[1], 4))
|
||||
goto panic_error; /* bound */
|
||||
break;
|
||||
|
||||
case RDP_ClearBreak:
|
||||
/* Clear Breakpoint */
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr, "RDP Clear Breakpoint\n");
|
||||
#endif
|
||||
MYwrite_char (mumkid[1], message);
|
||||
if (passon (debugsock, mumkid[1], 4))
|
||||
goto panic_error; /* point */
|
||||
break;
|
||||
|
||||
case RDP_SetWatch:
|
||||
/* Set Watchpoint */
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr, "RDP Set Watchpoint\n");
|
||||
#endif
|
||||
if (MYread_word (debugsock, &x))
|
||||
goto panic_error; /* address */
|
||||
|
||||
if (MYread_char(debugsock, &c))
|
||||
goto panic_error; /* type */
|
||||
|
||||
if (MYread_char (debugsock, &d))
|
||||
goto panic_error; /* datatype */
|
||||
|
||||
MYwrite_char (mumkid[1], message);
|
||||
MYwrite_word (mumkid[1], x);
|
||||
MYwrite_char (mumkid[1], c);
|
||||
MYwrite_char (mumkid[1], d);
|
||||
if (((c & 0xf) >= 5)
|
||||
&& passon(debugsock, mumkid[1], 4))
|
||||
goto panic_error; /* bound */
|
||||
break;
|
||||
|
||||
case RDP_ClearWatch:
|
||||
/* Clear Watchpoint */
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr, "RDP Clear Watchpoint\n");
|
||||
#endif
|
||||
MYwrite_char (mumkid[1], message);
|
||||
if (passon (debugsock, mumkid[1], 4))
|
||||
goto panic_error; /* point */
|
||||
break;
|
||||
|
||||
case RDP_Execute:
|
||||
/* Excecute */
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr, "RDP Execute\n");
|
||||
#endif
|
||||
|
||||
/* LEAVE THIS ONE 'TIL LATER... */
|
||||
/* NEED TO WORK THINGS OUT */
|
||||
|
||||
/* NO ASCYNCHROUS RUNNING */
|
||||
|
||||
if (MYread_char(debugsock, &c))
|
||||
goto panic_error; /* return */
|
||||
|
||||
/* Remember incase bit 7 is set and we have to send back a word */
|
||||
exreturn = c;
|
||||
|
||||
MYwrite_char(mumkid[1], message);
|
||||
MYwrite_char(mumkid[1], c);
|
||||
break;
|
||||
|
||||
case RDP_Step:
|
||||
/* Step */
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr, "RDP Step\n");
|
||||
#endif
|
||||
|
||||
if (MYread_char(debugsock, &c))
|
||||
goto panic_error; /* return */
|
||||
|
||||
if (MYread_word(debugsock, &x))
|
||||
goto panic_error; /* ninstr */
|
||||
|
||||
MYwrite_char (mumkid[1], message);
|
||||
MYwrite_char (mumkid[1], c);
|
||||
MYwrite_word (mumkid[1], x);
|
||||
break;
|
||||
|
||||
case RDP_Info:
|
||||
/* Info */
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr, "RDP Info\n");
|
||||
#endif
|
||||
/* INFO TARGET, SET RDI LEVEL */
|
||||
if (MYread_word (debugsock, &messagetype))
|
||||
goto panic_error; /* info */
|
||||
|
||||
switch (messagetype)
|
||||
{
|
||||
case RDIInfo_Target:
|
||||
MYwrite_char (mumkid[1], message);
|
||||
MYwrite_word (mumkid[1], messagetype);
|
||||
break;
|
||||
|
||||
case RDISet_RDILevel:
|
||||
MYwrite_char (mumkid[1], message);
|
||||
MYwrite_word (mumkid[1], messagetype);
|
||||
if (passon (debugsock, mumkid[1], 1))
|
||||
goto panic_error; /* argument */
|
||||
break;
|
||||
|
||||
case RDISet_Cmdline:
|
||||
/* Got to pass on a string argument */
|
||||
MYwrite_char (mumkid[1], message);
|
||||
MYwrite_word (mumkid[1], messagetype);
|
||||
do
|
||||
MYwrite_char (mumkid[1], c);
|
||||
MYwrite_word (mumkid[1], x);
|
||||
if (c & 0x2)
|
||||
{
|
||||
passon (debugsock, mumkid[1], 1); /* speed */
|
||||
}
|
||||
break;
|
||||
|
||||
case RDP_End:
|
||||
/* Close and Finalise */
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr, "RDP Close\n");
|
||||
#endif
|
||||
MYwrite_char (mumkid[1], message);
|
||||
break;
|
||||
|
||||
case RDP_Read:
|
||||
/* Read Memory Address */
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr, "RDP Read Memory\n");
|
||||
#endif
|
||||
MYwrite_char (mumkid[1], message);
|
||||
if (passon (debugsock, mumkid[1], 4))
|
||||
goto panic_error; /* address */
|
||||
if (MYread_word (debugsock, &nbytes))
|
||||
goto panic_error; /* nbytes */
|
||||
MYwrite_word (mumkid[1], nbytes);
|
||||
break;
|
||||
|
||||
case RDP_Write:
|
||||
/* Write Memory Address */
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr, "RDP Write Memory\n");
|
||||
#endif
|
||||
if (MYread_word (debugsock, &x))
|
||||
goto panic_error; /* address */
|
||||
|
||||
if (MYread_word (debugsock, &y))
|
||||
goto panic_error; /* nbytes */
|
||||
|
||||
MYwrite_char (mumkid[1], message);
|
||||
MYwrite_word (mumkid[1], x);
|
||||
MYwrite_word (mumkid[1], y);
|
||||
passon (debugsock, mumkid[1], y); /* actual data */
|
||||
break;
|
||||
|
||||
case RDP_CPUread:
|
||||
/* Read CPU State */
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr, "RDP Read CPU\n");
|
||||
#endif
|
||||
if (MYread_char (debugsock, &c))
|
||||
goto panic_error; /* mode */
|
||||
|
||||
if (MYread_word (debugsock, &mask))
|
||||
goto panic_error; /* mask */
|
||||
|
||||
MYwrite_char (mumkid[1], message);
|
||||
MYwrite_char (mumkid[1], c);
|
||||
MYwrite_word (mumkid[1], mask);
|
||||
break;
|
||||
|
||||
case RDP_CPUwrite:
|
||||
/* Write CPU State */
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr, "RDP Write CPU\n");
|
||||
#endif
|
||||
if (MYread_char (debugsock, &c))
|
||||
goto panic_error; /* mode */
|
||||
|
||||
if (MYread_word (debugsock, &x))
|
||||
goto panic_error; /* mask */
|
||||
|
||||
MYwrite_char (mumkid[1], message);
|
||||
MYwrite_char (mumkid[1], c);
|
||||
MYwrite_word (mumkid[1], x);
|
||||
for (k = 1, j = 0; k != 0x80000000; k *= 2, j++)
|
||||
if ((k & x) && passon (debugsock, mumkid[1], 4))
|
||||
goto panic_error;
|
||||
break;
|
||||
|
||||
case RDP_CPread:
|
||||
/* Read Co-Processor State */
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr, "RDP Read CP state\n");
|
||||
#endif
|
||||
if (MYread_char (debugsock, &CPnum))
|
||||
goto panic_error;
|
||||
|
||||
if (MYread_word (debugsock, &mask))
|
||||
goto panic_error;
|
||||
|
||||
MYwrite_char (mumkid[1], message);
|
||||
MYwrite_char (mumkid[1], CPnum);
|
||||
MYwrite_word (mumkid[1], mask);
|
||||
break;
|
||||
|
||||
case RDP_CPwrite:
|
||||
/* Write Co-Processor State */
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr, "RDP Write CP state\n");
|
||||
#endif
|
||||
if (MYread_char (debugsock, &CPnum))
|
||||
goto panic_error;
|
||||
|
||||
if (MYread_word (debugsock, &mask))
|
||||
goto panic_error;
|
||||
|
||||
MYwrite_char (mumkid[1], message);
|
||||
MYwrite_char (mumkid[1], c);
|
||||
MYwrite_char (mumkid[1], x);
|
||||
for (k = 1, j = 0; k != 0x80000000; k *= 2, j++)
|
||||
if (k & x)
|
||||
{
|
||||
if ((c == 1 || c == 2) && k <= 128)
|
||||
{
|
||||
/* FP register = 12 bytes + 4 bytes format */
|
||||
if (passon (debugsock, mumkid[1], 16))
|
||||
goto panic_error;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Normal register = 4 bytes */
|
||||
if (passon (debugsock, mumkid[1], 4))
|
||||
goto panic_error;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case RDP_SetBreak:
|
||||
/* Set Breakpoint */
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr, "RDP Set Breakpoint\n");
|
||||
#endif
|
||||
if (MYread_word (debugsock, &x))
|
||||
goto panic_error; /* address */
|
||||
|
||||
if (MYread_char (debugsock, &c))
|
||||
goto panic_error; /* type */
|
||||
|
||||
MYwrite_char (mumkid[1], message);
|
||||
MYwrite_word (mumkid[1], x);
|
||||
MYwrite_char (mumkid[1], c);
|
||||
if (((c & 0xf) >= 5) && passon (debugsock, mumkid[1], 4))
|
||||
goto panic_error; /* bound */
|
||||
break;
|
||||
|
||||
case RDP_ClearBreak:
|
||||
/* Clear Breakpoint */
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr, "RDP Clear Breakpoint\n");
|
||||
#endif
|
||||
MYwrite_char (mumkid[1], message);
|
||||
if (passon (debugsock, mumkid[1], 4))
|
||||
goto panic_error; /* point */
|
||||
break;
|
||||
|
||||
case RDP_SetWatch:
|
||||
/* Set Watchpoint */
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr, "RDP Set Watchpoint\n");
|
||||
#endif
|
||||
if (MYread_word (debugsock, &x))
|
||||
goto panic_error; /* address */
|
||||
|
||||
if (MYread_char (debugsock, &c))
|
||||
goto panic_error; /* type */
|
||||
|
||||
if (MYread_char (debugsock, &d))
|
||||
goto panic_error; /* datatype */
|
||||
|
||||
MYwrite_char (mumkid[1], message);
|
||||
MYwrite_word (mumkid[1], x);
|
||||
MYwrite_char (mumkid[1], c);
|
||||
MYwrite_char (mumkid[1], d);
|
||||
if (((c & 0xf) >= 5) && passon (debugsock, mumkid[1], 4))
|
||||
goto panic_error; /* bound */
|
||||
break;
|
||||
|
||||
case RDP_ClearWatch:
|
||||
/* Clear Watchpoint */
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr, "RDP Clear Watchpoint\n");
|
||||
#endif
|
||||
MYwrite_char (mumkid[1], message);
|
||||
if (passon (debugsock, mumkid[1], 4))
|
||||
goto panic_error; /* point */
|
||||
break;
|
||||
|
||||
case RDP_Execute:
|
||||
/* Excecute */
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr, "RDP Execute\n");
|
||||
#endif
|
||||
|
||||
/* LEAVE THIS ONE 'TIL LATER... */
|
||||
/* NEED TO WORK THINGS OUT */
|
||||
|
||||
/* NO ASCYNCHROUS RUNNING */
|
||||
|
||||
if (MYread_char (debugsock, &c))
|
||||
goto panic_error; /* return */
|
||||
|
||||
/* Remember incase bit 7 is set and we have to send back a word */
|
||||
exreturn = c;
|
||||
|
||||
MYwrite_char (mumkid[1], message);
|
||||
MYwrite_char (mumkid[1], c);
|
||||
break;
|
||||
|
||||
case RDP_Step:
|
||||
/* Step */
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr, "RDP Step\n");
|
||||
#endif
|
||||
|
||||
if (MYread_char (debugsock, &c))
|
||||
goto panic_error; /* return */
|
||||
|
||||
if (MYread_word (debugsock, &x))
|
||||
goto panic_error; /* ninstr */
|
||||
|
||||
MYwrite_char (mumkid[1], message);
|
||||
MYwrite_char (mumkid[1], c);
|
||||
MYwrite_word (mumkid[1], x);
|
||||
break;
|
||||
|
||||
case RDP_Info:
|
||||
/* Info */
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr, "RDP Info\n");
|
||||
#endif
|
||||
/* INFO TARGET, SET RDI LEVEL */
|
||||
if (MYread_word (debugsock, &messagetype))
|
||||
goto panic_error; /* info */
|
||||
|
||||
switch (messagetype)
|
||||
{
|
||||
case RDIInfo_Target:
|
||||
MYwrite_char (mumkid[1], message);
|
||||
MYwrite_word (mumkid[1], messagetype);
|
||||
break;
|
||||
|
||||
case RDISet_RDILevel:
|
||||
MYwrite_char (mumkid[1], message);
|
||||
MYwrite_word (mumkid[1], messagetype);
|
||||
if (passon (debugsock, mumkid[1], 1))
|
||||
goto panic_error; /* argument */
|
||||
break;
|
||||
|
||||
case RDISet_Cmdline:
|
||||
/* Got to pass on a string argument */
|
||||
MYwrite_char (mumkid[1], message);
|
||||
MYwrite_word (mumkid[1], messagetype);
|
||||
do
|
||||
{
|
||||
if (MYread_char (debugsock, &c))
|
||||
goto panic_error;
|
||||
|
||||
MYwrite_char (mumkid[1], c);
|
||||
}
|
||||
while (c);
|
||||
break;
|
||||
|
||||
case RDISignal_Stop:
|
||||
kill (child, SIGUSR1);
|
||||
MYwrite_char (debugsock, RDP_Return);
|
||||
MYwrite_char (debugsock, RDIError_UserInterrupt);
|
||||
break;
|
||||
|
||||
case RDIVector_Catch:
|
||||
MYread_word (debugsock, &x);
|
||||
MYwrite_char (mumkid[1], message);
|
||||
MYwrite_word (mumkid[1], messagetype);
|
||||
MYwrite_word (mumkid[1], x);
|
||||
break;
|
||||
|
||||
case RDIInfo_Step:
|
||||
MYwrite_char (mumkid[1], message);
|
||||
MYwrite_word (mumkid[1], messagetype);
|
||||
break;
|
||||
|
||||
case RDIInfo_Points:
|
||||
MYwrite_char (mumkid[1], message);
|
||||
MYwrite_word (mumkid[1], messagetype);
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf (stderr, "Unrecognized RDIInfo request %d\n",
|
||||
messagetype);
|
||||
goto panic_error;
|
||||
}
|
||||
break;
|
||||
|
||||
case RDP_OSOpReply:
|
||||
/* OS Operation Reply */
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr, "RDP OS Reply\n");
|
||||
#endif
|
||||
MYwrite_char (mumkid[1], message);
|
||||
if (MYread_char (debugsock, &message))
|
||||
goto panic_error;
|
||||
MYwrite_char (mumkid[1], message);
|
||||
switch (message)
|
||||
{
|
||||
case 0: /* return value i.e. nothing else. */
|
||||
break;
|
||||
|
||||
case 1: /* returns a byte... */
|
||||
if (MYread_char (debugsock, &c))
|
||||
goto panic_error;
|
||||
|
||||
MYwrite_char (mumkid[1], c);
|
||||
} while (c);
|
||||
break;
|
||||
|
||||
case 2: /* returns a word... */
|
||||
if (MYread_word (debugsock, &x))
|
||||
goto panic_error;
|
||||
|
||||
MYwrite_word (mumkid[1], x);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case RDISignal_Stop:
|
||||
kill (child, SIGUSR1);
|
||||
MYwrite_char (debugsock, RDP_Return);
|
||||
MYwrite_char (debugsock, RDIError_UserInterrupt);
|
||||
break;
|
||||
|
||||
case RDIVector_Catch:
|
||||
MYread_word (debugsock, &x);
|
||||
case RDP_Reset:
|
||||
/* Reset */
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr, "RDP Reset\n");
|
||||
#endif
|
||||
MYwrite_char (mumkid[1], message);
|
||||
MYwrite_word (mumkid[1], messagetype);
|
||||
MYwrite_word (mumkid[1], x);
|
||||
break;
|
||||
|
||||
case RDIInfo_Step:
|
||||
MYwrite_char (mumkid[1], message);
|
||||
MYwrite_word (mumkid[1], messagetype);
|
||||
break;
|
||||
|
||||
case RDIInfo_Points:
|
||||
MYwrite_char (mumkid[1], message);
|
||||
MYwrite_word (mumkid[1], messagetype);
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf (stderr, "Unrecognized RDIInfo request %d\n",
|
||||
messagetype);
|
||||
goto panic_error;
|
||||
}
|
||||
break;
|
||||
|
||||
case RDP_OSOpReply:
|
||||
/* OS Operation Reply */
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr, "RDP OS Reply\n");
|
||||
#endif
|
||||
MYwrite_char (mumkid[1], message);
|
||||
if (MYread_char (debugsock, &message))
|
||||
goto panic_error;
|
||||
MYwrite_char (mumkid[1], message);
|
||||
switch(message)
|
||||
{
|
||||
case 0: /* return value i.e. nothing else.*/
|
||||
break;
|
||||
|
||||
case 1: /* returns a byte... */
|
||||
if (MYread_char(debugsock, &c))
|
||||
goto panic_error;
|
||||
|
||||
MYwrite_char (mumkid[1], c);
|
||||
break;
|
||||
|
||||
case 2: /* returns a word... */
|
||||
if (MYread_word(debugsock, &x))
|
||||
goto panic_error;
|
||||
|
||||
MYwrite_word (mumkid[1], x);
|
||||
/* Hmm.. bad RDP operation */
|
||||
fprintf (stderr, "RDP Bad RDP request (%d)\n", message);
|
||||
MYwrite_char (debugsock, RDP_Return);
|
||||
MYwrite_char (debugsock, RDIError_UnimplementedMessage);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case RDP_Reset:
|
||||
/* Reset */
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr, "RDP Reset\n");
|
||||
#endif
|
||||
MYwrite_char (mumkid[1], message);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
/* Hmm.. bad RDP operation */
|
||||
fprintf (stderr, "RDP Bad RDP request (%d)\n", message);
|
||||
MYwrite_char (debugsock, RDP_Return);
|
||||
MYwrite_char (debugsock, RDIError_UnimplementedMessage);
|
||||
break;
|
||||
if (FD_ISSET (kidmum[0], &readfds))
|
||||
{
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr, "->ARMulator\n");
|
||||
#endif
|
||||
/* Anything we get from the ARMulator has to go to the debugger... */
|
||||
/* It is that simple! */
|
||||
|
||||
passon (kidmum[0], debugsock, 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (FD_ISSET (kidmum[0], &readfds))
|
||||
{
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr, "->ARMulator\n");
|
||||
#endif
|
||||
/* Anything we get from the ARMulator has to go to the debugger... */
|
||||
/* It is that simple! */
|
||||
|
||||
passon (kidmum[0], debugsock, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
instruction into its corresponding ARM instruction, and using the
|
||||
existing ARM simulator. */
|
||||
|
||||
#ifndef MODET /* required for the Thumb instruction support */
|
||||
#ifndef MODET /* required for the Thumb instruction support */
|
||||
#if 1
|
||||
#error "MODET needs to be defined for the Thumb world to work"
|
||||
#else
|
||||
@@ -36,16 +36,19 @@ existing ARM simulator. */
|
||||
held in the high 16-bits. Passing in two Thumb instructions allows
|
||||
easier simulation of the special dual BL instruction. */
|
||||
|
||||
tdstate
|
||||
ARMul_ThumbDecode (state,pc,tinstr,ainstr)
|
||||
ARMul_State *state;
|
||||
ARMword pc;
|
||||
ARMword tinstr;
|
||||
ARMword *ainstr;
|
||||
tdstate ARMul_ThumbDecode (state, pc, tinstr, ainstr)
|
||||
ARMul_State *
|
||||
state;
|
||||
ARMword
|
||||
pc;
|
||||
ARMword
|
||||
tinstr;
|
||||
ARMword *
|
||||
ainstr;
|
||||
{
|
||||
tdstate valid = t_decoded; /* default assumes a valid instruction */
|
||||
tdstate valid = t_decoded; /* default assumes a valid instruction */
|
||||
ARMword next_instr;
|
||||
|
||||
|
||||
if (state->bigendSig)
|
||||
{
|
||||
next_instr = tinstr & 0xFFFF;
|
||||
@@ -56,166 +59,171 @@ ARMul_ThumbDecode (state,pc,tinstr,ainstr)
|
||||
next_instr = tinstr >> 16;
|
||||
tinstr &= 0xFFFF;
|
||||
}
|
||||
|
||||
#if 1 /* debugging to catch non updates */
|
||||
|
||||
#if 1 /* debugging to catch non updates */
|
||||
*ainstr = 0xDEADC0DE;
|
||||
#endif
|
||||
|
||||
switch ((tinstr & 0xF800) >> 11)
|
||||
{
|
||||
case 0: /* LSL */
|
||||
case 1: /* LSR */
|
||||
case 2: /* ASR */
|
||||
case 0: /* LSL */
|
||||
case 1: /* LSR */
|
||||
case 2: /* ASR */
|
||||
/* Format 1 */
|
||||
*ainstr = 0xE1B00000 /* base opcode */
|
||||
| ((tinstr & 0x1800) >> (11 - 5)) /* shift type */
|
||||
| ((tinstr & 0x07C0) << (7 - 6)) /* imm5 */
|
||||
| ((tinstr & 0x0038) >> 3) /* Rs */
|
||||
| ((tinstr & 0x0007) << 12); /* Rd */
|
||||
*ainstr = 0xE1B00000 /* base opcode */
|
||||
| ((tinstr & 0x1800) >> (11 - 5)) /* shift type */
|
||||
| ((tinstr & 0x07C0) << (7 - 6)) /* imm5 */
|
||||
| ((tinstr & 0x0038) >> 3) /* Rs */
|
||||
| ((tinstr & 0x0007) << 12); /* Rd */
|
||||
break;
|
||||
case 3: /* ADD/SUB */
|
||||
case 3: /* ADD/SUB */
|
||||
/* Format 2 */
|
||||
{
|
||||
ARMword subset[4] = {
|
||||
0xE0900000, /* ADDS Rd,Rs,Rn */
|
||||
0xE0500000, /* SUBS Rd,Rs,Rn */
|
||||
0xE2900000, /* ADDS Rd,Rs,#imm3 */
|
||||
0xE2500000 /* SUBS Rd,Rs,#imm3 */
|
||||
};
|
||||
/* It is quicker indexing into a table, than performing switch
|
||||
or conditionals: */
|
||||
*ainstr = subset[(tinstr & 0x0600) >> 9] /* base opcode */
|
||||
| ((tinstr & 0x01C0) >> 6) /* Rn or imm3 */
|
||||
| ((tinstr & 0x0038) << (16 - 3)) /* Rs */
|
||||
| ((tinstr & 0x0007) << (12 - 0)); /* Rd */
|
||||
ARMword subset[4] = {
|
||||
0xE0900000, /* ADDS Rd,Rs,Rn */
|
||||
0xE0500000, /* SUBS Rd,Rs,Rn */
|
||||
0xE2900000, /* ADDS Rd,Rs,#imm3 */
|
||||
0xE2500000 /* SUBS Rd,Rs,#imm3 */
|
||||
};
|
||||
/* It is quicker indexing into a table, than performing switch
|
||||
or conditionals: */
|
||||
*ainstr = subset[(tinstr & 0x0600) >> 9] /* base opcode */
|
||||
| ((tinstr & 0x01C0) >> 6) /* Rn or imm3 */
|
||||
| ((tinstr & 0x0038) << (16 - 3)) /* Rs */
|
||||
| ((tinstr & 0x0007) << (12 - 0)); /* Rd */
|
||||
}
|
||||
break;
|
||||
case 4: /* MOV */
|
||||
case 5: /* CMP */
|
||||
case 6: /* ADD */
|
||||
case 7: /* SUB */
|
||||
case 4: /* MOV */
|
||||
case 5: /* CMP */
|
||||
case 6: /* ADD */
|
||||
case 7: /* SUB */
|
||||
/* Format 3 */
|
||||
{
|
||||
ARMword subset[4] = {
|
||||
0xE3B00000, /* MOVS Rd,#imm8 */
|
||||
0xE3500000, /* CMP Rd,#imm8 */
|
||||
0xE2900000, /* ADDS Rd,Rd,#imm8 */
|
||||
0xE2500000, /* SUBS Rd,Rd,#imm8 */
|
||||
};
|
||||
*ainstr = subset[(tinstr & 0x1800) >> 11] /* base opcode */
|
||||
| ((tinstr & 0x00FF) >> 0) /* imm8 */
|
||||
| ((tinstr & 0x0700) << (16 - 8)) /* Rn */
|
||||
| ((tinstr & 0x0700) << (12 - 8)); /* Rd */
|
||||
ARMword subset[4] = {
|
||||
0xE3B00000, /* MOVS Rd,#imm8 */
|
||||
0xE3500000, /* CMP Rd,#imm8 */
|
||||
0xE2900000, /* ADDS Rd,Rd,#imm8 */
|
||||
0xE2500000, /* SUBS Rd,Rd,#imm8 */
|
||||
};
|
||||
*ainstr = subset[(tinstr & 0x1800) >> 11] /* base opcode */
|
||||
| ((tinstr & 0x00FF) >> 0) /* imm8 */
|
||||
| ((tinstr & 0x0700) << (16 - 8)) /* Rn */
|
||||
| ((tinstr & 0x0700) << (12 - 8)); /* Rd */
|
||||
}
|
||||
break ;
|
||||
case 8: /* Arithmetic and high register transfers */
|
||||
break;
|
||||
case 8: /* Arithmetic and high register transfers */
|
||||
/* TODO: Since the subsets for both Format 4 and Format 5
|
||||
instructions are made up of different ARM encodings, we could
|
||||
save the following conditional, and just have one large
|
||||
subset. */
|
||||
if ((tinstr & (1 << 10)) == 0)
|
||||
{
|
||||
/* Format 4 */
|
||||
struct {
|
||||
ARMword opcode;
|
||||
enum {t_norm,t_shift,t_neg,t_mul} otype;
|
||||
} subset[16] = {
|
||||
{0xE0100000, t_norm}, /* ANDS Rd,Rd,Rs */
|
||||
{0xE0300000, t_norm}, /* EORS Rd,Rd,Rs */
|
||||
{0xE1B00010, t_shift}, /* MOVS Rd,Rd,LSL Rs */
|
||||
{0xE1B00030, t_shift}, /* MOVS Rd,Rd,LSR Rs */
|
||||
{0xE1B00050, t_shift}, /* MOVS Rd,Rd,ASR Rs */
|
||||
{0xE0B00000, t_norm}, /* ADCS Rd,Rd,Rs */
|
||||
{0xE0D00000, t_norm}, /* SBCS Rd,Rd,Rs */
|
||||
{0xE1B00070, t_shift}, /* MOVS Rd,Rd,ROR Rs */
|
||||
{0xE1100000, t_norm}, /* TST Rd,Rs */
|
||||
{0xE2700000, t_neg}, /* RSBS Rd,Rs,#0 */
|
||||
{0xE1500000, t_norm}, /* CMP Rd,Rs */
|
||||
{0xE1700000, t_norm}, /* CMN Rd,Rs */
|
||||
{0xE1900000, t_norm}, /* ORRS Rd,Rd,Rs */
|
||||
{0xE0100090, t_mul}, /* MULS Rd,Rd,Rs */
|
||||
{0xE1D00000, t_norm}, /* BICS Rd,Rd,Rs */
|
||||
{0xE1F00000, t_norm} /* MVNS Rd,Rs */
|
||||
};
|
||||
*ainstr = subset[(tinstr & 0x03C0)>>6].opcode; /* base */
|
||||
switch (subset[(tinstr & 0x03C0)>>6].otype)
|
||||
{
|
||||
case t_norm:
|
||||
*ainstr |= ((tinstr & 0x0007) << 16) /* Rn */
|
||||
| ((tinstr & 0x0007) << 12) /* Rd */
|
||||
| ((tinstr & 0x0038) >> 3); /* Rs */
|
||||
break;
|
||||
case t_shift:
|
||||
*ainstr |= ((tinstr & 0x0007) << 12) /* Rd */
|
||||
| ((tinstr & 0x0007) >> 0) /* Rm */
|
||||
| ((tinstr & 0x0038) << (8 - 3)); /* Rs */
|
||||
break;
|
||||
case t_neg:
|
||||
*ainstr |= ((tinstr & 0x0007) << 12) /* Rd */
|
||||
| ((tinstr & 0x0038) << (16 - 3)); /* Rn */
|
||||
break;
|
||||
case t_mul:
|
||||
*ainstr |= ((tinstr & 0x0007) << 16) /* Rd */
|
||||
| ((tinstr & 0x0007) << 8) /* Rs */
|
||||
| ((tinstr & 0x0038) >> 3); /* Rm */
|
||||
break;
|
||||
}
|
||||
}
|
||||
{
|
||||
/* Format 4 */
|
||||
struct
|
||||
{
|
||||
ARMword opcode;
|
||||
enum
|
||||
{ t_norm, t_shift, t_neg, t_mul }
|
||||
otype;
|
||||
}
|
||||
subset[16] =
|
||||
{
|
||||
{ 0xE0100000, t_norm}, /* ANDS Rd,Rd,Rs */
|
||||
{ 0xE0300000, t_norm}, /* EORS Rd,Rd,Rs */
|
||||
{ 0xE1B00010, t_shift}, /* MOVS Rd,Rd,LSL Rs */
|
||||
{ 0xE1B00030, t_shift}, /* MOVS Rd,Rd,LSR Rs */
|
||||
{ 0xE1B00050, t_shift}, /* MOVS Rd,Rd,ASR Rs */
|
||||
{ 0xE0B00000, t_norm}, /* ADCS Rd,Rd,Rs */
|
||||
{ 0xE0D00000, t_norm}, /* SBCS Rd,Rd,Rs */
|
||||
{ 0xE1B00070, t_shift}, /* MOVS Rd,Rd,ROR Rs */
|
||||
{ 0xE1100000, t_norm}, /* TST Rd,Rs */
|
||||
{ 0xE2700000, t_neg}, /* RSBS Rd,Rs,#0 */
|
||||
{ 0xE1500000, t_norm}, /* CMP Rd,Rs */
|
||||
{ 0xE1700000, t_norm}, /* CMN Rd,Rs */
|
||||
{ 0xE1900000, t_norm}, /* ORRS Rd,Rd,Rs */
|
||||
{ 0xE0100090, t_mul} , /* MULS Rd,Rd,Rs */
|
||||
{ 0xE1D00000, t_norm}, /* BICS Rd,Rd,Rs */
|
||||
{ 0xE1F00000, t_norm} /* MVNS Rd,Rs */
|
||||
};
|
||||
*ainstr = subset[(tinstr & 0x03C0) >> 6].opcode; /* base */
|
||||
switch (subset[(tinstr & 0x03C0) >> 6].otype)
|
||||
{
|
||||
case t_norm:
|
||||
*ainstr |= ((tinstr & 0x0007) << 16) /* Rn */
|
||||
| ((tinstr & 0x0007) << 12) /* Rd */
|
||||
| ((tinstr & 0x0038) >> 3); /* Rs */
|
||||
break;
|
||||
case t_shift:
|
||||
*ainstr |= ((tinstr & 0x0007) << 12) /* Rd */
|
||||
| ((tinstr & 0x0007) >> 0) /* Rm */
|
||||
| ((tinstr & 0x0038) << (8 - 3)); /* Rs */
|
||||
break;
|
||||
case t_neg:
|
||||
*ainstr |= ((tinstr & 0x0007) << 12) /* Rd */
|
||||
| ((tinstr & 0x0038) << (16 - 3)); /* Rn */
|
||||
break;
|
||||
case t_mul:
|
||||
*ainstr |= ((tinstr & 0x0007) << 16) /* Rd */
|
||||
| ((tinstr & 0x0007) << 8) /* Rs */
|
||||
| ((tinstr & 0x0038) >> 3); /* Rm */
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Format 5 */
|
||||
ARMword Rd = ((tinstr & 0x0007) >> 0);
|
||||
ARMword Rs = ((tinstr & 0x0038) >> 3);
|
||||
if (tinstr & (1 << 7))
|
||||
Rd += 8;
|
||||
if (tinstr & (1 << 6))
|
||||
Rs += 8;
|
||||
switch ((tinstr & 0x03C0) >> 6)
|
||||
{
|
||||
case 0x1: /* ADD Rd,Rd,Hs */
|
||||
case 0x2: /* ADD Hd,Hd,Rs */
|
||||
case 0x3: /* ADD Hd,Hd,Hs */
|
||||
*ainstr = 0xE0800000 /* base */
|
||||
| (Rd << 16) /* Rn */
|
||||
| (Rd << 12) /* Rd */
|
||||
| (Rs << 0); /* Rm */
|
||||
break;
|
||||
case 0x5: /* CMP Rd,Hs */
|
||||
case 0x6: /* CMP Hd,Rs */
|
||||
case 0x7: /* CMP Hd,Hs */
|
||||
*ainstr = 0xE1500000 /* base */
|
||||
| (Rd << 16) /* Rn */
|
||||
| (Rd << 12) /* Rd */
|
||||
| (Rs << 0); /* Rm */
|
||||
break;
|
||||
case 0x9: /* MOV Rd,Hs */
|
||||
case 0xA: /* MOV Hd,Rs */
|
||||
case 0xB: /* MOV Hd,Hs */
|
||||
*ainstr = 0xE1A00000 /* base */
|
||||
| (Rd << 16) /* Rn */
|
||||
| (Rd << 12) /* Rd */
|
||||
| (Rs << 0); /* Rm */
|
||||
break;
|
||||
case 0xC: /* BX Rs */
|
||||
case 0xD: /* BX Hs */
|
||||
*ainstr = 0xE12FFF10 /* base */
|
||||
| ((tinstr & 0x0078) >> 3); /* Rd */
|
||||
break;
|
||||
case 0x0: /* UNDEFINED */
|
||||
case 0x4: /* UNDEFINED */
|
||||
case 0x8: /* UNDEFINED */
|
||||
case 0xE: /* UNDEFINED */
|
||||
case 0xF: /* UNDEFINED */
|
||||
valid = t_undefined;
|
||||
break;
|
||||
}
|
||||
}
|
||||
{
|
||||
/* Format 5 */
|
||||
ARMword Rd = ((tinstr & 0x0007) >> 0);
|
||||
ARMword Rs = ((tinstr & 0x0038) >> 3);
|
||||
if (tinstr & (1 << 7))
|
||||
Rd += 8;
|
||||
if (tinstr & (1 << 6))
|
||||
Rs += 8;
|
||||
switch ((tinstr & 0x03C0) >> 6)
|
||||
{
|
||||
case 0x1: /* ADD Rd,Rd,Hs */
|
||||
case 0x2: /* ADD Hd,Hd,Rs */
|
||||
case 0x3: /* ADD Hd,Hd,Hs */
|
||||
*ainstr = 0xE0800000 /* base */
|
||||
| (Rd << 16) /* Rn */
|
||||
| (Rd << 12) /* Rd */
|
||||
| (Rs << 0); /* Rm */
|
||||
break;
|
||||
case 0x5: /* CMP Rd,Hs */
|
||||
case 0x6: /* CMP Hd,Rs */
|
||||
case 0x7: /* CMP Hd,Hs */
|
||||
*ainstr = 0xE1500000 /* base */
|
||||
| (Rd << 16) /* Rn */
|
||||
| (Rd << 12) /* Rd */
|
||||
| (Rs << 0); /* Rm */
|
||||
break;
|
||||
case 0x9: /* MOV Rd,Hs */
|
||||
case 0xA: /* MOV Hd,Rs */
|
||||
case 0xB: /* MOV Hd,Hs */
|
||||
*ainstr = 0xE1A00000 /* base */
|
||||
| (Rd << 16) /* Rn */
|
||||
| (Rd << 12) /* Rd */
|
||||
| (Rs << 0); /* Rm */
|
||||
break;
|
||||
case 0xC: /* BX Rs */
|
||||
case 0xD: /* BX Hs */
|
||||
*ainstr = 0xE12FFF10 /* base */
|
||||
| ((tinstr & 0x0078) >> 3); /* Rd */
|
||||
break;
|
||||
case 0x0: /* UNDEFINED */
|
||||
case 0x4: /* UNDEFINED */
|
||||
case 0x8: /* UNDEFINED */
|
||||
case 0xE: /* UNDEFINED */
|
||||
case 0xF: /* UNDEFINED */
|
||||
valid = t_undefined;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 9: /* LDR Rd,[PC,#imm8] */
|
||||
case 9: /* LDR Rd,[PC,#imm8] */
|
||||
/* Format 6 */
|
||||
*ainstr = 0xE59F0000 /* base */
|
||||
| ((tinstr & 0x0700) << (12 - 8)) /* Rd */
|
||||
| ((tinstr & 0x00FF) << (2 - 0)); /* off8 */
|
||||
*ainstr = 0xE59F0000 /* base */
|
||||
| ((tinstr & 0x0700) << (12 - 8)) /* Rd */
|
||||
| ((tinstr & 0x00FF) << (2 - 0)); /* off8 */
|
||||
break;
|
||||
case 10:
|
||||
case 11:
|
||||
@@ -223,236 +231,252 @@ ARMul_ThumbDecode (state,pc,tinstr,ainstr)
|
||||
the following could be merged into a single subset, saving on
|
||||
the following boolean: */
|
||||
if ((tinstr & (1 << 9)) == 0)
|
||||
{
|
||||
/* Format 7 */
|
||||
ARMword subset[4] = {
|
||||
0xE7800000, /* STR Rd,[Rb,Ro] */
|
||||
0xE7C00000, /* STRB Rd,[Rb,Ro] */
|
||||
0xE7900000, /* LDR Rd,[Rb,Ro] */
|
||||
0xE7D00000 /* LDRB Rd,[Rb,Ro] */
|
||||
};
|
||||
*ainstr = subset[(tinstr & 0x0C00) >> 10] /* base */
|
||||
| ((tinstr & 0x0007) << (12 - 0)) /* Rd */
|
||||
| ((tinstr & 0x0038) << (16 - 3)) /* Rb */
|
||||
| ((tinstr & 0x01C0) >> 6); /* Ro */
|
||||
}
|
||||
{
|
||||
/* Format 7 */
|
||||
ARMword subset[4] = {
|
||||
0xE7800000, /* STR Rd,[Rb,Ro] */
|
||||
0xE7C00000, /* STRB Rd,[Rb,Ro] */
|
||||
0xE7900000, /* LDR Rd,[Rb,Ro] */
|
||||
0xE7D00000 /* LDRB Rd,[Rb,Ro] */
|
||||
};
|
||||
*ainstr = subset[(tinstr & 0x0C00) >> 10] /* base */
|
||||
| ((tinstr & 0x0007) << (12 - 0)) /* Rd */
|
||||
| ((tinstr & 0x0038) << (16 - 3)) /* Rb */
|
||||
| ((tinstr & 0x01C0) >> 6); /* Ro */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Format 8 */
|
||||
ARMword subset[4] = {
|
||||
0xE18000B0, /* STRH Rd,[Rb,Ro] */
|
||||
0xE19000D0, /* LDRSB Rd,[Rb,Ro] */
|
||||
0xE19000B0, /* LDRH Rd,[Rb,Ro] */
|
||||
0xE19000F0 /* LDRSH Rd,[Rb,Ro] */
|
||||
};
|
||||
*ainstr = subset[(tinstr & 0x0C00) >> 10] /* base */
|
||||
| ((tinstr & 0x0007) << (12 - 0)) /* Rd */
|
||||
| ((tinstr & 0x0038) << (16 - 3)) /* Rb */
|
||||
| ((tinstr & 0x01C0) >> 6); /* Ro */
|
||||
}
|
||||
{
|
||||
/* Format 8 */
|
||||
ARMword subset[4] = {
|
||||
0xE18000B0, /* STRH Rd,[Rb,Ro] */
|
||||
0xE19000D0, /* LDRSB Rd,[Rb,Ro] */
|
||||
0xE19000B0, /* LDRH Rd,[Rb,Ro] */
|
||||
0xE19000F0 /* LDRSH Rd,[Rb,Ro] */
|
||||
};
|
||||
*ainstr = subset[(tinstr & 0x0C00) >> 10] /* base */
|
||||
| ((tinstr & 0x0007) << (12 - 0)) /* Rd */
|
||||
| ((tinstr & 0x0038) << (16 - 3)) /* Rb */
|
||||
| ((tinstr & 0x01C0) >> 6); /* Ro */
|
||||
}
|
||||
break;
|
||||
case 12: /* STR Rd,[Rb,#imm5] */
|
||||
case 13: /* LDR Rd,[Rb,#imm5] */
|
||||
case 14: /* STRB Rd,[Rb,#imm5] */
|
||||
case 15: /* LDRB Rd,[Rb,#imm5] */
|
||||
case 12: /* STR Rd,[Rb,#imm5] */
|
||||
case 13: /* LDR Rd,[Rb,#imm5] */
|
||||
case 14: /* STRB Rd,[Rb,#imm5] */
|
||||
case 15: /* LDRB Rd,[Rb,#imm5] */
|
||||
/* Format 9 */
|
||||
{
|
||||
ARMword subset[4] = {
|
||||
0xE5800000, /* STR Rd,[Rb,#imm5] */
|
||||
0xE5900000, /* LDR Rd,[Rb,#imm5] */
|
||||
0xE5C00000, /* STRB Rd,[Rb,#imm5] */
|
||||
0xE5D00000 /* LDRB Rd,[Rb,#imm5] */
|
||||
};
|
||||
/* The offset range defends on whether we are transferring a
|
||||
byte or word value: */
|
||||
*ainstr = subset[(tinstr & 0x1800) >> 11] /* base */
|
||||
| ((tinstr & 0x0007) << (12 - 0)) /* Rd */
|
||||
| ((tinstr & 0x0038) << (16 - 3)) /* Rb */
|
||||
| ((tinstr & 0x07C0) >>
|
||||
(6 - ((tinstr & (1 << 12)) ? 0 : 2))); /* off5 */
|
||||
ARMword subset[4] = {
|
||||
0xE5800000, /* STR Rd,[Rb,#imm5] */
|
||||
0xE5900000, /* LDR Rd,[Rb,#imm5] */
|
||||
0xE5C00000, /* STRB Rd,[Rb,#imm5] */
|
||||
0xE5D00000 /* LDRB Rd,[Rb,#imm5] */
|
||||
};
|
||||
/* The offset range defends on whether we are transferring a
|
||||
byte or word value: */
|
||||
*ainstr = subset[(tinstr & 0x1800) >> 11] /* base */
|
||||
| ((tinstr & 0x0007) << (12 - 0)) /* Rd */
|
||||
| ((tinstr & 0x0038) << (16 - 3)) /* Rb */
|
||||
| ((tinstr & 0x07C0) >> (6 - ((tinstr & (1 << 12)) ? 0 : 2))); /* off5 */
|
||||
}
|
||||
break;
|
||||
case 16: /* STRH Rd,[Rb,#imm5] */
|
||||
case 17: /* LDRH Rd,[Rb,#imm5] */
|
||||
case 16: /* STRH Rd,[Rb,#imm5] */
|
||||
case 17: /* LDRH Rd,[Rb,#imm5] */
|
||||
/* Format 10 */
|
||||
*ainstr = ((tinstr & (1 << 11)) /* base */
|
||||
? 0xE1D000B0 /* LDRH */
|
||||
: 0xE1C000B0) /* STRH */
|
||||
| ((tinstr & 0x0007) << (12 - 0)) /* Rd */
|
||||
| ((tinstr & 0x0038) << (16 - 3)) /* Rb */
|
||||
| ((tinstr & 0x01C0) >> (6 - 1)) /* off5, low nibble */
|
||||
| ((tinstr & 0x0600) >> (9 - 8)); /* off5, high nibble */
|
||||
*ainstr = ((tinstr & (1 << 11)) /* base */
|
||||
? 0xE1D000B0 /* LDRH */
|
||||
: 0xE1C000B0) /* STRH */
|
||||
| ((tinstr & 0x0007) << (12 - 0)) /* Rd */
|
||||
| ((tinstr & 0x0038) << (16 - 3)) /* Rb */
|
||||
| ((tinstr & 0x01C0) >> (6 - 1)) /* off5, low nibble */
|
||||
| ((tinstr & 0x0600) >> (9 - 8)); /* off5, high nibble */
|
||||
break;
|
||||
case 18: /* STR Rd,[SP,#imm8] */
|
||||
case 19: /* LDR Rd,[SP,#imm8] */
|
||||
case 18: /* STR Rd,[SP,#imm8] */
|
||||
case 19: /* LDR Rd,[SP,#imm8] */
|
||||
/* Format 11 */
|
||||
*ainstr = ((tinstr & (1 << 11)) /* base */
|
||||
? 0xE59D0000 /* LDR */
|
||||
: 0xE58D0000) /* STR */
|
||||
| ((tinstr & 0x0700) << (12 - 8)) /* Rd */
|
||||
| ((tinstr & 0x00FF) << 2); /* off8 */
|
||||
*ainstr = ((tinstr & (1 << 11)) /* base */
|
||||
? 0xE59D0000 /* LDR */
|
||||
: 0xE58D0000) /* STR */
|
||||
| ((tinstr & 0x0700) << (12 - 8)) /* Rd */
|
||||
| ((tinstr & 0x00FF) << 2); /* off8 */
|
||||
break;
|
||||
case 20: /* ADD Rd,PC,#imm8 */
|
||||
case 21: /* ADD Rd,SP,#imm8 */
|
||||
case 20: /* ADD Rd,PC,#imm8 */
|
||||
case 21: /* ADD Rd,SP,#imm8 */
|
||||
/* Format 12 */
|
||||
if ((tinstr & (1 << 11)) == 0)
|
||||
{
|
||||
/* NOTE: The PC value used here should by word aligned */
|
||||
{
|
||||
/* NOTE: The PC value used here should by word aligned */
|
||||
/* We encode shift-left-by-2 in the rotate immediate field,
|
||||
so no shift of off8 is needed. */
|
||||
*ainstr = 0xE28F0F00 /* base */
|
||||
| ((tinstr & 0x0700) << (12 - 8)) /* Rd */
|
||||
| (tinstr & 0x00FF); /* off8 */
|
||||
}
|
||||
*ainstr = 0xE28F0F00 /* base */
|
||||
| ((tinstr & 0x0700) << (12 - 8)) /* Rd */
|
||||
| (tinstr & 0x00FF); /* off8 */
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
/* We encode shift-left-by-2 in the rotate immediate field,
|
||||
so no shift of off8 is needed. */
|
||||
*ainstr = 0xE28D0F00 /* base */
|
||||
| ((tinstr & 0x0700) << (12 - 8)) /* Rd */
|
||||
| (tinstr & 0x00FF); /* off8 */
|
||||
}
|
||||
*ainstr = 0xE28D0F00 /* base */
|
||||
| ((tinstr & 0x0700) << (12 - 8)) /* Rd */
|
||||
| (tinstr & 0x00FF); /* off8 */
|
||||
}
|
||||
break;
|
||||
case 22:
|
||||
case 23:
|
||||
if ((tinstr & 0x0F00) == 0x0000)
|
||||
{
|
||||
/* Format 13 */
|
||||
/* NOTE: The instruction contains a shift left of 2
|
||||
equivalent (implemented as ROR #30): */
|
||||
*ainstr = ((tinstr & (1 << 7)) /* base */
|
||||
? 0xE24DDF00 /* SUB */
|
||||
: 0xE28DDF00) /* ADD */
|
||||
| (tinstr & 0x007F); /* off7 */
|
||||
}
|
||||
{
|
||||
/* Format 13 */
|
||||
/* NOTE: The instruction contains a shift left of 2
|
||||
equivalent (implemented as ROR #30): */
|
||||
*ainstr = ((tinstr & (1 << 7)) /* base */
|
||||
? 0xE24DDF00 /* SUB */
|
||||
: 0xE28DDF00) /* ADD */
|
||||
| (tinstr & 0x007F); /* off7 */
|
||||
}
|
||||
else if ((tinstr & 0x0F00) == 0x0e00)
|
||||
* ainstr = 0xEF000000 | SWI_Breakpoint;
|
||||
*ainstr = 0xEF000000 | SWI_Breakpoint;
|
||||
else
|
||||
{
|
||||
/* Format 14 */
|
||||
ARMword subset[4] = {
|
||||
0xE92D0000, /* STMDB sp!,{rlist} */
|
||||
0xE92D4000, /* STMDB sp!,{rlist,lr} */
|
||||
0xE8BD0000, /* LDMIA sp!,{rlist} */
|
||||
0xE8BD8000 /* LDMIA sp!,{rlist,pc} */
|
||||
};
|
||||
*ainstr = subset[((tinstr & (1 << 11)) >> 10)
|
||||
| ((tinstr & (1 << 8)) >> 8)] /* base */
|
||||
| (tinstr & 0x00FF); /* mask8 */
|
||||
}
|
||||
{
|
||||
/* Format 14 */
|
||||
ARMword subset[4] = {
|
||||
0xE92D0000, /* STMDB sp!,{rlist} */
|
||||
0xE92D4000, /* STMDB sp!,{rlist,lr} */
|
||||
0xE8BD0000, /* LDMIA sp!,{rlist} */
|
||||
0xE8BD8000 /* LDMIA sp!,{rlist,pc} */
|
||||
};
|
||||
*ainstr = subset[((tinstr & (1 << 11)) >> 10)
|
||||
| ((tinstr & (1 << 8)) >> 8)] /* base */
|
||||
| (tinstr & 0x00FF); /* mask8 */
|
||||
}
|
||||
break;
|
||||
case 24: /* STMIA */
|
||||
case 25: /* LDMIA */
|
||||
case 24: /* STMIA */
|
||||
case 25: /* LDMIA */
|
||||
/* Format 15 */
|
||||
*ainstr = ((tinstr & (1 << 11)) /* base */
|
||||
? 0xE8B00000 /* LDMIA */
|
||||
: 0xE8A00000) /* STMIA */
|
||||
| ((tinstr & 0x0700) << (16 - 8)) /* Rb */
|
||||
| (tinstr & 0x00FF); /* mask8 */
|
||||
*ainstr = ((tinstr & (1 << 11)) /* base */
|
||||
? 0xE8B00000 /* LDMIA */
|
||||
: 0xE8A00000) /* STMIA */
|
||||
| ((tinstr & 0x0700) << (16 - 8)) /* Rb */
|
||||
| (tinstr & 0x00FF); /* mask8 */
|
||||
break;
|
||||
case 26: /* Bcc */
|
||||
case 27: /* Bcc/SWI */
|
||||
case 26: /* Bcc */
|
||||
case 27: /* Bcc/SWI */
|
||||
if ((tinstr & 0x0F00) == 0x0F00)
|
||||
{
|
||||
/* Format 17 : SWI */
|
||||
*ainstr = 0xEF000000;
|
||||
{
|
||||
/* Format 17 : SWI */
|
||||
*ainstr = 0xEF000000;
|
||||
/* Breakpoint must be handled specially. */
|
||||
if ((tinstr & 0x00FF) == 0x18)
|
||||
*ainstr |= ((tinstr & 0x00FF) << 16);
|
||||
/* New breakpoint value. See gdb/arm-tdep.c */
|
||||
else if ((tinstr & 0x00FF) == 0xFE)
|
||||
* ainstr |= SWI_Breakpoint;
|
||||
*ainstr |= SWI_Breakpoint;
|
||||
else
|
||||
*ainstr |= (tinstr & 0x00FF);
|
||||
}
|
||||
}
|
||||
else if ((tinstr & 0x0F00) != 0x0E00)
|
||||
{
|
||||
/* Format 16 */
|
||||
int doit = FALSE;
|
||||
/* TODO: Since we are doing a switch here, we could just add
|
||||
the SWI and undefined instruction checks into this
|
||||
switch to same on a couple of conditionals: */
|
||||
switch ((tinstr & 0x0F00) >> 8) {
|
||||
case EQ : doit=ZFLAG ;
|
||||
break ;
|
||||
case NE : doit=!ZFLAG ;
|
||||
break ;
|
||||
case VS : doit=VFLAG ;
|
||||
break ;
|
||||
case VC : doit=!VFLAG ;
|
||||
break ;
|
||||
case MI : doit=NFLAG ;
|
||||
break ;
|
||||
case PL : doit=!NFLAG ;
|
||||
break ;
|
||||
case CS : doit=CFLAG ;
|
||||
break ;
|
||||
case CC : doit=!CFLAG ;
|
||||
break ;
|
||||
case HI : doit=(CFLAG && !ZFLAG) ;
|
||||
break ;
|
||||
case LS : doit=(!CFLAG || ZFLAG) ;
|
||||
break ;
|
||||
case GE : doit=((!NFLAG && !VFLAG) || (NFLAG && VFLAG)) ;
|
||||
break ;
|
||||
case LT : doit=((NFLAG && !VFLAG) || (!NFLAG && VFLAG)) ;
|
||||
break ;
|
||||
case GT : doit=((!NFLAG && !VFLAG && !ZFLAG) || (NFLAG && VFLAG && !ZFLAG)) ;
|
||||
break ;
|
||||
case LE : doit=((NFLAG && !VFLAG) || (!NFLAG && VFLAG)) || ZFLAG ;
|
||||
break ;
|
||||
}
|
||||
if (doit) {
|
||||
state->Reg[15] = pc + 4
|
||||
+ (((tinstr & 0x7F) << 1)
|
||||
| ((tinstr & (1 << 7)) ? 0xFFFFFF00 : 0));
|
||||
FLUSHPIPE;
|
||||
}
|
||||
valid = t_branch;
|
||||
}
|
||||
else /* UNDEFINED : cc=1110(AL) uses different format */
|
||||
valid = t_undefined;
|
||||
{
|
||||
/* Format 16 */
|
||||
int doit = FALSE;
|
||||
/* TODO: Since we are doing a switch here, we could just add
|
||||
the SWI and undefined instruction checks into this
|
||||
switch to same on a couple of conditionals: */
|
||||
switch ((tinstr & 0x0F00) >> 8)
|
||||
{
|
||||
case EQ:
|
||||
doit = ZFLAG;
|
||||
break;
|
||||
case NE:
|
||||
doit = !ZFLAG;
|
||||
break;
|
||||
case VS:
|
||||
doit = VFLAG;
|
||||
break;
|
||||
case VC:
|
||||
doit = !VFLAG;
|
||||
break;
|
||||
case MI:
|
||||
doit = NFLAG;
|
||||
break;
|
||||
case PL:
|
||||
doit = !NFLAG;
|
||||
break;
|
||||
case CS:
|
||||
doit = CFLAG;
|
||||
break;
|
||||
case CC:
|
||||
doit = !CFLAG;
|
||||
break;
|
||||
case HI:
|
||||
doit = (CFLAG && !ZFLAG);
|
||||
break;
|
||||
case LS:
|
||||
doit = (!CFLAG || ZFLAG);
|
||||
break;
|
||||
case GE:
|
||||
doit = ((!NFLAG && !VFLAG) || (NFLAG && VFLAG));
|
||||
break;
|
||||
case LT:
|
||||
doit = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG));
|
||||
break;
|
||||
case GT:
|
||||
doit = ((!NFLAG && !VFLAG && !ZFLAG)
|
||||
|| (NFLAG && VFLAG && !ZFLAG));
|
||||
break;
|
||||
case LE:
|
||||
doit = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG)) || ZFLAG;
|
||||
break;
|
||||
}
|
||||
if (doit)
|
||||
{
|
||||
state->Reg[15] = (pc + 4
|
||||
+ (((tinstr & 0x7F) << 1)
|
||||
| ((tinstr & (1 << 7)) ? 0xFFFFFF00 : 0)));
|
||||
FLUSHPIPE;
|
||||
}
|
||||
valid = t_branch;
|
||||
}
|
||||
else /* UNDEFINED : cc=1110(AL) uses different format */
|
||||
valid = t_undefined;
|
||||
break;
|
||||
case 28: /* B */
|
||||
case 28: /* B */
|
||||
/* Format 18 */
|
||||
state->Reg[15] = pc + 4
|
||||
+ (((tinstr & 0x3FF) << 1)
|
||||
| ((tinstr & (1 << 10)) ? 0xFFFFF800 : 0));
|
||||
state->Reg[15] = (pc + 4
|
||||
+ (((tinstr & 0x3FF) << 1)
|
||||
| ((tinstr & (1 << 10)) ? 0xFFFFF800 : 0)));
|
||||
FLUSHPIPE;
|
||||
valid = t_branch;
|
||||
break;
|
||||
case 29: /* UNDEFINED */
|
||||
case 29: /* UNDEFINED */
|
||||
valid = t_undefined;
|
||||
break;
|
||||
case 30: /* BL instruction 1 */
|
||||
case 30: /* BL instruction 1 */
|
||||
/* Format 19 */
|
||||
/* There is no single ARM instruction equivalent for this Thumb
|
||||
instruction. To keep the simulation simple (from the user
|
||||
perspective) we check if the following instruction is the
|
||||
second half of this BL, and if it is we simulate it
|
||||
immediately. */
|
||||
immediately. */
|
||||
state->Reg[14] = state->Reg[15] \
|
||||
+ (((tinstr & 0x07FF) << 12) \
|
||||
| ((tinstr & (1 << 10)) ? 0xFF800000 : 0));
|
||||
valid = t_branch; /* in-case we don't have the 2nd half */
|
||||
tinstr = next_instr; /* move the instruction down */
|
||||
+(((tinstr & 0x07FF) << 12) \
|
||||
|((tinstr & (1 << 10)) ? 0xFF800000 : 0));
|
||||
valid = t_branch; /* in-case we don't have the 2nd half */
|
||||
tinstr = next_instr; /* move the instruction down */
|
||||
if (((tinstr & 0xF800) >> 11) != 31)
|
||||
break; /* exit, since not correct instruction */
|
||||
break; /* exit, since not correct instruction */
|
||||
/* else we fall through to process the second half of the BL */
|
||||
pc += 2; /* point the pc at the 2nd half */
|
||||
case 31: /* BL instruction 2 */
|
||||
pc += 2; /* point the pc at the 2nd half */
|
||||
case 31: /* BL instruction 2 */
|
||||
/* Format 19 */
|
||||
/* There is no single ARM instruction equivalent for this
|
||||
instruction. Also, it should only ever be matched with the
|
||||
fmt19 "BL instruction 1" instruction. However, we do allow
|
||||
the simulation of it on its own, with undefined results if
|
||||
r14 is not suitably initialised.*/
|
||||
r14 is not suitably initialised. */
|
||||
{
|
||||
ARMword tmp = (pc + 2);
|
||||
state->Reg[15] = (state->Reg[14] + ((tinstr & 0x07FF) << 1));
|
||||
state->Reg[14] = (tmp | 1);
|
||||
valid = t_branch;
|
||||
FLUSHPIPE;
|
||||
ARMword tmp = (pc + 2);
|
||||
state->Reg[15] = (state->Reg[14] + ((tinstr & 0x07FF) << 1));
|
||||
state->Reg[14] = (tmp | 1);
|
||||
valid = t_branch;
|
||||
FLUSHPIPE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -52,19 +52,19 @@ static int big_endian;
|
||||
|
||||
int stop_simulator;
|
||||
|
||||
static void
|
||||
static void
|
||||
init ()
|
||||
{
|
||||
static int done;
|
||||
|
||||
if (!done)
|
||||
{
|
||||
ARMul_EmulateInit();
|
||||
ARMul_EmulateInit ();
|
||||
state = ARMul_NewState ();
|
||||
state->bigendSig = (big_endian ? HIGH : LOW);
|
||||
ARMul_MemoryInit(state, mem_size);
|
||||
ARMul_OSInit(state);
|
||||
ARMul_CoProInit(state);
|
||||
ARMul_MemoryInit (state, mem_size);
|
||||
ARMul_OSInit (state);
|
||||
ARMul_CoProInit (state);
|
||||
state->verbose = verbosity;
|
||||
done = 1;
|
||||
}
|
||||
@@ -83,18 +83,18 @@ sim_set_verbose (v)
|
||||
}
|
||||
|
||||
/* Set the memory size to SIZE bytes.
|
||||
Must be called before initializing simulator. */
|
||||
Must be called before initializing simulator. */
|
||||
/* FIXME: Rename to sim_set_mem_size. */
|
||||
|
||||
void
|
||||
void
|
||||
sim_size (size)
|
||||
int size;
|
||||
{
|
||||
mem_size = size;
|
||||
}
|
||||
|
||||
void
|
||||
ARMul_ConsolePrint (ARMul_State * state, const char *format,...)
|
||||
void
|
||||
ARMul_ConsolePrint (ARMul_State * state, const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
@@ -106,8 +106,7 @@ ARMul_ConsolePrint (ARMul_State * state, const char *format,...)
|
||||
}
|
||||
}
|
||||
|
||||
ARMword
|
||||
ARMul_Debug (ARMul_State * state, ARMword pc, ARMword instr)
|
||||
ARMword ARMul_Debug (ARMul_State * state, ARMword pc, ARMword instr)
|
||||
{
|
||||
|
||||
}
|
||||
@@ -123,7 +122,7 @@ sim_write (sd, addr, buffer, size)
|
||||
init ();
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
ARMul_WriteByte (state, addr+i, buffer[i]);
|
||||
ARMul_WriteByte (state, addr + i, buffer[i]);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
@@ -147,8 +146,9 @@ sim_read (sd, addr, buffer, size)
|
||||
int
|
||||
sim_trace (sd)
|
||||
SIM_DESC sd;
|
||||
{
|
||||
(*sim_callback->printf_filtered) (sim_callback, "This simulator does not support tracing\n");
|
||||
{
|
||||
(*sim_callback->printf_filtered) (sim_callback,
|
||||
"This simulator does not support tracing\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -177,8 +177,8 @@ sim_resume (sd, step, siggnal)
|
||||
}
|
||||
else
|
||||
{
|
||||
#if 1 /* JGS */
|
||||
state->NextInstr = RESUME; /* treat as PC change */
|
||||
#if 1 /* JGS */
|
||||
state->NextInstr = RESUME; /* treat as PC change */
|
||||
#endif
|
||||
state->Reg[15] = ARMul_DoProg (state);
|
||||
}
|
||||
@@ -193,49 +193,49 @@ sim_create_inferior (sd, abfd, argv, env)
|
||||
char **argv;
|
||||
char **env;
|
||||
{
|
||||
int argvlen=0;
|
||||
int argvlen = 0;
|
||||
char **arg;
|
||||
|
||||
if (abfd != NULL)
|
||||
ARMul_SetPC (state, bfd_get_start_address (abfd));
|
||||
else
|
||||
ARMul_SetPC (state, 0); /* ??? */
|
||||
ARMul_SetPC (state, 0); /* ??? */
|
||||
|
||||
#if 1 /* JGS */
|
||||
#if 1 /* JGS */
|
||||
/* We explicitly select a processor capable of supporting the ARM
|
||||
32bit mode, and then we force the simulated CPU into the 32bit
|
||||
User mode: */
|
||||
ARMul_SelectProcessor(state, ARM600);
|
||||
ARMul_SetCPSR(state, USER32MODE);
|
||||
ARMul_SelectProcessor (state, ARM600);
|
||||
ARMul_SetCPSR (state, USER32MODE);
|
||||
#endif
|
||||
|
||||
if (argv != NULL)
|
||||
{
|
||||
/*
|
||||
** Set up the command line (by laboriously stringing together the
|
||||
** environment carefully picked apart by our caller...)
|
||||
*/
|
||||
** Set up the command line (by laboriously stringing together the
|
||||
** environment carefully picked apart by our caller...)
|
||||
*/
|
||||
/* Free any old stuff */
|
||||
if (state->CommandLine != NULL)
|
||||
{
|
||||
free(state->CommandLine);
|
||||
free (state->CommandLine);
|
||||
state->CommandLine = NULL;
|
||||
}
|
||||
|
||||
|
||||
/* See how much we need */
|
||||
for (arg = argv; *arg != NULL; arg++)
|
||||
argvlen += strlen(*arg)+1;
|
||||
|
||||
argvlen += strlen (*arg) + 1;
|
||||
|
||||
/* allocate it... */
|
||||
state->CommandLine = malloc(argvlen+1);
|
||||
state->CommandLine = malloc (argvlen + 1);
|
||||
if (state->CommandLine != NULL)
|
||||
{
|
||||
arg = argv;
|
||||
state->CommandLine[0]='\0';
|
||||
state->CommandLine[0] = '\0';
|
||||
for (arg = argv; *arg != NULL; arg++)
|
||||
{
|
||||
strcat(state->CommandLine, *arg);
|
||||
strcat(state->CommandLine, " ");
|
||||
strcat (state->CommandLine, *arg);
|
||||
strcat (state->CommandLine, " ");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -245,13 +245,14 @@ sim_create_inferior (sd, abfd, argv, env)
|
||||
/* Now see if there's a MEMSIZE spec in the environment */
|
||||
while (*env)
|
||||
{
|
||||
if (strncmp(*env, "MEMSIZE=", sizeof("MEMSIZE=")-1)==0)
|
||||
if (strncmp (*env, "MEMSIZE=", sizeof ("MEMSIZE=") - 1) == 0)
|
||||
{
|
||||
unsigned long top_of_memory;
|
||||
char *end_of_num;
|
||||
|
||||
|
||||
/* Set up memory limit */
|
||||
state->MemSize = strtoul(*env + sizeof("MEMSIZE=")-1, &end_of_num, 0);
|
||||
state->MemSize =
|
||||
strtoul (*env + sizeof ("MEMSIZE=") - 1, &end_of_num, 0);
|
||||
}
|
||||
env++;
|
||||
}
|
||||
@@ -268,7 +269,7 @@ sim_info (sd, verbose)
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
static int
|
||||
frommem (state, memory)
|
||||
struct ARMul_State *state;
|
||||
unsigned char *memory;
|
||||
@@ -276,22 +277,18 @@ frommem (state, memory)
|
||||
if (state->bigendSig == HIGH)
|
||||
{
|
||||
return (memory[0] << 24)
|
||||
| (memory[1] << 16)
|
||||
| (memory[2] << 8)
|
||||
| (memory[3] << 0);
|
||||
| (memory[1] << 16) | (memory[2] << 8) | (memory[3] << 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
return (memory[3] << 24)
|
||||
| (memory[2] << 16)
|
||||
| (memory[1] << 8)
|
||||
| (memory[0] << 0);
|
||||
| (memory[2] << 16) | (memory[1] << 8) | (memory[0] << 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
tomem (state, memory, val)
|
||||
tomem (state, memory, val)
|
||||
struct ARMul_State *state;
|
||||
unsigned char *memory;
|
||||
int val;
|
||||
@@ -320,7 +317,7 @@ sim_store_register (sd, rn, memory, length)
|
||||
int length;
|
||||
{
|
||||
init ();
|
||||
ARMul_SetReg(state, state->Mode, rn, frommem (state, memory));
|
||||
ARMul_SetReg (state, state->Mode, rn, frommem (state, memory));
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -335,11 +332,11 @@ sim_fetch_register (sd, rn, memory, length)
|
||||
|
||||
init ();
|
||||
if (rn < 16)
|
||||
regval = ARMul_GetReg(state, state->Mode, rn);
|
||||
else if (rn == 25) /* FIXME: use PS_REGNUM from gdb/config/arm/tm-arm.h */
|
||||
regval = ARMul_GetCPSR(state);
|
||||
regval = ARMul_GetReg (state, state->Mode, rn);
|
||||
else if (rn == 25) /* FIXME: use PS_REGNUM from gdb/config/arm/tm-arm.h */
|
||||
regval = ARMul_GetCPSR (state);
|
||||
else
|
||||
regval = 0; /* FIXME: should report an error */
|
||||
regval = 0; /* FIXME: should report an error */
|
||||
tomem (state, memory, regval);
|
||||
return -1;
|
||||
}
|
||||
@@ -354,7 +351,7 @@ sim_open (kind, ptr, abfd, argv)
|
||||
sim_kind = kind;
|
||||
myname = argv[0];
|
||||
sim_callback = ptr;
|
||||
|
||||
|
||||
/* Decide upon the endian-ness of the processor.
|
||||
If we can, get the information from the bfd itself.
|
||||
Otherwise look to see if we have been given a command
|
||||
@@ -364,42 +361,42 @@ sim_open (kind, ptr, abfd, argv)
|
||||
else if (argv[1] != NULL)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
||||
/* Scan for endian-ness switch. */
|
||||
for (i = 0; (argv[i] != NULL) && (argv[i][0] != 0); i++)
|
||||
if (argv[i][0] == '-' && argv[i][1] == 'E')
|
||||
{
|
||||
char c;
|
||||
|
||||
if ((c = argv[i][2]) == 0)
|
||||
{
|
||||
++i;
|
||||
c = argv[i][0];
|
||||
}
|
||||
if (argv[i][0] == '-' && argv[i][1] == 'E')
|
||||
{
|
||||
char c;
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case 0:
|
||||
sim_callback->printf_filtered
|
||||
(sim_callback, "No argument to -E option provided\n");
|
||||
break;
|
||||
if ((c = argv[i][2]) == 0)
|
||||
{
|
||||
++i;
|
||||
c = argv[i][0];
|
||||
}
|
||||
|
||||
case 'b':
|
||||
case 'B':
|
||||
big_endian = 1;
|
||||
break;
|
||||
switch (c)
|
||||
{
|
||||
case 0:
|
||||
sim_callback->printf_filtered
|
||||
(sim_callback, "No argument to -E option provided\n");
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
case 'L':
|
||||
big_endian = 0;
|
||||
break;
|
||||
case 'b':
|
||||
case 'B':
|
||||
big_endian = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
sim_callback->printf_filtered
|
||||
(sim_callback, "Unrecognised argument to -E option\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
case 'l':
|
||||
case 'L':
|
||||
big_endian = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
sim_callback->printf_filtered
|
||||
(sim_callback, "Unrecognised argument to -E option\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (SIM_DESC) 1;
|
||||
@@ -420,12 +417,11 @@ sim_load (sd, prog, abfd, from_tty)
|
||||
bfd *abfd;
|
||||
int from_tty;
|
||||
{
|
||||
extern bfd *sim_load_file (); /* ??? Don't know where this should live. */
|
||||
extern bfd *sim_load_file (); /* ??? Don't know where this should live. */
|
||||
bfd *prog_bfd;
|
||||
|
||||
prog_bfd = sim_load_file (sd, myname, sim_callback, prog, abfd,
|
||||
sim_kind == SIM_OPEN_DEBUG,
|
||||
0, sim_write);
|
||||
sim_kind == SIM_OPEN_DEBUG, 0, sim_write);
|
||||
if (prog_bfd == NULL)
|
||||
return SIM_RC_FAIL;
|
||||
ARMul_SetPC (state, bfd_get_start_address (prog_bfd));
|
||||
@@ -464,8 +460,9 @@ void
|
||||
sim_do_command (sd, cmd)
|
||||
SIM_DESC sd;
|
||||
char *cmd;
|
||||
{
|
||||
(*sim_callback->printf_filtered) (sim_callback, "This simulator does not accept any commands.\n");
|
||||
{
|
||||
(*sim_callback->printf_filtered) (sim_callback,
|
||||
"This simulator does not accept any commands.\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
Fri Feb 4 09:45:15 2000 Donald Lindsay <dlindsay@cygnus.com>
|
||||
|
||||
* sim-main.c (cache_op): Added case arm so that CACHE ops to a secondary
|
||||
cache don't get ReservedInstruction traps.
|
||||
|
||||
1999-11-29 Mark Salter <msalter@cygnus.com>
|
||||
|
||||
* dv-tx3904sio.c (tx3904sio_io_write_buffer): Use write value as a mask
|
||||
|
||||
@@ -463,6 +463,7 @@ cache_op (SIM_DESC SD,
|
||||
break;
|
||||
|
||||
case 1: /* data cache */
|
||||
case 3: /* secondary data cache */
|
||||
switch (op >> 2) {
|
||||
case 0: /* Index Writeback Invalidate */
|
||||
case 1: /* Index Load Tag */
|
||||
|
||||
Reference in New Issue
Block a user