Statistics
| Branch: | Revision:

root / hw / ppc / e500.c @ 2c9b15ca

History | View | Annotate | Download (26.4 kB)

1 1db09b84 aurel32
/*
2 b3305981 Scott Wood
 * QEMU PowerPC e500-based platforms
3 1db09b84 aurel32
 *
4 1db09b84 aurel32
 * Copyright (C) 2009 Freescale Semiconductor, Inc. All rights reserved.
5 1db09b84 aurel32
 *
6 1db09b84 aurel32
 * Author: Yu Liu,     <yu.liu@freescale.com>
7 1db09b84 aurel32
 *
8 1db09b84 aurel32
 * This file is derived from hw/ppc440_bamboo.c,
9 1db09b84 aurel32
 * the copyright for that material belongs to the original owners.
10 1db09b84 aurel32
 *
11 1db09b84 aurel32
 * This is free software; you can redistribute it and/or modify
12 1db09b84 aurel32
 * it under the terms of  the GNU General  Public License as published by
13 1db09b84 aurel32
 * the Free Software Foundation;  either version 2 of the  License, or
14 1db09b84 aurel32
 * (at your option) any later version.
15 1db09b84 aurel32
 */
16 1db09b84 aurel32
17 1db09b84 aurel32
#include "config.h"
18 1db09b84 aurel32
#include "qemu-common.h"
19 e6eaabeb Scott Wood
#include "e500.h"
20 3eddc1be Bharat Bhushan
#include "e500-ccsr.h"
21 1422e32d Paolo Bonzini
#include "net/net.h"
22 1de7afc9 Paolo Bonzini
#include "qemu/config-file.h"
23 4a18e7c9 Scott Wood
#include "hw/hw.h"
24 0d09e41a Paolo Bonzini
#include "hw/char/serial.h"
25 a2cb15b0 Michael S. Tsirkin
#include "hw/pci/pci.h"
26 4a18e7c9 Scott Wood
#include "hw/boards.h"
27 9c17d615 Paolo Bonzini
#include "sysemu/sysemu.h"
28 9c17d615 Paolo Bonzini
#include "sysemu/kvm.h"
29 1db09b84 aurel32
#include "kvm_ppc.h"
30 9c17d615 Paolo Bonzini
#include "sysemu/device_tree.h"
31 0d09e41a Paolo Bonzini
#include "hw/ppc/openpic.h"
32 0d09e41a Paolo Bonzini
#include "hw/ppc/ppc.h"
33 4a18e7c9 Scott Wood
#include "hw/loader.h"
34 ca20cf32 Blue Swirl
#include "elf.h"
35 4a18e7c9 Scott Wood
#include "hw/sysbus.h"
36 022c62cb Paolo Bonzini
#include "exec/address-spaces.h"
37 1de7afc9 Paolo Bonzini
#include "qemu/host-utils.h"
38 0d09e41a Paolo Bonzini
#include "hw/pci-host/ppce500.h"
39 1db09b84 aurel32
40 cefd3cdb Bharat Bhushan
#define EPAPR_MAGIC                (0x45504150)
41 1db09b84 aurel32
#define BINARY_DEVICE_TREE_FILE    "mpc8544ds.dtb"
42 1db09b84 aurel32
#define UIMAGE_LOAD_BASE           0
43 9dd5eba1 Scott Wood
#define DTC_LOAD_PAD               0x1800000
44 75bb6589 Liu Yu
#define DTC_PAD_MASK               0xFFFFF
45 b8dec144 Alexander Graf
#define DTB_MAX_SIZE               (8 * 1024 * 1024)
46 75bb6589 Liu Yu
#define INITRD_LOAD_PAD            0x2000000
47 75bb6589 Liu Yu
#define INITRD_PAD_MASK            0xFFFFFF
48 1db09b84 aurel32
49 1db09b84 aurel32
#define RAM_SIZES_ALIGN            (64UL << 20)
50 1db09b84 aurel32
51 b3305981 Scott Wood
/* TODO: parameterize */
52 ed2bc496 Alexander Graf
#define MPC8544_CCSRBAR_BASE       0xE0000000ULL
53 ed2bc496 Alexander Graf
#define MPC8544_CCSRBAR_SIZE       0x00100000ULL
54 dffb1dc2 Bharat Bhushan
#define MPC8544_MPIC_REGS_OFFSET   0x40000ULL
55 a911b7a9 Alexander Graf
#define MPC8544_MSI_REGS_OFFSET   0x41600ULL
56 dffb1dc2 Bharat Bhushan
#define MPC8544_SERIAL0_REGS_OFFSET 0x4500ULL
57 dffb1dc2 Bharat Bhushan
#define MPC8544_SERIAL1_REGS_OFFSET 0x4600ULL
58 dffb1dc2 Bharat Bhushan
#define MPC8544_PCI_REGS_OFFSET    0x8000ULL
59 dffb1dc2 Bharat Bhushan
#define MPC8544_PCI_REGS_BASE      (MPC8544_CCSRBAR_BASE + \
60 dffb1dc2 Bharat Bhushan
                                    MPC8544_PCI_REGS_OFFSET)
61 ed2bc496 Alexander Graf
#define MPC8544_PCI_REGS_SIZE      0x1000ULL
62 ed2bc496 Alexander Graf
#define MPC8544_PCI_IO             0xE1000000ULL
63 dffb1dc2 Bharat Bhushan
#define MPC8544_UTIL_OFFSET        0xe0000ULL
64 ed2bc496 Alexander Graf
#define MPC8544_SPIN_BASE          0xEF000000ULL
65 1db09b84 aurel32
66 3b989d49 Alexander Graf
struct boot_info
67 3b989d49 Alexander Graf
{
68 3b989d49 Alexander Graf
    uint32_t dt_base;
69 cba2026a Alexander Graf
    uint32_t dt_size;
70 3b989d49 Alexander Graf
    uint32_t entry;
71 3b989d49 Alexander Graf
};
72 3b989d49 Alexander Graf
73 347dd79d Alexander Graf
static uint32_t *pci_map_create(void *fdt, uint32_t mpic, int first_slot,
74 347dd79d Alexander Graf
                                int nr_slots, int *len)
75 0dbc0798 Alexander Graf
{
76 347dd79d Alexander Graf
    int i = 0;
77 347dd79d Alexander Graf
    int slot;
78 347dd79d Alexander Graf
    int pci_irq;
79 9e2c1298 Alexander Graf
    int host_irq;
80 347dd79d Alexander Graf
    int last_slot = first_slot + nr_slots;
81 347dd79d Alexander Graf
    uint32_t *pci_map;
82 347dd79d Alexander Graf
83 347dd79d Alexander Graf
    *len = nr_slots * 4 * 7 * sizeof(uint32_t);
84 347dd79d Alexander Graf
    pci_map = g_malloc(*len);
85 347dd79d Alexander Graf
86 347dd79d Alexander Graf
    for (slot = first_slot; slot < last_slot; slot++) {
87 347dd79d Alexander Graf
        for (pci_irq = 0; pci_irq < 4; pci_irq++) {
88 347dd79d Alexander Graf
            pci_map[i++] = cpu_to_be32(slot << 11);
89 347dd79d Alexander Graf
            pci_map[i++] = cpu_to_be32(0x0);
90 347dd79d Alexander Graf
            pci_map[i++] = cpu_to_be32(0x0);
91 347dd79d Alexander Graf
            pci_map[i++] = cpu_to_be32(pci_irq + 1);
92 347dd79d Alexander Graf
            pci_map[i++] = cpu_to_be32(mpic);
93 9e2c1298 Alexander Graf
            host_irq = ppce500_pci_map_irq_slot(slot, pci_irq);
94 9e2c1298 Alexander Graf
            pci_map[i++] = cpu_to_be32(host_irq + 1);
95 347dd79d Alexander Graf
            pci_map[i++] = cpu_to_be32(0x1);
96 347dd79d Alexander Graf
        }
97 0dbc0798 Alexander Graf
    }
98 347dd79d Alexander Graf
99 347dd79d Alexander Graf
    assert((i * sizeof(uint32_t)) == *len);
100 347dd79d Alexander Graf
101 347dd79d Alexander Graf
    return pci_map;
102 0dbc0798 Alexander Graf
}
103 0dbc0798 Alexander Graf
104 a053a7ce Alexander Graf
static void dt_serial_create(void *fdt, unsigned long long offset,
105 a053a7ce Alexander Graf
                             const char *soc, const char *mpic,
106 a053a7ce Alexander Graf
                             const char *alias, int idx, bool defcon)
