|
Message
From: =?unknown-8bit?Q?Gy=F6rgy?= 'nog' Jeney<nog@s...>
Date: Thu Mar 24 21:10:35 CET 2005
Subject: [openrisc] [or1ksim #59] Don't call mtspr/mfspr when not needed
Hi,This patch changes some calls to mtspr()/mfspr() to directly accessing cpu_state.sprs[]. This is needed to avoid infinate loops in the recompiler when the immu is reconfigured. When the immu is reconfigured, immu_translate is called to check if the current page in execution is still resident in the immu. If it's not then simulate_itlb calls setsprbits, which calls mtspr but mtspr detects that the immu is reconfigured and calls immu_translate again.
I would go asfar as to argue that mfspr() and mtspr() should only be called from the l.mfspr and l.mtspr instructions. All code that messes with an spr should know exactly what it's doing and not screw up.
ChangeLog: * Replace some problematic calles to mfspr/mtspr with direct access to the spr.
nog. -------------- next part -------------- diff -urp --unidirectional-new-file /home/nog/or1ksim-split/cpu/or1k/sprs.h ./cpu/or1k/sprs.h --- /home/nog/or1ksim-split/cpu/or1k/sprs.h 2005-03-23 18:17:18.000000000 +0100 +++ ./cpu/or1k/sprs.h 2005-03-06 19:40:06.000000000 +0100 @@ -64,8 +64,8 @@ mfspr_(const uint16_t regno) static inline void setsprbits(const int regno, const unsigned long mask, const unsigned long value) { - sprword regvalue = mfspr(regno); - sprword shifted = 0x0; + sprword regvalue = cpu_state.sprs[regno]; + sprword shifted = 0x0; int m, v = 0; /* m counts bits in valuemask */ @@ -77,15 +77,15 @@ setsprbits(const int regno, const unsign } /* PRINTF("oldvalue %x setsprbits(%x, %x, %x) shifted %x", regvalue, regno, mask, value, shifted); */ - mtspr(regno, (regvalue & ~mask) | shifted); + cpu_state.sprs[regno] = (regvalue & ~mask) | shifted; } /* Get specific SPR bit(s) identified by mask. */ static inline unsigned long getsprbits(const int regno, const unsigned long mask) { - sprword regvalue = mfspr(regno); - sprword shifted = 0x0; + sprword regvalue = cpu_state.sprs[regno]; + sprword shifted = 0x0; int m, v = 0; /* m counts bits in valuemask */ @@ -103,12 +103,12 @@ getsprbits(const int regno, const unsign static inline void setsprbit(const int regno, const int bitnum, const unsigned long bitvalue) { - sprword mask; - sprword regvalue = mfspr(regno); + sprword mask; + sprword regvalue = cpu_state.sprs[regno]; mask = ~(1 << bitnum); - mtspr(regno, (regvalue & mask) | ((bitvalue & 0x1) << bitnum)); + cpu_state.sprs[regno] = (regvalue & mask) | ((bitvalue & 0x1) << bitnum); return; } @@ -117,7 +117,7 @@ setsprbit(const int regno, const int bit static inline int getsprbit(const int regno, const int bitnum) { - sprword regvalue = mfspr(regno); + sprword regvalue = cpu_state.sprs[regno]; return (regvalue >> bitnum) & 0x1; } @@ -126,7 +126,7 @@ getsprbit(const int regno, const int bit static inline unsigned long testsprbits(const int regno, const unsigned long mask) { - sprword regvalue = mfspr(regno); + sprword regvalue = cpu_state.sprs[regno]; return regvalue & mask; } --- cpu/or1k/except.c 2005-03-23 18:18:29.000000000 +0100 +++ /home/nog/or1ksim-split/cpu/or1k/except.c 2005-03-23 19:37:49.000000000 +0100 @@ -80,6 +80,18 @@ pcnext = except + (testsprbits (SPR_SR, SPR_SR_EPH) ? 0xf0000000 : 0x00000000); + cpu_state.sprs[SPR_EEAR_BASE] = ea; + cpu_state.sprs[SPR_ESR_BASE] = cpu_state.sprs[SPR_SR]; + + cpu_state.sprs[SPR_SR] &= ~SPR_SR_OVE; /* Disable overflow flag exception. */ + + cpu_state.sprs[SPR_SR] |= SPR_SR_SM; /* SUPV mode */ + cpu_state.sprs[SPR_SR] &= ~(SPR_SR_IEE | SPR_SR_TEE); /* Disable interrupts. */ + + /* Address translation is always disabled when starting exception. */ + cpu_state.sprs[SPR_SR] &= ~SPR_SR_DME; + cpu_state.sprs[SPR_SR] &= ~SPR_SR_IME; +
switch(except) {
/* EPCR is irrelevent */
case EXCEPT_RESET:
@@ -114,17 +126,5 @@
break;
}
- mtspr(SPR_EEAR_BASE, ea);
- mtspr(SPR_ESR_BASE, mfspr(SPR_SR));
-
- /* Address translation is always disabled when starting exception. */
- mtspr(SPR_SR, mfspr(SPR_SR) & ~(SPR_SR_DME));
- mtspr(SPR_SR, mfspr(SPR_SR) & ~(SPR_SR_IME));
-
- mtspr(SPR_SR, mfspr(SPR_SR) & ~SPR_SR_OVE); /* Disable overflow flag exception. */
-
- mtspr(SPR_SR, mfspr(SPR_SR) | SPR_SR_SM); /* SUPV mode */
- mtspr(SPR_SR, mfspr(SPR_SR) & ~(SPR_SR_IEE | SPR_SR_TEE)); /* Disable interrupts. */
-
cpu_state.delay_insn = 0;
}
--- cpu/or32/execute.c 2005-03-23 18:18:29.000000000 +0100
+++ /home/nog/or1ksim-split/cpu/or32/execute.c 2005-03-23 19:37:49.000000000 +0100
@@ -633,10 +633,10 @@
hist_exec_head->prev = hist_exec_tail;
/* Cpu configuration */
- mtspr(SPR_UPR, config.cpu.upr);
+ cpu_state.sprs[SPR_UPR] = config.cpu.upr;
setsprbits(SPR_VR, SPR_VR_VER, config.cpu.ver);
setsprbits(SPR_VR, SPR_VR_REV, config.cpu.rev);
- mtspr(SPR_SR, config.cpu.sr);
+ cpu_state.sprs[SPR_SR] = config.cpu.sr;
pcnext = 0x0; /* MM1409: All programs should start at reset vector entry! */
if (config.sim.verbose) PRINTF ("Starting at 0x%"PRIxADDR"\n", pcnext);
|
 |