@@ -57,6 +57,7 @@
#include "exec/semihost.h"
#include "hw/misc/mips_gcr.h"
#include "hw/intc/mips_gic.h"
+#include "hw/misc/mips_cpc.h"
//#define DEBUG_BOARD_INIT
@@ -97,6 +98,7 @@ typedef struct {
MIPSGCRState gcr;
MIPSGICState gic;
+ MIPSCPCState cpc;
qemu_irq *i8259;
} MaltaState;
@@ -617,6 +619,19 @@ static void gic_init(MaltaState *s, Error **err)
sysbus_mmio_map(gicbusdev, 0, gicbase);
}
+static void cpc_init(MaltaState *s, Error **err)
+{
+ object_initialize(&s->cpc, sizeof(s->cpc), TYPE_MIPS_CPC);
+ qdev_set_parent_bus(DEVICE(&s->cpc), sysbus_get_default());
+
+ object_property_set_bool(OBJECT(&s->cpc), true, "realized", err);
+ if (*err != NULL) {
+ return;
+ }
+
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->cpc), 0, CPC_BASE_ADDR);
+}
+
/* Network support */
static void network_init(PCIBus *pci_bus)
{
@@ -937,6 +952,7 @@ static void malta_mips_config(MIPSCPU *cpu)
static void main_cpu_reset(void *opaque)
{
MIPSCPU *cpu = opaque;
+ CPUState *cs = CPU(cpu);
CPUMIPSState *env = &cpu->env;
cpu_reset(CPU(cpu));
@@ -954,6 +970,15 @@ static void main_cpu_reset(void *opaque)
/* Start running from the bootloader we wrote to end of RAM */
env->active_tc.PC = 0x40000000 + loaderparams.ram_low_size;
}
+
+ /* At reset only VP0 on Core0 will start executing the code, other
+ VPs are halted until VP0 powers them up through Cluster Power
+ Controller. */
+ if ((env->CP0_Config5 & (1 << CP0C5_VP)) &&
+ (env->CP0_Config3 & (1 << CP0C3_CMGCR)) &&
+ (cs->cpu_index != 0)) {
+ cs->halted = 1;
+ }
}
static
@@ -1200,6 +1225,11 @@ void mips_malta_init(MachineState *machine)
error_report("%s", error_get_pretty(err));
exit(1);
}
+ cpc_init(s, &err);
+ if (err != NULL) {
+ error_report("%s", error_get_pretty(err));
+ exit(1);
+ }
}
/*
On Malta, after reset, only VP0 on Core0 starts the execution. Other VPs are halted until VP0 powers them up using Cluster Power Controller. Signed-off-by: Leon Alrae <leon.alrae@imgtec.com> --- hw/mips/mips_malta.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+)