107 a053a7ce Alexander Graf
{
108 a053a7ce Alexander Graf
    char ser[128];
109 a053a7ce Alexander Graf
110 a053a7ce Alexander Graf
    snprintf(ser, sizeof(ser), "%s/serial@%llx", soc, offset);
111 a053a7ce Alexander Graf
    qemu_devtree_add_subnode(fdt, ser);
112 a053a7ce Alexander Graf
    qemu_devtree_setprop_string(fdt, ser, "device_type", "serial");
113 a053a7ce Alexander Graf
    qemu_devtree_setprop_string(fdt, ser, "compatible", "ns16550");
114 a053a7ce Alexander Graf
    qemu_devtree_setprop_cells(fdt, ser, "reg", offset, 0x100);
115 a053a7ce Alexander Graf
    qemu_devtree_setprop_cell(fdt, ser, "cell-index", idx);
116 a053a7ce Alexander Graf
    qemu_devtree_setprop_cell(fdt, ser, "clock-frequency", 0);
117 7e99826c Alexander Graf
    qemu_devtree_setprop_cells(fdt, ser, "interrupts", 42, 2);
118 a053a7ce Alexander Graf
    qemu_devtree_setprop_phandle(fdt, ser, "interrupt-parent", mpic);
119 a053a7ce Alexander Graf
    qemu_devtree_setprop_string(fdt, "/aliases", alias, ser);
120 a053a7ce Alexander Graf
121 a053a7ce Alexander Graf
    if (defcon) {
122 a053a7ce Alexander Graf
        qemu_devtree_setprop_string(fdt, "/chosen", "linux,stdout-path", ser);
123 a053a7ce Alexander Graf
    }
124 a053a7ce Alexander Graf
}
125 a053a7ce Alexander Graf
126 b3305981 Scott Wood
static int ppce500_load_device_tree(CPUPPCState *env,
127 e6eaabeb Scott Wood
                                    PPCE500Params *params,
128 a8170e5e Avi Kivity
                                    hwaddr addr,
129 a8170e5e Avi Kivity
                                    hwaddr initrd_base,
130 a8170e5e Avi Kivity
                                    hwaddr initrd_size)
131 1db09b84 aurel32
{
132 dbf916d8 Aurelien Jarno
    int ret = -1;
133 e6eaabeb Scott Wood
    uint64_t mem_reg_property[] = { 0, cpu_to_be64(params->ram_size) };
134 7ec632b4 pbrook
    int fdt_size;
135 dbf916d8 Aurelien Jarno
    void *fdt;
136 5de6b46d Alexander Graf
    uint8_t hypercall[16];
137 911d6e7a Alexander Graf
    uint32_t clock_freq = 400000000;
138 911d6e7a Alexander Graf
    uint32_t tb_freq = 400000000;
139 621d05e3 Alexander Graf
    int i;
140 e6eaabeb Scott Wood
    const char *toplevel_compat = NULL; /* user override */
141 ebb9518a Alexander Graf
    char compatible_sb[] = "fsl,mpc8544-immr\0simple-bus";
142 5da96624 Alexander Graf
    char soc[128];
143 19ac9dea Alexander Graf
    char mpic[128];
144 19ac9dea Alexander Graf
    uint32_t mpic_ph;
145 a911b7a9 Alexander Graf
    uint32_t msi_ph;
146 f5038483 Alexander Graf
    char gutil[128];
147 0dbc0798 Alexander Graf
    char pci[128];
148 a911b7a9 Alexander Graf
    char msi[128];
149 347dd79d Alexander Graf
    uint32_t *pci_map = NULL;
150 347dd79d Alexander Graf
    int len;
151 3627757e Alexander Graf
    uint32_t pci_ranges[14] =
152 3627757e Alexander Graf
        {
153 3627757e Alexander Graf
            0x2000000, 0x0, 0xc0000000,
154 3627757e Alexander Graf
            0x0, 0xc0000000,
155 3627757e Alexander Graf
            0x0, 0x20000000,
156 3627757e Alexander Graf
157 3627757e Alexander Graf
            0x1000000, 0x0, 0x0,
158 3627757e Alexander Graf
            0x0, 0xe1000000,
159 3627757e Alexander Graf
            0x0, 0x10000,
160 3627757e Alexander Graf
        };
161 25b42708 Alexander Graf
    QemuOpts *machine_opts;
162 d1b93565 Alexander Graf
    const char *dtb_file = NULL;
163 d1b93565 Alexander Graf
164 d1b93565 Alexander Graf
    machine_opts = qemu_opts_find(qemu_find_opts("machine"), 0);
165 d1b93565 Alexander Graf
    if (machine_opts) {
166 d1b93565 Alexander Graf
        dtb_file = qemu_opt_get(machine_opts, "dtb");
167 e6eaabeb Scott Wood
        toplevel_compat = qemu_opt_get(machine_opts, "dt_compatible");
168 d1b93565 Alexander Graf
    }
169 d1b93565 Alexander Graf
170 d1b93565 Alexander Graf
    if (dtb_file) {
171 d1b93565 Alexander Graf
        char *filename;
172 d1b93565 Alexander Graf
        filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, dtb_file);
173 d1b93565 Alexander Graf
        if (!filename) {
174 d1b93565 Alexander Graf
            goto out;
175 d1b93565 Alexander Graf
        }
176 d1b93565 Alexander Graf
177 d1b93565 Alexander Graf
        fdt = load_device_tree(filename, &fdt_size);
178 d1b93565 Alexander Graf
        if (!fdt) {
179 d1b93565 Alexander Graf
            goto out;
180 d1b93565 Alexander Graf
        }
181 d1b93565 Alexander Graf
        goto done;
182 d1b93565 Alexander Graf
    }
183 1db09b84 aurel32
184 2636fcb6 Alexander Graf
    fdt = create_device_tree(&fdt_size);
185 5cea8590 Paul Brook
    if (fdt == NULL) {
186 5cea8590 Paul Brook
        goto out;
187 5cea8590 Paul Brook
    }
188 1db09b84 aurel32
189 1db09b84 aurel32
    /* Manipulate device tree in memory. */
190 3627757e Alexander Graf
    qemu_devtree_setprop_cell(fdt, "/", "#address-cells", 2);
191 3627757e Alexander Graf
    qemu_devtree_setprop_cell(fdt, "/", "#size-cells", 2);
192 51b852b7 Alexander Graf
193 dd0bcfca Alexander Graf
    qemu_devtree_add_subnode(fdt, "/memory");
194 dd0bcfca Alexander Graf
    qemu_devtree_setprop_string(fdt, "/memory", "device_type", "memory");
195 dd0bcfca Alexander Graf
    qemu_devtree_setprop(fdt, "/memory", "reg", mem_reg_property,
196 dd0bcfca Alexander Graf
                         sizeof(mem_reg_property));
197 1db09b84 aurel32
198 f5231aaf Alexander Graf
    qemu_devtree_add_subnode(fdt, "/chosen");
199 3b989d49 Alexander Graf
    if (initrd_size) {
200 3b989d49 Alexander Graf
        ret = qemu_devtree_setprop_cell(fdt, "/chosen", "linux,initrd-start",
201 3b989d49 Alexander Graf
                                        initrd_base);
202 3b989d49 Alexander Graf
        if (ret < 0) {
203 3b989d49 Alexander Graf
            fprintf(stderr, "couldn't set /chosen/linux,initrd-start\n");
204 3b989d49 Alexander Graf
        }
205 1db09b84 aurel32
206 3b989d49 Alexander Graf
        ret = qemu_devtree_setprop_cell(fdt, "/chosen", "linux,initrd-end",
207 3b989d49 Alexander Graf
                                        (initrd_base + initrd_size));
208 3b989d49 Alexander Graf
        if (ret < 0) {
209 3b989d49 Alexander Graf
            fprintf(stderr, "couldn't set /chosen/linux,initrd-end\n");
210 3b989d49 Alexander Graf
        }
211 3b989d49 Alexander Graf
    }
