e500.c 35.4 KB
Newer Older
1
/*
2
 * QEMU PowerPC e500-based platforms
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
 *
 * Copyright (C) 2009 Freescale Semiconductor, Inc. All rights reserved.
 *
 * Author: Yu Liu,     <yu.liu@freescale.com>
 *
 * This file is derived from hw/ppc440_bamboo.c,
 * the copyright for that material belongs to the original owners.
 *
 * This is free software; you can redistribute it and/or modify
 * it under the terms of  the GNU General  Public License as published by
 * the Free Software Foundation;  either version 2 of the  License, or
 * (at your option) any later version.
 */

#include "config.h"
#include "qemu-common.h"
19
#include "e500.h"
20
#include "e500-ccsr.h"
P
Paolo Bonzini 已提交
21
#include "net/net.h"
22
#include "qemu/config-file.h"
23
#include "hw/hw.h"
P
Paolo Bonzini 已提交
24
#include "hw/char/serial.h"
25
#include "hw/pci/pci.h"
26
#include "hw/boards.h"
27 28
#include "sysemu/sysemu.h"
#include "sysemu/kvm.h"
29
#include "kvm_ppc.h"
30
#include "sysemu/device_tree.h"
P
Paolo Bonzini 已提交
31 32
#include "hw/ppc/openpic.h"
#include "hw/ppc/ppc.h"
33
#include "hw/loader.h"
B
Blue Swirl 已提交
34
#include "elf.h"
35
#include "hw/sysbus.h"
36
#include "exec/address-spaces.h"
37
#include "qemu/host-utils.h"
P
Paolo Bonzini 已提交
38
#include "hw/pci-host/ppce500.h"
39 40
#include "qemu/error-report.h"
#include "hw/platform-bus.h"
41
#include "hw/net/fsl_etsec/etsec.h"
42

43
#define EPAPR_MAGIC                (0x45504150)
44
#define BINARY_DEVICE_TREE_FILE    "mpc8544ds.dtb"
S
Scott Wood 已提交
45
#define DTC_LOAD_PAD               0x1800000
46
#define DTC_PAD_MASK               0xFFFFF
47
#define DTB_MAX_SIZE               (8 * 1024 * 1024)
48 49
#define INITRD_LOAD_PAD            0x2000000
#define INITRD_PAD_MASK            0xFFFFFF
50 51 52

#define RAM_SIZES_ALIGN            (64UL << 20)

53
/* TODO: parameterize */
54
#define MPC8544_CCSRBAR_SIZE       0x00100000ULL
B
Bharat Bhushan 已提交
55
#define MPC8544_MPIC_REGS_OFFSET   0x40000ULL
A
Alexander Graf 已提交
56
#define MPC8544_MSI_REGS_OFFSET   0x41600ULL
B
Bharat Bhushan 已提交
57 58 59
#define MPC8544_SERIAL0_REGS_OFFSET 0x4500ULL
#define MPC8544_SERIAL1_REGS_OFFSET 0x4600ULL
#define MPC8544_PCI_REGS_OFFSET    0x8000ULL
60
#define MPC8544_PCI_REGS_SIZE      0x1000ULL
B
Bharat Bhushan 已提交
61
#define MPC8544_UTIL_OFFSET        0xe0000ULL
62
#define MPC8XXX_GPIO_OFFSET        0x000FF000ULL
63
#define MPC8XXX_GPIO_IRQ           47
64

65 66 67
struct boot_info
{
    uint32_t dt_base;
68
    uint32_t dt_size;
69 70 71
    uint32_t entry;
};

72 73
static uint32_t *pci_map_create(void *fdt, uint32_t mpic, int first_slot,
                                int nr_slots, int *len)
74
{
75 76 77
    int i = 0;
    int slot;
    int pci_irq;
78
    int host_irq;
79 80 81 82 83 84 85 86 87 88 89 90 91
    int last_slot = first_slot + nr_slots;
    uint32_t *pci_map;

    *len = nr_slots * 4 * 7 * sizeof(uint32_t);
    pci_map = g_malloc(*len);

    for (slot = first_slot; slot < last_slot; slot++) {
        for (pci_irq = 0; pci_irq < 4; pci_irq++) {
            pci_map[i++] = cpu_to_be32(slot << 11);
            pci_map[i++] = cpu_to_be32(0x0);
            pci_map[i++] = cpu_to_be32(0x0);
            pci_map[i++] = cpu_to_be32(pci_irq + 1);
            pci_map[i++] = cpu_to_be32(mpic);
92 93
            host_irq = ppce500_pci_map_irq_slot(slot, pci_irq);
            pci_map[i++] = cpu_to_be32(host_irq + 1);
94 95
            pci_map[i++] = cpu_to_be32(0x1);
        }
96
    }
97 98 99 100

    assert((i * sizeof(uint32_t)) == *len);

    return pci_map;
101 102
}

103 104 105 106 107 108 109
static void dt_serial_create(void *fdt, unsigned long long offset,
                             const char *soc, const char *mpic,
                             const char *alias, int idx, bool defcon)
{
    char ser[128];

    snprintf(ser, sizeof(ser), "%s/serial@%llx", soc, offset);
110 111 112 113 114 115 116 117 118
    qemu_fdt_add_subnode(fdt, ser);
    qemu_fdt_setprop_string(fdt, ser, "device_type", "serial");
    qemu_fdt_setprop_string(fdt, ser, "compatible", "ns16550");
    qemu_fdt_setprop_cells(fdt, ser, "reg", offset, 0x100);
    qemu_fdt_setprop_cell(fdt, ser, "cell-index", idx);
    qemu_fdt_setprop_cell(fdt, ser, "clock-frequency", 0);
    qemu_fdt_setprop_cells(fdt, ser, "interrupts", 42, 2);
    qemu_fdt_setprop_phandle(fdt, ser, "interrupt-parent", mpic);
    qemu_fdt_setprop_string(fdt, "/aliases", alias, ser);
119 120

    if (defcon) {
121
        qemu_fdt_setprop_string(fdt, "/chosen", "linux,stdout-path", ser);
122 123 124
    }
}

125 126 127 128 129
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);
130 131
    gchar *poweroff = g_strdup_printf("%s/power-off", soc);
    int gpio_ph;
132 133 134 135 136 137 138 139

    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);
140 141 142 143 144 145 146 147
    gpio_ph = qemu_fdt_alloc_phandle(fdt);
    qemu_fdt_setprop_cell(fdt, node, "phandle", gpio_ph);
    qemu_fdt_setprop_cell(fdt, node, "linux,phandle", gpio_ph);

    /* Power Off Pin */
    qemu_fdt_add_subnode(fdt, poweroff);
    qemu_fdt_setprop_string(fdt, poweroff, "compatible", "gpio-poweroff");
    qemu_fdt_setprop_cells(fdt, poweroff, "gpios", gpio_ph, 0, 0);
148 149

    g_free(node);
150
    g_free(poweroff);
151 152
}

153 154 155 156 157 158 159 160
typedef struct PlatformDevtreeData {
    void *fdt;
    const char *mpic;
    int irq_start;
    const char *node;
    PlatformBusDevice *pbus;
} PlatformDevtreeData;

161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197
static int create_devtree_etsec(SysBusDevice *sbdev, PlatformDevtreeData *data)
{
    eTSEC *etsec = ETSEC_COMMON(sbdev);
    PlatformBusDevice *pbus = data->pbus;
    hwaddr mmio0 = platform_bus_get_mmio_addr(pbus, sbdev, 0);
    int irq0 = platform_bus_get_irqn(pbus, sbdev, 0);
    int irq1 = platform_bus_get_irqn(pbus, sbdev, 1);
    int irq2 = platform_bus_get_irqn(pbus, sbdev, 2);
    gchar *node = g_strdup_printf("/platform/ethernet@%"PRIx64, mmio0);
    gchar *group = g_strdup_printf("%s/queue-group", node);
    void *fdt = data->fdt;

    assert((int64_t)mmio0 >= 0);
    assert(irq0 >= 0);
    assert(irq1 >= 0);
    assert(irq2 >= 0);

    qemu_fdt_add_subnode(fdt, node);
    qemu_fdt_setprop_string(fdt, node, "device_type", "network");
    qemu_fdt_setprop_string(fdt, node, "compatible", "fsl,etsec2");
    qemu_fdt_setprop_string(fdt, node, "model", "eTSEC");
    qemu_fdt_setprop(fdt, node, "local-mac-address", etsec->conf.macaddr.a, 6);
    qemu_fdt_setprop_cells(fdt, node, "fixed-link", 0, 1, 1000, 0, 0);

    qemu_fdt_add_subnode(fdt, group);
    qemu_fdt_setprop_cells(fdt, group, "reg", mmio0, 0x1000);
    qemu_fdt_setprop_cells(fdt, group, "interrupts",
        data->irq_start + irq0, 0x2,
        data->irq_start + irq1, 0x2,
        data->irq_start + irq2, 0x2);

    g_free(node);
    g_free(group);

    return 0;
}

198 199 200 201 202
static int sysbus_device_create_devtree(SysBusDevice *sbdev, void *opaque)
{
    PlatformDevtreeData *data = opaque;
    bool matched = false;

203 204 205 206 207
    if (object_dynamic_cast(OBJECT(sbdev), TYPE_ETSEC_COMMON)) {
        create_devtree_etsec(sbdev, data);
        matched = true;
    }

208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260
    if (!matched) {
        error_report("Device %s is not supported by this machine yet.",
                     qdev_fw_name(DEVICE(sbdev)));
        exit(1);
    }

    return 0;
}

static void platform_bus_create_devtree(PPCE500Params *params, void *fdt,
                                        const char *mpic)
{
    gchar *node = g_strdup_printf("/platform@%"PRIx64, params->platform_bus_base);
    const char platcomp[] = "qemu,platform\0simple-bus";
    uint64_t addr = params->platform_bus_base;
    uint64_t size = params->platform_bus_size;
    int irq_start = params->platform_bus_first_irq;
    PlatformBusDevice *pbus;
    DeviceState *dev;

    /* Create a /platform node that we can put all devices into */

    qemu_fdt_add_subnode(fdt, node);
    qemu_fdt_setprop(fdt, node, "compatible", platcomp, sizeof(platcomp));

    /* Our platform bus region is less than 32bit big, so 1 cell is enough for
       address and size */
    qemu_fdt_setprop_cells(fdt, node, "#size-cells", 1);
    qemu_fdt_setprop_cells(fdt, node, "#address-cells", 1);
    qemu_fdt_setprop_cells(fdt, node, "ranges", 0, addr >> 32, addr, size);

    qemu_fdt_setprop_phandle(fdt, node, "interrupt-parent", mpic);

    dev = qdev_find_recursive(sysbus_get_default(), TYPE_PLATFORM_BUS_DEVICE);
    pbus = PLATFORM_BUS_DEVICE(dev);

    /* We can only create dt nodes for dynamic devices when they're ready */
    if (pbus->done_gathering) {
        PlatformDevtreeData data = {
            .fdt = fdt,
            .mpic = mpic,
            .irq_start = irq_start,
            .node = node,
            .pbus = pbus,
        };

        /* Loop through all dynamic sysbus devices and create nodes for them */
        foreach_dynamic_sysbus_device(sysbus_device_create_devtree, &data);
    }

    g_free(node);
}

261
static int ppce500_load_device_tree(MachineState *machine,
262
                                    PPCE500Params *params,
A
Avi Kivity 已提交
263 264
                                    hwaddr addr,
                                    hwaddr initrd_base,
265
                                    hwaddr initrd_size,
266 267
                                    hwaddr kernel_base,
                                    hwaddr kernel_size,
268
                                    bool dry_run)
269
{
270
    CPUPPCState *env = first_cpu->env_ptr;
271
    int ret = -1;
272
    uint64_t mem_reg_property[] = { 0, cpu_to_be64(machine->ram_size) };
273
    int fdt_size;
274
    void *fdt;
275
    uint8_t hypercall[16];
276 277
    uint32_t clock_freq = 400000000;
    uint32_t tb_freq = 400000000;
278
    int i;
279
    char compatible_sb[] = "fsl,mpc8544-immr\0simple-bus";
280
    char soc[128];
281 282
    char mpic[128];
    uint32_t mpic_ph;
A
Alexander Graf 已提交
283
    uint32_t msi_ph;
284
    char gutil[128];
285
    char pci[128];
A
Alexander Graf 已提交
286
    char msi[128];
287 288
    uint32_t *pci_map = NULL;
    int len;
289 290
    uint32_t pci_ranges[14] =
        {
291 292
            0x2000000, 0x0, params->pci_mmio_bus_base,
            params->pci_mmio_base >> 32, params->pci_mmio_base,
293 294 295
            0x0, 0x20000000,

            0x1000000, 0x0, 0x0,
296
            params->pci_pio_base >> 32, params->pci_pio_base,
297 298
            0x0, 0x10000,
        };
299 300 301
    QemuOpts *machine_opts = qemu_get_machine_opts();
    const char *dtb_file = qemu_opt_get(machine_opts, "dtb");
    const char *toplevel_compat = qemu_opt_get(machine_opts, "dt_compatible");
302 303 304 305 306 307 308 309 310 311 312 313 314 315

    if (dtb_file) {
        char *filename;
        filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, dtb_file);
        if (!filename) {
            goto out;
        }

        fdt = load_device_tree(filename, &fdt_size);
        if (!fdt) {
            goto out;
        }
        goto done;
    }
316

317
    fdt = create_device_tree(&fdt_size);
P
Paul Brook 已提交
318 319 320
    if (fdt == NULL) {
        goto out;
    }
321 322

    /* Manipulate device tree in memory. */
323 324
    qemu_fdt_setprop_cell(fdt, "/", "#address-cells", 2);
    qemu_fdt_setprop_cell(fdt, "/", "#size-cells", 2);
325

326 327 328 329
    qemu_fdt_add_subnode(fdt, "/memory");
    qemu_fdt_setprop_string(fdt, "/memory", "device_type", "memory");
    qemu_fdt_setprop(fdt, "/memory", "reg", mem_reg_property,
                     sizeof(mem_reg_property));
330

331
    qemu_fdt_add_subnode(fdt, "/chosen");
332
    if (initrd_size) {
333 334
        ret = qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-start",
                                    initrd_base);
335 336 337
        if (ret < 0) {
            fprintf(stderr, "couldn't set /chosen/linux,initrd-start\n");
        }
338

339 340
        ret = qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-end",
                                    (initrd_base + initrd_size));
341 342 343
        if (ret < 0) {
            fprintf(stderr, "couldn't set /chosen/linux,initrd-end\n");
        }
344 345 346 347 348 349 350

    }

    if (kernel_base != -1ULL) {
        qemu_fdt_setprop_cells(fdt, "/chosen", "qemu,boot-kernel",
                                     kernel_base >> 32, kernel_base,
                                     kernel_size >> 32, kernel_size);
351
    }
352

353
    ret = qemu_fdt_setprop_string(fdt, "/chosen", "bootargs",
354
                                      machine->kernel_cmdline);
355 356 357 358
    if (ret < 0)
        fprintf(stderr, "couldn't set /chosen/bootargs\n");

    if (kvm_enabled()) {
359 360 361
        /* Read out host's frequencies */
        clock_freq = kvmppc_get_clockfreq();
        tb_freq = kvmppc_get_tbfreq();
362 363

        /* indicate KVM hypercall interface */
364 365 366
        qemu_fdt_add_subnode(fdt, "/hypervisor");
        qemu_fdt_setprop_string(fdt, "/hypervisor", "compatible",
                                "linux,kvm");
367
        kvmppc_get_hypercall(env, hypercall, sizeof(hypercall));
368 369
        qemu_fdt_setprop(fdt, "/hypervisor", "hcall-instructions",
                         hypercall, sizeof(hypercall));
370 371
        /* if KVM supports the idle hcall, set property indicating this */
        if (kvmppc_get_hasidle(env)) {
372
            qemu_fdt_setprop(fdt, "/hypervisor", "has-idle", NULL, 0);
373
        }
374
    }
375

376
    /* Create CPU nodes */
377 378 379
    qemu_fdt_add_subnode(fdt, "/cpus");
    qemu_fdt_setprop_cell(fdt, "/cpus", "#address-cells", 1);
    qemu_fdt_setprop_cell(fdt, "/cpus", "#size-cells", 0);
380

381 382 383
    /* We need to generate the cpu nodes in reverse order, so Linux can pick
       the first node as boot node and be happy */
    for (i = smp_cpus - 1; i >= 0; i--) {
384
        CPUState *cpu;
385
        PowerPCCPU *pcpu;
386
        char cpu_name[128];
387
        uint64_t cpu_release_addr = params->spin_base + (i * 0x20);
388

389
        cpu = qemu_get_cpu(i);
390
        if (cpu == NULL) {
391 392
            continue;
        }
393
        env = cpu->env_ptr;
394
        pcpu = POWERPC_CPU(cpu);
395

396
        snprintf(cpu_name, sizeof(cpu_name), "/cpus/PowerPC,8544@%x",
397
                 ppc_get_vcpu_dt_id(pcpu));
398 399 400 401
        qemu_fdt_add_subnode(fdt, cpu_name);
        qemu_fdt_setprop_cell(fdt, cpu_name, "clock-frequency", clock_freq);
        qemu_fdt_setprop_cell(fdt, cpu_name, "timebase-frequency", tb_freq);
        qemu_fdt_setprop_string(fdt, cpu_name, "device_type", "cpu");
402 403
        qemu_fdt_setprop_cell(fdt, cpu_name, "reg",
                              ppc_get_vcpu_dt_id(pcpu));
404 405 406 407 408 409 410
        qemu_fdt_setprop_cell(fdt, cpu_name, "d-cache-line-size",
                              env->dcache_line_size);
        qemu_fdt_setprop_cell(fdt, cpu_name, "i-cache-line-size",
                              env->icache_line_size);
        qemu_fdt_setprop_cell(fdt, cpu_name, "d-cache-size", 0x8000);
        qemu_fdt_setprop_cell(fdt, cpu_name, "i-cache-size", 0x8000);
        qemu_fdt_setprop_cell(fdt, cpu_name, "bus-frequency", 0);
411
        if (cpu->cpu_index) {
412 413 414 415 416
            qemu_fdt_setprop_string(fdt, cpu_name, "status", "disabled");
            qemu_fdt_setprop_string(fdt, cpu_name, "enable-method",
                                    "spin-table");
            qemu_fdt_setprop_u64(fdt, cpu_name, "cpu-release-addr",
                                 cpu_release_addr);
417
        } else {
418
            qemu_fdt_setprop_string(fdt, cpu_name, "status", "okay");
419
        }
420 421
    }

422
    qemu_fdt_add_subnode(fdt, "/aliases");
423
    /* XXX These should go into their respective devices' code */
424
    snprintf(soc, sizeof(soc), "/soc@%"PRIx64, params->ccsrbar_base);
425 426 427 428 429 430 431
    qemu_fdt_add_subnode(fdt, soc);
    qemu_fdt_setprop_string(fdt, soc, "device_type", "soc");
    qemu_fdt_setprop(fdt, soc, "compatible", compatible_sb,
                     sizeof(compatible_sb));
    qemu_fdt_setprop_cell(fdt, soc, "#address-cells", 1);
    qemu_fdt_setprop_cell(fdt, soc, "#size-cells", 1);
    qemu_fdt_setprop_cells(fdt, soc, "ranges", 0x0,
432
                           params->ccsrbar_base >> 32, params->ccsrbar_base,
433
                           MPC8544_CCSRBAR_SIZE);
434
    /* XXX should contain a reasonable value */
435
    qemu_fdt_setprop_cell(fdt, soc, "bus-frequency", 0);
436

B
Bharat Bhushan 已提交
437
    snprintf(mpic, sizeof(mpic), "%s/pic@%llx", soc, MPC8544_MPIC_REGS_OFFSET);
438 439 440 441 442 443 444 445 446 447 448
    qemu_fdt_add_subnode(fdt, mpic);
    qemu_fdt_setprop_string(fdt, mpic, "device_type", "open-pic");
    qemu_fdt_setprop_string(fdt, mpic, "compatible", "fsl,mpic");
    qemu_fdt_setprop_cells(fdt, mpic, "reg", MPC8544_MPIC_REGS_OFFSET,
                           0x40000);
    qemu_fdt_setprop_cell(fdt, mpic, "#address-cells", 0);
    qemu_fdt_setprop_cell(fdt, mpic, "#interrupt-cells", 2);
    mpic_ph = qemu_fdt_alloc_phandle(fdt);
    qemu_fdt_setprop_cell(fdt, mpic, "phandle", mpic_ph);
    qemu_fdt_setprop_cell(fdt, mpic, "linux,phandle", mpic_ph);
    qemu_fdt_setprop(fdt, mpic, "interrupt-controller", NULL, 0);
449

450 451 452 453 454
    /*
     * We have to generate ser1 first, because Linux takes the first
     * device it finds in the dt as serial output device. And we generate
     * devices in reverse order to the dt.
     */
455 456 457 458 459 460 461 462 463
    if (serial_hds[1]) {
        dt_serial_create(fdt, MPC8544_SERIAL1_REGS_OFFSET,
                         soc, mpic, "serial1", 1, false);
    }

    if (serial_hds[0]) {
        dt_serial_create(fdt, MPC8544_SERIAL0_REGS_OFFSET,
                         soc, mpic, "serial0", 0, true);
    }
464

465
    snprintf(gutil, sizeof(gutil), "%s/global-utilities@%llx", soc,
B
Bharat Bhushan 已提交
466
             MPC8544_UTIL_OFFSET);
467 468 469 470
    qemu_fdt_add_subnode(fdt, gutil);
    qemu_fdt_setprop_string(fdt, gutil, "compatible", "fsl,mpc8544-guts");
    qemu_fdt_setprop_cells(fdt, gutil, "reg", MPC8544_UTIL_OFFSET, 0x1000);
    qemu_fdt_setprop(fdt, gutil, "fsl,has-rstcr", NULL, 0);
471

A
Alexander Graf 已提交
472
    snprintf(msi, sizeof(msi), "/%s/msi@%llx", soc, MPC8544_MSI_REGS_OFFSET);
473 474 475 476 477 478 479
    qemu_fdt_add_subnode(fdt, msi);
    qemu_fdt_setprop_string(fdt, msi, "compatible", "fsl,mpic-msi");
    qemu_fdt_setprop_cells(fdt, msi, "reg", MPC8544_MSI_REGS_OFFSET, 0x200);
    msi_ph = qemu_fdt_alloc_phandle(fdt);
    qemu_fdt_setprop_cells(fdt, msi, "msi-available-ranges", 0x0, 0x100);
    qemu_fdt_setprop_phandle(fdt, msi, "interrupt-parent", mpic);
    qemu_fdt_setprop_cells(fdt, msi, "interrupts",
A
Alexander Graf 已提交
480 481 482 483 484 485 486 487
        0xe0, 0x0,
        0xe1, 0x0,
        0xe2, 0x0,
        0xe3, 0x0,
        0xe4, 0x0,
        0xe5, 0x0,
        0xe6, 0x0,
        0xe7, 0x0);
488 489
    qemu_fdt_setprop_cell(fdt, msi, "phandle", msi_ph);
    qemu_fdt_setprop_cell(fdt, msi, "linux,phandle", msi_ph);
A
Alexander Graf 已提交
490

491 492
    snprintf(pci, sizeof(pci), "/pci@%llx",
             params->ccsrbar_base + MPC8544_PCI_REGS_OFFSET);
493 494 495 496 497 498 499
    qemu_fdt_add_subnode(fdt, pci);
    qemu_fdt_setprop_cell(fdt, pci, "cell-index", 0);
    qemu_fdt_setprop_string(fdt, pci, "compatible", "fsl,mpc8540-pci");
    qemu_fdt_setprop_string(fdt, pci, "device_type", "pci");
    qemu_fdt_setprop_cells(fdt, pci, "interrupt-map-mask", 0xf800, 0x0,
                           0x0, 0x7);
    pci_map = pci_map_create(fdt, qemu_fdt_get_phandle(fdt, mpic),
500 501
                             params->pci_first_slot, params->pci_nr_slots,
                             &len);
502 503 504 505
    qemu_fdt_setprop(fdt, pci, "interrupt-map", pci_map, len);
    qemu_fdt_setprop_phandle(fdt, pci, "interrupt-parent", mpic);
    qemu_fdt_setprop_cells(fdt, pci, "interrupts", 24, 2);
    qemu_fdt_setprop_cells(fdt, pci, "bus-range", 0, 255);
506
    for (i = 0; i < 14; i++) {
507 508
        pci_ranges[i] = cpu_to_be32(pci_ranges[i]);
    }
509 510
    qemu_fdt_setprop_cell(fdt, pci, "fsl,msi", msi_ph);
    qemu_fdt_setprop(fdt, pci, "ranges", pci_ranges, sizeof(pci_ranges));
511 512 513 514
    qemu_fdt_setprop_cells(fdt, pci, "reg",
                           (params->ccsrbar_base + MPC8544_PCI_REGS_OFFSET) >> 32,
                           (params->ccsrbar_base + MPC8544_PCI_REGS_OFFSET),
                           0, 0x1000);
515 516 517 518 519
    qemu_fdt_setprop_cell(fdt, pci, "clock-frequency", 66666666);
    qemu_fdt_setprop_cell(fdt, pci, "#interrupt-cells", 1);
    qemu_fdt_setprop_cell(fdt, pci, "#size-cells", 2);
    qemu_fdt_setprop_cell(fdt, pci, "#address-cells", 3);
    qemu_fdt_setprop_string(fdt, "/aliases", "pci0", pci);
520

521 522 523 524
    if (params->has_mpc8xxx_gpio) {
        create_dt_mpc8xxx_gpio(fdt, soc, mpic);
    }

525 526 527 528
    if (params->has_platform_bus) {
        platform_bus_create_devtree(params, fdt, mpic);
    }

529 530 531
    params->fixup_devtree(params, fdt);

    if (toplevel_compat) {
532 533
        qemu_fdt_setprop(fdt, "/", "compatible", toplevel_compat,
                         strlen(toplevel_compat) + 1);
534 535
    }

536
done:
537
    if (!dry_run) {
538
        qemu_fdt_dumpdtb(fdt, fdt_size);
539
        cpu_physical_memory_write(addr, fdt, fdt_size);
540 541
    }
    ret = fdt_size;
542

543
out:
544
    g_free(pci_map);
545

546
    return ret;
547 548
}

549
typedef struct DeviceTreeParams {
550
    MachineState *machine;
551 552 553 554
    PPCE500Params params;
    hwaddr addr;
    hwaddr initrd_base;
    hwaddr initrd_size;
555 556
    hwaddr kernel_base;
    hwaddr kernel_size;
557
    Notifier notifier;
558 559 560 561 562
} DeviceTreeParams;

static void ppce500_reset_device_tree(void *opaque)
{
    DeviceTreeParams *p = opaque;
563
    ppce500_load_device_tree(p->machine, &p->params, p->addr, p->initrd_base,
564 565
                             p->initrd_size, p->kernel_base, p->kernel_size,
                             false);
566 567
}

568 569 570 571 572 573
static void ppce500_init_notify(Notifier *notifier, void *data)
{
    DeviceTreeParams *p = container_of(notifier, DeviceTreeParams, notifier);
    ppce500_reset_device_tree(p);
}

574
static int ppce500_prep_device_tree(MachineState *machine,
575 576 577
                                    PPCE500Params *params,
                                    hwaddr addr,
                                    hwaddr initrd_base,
578 579 580
                                    hwaddr initrd_size,
                                    hwaddr kernel_base,
                                    hwaddr kernel_size)
581 582
{
    DeviceTreeParams *p = g_new(DeviceTreeParams, 1);
583
    p->machine = machine;
584 585 586 587
    p->params = *params;
    p->addr = addr;
    p->initrd_base = initrd_base;
    p->initrd_size = initrd_size;
588 589
    p->kernel_base = kernel_base;
    p->kernel_size = kernel_size;
590 591

    qemu_register_reset(ppce500_reset_device_tree, p);
592 593
    p->notifier.notify = ppce500_init_notify;
    qemu_add_machine_init_done_notifier(&p->notifier);
594 595

    /* Issue the device tree loader once, so that we get the size of the blob */
596
    return ppce500_load_device_tree(machine, params, addr, initrd_base,
597 598
                                    initrd_size, kernel_base, kernel_size,
                                    true);
599 600
}

601
/* Create -kernel TLB entries for BookE.  */
A
Avi Kivity 已提交
602
static inline hwaddr booke206_page_size_to_tlb(uint64_t size)
603
{
604
    return 63 - clz64(size >> 10);
605 606
}

607
static int booke206_initial_map_tsize(CPUPPCState *env)
608
{
609
    struct boot_info *bi = env->load_info;
610
    hwaddr dt_end;
611 612 613 614 615 616
    int ps;

    /* Our initial TLB entry needs to cover everything from 0 to
       the device tree top */
    dt_end = bi->dt_base + bi->dt_size;
    ps = booke206_page_size_to_tlb(dt_end) + 1;
617 618 619 620
    if (ps & 1) {
        /* e500v2 can only do even TLB size bits */
        ps++;
    }
621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638
    return ps;
}

static uint64_t mmubooke_initial_mapsize(CPUPPCState *env)
{
    int tsize;

    tsize = booke206_initial_map_tsize(env);
    return (1ULL << 10 << tsize);
}

static void mmubooke_create_initial_mapping(CPUPPCState *env)
{
    ppcmas_tlb_t *tlb = booke206_get_tlbm(env, 1, 0, 0);
    hwaddr size;
    int ps;

    ps = booke206_initial_map_tsize(env);
639
    size = (ps << MAS1_TSIZE_SHIFT);
640
    tlb->mas1 = MAS1_VALID | size;
641 642
    tlb->mas2 = 0;
    tlb->mas7_3 = 0;
643
    tlb->mas7_3 |= MAS3_UR | MAS3_UW | MAS3_UX | MAS3_SR | MAS3_SW | MAS3_SX;
S
Scott Wood 已提交
644 645

    env->tlb_dirty = true;
646 647
}

648
static void ppce500_cpu_reset_sec(void *opaque)
A
Alexander Graf 已提交
649
{
650
    PowerPCCPU *cpu = opaque;
651
    CPUState *cs = CPU(cpu);
A
Alexander Graf 已提交
652

653
    cpu_reset(cs);
A
Alexander Graf 已提交
654 655 656

    /* Secondary CPU starts in halted state for now. Needs to change when
       implementing non-kernel boot. */
657
    cs->halted = 1;
658
    cs->exception_index = EXCP_HLT;
659 660
}

661
static void ppce500_cpu_reset(void *opaque)
662
{
663
    PowerPCCPU *cpu = opaque;
664
    CPUState *cs = CPU(cpu);
665
    CPUPPCState *env = &cpu->env;
666 667
    struct boot_info *bi = env->load_info;

668
    cpu_reset(cs);
669 670

    /* Set initial guest state. */
671
    cs->halted = 0;
672 673
    env->gpr[1] = (16<<20) - 8;
    env->gpr[3] = bi->dt_base;
674 675 676 677 678 679
    env->gpr[4] = 0;
    env->gpr[5] = 0;
    env->gpr[6] = EPAPR_MAGIC;
    env->gpr[7] = mmubooke_initial_mapsize(env);
    env->gpr[8] = 0;
    env->gpr[9] = 0;
680
    env->nip = bi->entry;
681
    mmubooke_create_initial_mapping(env);
682 683
}

S
Scott Wood 已提交
684 685
static DeviceState *ppce500_init_mpic_qemu(PPCE500Params *params,
                                           qemu_irq **irqs)
686 687 688 689 690
{
    DeviceState *dev;
    SysBusDevice *s;
    int i, j, k;

A
Andreas Färber 已提交
691
    dev = qdev_create(NULL, TYPE_OPENPIC);
692
    qdev_prop_set_uint32(dev, "model", params->mpic_version);
S
Scott Wood 已提交
693 694
    qdev_prop_set_uint32(dev, "nb_cpus", smp_cpus);

695 696 697 698 699 700 701 702 703 704
    qdev_init_nofail(dev);
    s = SYS_BUS_DEVICE(dev);

    k = 0;
    for (i = 0; i < smp_cpus; i++) {
        for (j = 0; j < OPENPIC_OUTPUT_NB; j++) {
            sysbus_connect_irq(s, k++, irqs[i][j]);
        }
    }

S
Scott Wood 已提交
705 706 707 708 709 710 711 712 713 714
    return dev;
}

static DeviceState *ppce500_init_mpic_kvm(PPCE500Params *params,
                                          qemu_irq **irqs)
{
    DeviceState *dev;
    CPUState *cs;
    int r;

715
    dev = qdev_create(NULL, TYPE_KVM_OPENPIC);
S
Scott Wood 已提交
716 717 718 719 720 721 722
    qdev_prop_set_uint32(dev, "model", params->mpic_version);

    r = qdev_init(dev);
    if (r) {
        return NULL;
    }

A
Andreas Färber 已提交
723
    CPU_FOREACH(cs) {
S
Scott Wood 已提交
724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741
        if (kvm_openpic_connect_vcpu(dev, cs)) {
            fprintf(stderr, "%s: failed to connect vcpu to irqchip\n",
                    __func__);
            abort();
        }
    }

    return dev;
}

static qemu_irq *ppce500_init_mpic(PPCE500Params *params, MemoryRegion *ccsr,
                                   qemu_irq **irqs)
{
    qemu_irq *mpic;
    DeviceState *dev = NULL;
    SysBusDevice *s;
    int i;

742
    mpic = g_new0(qemu_irq, 256);
S
Scott Wood 已提交
743 744

    if (kvm_enabled()) {
745 746
        QemuOpts *machine_opts = qemu_get_machine_opts();
        bool irqchip_allowed = qemu_opt_get_bool(machine_opts,
S
Scott Wood 已提交
747
                                                "kernel_irqchip", true);
748 749
        bool irqchip_required = qemu_opt_get_bool(machine_opts,
                                                  "kernel_irqchip", false);
S
Scott Wood 已提交
750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765

        if (irqchip_allowed) {
            dev = ppce500_init_mpic_kvm(params, irqs);
        }

        if (irqchip_required && !dev) {
            fprintf(stderr, "%s: irqchip requested but unavailable\n",
                    __func__);
            abort();
        }
    }

    if (!dev) {
        dev = ppce500_init_mpic_qemu(params, irqs);
    }

766 767 768 769
    for (i = 0; i < 256; i++) {
        mpic[i] = qdev_get_gpio_in(dev, i);
    }

S
Scott Wood 已提交
770
    s = SYS_BUS_DEVICE(dev);
771 772 773 774 775 776
    memory_region_add_subregion(ccsr, MPC8544_MPIC_REGS_OFFSET,
                                s->mmio[0].memory);

    return mpic;
}

777 778 779 780 781 782 783
static void ppce500_power_off(void *opaque, int line, int on)
{
    if (on) {
        qemu_system_shutdown_request();
    }
}

