14d5c29caSScott Wood /*
24d5c29caSScott Wood * Generic device-tree-driven paravirt PPC e500 platform
34d5c29caSScott Wood *
44d5c29caSScott Wood * Copyright 2012 Freescale Semiconductor, Inc.
54d5c29caSScott Wood *
64d5c29caSScott Wood * This is free software; you can redistribute it and/or modify
74d5c29caSScott Wood * it under the terms of the GNU General Public License as published by
84d5c29caSScott Wood * the Free Software Foundation; either version 2 of the License, or
94d5c29caSScott Wood * (at your option) any later version.
104d5c29caSScott Wood */
114d5c29caSScott Wood
120d75590dSPeter Maydell #include "qemu/osdep.h"
13ab3dd749SPhilippe Mathieu-Daudé #include "qemu/units.h"
144d5c29caSScott Wood #include "e500.h"
1550d01d24SEduardo Habkost #include "hw/net/fsl_etsec/etsec.h"
169c17d615SPaolo Bonzini #include "sysemu/device_tree.h"
1777ac58ddSPaolo Bonzini #include "sysemu/kvm.h"
180bd1909dSEduardo Habkost #include "hw/sysbus.h"
199c17d615SPaolo Bonzini #include "hw/pci/pci.h"
200d09e41aSPaolo Bonzini #include "hw/ppc/openpic.h"
213b961124SStuart Yoder #include "kvm_ppc.h"
224d5c29caSScott Wood
e500plat_fixup_devtree(void * fdt)2303f04809SIgor Mammedov static void e500plat_fixup_devtree(void *fdt)
244d5c29caSScott Wood {
254d5c29caSScott Wood const char model[] = "QEMU ppce500";
264d5c29caSScott Wood const char compatible[] = "fsl,qemu-e500";
274d5c29caSScott Wood
285a4348d1SPeter Crosthwaite qemu_fdt_setprop(fdt, "/", "model", model, sizeof(model));
295a4348d1SPeter Crosthwaite qemu_fdt_setprop(fdt, "/", "compatible", compatible,
304d5c29caSScott Wood sizeof(compatible));
314d5c29caSScott Wood }
324d5c29caSScott Wood
e500plat_init(MachineState * machine)333ef96221SMarcel Apfelbaum static void e500plat_init(MachineState *machine)
344d5c29caSScott Wood {
3503f04809SIgor Mammedov PPCE500MachineClass *pmc = PPCE500_MACHINE_GET_CLASS(machine);
363b961124SStuart Yoder /* Older KVM versions don't support EPR which breaks guests when we announce
373b961124SStuart Yoder MPIC variants that support EPR. Revert to an older one for those */
383b961124SStuart Yoder if (kvm_enabled() && !kvmppc_has_cap_epr()) {
3903f04809SIgor Mammedov pmc->mpic_version = OPENPIC_MODEL_FSL_MPIC_20;
403b961124SStuart Yoder }
413b961124SStuart Yoder
4203f04809SIgor Mammedov ppce500_init(machine);
434d5c29caSScott Wood }
444d5c29caSScott Wood
e500plat_machine_device_plug_cb(HotplugHandler * hotplug_dev,DeviceState * dev,Error ** errp)45a3fc8396SIgor Mammedov static void e500plat_machine_device_plug_cb(HotplugHandler *hotplug_dev,
46a3fc8396SIgor Mammedov DeviceState *dev, Error **errp)
47a3fc8396SIgor Mammedov {
48a3fc8396SIgor Mammedov PPCE500MachineState *pms = PPCE500_MACHINE(hotplug_dev);
49e7e0d52dSPeter Maydell MachineClass *mc = MACHINE_GET_CLASS(pms);
50e7e0d52dSPeter Maydell
51e7e0d52dSPeter Maydell if (device_is_dynamic_sysbus(mc, dev)) {
52a3fc8396SIgor Mammedov platform_bus_link_device(pms->pbus_dev, SYS_BUS_DEVICE(dev));
53a3fc8396SIgor Mammedov }
54a3fc8396SIgor Mammedov }
55a3fc8396SIgor Mammedov
56a3fc8396SIgor Mammedov static
e500plat_machine_get_hotpug_handler(MachineState * machine,DeviceState * dev)57a3fc8396SIgor Mammedov HotplugHandler *e500plat_machine_get_hotpug_handler(MachineState *machine,
58a3fc8396SIgor Mammedov DeviceState *dev)
59a3fc8396SIgor Mammedov {
60e7e0d52dSPeter Maydell MachineClass *mc = MACHINE_GET_CLASS(machine);
61e7e0d52dSPeter Maydell
62e7e0d52dSPeter Maydell if (device_is_dynamic_sysbus(mc, dev)) {
63a3fc8396SIgor Mammedov return HOTPLUG_HANDLER(machine);
64a3fc8396SIgor Mammedov }
65a3fc8396SIgor Mammedov
66a3fc8396SIgor Mammedov return NULL;
67a3fc8396SIgor Mammedov }
68a3fc8396SIgor Mammedov
6903f04809SIgor Mammedov #define TYPE_E500PLAT_MACHINE MACHINE_TYPE_NAME("ppce500")
7003f04809SIgor Mammedov
e500plat_machine_class_init(ObjectClass * oc,void * data)7103f04809SIgor Mammedov static void e500plat_machine_class_init(ObjectClass *oc, void *data)
724d5c29caSScott Wood {
7303f04809SIgor Mammedov PPCE500MachineClass *pmc = PPCE500_MACHINE_CLASS(oc);
74a3fc8396SIgor Mammedov HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc);
7503f04809SIgor Mammedov MachineClass *mc = MACHINE_CLASS(oc);
7603f04809SIgor Mammedov
77debbdc00SIgor Mammedov assert(!mc->get_hotplug_handler);
78a3fc8396SIgor Mammedov mc->get_hotplug_handler = e500plat_machine_get_hotpug_handler;
79a3fc8396SIgor Mammedov hc->plug = e500plat_machine_device_plug_cb;
80a3fc8396SIgor Mammedov
8103f04809SIgor Mammedov pmc->pci_first_slot = 0x1;
8203f04809SIgor Mammedov pmc->pci_nr_slots = PCI_SLOT_MAX - 1;
8303f04809SIgor Mammedov pmc->fixup_devtree = e500plat_fixup_devtree;
8403f04809SIgor Mammedov pmc->mpic_version = OPENPIC_MODEL_FSL_MPIC_42;
8503f04809SIgor Mammedov pmc->has_mpc8xxx_gpio = true;
863f288c4bSPhilippe Mathieu-Daudé pmc->has_esdhc = true;
8703f04809SIgor Mammedov pmc->platform_bus_base = 0xf00000000ULL;
88ab3dd749SPhilippe Mathieu-Daudé pmc->platform_bus_size = 128 * MiB;
8903f04809SIgor Mammedov pmc->platform_bus_first_irq = 5;
9003f04809SIgor Mammedov pmc->platform_bus_num_irqs = 10;
9103f04809SIgor Mammedov pmc->ccsrbar_base = 0xFE0000000ULL;
9203f04809SIgor Mammedov pmc->pci_pio_base = 0xFE1000000ULL;
9303f04809SIgor Mammedov pmc->pci_mmio_base = 0xC00000000ULL;
9403f04809SIgor Mammedov pmc->pci_mmio_bus_base = 0xE0000000ULL;
9503f04809SIgor Mammedov pmc->spin_base = 0xFEF000000ULL;
9603f04809SIgor Mammedov
97e264d29dSEduardo Habkost mc->desc = "generic paravirt e500 platform";
98e264d29dSEduardo Habkost mc->init = e500plat_init;
99e264d29dSEduardo Habkost mc->max_cpus = 32;
10059e816fdSIgor Mammedov mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("e500v2_v30");
10197316645SIgor Mammedov mc->default_ram_id = "mpc8544ds.ram";
102*053b7086SThomas Huth mc->default_nic = "virtio-net-pci";
10303f04809SIgor Mammedov machine_class_allow_dynamic_sysbus_dev(mc, TYPE_ETSEC_COMMON);
1044d5c29caSScott Wood }
1054d5c29caSScott Wood
10603f04809SIgor Mammedov static const TypeInfo e500plat_info = {
10703f04809SIgor Mammedov .name = TYPE_E500PLAT_MACHINE,
10803f04809SIgor Mammedov .parent = TYPE_PPCE500_MACHINE,
10903f04809SIgor Mammedov .class_init = e500plat_machine_class_init,
110a3fc8396SIgor Mammedov .interfaces = (InterfaceInfo[]) {
111a3fc8396SIgor Mammedov { TYPE_HOTPLUG_HANDLER },
112a3fc8396SIgor Mammedov { }
113a3fc8396SIgor Mammedov }
11403f04809SIgor Mammedov };
11503f04809SIgor Mammedov
e500plat_register_types(void)11603f04809SIgor Mammedov static void e500plat_register_types(void)
11703f04809SIgor Mammedov {
11803f04809SIgor Mammedov type_register_static(&e500plat_info);
11903f04809SIgor Mammedov }
12003f04809SIgor Mammedov type_init(e500plat_register_types)
121