Line 37... |
Line 37... |
#include "spr_defs.h"
|
#include "spr_defs.h"
|
#include "execute.h"
|
#include "execute.h"
|
#include "sprs.h"
|
#include "sprs.h"
|
#include "dcache_model.h"
|
#include "dcache_model.h"
|
#include "icache_model.h"
|
#include "icache_model.h"
|
|
#include "debug.h"
|
|
|
|
DECLARE_DEBUG_CHANNEL(immu);
|
|
|
extern int flag;
|
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
|
void
|
mtspr(uint16_t regno, const sprword value)
|
mtspr(uint16_t regno, const sprword value)
|
{
|
{
|
|
sprword prev_val;
|
|
|
regno %= MAX_SPRS;
|
regno %= MAX_SPRS;
|
|
prev_val = cpu_state.sprs[regno];
|
cpu_state.sprs[regno] = value;
|
cpu_state.sprs[regno] = value;
|
|
|
/* MM: Register hooks. */
|
/* MM: Register hooks. */
|
switch (regno) {
|
switch (regno) {
|
case SPR_TTCR:
|
case SPR_TTCR:
|
Line 105... |
Line 110... |
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;
|
cpu_state.sprs[regno] |= SPR_SR_FO;
|
cpu_state.sprs[regno] |= SPR_SR_FO;
|
|
#if DYNAMIC_EXECUTION
|
|
if((value & SPR_SR_IME) && !(prev_val & SPR_SR_IME)) {
|
|
TRACE_(immu)("IMMU just became enabled (%lli).\n", runtime.sim.cycles);
|
|
recheck_immu(IMMU_GOT_ENABLED);
|
|
} else if(!(value & SPR_SR_IME) && (prev_val & SPR_SR_IME)) {
|
|
TRACE_(immu)("Remove counting of mmu hit delay with cycles (%lli)\n",
|
|
runtime.sim.cycles);
|
|
recheck_immu(IMMU_GOT_DISABLED);
|
|
}
|
|
#endif
|
break;
|
break;
|
case SPR_NPC:
|
case SPR_NPC:
|
{
|
{
|
/* 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
|
Line 160... |
Line 175... |
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))) {
|
|
TRACE_(immu)("Writting to an mmu way (reg: %"PRIx16", value: %"PRIx32")\n",
|
|
regno, value);
|
if((regno & 0xff) < 0x80)
|
if((regno & 0xff) < 0x80)
|
cpu_state.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
|
cpu_state.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));
|
|
|
|
#if DYNAMIC_EXECUTION
|
|
if(cpu_state.sprs[SPR_SR] & SPR_SR_IME) {
|
|
/* The immu got reconfigured. Recheck if the current page in execution
|
|
* is resident in the immu ways. This check would be done during the
|
|
* instruction fetch but since the dynamic execution model does not do
|
|
* instruction fetchs, do it now. */
|
|
recheck_immu(0);
|
|
}
|
|
#endif
|
}
|
}
|
|
|
/* Links to GPRS */
|
/* Links to GPRS */
|
if(regno >= 0x0400 && regno < 0x0420) {
|
if(regno >= 0x0400 && regno < 0x0420) {
|
cpu_state.reg[regno - 0x0400] = value;
|
cpu_state.reg[regno - 0x0400] = value;
|