11db09b84Saurel32 /* 2b3305981SScott Wood * QEMU PowerPC e500-based platforms 31db09b84Saurel32 * 41db09b84Saurel32 * Copyright (C) 2009 Freescale Semiconductor, Inc. All rights reserved. 51db09b84Saurel32 * 61db09b84Saurel32 * Author: Yu Liu, <yu.liu@freescale.com> 71db09b84Saurel32 * 81db09b84Saurel32 * This file is derived from hw/ppc440_bamboo.c, 91db09b84Saurel32 * the copyright for that material belongs to the original owners. 101db09b84Saurel32 * 111db09b84Saurel32 * This is free software; you can redistribute it and/or modify 121db09b84Saurel32 * it under the terms of the GNU General Public License as published by 131db09b84Saurel32 * the Free Software Foundation; either version 2 of the License, or 141db09b84Saurel32 * (at your option) any later version. 151db09b84Saurel32 */ 161db09b84Saurel32 171db09b84Saurel32 #include "config.h" 181db09b84Saurel32 #include "qemu-common.h" 19e6eaabebSScott Wood #include "e500.h" 203eddc1beSBharat Bhushan #include "e500-ccsr.h" 211db09b84Saurel32 #include "net.h" 224a18e7c9SScott Wood #include "hw/hw.h" 23488cb996SGerd Hoffmann #include "hw/serial.h" 244a18e7c9SScott Wood #include "hw/pci.h" 254a18e7c9SScott Wood #include "hw/boards.h" 261db09b84Saurel32 #include "sysemu.h" 271db09b84Saurel32 #include "kvm.h" 281db09b84Saurel32 #include "kvm_ppc.h" 291db09b84Saurel32 #include "device_tree.h" 304a18e7c9SScott Wood #include "hw/openpic.h" 314a18e7c9SScott Wood #include "hw/ppc.h" 324a18e7c9SScott Wood #include "hw/loader.h" 33ca20cf32SBlue Swirl #include "elf.h" 344a18e7c9SScott Wood #include "hw/sysbus.h" 3539186d8aSRichard Henderson #include "exec-memory.h" 36cba2026aSAlexander Graf #include "host-utils.h" 371db09b84Saurel32 381db09b84Saurel32 #define BINARY_DEVICE_TREE_FILE "mpc8544ds.dtb" 391db09b84Saurel32 #define UIMAGE_LOAD_BASE 0 409dd5eba1SScott Wood #define DTC_LOAD_PAD 0x1800000 4175bb6589SLiu Yu #define DTC_PAD_MASK 0xFFFFF 4275bb6589SLiu Yu #define INITRD_LOAD_PAD 0x2000000 4375bb6589SLiu Yu #define INITRD_PAD_MASK 0xFFFFFF 441db09b84Saurel32 451db09b84Saurel32 #define RAM_SIZES_ALIGN (64UL << 20) 461db09b84Saurel32 47b3305981SScott Wood /* TODO: parameterize */ 48ed2bc496SAlexander Graf #define MPC8544_CCSRBAR_BASE 0xE0000000ULL 49ed2bc496SAlexander Graf #define MPC8544_CCSRBAR_SIZE 0x00100000ULL 50dffb1dc2SBharat Bhushan #define MPC8544_MPIC_REGS_OFFSET 0x40000ULL 51*a911b7a9SAlexander Graf #define MPC8544_MSI_REGS_OFFSET 0x41600ULL 52dffb1dc2SBharat Bhushan #define MPC8544_SERIAL0_REGS_OFFSET 0x4500ULL 53dffb1dc2SBharat Bhushan #define MPC8544_SERIAL1_REGS_OFFSET 0x4600ULL 54dffb1dc2SBharat Bhushan #define MPC8544_PCI_REGS_OFFSET 0x8000ULL 55dffb1dc2SBharat Bhushan #define MPC8544_PCI_REGS_BASE (MPC8544_CCSRBAR_BASE + \ 56dffb1dc2SBharat Bhushan MPC8544_PCI_REGS_OFFSET) 57ed2bc496SAlexander Graf #define MPC8544_PCI_REGS_SIZE 0x1000ULL 58ed2bc496SAlexander Graf #define MPC8544_PCI_IO 0xE1000000ULL 59dffb1dc2SBharat Bhushan #define MPC8544_UTIL_OFFSET 0xe0000ULL 60ed2bc496SAlexander Graf #define MPC8544_SPIN_BASE 0xEF000000ULL 611db09b84Saurel32 623b989d49SAlexander Graf struct boot_info 633b989d49SAlexander Graf { 643b989d49SAlexander Graf uint32_t dt_base; 65cba2026aSAlexander Graf uint32_t dt_size; 663b989d49SAlexander Graf uint32_t entry; 673b989d49SAlexander Graf }; 683b989d49SAlexander Graf 690dbc0798SAlexander Graf static void pci_map_create(void *fdt, uint32_t *pci_map, uint32_t mpic) 700dbc0798SAlexander Graf { 710dbc0798SAlexander Graf int i; 720dbc0798SAlexander Graf const uint32_t tmp[] = { 730dbc0798SAlexander Graf /* IDSEL 0x11 J17 Slot 1 */ 747e99826cSAlexander Graf 0x8800, 0x0, 0x0, 0x1, mpic, 0x2, 0x1, 757e99826cSAlexander Graf 0x8800, 0x0, 0x0, 0x2, mpic, 0x3, 0x1, 767e99826cSAlexander Graf 0x8800, 0x0, 0x0, 0x3, mpic, 0x4, 0x1, 777e99826cSAlexander Graf 0x8800, 0x0, 0x0, 0x4, mpic, 0x1, 0x1, 780dbc0798SAlexander Graf 790dbc0798SAlexander Graf /* IDSEL 0x12 J16 Slot 2 */ 807e99826cSAlexander Graf 0x9000, 0x0, 0x0, 0x1, mpic, 0x3, 0x1, 817e99826cSAlexander Graf 0x9000, 0x0, 0x0, 0x2, mpic, 0x4, 0x1, 827e99826cSAlexander Graf 0x9000, 0x0, 0x0, 0x3, mpic, 0x2, 0x1, 837e99826cSAlexander Graf 0x9000, 0x0, 0x0, 0x4, mpic, 0x1, 0x1, 840dbc0798SAlexander Graf }; 857e99826cSAlexander Graf for (i = 0; i < (7 * 8); i++) { 860dbc0798SAlexander Graf pci_map[i] = cpu_to_be32(tmp[i]); 870dbc0798SAlexander Graf } 880dbc0798SAlexander Graf } 890dbc0798SAlexander Graf 90a053a7ceSAlexander Graf static void dt_serial_create(void *fdt, unsigned long long offset, 91a053a7ceSAlexander Graf const char *soc, const char *mpic, 92a053a7ceSAlexander Graf const char *alias, int idx, bool defcon) 93a053a7ceSAlexander Graf { 94a053a7ceSAlexander Graf char ser[128]; 95a053a7ceSAlexander Graf 96a053a7ceSAlexander Graf snprintf(ser, sizeof(ser), "%s/serial@%llx", soc, offset); 97a053a7ceSAlexander Graf qemu_devtree_add_subnode(fdt, ser); 98a053a7ceSAlexander Graf qemu_devtree_setprop_string(fdt, ser, "device_type", "serial"); 99a053a7ceSAlexander Graf qemu_devtree_setprop_string(fdt, ser, "compatible", "ns16550"); 100a053a7ceSAlexander Graf qemu_devtree_setprop_cells(fdt, ser, "reg", offset, 0x100); 101a053a7ceSAlexander Graf qemu_devtree_setprop_cell(fdt, ser, "cell-index", idx); 102a053a7ceSAlexander Graf qemu_devtree_setprop_cell(fdt, ser, "clock-frequency", 0); 1037e99826cSAlexander Graf qemu_devtree_setprop_cells(fdt, ser, "interrupts", 42, 2); 104a053a7ceSAlexander Graf qemu_devtree_setprop_phandle(fdt, ser, "interrupt-parent", mpic); 105a053a7ceSAlexander Graf qemu_devtree_setprop_string(fdt, "/aliases", alias, ser); 106a053a7ceSAlexander Graf 107a053a7ceSAlexander Graf if (defcon) { 108a053a7ceSAlexander Graf qemu_devtree_setprop_string(fdt, "/chosen", "linux,stdout-path", ser); 109a053a7ceSAlexander Graf } 110a053a7ceSAlexander Graf } 111a053a7ceSAlexander Graf 112b3305981SScott Wood static int ppce500_load_device_tree(CPUPPCState *env, 113e6eaabebSScott Wood PPCE500Params *params, 114a8170e5eSAvi Kivity hwaddr addr, 115a8170e5eSAvi Kivity hwaddr initrd_base, 116a8170e5eSAvi Kivity hwaddr initrd_size) 1171db09b84Saurel32 { 118dbf916d8SAurelien Jarno int ret = -1; 119e6eaabebSScott Wood uint64_t mem_reg_property[] = { 0, cpu_to_be64(params->ram_size) }; 1207ec632b4Spbrook int fdt_size; 121dbf916d8SAurelien Jarno void *fdt; 1225de6b46dSAlexander Graf uint8_t hypercall[16]; 123911d6e7aSAlexander Graf uint32_t clock_freq = 400000000; 124911d6e7aSAlexander Graf uint32_t tb_freq = 400000000; 125621d05e3SAlexander Graf int i; 126e6eaabebSScott Wood const char *toplevel_compat = NULL; /* user override */ 127ebb9518aSAlexander Graf char compatible_sb[] = "fsl,mpc8544-immr\0simple-bus"; 1285da96624SAlexander Graf char soc[128]; 12919ac9deaSAlexander Graf char mpic[128]; 13019ac9deaSAlexander Graf uint32_t mpic_ph; 131*a911b7a9SAlexander Graf uint32_t msi_ph; 132f5038483SAlexander Graf char gutil[128]; 1330dbc0798SAlexander Graf char pci[128]; 134*a911b7a9SAlexander Graf char msi[128]; 1357e99826cSAlexander Graf uint32_t pci_map[7 * 8]; 1363627757eSAlexander Graf uint32_t pci_ranges[14] = 1373627757eSAlexander Graf { 1383627757eSAlexander Graf 0x2000000, 0x0, 0xc0000000, 1393627757eSAlexander Graf 0x0, 0xc0000000, 1403627757eSAlexander Graf 0x0, 0x20000000, 1413627757eSAlexander Graf 1423627757eSAlexander Graf 0x1000000, 0x0, 0x0, 1433627757eSAlexander Graf 0x0, 0xe1000000, 1443627757eSAlexander Graf 0x0, 0x10000, 1453627757eSAlexander Graf }; 14625b42708SAlexander Graf QemuOpts *machine_opts; 147d1b93565SAlexander Graf const char *dtb_file = NULL; 148d1b93565SAlexander Graf 149d1b93565SAlexander Graf machine_opts = qemu_opts_find(qemu_find_opts("machine"), 0); 150d1b93565SAlexander Graf if (machine_opts) { 151d1b93565SAlexander Graf dtb_file = qemu_opt_get(machine_opts, "dtb"); 152e6eaabebSScott Wood toplevel_compat = qemu_opt_get(machine_opts, "dt_compatible"); 153d1b93565SAlexander Graf } 154d1b93565SAlexander Graf 155d1b93565SAlexander Graf if (dtb_file) { 156d1b93565SAlexander Graf char *filename; 157d1b93565SAlexander Graf filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, dtb_file); 158d1b93565SAlexander Graf if (!filename) { 159d1b93565SAlexander Graf goto out; 160d1b93565SAlexander Graf } 161d1b93565SAlexander Graf 162d1b93565SAlexander Graf fdt = load_device_tree(filename, &fdt_size); 163d1b93565SAlexander Graf if (!fdt) { 164d1b93565SAlexander Graf goto out; 165d1b93565SAlexander Graf } 166d1b93565SAlexander Graf goto done; 167d1b93565SAlexander Graf } 1681db09b84Saurel32 1692636fcb6SAlexander Graf fdt = create_device_tree(&fdt_size); 1705cea8590SPaul Brook if (fdt == NULL) { 1715cea8590SPaul Brook goto out; 1725cea8590SPaul Brook } 1731db09b84Saurel32 1741db09b84Saurel32 /* Manipulate device tree in memory. */ 1753627757eSAlexander Graf qemu_devtree_setprop_cell(fdt, "/", "#address-cells", 2); 1763627757eSAlexander Graf qemu_devtree_setprop_cell(fdt, "/", "#size-cells", 2); 17751b852b7SAlexander Graf 178dd0bcfcaSAlexander Graf qemu_devtree_add_subnode(fdt, "/memory"); 179dd0bcfcaSAlexander Graf qemu_devtree_setprop_string(fdt, "/memory", "device_type", "memory"); 180dd0bcfcaSAlexander Graf qemu_devtree_setprop(fdt, "/memory", "reg", mem_reg_property, 1811db09b84Saurel32 sizeof(mem_reg_property)); 1821db09b84Saurel32 183f5231aafSAlexander Graf qemu_devtree_add_subnode(fdt, "/chosen"); 1843b989d49SAlexander Graf if (initrd_size) { 1851db09b84Saurel32 ret = qemu_devtree_setprop_cell(fdt, "/chosen", "linux,initrd-start", 1861db09b84Saurel32 initrd_base); 1873b989d49SAlexander Graf if (ret < 0) { 1881db09b84Saurel32 fprintf(stderr, "couldn't set /chosen/linux,initrd-start\n"); 1893b989d49SAlexander Graf } 1901db09b84Saurel32 1911db09b84Saurel32 ret = qemu_devtree_setprop_cell(fdt, "/chosen", "linux,initrd-end", 1921db09b84Saurel32 (initrd_base + initrd_size)); 1933b989d49SAlexander Graf if (ret < 0) { 1941db09b84Saurel32 fprintf(stderr, "couldn't set /chosen/linux,initrd-end\n"); 1953b989d49SAlexander Graf } 1963b989d49SAlexander Graf } 1971db09b84Saurel32 1981db09b84Saurel32 ret = qemu_devtree_setprop_string(fdt, "/chosen", "bootargs", 199e6eaabebSScott Wood params->kernel_cmdline); 2001db09b84Saurel32 if (ret < 0) 2011db09b84Saurel32 fprintf(stderr, "couldn't set /chosen/bootargs\n"); 2021db09b84Saurel32 2031db09b84Saurel32 if (kvm_enabled()) { 204911d6e7aSAlexander Graf /* Read out host's frequencies */ 205911d6e7aSAlexander Graf clock_freq = kvmppc_get_clockfreq(); 206911d6e7aSAlexander Graf tb_freq = kvmppc_get_tbfreq(); 2075de6b46dSAlexander Graf 2085de6b46dSAlexander Graf /* indicate KVM hypercall interface */ 209d50f71a5SAlexander Graf qemu_devtree_add_subnode(fdt, "/hypervisor"); 2105de6b46dSAlexander Graf qemu_devtree_setprop_string(fdt, "/hypervisor", "compatible", 2115de6b46dSAlexander Graf "linux,kvm"); 2125de6b46dSAlexander Graf kvmppc_get_hypercall(env, hypercall, sizeof(hypercall)); 2135de6b46dSAlexander Graf qemu_devtree_setprop(fdt, "/hypervisor", "hcall-instructions", 2145de6b46dSAlexander Graf hypercall, sizeof(hypercall)); 2151db09b84Saurel32 } 2161db09b84Saurel32 217625e665bSAlexander Graf /* Create CPU nodes */ 218625e665bSAlexander Graf qemu_devtree_add_subnode(fdt, "/cpus"); 219625e665bSAlexander Graf qemu_devtree_setprop_cell(fdt, "/cpus", "#address-cells", 1); 220625e665bSAlexander Graf qemu_devtree_setprop_cell(fdt, "/cpus", "#size-cells", 0); 221625e665bSAlexander Graf 2221e3debf0SAlexander Graf /* We need to generate the cpu nodes in reverse order, so Linux can pick 2231e3debf0SAlexander Graf the first node as boot node and be happy */ 2241e3debf0SAlexander Graf for (i = smp_cpus - 1; i >= 0; i--) { 225621d05e3SAlexander Graf char cpu_name[128]; 2261d2e5c52SAlexander Graf uint64_t cpu_release_addr = MPC8544_SPIN_BASE + (i * 0x20); 22710f25a46SAlexander Graf 2281e3debf0SAlexander Graf for (env = first_cpu; env != NULL; env = env->next_cpu) { 2291e3debf0SAlexander Graf if (env->cpu_index == i) { 2301e3debf0SAlexander Graf break; 2311e3debf0SAlexander Graf } 232621d05e3SAlexander Graf } 233911d6e7aSAlexander Graf 2341e3debf0SAlexander Graf if (!env) { 2351e3debf0SAlexander Graf continue; 2361e3debf0SAlexander Graf } 2371e3debf0SAlexander Graf 2381e3debf0SAlexander Graf snprintf(cpu_name, sizeof(cpu_name), "/cpus/PowerPC,8544@%x", env->cpu_index); 2391e3debf0SAlexander Graf qemu_devtree_add_subnode(fdt, cpu_name); 2401e3debf0SAlexander Graf qemu_devtree_setprop_cell(fdt, cpu_name, "clock-frequency", clock_freq); 2411e3debf0SAlexander Graf qemu_devtree_setprop_cell(fdt, cpu_name, "timebase-frequency", tb_freq); 2421e3debf0SAlexander Graf qemu_devtree_setprop_string(fdt, cpu_name, "device_type", "cpu"); 2431e3debf0SAlexander Graf qemu_devtree_setprop_cell(fdt, cpu_name, "reg", env->cpu_index); 2441e3debf0SAlexander Graf qemu_devtree_setprop_cell(fdt, cpu_name, "d-cache-line-size", 2451e3debf0SAlexander Graf env->dcache_line_size); 2461e3debf0SAlexander Graf qemu_devtree_setprop_cell(fdt, cpu_name, "i-cache-line-size", 2471e3debf0SAlexander Graf env->icache_line_size); 2481e3debf0SAlexander Graf qemu_devtree_setprop_cell(fdt, cpu_name, "d-cache-size", 0x8000); 2491e3debf0SAlexander Graf qemu_devtree_setprop_cell(fdt, cpu_name, "i-cache-size", 0x8000); 2501e3debf0SAlexander Graf qemu_devtree_setprop_cell(fdt, cpu_name, "bus-frequency", 0); 2511e3debf0SAlexander Graf if (env->cpu_index) { 2521e3debf0SAlexander Graf qemu_devtree_setprop_string(fdt, cpu_name, "status", "disabled"); 2531e3debf0SAlexander Graf qemu_devtree_setprop_string(fdt, cpu_name, "enable-method", "spin-table"); 2541d2e5c52SAlexander Graf qemu_devtree_setprop_u64(fdt, cpu_name, "cpu-release-addr", 2551d2e5c52SAlexander Graf cpu_release_addr); 2561e3debf0SAlexander Graf } else { 2571e3debf0SAlexander Graf qemu_devtree_setprop_string(fdt, cpu_name, "status", "okay"); 2581e3debf0SAlexander Graf } 2591db09b84Saurel32 } 2601db09b84Saurel32 2610cfc6e8dSAlexander Graf qemu_devtree_add_subnode(fdt, "/aliases"); 2625da96624SAlexander Graf /* XXX These should go into their respective devices' code */ 263ed2bc496SAlexander Graf snprintf(soc, sizeof(soc), "/soc@%llx", MPC8544_CCSRBAR_BASE); 2645da96624SAlexander Graf qemu_devtree_add_subnode(fdt, soc); 2655da96624SAlexander Graf qemu_devtree_setprop_string(fdt, soc, "device_type", "soc"); 266ebb9518aSAlexander Graf qemu_devtree_setprop(fdt, soc, "compatible", compatible_sb, 267ebb9518aSAlexander Graf sizeof(compatible_sb)); 2685da96624SAlexander Graf qemu_devtree_setprop_cell(fdt, soc, "#address-cells", 1); 2695da96624SAlexander Graf qemu_devtree_setprop_cell(fdt, soc, "#size-cells", 1); 2703627757eSAlexander Graf qemu_devtree_setprop_cells(fdt, soc, "ranges", 0x0, 2713627757eSAlexander Graf MPC8544_CCSRBAR_BASE >> 32, MPC8544_CCSRBAR_BASE, 2725da96624SAlexander Graf MPC8544_CCSRBAR_SIZE); 2735da96624SAlexander Graf /* XXX should contain a reasonable value */ 2745da96624SAlexander Graf qemu_devtree_setprop_cell(fdt, soc, "bus-frequency", 0); 2755da96624SAlexander Graf 276dffb1dc2SBharat Bhushan snprintf(mpic, sizeof(mpic), "%s/pic@%llx", soc, MPC8544_MPIC_REGS_OFFSET); 27719ac9deaSAlexander Graf qemu_devtree_add_subnode(fdt, mpic); 27819ac9deaSAlexander Graf qemu_devtree_setprop_string(fdt, mpic, "device_type", "open-pic"); 2797e99826cSAlexander Graf qemu_devtree_setprop_string(fdt, mpic, "compatible", "chrp,open-pic"); 280dffb1dc2SBharat Bhushan qemu_devtree_setprop_cells(fdt, mpic, "reg", MPC8544_MPIC_REGS_OFFSET, 281dffb1dc2SBharat Bhushan 0x40000); 28219ac9deaSAlexander Graf qemu_devtree_setprop_cell(fdt, mpic, "#address-cells", 0); 2837e99826cSAlexander Graf qemu_devtree_setprop_cell(fdt, mpic, "#interrupt-cells", 2); 28419ac9deaSAlexander Graf mpic_ph = qemu_devtree_alloc_phandle(fdt); 28519ac9deaSAlexander Graf qemu_devtree_setprop_cell(fdt, mpic, "phandle", mpic_ph); 28619ac9deaSAlexander Graf qemu_devtree_setprop_cell(fdt, mpic, "linux,phandle", mpic_ph); 28719ac9deaSAlexander Graf qemu_devtree_setprop(fdt, mpic, "interrupt-controller", NULL, 0); 28819ac9deaSAlexander Graf 2890cfc6e8dSAlexander Graf /* 2900cfc6e8dSAlexander Graf * We have to generate ser1 first, because Linux takes the first 2910cfc6e8dSAlexander Graf * device it finds in the dt as serial output device. And we generate 2920cfc6e8dSAlexander Graf * devices in reverse order to the dt. 2930cfc6e8dSAlexander Graf */ 294dffb1dc2SBharat Bhushan dt_serial_create(fdt, MPC8544_SERIAL1_REGS_OFFSET, 295a053a7ceSAlexander Graf soc, mpic, "serial1", 1, false); 296dffb1dc2SBharat Bhushan dt_serial_create(fdt, MPC8544_SERIAL0_REGS_OFFSET, 297a053a7ceSAlexander Graf soc, mpic, "serial0", 0, true); 2980cfc6e8dSAlexander Graf 299ed2bc496SAlexander Graf snprintf(gutil, sizeof(gutil), "%s/global-utilities@%llx", soc, 300dffb1dc2SBharat Bhushan MPC8544_UTIL_OFFSET); 301f5038483SAlexander Graf qemu_devtree_add_subnode(fdt, gutil); 302f5038483SAlexander Graf qemu_devtree_setprop_string(fdt, gutil, "compatible", "fsl,mpc8544-guts"); 303dffb1dc2SBharat Bhushan qemu_devtree_setprop_cells(fdt, gutil, "reg", MPC8544_UTIL_OFFSET, 0x1000); 304f5038483SAlexander Graf qemu_devtree_setprop(fdt, gutil, "fsl,has-rstcr", NULL, 0); 305f5038483SAlexander Graf 306*a911b7a9SAlexander Graf snprintf(msi, sizeof(msi), "/%s/msi@%llx", soc, MPC8544_MSI_REGS_OFFSET); 307*a911b7a9SAlexander Graf qemu_devtree_add_subnode(fdt, msi); 308*a911b7a9SAlexander Graf qemu_devtree_setprop_string(fdt, msi, "compatible", "fsl,mpic-msi"); 309*a911b7a9SAlexander Graf qemu_devtree_setprop_cells(fdt, msi, "reg", MPC8544_MSI_REGS_OFFSET, 0x200); 310*a911b7a9SAlexander Graf msi_ph = qemu_devtree_alloc_phandle(fdt); 311*a911b7a9SAlexander Graf qemu_devtree_setprop_cells(fdt, msi, "msi-available-ranges", 0x0, 0x100); 312*a911b7a9SAlexander Graf qemu_devtree_setprop_phandle(fdt, msi, "interrupt-parent", mpic); 313*a911b7a9SAlexander Graf qemu_devtree_setprop_cells(fdt, msi, "interrupts", 314*a911b7a9SAlexander Graf 0xe0, 0x0, 315*a911b7a9SAlexander Graf 0xe1, 0x0, 316*a911b7a9SAlexander Graf 0xe2, 0x0, 317*a911b7a9SAlexander Graf 0xe3, 0x0, 318*a911b7a9SAlexander Graf 0xe4, 0x0, 319*a911b7a9SAlexander Graf 0xe5, 0x0, 320*a911b7a9SAlexander Graf 0xe6, 0x0, 321*a911b7a9SAlexander Graf 0xe7, 0x0); 322*a911b7a9SAlexander Graf qemu_devtree_setprop_cell(fdt, msi, "phandle", msi_ph); 323*a911b7a9SAlexander Graf qemu_devtree_setprop_cell(fdt, msi, "linux,phandle", msi_ph); 324*a911b7a9SAlexander Graf 325ed2bc496SAlexander Graf snprintf(pci, sizeof(pci), "/pci@%llx", MPC8544_PCI_REGS_BASE); 3260dbc0798SAlexander Graf qemu_devtree_add_subnode(fdt, pci); 3270dbc0798SAlexander Graf qemu_devtree_setprop_cell(fdt, pci, "cell-index", 0); 3280dbc0798SAlexander Graf qemu_devtree_setprop_string(fdt, pci, "compatible", "fsl,mpc8540-pci"); 3290dbc0798SAlexander Graf qemu_devtree_setprop_string(fdt, pci, "device_type", "pci"); 3300dbc0798SAlexander Graf qemu_devtree_setprop_cells(fdt, pci, "interrupt-map-mask", 0xf800, 0x0, 3310dbc0798SAlexander Graf 0x0, 0x7); 3320dbc0798SAlexander Graf pci_map_create(fdt, pci_map, qemu_devtree_get_phandle(fdt, mpic)); 3330dbc0798SAlexander Graf qemu_devtree_setprop(fdt, pci, "interrupt-map", pci_map, sizeof(pci_map)); 3340dbc0798SAlexander Graf qemu_devtree_setprop_phandle(fdt, pci, "interrupt-parent", mpic); 3357e99826cSAlexander Graf qemu_devtree_setprop_cells(fdt, pci, "interrupts", 24, 2); 3360dbc0798SAlexander Graf qemu_devtree_setprop_cells(fdt, pci, "bus-range", 0, 255); 3373627757eSAlexander Graf for (i = 0; i < 14; i++) { 3380dbc0798SAlexander Graf pci_ranges[i] = cpu_to_be32(pci_ranges[i]); 3390dbc0798SAlexander Graf } 340*a911b7a9SAlexander Graf qemu_devtree_setprop_cell(fdt, pci, "fsl,msi", msi_ph); 3410dbc0798SAlexander Graf qemu_devtree_setprop(fdt, pci, "ranges", pci_ranges, sizeof(pci_ranges)); 3423627757eSAlexander Graf qemu_devtree_setprop_cells(fdt, pci, "reg", MPC8544_PCI_REGS_BASE >> 32, 3433627757eSAlexander Graf MPC8544_PCI_REGS_BASE, 0, 0x1000); 3440dbc0798SAlexander Graf qemu_devtree_setprop_cell(fdt, pci, "clock-frequency", 66666666); 3450dbc0798SAlexander Graf qemu_devtree_setprop_cell(fdt, pci, "#interrupt-cells", 1); 3460dbc0798SAlexander Graf qemu_devtree_setprop_cell(fdt, pci, "#size-cells", 2); 3470dbc0798SAlexander Graf qemu_devtree_setprop_cell(fdt, pci, "#address-cells", 3); 3480dbc0798SAlexander Graf qemu_devtree_setprop_string(fdt, "/aliases", "pci0", pci); 3490dbc0798SAlexander Graf 350e6eaabebSScott Wood params->fixup_devtree(params, fdt); 351e6eaabebSScott Wood 352e6eaabebSScott Wood if (toplevel_compat) { 353e6eaabebSScott Wood qemu_devtree_setprop(fdt, "/", "compatible", toplevel_compat, 354e6eaabebSScott Wood strlen(toplevel_compat) + 1); 355e6eaabebSScott Wood } 356e6eaabebSScott Wood 357d1b93565SAlexander Graf done: 35871193433SAlexander Graf qemu_devtree_dumpdtb(fdt, fdt_size); 35904088adbSLiu Yu ret = rom_add_blob_fixed(BINARY_DEVICE_TREE_FILE, fdt, fdt_size, addr); 360cba2026aSAlexander Graf if (ret < 0) { 361cba2026aSAlexander Graf goto out; 362cba2026aSAlexander Graf } 3637267c094SAnthony Liguori g_free(fdt); 364cba2026aSAlexander Graf ret = fdt_size; 3657ec632b4Spbrook 3661db09b84Saurel32 out: 3671db09b84Saurel32 36804088adbSLiu Yu return ret; 3691db09b84Saurel32 } 3701db09b84Saurel32 371cba2026aSAlexander Graf /* Create -kernel TLB entries for BookE. */ 372a8170e5eSAvi Kivity static inline hwaddr booke206_page_size_to_tlb(uint64_t size) 373d1e256feSAlexander Graf { 374cba2026aSAlexander Graf return 63 - clz64(size >> 10); 375d1e256feSAlexander Graf } 376d1e256feSAlexander Graf 377cba2026aSAlexander Graf static void mmubooke_create_initial_mapping(CPUPPCState *env) 3783b989d49SAlexander Graf { 379cba2026aSAlexander Graf struct boot_info *bi = env->load_info; 380d1e256feSAlexander Graf ppcmas_tlb_t *tlb = booke206_get_tlbm(env, 1, 0, 0); 381a8170e5eSAvi Kivity hwaddr size, dt_end; 382cba2026aSAlexander Graf int ps; 3833b989d49SAlexander Graf 384cba2026aSAlexander Graf /* Our initial TLB entry needs to cover everything from 0 to 385cba2026aSAlexander Graf the device tree top */ 386cba2026aSAlexander Graf dt_end = bi->dt_base + bi->dt_size; 387cba2026aSAlexander Graf ps = booke206_page_size_to_tlb(dt_end) + 1; 388fb37c302SAlexander Graf if (ps & 1) { 389fb37c302SAlexander Graf /* e500v2 can only do even TLB size bits */ 390fb37c302SAlexander Graf ps++; 391fb37c302SAlexander Graf } 392cba2026aSAlexander Graf size = (ps << MAS1_TSIZE_SHIFT); 393d1e256feSAlexander Graf tlb->mas1 = MAS1_VALID | size; 394cba2026aSAlexander Graf tlb->mas2 = 0; 395cba2026aSAlexander Graf tlb->mas7_3 = 0; 396d1e256feSAlexander Graf tlb->mas7_3 |= MAS3_UR | MAS3_UW | MAS3_UX | MAS3_SR | MAS3_SW | MAS3_SX; 39793dd5e85SScott Wood 39893dd5e85SScott Wood env->tlb_dirty = true; 3993b989d49SAlexander Graf } 4003b989d49SAlexander Graf 401b3305981SScott Wood static void ppce500_cpu_reset_sec(void *opaque) 4025c145dacSAlexander Graf { 40338f92da6SAndreas Färber PowerPCCPU *cpu = opaque; 40438f92da6SAndreas Färber CPUPPCState *env = &cpu->env; 4055c145dacSAlexander Graf 40638f92da6SAndreas Färber cpu_reset(CPU(cpu)); 4075c145dacSAlexander Graf 4085c145dacSAlexander Graf /* Secondary CPU starts in halted state for now. Needs to change when 4095c145dacSAlexander Graf implementing non-kernel boot. */ 4105c145dacSAlexander Graf env->halted = 1; 4115c145dacSAlexander Graf env->exception_index = EXCP_HLT; 4123b989d49SAlexander Graf } 4133b989d49SAlexander Graf 414b3305981SScott Wood static void ppce500_cpu_reset(void *opaque) 4153b989d49SAlexander Graf { 41638f92da6SAndreas Färber PowerPCCPU *cpu = opaque; 41738f92da6SAndreas Färber CPUPPCState *env = &cpu->env; 4183b989d49SAlexander Graf struct boot_info *bi = env->load_info; 4193b989d49SAlexander Graf 42038f92da6SAndreas Färber cpu_reset(CPU(cpu)); 4213b989d49SAlexander Graf 4223b989d49SAlexander Graf /* Set initial guest state. */ 4235c145dacSAlexander Graf env->halted = 0; 4243b989d49SAlexander Graf env->gpr[1] = (16<<20) - 8; 4253b989d49SAlexander Graf env->gpr[3] = bi->dt_base; 4263b989d49SAlexander Graf env->nip = bi->entry; 427cba2026aSAlexander Graf mmubooke_create_initial_mapping(env); 4283b989d49SAlexander Graf } 4293b989d49SAlexander Graf 430e6eaabebSScott Wood void ppce500_init(PPCE500Params *params) 4311db09b84Saurel32 { 43239186d8aSRichard Henderson MemoryRegion *address_space_mem = get_system_memory(); 4332646c133SAvi Kivity MemoryRegion *ram = g_new(MemoryRegion, 1); 4341db09b84Saurel32 PCIBus *pci_bus; 435e2684c0bSAndreas Färber CPUPPCState *env = NULL; 4361db09b84Saurel32 uint64_t elf_entry; 4371db09b84Saurel32 uint64_t elf_lowaddr; 438a8170e5eSAvi Kivity hwaddr entry=0; 439a8170e5eSAvi Kivity hwaddr loadaddr=UIMAGE_LOAD_BASE; 4401db09b84Saurel32 target_long kernel_size=0; 44175bb6589SLiu Yu target_ulong dt_base = 0; 44275bb6589SLiu Yu target_ulong initrd_base = 0; 4431db09b84Saurel32 target_long initrd_size=0; 444d0b72631SAlexander Graf int i = 0, j, k; 4451db09b84Saurel32 unsigned int pci_irq_nrs[4] = {1, 2, 3, 4}; 446a915249fSAlexander Graf qemu_irq **irqs, *mpic; 447be13cc7aSAlexander Graf DeviceState *dev; 448e2684c0bSAndreas Färber CPUPPCState *firstenv = NULL; 4493eddc1beSBharat Bhushan MemoryRegion *ccsr_addr_space; 450dffb1dc2SBharat Bhushan SysBusDevice *s; 4513eddc1beSBharat Bhushan PPCE500CCSRState *ccsr; 4521db09b84Saurel32 453e61c36d5SAlexander Graf /* Setup CPUs */ 454e6eaabebSScott Wood if (params->cpu_model == NULL) { 455e6eaabebSScott Wood params->cpu_model = "e500v2_v30"; 456ef250db6SAlexander Graf } 457ef250db6SAlexander Graf 458a915249fSAlexander Graf irqs = g_malloc0(smp_cpus * sizeof(qemu_irq *)); 459a915249fSAlexander Graf irqs[0] = g_malloc0(smp_cpus * sizeof(qemu_irq) * OPENPIC_OUTPUT_NB); 460e61c36d5SAlexander Graf for (i = 0; i < smp_cpus; i++) { 461397b457dSAndreas Färber PowerPCCPU *cpu; 462e61c36d5SAlexander Graf qemu_irq *input; 463397b457dSAndreas Färber 464e6eaabebSScott Wood cpu = cpu_ppc_init(params->cpu_model); 465397b457dSAndreas Färber if (cpu == NULL) { 4661db09b84Saurel32 fprintf(stderr, "Unable to initialize CPU!\n"); 4671db09b84Saurel32 exit(1); 4681db09b84Saurel32 } 469397b457dSAndreas Färber env = &cpu->env; 4701db09b84Saurel32 471e61c36d5SAlexander Graf if (!firstenv) { 472e61c36d5SAlexander Graf firstenv = env; 473e61c36d5SAlexander Graf } 474e61c36d5SAlexander Graf 475a915249fSAlexander Graf irqs[i] = irqs[0] + (i * OPENPIC_OUTPUT_NB); 476a915249fSAlexander Graf input = (qemu_irq *)env->irq_inputs; 477a915249fSAlexander Graf irqs[i][OPENPIC_OUTPUT_INT] = input[PPCE500_INPUT_INT]; 478a915249fSAlexander Graf irqs[i][OPENPIC_OUTPUT_CINT] = input[PPCE500_INPUT_CINT]; 479e61c36d5SAlexander Graf env->spr[SPR_BOOKE_PIR] = env->cpu_index = i; 480dffb1dc2SBharat Bhushan env->mpic_cpu_base = MPC8544_CCSRBAR_BASE + 481dffb1dc2SBharat Bhushan MPC8544_MPIC_REGS_OFFSET + 0x20000; 482e61c36d5SAlexander Graf 483ddd1055bSFabien Chouteau ppc_booke_timers_init(env, 400000000, PPC_TIMER_E500); 4843b989d49SAlexander Graf 4853b989d49SAlexander Graf /* Register reset handler */ 4865c145dacSAlexander Graf if (!i) { 4875c145dacSAlexander Graf /* Primary CPU */ 4885c145dacSAlexander Graf struct boot_info *boot_info; 489e61c36d5SAlexander Graf boot_info = g_malloc0(sizeof(struct boot_info)); 490b3305981SScott Wood qemu_register_reset(ppce500_cpu_reset, cpu); 491e61c36d5SAlexander Graf env->load_info = boot_info; 4925c145dacSAlexander Graf } else { 4935c145dacSAlexander Graf /* Secondary CPUs */ 494b3305981SScott Wood qemu_register_reset(ppce500_cpu_reset_sec, cpu); 4955c145dacSAlexander Graf } 496e61c36d5SAlexander Graf } 497e61c36d5SAlexander Graf 498e61c36d5SAlexander Graf env = firstenv; 4993b989d49SAlexander Graf 5001db09b84Saurel32 /* Fixup Memory size on a alignment boundary */ 5011db09b84Saurel32 ram_size &= ~(RAM_SIZES_ALIGN - 1); 5021db09b84Saurel32 5031db09b84Saurel32 /* Register Memory */ 504c5705a77SAvi Kivity memory_region_init_ram(ram, "mpc8544ds.ram", ram_size); 505c5705a77SAvi Kivity vmstate_register_ram_global(ram); 5062646c133SAvi Kivity memory_region_add_subregion(address_space_mem, 0, ram); 5071db09b84Saurel32 5083eddc1beSBharat Bhushan dev = qdev_create(NULL, "e500-ccsr"); 5093eddc1beSBharat Bhushan object_property_add_child(qdev_get_machine(), "e500-ccsr", 5103eddc1beSBharat Bhushan OBJECT(dev), NULL); 5113eddc1beSBharat Bhushan qdev_init_nofail(dev); 5123eddc1beSBharat Bhushan ccsr = CCSR(dev); 5133eddc1beSBharat Bhushan ccsr_addr_space = &ccsr->ccsr_space; 5143eddc1beSBharat Bhushan memory_region_add_subregion(address_space_mem, MPC8544_CCSRBAR_BASE, 5153eddc1beSBharat Bhushan ccsr_addr_space); 516dffb1dc2SBharat Bhushan 5171db09b84Saurel32 /* MPIC */ 518d0b72631SAlexander Graf mpic = g_new(qemu_irq, 256); 519d0b72631SAlexander Graf dev = qdev_create(NULL, "openpic"); 520d0b72631SAlexander Graf qdev_prop_set_uint32(dev, "nb_cpus", smp_cpus); 521d0b72631SAlexander Graf qdev_prop_set_uint32(dev, "model", OPENPIC_MODEL_FSL_MPIC_20); 522d0b72631SAlexander Graf qdev_init_nofail(dev); 523d0b72631SAlexander Graf s = sysbus_from_qdev(dev); 524a915249fSAlexander Graf 525d0b72631SAlexander Graf k = 0; 526d0b72631SAlexander Graf for (i = 0; i < smp_cpus; i++) { 527d0b72631SAlexander Graf for (j = 0; j < OPENPIC_OUTPUT_NB; j++) { 528d0b72631SAlexander Graf sysbus_connect_irq(s, k++, irqs[i][j]); 529a915249fSAlexander Graf } 530d0b72631SAlexander Graf } 531d0b72631SAlexander Graf 532d0b72631SAlexander Graf for (i = 0; i < 256; i++) { 533d0b72631SAlexander Graf mpic[i] = qdev_get_gpio_in(dev, i); 534d0b72631SAlexander Graf } 535d0b72631SAlexander Graf 536d0b72631SAlexander Graf memory_region_add_subregion(ccsr_addr_space, MPC8544_MPIC_REGS_OFFSET, 537d0b72631SAlexander Graf s->mmio[0].memory); 5381db09b84Saurel32 5391db09b84Saurel32 /* Serial */ 5402d48377aSBlue Swirl if (serial_hds[0]) { 5413eddc1beSBharat Bhushan serial_mm_init(ccsr_addr_space, MPC8544_SERIAL0_REGS_OFFSET, 542cdbb912aSAlexander Graf 0, mpic[42], 399193, 5432ff0c7c3SRichard Henderson serial_hds[0], DEVICE_BIG_ENDIAN); 5442d48377aSBlue Swirl } 5451db09b84Saurel32 5462d48377aSBlue Swirl if (serial_hds[1]) { 5473eddc1beSBharat Bhushan serial_mm_init(ccsr_addr_space, MPC8544_SERIAL1_REGS_OFFSET, 548cdbb912aSAlexander Graf 0, mpic[42], 399193, 54959de4f98SBharat Bhushan serial_hds[1], DEVICE_BIG_ENDIAN); 5502d48377aSBlue Swirl } 5511db09b84Saurel32 552b0fb8423SAlexander Graf /* General Utility device */ 553dffb1dc2SBharat Bhushan dev = qdev_create(NULL, "mpc8544-guts"); 554dffb1dc2SBharat Bhushan qdev_init_nofail(dev); 555dffb1dc2SBharat Bhushan s = SYS_BUS_DEVICE(dev); 5563eddc1beSBharat Bhushan memory_region_add_subregion(ccsr_addr_space, MPC8544_UTIL_OFFSET, 557dffb1dc2SBharat Bhushan sysbus_mmio_get_region(s, 0)); 558b0fb8423SAlexander Graf 5591db09b84Saurel32 /* PCI */ 560dffb1dc2SBharat Bhushan dev = qdev_create(NULL, "e500-pcihost"); 561dffb1dc2SBharat Bhushan qdev_init_nofail(dev); 562dffb1dc2SBharat Bhushan s = SYS_BUS_DEVICE(dev); 563dffb1dc2SBharat Bhushan sysbus_connect_irq(s, 0, mpic[pci_irq_nrs[0]]); 564dffb1dc2SBharat Bhushan sysbus_connect_irq(s, 1, mpic[pci_irq_nrs[1]]); 565dffb1dc2SBharat Bhushan sysbus_connect_irq(s, 2, mpic[pci_irq_nrs[2]]); 566dffb1dc2SBharat Bhushan sysbus_connect_irq(s, 3, mpic[pci_irq_nrs[3]]); 5673eddc1beSBharat Bhushan memory_region_add_subregion(ccsr_addr_space, MPC8544_PCI_REGS_OFFSET, 568dffb1dc2SBharat Bhushan sysbus_mmio_get_region(s, 0)); 569dffb1dc2SBharat Bhushan 570d461e3b9SAlexander Graf pci_bus = (PCIBus *)qdev_get_child_bus(dev, "pci.0"); 5711db09b84Saurel32 if (!pci_bus) 5721db09b84Saurel32 printf("couldn't create PCI controller!\n"); 5731db09b84Saurel32 574a1bc20dfSAlexander Graf sysbus_mmio_map(sysbus_from_qdev(dev), 1, MPC8544_PCI_IO); 5751db09b84Saurel32 5761db09b84Saurel32 if (pci_bus) { 5771db09b84Saurel32 /* Register network interfaces. */ 5781db09b84Saurel32 for (i = 0; i < nb_nics; i++) { 57907caea31SMarkus Armbruster pci_nic_init_nofail(&nd_table[i], "virtio", NULL); 5801db09b84Saurel32 } 5811db09b84Saurel32 } 5821db09b84Saurel32 5835c145dacSAlexander Graf /* Register spinning region */ 5845c145dacSAlexander Graf sysbus_create_simple("e500-spin", MPC8544_SPIN_BASE, NULL); 5855c145dacSAlexander Graf 5861db09b84Saurel32 /* Load kernel. */ 587e6eaabebSScott Wood if (params->kernel_filename) { 588e6eaabebSScott Wood kernel_size = load_uimage(params->kernel_filename, &entry, 589e6eaabebSScott Wood &loadaddr, NULL); 5901db09b84Saurel32 if (kernel_size < 0) { 591e6eaabebSScott Wood kernel_size = load_elf(params->kernel_filename, NULL, NULL, 592e6eaabebSScott Wood &elf_entry, &elf_lowaddr, NULL, 1, 593e6eaabebSScott Wood ELF_MACHINE, 0); 5941db09b84Saurel32 entry = elf_entry; 5951db09b84Saurel32 loadaddr = elf_lowaddr; 5961db09b84Saurel32 } 5971db09b84Saurel32 /* XXX try again as binary */ 5981db09b84Saurel32 if (kernel_size < 0) { 5991db09b84Saurel32 fprintf(stderr, "qemu: could not load kernel '%s'\n", 600e6eaabebSScott Wood params->kernel_filename); 6011db09b84Saurel32 exit(1); 6021db09b84Saurel32 } 6031db09b84Saurel32 } 6041db09b84Saurel32 6051db09b84Saurel32 /* Load initrd. */ 606e6eaabebSScott Wood if (params->initrd_filename) { 6077e7ec2d2SScott Wood initrd_base = (loadaddr + kernel_size + INITRD_LOAD_PAD) & 6087e7ec2d2SScott Wood ~INITRD_PAD_MASK; 609e6eaabebSScott Wood initrd_size = load_image_targphys(params->initrd_filename, initrd_base, 610d7585251Spbrook ram_size - initrd_base); 6111db09b84Saurel32 6121db09b84Saurel32 if (initrd_size < 0) { 6131db09b84Saurel32 fprintf(stderr, "qemu: could not load initial ram disk '%s'\n", 614e6eaabebSScott Wood params->initrd_filename); 6151db09b84Saurel32 exit(1); 6161db09b84Saurel32 } 6171db09b84Saurel32 } 6181db09b84Saurel32 6191db09b84Saurel32 /* If we're loading a kernel directly, we must load the device tree too. */ 620e6eaabebSScott Wood if (params->kernel_filename) { 6215c145dacSAlexander Graf struct boot_info *boot_info; 622cba2026aSAlexander Graf int dt_size; 6235c145dacSAlexander Graf 624cba2026aSAlexander Graf dt_base = (loadaddr + kernel_size + DTC_LOAD_PAD) & ~DTC_PAD_MASK; 625e6eaabebSScott Wood dt_size = ppce500_load_device_tree(env, params, dt_base, initrd_base, 626e6eaabebSScott Wood initrd_size); 627cba2026aSAlexander Graf if (dt_size < 0) { 6281db09b84Saurel32 fprintf(stderr, "couldn't load device tree\n"); 6291db09b84Saurel32 exit(1); 6301db09b84Saurel32 } 6311db09b84Saurel32 632e61c36d5SAlexander Graf boot_info = env->load_info; 6333b989d49SAlexander Graf boot_info->entry = entry; 6343b989d49SAlexander Graf boot_info->dt_base = dt_base; 635cba2026aSAlexander Graf boot_info->dt_size = dt_size; 6361db09b84Saurel32 } 6371db09b84Saurel32 6383b989d49SAlexander Graf if (kvm_enabled()) { 6391db09b84Saurel32 kvmppc_init(); 6403b989d49SAlexander Graf } 6411db09b84Saurel32 } 6423eddc1beSBharat Bhushan 6433eddc1beSBharat Bhushan static int e500_ccsr_initfn(SysBusDevice *dev) 6443eddc1beSBharat Bhushan { 6453eddc1beSBharat Bhushan PPCE500CCSRState *ccsr; 6463eddc1beSBharat Bhushan 6473eddc1beSBharat Bhushan ccsr = CCSR(dev); 6483eddc1beSBharat Bhushan memory_region_init(&ccsr->ccsr_space, "e500-ccsr", 6493eddc1beSBharat Bhushan MPC8544_CCSRBAR_SIZE); 6503eddc1beSBharat Bhushan return 0; 6513eddc1beSBharat Bhushan } 6523eddc1beSBharat Bhushan 6533eddc1beSBharat Bhushan static void e500_ccsr_class_init(ObjectClass *klass, void *data) 6543eddc1beSBharat Bhushan { 6553eddc1beSBharat Bhushan SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); 6563eddc1beSBharat Bhushan k->init = e500_ccsr_initfn; 6573eddc1beSBharat Bhushan } 6583eddc1beSBharat Bhushan 6593eddc1beSBharat Bhushan static const TypeInfo e500_ccsr_info = { 6603eddc1beSBharat Bhushan .name = TYPE_CCSR, 6613eddc1beSBharat Bhushan .parent = TYPE_SYS_BUS_DEVICE, 6623eddc1beSBharat Bhushan .instance_size = sizeof(PPCE500CCSRState), 6633eddc1beSBharat Bhushan .class_init = e500_ccsr_class_init, 6643eddc1beSBharat Bhushan }; 6653eddc1beSBharat Bhushan 6663eddc1beSBharat Bhushan static void e500_register_types(void) 6673eddc1beSBharat Bhushan { 6683eddc1beSBharat Bhushan type_register_static(&e500_ccsr_info); 6693eddc1beSBharat Bhushan } 6703eddc1beSBharat Bhushan 6713eddc1beSBharat Bhushan type_init(e500_register_types) 672