aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlistair Francis <alistair.francis@xilinx.com>2015-05-29 16:30:05 +1000
committerEdgar E. Iglesias <edgar.iglesias@xilinx.com>2015-06-21 17:20:15 +1000
commit8bac22423e4c3b70082dd6c1b492ccf21f3b5a0c (patch)
treea2dba44421686bba491643d92b8cd5e7bb9a75f0
parent53432dc9ea37d3be4c8efc3023c2382e9da5334a (diff)
target-microblaze: Preserve the pvr registers during reset
Move the Microblaze PVR registers to the end of the CPUMBState and preserve them during reset. This is similar to what the QEMU ARM model does with some of it's registers. This allows the Microblaze PVR registers to only be set once at realise instead of constantly at reset. Signed-off-by: Alistair Francis <alistair.francis@xilinx.com> Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com> Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com> Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
-rw-r--r--target-microblaze/cpu.c40
-rw-r--r--target-microblaze/cpu.h10
2 files changed, 28 insertions, 22 deletions
diff --git a/target-microblaze/cpu.c b/target-microblaze/cpu.c
index 67e3182f70..95be540124 100644
--- a/target-microblaze/cpu.c
+++ b/target-microblaze/cpu.c
@@ -63,13 +63,34 @@ static void mb_cpu_reset(CPUState *s)
mcc->parent_reset(s);
- memset(env, 0, sizeof(CPUMBState));
+ memset(env, 0, offsetof(CPUMBState, pvr));
env->res_addr = RES_ADDR_NONE;
tlb_flush(s, 1);
/* Disable stack protector. */
env->shr = ~0;
+#if defined(CONFIG_USER_ONLY)
+ /* start in user mode with interrupts enabled. */
+ env->sregs[SR_MSR] = MSR_EE | MSR_IE | MSR_VM | MSR_UM;
+#else
+ env->sregs[SR_MSR] = 0;
+ mmu_init(&env->mmu);
+ env->mmu.c_mmu = 3;
+ env->mmu.c_mmu_tlb_access = 3;
+ env->mmu.c_mmu_zones = 16;
+#endif
+}
+
+static void mb_cpu_realizefn(DeviceState *dev, Error **errp)
+{
+ CPUState *cs = CPU(dev);
+ MicroBlazeCPUClass *mcc = MICROBLAZE_CPU_GET_CLASS(dev);
+ MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
+ CPUMBState *env = &cpu->env;
+
+ qemu_init_vcpu(cs);
+
env->pvr.regs[0] = PVR0_PVR_FULL_MASK \
| PVR0_USE_BARREL_MASK \
| PVR0_USE_DIV_MASK \
@@ -99,25 +120,8 @@ static void mb_cpu_reset(CPUState *s)
env->sregs[SR_PC] = cpu->base_vectors;
#if defined(CONFIG_USER_ONLY)
- /* start in user mode with interrupts enabled. */
- env->sregs[SR_MSR] = MSR_EE | MSR_IE | MSR_VM | MSR_UM;
env->pvr.regs[10] = 0x0c000000; /* Spartan 3a dsp. */
-#else
- env->sregs[SR_MSR] = 0;
- mmu_init(&env->mmu);
- env->mmu.c_mmu = 3;
- env->mmu.c_mmu_tlb_access = 3;
- env->mmu.c_mmu_zones = 16;
#endif
-}
-
-static void mb_cpu_realizefn(DeviceState *dev, Error **errp)
-{
- CPUState *cs = CPU(dev);
- MicroBlazeCPUClass *mcc = MICROBLAZE_CPU_GET_CLASS(dev);
-
- cpu_reset(cs);
- qemu_init_vcpu(cs);
mcc->parent_realize(dev, errp);
}
diff --git a/target-microblaze/cpu.h b/target-microblaze/cpu.h
index d73e1c7286..534e1cf6a5 100644
--- a/target-microblaze/cpu.h
+++ b/target-microblaze/cpu.h
@@ -260,16 +260,18 @@ struct CPUMBState {
#define IFLAGS_TB_MASK (D_FLAG | IMM_FLAG | DRTI_FLAG | DRTE_FLAG | DRTB_FLAG)
uint32_t iflags;
- struct {
- uint32_t regs[16];
- } pvr;
-
#if !defined(CONFIG_USER_ONLY)
/* Unified MMU. */
struct microblaze_mmu mmu;
#endif
CPU_COMMON
+
+ /* These fields are preserved on reset. */
+
+ struct {
+ uint32_t regs[16];
+ } pvr;
};
#include "cpu-qom.h"