Line 29... |
Line 29... |
#endif
|
#endif
|
|
|
#include "port.h"
|
#include "port.h"
|
#include "arch.h"
|
#include "arch.h"
|
#include "abstract.h"
|
#include "abstract.h"
|
#include "sprs.h"
|
|
#include "sim-config.h"
|
#include "sim-config.h"
|
#include "except.h"
|
#include "except.h"
|
|
#include "opcode/or32.h"
|
|
#include "spr_defs.h"
|
#include "execute.h"
|
#include "execute.h"
|
|
#include "sprs.h"
|
#include "dcache_model.h"
|
#include "dcache_model.h"
|
#include "icache_model.h"
|
#include "icache_model.h"
|
|
|
extern int flag;
|
|
|
|
sprword sprs[MAX_SPRS];
|
extern int flag;
|
|
|
int audio_cnt = 0;
|
int audio_cnt = 0;
|
|
|
static FILE *fo = 0;
|
static FILE *fo = 0;
|
/* Set a specific SPR with a value. */
|
/* Set a specific SPR with a value. */
|
inline void
|
inline void
|
mtspr(uint16_t regno, const sprword value)
|
mtspr(uint16_t regno, const sprword value)
|
{
|
{
|
regno %= MAX_SPRS;
|
regno %= MAX_SPRS;
|
sprs[regno] = value;
|
cpu_state.sprs[regno] = value;
|
|
|
/* MM: Register hooks. */
|
/* MM: Register hooks. */
|
switch (regno) {
|
switch (regno) {
|
case SPR_TTCR:
|
case SPR_TTCR:
|
spr_write_ttcr (value);
|
spr_write_ttcr (value);
|
Line 62... |
Line 63... |
break;
|
break;
|
/* Data cache simulateing stuff */
|
/* Data cache simulateing stuff */
|
case SPR_DCBPR:
|
case SPR_DCBPR:
|
if(value) {
|
if(value) {
|
dc_simulate_read(value, 4);
|
dc_simulate_read(value, 4);
|
sprs[SPR_DCBPR] = 0;
|
cpu_state.sprs[SPR_DCBPR] = 0;
|
}
|
}
|
break;
|
break;
|
case SPR_DCBFR:
|
case SPR_DCBFR:
|
if(value != -1) {
|
if(value != -1) {
|
dc_inv(value);
|
dc_inv(value);
|
sprs[SPR_DCBFR] = -1;
|
cpu_state.sprs[SPR_DCBFR] = -1;
|
}
|
}
|
break;
|
break;
|
case SPR_DCBIR:
|
case SPR_DCBIR:
|
if(value != 0) {
|
if(value != 0) {
|
dc_inv(value);
|
dc_inv(value);
|
sprs[SPR_DCBIR] = 0;
|
cpu_state.sprs[SPR_DCBIR] = 0;
|
}
|
}
|
break;
|
break;
|
case SPR_DCBWR:
|
case SPR_DCBWR:
|
sprs[SPR_DCBWR] = 0;
|
cpu_state.sprs[SPR_DCBWR] = 0;
|
break;
|
break;
|
case SPR_DCBLR:
|
case SPR_DCBLR:
|
sprs[SPR_DCBLR] = 0;
|
cpu_state.sprs[SPR_DCBLR] = 0;
|
break;
|
break;
|
/* Instruction cache simulateing stuff */
|
/* Instruction cache simulateing stuff */
|
case SPR_ICBPR:
|
case SPR_ICBPR:
|
if(value) {
|
if(value) {
|
ic_simulate_fetch(value);
|
ic_simulate_fetch(value);
|
sprs[SPR_ICBPR] = 0;
|
cpu_state.sprs[SPR_ICBPR] = 0;
|
}
|
}
|
break;
|
break;
|
case SPR_ICBIR:
|
case SPR_ICBIR:
|
if(value) {
|
if(value) {
|
ic_inv(value);
|
ic_inv(value);
|
sprs[SPR_ICBIR] = 0;
|
cpu_state.sprs[SPR_ICBIR] = 0;
|
}
|
}
|
break;
|
break;
|
case SPR_ICBLR:
|
case SPR_ICBLR:
|
sprs[SPR_ICBLR] = 0;
|
cpu_state.sprs[SPR_ICBLR] = 0;
|
break;
|
break;
|
case SPR_SR:
|
case SPR_SR:
|
/* Set internal flag also */
|
/* Set internal flag also */
|
if(value & SPR_SR_F) flag = 1;
|
if(value & SPR_SR_F) flag = 1;
|
else flag = 0;
|
else flag = 0;
|
sprs[regno] |= SPR_SR_FO;
|
cpu_state.sprs[regno] |= SPR_SR_FO;
|
break;
|
break;
|
case SPR_NPC:
|
case SPR_NPC:
|
{
|
{
|
extern int delay_insn;
|
|
|
|
/* The debugger has redirected us to a new address */
|
/* The debugger has redirected us to a new address */
|
/* This is usually done to reissue an instruction
|
/* This is usually done to reissue an instruction
|
which just caused a breakpoint exception. */
|
which just caused a breakpoint exception. */
|
pc = value;
|
cpu_state.pc = value;
|
|
|
if(!value && config.sim.verbose)
|
if(!value && config.sim.verbose)
|
PRINTF("WARNING: PC just set to 0!\n");
|
PRINTF("WARNING: PC just set to 0!\n");
|
|
|
/* Clear any pending delay slot jumps also */
|
/* Clear any pending delay slot jumps also */
|
delay_insn = 0;
|
cpu_state.delay_insn = 0;
|
pcnext = value + 4;
|
pcnext = value + 4;
|
}
|
}
|
break;
|
break;
|
case 0xFFFD:
|
case 0xFFFD:
|
fo = fopen ("audiosim.pcm", "wb+");
|
fo = fopen ("audiosim.pcm", "wb+");
|
Line 150... |
Line 149... |
break;
|
break;
|
default:
|
default:
|
/* Mask reseved bits in DTLBMR and DTLBMR registers */
|
/* Mask reseved bits in DTLBMR and DTLBMR registers */
|
if ( (regno >= SPR_DTLBMR_BASE(0)) && (regno < SPR_DTLBTR_LAST(3))) {
|
if ( (regno >= SPR_DTLBMR_BASE(0)) && (regno < SPR_DTLBTR_LAST(3))) {
|
if((regno & 0xff) < 0x80)
|
if((regno & 0xff) < 0x80)
|
sprs[regno] = ((value / config.dmmu.pagesize) * config.dmmu.pagesize) |
|
cpu_state.sprs[regno] = ((value / config.dmmu.pagesize) * config.dmmu.pagesize) |
|
(value & (SPR_DTLBMR_V | SPR_DTLBMR_PL1 | SPR_DTLBMR_CID | SPR_DTLBMR_LRU));
|
(value & (SPR_DTLBMR_V | SPR_DTLBMR_PL1 | SPR_DTLBMR_CID | SPR_DTLBMR_LRU));
|
else
|
else
|
sprs[regno] = ((value / config.dmmu.pagesize) * config.dmmu.pagesize) |
|
cpu_state.sprs[regno] = ((value / config.dmmu.pagesize) * config.dmmu.pagesize) |
|
(value & (SPR_DTLBTR_CC | SPR_DTLBTR_CI | SPR_DTLBTR_WBC | SPR_DTLBTR_WOM |
|
(value & (SPR_DTLBTR_CC | SPR_DTLBTR_CI | SPR_DTLBTR_WBC | SPR_DTLBTR_WOM |
|
SPR_DTLBTR_A | SPR_DTLBTR_D | SPR_DTLBTR_URE | SPR_DTLBTR_UWE | SPR_DTLBTR_SRE |
|
SPR_DTLBTR_A | SPR_DTLBTR_D | SPR_DTLBTR_URE | SPR_DTLBTR_UWE | SPR_DTLBTR_SRE |
|
SPR_DTLBTR_SWE));
|
SPR_DTLBTR_SWE));
|
}
|
}
|
|
|
/* Mask reseved bits in ITLBMR and ITLBMR registers */
|
/* Mask reseved bits in ITLBMR and ITLBMR registers */
|
if ( (regno >= SPR_ITLBMR_BASE(0)) && (regno < SPR_ITLBTR_LAST(3))) {
|
if ( (regno >= SPR_ITLBMR_BASE(0)) && (regno < SPR_ITLBTR_LAST(3))) {
|
if((regno & 0xff) < 0x80)
|
if((regno & 0xff) < 0x80)
|
sprs[regno] = ((value / config.immu.pagesize) * config.immu.pagesize) |
|
cpu_state.sprs[regno] = ((value / config.immu.pagesize) * config.immu.pagesize) |
|
(value & (SPR_ITLBMR_V | SPR_ITLBMR_PL1 | SPR_ITLBMR_CID | SPR_ITLBMR_LRU));
|
(value & (SPR_ITLBMR_V | SPR_ITLBMR_PL1 | SPR_ITLBMR_CID | SPR_ITLBMR_LRU));
|
else
|
else
|
sprs[regno] = ((value / config.immu.pagesize) * config.immu.pagesize) |
|
cpu_state.sprs[regno] = ((value / config.immu.pagesize) * config.immu.pagesize) |
|
(value & (SPR_ITLBTR_CC | SPR_ITLBTR_CI | SPR_ITLBTR_WBC | SPR_ITLBTR_WOM |
|
(value & (SPR_ITLBTR_CC | SPR_ITLBTR_CI | SPR_ITLBTR_WBC | SPR_ITLBTR_WOM |
|
SPR_ITLBTR_A | SPR_ITLBTR_D | SPR_ITLBTR_SXE | SPR_ITLBTR_UXE));
|
SPR_ITLBTR_A | SPR_ITLBTR_D | SPR_ITLBTR_SXE | SPR_ITLBTR_UXE));
|
}
|
}
|
|
|
/* Links to GPRS */
|
/* Links to GPRS */
|
if(regno >= 0x0400 && regno < 0x0420) {
|
if(regno >= 0x0400 && regno < 0x0420) {
|
extern uorreg_t reg[32];
|
cpu_state.reg[regno - 0x0400] = value;
|
reg[regno - 0x0400] = value;
|
|
}
|
}
|
break;
|
break;
|
}
|
}
|
}
|
}
|
|
|