Add function to fetch 32bit instructions
When address translation of insn fetch fails raise exception immediatly. Use address_word as type of all address variables (instead of unsigned64), the former is configured as either 32 or 64 bit type. Always compile fpu code (no #if has fpu)
This commit is contained in:
parent
49a7683337
commit
dad6f1f326
|
@ -1,3 +1,23 @@
|
||||||
|
Wed Oct 22 12:52:06 1997 Andrew Cagney <cagney@b1.cygnus.com>
|
||||||
|
|
||||||
|
* sim-main.h (NULLIFY_NEXT_INSTRUCTION, DELAY_SLOT): Define.
|
||||||
|
|
||||||
|
* interp.c (ColdReset): Remove #ifdef HASFPU, check
|
||||||
|
CURRENT_FLOATING_POINT instead.
|
||||||
|
|
||||||
|
* interp.c (ifetch32): New function. Fetch 32 bit instruction.
|
||||||
|
(address_translation): Raise exception InstructionFetch when
|
||||||
|
translation fails and isINSTRUCTION.
|
||||||
|
|
||||||
|
* interp.c (sim_open, sim_write, sim_monitor, store_word,
|
||||||
|
sim_engine_run): Change type of of vaddr and paddr to
|
||||||
|
address_word.
|
||||||
|
(address_translation, prefetch, load_memory, store_memory,
|
||||||
|
cache_op): Change type of vAddr and pAddr to address_word.
|
||||||
|
|
||||||
|
* gencode.c (build_instruction): Change type of vaddr and paddr to
|
||||||
|
address_word.
|
||||||
|
|
||||||
Mon Oct 20 15:29:04 1997 Andrew Cagney <cagney@b1.cygnus.com>
|
Mon Oct 20 15:29:04 1997 Andrew Cagney <cagney@b1.cygnus.com>
|
||||||
|
|
||||||
* sim-main.h (ALU64_END, ALU32_END): Use ALU*_OVERFLOW_RESULT
|
* sim-main.h (ALU64_END, ALU32_END): Use ALU*_OVERFLOW_RESULT
|
||||||
|
|
|
@ -1865,7 +1865,7 @@ build_mips16_operands (bitmap)
|
||||||
if ((op->flags & MIPS16_JUMP_ADDR) != 0)
|
if ((op->flags & MIPS16_JUMP_ADDR) != 0)
|
||||||
{
|
{
|
||||||
printf (" {\n");
|
printf (" {\n");
|
||||||
printf (" uword64 paddr;\n");
|
printf (" address_word paddr;\n");
|
||||||
printf (" int uncached;\n");
|
printf (" int uncached;\n");
|
||||||
printf (" if (AddressTranslation (PC &~ (uword64) 1, isINSTRUCTION, isLOAD, &paddr, &uncached, isTARGET, isREAL))\n");
|
printf (" if (AddressTranslation (PC &~ (uword64) 1, isINSTRUCTION, isLOAD, &paddr, &uncached, isTARGET, isREAL))\n");
|
||||||
printf (" {\n");
|
printf (" {\n");
|
||||||
|
@ -2766,8 +2766,8 @@ build_instruction (doisa, features, mips16, insn)
|
||||||
/* 16-bit offset is sign-extended and added to the base register to make a virtual address */
|
/* 16-bit offset is sign-extended and added to the base register to make a virtual address */
|
||||||
/* The virtual address is translated to a physical address using the TLB */
|
/* The virtual address is translated to a physical address using the TLB */
|
||||||
/* The hint specifies a cache operation for that address */
|
/* The hint specifies a cache operation for that address */
|
||||||
printf(" uword64 vaddr = (op1 + offset);\n");
|
printf(" address_word vaddr = (op1 + offset);\n");
|
||||||
printf(" uword64 paddr;\n");
|
printf(" address_word paddr;\n");
|
||||||
printf(" int uncached;\n");
|
printf(" int uncached;\n");
|
||||||
/* NOTE: We are assuming that the AddressTranslation is a load: */
|
/* NOTE: We are assuming that the AddressTranslation is a load: */
|
||||||
printf(" if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))\n");
|
printf(" if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))\n");
|
||||||
|
@ -2928,10 +2928,10 @@ build_instruction (doisa, features, mips16, insn)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (insn->flags & REG)
|
if (insn->flags & REG)
|
||||||
printf(" uword64 vaddr = ((uword64)op1 + op2);\n");
|
printf(" address_word vaddr = ((uword64)op1 + op2);\n");
|
||||||
else
|
else
|
||||||
printf(" uword64 vaddr = ((uword64)op1 + offset);\n");
|
printf(" address_word vaddr = ((uword64)op1 + offset);\n");
|
||||||
printf(" uword64 paddr;\n");
|
printf(" address_word paddr;\n");
|
||||||
printf(" int uncached;\n");
|
printf(" int uncached;\n");
|
||||||
|
|
||||||
/* The following check should only occur on normal (non-shifted) memory loads */
|
/* The following check should only occur on normal (non-shifted) memory loads */
|
||||||
|
@ -3265,8 +3265,8 @@ build_instruction (doisa, features, mips16, insn)
|
||||||
|
|
||||||
case FPPREFX:
|
case FPPREFX:
|
||||||
/* This code could be merged with the PREFIX generation above: */
|
/* This code could be merged with the PREFIX generation above: */
|
||||||
printf(" uword64 vaddr = ((uword64)op1 + (uword64)op2);\n");
|
printf(" address_word vaddr = ((uword64)op1 + (uword64)op2);\n");
|
||||||
printf(" uword64 paddr;\n");
|
printf(" address_word paddr;\n");
|
||||||
printf(" int uncached;\n");
|
printf(" int uncached;\n");
|
||||||
printf(" if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))\n");
|
printf(" if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))\n");
|
||||||
printf(" Prefetch(uncached,paddr,vaddr,isDATA,fs);\n");
|
printf(" Prefetch(uncached,paddr,vaddr,isDATA,fs);\n");
|
||||||
|
|
|
@ -441,8 +441,8 @@ sim_open (kind, cb, abfd, argv)
|
||||||
the MIPS TRAP system, we place our own (simulator specific)
|
the MIPS TRAP system, we place our own (simulator specific)
|
||||||
"undefined" instructions into the relevant vector slots. */
|
"undefined" instructions into the relevant vector slots. */
|
||||||
for (loop = 0; (loop < monitor_size); loop += 4) {
|
for (loop = 0; (loop < monitor_size); loop += 4) {
|
||||||
uword64 vaddr = (monitor_base + loop);
|
address_word vaddr = (monitor_base + loop);
|
||||||
uword64 paddr;
|
address_word paddr;
|
||||||
int cca;
|
int cca;
|
||||||
if (AddressTranslation(vaddr, isDATA, isSTORE, &paddr, &cca, isTARGET, isRAW))
|
if (AddressTranslation(vaddr, isDATA, isSTORE, &paddr, &cca, isTARGET, isRAW))
|
||||||
StoreMemory(cca, AccessLength_WORD,
|
StoreMemory(cca, AccessLength_WORD,
|
||||||
|
@ -457,8 +457,8 @@ sim_open (kind, cb, abfd, argv)
|
||||||
entry points.*/
|
entry points.*/
|
||||||
for (loop = 0; (loop < 24); loop++)
|
for (loop = 0; (loop < 24); loop++)
|
||||||
{
|
{
|
||||||
uword64 vaddr = (monitor_base + 0x500 + (loop * 4));
|
address_word vaddr = (monitor_base + 0x500 + (loop * 4));
|
||||||
uword64 paddr;
|
address_word paddr;
|
||||||
int cca;
|
int cca;
|
||||||
unsigned int value = ((0x500 - 8) / 8); /* default UNDEFINED reason code */
|
unsigned int value = ((0x500 - 8) / 8); /* default UNDEFINED reason code */
|
||||||
switch (loop)
|
switch (loop)
|
||||||
|
@ -587,7 +587,7 @@ sim_write (sd,addr,buffer,size)
|
||||||
way. We can then perform doubleword transfers to and from the
|
way. We can then perform doubleword transfers to and from the
|
||||||
simulator memory for optimum performance. */
|
simulator memory for optimum performance. */
|
||||||
if (index && (index & 1)) {
|
if (index && (index & 1)) {
|
||||||
uword64 paddr;
|
address_word paddr;
|
||||||
int cca;
|
int cca;
|
||||||
if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&cca,isTARGET,isRAW)) {
|
if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&cca,isTARGET,isRAW)) {
|
||||||
uword64 value = ((uword64)(*buffer++));
|
uword64 value = ((uword64)(*buffer++));
|
||||||
|
@ -597,7 +597,7 @@ sim_write (sd,addr,buffer,size)
|
||||||
index &= ~1; /* logical operations usually quicker than arithmetic on RISC systems */
|
index &= ~1; /* logical operations usually quicker than arithmetic on RISC systems */
|
||||||
}
|
}
|
||||||
if (index && (index & 2)) {
|
if (index && (index & 2)) {
|
||||||
uword64 paddr;
|
address_word paddr;
|
||||||
int cca;
|
int cca;
|
||||||
if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&cca,isTARGET,isRAW)) {
|
if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&cca,isTARGET,isRAW)) {
|
||||||
uword64 value;
|
uword64 value;
|
||||||
|
@ -617,7 +617,7 @@ sim_write (sd,addr,buffer,size)
|
||||||
index &= ~2;
|
index &= ~2;
|
||||||
}
|
}
|
||||||
if (index && (index & 4)) {
|
if (index && (index & 4)) {
|
||||||
uword64 paddr;
|
address_word paddr;
|
||||||
int cca;
|
int cca;
|
||||||
if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&cca,isTARGET,isRAW)) {
|
if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&cca,isTARGET,isRAW)) {
|
||||||
uword64 value;
|
uword64 value;
|
||||||
|
@ -638,7 +638,7 @@ sim_write (sd,addr,buffer,size)
|
||||||
index &= ~4;
|
index &= ~4;
|
||||||
}
|
}
|
||||||
for (;index; index -= 8) {
|
for (;index; index -= 8) {
|
||||||
uword64 paddr;
|
address_word paddr;
|
||||||
int cca;
|
int cca;
|
||||||
if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&cca,isTARGET,isRAW)) {
|
if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&cca,isTARGET,isRAW)) {
|
||||||
uword64 value;
|
uword64 value;
|
||||||
|
@ -688,9 +688,11 @@ sim_read (sd,addr,buffer,size)
|
||||||
to ensure that the source physical address is doubleword aligned
|
to ensure that the source physical address is doubleword aligned
|
||||||
before, and then deal with trailing bytes. */
|
before, and then deal with trailing bytes. */
|
||||||
for (index = 0; (index < size); index++) {
|
for (index = 0; (index < size); index++) {
|
||||||
uword64 vaddr,paddr,value;
|
address_word vaddr;
|
||||||
|
address_word paddr;
|
||||||
|
unsigned64 value;
|
||||||
int cca;
|
int cca;
|
||||||
vaddr = (uword64)addr + index;
|
vaddr = (address_word)addr + index;
|
||||||
if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&cca,isTARGET,isRAW)) {
|
if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&cca,isTARGET,isRAW)) {
|
||||||
LoadMemory(&value,NULL,cca,AccessLength_BYTE,paddr,vaddr,isDATA,isRAW);
|
LoadMemory(&value,NULL,cca,AccessLength_BYTE,paddr,vaddr,isDATA,isRAW);
|
||||||
buffer[index] = (unsigned char)(value&0xFF);
|
buffer[index] = (unsigned char)(value&0xFF);
|
||||||
|
@ -819,38 +821,24 @@ sim_create_inferior (sd, abfd, argv,env)
|
||||||
#endif /* DEBUG */
|
#endif /* DEBUG */
|
||||||
|
|
||||||
ColdReset(sd);
|
ColdReset(sd);
|
||||||
/* If we were providing a more complete I/O, co-processor or memory
|
|
||||||
simulation, we should perform any "device" initialisation at this
|
|
||||||
point. This can include pre-loading memory areas with particular
|
|
||||||
patterns (e.g. simulating ROM monitors). */
|
|
||||||
|
|
||||||
#if 1
|
|
||||||
if (abfd != NULL)
|
if (abfd != NULL)
|
||||||
PC = (unsigned64) bfd_get_start_address(abfd);
|
/* override PC value set by ColdReset () */
|
||||||
else
|
PC = (unsigned64) bfd_get_start_address (abfd);
|
||||||
PC = 0; /* ???? */
|
|
||||||
#else
|
|
||||||
/* TODO: Sort this properly. SIM_ADDR may already be a 64bit value: */
|
|
||||||
PC = SIGNEXTEND(bfd_get_start_address(abfd),32);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Prepare to execute the program to be simulated */
|
|
||||||
/* argv and env are NULL terminated lists of pointers */
|
|
||||||
|
|
||||||
if (argv || env) {
|
|
||||||
#if 0 /* def DEBUG */
|
#if 0 /* def DEBUG */
|
||||||
sim_io_printf(sd,"sim_create_inferior() : passed arguments ignored\n");
|
if (argv || env)
|
||||||
{
|
{
|
||||||
char **cptr;
|
/* We should really place the argv slot values into the argument
|
||||||
for (cptr = argv; (cptr && *cptr); cptr++)
|
registers, and onto the stack as required. However, this
|
||||||
printf("DBG: arg \"%s\"\n",*cptr);
|
assumes that we have a stack defined, which is not
|
||||||
|
necessarily true at the moment. */
|
||||||
|
char **cptr;
|
||||||
|
sim_io_printf(sd,"sim_create_inferior() : passed arguments ignored\n");
|
||||||
|
for (cptr = argv; (cptr && *cptr); cptr++)
|
||||||
|
printf("DBG: arg \"%s\"\n",*cptr);
|
||||||
}
|
}
|
||||||
#endif /* DEBUG */
|
#endif /* DEBUG */
|
||||||
/* We should really place the argv slot values into the argument
|
|
||||||
registers, and onto the stack as required. However, this
|
|
||||||
assumes that we have a stack defined, which is not necessarily
|
|
||||||
true at the moment. */
|
|
||||||
}
|
|
||||||
|
|
||||||
return SIM_RC_OK;
|
return SIM_RC_OK;
|
||||||
}
|
}
|
||||||
|
@ -984,7 +972,7 @@ sim_monitor(sd,reason)
|
||||||
switch (reason) {
|
switch (reason) {
|
||||||
case 6: /* int open(char *path,int flags) */
|
case 6: /* int open(char *path,int flags) */
|
||||||
{
|
{
|
||||||
uword64 paddr;
|
address_word paddr;
|
||||||
int cca;
|
int cca;
|
||||||
if (AddressTranslation(A0,isDATA,isLOAD,&paddr,&cca,isHOST,isREAL))
|
if (AddressTranslation(A0,isDATA,isLOAD,&paddr,&cca,isHOST,isREAL))
|
||||||
V0 = sim_io_open(sd,(char *)((int)paddr),(int)A1);
|
V0 = sim_io_open(sd,(char *)((int)paddr),(int)A1);
|
||||||
|
@ -995,7 +983,7 @@ sim_monitor(sd,reason)
|
||||||
|
|
||||||
case 7: /* int read(int file,char *ptr,int len) */
|
case 7: /* int read(int file,char *ptr,int len) */
|
||||||
{
|
{
|
||||||
uword64 paddr;
|
address_word paddr;
|
||||||
int cca;
|
int cca;
|
||||||
if (AddressTranslation(A1,isDATA,isLOAD,&paddr,&cca,isHOST,isREAL))
|
if (AddressTranslation(A1,isDATA,isLOAD,&paddr,&cca,isHOST,isREAL))
|
||||||
V0 = sim_io_read(sd,(int)A0,(char *)((int)paddr),(int)A2);
|
V0 = sim_io_read(sd,(int)A0,(char *)((int)paddr),(int)A2);
|
||||||
|
@ -1006,7 +994,7 @@ sim_monitor(sd,reason)
|
||||||
|
|
||||||
case 8: /* int write(int file,char *ptr,int len) */
|
case 8: /* int write(int file,char *ptr,int len) */
|
||||||
{
|
{
|
||||||
uword64 paddr;
|
address_word paddr;
|
||||||
int cca;
|
int cca;
|
||||||
if (AddressTranslation(A1,isDATA,isLOAD,&paddr,&cca,isHOST,isREAL))
|
if (AddressTranslation(A1,isDATA,isLOAD,&paddr,&cca,isHOST,isREAL))
|
||||||
V0 = sim_io_write(sd,(int)A0,(const char *)((int)paddr),(int)A2);
|
V0 = sim_io_write(sd,(int)A0,(const char *)((int)paddr),(int)A2);
|
||||||
|
@ -1053,8 +1041,8 @@ sim_monitor(sd,reason)
|
||||||
/* [A0 + 4] = instruction cache size */
|
/* [A0 + 4] = instruction cache size */
|
||||||
/* [A0 + 8] = data cache size */
|
/* [A0 + 8] = data cache size */
|
||||||
{
|
{
|
||||||
uword64 vaddr = A0;
|
address_word vaddr = A0;
|
||||||
uword64 paddr, value;
|
address_word paddr, value;
|
||||||
int cca;
|
int cca;
|
||||||
int failed = 0;
|
int failed = 0;
|
||||||
|
|
||||||
|
@ -1095,7 +1083,7 @@ sim_monitor(sd,reason)
|
||||||
/* out: void */
|
/* out: void */
|
||||||
/* The following is based on the PMON printf source */
|
/* The following is based on the PMON printf source */
|
||||||
{
|
{
|
||||||
uword64 paddr;
|
address_word paddr;
|
||||||
int cca;
|
int cca;
|
||||||
/* This isn't the quickest way, since we call the host print
|
/* This isn't the quickest way, since we call the host print
|
||||||
routine for every character almost. But it does avoid
|
routine for every character almost. But it does avoid
|
||||||
|
@ -1210,7 +1198,7 @@ store_word (sd, vaddr, val)
|
||||||
uword64 vaddr;
|
uword64 vaddr;
|
||||||
t_reg val;
|
t_reg val;
|
||||||
{
|
{
|
||||||
uword64 paddr;
|
address_word paddr;
|
||||||
int uncached;
|
int uncached;
|
||||||
|
|
||||||
if ((vaddr & 3) != 0)
|
if ((vaddr & 3) != 0)
|
||||||
|
@ -1244,7 +1232,7 @@ load_word (sd, vaddr)
|
||||||
SignalExceptionAddressLoad ();
|
SignalExceptionAddressLoad ();
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
uword64 paddr;
|
address_word paddr;
|
||||||
int uncached;
|
int uncached;
|
||||||
|
|
||||||
if (AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached,
|
if (AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached,
|
||||||
|
@ -1475,20 +1463,20 @@ void dotrace(SIM_DESC sd,FILE *tracefh,int type,SIM_ADDR address,int width,char
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ColdReset(sd)
|
ColdReset (sd)
|
||||||
SIM_DESC sd;
|
SIM_DESC sd;
|
||||||
{
|
{
|
||||||
/* RESET: Fixed PC address: */
|
/* RESET: Fixed PC address: */
|
||||||
PC = (((uword64)0xFFFFFFFF<<32) | 0xBFC00000);
|
PC = UNSIGNED64 (0xFFFFFFFFBFC00000);
|
||||||
/* The reset vector address is in the unmapped, uncached memory space. */
|
/* The reset vector address is in the unmapped, uncached memory space. */
|
||||||
|
|
||||||
SR &= ~(status_SR | status_TS | status_RP);
|
SR &= ~(status_SR | status_TS | status_RP);
|
||||||
SR |= (status_ERL | status_BEV);
|
SR |= (status_ERL | status_BEV);
|
||||||
|
|
||||||
#if defined(HASFPU) && (GPRLEN == (64))
|
/* Cheat and allow access to the complete register set immediately */
|
||||||
/* Cheat and allow access to the complete register set immediately: */
|
if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT
|
||||||
SR |= status_FR; /* 64bit registers */
|
&& WITH_TARGET_WORD_BITSIZE == 64)
|
||||||
#endif /* HASFPU and 64bit FP registers */
|
SR |= status_FR; /* 64bit registers */
|
||||||
|
|
||||||
/* Ensure that any instructions with pending register updates are
|
/* Ensure that any instructions with pending register updates are
|
||||||
cleared: */
|
cleared: */
|
||||||
|
@ -1499,19 +1487,19 @@ ColdReset(sd)
|
||||||
PENDING_IN = PENDING_OUT = PENDING_TOTAL = 0;
|
PENDING_IN = PENDING_OUT = PENDING_TOTAL = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(HASFPU)
|
|
||||||
/* Initialise the FPU registers to the unknown state */
|
/* Initialise the FPU registers to the unknown state */
|
||||||
{
|
if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
|
||||||
int rn;
|
{
|
||||||
for (rn = 0; (rn < 32); rn++)
|
int rn;
|
||||||
FPR_STATE[rn] = fmt_uninterpreted;
|
for (rn = 0; (rn < 32); rn++)
|
||||||
}
|
FPR_STATE[rn] = fmt_uninterpreted;
|
||||||
#endif /* HASFPU */
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Description from page A-22 of the "MIPS IV Instruction Set" manual (revision 3.1) */
|
/* Description from page A-22 of the "MIPS IV Instruction Set" manual
|
||||||
|
(revision 3.1) */
|
||||||
/* Translate a virtual address to a physical address and cache
|
/* Translate a virtual address to a physical address and cache
|
||||||
coherence algorithm describing the mechanism used to resolve the
|
coherence algorithm describing the mechanism used to resolve the
|
||||||
memory reference. Given the virtual address vAddr, and whether the
|
memory reference. Given the virtual address vAddr, and whether the
|
||||||
|
@ -1525,17 +1513,16 @@ ColdReset(sd)
|
||||||
translation is not present in the TLB or the desired access is not
|
translation is not present in the TLB or the desired access is not
|
||||||
permitted the function fails and an exception is taken.
|
permitted the function fails and an exception is taken.
|
||||||
|
|
||||||
NOTE: This function is extended to return an exception state. This,
|
NOTE: Normally (RAW == 0), when address translation fails, this
|
||||||
along with the exception generation is used to notify whether a
|
function raises an exception and does not return. */
|
||||||
valid address translation occured */
|
|
||||||
|
|
||||||
int
|
int
|
||||||
address_translation(sd,vAddr,IorD,LorS,pAddr,CCA,host,raw)
|
address_translation(sd,vAddr,IorD,LorS,pAddr,CCA,host,raw)
|
||||||
SIM_DESC sd;
|
SIM_DESC sd;
|
||||||
uword64 vAddr;
|
address_word vAddr;
|
||||||
int IorD;
|
int IorD;
|
||||||
int LorS;
|
int LorS;
|
||||||
uword64 *pAddr;
|
address_word *pAddr;
|
||||||
int *CCA;
|
int *CCA;
|
||||||
int host;
|
int host;
|
||||||
int raw;
|
int raw;
|
||||||
|
@ -1583,17 +1570,21 @@ address_translation(sd,vAddr,IorD,LorS,pAddr,CCA,host,raw)
|
||||||
res = 0; /* AddressTranslation has failed */
|
res = 0; /* AddressTranslation has failed */
|
||||||
*pAddr = (SIM_ADDR)-1;
|
*pAddr = (SIM_ADDR)-1;
|
||||||
if (!raw) /* only generate exceptions on real memory transfers */
|
if (!raw) /* only generate exceptions on real memory transfers */
|
||||||
if (LorS == isSTORE)
|
{
|
||||||
SignalExceptionAddressStore ();
|
if (IorD == isINSTRUCTION)
|
||||||
else
|
SignalExceptionInstructionFetch ();
|
||||||
SignalExceptionAddressLoad ();
|
else if (LorS == isSTORE)
|
||||||
|
SignalExceptionAddressStore ();
|
||||||
|
else
|
||||||
|
SignalExceptionAddressLoad ();
|
||||||
|
}
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
else
|
else
|
||||||
/* This is a normal occurance during gdb operation, for instance trying
|
/* This is a normal occurance during gdb operation, for instance
|
||||||
to print parameters at function start before they have been setup,
|
trying to print parameters at function start before they have
|
||||||
and hence we should not print a warning except when debugging the
|
been setup, and hence we should not print a warning except
|
||||||
simulator. */
|
when debugging the simulator. */
|
||||||
sim_io_eprintf(sd,"AddressTranslation for %s %s from 0x%s failed\n",(IorD ? "data" : "instruction"),(LorS ? "store" : "load"),pr_addr(vAddr));
|
sim_io_eprintf(sd,"AddressTranslation for %s %s from 0x%s failed\n",(IorD ? "data" : "instruction"),(LorS ? "store" : "load"),pr_addr(vAddr));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1610,8 +1601,8 @@ void
|
||||||
prefetch(sd,CCA,pAddr,vAddr,DATA,hint)
|
prefetch(sd,CCA,pAddr,vAddr,DATA,hint)
|
||||||
SIM_DESC sd;
|
SIM_DESC sd;
|
||||||
int CCA;
|
int CCA;
|
||||||
uword64 pAddr;
|
address_word pAddr;
|
||||||
uword64 vAddr;
|
address_word vAddr;
|
||||||
int DATA;
|
int DATA;
|
||||||
int hint;
|
int hint;
|
||||||
{
|
{
|
||||||
|
@ -1645,8 +1636,8 @@ load_memory(sd,memvalp,memval1p,CCA,AccessLength,pAddr,vAddr,IorD,raw)
|
||||||
uword64* memval1p;
|
uword64* memval1p;
|
||||||
int CCA;
|
int CCA;
|
||||||
int AccessLength;
|
int AccessLength;
|
||||||
uword64 pAddr;
|
address_word pAddr;
|
||||||
uword64 vAddr;
|
address_word vAddr;
|
||||||
int IorD;
|
int IorD;
|
||||||
int raw;
|
int raw;
|
||||||
{
|
{
|
||||||
|
@ -1841,8 +1832,8 @@ store_memory(sd,CCA,AccessLength,MemElem,MemElem1,pAddr,vAddr,raw)
|
||||||
int AccessLength;
|
int AccessLength;
|
||||||
uword64 MemElem;
|
uword64 MemElem;
|
||||||
uword64 MemElem1; /* High order 64 bits */
|
uword64 MemElem1; /* High order 64 bits */
|
||||||
uword64 pAddr;
|
address_word pAddr;
|
||||||
uword64 vAddr;
|
address_word vAddr;
|
||||||
int raw;
|
int raw;
|
||||||
{
|
{
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
@ -2003,6 +1994,26 @@ store_memory(sd,CCA,AccessLength,MemElem,MemElem1,pAddr,vAddr,raw)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unsigned32
|
||||||
|
ifetch32 (SIM_DESC sd, address_word vaddr)
|
||||||
|
{
|
||||||
|
/* Copy the action of the LW instruction */
|
||||||
|
address_word reverse = (ReverseEndian ? (LOADDRMASK >> 2) : 0);
|
||||||
|
address_word bigend = (BigEndianCPU ? (LOADDRMASK >> 2) : 0);
|
||||||
|
unsigned64 value;
|
||||||
|
address_word paddr;
|
||||||
|
unsigned32 instruction;
|
||||||
|
unsigned byte;
|
||||||
|
int cca;
|
||||||
|
AddressTranslation (vaddr, isINSTRUCTION, isLOAD, &paddr, &cca, isTARGET, isREAL);
|
||||||
|
paddr = ((paddr & ~LOADDRMASK) | ((paddr & LOADDRMASK) ^ (reverse << 2)));
|
||||||
|
LoadMemory (&value, NULL, cca, AccessLength_WORD, paddr, vaddr, isINSTRUCTION, isREAL);
|
||||||
|
byte = ((vaddr & LOADDRMASK) ^ (bigend << 2));
|
||||||
|
instruction = ((value >> (8 * byte)) & 0xFFFFFFFF);
|
||||||
|
return instruction;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Description from page A-26 of the "MIPS IV Instruction Set" manual (revision 3.1) */
|
/* Description from page A-26 of the "MIPS IV Instruction Set" manual (revision 3.1) */
|
||||||
/* Order loads and stores to synchronise shared memory. Perform the
|
/* Order loads and stores to synchronise shared memory. Perform the
|
||||||
action necessary to make the effects of groups of synchronizable
|
action necessary to make the effects of groups of synchronizable
|
||||||
|
@ -2269,8 +2280,8 @@ void
|
||||||
cache_op(sd,op,pAddr,vAddr,instruction)
|
cache_op(sd,op,pAddr,vAddr,instruction)
|
||||||
SIM_DESC sd;
|
SIM_DESC sd;
|
||||||
int op;
|
int op;
|
||||||
uword64 pAddr;
|
address_word pAddr;
|
||||||
uword64 vAddr;
|
address_word vAddr;
|
||||||
unsigned int instruction;
|
unsigned int instruction;
|
||||||
{
|
{
|
||||||
#if 1 /* stop warning message being displayed (we should really just remove the code) */
|
#if 1 /* stop warning message being displayed (we should really just remove the code) */
|
||||||
|
@ -3546,8 +3557,14 @@ decode_coproc(sd,instruction)
|
||||||
|
|
||||||
/*-- instruction simulation -------------------------------------------------*/
|
/*-- instruction simulation -------------------------------------------------*/
|
||||||
|
|
||||||
|
#if defined (WITH_IGEN)
|
||||||
|
void old_engine_run PARAMS ((SIM_DESC sd, int next_cpu_nr, int siggnal));
|
||||||
|
void
|
||||||
|
old_engine_run (sd, next_cpu_nr, siggnal)
|
||||||
|
#else
|
||||||
void
|
void
|
||||||
sim_engine_run (sd, next_cpu_nr, siggnal)
|
sim_engine_run (sd, next_cpu_nr, siggnal)
|
||||||
|
#endif
|
||||||
SIM_DESC sd;
|
SIM_DESC sd;
|
||||||
int next_cpu_nr; /* ignore */
|
int next_cpu_nr; /* ignore */
|
||||||
int siggnal; /* ignore */
|
int siggnal; /* ignore */
|
||||||
|
@ -3573,23 +3590,16 @@ sim_engine_run (sd, next_cpu_nr, siggnal)
|
||||||
/* main controlling loop */
|
/* main controlling loop */
|
||||||
while (1) {
|
while (1) {
|
||||||
/* Fetch the next instruction from the simulator memory: */
|
/* Fetch the next instruction from the simulator memory: */
|
||||||
uword64 vaddr = (uword64)PC;
|
address_word vaddr = (uword64)PC;
|
||||||
uword64 paddr;
|
address_word paddr;
|
||||||
int cca;
|
int cca;
|
||||||
unsigned int instruction; /* uword64? what's this used for? FIXME! */
|
unsigned int instruction; /* uword64? what's this used for? FIXME! */
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
{
|
{
|
||||||
printf("DBG: state = 0x%08X :",state);
|
printf("DBG: state = 0x%08X :",state);
|
||||||
#if 0
|
|
||||||
if (state & simSTOP) printf(" simSTOP");
|
|
||||||
if (state & simSTEP) printf(" simSTEP");
|
|
||||||
#endif
|
|
||||||
if (state & simHALTEX) printf(" simHALTEX");
|
if (state & simHALTEX) printf(" simHALTEX");
|
||||||
if (state & simHALTIN) printf(" simHALTIN");
|
if (state & simHALTIN) printf(" simHALTIN");
|
||||||
#if 0
|
|
||||||
if (state & simBE) printf(" simBE");
|
|
||||||
#endif
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
#endif /* DEBUG */
|
#endif /* DEBUG */
|
||||||
|
|
|
@ -35,21 +35,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
|
||||||
#include "sim-basics.h"
|
#include "sim-basics.h"
|
||||||
|
|
||||||
|
typedef address_word sim_cia;
|
||||||
#if 0
|
|
||||||
/* These are generated files. */
|
|
||||||
#include "itable.h"
|
|
||||||
#include "idecode.h"
|
|
||||||
#include "idecode.h"
|
|
||||||
|
|
||||||
/* dummy - not used */
|
|
||||||
typedef instruction_address sim_cia;
|
|
||||||
static const sim_cia null_cia = {0}; /* dummy */
|
|
||||||
#define NULL_CIA null_cia
|
|
||||||
#else
|
|
||||||
typedef int sim_cia;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#include "sim-base.h"
|
#include "sim-base.h"
|
||||||
|
|
||||||
|
@ -303,13 +289,31 @@ struct _sim_cpu {
|
||||||
|
|
||||||
/* The following are internal simulator state variables: */
|
/* The following are internal simulator state variables: */
|
||||||
sim_cia cia;
|
sim_cia cia;
|
||||||
#define CPU_CIA(CPU) ((CPU)->cia)
|
#define CPU_CIA(CPU) (PC)
|
||||||
address_word ipc; /* internal Instruction PC */
|
address_word ipc; /* internal Instruction PC */
|
||||||
address_word dspc; /* delay-slot PC */
|
address_word dspc; /* delay-slot PC */
|
||||||
#define IPC ((STATE_CPU (sd,0))->ipc)
|
#define IPC ((STATE_CPU (sd,0))->ipc)
|
||||||
#define DSPC ((STATE_CPU (sd,0))->dspc)
|
#define DSPC ((STATE_CPU (sd,0))->dspc)
|
||||||
|
|
||||||
#define NULLIFY_NIA() { nia.ip = cia.dp + 4; nia.dp = nia.ip += 4; }
|
/* Issue a delay slot instruction immediatly by re-calling
|
||||||
|
idecode_issue */
|
||||||
|
#define DELAY_SLOT(TARGET) \
|
||||||
|
do { \
|
||||||
|
address_word target = (TARGET); \
|
||||||
|
instruction_word delay_insn; \
|
||||||
|
sim_events_slip (sd, 1); \
|
||||||
|
PC = CIA + 4; \
|
||||||
|
STATE |= simDELAYSLOT; \
|
||||||
|
delay_insn = IMEM (PC); \
|
||||||
|
idecode_issue (sd, delay_insn, (PC)); \
|
||||||
|
STATE &= !simDELAYSLOT; \
|
||||||
|
PC = target; \
|
||||||
|
} while (0)
|
||||||
|
#define NULLIFY_NEXT_INSTRUCTION() \
|
||||||
|
do { \
|
||||||
|
sim_events_slip (sd, 1); \
|
||||||
|
NIA = CIA + 4; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -680,28 +684,29 @@ void decode_coproc PARAMS ((SIM_DESC sd,unsigned int instruction));
|
||||||
#define AccessLength_DOUBLEWORD (7)
|
#define AccessLength_DOUBLEWORD (7)
|
||||||
#define AccessLength_QUADWORD (15)
|
#define AccessLength_QUADWORD (15)
|
||||||
|
|
||||||
int address_translation PARAMS ((SIM_DESC sd, uword64 vAddr, int IorD, int LorS, uword64 *pAddr, int *CCA, int host, int raw));
|
int address_translation PARAMS ((SIM_DESC sd, address_word vAddr, int IorD, int LorS, address_word *pAddr, int *CCA, int host, int raw));
|
||||||
#define AddressTranslation(vAddr,IorD,LorS,pAddr,CCA,host,raw) \
|
#define AddressTranslation(vAddr,IorD,LorS,pAddr,CCA,host,raw) \
|
||||||
address_translation(sd, vAddr,IorD,LorS,pAddr,CCA,host,raw)
|
address_translation(sd, vAddr,IorD,LorS,pAddr,CCA,host,raw)
|
||||||
|
|
||||||
void load_memory PARAMS ((SIM_DESC sd, uword64* memvalp, uword64* memval1p, int CCA, int AccessLength, uword64 pAddr, uword64 vAddr, int IorD, int raw));
|
void load_memory PARAMS ((SIM_DESC sd, uword64* memvalp, uword64* memval1p, int CCA, int AccessLength, address_word pAddr, address_word vAddr, int IorD, int raw));
|
||||||
#define LoadMemory(memvalp,memval1p,CCA,AccessLength,pAddr,vAddr,IorD,raw) \
|
#define LoadMemory(memvalp,memval1p,CCA,AccessLength,pAddr,vAddr,IorD,raw) \
|
||||||
load_memory(sd,memvalp,memval1p,CCA,AccessLength,pAddr,vAddr,IorD,raw)
|
load_memory(sd,memvalp,memval1p,CCA,AccessLength,pAddr,vAddr,IorD,raw)
|
||||||
|
|
||||||
void store_memory PARAMS ((SIM_DESC sd, int CCA, int AccessLength, uword64 MemElem, uword64 MemElem1, uword64 pAddr, uword64 vAddr, int raw));
|
void store_memory PARAMS ((SIM_DESC sd, int CCA, int AccessLength, uword64 MemElem, uword64 MemElem1, address_word pAddr, address_word vAddr, int raw));
|
||||||
#define StoreMemory(CCA,AccessLength,MemElem,MemElem1,pAddr,vAddr,raw) \
|
#define StoreMemory(CCA,AccessLength,MemElem,MemElem1,pAddr,vAddr,raw) \
|
||||||
store_memory(sd,CCA,AccessLength,MemElem,MemElem1,pAddr,vAddr,raw)
|
store_memory(sd,CCA,AccessLength,MemElem,MemElem1,pAddr,vAddr,raw)
|
||||||
|
|
||||||
void cache_op PARAMS ((SIM_DESC sd, int op, uword64 pAddr, uword64 vAddr, unsigned int instruction));
|
void cache_op PARAMS ((SIM_DESC sd, int op, address_word pAddr, address_word vAddr, unsigned int instruction));
|
||||||
#define CacheOp(op,pAddr,vAddr,instruction) cache_op(sd,op,pAddr,vAddr,instruction)
|
#define CacheOp(op,pAddr,vAddr,instruction) cache_op(sd,op,pAddr,vAddr,instruction)
|
||||||
|
|
||||||
void sync_operation PARAMS ((SIM_DESC sd, int stype));
|
void sync_operation PARAMS ((SIM_DESC sd, int stype));
|
||||||
#define SyncOperation(stype) sync_operation (sd, (stype))
|
#define SyncOperation(stype) sync_operation (sd, (stype))
|
||||||
|
|
||||||
void prefetch PARAMS ((SIM_DESC sd, int CCA, uword64 pAddr, uword64 vAddr, int DATA, int hint));
|
void prefetch PARAMS ((SIM_DESC sd, int CCA, address_word pAddr, address_word vAddr, int DATA, int hint));
|
||||||
#define Prefetch(CCA,pAddr,vAddr,DATA,hint) prefetch(sd,CCA,pAddr,vAddr,DATA,hint)
|
#define Prefetch(CCA,pAddr,vAddr,DATA,hint) prefetch(sd,CCA,pAddr,vAddr,DATA,hint)
|
||||||
|
|
||||||
#define IMEM(CIA) 0 /* FIXME */
|
unsigned32 ifetch32 PARAMS ((SIM_DESC sd, address_word cia));
|
||||||
|
#define IMEM(CIA) ifetch32 (SD, (CIA))
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue