aboutsummaryrefslogtreecommitdiff
path: root/target/openrisc/sys_helper.c
diff options
context:
space:
mode:
Diffstat (limited to 'target/openrisc/sys_helper.c')
-rw-r--r--target/openrisc/sys_helper.c62
1 files changed, 31 insertions, 31 deletions
diff --git a/target/openrisc/sys_helper.c b/target/openrisc/sys_helper.c
index daea902..60c3193 100644
--- a/target/openrisc/sys_helper.c
+++ b/target/openrisc/sys_helper.c
@@ -29,11 +29,10 @@ void HELPER(mtspr)(CPUOpenRISCState *env,
target_ulong ra, target_ulong rb, target_ulong offset)
{
#ifndef CONFIG_USER_ONLY
- int spr = (ra | offset);
- int idx;
-
OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
CPUState *cs = CPU(cpu);
+ int spr = (ra | offset);
+ int idx;
switch (spr) {
case TO_SPR(0, 0): /* VR */
@@ -41,7 +40,14 @@ void HELPER(mtspr)(CPUOpenRISCState *env,
break;
case TO_SPR(0, 16): /* NPC */
- env->npc = rb;
+ cpu_restore_state(cs, GETPC());
+ /* ??? Mirror or1ksim in not trashing delayed branch state
+ when "jumping" to the current instruction. */
+ if (env->pc != rb) {
+ env->pc = rb;
+ env->dflag = 0;
+ cpu_loop_exit(cs);
+ }
break;
case TO_SPR(0, 17): /* SR */
@@ -49,8 +55,7 @@ void HELPER(mtspr)(CPUOpenRISCState *env,
(rb & (SR_IME | SR_DME | SR_SM))) {
tlb_flush(cs);
}
- env->sr = rb;
- env->sr |= SR_FO; /* FO is const equal to 1 */
+ cpu_set_sr(env, rb);
if (env->sr & SR_DME) {
env->tlb->cpu_openrisc_map_address_data =
&cpu_openrisc_get_phys_data;
@@ -121,6 +126,12 @@ void HELPER(mtspr)(CPUOpenRISCState *env,
case TO_SPR(2, 1280) ... TO_SPR(2, 1407): /* ITLBW3MR 0-127 */
case TO_SPR(2, 1408) ... TO_SPR(2, 1535): /* ITLBW3TR 0-127 */
break;
+ case TO_SPR(5, 1): /* MACLO */
+ env->mac = deposit64(env->mac, 0, 32, rb);
+ break;
+ case TO_SPR(5, 2): /* MACHI */
+ env->mac = deposit64(env->mac, 32, 32, rb);
+ break;
case TO_SPR(9, 0): /* PICMR */
env->picmr |= rb;
break;
@@ -165,7 +176,6 @@ void HELPER(mtspr)(CPUOpenRISCState *env,
cpu_openrisc_timer_update(cpu);
break;
default:
-
break;
}
#endif
@@ -175,11 +185,11 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env,
target_ulong rd, target_ulong ra, uint32_t offset)
{
#ifndef CONFIG_USER_ONLY
+ OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
+ CPUState *cs = CPU(cpu);
int spr = (ra | offset);
int idx;
- OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
-
switch (spr) {
case TO_SPR(0, 0): /* VR */
return env->vr & SPR_VR;
@@ -196,13 +206,15 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env,
case TO_SPR(0, 4): /* IMMUCFGR */
return env->immucfgr;
- case TO_SPR(0, 16): /* NPC */
- return env->npc;
+ case TO_SPR(0, 16): /* NPC (equals PC) */
+ cpu_restore_state(cs, GETPC());
+ return env->pc;
case TO_SPR(0, 17): /* SR */
- return env->sr;
+ return cpu_get_sr(env);
case TO_SPR(0, 18): /* PPC */
+ cpu_restore_state(cs, GETPC());
return env->ppc;
case TO_SPR(0, 32): /* EPCR */
@@ -246,6 +258,13 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env,
case TO_SPR(2, 1408) ... TO_SPR(2, 1535): /* ITLBW3TR 0-127 */
break;
+ case TO_SPR(5, 1): /* MACLO */
+ return (uint32_t)env->mac;
+ break;
+ case TO_SPR(5, 2): /* MACHI */
+ return env->mac >> 32;
+ break;
+
case TO_SPR(9, 0): /* PICMR */
return env->picmr;
@@ -264,25 +283,6 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env,
}
#endif
-/*If we later need to add tracepoints (or debug printfs) for the return
-value, it may be useful to structure the code like this:
-
-target_ulong ret = 0;
-
-switch() {
-case x:
- ret = y;
- break;
-case z:
- ret = 42;
- break;
-...
-}
-
-later something like trace_spr_read(ret);
-
-return ret;*/
-
/* for rd is passed in, if rd unchanged, just keep it back. */
return rd;
}