212 1db09b84 aurel32
213 1db09b84 aurel32
    ret = qemu_devtree_setprop_string(fdt, "/chosen", "bootargs",
214 e6eaabeb Scott Wood
                                      params->kernel_cmdline);
215 1db09b84 aurel32
    if (ret < 0)
216 1db09b84 aurel32
        fprintf(stderr, "couldn't set /chosen/bootargs\n");
217 1db09b84 aurel32
218 1db09b84 aurel32
    if (kvm_enabled()) {
219 911d6e7a Alexander Graf
        /* Read out host's frequencies */
220 911d6e7a Alexander Graf
        clock_freq = kvmppc_get_clockfreq();
221 911d6e7a Alexander Graf
        tb_freq = kvmppc_get_tbfreq();
222 5de6b46d Alexander Graf
223 5de6b46d Alexander Graf
        /* indicate KVM hypercall interface */
224 d50f71a5 Alexander Graf
        qemu_devtree_add_subnode(fdt, "/hypervisor");
225 5de6b46d Alexander Graf
        qemu_devtree_setprop_string(fdt, "/hypervisor", "compatible",
226 5de6b46d Alexander Graf
                                    "linux,kvm");
227 5de6b46d Alexander Graf
        kvmppc_get_hypercall(env, hypercall, sizeof(hypercall));
228 5de6b46d Alexander Graf
        qemu_devtree_setprop(fdt, "/hypervisor", "hcall-instructions",
229 5de6b46d Alexander Graf
                             hypercall, sizeof(hypercall));
230 1a61a9ae Stuart Yoder
        /* if KVM supports the idle hcall, set property indicating this */
231 1a61a9ae Stuart Yoder
        if (kvmppc_get_hasidle(env)) {
232 1a61a9ae Stuart Yoder
            qemu_devtree_setprop(fdt, "/hypervisor", "has-idle", NULL, 0);
233 1a61a9ae Stuart Yoder
        }
234 1db09b84 aurel32
    }
235 3b989d49 Alexander Graf
236 625e665b Alexander Graf
    /* Create CPU nodes */
237 625e665b Alexander Graf
    qemu_devtree_add_subnode(fdt, "/cpus");
238 625e665b Alexander Graf
    qemu_devtree_setprop_cell(fdt, "/cpus", "#address-cells", 1);
239 625e665b Alexander Graf
    qemu_devtree_setprop_cell(fdt, "/cpus", "#size-cells", 0);
240 625e665b Alexander Graf
241 1e3debf0 Alexander Graf
    /* We need to generate the cpu nodes in reverse order, so Linux can pick
242 1e3debf0 Alexander Graf
       the first node as boot node and be happy */
243 1e3debf0 Alexander Graf
    for (i = smp_cpus - 1; i >= 0; i--) {
244 440c8152 Andreas Färber
        CPUState *cpu;
245 621d05e3 Alexander Graf
        char cpu_name[128];
246 1d2e5c52 Alexander Graf
        uint64_t cpu_release_addr = MPC8544_SPIN_BASE + (i * 0x20);
247 10f25a46 Alexander Graf
248 440c8152 Andreas Färber
        cpu = qemu_get_cpu(i);
249 55e5c285 Andreas Färber
        if (cpu == NULL) {
250 1e3debf0 Alexander Graf
            continue;
251 1e3debf0 Alexander Graf
        }
252 440c8152 Andreas Färber
        env = cpu->env_ptr;
253 1e3debf0 Alexander Graf
254 55e5c285 Andreas Färber
        snprintf(cpu_name, sizeof(cpu_name), "/cpus/PowerPC,8544@%x",
255 55e5c285 Andreas Färber
                 cpu->cpu_index);
256 1e3debf0 Alexander Graf
        qemu_devtree_add_subnode(fdt, cpu_name);
257 621d05e3 Alexander Graf
        qemu_devtree_setprop_cell(fdt, cpu_name, "clock-frequency", clock_freq);
258 621d05e3 Alexander Graf
        qemu_devtree_setprop_cell(fdt, cpu_name, "timebase-frequency", tb_freq);
259 1e3debf0 Alexander Graf
        qemu_devtree_setprop_string(fdt, cpu_name, "device_type", "cpu");
260 55e5c285 Andreas Färber
        qemu_devtree_setprop_cell(fdt, cpu_name, "reg", cpu->cpu_index);
261 1e3debf0 Alexander Graf
        qemu_devtree_setprop_cell(fdt, cpu_name, "d-cache-line-size",
262 1e3debf0 Alexander Graf
                                  env->dcache_line_size);
263 1e3debf0 Alexander Graf
        qemu_devtree_setprop_cell(fdt, cpu_name, "i-cache-line-size",
264 1e3debf0 Alexander Graf
                                  env->icache_line_size);
265 1e3debf0 Alexander Graf
        qemu_devtree_setprop_cell(fdt, cpu_name, "d-cache-size", 0x8000);
266 1e3debf0 Alexander Graf
        qemu_devtree_setprop_cell(fdt, cpu_name, "i-cache-size", 0x8000);
267 1e3debf0 Alexander Graf
        qemu_devtree_setprop_cell(fdt, cpu_name, "bus-frequency", 0);
268 55e5c285 Andreas Färber
        if (cpu->cpu_index) {
269 1e3debf0 Alexander Graf
            qemu_devtree_setprop_string(fdt, cpu_name, "status", "disabled");
270 1e3debf0 Alexander Graf
            qemu_devtree_setprop_string(fdt, cpu_name, "enable-method", "spin-table");
271 1d2e5c52 Alexander Graf
            qemu_devtree_setprop_u64(fdt, cpu_name, "cpu-release-addr",
272 1d2e5c52 Alexander Graf
                                     cpu_release_addr);
273 1e3debf0 Alexander Graf
        } else {
274 1e3debf0 Alexander Graf
            qemu_devtree_setprop_string(fdt, cpu_name, "status", "okay");
275 1e3debf0 Alexander Graf
        }
276 1db09b84 aurel32
    }
277 1db09b84 aurel32
278 0cfc6e8d Alexander Graf
    qemu_devtree_add_subnode(fdt, "/aliases");
279 5da96624 Alexander Graf
    /* XXX These should go into their respective devices' code */
280 ed2bc496 Alexander Graf
    snprintf(soc, sizeof(soc), "/soc@%llx", MPC8544_CCSRBAR_BASE);
281 5da96624 Alexander Graf
    qemu_devtree_add_subnode(fdt, soc);
282 5da96624 Alexander Graf
    qemu_devtree_setprop_string(fdt, soc, "device_type", "soc");
283 ebb9518a Alexander Graf
    qemu_devtree_setprop(fdt, soc, "compatible", compatible_sb,
284 ebb9518a Alexander Graf
                         sizeof(compatible_sb));
285 5da96624 Alexander Graf
    qemu_devtree_setprop_cell(fdt, soc, "#address-cells", 1);
286 5da96624 Alexander Graf
    qemu_devtree_setprop_cell(fdt, soc, "#size-cells", 1);
287 3627757e Alexander Graf
    qemu_devtree_setprop_cells(fdt, soc, "ranges", 0x0,
288 3627757e Alexander Graf
                               MPC8544_CCSRBAR_BASE >> 32, MPC8544_CCSRBAR_BASE,
289 5da96624 Alexander Graf
                               MPC8544_CCSRBAR_SIZE);
290 5da96624 Alexander Graf
    /* XXX should contain a reasonable value */
291 5da96624 Alexander Graf
    qemu_devtree_setprop_cell(fdt, soc, "bus-frequency", 0);
292 5da96624 Alexander Graf
293 dffb1dc2 Bharat Bhushan
    snprintf(mpic, sizeof(mpic), "%s/pic@%llx", soc, MPC8544_MPIC_REGS_OFFSET);
294 19ac9dea Alexander Graf
    qemu_devtree_add_subnode(fdt, mpic);
295 19ac9dea Alexander Graf
    qemu_devtree_setprop_string(fdt, mpic, "device_type", "open-pic");
296 f5fba9d2 Scott Wood
    qemu_devtree_setprop_string(fdt, mpic, "compatible", "fsl,mpic");
297 dffb1dc2 Bharat Bhushan
    qemu_devtree_setprop_cells(fdt, mpic, "reg", MPC8544_MPIC_REGS_OFFSET,
298 dffb1dc2 Bharat Bhushan
                               0x40000);
299 19ac9dea Alexander Graf
    qemu_devtree_setprop_cell(fdt, mpic, "#address-cells", 0);
300 7e99826c Alexander Graf
    qemu_devtree_setprop_cell(fdt, mpic, "#interrupt-cells", 2);
301 19ac9dea Alexander Graf
    mpic_ph = qemu_devtree_alloc_phandle(fdt);
302 19ac9dea Alexander Graf
    qemu_devtree_setprop_cell(fdt, mpic, "phandle", mpic_ph);
303 19ac9dea Alexander Graf
    qemu_devtree_setprop_cell(fdt, mpic, "linux,phandle", mpic_ph);
304 19ac9dea Alexander Graf
    qemu_devtree_setprop(fdt, mpic, "interrupt-controller", NULL, 0);
305 19ac9dea Alexander Graf
306 0cfc6e8d Alexander Graf
    /*
307 0cfc6e8d Alexander Graf
     * We have to generate ser1 first, because Linux takes the first
308 0cfc6e8d Alexander Graf
     * device it finds in the dt as serial output device. And we generate
309 0cfc6e8d Alexander Graf
     * devices in reverse order to the dt.
310 0cfc6e8d Alexander Graf
     */
311 dffb1dc2 Bharat Bhushan
    dt_serial_create(fdt, MPC8544_SERIAL1_REGS_OFFSET,
312 a053a7ce Alexander Graf
                     soc, mpic, "serial1", 1, false);
313 dffb1dc2 Bharat Bhushan
    dt_serial_create(fdt, MPC8544_SERIAL0_REGS_OFFSET,
314 a053a7ce Alexander Graf
                     soc, mpic, "serial0", 0, true);
315 0cfc6e8d Alexander Graf
316 ed2bc496 Alexander Graf
    snprintf(gutil, sizeof(gutil), "%s/global-utilities@%llx", soc,
317 dffb1dc2 Bharat Bhushan
             MPC8544_UTIL_OFFSET);
318 f5038483 Alexander Graf
    qemu_devtree_add_subnode(fdt, gutil);
319 f5038483 Alexander Graf
    qemu_devtree_setprop_string(fdt, gutil, "compatible", "fsl,mpc8544-guts");
320 dffb1dc2 Bharat Bhushan
    qemu_devtree_setprop_cells(fdt, gutil, "reg", MPC8544_UTIL_OFFSET, 0x1000);
321 f5038483 Alexander Graf
    qemu_devtree_setprop(fdt, gutil, "fsl,has-rstcr", NULL, 0);
322 f5038483 Alexander Graf
323 a911b7a9 Alexander Graf
    snprintf(msi, sizeof(msi), "/%s/msi@%llx", soc, MPC8544_MSI_REGS_OFFSET);
324 a911b7a9 Alexander Graf
    qemu_devtree_add_subnode(fdt, msi);
325 a911b7a9 Alexander Graf
    qemu_devtree_setprop_string(fdt, msi, "compatible", "fsl,mpic-msi");
326 a911b7a9 Alexander Graf
    qemu_devtree_setprop_cells(fdt, msi, "reg", MPC8544_MSI_REGS_OFFSET, 0x200);
327 a911b7a9 Alexander Graf
    msi_ph = qemu_devtree_alloc_phandle(fdt);
328 a911b7a9 Alexander Graf
    qemu_devtree_setprop_cells(fdt, msi, "msi-available-ranges", 0x0, 0x100);
329 a911b7a9 Alexander Graf
    qemu_devtree_setprop_phandle(fdt, msi, "interrupt-parent", mpic);
330 a911b7a9 Alexander Graf
    qemu_devtree_setprop_cells(fdt, msi, "interrupts",
331 a911b7a9 Alexander Graf
        0xe0, 0x0,
332 a911b7a9 Alexander Graf
        0xe1, 0x0,
333 a911b7a9 Alexander Graf
        0xe2, 0x0,
334 a911b7a9 Alexander Graf
        0xe3, 0x0,
335 a911b7a9 Alexander Graf
        0xe4, 0x0,
336 a911b7a9 Alexander Graf
        0xe5, 0x0,
337 a911b7a9 Alexander Graf
        0xe6, 0x0,
338 a911b7a9 Alexander Graf
        0xe7, 0x0);
339 a911b7a9 Alexander Graf
    qemu_devtree_setprop_cell(fdt, msi, "phandle", msi_ph);
340 a911b7a9 Alexander Graf
    qemu_devtree_setprop_cell(fdt, msi, "linux,phandle", msi_ph);
341 a911b7a9 Alexander Graf
342 ed2bc496 Alexander Graf
    snprintf(pci, sizeof(pci), "/pci@%llx", MPC8544_PCI_REGS_BASE);
343 0dbc0798 Alexander Graf
    qemu_devtree_add_subnode(fdt, pci);
344 0dbc0798 Alexander Graf
    qemu_devtree_setprop_cell(fdt, pci, "cell-index", 0);
345 0dbc0798 Alexander Graf
    qemu_devtree_setprop_string(fdt, pci, "compatible", "fsl,mpc8540-pci");
346 0dbc0798 Alexander Graf
    qemu_devtree_setprop_string(fdt, pci, "device_type", "pci");
347 0dbc0798 Alexander Graf
    qemu_devtree_setprop_cells(fdt, pci, "interrupt-map-mask", 0xf800, 0x0,
348 0dbc0798 Alexander Graf
                               0x0, 0x7);
349 347dd79d Alexander Graf
    pci_map = pci_map_create(fdt, qemu_devtree_get_phandle(fdt, mpic),
350 492ec48d Alexander Graf
                             params->pci_first_slot, params->pci_nr_slots,
351 492ec48d Alexander Graf
                             &len);
352 347dd79d Alexander Graf
    qemu_devtree_setprop(fdt, pci, "interrupt-map", pci_map, len);
353 0dbc0798 Alexander Graf
    qemu_devtree_setprop_phandle(fdt, pci, "interrupt-parent", mpic);
354 7e99826c Alexander Graf
    qemu_devtree_setprop_cells(fdt, pci, "interrupts", 24, 2);
355 0dbc0798 Alexander Graf
    qemu_devtree_setprop_cells(fdt, pci, "bus-range", 0, 255);
356 3627757e Alexander Graf
    for (i = 0; i < 14; i++) {
357 0dbc0798 Alexander Graf
        pci_ranges[i] = cpu_to_be32(pci_ranges[i]);
358 0dbc0798 Alexander Graf
    }
359 a911b7a9 Alexander Graf
    qemu_devtree_setprop_cell(fdt, pci, "fsl,msi", msi_ph);
360 0dbc0798 Alexander Graf
    qemu_devtree_setprop(fdt, pci, "ranges", pci_ranges, sizeof(pci_ranges));
361 3627757e Alexander Graf
    qemu_devtree_setprop_cells(fdt, pci, "reg", MPC8544_PCI_REGS_BASE >> 32,
362 3627757e Alexander Graf
                               MPC8544_PCI_REGS_BASE, 0, 0x1000);
363 0dbc0798 Alexander Graf
    qemu_devtree_setprop_cell(fdt, pci, "clock-frequency", 66666666);
364 0dbc0798 Alexander Graf
    qemu_devtree_setprop_cell(fdt, pci, "#interrupt-cells", 1);
365 0dbc0798 Alexander Graf
    qemu_devtree_setprop_cell(fdt, pci, "#size-cells", 2);
366 0dbc0798 Alexander Graf
    qemu_devtree_setprop_cell(fdt, pci, "#address-cells", 3);
367 0dbc0798 Alexander Graf
    qemu_devtree_setprop_string(fdt, "/aliases", "pci0", pci);
368 0dbc0798 Alexander Graf
369 e6eaabeb Scott Wood
    params->fixup_devtree(params, fdt);
370 e6eaabeb Scott Wood
371 e6eaabeb Scott Wood
    if (toplevel_compat) {
372 e6eaabeb Scott Wood
        qemu_devtree_setprop(fdt, "/", "compatible", toplevel_compat,
373 e6eaabeb Scott Wood
                             strlen(toplevel_compat) + 1);
374 e6eaabeb Scott Wood
    }
375 e6eaabeb Scott Wood
376 d1b93565 Alexander Graf
done:
377 71193433 Alexander Graf
    qemu_devtree_dumpdtb(fdt, fdt_size);
378 04088adb Liu Yu
    ret = rom_add_blob_fixed(BINARY_DEVICE_TREE_FILE, fdt, fdt_size, addr);
379 cba2026a Alexander Graf
    if (ret < 0) {
380 cba2026a Alexander Graf
        goto out;
381 cba2026a Alexander Graf
    }
382 7267c094 Anthony Liguori
    g_free(fdt);
383 cba2026a Alexander Graf
    ret = fdt_size;
384 7ec632b4 pbrook
385 1db09b84 aurel32
out:
386 347dd79d Alexander Graf
    g_free(pci_map);
387 1db09b84 aurel32
388 04088adb Liu Yu
    return ret;
389 1db09b84 aurel32
}
390 1db09b84 aurel32
391 cba2026a Alexander Graf
/* Create -kernel TLB entries for BookE.  */
392 a8170e5e Avi Kivity
static inline hwaddr booke206_page_size_to_tlb(uint64_t size)
393 d1e256fe Alexander Graf
{
394 cba2026a Alexander Graf
    return 63 - clz64(size >> 10);
395 d1e256fe Alexander Graf
}
396 d1e256fe Alexander Graf
397 cefd3cdb Bharat Bhushan
static int booke206_initial_map_tsize(CPUPPCState *env)
398 3b989d49 Alexander Graf
{
399 cba2026a Alexander Graf
    struct boot_info *bi = env->load_info;
400 cefd3cdb Bharat Bhushan
    hwaddr dt_end;
401 cba2026a Alexander Graf
    int ps;
402 cba2026a Alexander Graf
403 cba2026a Alexander Graf
    /* Our initial TLB entry needs to cover everything from 0 to
404 cba2026a Alexander Graf
       the device tree top */
405 cba2026a Alexander Graf
    dt_end = bi->dt_base + bi->dt_size;
406 cba2026a Alexander Graf
    ps = booke206_page_size_to_tlb(dt_end) + 1;
407 fb37c302 Alexander Graf
    if (ps & 1) {
408 fb37c302 Alexander Graf
        /* e500v2 can only do even TLB size bits */
409 fb37c302 Alexander Graf
        ps++;
410 fb37c302 Alexander Graf
    }
411 cefd3cdb Bharat Bhushan
    return ps;
412 cefd3cdb Bharat Bhushan
}
413 cefd3cdb Bharat Bhushan
414 cefd3cdb Bharat Bhushan
static uint64_t mmubooke_initial_mapsize(CPUPPCState *env)
415 cefd3cdb Bharat Bhushan
{
416 cefd3cdb Bharat Bhushan
    int tsize;
417 cefd3cdb Bharat Bhushan
418 cefd3cdb Bharat Bhushan
    tsize = booke206_initial_map_tsize(env);
419 cefd3cdb Bharat Bhushan
    return (1ULL << 10 << tsize);
420 cefd3cdb Bharat Bhushan
}
421 cefd3cdb Bharat Bhushan
422 cefd3cdb Bharat Bhushan
static void mmubooke_create_initial_mapping(CPUPPCState *env)
423 cefd3cdb Bharat Bhushan
{
424 cefd3cdb Bharat Bhushan
    ppcmas_tlb_t *tlb = booke206_get_tlbm(env, 1, 0, 0);
425 cefd3cdb Bharat Bhushan
    hwaddr size;
426 cefd3cdb Bharat Bhushan
    int ps;
427 cefd3cdb Bharat Bhushan
428 cefd3cdb Bharat Bhushan
    ps = booke206_initial_map_tsize(env);
429 cba2026a Alexander Graf
    size = (ps << MAS1_TSIZE_SHIFT);
430 d1e256fe Alexander Graf
    tlb->mas1 = MAS1_VALID | size;
431 cba2026a Alexander Graf
    tlb->mas2 = 0;
432 cba2026a Alexander Graf
    tlb->mas7_3 = 0;
433 d1e256fe Alexander Graf
    tlb->mas7_3 |= MAS3_UR | MAS3_UW | MAS3_UX | MAS3_SR | MAS3_SW | MAS3_SX;
434 93dd5e85 Scott Wood
435 93dd5e85 Scott Wood
    env->tlb_dirty = true;
436 3b989d49 Alexander Graf
}
437 3b989d49 Alexander Graf
438 b3305981 Scott Wood
static void ppce500_cpu_reset_sec(void *opaque)
439 5c145dac Alexander Graf
{
440 38f92da6 Andreas Färber
    PowerPCCPU *cpu = opaque;
441 259186a7 Andreas Färber
    CPUState *cs = CPU(cpu);
442 38f92da6 Andreas Färber
    CPUPPCState *env = &cpu->env;
443 5c145dac Alexander Graf
444 259186a7 Andreas Färber
    cpu_reset(cs);
445 5c145dac Alexander Graf
446 5c145dac Alexander Graf
    /* Secondary CPU starts in halted state for now. Needs to change when
447 5c145dac Alexander Graf
       implementing non-kernel boot. */
448 259186a7 Andreas Färber
    cs->halted = 1;
449 5c145dac Alexander Graf
    env->exception_index = EXCP_HLT;
450 3b989d49 Alexander Graf
}
451 3b989d49 Alexander Graf
452 b3305981 Scott Wood
static void ppce500_cpu_reset(void *opaque)
453 3b989d49 Alexander Graf
{
454 38f92da6 Andreas Färber
    PowerPCCPU *cpu = opaque;
455 259186a7 Andreas Färber
    CPUState *cs = CPU(cpu);
456 38f92da6 Andreas Färber
    CPUPPCState *env = &cpu->env;
457 3b989d49 Alexander Graf
    struct boot_info *bi = env->load_info;
458 3b989d49 Alexander Graf
459 259186a7 Andreas Färber
    cpu_reset(cs);
460 3b989d49 Alexander Graf
461 3b989d49 Alexander Graf
    /* Set initial guest state. */
462 259186a7 Andreas Färber
    cs->halted = 0;
463 3b989d49 Alexander Graf
    env->gpr[1] = (16<<20) - 8;
464 3b989d49 Alexander Graf
    env->gpr[3] = bi->dt_base;
465 cefd3cdb Bharat Bhushan
    env->gpr[4] = 0;
466 cefd3cdb Bharat Bhushan
    env->gpr[5] = 0;
467 cefd3cdb Bharat Bhushan
    env->gpr[6] = EPAPR_MAGIC;
468 cefd3cdb Bharat Bhushan
    env->gpr[7] = mmubooke_initial_mapsize(env);
469 cefd3cdb Bharat Bhushan
    env->gpr[8] = 0;
470 cefd3cdb Bharat Bhushan
    env->gpr[9] = 0;
471 3b989d49 Alexander Graf
    env->nip = bi->entry;
472 cba2026a Alexander Graf
    mmubooke_create_initial_mapping(env);
473 3b989d49 Alexander Graf
}
474 3b989d49 Alexander Graf
475 d85937e6 Scott Wood
static DeviceState *ppce500_init_mpic_qemu(PPCE500Params *params,
476 d85937e6 Scott Wood
                                           qemu_irq **irqs)
