@@ -63,6 +63,21 @@ struct ppc4xx_bd_info_t {
uint32_t bi_iic_fast[2];
};
+/* On Chip Memory */
+#define TYPE_PPC405_OCM "ppc405-ocm"
+OBJECT_DECLARE_SIMPLE_TYPE(Ppc405OcmState, PPC405_OCM);
+struct Ppc405OcmState {
+ Ppc4xxDcrDeviceState parent_obj;
+
+ MemoryRegion ram;
+ MemoryRegion isarc_ram;
+ MemoryRegion dsarc_ram;
+ uint32_t isarc;
+ uint32_t isacntl;
+ uint32_t dsarc;
+ uint32_t dsacntl;
+};
+
/* General purpose timers */
#define TYPE_PPC405_GPT "ppc405-gpt"
OBJECT_DECLARE_SIMPLE_TYPE(Ppc405GptState, PPC405_GPT);
@@ -136,6 +151,7 @@ struct Ppc405SoCState {
DeviceState *uic;
Ppc405CpcState cpc;
Ppc405GptState gpt;
+ Ppc405OcmState ocm;
};
/* PowerPC 405 core */
@@ -773,20 +773,9 @@ enum {
OCM0_DSACNTL = 0x01B,
};
-typedef struct ppc405_ocm_t ppc405_ocm_t;
-struct ppc405_ocm_t {
- MemoryRegion ram;
- MemoryRegion isarc_ram;
- MemoryRegion dsarc_ram;
- uint32_t isarc;
- uint32_t isacntl;
- uint32_t dsarc;
- uint32_t dsacntl;
-};
-
-static void ocm_update_mappings (ppc405_ocm_t *ocm,
- uint32_t isarc, uint32_t isacntl,
- uint32_t dsarc, uint32_t dsacntl)
+static void ocm_update_mappings(Ppc405OcmState *ocm,
+ uint32_t isarc, uint32_t isacntl,
+ uint32_t dsarc, uint32_t dsacntl)
{
trace_ocm_update_mappings(isarc, isacntl, dsarc, dsacntl, ocm->isarc,
ocm->isacntl, ocm->dsarc, ocm->dsacntl);
@@ -830,10 +819,9 @@ static void ocm_update_mappings (ppc405_ocm_t *ocm,
static uint32_t dcr_read_ocm (void *opaque, int dcrn)
{
- ppc405_ocm_t *ocm;
+ Ppc405OcmState *ocm = PPC405_OCM(opaque);
uint32_t ret;
- ocm = opaque;
switch (dcrn) {
case OCM0_ISARC:
ret = ocm->isarc;
@@ -857,10 +845,9 @@ static uint32_t dcr_read_ocm (void *opaque, int dcrn)
static void dcr_write_ocm (void *opaque, int dcrn, uint32_t val)
{
- ppc405_ocm_t *ocm;
+ Ppc405OcmState *ocm = PPC405_OCM(opaque);
uint32_t isarc, dsarc, isacntl, dsacntl;
- ocm = opaque;
isarc = ocm->isarc;
dsarc = ocm->dsarc;
isacntl = ocm->isacntl;
@@ -886,12 +873,11 @@ static void dcr_write_ocm (void *opaque, int dcrn, uint32_t val)
ocm->dsacntl = dsacntl;
}
-static void ocm_reset (void *opaque)
+static void ppc405_ocm_reset(DeviceState *dev)
{
- ppc405_ocm_t *ocm;
+ Ppc405OcmState *ocm = PPC405_OCM(dev);
uint32_t isarc, dsarc, isacntl, dsacntl;
- ocm = opaque;
isarc = 0x00000000;
isacntl = 0x00000000;
dsarc = 0x00000000;
@@ -903,25 +889,31 @@ static void ocm_reset (void *opaque)
ocm->dsacntl = dsacntl;
}
-static void ppc405_ocm_init(CPUPPCState *env)
+static void ppc405_ocm_realize(DeviceState *dev, Error **errp)
{
- ppc405_ocm_t *ocm;
+ Ppc405OcmState *ocm = PPC405_OCM(dev);
+ Ppc4xxDcrDeviceState *dcr = PPC4xx_DCR_DEVICE(dev);
- ocm = g_new0(ppc405_ocm_t, 1);
/* XXX: Size is 4096 or 0x04000000 */
- memory_region_init_ram(&ocm->isarc_ram, NULL, "ppc405.ocm", 4 * KiB,
+ memory_region_init_ram(&ocm->isarc_ram, OBJECT(ocm), "ppc405.ocm", 4 * KiB,
&error_fatal);
- memory_region_init_alias(&ocm->dsarc_ram, NULL, "ppc405.dsarc",
+ memory_region_init_alias(&ocm->dsarc_ram, OBJECT(ocm), "ppc405.dsarc",
&ocm->isarc_ram, 0, 4 * KiB);
- qemu_register_reset(&ocm_reset, ocm);
- ppc_dcr_register(env, OCM0_ISARC,
- ocm, &dcr_read_ocm, &dcr_write_ocm);
- ppc_dcr_register(env, OCM0_ISACNTL,
- ocm, &dcr_read_ocm, &dcr_write_ocm);
- ppc_dcr_register(env, OCM0_DSARC,
- ocm, &dcr_read_ocm, &dcr_write_ocm);
- ppc_dcr_register(env, OCM0_DSACNTL,
- ocm, &dcr_read_ocm, &dcr_write_ocm);
+
+ ppc4xx_dcr_register(dcr, OCM0_ISARC, &dcr_read_ocm, &dcr_write_ocm);
+ ppc4xx_dcr_register(dcr, OCM0_ISACNTL, &dcr_read_ocm, &dcr_write_ocm);
+ ppc4xx_dcr_register(dcr, OCM0_DSARC, &dcr_read_ocm, &dcr_write_ocm);
+ ppc4xx_dcr_register(dcr, OCM0_DSACNTL, &dcr_read_ocm, &dcr_write_ocm);
+}
+
+static void ppc405_ocm_class_init(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+
+ dc->realize = ppc405_ocm_realize;
+ /* Reason: only works as function of a ppc4xx SoC */
+ dc->user_creatable = false;
+ dc->reset = ppc405_ocm_reset;
}
/*****************************************************************************/
@@ -1414,6 +1406,8 @@ static void ppc405_soc_instance_init(Object *obj)
object_property_add_alias(obj, "sys-clk", OBJECT(&s->cpc), "sys-clk");
object_initialize_child(obj, "gpt", &s->gpt, TYPE_PPC405_GPT);
+
+ object_initialize_child(obj, "ocm", &s->ocm, TYPE_PPC405_OCM);
}
static void ppc405_reset(void *opaque)
@@ -1509,7 +1503,9 @@ static void ppc405_soc_realize(DeviceState *dev, Error **errp)
}
/* OCM */
- ppc405_ocm_init(env);
+ if (!ppc4xx_dcr_realize(PPC4xx_DCR_DEVICE(&s->ocm), &s->cpu, errp)) {
+ return;
+ }
/* GPT */
if (!sysbus_realize(SYS_BUS_DEVICE(&s->gpt), errp)) {
@@ -1553,6 +1549,11 @@ static void ppc405_soc_class_init(ObjectClass *oc, void *data)
static const TypeInfo ppc405_types[] = {
{
+ .name = TYPE_PPC405_OCM,
+ .parent = TYPE_PPC4xx_DCR_DEVICE,
+ .instance_size = sizeof(Ppc405OcmState),
+ .class_init = ppc405_ocm_class_init,
+ }, {
.name = TYPE_PPC405_GPT,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(Ppc405GptState),