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" 16*32cad1ffSPhilippe Mathieu-Daudé #include "system/device_tree.h" 17*32cad1ffSPhilippe Mathieu-Daudé #include "system/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 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 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 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 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 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"; 102053b7086SThomas 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 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