477 82fc73b6 Scott Wood
{
478 82fc73b6 Scott Wood
    DeviceState *dev;
479 82fc73b6 Scott Wood
    SysBusDevice *s;
480 82fc73b6 Scott Wood
    int i, j, k;
481 82fc73b6 Scott Wood
482 e1766344 Andreas Färber
    dev = qdev_create(NULL, TYPE_OPENPIC);
483 82fc73b6 Scott Wood
    qdev_prop_set_uint32(dev, "model", params->mpic_version);
484 d85937e6 Scott Wood
    qdev_prop_set_uint32(dev, "nb_cpus", smp_cpus);
485 d85937e6 Scott Wood
486 82fc73b6 Scott Wood
    qdev_init_nofail(dev);
487 82fc73b6 Scott Wood
    s = SYS_BUS_DEVICE(dev);
488 82fc73b6 Scott Wood
489 82fc73b6 Scott Wood
    k = 0;
490 82fc73b6 Scott Wood
    for (i = 0; i < smp_cpus; i++) {
491 82fc73b6 Scott Wood
        for (j = 0; j < OPENPIC_OUTPUT_NB; j++) {
492 82fc73b6 Scott Wood
            sysbus_connect_irq(s, k++, irqs[i][j]);
493 82fc73b6 Scott Wood
        }
494 82fc73b6 Scott Wood
    }
495 82fc73b6 Scott Wood
496 d85937e6 Scott Wood
    return dev;
497 d85937e6 Scott Wood
}
498 d85937e6 Scott Wood
499 d85937e6 Scott Wood
static DeviceState *ppce500_init_mpic_kvm(PPCE500Params *params,
500 d85937e6 Scott Wood
                                          qemu_irq **irqs)
501 d85937e6 Scott Wood
{
502 d85937e6 Scott Wood
    DeviceState *dev;
503 d85937e6 Scott Wood
    CPUPPCState *env;
504 d85937e6 Scott Wood
    CPUState *cs;
505 d85937e6 Scott Wood
    int r;
506 d85937e6 Scott Wood
507 dd49c038 Andreas Färber
    dev = qdev_create(NULL, TYPE_KVM_OPENPIC);
508 d85937e6 Scott Wood
    qdev_prop_set_uint32(dev, "model", params->mpic_version);
509 d85937e6 Scott Wood
510 d85937e6 Scott Wood
    r = qdev_init(dev);
511 d85937e6 Scott Wood
    if (r) {
512 d85937e6 Scott Wood
        return NULL;
513 d85937e6 Scott Wood
    }
514 d85937e6 Scott Wood
515 d85937e6 Scott Wood
    for (env = first_cpu; env != NULL; env = env->next_cpu) {
516 d85937e6 Scott Wood
        cs = ENV_GET_CPU(env);
517 d85937e6 Scott Wood
518 d85937e6 Scott Wood
        if (kvm_openpic_connect_vcpu(dev, cs)) {
519 d85937e6 Scott Wood
            fprintf(stderr, "%s: failed to connect vcpu to irqchip\n",
520 d85937e6 Scott Wood
                    __func__);
521 d85937e6 Scott Wood
            abort();
522 d85937e6 Scott Wood
        }
523 d85937e6 Scott Wood
    }
524 d85937e6 Scott Wood
525 d85937e6 Scott Wood
    return dev;
526 d85937e6 Scott Wood
}
527 d85937e6 Scott Wood
528 d85937e6 Scott Wood
static qemu_irq *ppce500_init_mpic(PPCE500Params *params, MemoryRegion *ccsr,
529 d85937e6 Scott Wood
                                   qemu_irq **irqs)
530 d85937e6 Scott Wood
{
531 d85937e6 Scott Wood
    QemuOptsList *list;
532 d85937e6 Scott Wood
    qemu_irq *mpic;
533 d85937e6 Scott Wood
    DeviceState *dev = NULL;
534 d85937e6 Scott Wood
    SysBusDevice *s;
535 d85937e6 Scott Wood
    int i;
536 d85937e6 Scott Wood
537 d85937e6 Scott Wood
    mpic = g_new(qemu_irq, 256);
538 d85937e6 Scott Wood
539 d85937e6 Scott Wood
    if (kvm_enabled()) {
540 d85937e6 Scott Wood
        bool irqchip_allowed = true, irqchip_required = false;
541 d85937e6 Scott Wood
542 d85937e6 Scott Wood
        list = qemu_find_opts("machine");
543 d85937e6 Scott Wood
        if (!QTAILQ_EMPTY(&list->head)) {
544 d85937e6 Scott Wood
            irqchip_allowed = qemu_opt_get_bool(QTAILQ_FIRST(&list->head),
545 d85937e6 Scott Wood
                                                "kernel_irqchip", true);
546 d85937e6 Scott Wood
            irqchip_required = qemu_opt_get_bool(QTAILQ_FIRST(&list->head),
547 d85937e6 Scott Wood
                                                 "kernel_irqchip", false);
548 d85937e6 Scott Wood
        }
549 d85937e6 Scott Wood
550 d85937e6 Scott Wood
        if (irqchip_allowed) {
551 d85937e6 Scott Wood
            dev = ppce500_init_mpic_kvm(params, irqs);
552 d85937e6 Scott Wood
        }
553 d85937e6 Scott Wood
554 d85937e6 Scott Wood
        if (irqchip_required && !dev) {
555 d85937e6 Scott Wood
            fprintf(stderr, "%s: irqchip requested but unavailable\n",
556 d85937e6 Scott Wood
                    __func__);
557 d85937e6 Scott Wood
            abort();
558 d85937e6 Scott Wood
        }
559 d85937e6 Scott Wood
    }
560 d85937e6 Scott Wood
561 d85937e6 Scott Wood
    if (!dev) {
562 d85937e6 Scott Wood
        dev = ppce500_init_mpic_qemu(params, irqs);
563 d85937e6 Scott Wood
    }
564 d85937e6 Scott Wood
565 82fc73b6 Scott Wood
    for (i = 0; i < 256; i++) {
566 82fc73b6 Scott Wood
        mpic[i] = qdev_get_gpio_in(dev, i);
567 82fc73b6 Scott Wood
    }
568 82fc73b6 Scott Wood
569 d85937e6 Scott Wood
    s = SYS_BUS_DEVICE(dev);
570 82fc73b6 Scott Wood
    memory_region_add_subregion(ccsr, MPC8544_MPIC_REGS_OFFSET,
571 82fc73b6 Scott Wood
                                s->mmio[0].memory);
572 82fc73b6 Scott Wood
573 82fc73b6 Scott Wood
    return mpic;
574 82fc73b6 Scott Wood
}
575 82fc73b6 Scott Wood
576 e6eaabeb Scott Wood
void ppce500_init(PPCE500Params *params)
577 1db09b84 aurel32
{
578 39186d8a Richard Henderson
    MemoryRegion *address_space_mem = get_system_memory();
579 2646c133 Avi Kivity
    MemoryRegion *ram = g_new(MemoryRegion, 1);
580 1db09b84 aurel32
    PCIBus *pci_bus;
581 e2684c0b Andreas Färber
    CPUPPCState *env = NULL;
582 1db09b84 aurel32
    uint64_t elf_entry;
583 1db09b84 aurel32
    uint64_t elf_lowaddr;
584 a8170e5e Avi Kivity
    hwaddr entry=0;
585 a8170e5e Avi Kivity
    hwaddr loadaddr=UIMAGE_LOAD_BASE;
586 1db09b84 aurel32
    target_long kernel_size=0;
587 75bb6589 Liu Yu
    target_ulong dt_base = 0;
588 75bb6589 Liu Yu
    target_ulong initrd_base = 0;
589 528e536e Alexander Graf
    target_long initrd_size = 0;
590 528e536e Alexander Graf
    target_ulong cur_base = 0;
591 82fc73b6 Scott Wood
    int i;
592 1db09b84 aurel32
    unsigned int pci_irq_nrs[4] = {1, 2, 3, 4};
593 a915249f Alexander Graf
    qemu_irq **irqs, *mpic;
594 be13cc7a Alexander Graf
    DeviceState *dev;
595 e2684c0b Andreas Färber
    CPUPPCState *firstenv = NULL;
596 3eddc1be Bharat Bhushan
    MemoryRegion *ccsr_addr_space;
597 dffb1dc2 Bharat Bhushan
    SysBusDevice *s;
598 3eddc1be Bharat Bhushan
    PPCE500CCSRState *ccsr;
599 1db09b84 aurel32
600 e61c36d5 Alexander Graf
    /* Setup CPUs */
601 e6eaabeb Scott Wood
    if (params->cpu_model == NULL) {
602 e6eaabeb Scott Wood
        params->cpu_model = "e500v2_v30";
603 ef250db6 Alexander Graf
    }
604 ef250db6 Alexander Graf
605 a915249f Alexander Graf
    irqs = g_malloc0(smp_cpus * sizeof(qemu_irq *));
606 a915249f Alexander Graf
    irqs[0] = g_malloc0(smp_cpus * sizeof(qemu_irq) * OPENPIC_OUTPUT_NB);
607 e61c36d5 Alexander Graf
    for (i = 0; i < smp_cpus; i++) {
608 397b457d Andreas Färber
        PowerPCCPU *cpu;
609 55e5c285 Andreas Färber
        CPUState *cs;
610 e61c36d5 Alexander Graf
        qemu_irq *input;
611 397b457d Andreas Färber
612 e6eaabeb Scott Wood
        cpu = cpu_ppc_init(params->cpu_model);
613 397b457d Andreas Färber
        if (cpu == NULL) {
614 e61c36d5 Alexander Graf
            fprintf(stderr, "Unable to initialize CPU!\n");
615 e61c36d5 Alexander Graf
            exit(1);
616 e61c36d5 Alexander Graf
        }
617 397b457d Andreas Färber
        env = &cpu->env;
618 55e5c285 Andreas Färber
        cs = CPU(cpu);
619 1db09b84 aurel32
620 e61c36d5 Alexander Graf
        if (!firstenv) {
621 e61c36d5 Alexander Graf
            firstenv = env;
622 e61c36d5 Alexander Graf
        }
623 1db09b84 aurel32
624 a915249f Alexander Graf
        irqs[i] = irqs[0] + (i * OPENPIC_OUTPUT_NB);
625 a915249f Alexander Graf
        input = (qemu_irq *)env->irq_inputs;
626 a915249f Alexander Graf
        irqs[i][OPENPIC_OUTPUT_INT] = input[PPCE500_INPUT_INT];
627 a915249f Alexander Graf
        irqs[i][OPENPIC_OUTPUT_CINT] = input[PPCE500_INPUT_CINT];
628 55e5c285 Andreas Färber
        env->spr[SPR_BOOKE_PIR] = cs->cpu_index = i;
629 68c2dd70 Alexander Graf
        env->mpic_iack = MPC8544_CCSRBAR_BASE +
630 bd25922e Scott Wood
                         MPC8544_MPIC_REGS_OFFSET + 0xa0;
631 3b989d49 Alexander Graf
632 a34a92b9 Andreas Färber
        ppc_booke_timers_init(cpu, 400000000, PPC_TIMER_E500);
633 e61c36d5 Alexander Graf
634 e61c36d5 Alexander Graf
        /* Register reset handler */
635 5c145dac Alexander Graf
        if (!i) {
636 5c145dac Alexander Graf
            /* Primary CPU */
637 5c145dac Alexander Graf
            struct boot_info *boot_info;
638 5c145dac Alexander Graf
            boot_info = g_malloc0(sizeof(struct boot_info));
639 b3305981 Scott Wood
            qemu_register_reset(ppce500_cpu_reset, cpu);
640 5c145dac Alexander Graf
            env->load_info = boot_info;
641 5c145dac Alexander Graf
        } else {
642 5c145dac Alexander Graf
            /* Secondary CPUs */
643 b3305981 Scott Wood
            qemu_register_reset(ppce500_cpu_reset_sec, cpu);
644 5c145dac Alexander Graf
        }
645 e61c36d5 Alexander Graf
    }
646 3b989d49 Alexander Graf
647 e61c36d5 Alexander Graf
    env = firstenv;
648 3b989d49 Alexander Graf
649 1db09b84 aurel32
    /* Fixup Memory size on a alignment boundary */
650 1db09b84 aurel32
    ram_size &= ~(RAM_SIZES_ALIGN - 1);
651 43d03f29 Tiejun Chen
    params->ram_size = ram_size;
652 1db09b84 aurel32
653 1db09b84 aurel32
    /* Register Memory */
654 2c9b15ca Paolo Bonzini
    memory_region_init_ram(ram, NULL, "mpc8544ds.ram", ram_size);
655 c5705a77 Avi Kivity
    vmstate_register_ram_global(ram);
656 2646c133 Avi Kivity
    memory_region_add_subregion(address_space_mem, 0, ram);
657 1db09b84 aurel32
658 3eddc1be Bharat Bhushan
    dev = qdev_create(NULL, "e500-ccsr");
659 3eddc1be Bharat Bhushan
    object_property_add_child(qdev_get_machine(), "e500-ccsr",
660 3eddc1be Bharat Bhushan
                              OBJECT(dev), NULL);
661 3eddc1be Bharat Bhushan
    qdev_init_nofail(dev);
662 3eddc1be Bharat Bhushan
    ccsr = CCSR(dev);
663 3eddc1be Bharat Bhushan
    ccsr_addr_space = &ccsr->ccsr_space;
664 3eddc1be Bharat Bhushan
    memory_region_add_subregion(address_space_mem, MPC8544_CCSRBAR_BASE,
665 3eddc1be Bharat Bhushan
                                ccsr_addr_space);
666 dffb1dc2 Bharat Bhushan
667 82fc73b6 Scott Wood
    mpic = ppce500_init_mpic(params, ccsr_addr_space, irqs);
668 d0b72631 Alexander Graf
669 1db09b84 aurel32
    /* Serial */
670 2d48377a Blue Swirl
    if (serial_hds[0]) {
671 3eddc1be Bharat Bhushan
        serial_mm_init(ccsr_addr_space, MPC8544_SERIAL0_REGS_OFFSET,
672 cdbb912a Alexander Graf
                       0, mpic[42], 399193,
673 2ff0c7c3 Richard Henderson
                       serial_hds[0], DEVICE_BIG_ENDIAN);
674 2d48377a Blue Swirl
    }
675 1db09b84 aurel32
676 2d48377a Blue Swirl
    if (serial_hds[1]) {
677 3eddc1be Bharat Bhushan
        serial_mm_init(ccsr_addr_space, MPC8544_SERIAL1_REGS_OFFSET,
678 cdbb912a Alexander Graf
                       0, mpic[42], 399193,
679 59de4f98 Bharat Bhushan
                       serial_hds[1], DEVICE_BIG_ENDIAN);
680 2d48377a Blue Swirl
    }
681 1db09b84 aurel32
682 b0fb8423 Alexander Graf
    /* General Utility device */
683 dffb1dc2 Bharat Bhushan
    dev = qdev_create(NULL, "mpc8544-guts");
684 dffb1dc2 Bharat Bhushan
    qdev_init_nofail(dev);
685 dffb1dc2 Bharat Bhushan
    s = SYS_BUS_DEVICE(dev);
686 3eddc1be Bharat Bhushan
    memory_region_add_subregion(ccsr_addr_space, MPC8544_UTIL_OFFSET,
687 dffb1dc2 Bharat Bhushan
                                sysbus_mmio_get_region(s, 0));
688 b0fb8423 Alexander Graf
689 1db09b84 aurel32
    /* PCI */
690 dffb1dc2 Bharat Bhushan
    dev = qdev_create(NULL, "e500-pcihost");
691 492ec48d Alexander Graf
    qdev_prop_set_uint32(dev, "first_slot", params->pci_first_slot);
692 dffb1dc2 Bharat Bhushan
    qdev_init_nofail(dev);
693 dffb1dc2 Bharat Bhushan
    s = SYS_BUS_DEVICE(dev);
694 dffb1dc2 Bharat Bhushan
    sysbus_connect_irq(s, 0, mpic[pci_irq_nrs[0]]);
695 dffb1dc2 Bharat Bhushan
    sysbus_connect_irq(s, 1, mpic[pci_irq_nrs[1]]);
696 dffb1dc2 Bharat Bhushan
    sysbus_connect_irq(s, 2, mpic[pci_irq_nrs[2]]);
697 dffb1dc2 Bharat Bhushan
    sysbus_connect_irq(s, 3, mpic[pci_irq_nrs[3]]);
698 3eddc1be Bharat Bhushan
    memory_region_add_subregion(ccsr_addr_space, MPC8544_PCI_REGS_OFFSET,
699 dffb1dc2 Bharat Bhushan
                                sysbus_mmio_get_region(s, 0));
700 dffb1dc2 Bharat Bhushan
701 d461e3b9 Alexander Graf
    pci_bus = (PCIBus *)qdev_get_child_bus(dev, "pci.0");
702 1db09b84 aurel32
    if (!pci_bus)
703 1db09b84 aurel32
        printf("couldn't create PCI controller!\n");
704 1db09b84 aurel32
705 1356b98d Andreas Färber
    sysbus_mmio_map(SYS_BUS_DEVICE(dev), 1, MPC8544_PCI_IO);
706 1db09b84 aurel32
707 1db09b84 aurel32
    if (pci_bus) {
708 1db09b84 aurel32
        /* Register network interfaces. */
709 1db09b84 aurel32
        for (i = 0; i < nb_nics; i++) {
710 07caea31 Markus Armbruster
            pci_nic_init_nofail(&nd_table[i], "virtio", NULL);
711 1db09b84 aurel32
        }
712 1db09b84 aurel32
    }
713 1db09b84 aurel32
714 5c145dac Alexander Graf
    /* Register spinning region */
715 5c145dac Alexander Graf
    sysbus_create_simple("e500-spin", MPC8544_SPIN_BASE, NULL);
716 5c145dac Alexander Graf
717 1db09b84 aurel32
    /* Load kernel. */
718 e6eaabeb Scott Wood
    if (params->kernel_filename) {
719 e6eaabeb Scott Wood
        kernel_size = load_uimage(params->kernel_filename, &entry,
720 e6eaabeb Scott Wood
                                  &loadaddr, NULL);
721 1db09b84 aurel32
        if (kernel_size < 0) {
722 e6eaabeb Scott Wood
            kernel_size = load_elf(params->kernel_filename, NULL, NULL,
723 e6eaabeb Scott Wood
                                   &elf_entry, &elf_lowaddr, NULL, 1,
724 e6eaabeb Scott Wood
                                   ELF_MACHINE, 0);
725 1db09b84 aurel32
            entry = elf_entry;
726 1db09b84 aurel32
            loadaddr = elf_lowaddr;
727 1db09b84 aurel32
        }
728 1db09b84 aurel32
        /* XXX try again as binary */
729 1db09b84 aurel32
        if (kernel_size < 0) {
730 1db09b84 aurel32
            fprintf(stderr, "qemu: could not load kernel '%s'\n",
731 e6eaabeb Scott Wood
                    params->kernel_filename);
732 1db09b84 aurel32
            exit(1);
733 1db09b84 aurel32
        }
734 528e536e Alexander Graf
735 528e536e Alexander Graf
        cur_base = loadaddr + kernel_size;
736 b8dec144 Alexander Graf
737 b8dec144 Alexander Graf
        /* Reserve space for dtb */
738 b8dec144 Alexander Graf
        dt_base = (cur_base + DTC_LOAD_PAD) & ~DTC_PAD_MASK;
739 b8dec144 Alexander Graf
        cur_base += DTB_MAX_SIZE;
740 1db09b84 aurel32
    }
741 1db09b84 aurel32
742 1db09b84 aurel32
    /* Load initrd. */
743 e6eaabeb Scott Wood
    if (params->initrd_filename) {
744 528e536e Alexander Graf
        initrd_base = (cur_base + INITRD_LOAD_PAD) & ~INITRD_PAD_MASK;
745 e6eaabeb Scott Wood
        initrd_size = load_image_targphys(params->initrd_filename, initrd_base,
746 d7585251 pbrook
                                          ram_size - initrd_base);
747 1db09b84 aurel32
748 1db09b84 aurel32
        if (initrd_size < 0) {
749 1db09b84 aurel32
            fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
750 e6eaabeb Scott Wood
                    params->initrd_filename);
751 1db09b84 aurel32
            exit(1);
752 1db09b84 aurel32
        }
753 528e536e Alexander Graf
754 528e536e Alexander Graf
        cur_base = initrd_base + initrd_size;
755 1db09b84 aurel32
    }