784
void ppce500_init(MachineState *machine, PPCE500Params *params)
785
{
786
    MemoryRegion *address_space_mem = get_system_memory();
787
    MemoryRegion *ram = g_new(MemoryRegion, 1);
788
    PCIBus *pci_bus;
A
Andreas Färber 已提交
789
    CPUPPCState *env = NULL;
790 791 792 793 794 795 796 797 798 799 800 801
    uint64_t loadaddr;
    hwaddr kernel_base = -1LL;
    int kernel_size = 0;
    hwaddr dt_base = 0;
    hwaddr initrd_base = 0;
    int initrd_size = 0;
    hwaddr cur_base = 0;
    char *filename;
    hwaddr bios_entry = 0;
    target_long bios_size;
    struct boot_info *boot_info;
    int dt_size;
802
    int i;
803 804 805
    /* irq num for pin INTA, INTB, INTC and INTD is 1, 2, 3 and
     * 4 respectively */
    unsigned int pci_irq_nrs[PCI_NUM_PINS] = {1, 2, 3, 4};
806
    qemu_irq **irqs, *mpic;
A
Alexander Graf 已提交
807
    DeviceState *dev;
A
Andreas Färber 已提交
808
    CPUPPCState *firstenv = NULL;
809
    MemoryRegion *ccsr_addr_space;
B
Bharat Bhushan 已提交
810
    SysBusDevice *s;
811
    PPCE500CCSRState *ccsr;
812

A
Alexander Graf 已提交
813
    /* Setup CPUs */
814 815
    if (machine->cpu_model == NULL) {
        machine->cpu_model = "e500v2_v30";
816 817
    }

818 819
    irqs = g_malloc0(smp_cpus * sizeof(qemu_irq *));
    irqs[0] = g_malloc0(smp_cpus * sizeof(qemu_irq) * OPENPIC_OUTPUT_NB);
A
Alexander Graf 已提交
820
    for (i = 0; i < smp_cpus; i++) {
821
        PowerPCCPU *cpu;
822
        CPUState *cs;
A
Alexander Graf 已提交
823
        qemu_irq *input;
824

825
        cpu = cpu_ppc_init(machine->cpu_model);
826
        if (cpu == NULL) {
A
Alexander Graf 已提交
827 828 829
            fprintf(stderr, "Unable to initialize CPU!\n");
            exit(1);
        }
830
        env = &cpu->env;
831
        cs = CPU(cpu);
832

A
Alexander Graf 已提交
833 834 835
        if (!firstenv) {
            firstenv = env;
        }
836

837 838 839 840
        irqs[i] = irqs[0] + (i * OPENPIC_OUTPUT_NB);
        input = (qemu_irq *)env->irq_inputs;
        irqs[i][OPENPIC_OUTPUT_INT] = input[PPCE500_INPUT_INT];
        irqs[i][OPENPIC_OUTPUT_CINT] = input[PPCE500_INPUT_CINT];
841
        env->spr_cb[SPR_BOOKE_PIR].default_value = cs->cpu_index = i;
842
        env->mpic_iack = params->ccsrbar_base +
S
Scott Wood 已提交
843
                         MPC8544_MPIC_REGS_OFFSET + 0xa0;
844

845
        ppc_booke_timers_init(cpu, 400000000, PPC_TIMER_E500);
A
Alexander Graf 已提交
846 847

        /* Register reset handler */
A
Alexander Graf 已提交
848 849 850 851
        if (!i) {
            /* Primary CPU */
            struct boot_info *boot_info;
            boot_info = g_malloc0(sizeof(struct boot_info));
852
            qemu_register_reset(ppce500_cpu_reset, cpu);
A
Alexander Graf 已提交
853 854 855
            env->load_info = boot_info;
        } else {
            /* Secondary CPUs */
856
            qemu_register_reset(ppce500_cpu_reset_sec, cpu);
A
Alexander Graf 已提交
857
        }
A
Alexander Graf 已提交
858
    }
859

A
Alexander Graf 已提交
860
    env = firstenv;
861

862 863
    /* Fixup Memory size on a alignment boundary */
    ram_size &= ~(RAM_SIZES_ALIGN - 1);
864
    machine->ram_size = ram_size;
865 866

    /* Register Memory */
867
    memory_region_allocate_system_memory(ram, NULL, "mpc8544ds.ram", ram_size);
868
    memory_region_add_subregion(address_space_mem, 0, ram);
869

870 871 872 873 874 875
    dev = qdev_create(NULL, "e500-ccsr");
    object_property_add_child(qdev_get_machine(), "e500-ccsr",
                              OBJECT(dev), NULL);
    qdev_init_nofail(dev);
    ccsr = CCSR(dev);
    ccsr_addr_space = &ccsr->ccsr_space;
876
    memory_region_add_subregion(address_space_mem, params->ccsrbar_base,
877
                                ccsr_addr_space);
B
Bharat Bhushan 已提交
878

879
    mpic = ppce500_init_mpic(params, ccsr_addr_space, irqs);
A
Alexander Graf 已提交
880

881
    /* Serial */
B
Blue Swirl 已提交
882
    if (serial_hds[0]) {
883
        serial_mm_init(ccsr_addr_space, MPC8544_SERIAL0_REGS_OFFSET,
A
Alexander Graf 已提交
884
                       0, mpic[42], 399193,
885
                       serial_hds[0], DEVICE_BIG_ENDIAN);
B
Blue Swirl 已提交
886
    }
887

B
Blue Swirl 已提交
888
    if (serial_hds[1]) {
889
        serial_mm_init(ccsr_addr_space, MPC8544_SERIAL1_REGS_OFFSET,
A
Alexander Graf 已提交
890
                       0, mpic[42], 399193,
B
Bharat Bhushan 已提交
891
                       serial_hds[1], DEVICE_BIG_ENDIAN);
B
Blue Swirl 已提交
892
    }
893

894
    /* General Utility device */
B
Bharat Bhushan 已提交
895 896 897
    dev = qdev_create(NULL, "mpc8544-guts");
    qdev_init_nofail(dev);
    s = SYS_BUS_DEVICE(dev);
898
    memory_region_add_subregion(ccsr_addr_space, MPC8544_UTIL_OFFSET,
B
Bharat Bhushan 已提交
899
                                sysbus_mmio_get_region(s, 0));
900

901
    /* PCI */
B
Bharat Bhushan 已提交
902
    dev = qdev_create(NULL, "e500-pcihost");
903
    qdev_prop_set_uint32(dev, "first_slot", params->pci_first_slot);
904
    qdev_prop_set_uint32(dev, "first_pin_irq", pci_irq_nrs[0]);
B
Bharat Bhushan 已提交
905 906
    qdev_init_nofail(dev);
    s = SYS_BUS_DEVICE(dev);
907 908 909 910
    for (i = 0; i < PCI_NUM_PINS; i++) {
        sysbus_connect_irq(s, i, mpic[pci_irq_nrs[i]]);
    }

911
    memory_region_add_subregion(ccsr_addr_space, MPC8544_PCI_REGS_OFFSET,
B
Bharat Bhushan 已提交
912 913
                                sysbus_mmio_get_region(s, 0));

914
    pci_bus = (PCIBus *)qdev_get_child_bus(dev, "pci.0");
915 916 917 918 919 920
    if (!pci_bus)
        printf("couldn't create PCI controller!\n");

    if (pci_bus) {
        /* Register network interfaces. */
        for (i = 0; i < nb_nics; i++) {
921
            pci_nic_init_nofail(&nd_table[i], pci_bus, "virtio", NULL);
922 923 924
        }
    }

A
Alexander Graf 已提交
925
    /* Register spinning region */
926
    sysbus_create_simple("e500-spin", params->spin_base, NULL);
A
Alexander Graf 已提交
927

928 929 930 931 932
    if (cur_base < (32 * 1024 * 1024)) {
        /* u-boot occupies memory up to 32MB, so load blobs above */
        cur_base = (32 * 1024 * 1024);
    }

933
    if (params->has_mpc8xxx_gpio) {
934 935
        qemu_irq poweroff_irq;

936 937 938 939 940 941
        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));
