*/
#include "qemu/osdep.h"
-#include "qapi/error.h"
#include "qemu/log.h"
-#include "hw/hw.h"
+#include "qemu/module.h"
#include "hw/sysbus.h"
-#include "sysemu/sysemu.h"
+#include "migration/vmstate.h"
#include "hw/misc/mips_cmgcr.h"
#include "hw/misc/mips_cpc.h"
+#include "hw/qdev-properties.h"
#include "hw/intc/mips_gic.h"
static inline bool is_cpc_connected(MIPSGCRState *s)
return s->gic_mr != NULL;
}
+static inline void update_gcr_base(MIPSGCRState *gcr, uint64_t val)
+{
+ CPUState *cpu;
+ MIPSCPU *mips_cpu;
+
+ gcr->gcr_base = val & GCR_BASE_GCRBASE_MSK;
+ memory_region_set_address(&gcr->iomem, gcr->gcr_base);
+
+ CPU_FOREACH(cpu) {
+ mips_cpu = MIPS_CPU(cpu);
+ mips_cpu->env.CP0_CMGCRBase = gcr->gcr_base >> 4;
+ }
+}
+
static inline void update_cpc_base(MIPSGCRState *gcr, uint64_t val)
{
if (is_cpc_connected(gcr)) {
MIPSGCRVPState *other_vps = &gcr->vps[current_vps->other];
switch (addr) {
+ case GCR_BASE_OFS:
+ update_gcr_base(gcr, data);
+ break;
case GCR_GIC_BASE_OFS:
update_gic_base(gcr, data);
break;
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
MIPSGCRState *s = MIPS_GCR(obj);
- object_property_add_link(obj, "gic", TYPE_MEMORY_REGION,
- (Object **)&s->gic_mr,
- qdev_prop_allow_set_link_before_realize,
- OBJ_PROP_LINK_UNREF_ON_RELEASE,
- &error_abort);
-
- object_property_add_link(obj, "cpc", TYPE_MEMORY_REGION,
- (Object **)&s->cpc_mr,
- qdev_prop_allow_set_link_before_realize,
- OBJ_PROP_LINK_UNREF_ON_RELEASE,
- &error_abort);
-
memory_region_init_io(&s->iomem, OBJECT(s), &gcr_ops, s,
"mips-gcr", GCR_ADDRSPACE_SZ);
sysbus_init_mmio(sbd, &s->iomem);
DEFINE_PROP_INT32("num-vp", MIPSGCRState, num_vps, 1),
DEFINE_PROP_INT32("gcr-rev", MIPSGCRState, gcr_rev, 0x800),
DEFINE_PROP_UINT64("gcr-base", MIPSGCRState, gcr_base, GCR_BASE_ADDR),
+ DEFINE_PROP_LINK("gic", MIPSGCRState, gic_mr, TYPE_MEMORY_REGION,
+ MemoryRegion *),
+ DEFINE_PROP_LINK("cpc", MIPSGCRState, cpc_mr, TYPE_MEMORY_REGION,
+ MemoryRegion *),
DEFINE_PROP_END_OF_LIST(),
};