756 1db09b84 aurel32
757 1db09b84 aurel32
    /* If we're loading a kernel directly, we must load the device tree too. */
758 e6eaabeb Scott Wood
    if (params->kernel_filename) {
759 5c145dac Alexander Graf
        struct boot_info *boot_info;
760 cba2026a Alexander Graf
        int dt_size;
761 5c145dac Alexander Graf
762 e6eaabeb Scott Wood
        dt_size = ppce500_load_device_tree(env, params, dt_base, initrd_base,
763 e6eaabeb Scott Wood
                                           initrd_size);
764 cba2026a Alexander Graf
        if (dt_size < 0) {
765 1db09b84 aurel32
            fprintf(stderr, "couldn't load device tree\n");
766 1db09b84 aurel32
            exit(1);
767 1db09b84 aurel32
        }
768 b8dec144 Alexander Graf
        assert(dt_size < DTB_MAX_SIZE);
769 1db09b84 aurel32
770 e61c36d5 Alexander Graf
        boot_info = env->load_info;
771 3b989d49 Alexander Graf
        boot_info->entry = entry;
772 3b989d49 Alexander Graf
        boot_info->dt_base = dt_base;
773 cba2026a Alexander Graf
        boot_info->dt_size = dt_size;
774 1db09b84 aurel32
    }
775 1db09b84 aurel32
776 3b989d49 Alexander Graf
    if (kvm_enabled()) {
777 1db09b84 aurel32
        kvmppc_init();
778 3b989d49 Alexander Graf
    }
779 1db09b84 aurel32
}
780 3eddc1be Bharat Bhushan
781 3eddc1be Bharat Bhushan
static int e500_ccsr_initfn(SysBusDevice *dev)
782 3eddc1be Bharat Bhushan
{
783 3eddc1be Bharat Bhushan
    PPCE500CCSRState *ccsr;
784 3eddc1be Bharat Bhushan
785 3eddc1be Bharat Bhushan
    ccsr = CCSR(dev);
786 2c9b15ca Paolo Bonzini
    memory_region_init(&ccsr->ccsr_space, NULL, "e500-ccsr",
787 3eddc1be Bharat Bhushan
                       MPC8544_CCSRBAR_SIZE);
788 3eddc1be Bharat Bhushan
    return 0;
789 3eddc1be Bharat Bhushan
}
790 3eddc1be Bharat Bhushan
791 3eddc1be Bharat Bhushan
static void e500_ccsr_class_init(ObjectClass *klass, void *data)
792 3eddc1be Bharat Bhushan
{
793 3eddc1be Bharat Bhushan
    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
794 3eddc1be Bharat Bhushan
    k->init = e500_ccsr_initfn;
795 3eddc1be Bharat Bhushan
}
796 3eddc1be Bharat Bhushan
797 3eddc1be Bharat Bhushan
static const TypeInfo e500_ccsr_info = {
798 3eddc1be Bharat Bhushan
    .name          = TYPE_CCSR,
799 3eddc1be Bharat Bhushan
    .parent        = TYPE_SYS_BUS_DEVICE,
800 3eddc1be Bharat Bhushan
    .instance_size = sizeof(PPCE500CCSRState),
801 3eddc1be Bharat Bhushan
    .class_init    = e500_ccsr_class_init,
802 3eddc1be Bharat Bhushan
};
803 3eddc1be Bharat Bhushan
804 3eddc1be Bharat Bhushan
static void e500_register_types(void)
805 3eddc1be Bharat Bhushan
{
806 3eddc1be Bharat Bhushan
    type_register_static(&e500_ccsr_info);
807 3eddc1be Bharat Bhushan
}
808 3eddc1be Bharat Bhushan
809 3eddc1be Bharat Bhushan
type_init(e500_register_types)