mirror of https://github.com/xqemu/xqemu.git
hw/mips/cps: create GIC block inside CPS
Add GIC to CPS and expose its interrupt pins instead of CPU's. Signed-off-by: Leon Alrae <leon.alrae@imgtec.com>
This commit is contained in:
parent
e8bd336dd1
commit
19494f811a
|
@ -26,13 +26,8 @@
|
||||||
|
|
||||||
qemu_irq get_cps_irq(MIPSCPSState *s, int pin_number)
|
qemu_irq get_cps_irq(MIPSCPSState *s, int pin_number)
|
||||||
{
|
{
|
||||||
MIPSCPU *cpu = MIPS_CPU(first_cpu);
|
|
||||||
CPUMIPSState *env = &cpu->env;
|
|
||||||
|
|
||||||
assert(pin_number < s->num_irq);
|
assert(pin_number < s->num_irq);
|
||||||
|
return s->gic.irq_state[pin_number].irq;
|
||||||
/* TODO: return GIC pins once implemented */
|
|
||||||
return env->irq[pin_number];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mips_cps_init(Object *obj)
|
static void mips_cps_init(Object *obj)
|
||||||
|
@ -130,6 +125,21 @@ static void mips_cps_realize(DeviceState *dev, Error **errp)
|
||||||
memory_region_add_subregion(&s->container, 0,
|
memory_region_add_subregion(&s->container, 0,
|
||||||
sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->cpc), 0));
|
sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->cpc), 0));
|
||||||
|
|
||||||
|
/* Global Interrupt Controller */
|
||||||
|
object_initialize(&s->gic, sizeof(s->gic), TYPE_MIPS_GIC);
|
||||||
|
qdev_set_parent_bus(DEVICE(&s->gic), sysbus_get_default());
|
||||||
|
|
||||||
|
object_property_set_int(OBJECT(&s->gic), s->num_vp, "num-vp", &err);
|
||||||
|
object_property_set_int(OBJECT(&s->gic), 128, "num-irq", &err);
|
||||||
|
object_property_set_bool(OBJECT(&s->gic), true, "realized", &err);
|
||||||
|
if (err != NULL) {
|
||||||
|
error_propagate(errp, err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
memory_region_add_subregion(&s->container, 0,
|
||||||
|
sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->gic), 0));
|
||||||
|
|
||||||
/* Global Configuration Registers */
|
/* Global Configuration Registers */
|
||||||
gcr_base = env->CP0_CMGCRBase << 4;
|
gcr_base = env->CP0_CMGCRBase << 4;
|
||||||
|
|
||||||
|
@ -139,6 +149,7 @@ static void mips_cps_realize(DeviceState *dev, Error **errp)
|
||||||
object_property_set_int(OBJECT(&s->gcr), s->num_vp, "num-vp", &err);
|
object_property_set_int(OBJECT(&s->gcr), s->num_vp, "num-vp", &err);
|
||||||
object_property_set_int(OBJECT(&s->gcr), 0x800, "gcr-rev", &err);
|
object_property_set_int(OBJECT(&s->gcr), 0x800, "gcr-rev", &err);
|
||||||
object_property_set_int(OBJECT(&s->gcr), gcr_base, "gcr-base", &err);
|
object_property_set_int(OBJECT(&s->gcr), gcr_base, "gcr-base", &err);
|
||||||
|
object_property_set_link(OBJECT(&s->gcr), OBJECT(&s->gic.mr), "gic", &err);
|
||||||
object_property_set_link(OBJECT(&s->gcr), OBJECT(&s->cpc.mr), "cpc", &err);
|
object_property_set_link(OBJECT(&s->gcr), OBJECT(&s->cpc.mr), "cpc", &err);
|
||||||
object_property_set_bool(OBJECT(&s->gcr), true, "realized", &err);
|
object_property_set_bool(OBJECT(&s->gcr), true, "realized", &err);
|
||||||
if (err != NULL) {
|
if (err != NULL) {
|
||||||
|
@ -152,7 +163,7 @@ static void mips_cps_realize(DeviceState *dev, Error **errp)
|
||||||
|
|
||||||
static Property mips_cps_properties[] = {
|
static Property mips_cps_properties[] = {
|
||||||
DEFINE_PROP_UINT32("num-vp", MIPSCPSState, num_vp, 1),
|
DEFINE_PROP_UINT32("num-vp", MIPSCPSState, num_vp, 1),
|
||||||
DEFINE_PROP_UINT32("num-irq", MIPSCPSState, num_irq, 8),
|
DEFINE_PROP_UINT32("num-irq", MIPSCPSState, num_irq, 256),
|
||||||
DEFINE_PROP_STRING("cpu-model", MIPSCPSState, cpu_model),
|
DEFINE_PROP_STRING("cpu-model", MIPSCPSState, cpu_model),
|
||||||
DEFINE_PROP_END_OF_LIST()
|
DEFINE_PROP_END_OF_LIST()
|
||||||
};
|
};
|
||||||
|
|
|
@ -955,9 +955,7 @@ static void create_cps(MaltaState *s, const char *cpu_model,
|
||||||
|
|
||||||
sysbus_mmio_map_overlap(SYS_BUS_DEVICE(s->cps), 0, 0, 1);
|
sysbus_mmio_map_overlap(SYS_BUS_DEVICE(s->cps), 0, 0, 1);
|
||||||
|
|
||||||
/* FIXME: When GIC is present then we should use GIC's IRQ 3.
|
*i8259_irq = get_cps_irq(s->cps, 3);
|
||||||
Until then CPS exposes CPU's IRQs thus use the default IRQ 2. */
|
|
||||||
*i8259_irq = get_cps_irq(s->cps, 2);
|
|
||||||
*cbus_irq = NULL;
|
*cbus_irq = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,12 +17,18 @@
|
||||||
#include "sysemu/sysemu.h"
|
#include "sysemu/sysemu.h"
|
||||||
#include "hw/misc/mips_cmgcr.h"
|
#include "hw/misc/mips_cmgcr.h"
|
||||||
#include "hw/misc/mips_cpc.h"
|
#include "hw/misc/mips_cpc.h"
|
||||||
|
#include "hw/intc/mips_gic.h"
|
||||||
|
|
||||||
static inline bool is_cpc_connected(MIPSGCRState *s)
|
static inline bool is_cpc_connected(MIPSGCRState *s)
|
||||||
{
|
{
|
||||||
return s->cpc_mr != NULL;
|
return s->cpc_mr != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool is_gic_connected(MIPSGCRState *s)
|
||||||
|
{
|
||||||
|
return s->gic_mr != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static inline void update_cpc_base(MIPSGCRState *gcr, uint64_t val)
|
static inline void update_cpc_base(MIPSGCRState *gcr, uint64_t val)
|
||||||
{
|
{
|
||||||
if (is_cpc_connected(gcr)) {
|
if (is_cpc_connected(gcr)) {
|
||||||
|
@ -36,6 +42,19 @@ static inline void update_cpc_base(MIPSGCRState *gcr, uint64_t val)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void update_gic_base(MIPSGCRState *gcr, uint64_t val)
|
||||||
|
{
|
||||||
|
if (is_gic_connected(gcr)) {
|
||||||
|
gcr->gic_base = val & GCR_GIC_BASE_MSK;
|
||||||
|
memory_region_transaction_begin();
|
||||||
|
memory_region_set_address(gcr->gic_mr,
|
||||||
|
gcr->gic_base & GCR_GIC_BASE_GICBASE_MSK);
|
||||||
|
memory_region_set_enabled(gcr->gic_mr,
|
||||||
|
gcr->gic_base & GCR_GIC_BASE_GICEN_MSK);
|
||||||
|
memory_region_transaction_commit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Read GCR registers */
|
/* Read GCR registers */
|
||||||
static uint64_t gcr_read(void *opaque, hwaddr addr, unsigned size)
|
static uint64_t gcr_read(void *opaque, hwaddr addr, unsigned size)
|
||||||
{
|
{
|
||||||
|
@ -50,8 +69,12 @@ static uint64_t gcr_read(void *opaque, hwaddr addr, unsigned size)
|
||||||
return gcr->gcr_base;
|
return gcr->gcr_base;
|
||||||
case GCR_REV_OFS:
|
case GCR_REV_OFS:
|
||||||
return gcr->gcr_rev;
|
return gcr->gcr_rev;
|
||||||
|
case GCR_GIC_BASE_OFS:
|
||||||
|
return gcr->gic_base;
|
||||||
case GCR_CPC_BASE_OFS:
|
case GCR_CPC_BASE_OFS:
|
||||||
return gcr->cpc_base;
|
return gcr->cpc_base;
|
||||||
|
case GCR_GIC_STATUS_OFS:
|
||||||
|
return is_gic_connected(gcr);
|
||||||
case GCR_CPC_STATUS_OFS:
|
case GCR_CPC_STATUS_OFS:
|
||||||
return is_cpc_connected(gcr);
|
return is_cpc_connected(gcr);
|
||||||
case GCR_L2_CONFIG_OFS:
|
case GCR_L2_CONFIG_OFS:
|
||||||
|
@ -78,6 +101,9 @@ static void gcr_write(void *opaque, hwaddr addr, uint64_t data, unsigned size)
|
||||||
MIPSGCRState *gcr = (MIPSGCRState *)opaque;
|
MIPSGCRState *gcr = (MIPSGCRState *)opaque;
|
||||||
|
|
||||||
switch (addr) {
|
switch (addr) {
|
||||||
|
case GCR_GIC_BASE_OFS:
|
||||||
|
update_gic_base(gcr, data);
|
||||||
|
break;
|
||||||
case GCR_CPC_BASE_OFS:
|
case GCR_CPC_BASE_OFS:
|
||||||
update_cpc_base(gcr, data);
|
update_cpc_base(gcr, data);
|
||||||
break;
|
break;
|
||||||
|
@ -102,6 +128,12 @@ static void mips_gcr_init(Object *obj)
|
||||||
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
|
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
|
||||||
MIPSGCRState *s = MIPS_GCR(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_property_add_link(obj, "cpc", TYPE_MEMORY_REGION,
|
||||||
(Object **)&s->cpc_mr,
|
(Object **)&s->cpc_mr,
|
||||||
qdev_prop_allow_set_link_before_realize,
|
qdev_prop_allow_set_link_before_realize,
|
||||||
|
@ -117,6 +149,7 @@ static void mips_gcr_reset(DeviceState *dev)
|
||||||
{
|
{
|
||||||
MIPSGCRState *s = MIPS_GCR(dev);
|
MIPSGCRState *s = MIPS_GCR(dev);
|
||||||
|
|
||||||
|
update_gic_base(s, 0);
|
||||||
update_cpc_base(s, 0);
|
update_cpc_base(s, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
|
|
||||||
#include "hw/sysbus.h"
|
#include "hw/sysbus.h"
|
||||||
#include "hw/misc/mips_cmgcr.h"
|
#include "hw/misc/mips_cmgcr.h"
|
||||||
|
#include "hw/intc/mips_gic.h"
|
||||||
#include "hw/misc/mips_cpc.h"
|
#include "hw/misc/mips_cpc.h"
|
||||||
#include "hw/misc/mips_itu.h"
|
#include "hw/misc/mips_itu.h"
|
||||||
|
|
||||||
|
@ -37,6 +38,7 @@ typedef struct MIPSCPSState {
|
||||||
|
|
||||||
MemoryRegion container;
|
MemoryRegion container;
|
||||||
MIPSGCRState gcr;
|
MIPSGCRState gcr;
|
||||||
|
MIPSGICState gic;
|
||||||
MIPSCPCState cpc;
|
MIPSCPCState cpc;
|
||||||
MIPSITUState itu;
|
MIPSITUState itu;
|
||||||
} MIPSCPSState;
|
} MIPSCPSState;
|
||||||
|
|
|
@ -26,7 +26,9 @@
|
||||||
#define GCR_CONFIG_OFS 0x0000
|
#define GCR_CONFIG_OFS 0x0000
|
||||||
#define GCR_BASE_OFS 0x0008
|
#define GCR_BASE_OFS 0x0008
|
||||||
#define GCR_REV_OFS 0x0030
|
#define GCR_REV_OFS 0x0030
|
||||||
|
#define GCR_GIC_BASE_OFS 0x0080
|
||||||
#define GCR_CPC_BASE_OFS 0x0088
|
#define GCR_CPC_BASE_OFS 0x0088
|
||||||
|
#define GCR_GIC_STATUS_OFS 0x00D0
|
||||||
#define GCR_CPC_STATUS_OFS 0x00F0
|
#define GCR_CPC_STATUS_OFS 0x00F0
|
||||||
#define GCR_L2_CONFIG_OFS 0x0130
|
#define GCR_L2_CONFIG_OFS 0x0130
|
||||||
|
|
||||||
|
@ -38,6 +40,11 @@
|
||||||
#define GCR_L2_CONFIG_BYPASS_SHF 20
|
#define GCR_L2_CONFIG_BYPASS_SHF 20
|
||||||
#define GCR_L2_CONFIG_BYPASS_MSK ((0x1ULL) << GCR_L2_CONFIG_BYPASS_SHF)
|
#define GCR_L2_CONFIG_BYPASS_MSK ((0x1ULL) << GCR_L2_CONFIG_BYPASS_SHF)
|
||||||
|
|
||||||
|
/* GCR_GIC_BASE register fields */
|
||||||
|
#define GCR_GIC_BASE_GICEN_MSK 1
|
||||||
|
#define GCR_GIC_BASE_GICBASE_MSK 0xFFFFFFFE0000ULL
|
||||||
|
#define GCR_GIC_BASE_MSK (GCR_GIC_BASE_GICEN_MSK | GCR_GIC_BASE_GICBASE_MSK)
|
||||||
|
|
||||||
/* GCR_CPC_BASE register fields */
|
/* GCR_CPC_BASE register fields */
|
||||||
#define GCR_CPC_BASE_CPCEN_MSK 1
|
#define GCR_CPC_BASE_CPCEN_MSK 1
|
||||||
#define GCR_CPC_BASE_CPCBASE_MSK 0xFFFFFFFF8000ULL
|
#define GCR_CPC_BASE_CPCBASE_MSK 0xFFFFFFFF8000ULL
|
||||||
|
@ -52,8 +59,10 @@ struct MIPSGCRState {
|
||||||
hwaddr gcr_base;
|
hwaddr gcr_base;
|
||||||
MemoryRegion iomem;
|
MemoryRegion iomem;
|
||||||
MemoryRegion *cpc_mr;
|
MemoryRegion *cpc_mr;
|
||||||
|
MemoryRegion *gic_mr;
|
||||||
|
|
||||||
uint64_t cpc_base;
|
uint64_t cpc_base;
|
||||||
|
uint64_t gic_base;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* _MIPS_GCR_H */
|
#endif /* _MIPS_GCR_H */
|
||||||
|
|
Loading…
Reference in New Issue