942 943 944 945

        /* Power Off GPIO at Pin 0 */
        poweroff_irq = qemu_allocate_irq(ppce500_power_off, NULL, 0);
        qdev_connect_gpio_out(dev, 0, poweroff_irq);
946 947
    }

948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966
    /* Platform Bus Device */
    if (params->has_platform_bus) {
        dev = qdev_create(NULL, TYPE_PLATFORM_BUS_DEVICE);
        dev->id = TYPE_PLATFORM_BUS_DEVICE;
        qdev_prop_set_uint32(dev, "num_irqs", params->platform_bus_num_irqs);
        qdev_prop_set_uint32(dev, "mmio_size", params->platform_bus_size);
        qdev_init_nofail(dev);
        s = SYS_BUS_DEVICE(dev);

        for (i = 0; i < params->platform_bus_num_irqs; i++) {
            int irqn = params->platform_bus_first_irq + i;
            sysbus_connect_irq(s, i, mpic[irqn]);
        }

        memory_region_add_subregion(address_space_mem,
                                    params->platform_bus_base,
                                    sysbus_mmio_get_region(s, 0));
    }

967
    /* Load kernel. */
968
    if (machine->kernel_filename) {
969 970 971 972
        kernel_base = cur_base;
        kernel_size = load_image_targphys(machine->kernel_filename,
                                          cur_base,
                                          ram_size - cur_base);
973 974
        if (kernel_size < 0) {
            fprintf(stderr, "qemu: could not load kernel '%s'\n",
975
                    machine->kernel_filename);
976 977
            exit(1);
        }
978

979
        cur_base += kernel_size;
980 981 982
    }

    /* Load initrd. */
983
    if (machine->initrd_filename) {
984
        initrd_base = (cur_base + INITRD_LOAD_PAD) & ~INITRD_PAD_MASK;
985
        initrd_size = load_image_targphys(machine->initrd_filename, initrd_base,
P
pbrook 已提交
986
                                          ram_size - initrd_base);
987 988 989

        if (initrd_size < 0) {
            fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
990
                    machine->initrd_filename);
991 992
            exit(1);
        }
993 994

        cur_base = initrd_base + initrd_size;
995 996
    }

997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027
    /*
     * Smart firmware defaults ahead!
     *
     * We follow the following table to select which payload we execute.
     *
     *  -kernel | -bios | payload
     * ---------+-------+---------
     *     N    |   Y   | u-boot
     *     N    |   N   | u-boot
     *     Y    |   Y   | u-boot
     *     Y    |   N   | kernel
     *
     * This ensures backwards compatibility with how we used to expose
     * -kernel to users but allows them to run through u-boot as well.
     */
    if (bios_name == NULL) {
        if (machine->kernel_filename) {
            bios_name = machine->kernel_filename;
        } else {
            bios_name = "u-boot.e500";
        }
    }
    filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);

    bios_size = load_elf(filename, NULL, NULL, &bios_entry, &loadaddr, NULL,
                         1, ELF_MACHINE, 0);
    if (bios_size < 0) {
        /*
         * Hrm. No ELF image? Try a uImage, maybe someone is giving us an
         * ePAPR compliant kernel
         */
1028 1029
        kernel_size = load_uimage(filename, &bios_entry, &loadaddr, NULL,
                                  NULL, NULL);
1030 1031
        if (kernel_size < 0) {
            fprintf(stderr, "qemu: could not load firmware '%s'\n", filename);
1032 1033
            exit(1);
        }
1034 1035 1036 1037
    }

    /* Reserve space for dtb */
    dt_base = (loadaddr + bios_size + DTC_LOAD_PAD) & ~DTC_PAD_MASK;
1038

1039 1040 1041 1042 1043 1044
    dt_size = ppce500_prep_device_tree(machine, params, dt_base,
                                       initrd_base, initrd_size,
                                       kernel_base, kernel_size);
    if (dt_size < 0) {
        fprintf(stderr, "couldn't load device tree\n");
        exit(1);
1045
    }
1046 1047 1048 1049 1050 1051
    assert(dt_size < DTB_MAX_SIZE);

    boot_info = env->load_info;
    boot_info->entry = bios_entry;
    boot_info->dt_base = dt_base;
    boot_info->dt_size = dt_size;
1052

1053
    if (kvm_enabled()) {
1054
        kvmppc_init();
1055
    }
1056
}
1057 1058 1059 1060 1061 1062

static int e500_ccsr_initfn(SysBusDevice *dev)
{
    PPCE500CCSRState *ccsr;

    ccsr = CCSR(dev);
1063
    memory_region_init(&ccsr->ccsr_space, OBJECT(ccsr), "e500-ccsr",
1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086
                       MPC8544_CCSRBAR_SIZE);
    return 0;
}

static void e500_ccsr_class_init(ObjectClass *klass, void *data)
{
    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
    k->init = e500_ccsr_initfn;
}

static const TypeInfo e500_ccsr_info = {
    .name          = TYPE_CCSR,
    .parent        = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(PPCE500CCSRState),
    .class_init    = e500_ccsr_class_init,
};

static void e500_register_types(void)
{
    type_register_static(&e500_ccsr_info);
}

type_init(e500_register_types)