@@ -64,6 +64,8 @@
#define MPC8544_PCI_IO 0xE1000000ULL
#define MPC8544_UTIL_OFFSET 0xe0000ULL
#define MPC8544_SPIN_BASE 0xEF000000ULL
+#define MPC8XXX_GPIO_OFFSET 0x000FF000ULL
+#define MPC8XXX_GPIO_IRQ 43
struct boot_info
{
@@ -170,6 +172,23 @@ static int create_devtree_etsec(SysBusDevice *sbdev, PlatformDevtreeData *data)
return 0;
}
+static void create_dt_mpc8xxx_gpio(void *fdt, const char *soc, const char *mpic)
+{
+ hwaddr mmio0 = MPC8XXX_GPIO_OFFSET;
+ int irq0 = MPC8XXX_GPIO_IRQ;
+ gchar *node = g_strdup_printf("%s/gpio@%"PRIx64, soc, mmio0);
+
+ qemu_fdt_add_subnode(fdt, node);
+ qemu_fdt_setprop_string(fdt, node, "compatible", "fsl,qoriq-gpio");
+ qemu_fdt_setprop_cells(fdt, node, "reg", mmio0, 0x1000);
+ qemu_fdt_setprop_cells(fdt, node, "interrupts", irq0, 0x2);
+ qemu_fdt_setprop_phandle(fdt, node, "interrupt-parent", mpic);
+ qemu_fdt_setprop_cells(fdt, node, "#gpio-cells", 2);
+ qemu_fdt_setprop(fdt, node, "gpio-controller", NULL, 0);
+
+ g_free(node);
+}
+
static int sysbus_device_create_devtree(SysBusDevice *sbdev, void *opaque)
{
PlatformDevtreeData *data = opaque;
@@ -490,6 +509,10 @@ static int ppce500_load_device_tree(MachineState *machine,
qemu_fdt_setprop_cell(fdt, pci, "#address-cells", 3);
qemu_fdt_setprop_string(fdt, "/aliases", "pci0", pci);
+ if (params->has_mpc8xxx_gpio) {
+ create_dt_mpc8xxx_gpio(fdt, soc, mpic);
+ }
+
if (params->has_platform_bus) {
platform_bus_create_devtree(params, fdt, mpic);
}
@@ -912,6 +935,15 @@ void ppce500_init(MachineState *machine, PPCE500Params *params)
sysbus_mmio_get_region(s, 0));
}
+ if (params->has_mpc8xxx_gpio) {
+ dev = qdev_create(NULL, "mpc8xxx_gpio");
+ s = SYS_BUS_DEVICE(dev);
+ qdev_init_nofail(dev);
+ sysbus_connect_irq(s, 0, mpic[MPC8XXX_GPIO_IRQ]);
+ memory_region_add_subregion(ccsr_addr_space, MPC8XXX_GPIO_OFFSET,
+ sysbus_mmio_get_region(s, 0));
+ }
+
/* Load kernel. */
if (machine->kernel_filename) {
kernel_base = cur_base;
@@ -16,6 +16,7 @@ typedef struct PPCE500Params {
hwaddr platform_bus_size;
int platform_bus_first_irq;
int platform_bus_num_irqs;
+ bool has_mpc8xxx_gpio;
} PPCE500Params;
void ppce500_init(MachineState *machine, PPCE500Params *params);
@@ -40,6 +40,7 @@ static void e500plat_init(MachineState *machine)
.platform_bus_size = (128ULL * 1024 * 1024),
.platform_bus_first_irq = 5,
.platform_bus_num_irqs = 10,
+ .has_mpc8xxx_gpio = true,
};
/* Older KVM versions don't support EPR which breaks guests when we announce
With the e500 virt machine, we don't have to adhere to the exact hardware layout of an mpc8544ds board. So there we can just add a qoriq compatible GPIO controller into the system that we can add a power off hook to. Signed-off-by: Alexander Graf <agraf@suse.de> --- hw/ppc/e500.c | 32 ++++++++++++++++++++++++++++++++ hw/ppc/e500.h | 1 + hw/ppc/e500plat.c | 1 + 3 files changed, 34 insertions(+)