aboutsummaryrefslogtreecommitdiff
path: root/target/sparc/machine.c
diff options
context:
space:
mode:
Diffstat (limited to 'target/sparc/machine.c')
-rw-r--r--target/sparc/machine.c106
1 files changed, 88 insertions, 18 deletions
diff --git a/target/sparc/machine.c b/target/sparc/machine.c
index 8ff9dea297..48e0cf22f3 100644
--- a/target/sparc/machine.c
+++ b/target/sparc/machine.c
@@ -1,9 +1,6 @@
#include "qemu/osdep.h"
-#include "qemu-common.h"
#include "cpu.h"
#include "exec/exec-all.h"
-#include "hw/hw.h"
-#include "hw/boards.h"
#include "qemu/timer.h"
#include "migration/cpu.h"
@@ -13,8 +10,7 @@ static const VMStateDescription vmstate_cpu_timer = {
.name = "cpu_timer",
.version_id = 1,
.minimum_version_id = 1,
- .minimum_version_id_old = 1,
- .fields = (VMStateField[]) {
+ .fields = (const VMStateField[]) {
VMSTATE_UINT32(frequency, CPUTimer),
VMSTATE_UINT32(disabled, CPUTimer),
VMSTATE_UINT64(disabled_mask, CPUTimer),
@@ -33,8 +29,7 @@ static const VMStateDescription vmstate_trap_state = {
.name = "trap_state",
.version_id = 1,
.minimum_version_id = 1,
- .minimum_version_id_old = 1,
- .fields = (VMStateField[]) {
+ .fields = (const VMStateField[]) {
VMSTATE_UINT64(tpc, trap_state),
VMSTATE_UINT64(tnpc, trap_state),
VMSTATE_UINT64(tstate, trap_state),
@@ -47,8 +42,7 @@ static const VMStateDescription vmstate_tlb_entry = {
.name = "tlb_entry",
.version_id = 1,
.minimum_version_id = 1,
- .minimum_version_id_old = 1,
- .fields = (VMStateField[]) {
+ .fields = (const VMStateField[]) {
VMSTATE_UINT64(tag, SparcTLBEntry),
VMSTATE_UINT64(tte, SparcTLBEntry),
VMSTATE_END_OF_LIST()
@@ -56,7 +50,8 @@ static const VMStateDescription vmstate_tlb_entry = {
};
#endif
-static int get_psr(QEMUFile *f, void *opaque, size_t size, VMStateField *field)
+static int get_psr(QEMUFile *f, void *opaque, size_t size,
+ const VMStateField *field)
{
SPARCCPU *cpu = opaque;
CPUSPARCState *env = &cpu->env;
@@ -69,8 +64,8 @@ static int get_psr(QEMUFile *f, void *opaque, size_t size, VMStateField *field)
return 0;
}
-static int put_psr(QEMUFile *f, void *opaque, size_t size, VMStateField *field,
- QJSON *vmdesc)
+static int put_psr(QEMUFile *f, void *opaque, size_t size,
+ const VMStateField *field, JSONWriter *vmdesc)
{
SPARCCPU *cpu = opaque;
CPUSPARCState *env = &cpu->env;
@@ -88,6 +83,68 @@ static const VMStateInfo vmstate_psr = {
.put = put_psr,
};
+static int get_fsr(QEMUFile *f, void *opaque, size_t size,
+ const VMStateField *field)
+{
+ SPARCCPU *cpu = opaque;
+ target_ulong val = qemu_get_betl(f);
+
+ cpu_put_fsr(&cpu->env, val);
+ return 0;
+}
+
+static int put_fsr(QEMUFile *f, void *opaque, size_t size,
+ const VMStateField *field, JSONWriter *vmdesc)
+{
+ SPARCCPU *cpu = opaque;
+ target_ulong val = cpu_get_fsr(&cpu->env);
+
+ qemu_put_betl(f, val);
+ return 0;
+}
+
+static const VMStateInfo vmstate_fsr = {
+ .name = "fsr",
+ .get = get_fsr,
+ .put = put_fsr,
+};
+
+#ifdef TARGET_SPARC64
+static int get_xcc(QEMUFile *f, void *opaque, size_t size,
+ const VMStateField *field)
+{
+ SPARCCPU *cpu = opaque;
+ CPUSPARCState *env = &cpu->env;
+ uint32_t val = qemu_get_be32(f);
+
+ /* Do not clobber icc.[NV] */
+ env->cc_N = deposit64(env->cc_N, 32, 32, -(val & PSR_NEG));
+ env->cc_V = deposit64(env->cc_V, 32, 32, -(val & PSR_OVF));
+ env->xcc_Z = ~val & PSR_ZERO;
+ env->xcc_C = (val >> PSR_CARRY_SHIFT) & 1;
+
+ return 0;
+}
+
+static int put_xcc(QEMUFile *f, void *opaque, size_t size,
+ const VMStateField *field, JSONWriter *vmdesc)
+{
+ SPARCCPU *cpu = opaque;
+ CPUSPARCState *env = &cpu->env;
+ uint32_t val = cpu_get_ccr(env);
+
+ /* Extract just xcc out of ccr and shift into legacy position. */
+ qemu_put_be32(f, (val & 0xf0) << (20 - 4));
+ return 0;
+}
+
+static const VMStateInfo vmstate_xcc = {
+ .name = "xcc",
+ .get = get_xcc,
+ .put = put_xcc,
+};
+#endif
+
static int cpu_pre_save(void *opaque)
{
SPARCCPU *cpu = opaque;
@@ -115,9 +172,8 @@ const VMStateDescription vmstate_sparc_cpu = {
.name = "cpu",
.version_id = SPARC_VMSTATE_VER,
.minimum_version_id = SPARC_VMSTATE_VER,
- .minimum_version_id_old = SPARC_VMSTATE_VER,
.pre_save = cpu_pre_save,
- .fields = (VMStateField[]) {
+ .fields = (const VMStateField[]) {
VMSTATE_UINTTL_ARRAY(env.gregs, SPARCCPU, 8),
VMSTATE_UINT32(env.nwindows, SPARCCPU),
VMSTATE_VARRAY_MULTIPLY(env.regbase, SPARCCPU, env.nwindows, 16,
@@ -127,7 +183,6 @@ const VMStateDescription vmstate_sparc_cpu = {
VMSTATE_UINTTL(env.npc, SPARCCPU),
VMSTATE_UINTTL(env.y, SPARCCPU),
{
-
.name = "psr",
.version_id = 0,
.size = sizeof(uint32_t),
@@ -135,7 +190,14 @@ const VMStateDescription vmstate_sparc_cpu = {
.flags = VMS_SINGLE,
.offset = 0,
},
- VMSTATE_UINTTL(env.fsr, SPARCCPU),
+ {
+ .name = "fsr",
+ .version_id = 0,
+ .size = sizeof(target_ulong),
+ .info = &vmstate_fsr,
+ .flags = VMS_SINGLE,
+ .offset = 0,
+ },
VMSTATE_UINTTL(env.tbr, SPARCCPU),
VMSTATE_INT32(env.interrupt_index, SPARCCPU),
VMSTATE_UINT32(env.pil_in, SPARCCPU),
@@ -161,7 +223,14 @@ const VMStateDescription vmstate_sparc_cpu = {
VMSTATE_UINT32(env.mmu_version, SPARCCPU),
VMSTATE_STRUCT_ARRAY(env.ts, SPARCCPU, MAXTL_MAX, 0,
vmstate_trap_state, trap_state),
- VMSTATE_UINT32(env.xcc, SPARCCPU),
+ {
+ .name = "xcc",
+ .version_id = 0,
+ .size = sizeof(uint32_t),
+ .info = &vmstate_xcc,
+ .flags = VMS_SINGLE,
+ .offset = 0,
+ },
VMSTATE_UINT32(env.asi, SPARCCPU),
VMSTATE_UINT32(env.pstate, SPARCCPU),
VMSTATE_UINT32(env.tl, SPARCCPU),
@@ -174,7 +243,8 @@ const VMStateDescription vmstate_sparc_cpu = {
VMSTATE_UINT64_ARRAY(env.bgregs, SPARCCPU, 8),
VMSTATE_UINT64_ARRAY(env.igregs, SPARCCPU, 8),
VMSTATE_UINT64_ARRAY(env.mgregs, SPARCCPU, 8),
- VMSTATE_UINT64(env.fprs, SPARCCPU),
+ VMSTATE_UNUSED(4), /* was unused high half of uint64_t fprs */
+ VMSTATE_UINT32(env.fprs, SPARCCPU),
VMSTATE_UINT64(env.tick_cmpr, SPARCCPU),
VMSTATE_UINT64(env.stick_cmpr, SPARCCPU),
VMSTATE_CPU_TIMER(env.tick, SPARCCPU),