#ifndef SIM_MAIN_C
#define SIM_MAIN_C
#include "sim-main.h"
#include "sim-assert.h"
INLINE_SIM_MAIN
(int)
address_translation (SIM_DESC sd,
sim_cpu * cpu,
address_word cia,
address_word vAddr,
int IorD,
int LorS,
address_word * pAddr,
int *CCA,
int raw)
{
int res = -1;
#ifdef DEBUG
sim_io_printf (sd, "AddressTranslation(0x%s,%s,%s,...);\n", pr_addr (vAddr), (IorD ? "isDATA" : "isINSTRUCTION"), (LorS ? "iSTORE" : "isLOAD"));
#endif
vAddr &= 0xFFFFFFFF;
*pAddr = vAddr;
*CCA = Uncached;
return (res);
}
INLINE_SIM_MAIN (void)
prefetch (SIM_DESC sd,
sim_cpu *cpu,
address_word cia,
int CCA,
address_word pAddr,
address_word vAddr,
int DATA,
int hint)
{
#ifdef DEBUG
sim_io_printf(sd,"Prefetch(%d,0x%s,0x%s,%d,%d);\n",CCA,pr_addr(pAddr),pr_addr(vAddr),DATA,hint);
#endif
return;
}
INLINE_SIM_MAIN (void)
load_memory (SIM_DESC SD,
sim_cpu *CPU,
address_word cia,
uword64* memvalp,
uword64* memval1p,
int CCA,
unsigned int AccessLength,
address_word pAddr,
address_word vAddr,
int IorD)
{
uword64 value = 0;
uword64 value1 = 0;
#ifdef DEBUG
sim_io_printf(sd,"DBG: LoadMemory(%p,%p,%d,%d,0x%s,0x%s,%s)\n",memvalp,memval1p,CCA,AccessLength,pr_addr(pAddr),pr_addr(vAddr),(IorD ? "isDATA" : "isINSTRUCTION"));
#endif
#if defined(WARN_MEM)
if (CCA != uncached)
sim_io_eprintf(sd,"LoadMemory CCA (%d) is not uncached (currently all accesses treated as cached)\n",CCA);
#endif
if (((pAddr & LOADDRMASK) + AccessLength) > LOADDRMASK)
{
sim_io_error (SD, "LOAD AccessLength of %d would extend over %d bit aligned boundary for physical address 0x%s\n",
AccessLength,
(LOADDRMASK + 1) << 3,
pr_addr (pAddr));
}
#if defined(TRACE)
dotrace (SD, CPU, tracefh,((IorD == isDATA) ? 0 : 2),(unsigned int)(pAddr&0xFFFFFFFF),(AccessLength + 1),"load%s",((IorD == isDATA) ? "" : " instruction"));
#endif
switch (AccessLength)
{
case AccessLength_QUADWORD:
{
unsigned_16 val = sim_core_read_aligned_16 (CPU, cia, read_map, pAddr);
value1 = VH8_16 (val);
value = VL8_16 (val);
break;
}
case AccessLength_DOUBLEWORD:
value = sim_core_read_aligned_8 (CPU, cia, read_map, pAddr);
break;
case AccessLength_SEPTIBYTE:
value = sim_core_read_misaligned_7 (CPU, cia, read_map, pAddr);
break;
case AccessLength_SEXTIBYTE:
value = sim_core_read_misaligned_6 (CPU, cia, read_map, pAddr);
break;
case AccessLength_QUINTIBYTE:
value = sim_core_read_misaligned_5 (CPU, cia, read_map, pAddr);
break;
case AccessLength_WORD:
value = sim_core_read_aligned_4 (CPU, cia, read_map, pAddr);
break;
case AccessLength_TRIPLEBYTE:
value = sim_core_read_misaligned_3 (CPU, cia, read_map, pAddr);
break;
case AccessLength_HALFWORD:
value = sim_core_read_aligned_2 (CPU, cia, read_map, pAddr);
break;
case AccessLength_BYTE:
value = sim_core_read_aligned_1 (CPU, cia, read_map, pAddr);
break;
default:
abort ();
}
#ifdef DEBUG
printf("DBG: LoadMemory() : (offset %d) : value = 0x%s%s\n",
(int)(pAddr & LOADDRMASK),pr_uword64(value1),pr_uword64(value));
#endif
if (AccessLength <= LOADDRMASK)
{
if (BigEndianMem)
value <<= (((LOADDRMASK - (pAddr & LOADDRMASK)) - AccessLength) * 8);
else
value <<= ((pAddr & LOADDRMASK) * 8);
}
#ifdef DEBUG
printf("DBG: LoadMemory() : shifted value = 0x%s%s\n",
pr_uword64(value1),pr_uword64(value));
#endif
*memvalp = value;
if (memval1p) *memval1p = value1;
}
INLINE_SIM_MAIN (void)
store_memory (SIM_DESC SD,
sim_cpu *CPU,
address_word cia,
int CCA,
unsigned int AccessLength,
uword64 MemElem,
uword64 MemElem1,
address_word pAddr,
address_word vAddr)
{
#ifdef DEBUG
sim_io_printf(sd,"DBG: StoreMemory(%d,%d,0x%s,0x%s,0x%s,0x%s)\n",CCA,AccessLength,pr_uword64(MemElem),pr_uword64(MemElem1),pr_addr(pAddr),pr_addr(vAddr));
#endif
#if defined(WARN_MEM)
if (CCA != uncached)
sim_io_eprintf(sd,"StoreMemory CCA (%d) is not uncached (currently all accesses treated as cached)\n",CCA);
#endif
if (((pAddr & LOADDRMASK) + AccessLength) > LOADDRMASK)
sim_io_error (SD, "STORE AccessLength of %d would extend over %d bit aligned boundary for physical address 0x%s\n",
AccessLength,
(LOADDRMASK + 1) << 3,
pr_addr(pAddr));
#if defined(TRACE)
dotrace (SD, CPU, tracefh,1,(unsigned int)(pAddr&0xFFFFFFFF),(AccessLength + 1),"store");
#endif
#ifdef DEBUG
printf("DBG: StoreMemory: offset = %d MemElem = 0x%s%s\n",(unsigned int)(pAddr & LOADDRMASK),pr_uword64(MemElem1),pr_uword64(MemElem));
#endif
if (AccessLength <= LOADDRMASK)
{
if (BigEndianMem)
MemElem >>= (((LOADDRMASK - (pAddr & LOADDRMASK)) - AccessLength) * 8);
else
MemElem >>= ((pAddr & LOADDRMASK) * 8);
}
#ifdef DEBUG
printf("DBG: StoreMemory: shift = %d MemElem = 0x%s%s\n",shift,pr_uword64(MemElem1),pr_uword64(MemElem));
#endif
switch (AccessLength)
{
case AccessLength_QUADWORD:
{
unsigned_16 val = U16_8 (MemElem1, MemElem);
sim_core_write_aligned_16 (CPU, cia, write_map, pAddr, val);
break;
}
case AccessLength_DOUBLEWORD:
sim_core_write_aligned_8 (CPU, cia, write_map, pAddr, MemElem);
break;
case AccessLength_SEPTIBYTE:
sim_core_write_misaligned_7 (CPU, cia, write_map, pAddr, MemElem);
break;
case AccessLength_SEXTIBYTE:
sim_core_write_misaligned_6 (CPU, cia, write_map, pAddr, MemElem);
break;
case AccessLength_QUINTIBYTE:
sim_core_write_misaligned_5 (CPU, cia, write_map, pAddr, MemElem);
break;
case AccessLength_WORD:
sim_core_write_aligned_4 (CPU, cia, write_map, pAddr, MemElem);
break;
case AccessLength_TRIPLEBYTE:
sim_core_write_misaligned_3 (CPU, cia, write_map, pAddr, MemElem);
break;
case AccessLength_HALFWORD:
sim_core_write_aligned_2 (CPU, cia, write_map, pAddr, MemElem);
break;
case AccessLength_BYTE:
sim_core_write_aligned_1 (CPU, cia, write_map, pAddr, MemElem);
break;
default:
abort ();
}
return;
}
INLINE_SIM_MAIN (unsigned32)
ifetch32 (SIM_DESC SD,
sim_cpu *CPU,
address_word cia,
address_word vaddr)
{
address_word mask = LOADDRMASK;
address_word access = AccessLength_WORD;
address_word reverseendian = (ReverseEndian ? (mask ^ access) : 0);
address_word bigendiancpu = (BigEndianCPU ? (mask ^ access) : 0);
unsigned int byte;
address_word paddr;
int uncached;
unsigned64 memval;
if ((vaddr & access) != 0)
SignalExceptionInstructionFetch ();
AddressTranslation (vaddr, isINSTRUCTION, isLOAD, &paddr, &uncached, isTARGET, isREAL);
paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverseendian));
LoadMemory (&memval, NULL, uncached, access, paddr, vaddr, isINSTRUCTION, isREAL);
byte = ((vaddr & mask) ^ bigendiancpu);
return (memval >> (8 * byte));
}
INLINE_SIM_MAIN (unsigned16)
ifetch16 (SIM_DESC SD,
sim_cpu *CPU,
address_word cia,
address_word vaddr)
{
address_word mask = LOADDRMASK;
address_word access = AccessLength_HALFWORD;
address_word reverseendian = (ReverseEndian ? (mask ^ access) : 0);
address_word bigendiancpu = (BigEndianCPU ? (mask ^ access) : 0);
unsigned int byte;
address_word paddr;
int uncached;
unsigned64 memval;
if ((vaddr & access) != 0)
SignalExceptionInstructionFetch ();
AddressTranslation (vaddr, isINSTRUCTION, isLOAD, &paddr, &uncached, isTARGET, isREAL);
paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverseendian));
LoadMemory (&memval, NULL, uncached, access, paddr, vaddr, isINSTRUCTION, isREAL);
byte = ((vaddr & mask) ^ bigendiancpu);
return (memval >> (8 * byte));
}
INLINE_SIM_MAIN (void)
sync_operation (SIM_DESC sd,
sim_cpu *cpu,
address_word cia,
int stype)
{
#ifdef DEBUG
sim_io_printf(sd,"SyncOperation(%d) : TODO\n",stype);
#endif
return;
}
INLINE_SIM_MAIN (void)
cache_op (SIM_DESC SD,
sim_cpu *CPU,
address_word cia,
int op,
address_word pAddr,
address_word vAddr,
unsigned int instruction)
{
#if 1
static int icache_warning = 1;
static int dcache_warning = 1;
#else
static int icache_warning = 0;
static int dcache_warning = 0;
#endif
#if 0
sim_io_printf(SD,"TODO: Cache availability checking (PC = 0x%s)\n",pr_addr(cia));
#endif
switch (op & 0x3) {
case 0:
switch (op >> 2) {
case 0:
case 1:
case 2:
case 4:
case 5:
case 6:
if (!icache_warning)
{
sim_io_eprintf(SD,"Instruction CACHE operation %d to be coded\n",(op >> 2));
icache_warning = 1;
}
break;
default:
SignalException(ReservedInstruction,instruction);
break;
}
break;
case 1:
case 3:
switch (op >> 2) {
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
if (!dcache_warning)
{
sim_io_eprintf(SD,"Data CACHE operation %d to be coded\n",(op >> 2));
dcache_warning = 1;
}
break;
default:
SignalException(ReservedInstruction,instruction);
break;
}
break;
default:
SignalException(ReservedInstruction,instruction);
break;
}
return;
}
INLINE_SIM_MAIN (void)
pending_tick (SIM_DESC SD,
sim_cpu *CPU,
address_word cia)
{
if (PENDING_TRACE)
sim_io_eprintf (SD, "PENDING_DRAIN - 0x%lx - pending_in = %d, pending_out = %d, pending_total = %d\n", (unsigned long) cia, PENDING_IN, PENDING_OUT, PENDING_TOTAL);
if (PENDING_OUT != PENDING_IN)
{
int loop;
int index = PENDING_OUT;
int total = PENDING_TOTAL;
if (PENDING_TOTAL == 0)
sim_engine_abort (SD, CPU, cia, "PENDING_DRAIN - Mis-match on pending update pointers\n");
for (loop = 0, index = PENDING_OUT;
(loop < total);
loop++, index = (index + 1) % PSLOTS)
{
if (PENDING_SLOT_DEST[index] != NULL)
{
PENDING_SLOT_DELAY[index] -= 1;
if (PENDING_SLOT_DELAY[index] == 0)
{
if (PENDING_TRACE)
sim_io_eprintf (SD, "PENDING_DRAIN - drained - index %d, dest 0x%lx, bit %d, val 0x%lx, size %d\n",
index,
(unsigned long) PENDING_SLOT_DEST[index],
PENDING_SLOT_BIT[index],
(unsigned long) PENDING_SLOT_VALUE[index],
PENDING_SLOT_SIZE[index]);
if (PENDING_SLOT_BIT[index] >= 0)
switch (PENDING_SLOT_SIZE[index])
{
case 4:
if (PENDING_SLOT_VALUE[index])
*(unsigned32*)PENDING_SLOT_DEST[index] |=
BIT32 (PENDING_SLOT_BIT[index]);
else
*(unsigned32*)PENDING_SLOT_DEST[index] &=
BIT32 (PENDING_SLOT_BIT[index]);
break;
case 8:
if (PENDING_SLOT_VALUE[index])
*(unsigned64*)PENDING_SLOT_DEST[index] |=
BIT64 (PENDING_SLOT_BIT[index]);
else
*(unsigned64*)PENDING_SLOT_DEST[index] &=
BIT64 (PENDING_SLOT_BIT[index]);
break;
}
else
switch (PENDING_SLOT_SIZE[index])
{
case 4:
*(unsigned32*)PENDING_SLOT_DEST[index] =
PENDING_SLOT_VALUE[index];
break;
case 8:
*(unsigned64*)PENDING_SLOT_DEST[index] =
PENDING_SLOT_VALUE[index];
break;
}
if (PENDING_OUT == index)
{
PENDING_SLOT_DEST[index] = NULL;
PENDING_OUT = (PENDING_OUT + 1) % PSLOTS;
PENDING_TOTAL--;
}
}
else if (PENDING_TRACE && PENDING_SLOT_DELAY[index] > 0)
sim_io_eprintf (SD, "PENDING_DRAIN - queued - index %d, delay %d, dest 0x%lx, bit %d, val 0x%lx, size %d\n",
index, PENDING_SLOT_DELAY[index],
(unsigned long) PENDING_SLOT_DEST[index],
PENDING_SLOT_BIT[index],
(unsigned long) PENDING_SLOT_VALUE[index],
PENDING_SLOT_SIZE[index]);
}
}
}
}
#endif