ppc/ppc4xx: Introduce a DCR device model

The Device Control Registers (DCR) of on-SoC devices are accessed by
software through the use of the mtdcr and mfdcr instructions. These
are converted in transactions on a side band bus, the DCR bus, which
connects the on-SoC devices to the CPU.

Ideally, we should model these accesses with a DCR namespace and DCR
memory regions but today the DCR handlers are installed in a DCR table
under the CPU. Instead, introduce a little device model wrapper to hold
a CPU link and handle registration of DCR handlers.

The DCR device inherits from SysBus because most of these devices also
have MMIO regions and/or IRQs. Being a SysBusDevice makes things easier
to install the device model in the overall SoC.

Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
[balaton: Explicit opaque parameter for dcr callbacks]
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
Message-Id: <9b21bdf55e0a728f093bad299e030d98f302ded0.1660746880.git.balaton@eik.bme.hu>
Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com>
This commit is contained in:
Cédric Le Goater 2022-08-17 17:08:18 +02:00 committed by Daniel Henrique Barboza
parent b42ad43756
commit 629cae6170
2 changed files with 58 additions and 0 deletions

View File

@ -664,3 +664,44 @@ void ppc4xx_mal_init(CPUPPCState *env, uint8_t txcnum, uint8_t rxcnum,
mal, &dcr_read_mal, &dcr_write_mal);
}
}
/* PPC4xx_DCR_DEVICE */
void ppc4xx_dcr_register(Ppc4xxDcrDeviceState *dev, int dcrn, void *opaque,
dcr_read_cb dcr_read, dcr_write_cb dcr_write)
{
assert(dev->cpu);
ppc_dcr_register(&dev->cpu->env, dcrn, opaque, dcr_read, dcr_write);
}
bool ppc4xx_dcr_realize(Ppc4xxDcrDeviceState *dev, PowerPCCPU *cpu,
Error **errp)
{
object_property_set_link(OBJECT(dev), "cpu", OBJECT(cpu), &error_abort);
return sysbus_realize(SYS_BUS_DEVICE(dev), errp);
}
static Property ppc4xx_dcr_properties[] = {
DEFINE_PROP_LINK("cpu", Ppc4xxDcrDeviceState, cpu, TYPE_POWERPC_CPU,
PowerPCCPU *),
DEFINE_PROP_END_OF_LIST(),
};
static void ppc4xx_dcr_class_init(ObjectClass *oc, void *data)
{
DeviceClass *dc = DEVICE_CLASS(oc);
device_class_set_props(dc, ppc4xx_dcr_properties);
}
static const TypeInfo ppc4xx_types[] = {
{
.name = TYPE_PPC4xx_DCR_DEVICE,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(Ppc4xxDcrDeviceState),
.class_init = ppc4xx_dcr_class_init,
.abstract = true,
}
};
DEFINE_TYPES(ppc4xx_types)

View File

@ -27,6 +27,7 @@
#include "hw/ppc/ppc.h"
#include "exec/memory.h"
#include "hw/sysbus.h"
void ppc4xx_sdram_banks(MemoryRegion *ram, int nr_banks,
MemoryRegion ram_memories[],
@ -44,4 +45,20 @@ void ppc4xx_mal_init(CPUPPCState *env, uint8_t txcnum, uint8_t rxcnum,
#define TYPE_PPC4xx_PCI_HOST_BRIDGE "ppc4xx-pcihost"
/*
* Generic DCR device
*/
#define TYPE_PPC4xx_DCR_DEVICE "ppc4xx-dcr-device"
OBJECT_DECLARE_SIMPLE_TYPE(Ppc4xxDcrDeviceState, PPC4xx_DCR_DEVICE);
struct Ppc4xxDcrDeviceState {
SysBusDevice parent_obj;
PowerPCCPU *cpu;
};
void ppc4xx_dcr_register(Ppc4xxDcrDeviceState *dev, int dcrn, void *opaque,
dcr_read_cb dcr_read, dcr_write_cb dcr_write);
bool ppc4xx_dcr_realize(Ppc4xxDcrDeviceState *dev, PowerPCCPU *cpu,
Error **errp);
#endif /* PPC4XX_H */