Statistics
| Branch: | Revision:

root / hw / ppce500_mpc8544ds.c @ 37952117

History | View | Annotate | Download (21.5 kB)

1 1db09b84 aurel32
/*
2 5cbdb3a3 Stefan Weil
 * QEMU PowerPC MPC8544DS board emulation
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 1db09b84 aurel32
#include "net.h"
20 1db09b84 aurel32
#include "hw.h"
21 1db09b84 aurel32
#include "pc.h"
22 1db09b84 aurel32
#include "pci.h"
23 1db09b84 aurel32
#include "boards.h"
24 1db09b84 aurel32
#include "sysemu.h"
25 1db09b84 aurel32
#include "kvm.h"
26 1db09b84 aurel32
#include "kvm_ppc.h"
27 1db09b84 aurel32
#include "device_tree.h"
28 1db09b84 aurel32
#include "openpic.h"
29 3b989d49 Alexander Graf
#include "ppc.h"
30 ca20cf32 Blue Swirl
#include "loader.h"
31 ca20cf32 Blue Swirl
#include "elf.h"
32 be13cc7a Alexander Graf
#include "sysbus.h"
33 39186d8a Richard Henderson
#include "exec-memory.h"
34 cba2026a Alexander Graf
#include "host-utils.h"
35 1db09b84 aurel32
36 1db09b84 aurel32
#define BINARY_DEVICE_TREE_FILE    "mpc8544ds.dtb"
37 1db09b84 aurel32
#define UIMAGE_LOAD_BASE           0
38 75bb6589 Liu Yu
#define DTC_LOAD_PAD               0x500000
39 75bb6589 Liu Yu
#define DTC_PAD_MASK               0xFFFFF
40 75bb6589 Liu Yu
#define INITRD_LOAD_PAD            0x2000000
41 75bb6589 Liu Yu
#define INITRD_PAD_MASK            0xFFFFFF
42 1db09b84 aurel32
43 1db09b84 aurel32
#define RAM_SIZES_ALIGN            (64UL << 20)
44 1db09b84 aurel32
45 ed2bc496 Alexander Graf
#define MPC8544_CCSRBAR_BASE       0xE0000000ULL
46 ed2bc496 Alexander Graf
#define MPC8544_CCSRBAR_SIZE       0x00100000ULL
47 ed2bc496 Alexander Graf
#define MPC8544_MPIC_REGS_BASE     (MPC8544_CCSRBAR_BASE + 0x40000ULL)
48 ed2bc496 Alexander Graf
#define MPC8544_SERIAL0_REGS_BASE  (MPC8544_CCSRBAR_BASE + 0x4500ULL)
49 ed2bc496 Alexander Graf
#define MPC8544_SERIAL1_REGS_BASE  (MPC8544_CCSRBAR_BASE + 0x4600ULL)
50 ed2bc496 Alexander Graf
#define MPC8544_PCI_REGS_BASE      (MPC8544_CCSRBAR_BASE + 0x8000ULL)
51 ed2bc496 Alexander Graf
#define MPC8544_PCI_REGS_SIZE      0x1000ULL
52 ed2bc496 Alexander Graf
#define MPC8544_PCI_IO             0xE1000000ULL
53 ed2bc496 Alexander Graf
#define MPC8544_PCI_IOLEN          0x10000ULL
54 ed2bc496 Alexander Graf
#define MPC8544_UTIL_BASE          (MPC8544_CCSRBAR_BASE + 0xe0000ULL)
55 ed2bc496 Alexander Graf
#define MPC8544_SPIN_BASE          0xEF000000ULL
56 1db09b84 aurel32
57 3b989d49 Alexander Graf
struct boot_info
58 3b989d49 Alexander Graf
{
59 3b989d49 Alexander Graf
    uint32_t dt_base;
60 cba2026a Alexander Graf
    uint32_t dt_size;
61 3b989d49 Alexander Graf
    uint32_t entry;
62 3b989d49 Alexander Graf
};
63 3b989d49 Alexander Graf
64 0dbc0798 Alexander Graf
static void pci_map_create(void *fdt, uint32_t *pci_map, uint32_t mpic)
65 0dbc0798 Alexander Graf
{
66 0dbc0798 Alexander Graf
    int i;
67 0dbc0798 Alexander Graf
    const uint32_t tmp[] = {
68 0dbc0798 Alexander Graf
                             /* IDSEL 0x11 J17 Slot 1 */
69 518c7fb4 Alexander Graf
                             0x8800, 0x0, 0x0, 0x1, mpic, 0x2, 0x1, 0x0, 0x0,
70 518c7fb4 Alexander Graf
                             0x8800, 0x0, 0x0, 0x2, mpic, 0x3, 0x1, 0x0, 0x0,
71 518c7fb4 Alexander Graf
                             0x8800, 0x0, 0x0, 0x3, mpic, 0x4, 0x1, 0x0, 0x0,
72 518c7fb4 Alexander Graf
                             0x8800, 0x0, 0x0, 0x4, mpic, 0x1, 0x1, 0x0, 0x0,
73 0dbc0798 Alexander Graf
74 0dbc0798 Alexander Graf
                             /* IDSEL 0x12 J16 Slot 2 */
75 518c7fb4 Alexander Graf
                             0x9000, 0x0, 0x0, 0x1, mpic, 0x3, 0x1, 0x0, 0x0,
76 518c7fb4 Alexander Graf
                             0x9000, 0x0, 0x0, 0x2, mpic, 0x4, 0x1, 0x0, 0x0,
77 518c7fb4 Alexander Graf
                             0x9000, 0x0, 0x0, 0x3, mpic, 0x2, 0x1, 0x0, 0x0,
78 518c7fb4 Alexander Graf
                             0x9000, 0x0, 0x0, 0x4, mpic, 0x1, 0x1, 0x0, 0x0,
79 0dbc0798 Alexander Graf
                           };
80 518c7fb4 Alexander Graf
    for (i = 0; i < ARRAY_SIZE(tmp); i++) {
81 0dbc0798 Alexander Graf
        pci_map[i] = cpu_to_be32(tmp[i]);
82 0dbc0798 Alexander Graf
    }
83 0dbc0798 Alexander Graf
}
84 0dbc0798 Alexander Graf
85 a053a7ce Alexander Graf
static void dt_serial_create(void *fdt, unsigned long long offset,
86 a053a7ce Alexander Graf
                             const char *soc, const char *mpic,
87 a053a7ce Alexander Graf
                             const char *alias, int idx, bool defcon)
88 a053a7ce Alexander Graf
{
89 a053a7ce Alexander Graf
    char ser[128];
90 a053a7ce Alexander Graf
91 a053a7ce Alexander Graf
    snprintf(ser, sizeof(ser), "%s/serial@%llx", soc, offset);
92 a053a7ce Alexander Graf
    qemu_devtree_add_subnode(fdt, ser);
93 a053a7ce Alexander Graf
    qemu_devtree_setprop_string(fdt, ser, "device_type", "serial");
94 a053a7ce Alexander Graf
    qemu_devtree_setprop_string(fdt, ser, "compatible", "ns16550");
95 a053a7ce Alexander Graf
    qemu_devtree_setprop_cells(fdt, ser, "reg", offset, 0x100);
96 a053a7ce Alexander Graf
    qemu_devtree_setprop_cell(fdt, ser, "cell-index", idx);
97 a053a7ce Alexander Graf
    qemu_devtree_setprop_cell(fdt, ser, "clock-frequency", 0);
98 a053a7ce Alexander Graf
    qemu_devtree_setprop_cells(fdt, ser, "interrupts", 42, 2, 0, 0);
99 a053a7ce Alexander Graf
    qemu_devtree_setprop_phandle(fdt, ser, "interrupt-parent", mpic);
100 a053a7ce Alexander Graf
    qemu_devtree_setprop_string(fdt, "/aliases", alias, ser);
101 a053a7ce Alexander Graf
102 a053a7ce Alexander Graf
    if (defcon) {
103 a053a7ce Alexander Graf
        qemu_devtree_setprop_string(fdt, "/chosen", "linux,stdout-path", ser);
104 a053a7ce Alexander Graf
    }
105 a053a7ce Alexander Graf
}
106 a053a7ce Alexander Graf
107 e2684c0b Andreas Färber
static int mpc8544_load_device_tree(CPUPPCState *env,
108 5de6b46d Alexander Graf
                                    target_phys_addr_t addr,
109 7f47b41f Alexander Graf
                                    target_phys_addr_t ramsize,
110 5de6b46d Alexander Graf
                                    target_phys_addr_t initrd_base,
111 5de6b46d Alexander Graf
                                    target_phys_addr_t initrd_size,
112 5de6b46d Alexander Graf
                                    const char *kernel_cmdline)
113 1db09b84 aurel32
{
114 dbf916d8 Aurelien Jarno
    int ret = -1;
115 3627757e Alexander Graf
    uint64_t mem_reg_property[] = { 0, cpu_to_be64(ramsize) };
116 7ec632b4 pbrook
    int fdt_size;
117 dbf916d8 Aurelien Jarno
    void *fdt;
118 5de6b46d Alexander Graf
    uint8_t hypercall[16];
119 911d6e7a Alexander Graf
    uint32_t clock_freq = 400000000;
120 911d6e7a Alexander Graf
    uint32_t tb_freq = 400000000;
121 621d05e3 Alexander Graf
    int i;
122 caedc737 Alexander Graf
    const char *compatible = "MPC8544DS\0MPC85xxDS";
123 caedc737 Alexander Graf
    int compatible_len = sizeof("MPC8544DS\0MPC85xxDS");
124 ebb9518a Alexander Graf
    char compatible_sb[] = "fsl,mpc8544-immr\0simple-bus";
125 51b852b7 Alexander Graf
    char model[] = "MPC8544DS";
126 5da96624 Alexander Graf
    char soc[128];
127 19ac9dea Alexander Graf
    char mpic[128];
128 19ac9dea Alexander Graf
    uint32_t mpic_ph;
129 f5038483 Alexander Graf
    char gutil[128];
130 0dbc0798 Alexander Graf
    char pci[128];
131 518c7fb4 Alexander Graf
    uint32_t pci_map[9 * 8];
132 3627757e Alexander Graf
    uint32_t pci_ranges[14] =
133 3627757e Alexander Graf
        {
134 3627757e Alexander Graf
            0x2000000, 0x0, 0xc0000000,
135 3627757e Alexander Graf
            0x0, 0xc0000000,
136 3627757e Alexander Graf
            0x0, 0x20000000,
137 3627757e Alexander Graf
138 3627757e Alexander Graf
            0x1000000, 0x0, 0x0,
139 3627757e Alexander Graf
            0x0, 0xe1000000,
140 3627757e Alexander Graf
            0x0, 0x10000,
141 3627757e Alexander Graf
        };
142 25b42708 Alexander Graf
    QemuOpts *machine_opts;
143 25b42708 Alexander Graf
    const char *dumpdtb = NULL;
144 d1b93565 Alexander Graf
    const char *dtb_file = NULL;
145 d1b93565 Alexander Graf
146 d1b93565 Alexander Graf
    machine_opts = qemu_opts_find(qemu_find_opts("machine"), 0);
147 d1b93565 Alexander Graf
    if (machine_opts) {
148 caedc737 Alexander Graf
        const char *tmp;
149 d1b93565 Alexander Graf
        dumpdtb = qemu_opt_get(machine_opts, "dumpdtb");
150 d1b93565 Alexander Graf
        dtb_file = qemu_opt_get(machine_opts, "dtb");
151 caedc737 Alexander Graf
        tmp = qemu_opt_get(machine_opts, "dt_compatible");
152 caedc737 Alexander Graf
        if (tmp) {
153 caedc737 Alexander Graf
            compatible = tmp;
154 caedc737 Alexander Graf
            compatible_len = strlen(compatible) + 1;
155 caedc737 Alexander Graf
        }
156 d1b93565 Alexander Graf
    }
157 d1b93565 Alexander Graf
158 d1b93565 Alexander Graf
    if (dtb_file) {
159 d1b93565 Alexander Graf
        char *filename;
160 d1b93565 Alexander Graf
        filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, dtb_file);
161 d1b93565 Alexander Graf
        if (!filename) {
162 d1b93565 Alexander Graf
            goto out;
163 d1b93565 Alexander Graf
        }
164 d1b93565 Alexander Graf
165 d1b93565 Alexander Graf
        fdt = load_device_tree(filename, &fdt_size);
166 d1b93565 Alexander Graf
        if (!fdt) {
167 d1b93565 Alexander Graf
            goto out;
168 d1b93565 Alexander Graf
        }
169 d1b93565 Alexander Graf
        goto done;
170 d1b93565 Alexander Graf
    }
171 1db09b84 aurel32
172 2636fcb6 Alexander Graf
    fdt = create_device_tree(&fdt_size);
173 5cea8590 Paul Brook
    if (fdt == NULL) {
174 5cea8590 Paul Brook
        goto out;
175 5cea8590 Paul Brook
    }
176 1db09b84 aurel32
177 1db09b84 aurel32
    /* Manipulate device tree in memory. */
178 51b852b7 Alexander Graf
    qemu_devtree_setprop_string(fdt, "/", "model", model);
179 caedc737 Alexander Graf
    qemu_devtree_setprop(fdt, "/", "compatible", compatible, compatible_len);
180 3627757e Alexander Graf
    qemu_devtree_setprop_cell(fdt, "/", "#address-cells", 2);
181 3627757e Alexander Graf
    qemu_devtree_setprop_cell(fdt, "/", "#size-cells", 2);
182 51b852b7 Alexander Graf
183 dd0bcfca Alexander Graf
    qemu_devtree_add_subnode(fdt, "/memory");
184 dd0bcfca Alexander Graf
    qemu_devtree_setprop_string(fdt, "/memory", "device_type", "memory");
185 dd0bcfca Alexander Graf
    qemu_devtree_setprop(fdt, "/memory", "reg", mem_reg_property,
186 dd0bcfca Alexander Graf
                         sizeof(mem_reg_property));
187 1db09b84 aurel32
188 f5231aaf Alexander Graf
    qemu_devtree_add_subnode(fdt, "/chosen");
189 3b989d49 Alexander Graf
    if (initrd_size) {
190 3b989d49 Alexander Graf
        ret = qemu_devtree_setprop_cell(fdt, "/chosen", "linux,initrd-start",
191 3b989d49 Alexander Graf
                                        initrd_base);
192 3b989d49 Alexander Graf
        if (ret < 0) {
193 3b989d49 Alexander Graf
            fprintf(stderr, "couldn't set /chosen/linux,initrd-start\n");
194 3b989d49 Alexander Graf
        }
195 1db09b84 aurel32
196 3b989d49 Alexander Graf
        ret = qemu_devtree_setprop_cell(fdt, "/chosen", "linux,initrd-end",
197 3b989d49 Alexander Graf
                                        (initrd_base + initrd_size));
198 3b989d49 Alexander Graf
        if (ret < 0) {
199 3b989d49 Alexander Graf
            fprintf(stderr, "couldn't set /chosen/linux,initrd-end\n");
200 3b989d49 Alexander Graf
        }
201 3b989d49 Alexander Graf
    }
202 1db09b84 aurel32
203 1db09b84 aurel32
    ret = qemu_devtree_setprop_string(fdt, "/chosen", "bootargs",
204 1db09b84 aurel32
                                      kernel_cmdline);
205 1db09b84 aurel32
    if (ret < 0)
206 1db09b84 aurel32
        fprintf(stderr, "couldn't set /chosen/bootargs\n");
207 1db09b84 aurel32
208 1db09b84 aurel32
    if (kvm_enabled()) {
209 911d6e7a Alexander Graf
        /* Read out host's frequencies */
210 911d6e7a Alexander Graf
        clock_freq = kvmppc_get_clockfreq();
211 911d6e7a Alexander Graf
        tb_freq = kvmppc_get_tbfreq();
212 5de6b46d Alexander Graf
213 5de6b46d Alexander Graf
        /* indicate KVM hypercall interface */
214 d50f71a5 Alexander Graf
        qemu_devtree_add_subnode(fdt, "/hypervisor");
215 5de6b46d Alexander Graf
        qemu_devtree_setprop_string(fdt, "/hypervisor", "compatible",
216 5de6b46d Alexander Graf
                                    "linux,kvm");
217 5de6b46d Alexander Graf
        kvmppc_get_hypercall(env, hypercall, sizeof(hypercall));
218 5de6b46d Alexander Graf
        qemu_devtree_setprop(fdt, "/hypervisor", "hcall-instructions",
219 5de6b46d Alexander Graf
                             hypercall, sizeof(hypercall));
220 1db09b84 aurel32
    }
221 3b989d49 Alexander Graf
222 625e665b Alexander Graf
    /* Create CPU nodes */
223 625e665b Alexander Graf
    qemu_devtree_add_subnode(fdt, "/cpus");
224 625e665b Alexander Graf
    qemu_devtree_setprop_cell(fdt, "/cpus", "#address-cells", 1);
225 625e665b Alexander Graf
    qemu_devtree_setprop_cell(fdt, "/cpus", "#size-cells", 0);
226 625e665b Alexander Graf
227 1e3debf0 Alexander Graf
    /* We need to generate the cpu nodes in reverse order, so Linux can pick
228 1e3debf0 Alexander Graf
       the first node as boot node and be happy */
229 1e3debf0 Alexander Graf
    for (i = smp_cpus - 1; i >= 0; i--) {
230 621d05e3 Alexander Graf
        char cpu_name[128];
231 1d2e5c52 Alexander Graf
        uint64_t cpu_release_addr = MPC8544_SPIN_BASE + (i * 0x20);
232 10f25a46 Alexander Graf
233 1e3debf0 Alexander Graf
        for (env = first_cpu; env != NULL; env = env->next_cpu) {
234 1e3debf0 Alexander Graf
            if (env->cpu_index == i) {
235 1e3debf0 Alexander Graf
                break;
236 1e3debf0 Alexander Graf
            }
237 1e3debf0 Alexander Graf
        }
238 1e3debf0 Alexander Graf
239 1e3debf0 Alexander Graf
        if (!env) {
240 1e3debf0 Alexander Graf
            continue;
241 1e3debf0 Alexander Graf
        }
242 1e3debf0 Alexander Graf
243 1e3debf0 Alexander Graf
        snprintf(cpu_name, sizeof(cpu_name), "/cpus/PowerPC,8544@%x", env->cpu_index);
244 1e3debf0 Alexander Graf
        qemu_devtree_add_subnode(fdt, cpu_name);
245 621d05e3 Alexander Graf
        qemu_devtree_setprop_cell(fdt, cpu_name, "clock-frequency", clock_freq);
246 621d05e3 Alexander Graf
        qemu_devtree_setprop_cell(fdt, cpu_name, "timebase-frequency", tb_freq);
247 1e3debf0 Alexander Graf
        qemu_devtree_setprop_string(fdt, cpu_name, "device_type", "cpu");
248 1e3debf0 Alexander Graf
        qemu_devtree_setprop_cell(fdt, cpu_name, "reg", env->cpu_index);
249 1e3debf0 Alexander Graf
        qemu_devtree_setprop_cell(fdt, cpu_name, "d-cache-line-size",
250 1e3debf0 Alexander Graf
                                  env->dcache_line_size);
251 1e3debf0 Alexander Graf
        qemu_devtree_setprop_cell(fdt, cpu_name, "i-cache-line-size",
252 1e3debf0 Alexander Graf
                                  env->icache_line_size);
253 1e3debf0 Alexander Graf
        qemu_devtree_setprop_cell(fdt, cpu_name, "d-cache-size", 0x8000);
254 1e3debf0 Alexander Graf
        qemu_devtree_setprop_cell(fdt, cpu_name, "i-cache-size", 0x8000);
255 1e3debf0 Alexander Graf
        qemu_devtree_setprop_cell(fdt, cpu_name, "bus-frequency", 0);
256 1e3debf0 Alexander Graf
        if (env->cpu_index) {
257 1e3debf0 Alexander Graf
            qemu_devtree_setprop_string(fdt, cpu_name, "status", "disabled");
258 1e3debf0 Alexander Graf
            qemu_devtree_setprop_string(fdt, cpu_name, "enable-method", "spin-table");
259 1d2e5c52 Alexander Graf
            qemu_devtree_setprop_u64(fdt, cpu_name, "cpu-release-addr",
260 1d2e5c52 Alexander Graf
                                     cpu_release_addr);
261 1e3debf0 Alexander Graf
        } else {
262 1e3debf0 Alexander Graf
            qemu_devtree_setprop_string(fdt, cpu_name, "status", "okay");
263 1e3debf0 Alexander Graf
        }
264 1db09b84 aurel32
    }
265 1db09b84 aurel32
266 0cfc6e8d Alexander Graf
    qemu_devtree_add_subnode(fdt, "/aliases");
267 5da96624 Alexander Graf
    /* XXX These should go into their respective devices' code */
268 ed2bc496 Alexander Graf
    snprintf(soc, sizeof(soc), "/soc@%llx", MPC8544_CCSRBAR_BASE);
269 5da96624 Alexander Graf
    qemu_devtree_add_subnode(fdt, soc);
270 5da96624 Alexander Graf
    qemu_devtree_setprop_string(fdt, soc, "device_type", "soc");
271 ebb9518a Alexander Graf
    qemu_devtree_setprop(fdt, soc, "compatible", compatible_sb,
272 ebb9518a Alexander Graf
                         sizeof(compatible_sb));
273 5da96624 Alexander Graf
    qemu_devtree_setprop_cell(fdt, soc, "#address-cells", 1);
274 5da96624 Alexander Graf
    qemu_devtree_setprop_cell(fdt, soc, "#size-cells", 1);
275 3627757e Alexander Graf
    qemu_devtree_setprop_cells(fdt, soc, "ranges", 0x0,
276 3627757e Alexander Graf
                               MPC8544_CCSRBAR_BASE >> 32, MPC8544_CCSRBAR_BASE,
277 5da96624 Alexander Graf
                               MPC8544_CCSRBAR_SIZE);
278 5da96624 Alexander Graf
    /* XXX should contain a reasonable value */
279 5da96624 Alexander Graf
    qemu_devtree_setprop_cell(fdt, soc, "bus-frequency", 0);
280 5da96624 Alexander Graf
281 ed2bc496 Alexander Graf
    snprintf(mpic, sizeof(mpic), "%s/pic@%llx", soc,
282 19ac9dea Alexander Graf
             MPC8544_MPIC_REGS_BASE - MPC8544_CCSRBAR_BASE);
283 19ac9dea Alexander Graf
    qemu_devtree_add_subnode(fdt, mpic);
284 19ac9dea Alexander Graf
    qemu_devtree_setprop_string(fdt, mpic, "device_type", "open-pic");
285 518c7fb4 Alexander Graf
    qemu_devtree_setprop_string(fdt, mpic, "compatible", "fsl,mpic");
286 19ac9dea Alexander Graf
    qemu_devtree_setprop_cells(fdt, mpic, "reg", MPC8544_MPIC_REGS_BASE -
287 19ac9dea Alexander Graf
                               MPC8544_CCSRBAR_BASE, 0x40000);
288 19ac9dea Alexander Graf
    qemu_devtree_setprop_cell(fdt, mpic, "#address-cells", 0);
289 518c7fb4 Alexander Graf
    qemu_devtree_setprop_cell(fdt, mpic, "#interrupt-cells", 4);
290 19ac9dea Alexander Graf
    mpic_ph = qemu_devtree_alloc_phandle(fdt);
291 19ac9dea Alexander Graf
    qemu_devtree_setprop_cell(fdt, mpic, "phandle", mpic_ph);
292 19ac9dea Alexander Graf
    qemu_devtree_setprop_cell(fdt, mpic, "linux,phandle", mpic_ph);
293 19ac9dea Alexander Graf
    qemu_devtree_setprop(fdt, mpic, "interrupt-controller", NULL, 0);
294 518c7fb4 Alexander Graf
    qemu_devtree_setprop(fdt, mpic, "big-endian", NULL, 0);
295 518c7fb4 Alexander Graf
    qemu_devtree_setprop(fdt, mpic, "single-cpu-affinity", NULL, 0);
296 518c7fb4 Alexander Graf
    qemu_devtree_setprop_cell(fdt, mpic, "last-interrupt-source", 255);
297 19ac9dea Alexander Graf
298 0cfc6e8d Alexander Graf
    /*
299 0cfc6e8d Alexander Graf
     * We have to generate ser1 first, because Linux takes the first
300 0cfc6e8d Alexander Graf
     * device it finds in the dt as serial output device. And we generate
301 0cfc6e8d Alexander Graf
     * devices in reverse order to the dt.
302 0cfc6e8d Alexander Graf
     */
303 a053a7ce Alexander Graf
    dt_serial_create(fdt, MPC8544_SERIAL1_REGS_BASE - MPC8544_CCSRBAR_BASE,
304 a053a7ce Alexander Graf
                     soc, mpic, "serial1", 1, false);
305 a053a7ce Alexander Graf
    dt_serial_create(fdt, MPC8544_SERIAL0_REGS_BASE - MPC8544_CCSRBAR_BASE,
306 a053a7ce Alexander Graf
                     soc, mpic, "serial0", 0, true);
307 0cfc6e8d Alexander Graf
308 ed2bc496 Alexander Graf
    snprintf(gutil, sizeof(gutil), "%s/global-utilities@%llx", soc,
309 f5038483 Alexander Graf
             MPC8544_UTIL_BASE - MPC8544_CCSRBAR_BASE);
310 f5038483 Alexander Graf
    qemu_devtree_add_subnode(fdt, gutil);
311 f5038483 Alexander Graf
    qemu_devtree_setprop_string(fdt, gutil, "compatible", "fsl,mpc8544-guts");
312 f5038483 Alexander Graf
    qemu_devtree_setprop_cells(fdt, gutil, "reg", MPC8544_UTIL_BASE -
313 f5038483 Alexander Graf
                               MPC8544_CCSRBAR_BASE, 0x1000);
314 f5038483 Alexander Graf
    qemu_devtree_setprop(fdt, gutil, "fsl,has-rstcr", NULL, 0);
315 f5038483 Alexander Graf
316 ed2bc496 Alexander Graf
    snprintf(pci, sizeof(pci), "/pci@%llx", MPC8544_PCI_REGS_BASE);
317 0dbc0798 Alexander Graf
    qemu_devtree_add_subnode(fdt, pci);
318 0dbc0798 Alexander Graf
    qemu_devtree_setprop_cell(fdt, pci, "cell-index", 0);
319 0dbc0798 Alexander Graf
    qemu_devtree_setprop_string(fdt, pci, "compatible", "fsl,mpc8540-pci");
320 0dbc0798 Alexander Graf
    qemu_devtree_setprop_string(fdt, pci, "device_type", "pci");
321 0dbc0798 Alexander Graf
    qemu_devtree_setprop_cells(fdt, pci, "interrupt-map-mask", 0xf800, 0x0,
322 0dbc0798 Alexander Graf
                               0x0, 0x7);
323 0dbc0798 Alexander Graf
    pci_map_create(fdt, pci_map, qemu_devtree_get_phandle(fdt, mpic));
324 0dbc0798 Alexander Graf
    qemu_devtree_setprop(fdt, pci, "interrupt-map", pci_map, sizeof(pci_map));
325 0dbc0798 Alexander Graf
    qemu_devtree_setprop_phandle(fdt, pci, "interrupt-parent", mpic);
326 518c7fb4 Alexander Graf
    qemu_devtree_setprop_cells(fdt, pci, "interrupts", 24, 2, 0, 0);
327 0dbc0798 Alexander Graf
    qemu_devtree_setprop_cells(fdt, pci, "bus-range", 0, 255);
328 3627757e Alexander Graf
    for (i = 0; i < 14; i++) {
329 0dbc0798 Alexander Graf
        pci_ranges[i] = cpu_to_be32(pci_ranges[i]);
330 0dbc0798 Alexander Graf
    }
331 0dbc0798 Alexander Graf
    qemu_devtree_setprop(fdt, pci, "ranges", pci_ranges, sizeof(pci_ranges));
332 3627757e Alexander Graf
    qemu_devtree_setprop_cells(fdt, pci, "reg", MPC8544_PCI_REGS_BASE >> 32,
333 3627757e Alexander Graf
                               MPC8544_PCI_REGS_BASE, 0, 0x1000);
334 0dbc0798 Alexander Graf
    qemu_devtree_setprop_cell(fdt, pci, "clock-frequency", 66666666);
335 0dbc0798 Alexander Graf
    qemu_devtree_setprop_cell(fdt, pci, "#interrupt-cells", 1);
336 0dbc0798 Alexander Graf
    qemu_devtree_setprop_cell(fdt, pci, "#size-cells", 2);
337 0dbc0798 Alexander Graf
    qemu_devtree_setprop_cell(fdt, pci, "#address-cells", 3);
338 0dbc0798 Alexander Graf
    qemu_devtree_setprop_string(fdt, "/aliases", "pci0", pci);
339 0dbc0798 Alexander Graf
340 d1b93565 Alexander Graf
done:
341 25b42708 Alexander Graf
    if (dumpdtb) {
342 25b42708 Alexander Graf
        /* Dump the dtb to a file and quit */
343 25b42708 Alexander Graf
        FILE *f = fopen(dumpdtb, "wb");
344 25b42708 Alexander Graf
        size_t len;
345 25b42708 Alexander Graf
        len = fwrite(fdt, fdt_size, 1, f);
346 25b42708 Alexander Graf
        fclose(f);
347 25b42708 Alexander Graf
        if (len != fdt_size) {
348 25b42708 Alexander Graf
            exit(1);
349 25b42708 Alexander Graf
        }
350 25b42708 Alexander Graf
        exit(0);
351 25b42708 Alexander Graf
    }
352 25b42708 Alexander Graf
353 04088adb Liu Yu
    ret = rom_add_blob_fixed(BINARY_DEVICE_TREE_FILE, fdt, fdt_size, addr);
354 cba2026a Alexander Graf
    if (ret < 0) {
355 cba2026a Alexander Graf
        goto out;
356 cba2026a Alexander Graf
    }
357 7267c094 Anthony Liguori
    g_free(fdt);
358 cba2026a Alexander Graf
    ret = fdt_size;
359 7ec632b4 pbrook
360 1db09b84 aurel32
out:
361 1db09b84 aurel32
362 04088adb Liu Yu
    return ret;
363 1db09b84 aurel32
}
364 1db09b84 aurel32
365 cba2026a Alexander Graf
/* Create -kernel TLB entries for BookE.  */
366 d1e256fe Alexander Graf
static inline target_phys_addr_t booke206_page_size_to_tlb(uint64_t size)
367 d1e256fe Alexander Graf
{
368 cba2026a Alexander Graf
    return 63 - clz64(size >> 10);
369 d1e256fe Alexander Graf
}
370 d1e256fe Alexander Graf
371 cba2026a Alexander Graf
static void mmubooke_create_initial_mapping(CPUPPCState *env)
372 3b989d49 Alexander Graf
{
373 cba2026a Alexander Graf
    struct boot_info *bi = env->load_info;
374 d1e256fe Alexander Graf
    ppcmas_tlb_t *tlb = booke206_get_tlbm(env, 1, 0, 0);
375 cba2026a Alexander Graf
    target_phys_addr_t size, dt_end;
376 cba2026a Alexander Graf
    int ps;
377 cba2026a Alexander Graf
378 cba2026a Alexander Graf
    /* Our initial TLB entry needs to cover everything from 0 to
379 cba2026a Alexander Graf
       the device tree top */
380 cba2026a Alexander Graf
    dt_end = bi->dt_base + bi->dt_size;
381 cba2026a Alexander Graf
    ps = booke206_page_size_to_tlb(dt_end) + 1;
382 cba2026a Alexander Graf
    size = (ps << MAS1_TSIZE_SHIFT);
383 d1e256fe Alexander Graf
    tlb->mas1 = MAS1_VALID | size;
384 cba2026a Alexander Graf
    tlb->mas2 = 0;
385 cba2026a Alexander Graf
    tlb->mas7_3 = 0;
386 d1e256fe Alexander Graf
    tlb->mas7_3 |= MAS3_UR | MAS3_UW | MAS3_UX | MAS3_SR | MAS3_SW | MAS3_SX;
387 93dd5e85 Scott Wood
388 93dd5e85 Scott Wood
    env->tlb_dirty = true;
389 3b989d49 Alexander Graf
}
390 3b989d49 Alexander Graf
391 5c145dac Alexander Graf
static void mpc8544ds_cpu_reset_sec(void *opaque)
392 5c145dac Alexander Graf
{
393 38f92da6 Andreas Färber
    PowerPCCPU *cpu = opaque;
394 38f92da6 Andreas Färber
    CPUPPCState *env = &cpu->env;
395 5c145dac Alexander Graf
396 38f92da6 Andreas Färber
    cpu_reset(CPU(cpu));
397 5c145dac Alexander Graf
398 5c145dac Alexander Graf
    /* Secondary CPU starts in halted state for now. Needs to change when
399 5c145dac Alexander Graf
       implementing non-kernel boot. */
400 5c145dac Alexander Graf
    env->halted = 1;
401 5c145dac Alexander Graf
    env->exception_index = EXCP_HLT;
402 3b989d49 Alexander Graf
}
403 3b989d49 Alexander Graf
404 3b989d49 Alexander Graf
static void mpc8544ds_cpu_reset(void *opaque)
405 3b989d49 Alexander Graf
{
406 38f92da6 Andreas Färber
    PowerPCCPU *cpu = opaque;
407 38f92da6 Andreas Färber
    CPUPPCState *env = &cpu->env;
408 3b989d49 Alexander Graf
    struct boot_info *bi = env->load_info;
409 3b989d49 Alexander Graf
410 38f92da6 Andreas Färber
    cpu_reset(CPU(cpu));
411 3b989d49 Alexander Graf
412 3b989d49 Alexander Graf
    /* Set initial guest state. */
413 5c145dac Alexander Graf
    env->halted = 0;
414 3b989d49 Alexander Graf
    env->gpr[1] = (16<<20) - 8;
415 3b989d49 Alexander Graf
    env->gpr[3] = bi->dt_base;
416 3b989d49 Alexander Graf
    env->nip = bi->entry;
417 cba2026a Alexander Graf
    mmubooke_create_initial_mapping(env);
418 3b989d49 Alexander Graf
}
419 3b989d49 Alexander Graf
420 c227f099 Anthony Liguori
static void mpc8544ds_init(ram_addr_t ram_size,
421 1db09b84 aurel32
                         const char *boot_device,
422 1db09b84 aurel32
                         const char *kernel_filename,
423 1db09b84 aurel32
                         const char *kernel_cmdline,
424 1db09b84 aurel32
                         const char *initrd_filename,
425 1db09b84 aurel32
                         const char *cpu_model)
426 1db09b84 aurel32
{
427 39186d8a Richard Henderson
    MemoryRegion *address_space_mem = get_system_memory();
428 2646c133 Avi Kivity
    MemoryRegion *ram = g_new(MemoryRegion, 1);
429 1db09b84 aurel32
    PCIBus *pci_bus;
430 e2684c0b Andreas Färber
    CPUPPCState *env = NULL;
431 1db09b84 aurel32
    uint64_t elf_entry;
432 1db09b84 aurel32
    uint64_t elf_lowaddr;
433 c227f099 Anthony Liguori
    target_phys_addr_t entry=0;
434 c227f099 Anthony Liguori
    target_phys_addr_t loadaddr=UIMAGE_LOAD_BASE;
435 1db09b84 aurel32
    target_long kernel_size=0;
436 75bb6589 Liu Yu
    target_ulong dt_base = 0;
437 75bb6589 Liu Yu
    target_ulong initrd_base = 0;
438 1db09b84 aurel32
    target_long initrd_size=0;
439 1db09b84 aurel32
    int i=0;
440 1db09b84 aurel32
    unsigned int pci_irq_nrs[4] = {1, 2, 3, 4};
441 a915249f Alexander Graf
    qemu_irq **irqs, *mpic;
442 be13cc7a Alexander Graf
    DeviceState *dev;
443 e2684c0b Andreas Färber
    CPUPPCState *firstenv = NULL;
444 1db09b84 aurel32
445 e61c36d5 Alexander Graf
    /* Setup CPUs */
446 ef250db6 Alexander Graf
    if (cpu_model == NULL) {
447 ef250db6 Alexander Graf
        cpu_model = "e500v2_v30";
448 ef250db6 Alexander Graf
    }
449 ef250db6 Alexander Graf
450 a915249f Alexander Graf
    irqs = g_malloc0(smp_cpus * sizeof(qemu_irq *));
451 a915249f Alexander Graf
    irqs[0] = g_malloc0(smp_cpus * sizeof(qemu_irq) * OPENPIC_OUTPUT_NB);
452 e61c36d5 Alexander Graf
    for (i = 0; i < smp_cpus; i++) {
453 397b457d Andreas Färber
        PowerPCCPU *cpu;
454 e61c36d5 Alexander Graf
        qemu_irq *input;
455 397b457d Andreas Färber
456 397b457d Andreas Färber
        cpu = cpu_ppc_init(cpu_model);
457 397b457d Andreas Färber
        if (cpu == NULL) {
458 e61c36d5 Alexander Graf
            fprintf(stderr, "Unable to initialize CPU!\n");
459 e61c36d5 Alexander Graf
            exit(1);
460 e61c36d5 Alexander Graf
        }
461 397b457d Andreas Färber
        env = &cpu->env;
462 1db09b84 aurel32
463 e61c36d5 Alexander Graf
        if (!firstenv) {
464 e61c36d5 Alexander Graf
            firstenv = env;
465 e61c36d5 Alexander Graf
        }
466 1db09b84 aurel32
467 a915249f Alexander Graf
        irqs[i] = irqs[0] + (i * OPENPIC_OUTPUT_NB);
468 a915249f Alexander Graf
        input = (qemu_irq *)env->irq_inputs;
469 a915249f Alexander Graf
        irqs[i][OPENPIC_OUTPUT_INT] = input[PPCE500_INPUT_INT];
470 a915249f Alexander Graf
        irqs[i][OPENPIC_OUTPUT_CINT] = input[PPCE500_INPUT_CINT];
471 e61c36d5 Alexander Graf
        env->spr[SPR_BOOKE_PIR] = env->cpu_index = i;
472 2a7a47fc Alexander Graf
        env->mpic_cpu_base = MPC8544_MPIC_REGS_BASE + 0x20000;
473 3b989d49 Alexander Graf
474 ddd1055b Fabien Chouteau
        ppc_booke_timers_init(env, 400000000, PPC_TIMER_E500);
475 e61c36d5 Alexander Graf
476 e61c36d5 Alexander Graf
        /* Register reset handler */
477 5c145dac Alexander Graf
        if (!i) {
478 5c145dac Alexander Graf
            /* Primary CPU */
479 5c145dac Alexander Graf
            struct boot_info *boot_info;
480 5c145dac Alexander Graf
            boot_info = g_malloc0(sizeof(struct boot_info));
481 38f92da6 Andreas Färber
            qemu_register_reset(mpc8544ds_cpu_reset, cpu);
482 5c145dac Alexander Graf
            env->load_info = boot_info;
483 5c145dac Alexander Graf
        } else {
484 5c145dac Alexander Graf
            /* Secondary CPUs */
485 38f92da6 Andreas Färber
            qemu_register_reset(mpc8544ds_cpu_reset_sec, cpu);
486 5c145dac Alexander Graf
        }
487 e61c36d5 Alexander Graf
    }
488 3b989d49 Alexander Graf
489 e61c36d5 Alexander Graf
    env = firstenv;
490 3b989d49 Alexander Graf
491 1db09b84 aurel32
    /* Fixup Memory size on a alignment boundary */
492 1db09b84 aurel32
    ram_size &= ~(RAM_SIZES_ALIGN - 1);
493 1db09b84 aurel32
494 1db09b84 aurel32
    /* Register Memory */
495 c5705a77 Avi Kivity
    memory_region_init_ram(ram, "mpc8544ds.ram", ram_size);
496 c5705a77 Avi Kivity
    vmstate_register_ram_global(ram);
497 2646c133 Avi Kivity
    memory_region_add_subregion(address_space_mem, 0, ram);
498 1db09b84 aurel32
499 1db09b84 aurel32
    /* MPIC */
500 df2921d3 Avi Kivity
    mpic = mpic_init(address_space_mem, MPC8544_MPIC_REGS_BASE,
501 df2921d3 Avi Kivity
                     smp_cpus, irqs, NULL);
502 a915249f Alexander Graf
503 a915249f Alexander Graf
    if (!mpic) {
504 a915249f Alexander Graf
        cpu_abort(env, "MPIC failed to initialize\n");
505 a915249f Alexander Graf
    }
506 1db09b84 aurel32
507 1db09b84 aurel32
    /* Serial */
508 2d48377a Blue Swirl
    if (serial_hds[0]) {
509 39186d8a Richard Henderson
        serial_mm_init(address_space_mem, MPC8544_SERIAL0_REGS_BASE,
510 49a2942d Blue Swirl
                       0, mpic[12+26], 399193,
511 2ff0c7c3 Richard Henderson
                       serial_hds[0], DEVICE_BIG_ENDIAN);
512 2d48377a Blue Swirl
    }
513 1db09b84 aurel32
514 2d48377a Blue Swirl
    if (serial_hds[1]) {
515 39186d8a Richard Henderson
        serial_mm_init(address_space_mem, MPC8544_SERIAL1_REGS_BASE,
516 49a2942d Blue Swirl
                       0, mpic[12+26], 399193,
517 2ff0c7c3 Richard Henderson
                       serial_hds[0], DEVICE_BIG_ENDIAN);
518 2d48377a Blue Swirl
    }
519 1db09b84 aurel32
520 b0fb8423 Alexander Graf
    /* General Utility device */
521 b0fb8423 Alexander Graf
    sysbus_create_simple("mpc8544-guts", MPC8544_UTIL_BASE, NULL);
522 b0fb8423 Alexander Graf
523 1db09b84 aurel32
    /* PCI */
524 be13cc7a Alexander Graf
    dev = sysbus_create_varargs("e500-pcihost", MPC8544_PCI_REGS_BASE,
525 be13cc7a Alexander Graf
                                mpic[pci_irq_nrs[0]], mpic[pci_irq_nrs[1]],
526 be13cc7a Alexander Graf
                                mpic[pci_irq_nrs[2]], mpic[pci_irq_nrs[3]],
527 be13cc7a Alexander Graf
                                NULL);
528 d461e3b9 Alexander Graf
    pci_bus = (PCIBus *)qdev_get_child_bus(dev, "pci.0");
529 1db09b84 aurel32
    if (!pci_bus)
530 1db09b84 aurel32
        printf("couldn't create PCI controller!\n");
531 1db09b84 aurel32
532 968d683c Alexander Graf
    isa_mmio_init(MPC8544_PCI_IO, MPC8544_PCI_IOLEN);
533 1db09b84 aurel32
534 1db09b84 aurel32
    if (pci_bus) {
535 1db09b84 aurel32
        /* Register network interfaces. */
536 1db09b84 aurel32
        for (i = 0; i < nb_nics; i++) {
537 07caea31 Markus Armbruster
            pci_nic_init_nofail(&nd_table[i], "virtio", NULL);
538 1db09b84 aurel32
        }
539 1db09b84 aurel32
    }
540 1db09b84 aurel32
541 5c145dac Alexander Graf
    /* Register spinning region */
542 5c145dac Alexander Graf
    sysbus_create_simple("e500-spin", MPC8544_SPIN_BASE, NULL);
543 5c145dac Alexander Graf
544 1db09b84 aurel32
    /* Load kernel. */
545 1db09b84 aurel32
    if (kernel_filename) {
546 1db09b84 aurel32
        kernel_size = load_uimage(kernel_filename, &entry, &loadaddr, NULL);
547 1db09b84 aurel32
        if (kernel_size < 0) {
548 409dbce5 Aurelien Jarno
            kernel_size = load_elf(kernel_filename, NULL, NULL, &elf_entry,
549 409dbce5 Aurelien Jarno
                                   &elf_lowaddr, NULL, 1, ELF_MACHINE, 0);
550 1db09b84 aurel32
            entry = elf_entry;
551 1db09b84 aurel32
            loadaddr = elf_lowaddr;
552 1db09b84 aurel32
        }
553 1db09b84 aurel32
        /* XXX try again as binary */
554 1db09b84 aurel32
        if (kernel_size < 0) {
555 1db09b84 aurel32
            fprintf(stderr, "qemu: could not load kernel '%s'\n",
556 1db09b84 aurel32
                    kernel_filename);
557 1db09b84 aurel32
            exit(1);
558 1db09b84 aurel32
        }
559 1db09b84 aurel32
    }
560 1db09b84 aurel32
561 1db09b84 aurel32
    /* Load initrd. */
562 1db09b84 aurel32
    if (initrd_filename) {
563 75bb6589 Liu Yu
        initrd_base = (kernel_size + INITRD_LOAD_PAD) & ~INITRD_PAD_MASK;
564 d7585251 pbrook
        initrd_size = load_image_targphys(initrd_filename, initrd_base,
565 d7585251 pbrook
                                          ram_size - initrd_base);
566 1db09b84 aurel32
567 1db09b84 aurel32
        if (initrd_size < 0) {
568 1db09b84 aurel32
            fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
569 1db09b84 aurel32
                    initrd_filename);
570 1db09b84 aurel32
            exit(1);
571 1db09b84 aurel32
        }
572 1db09b84 aurel32
    }
573 1db09b84 aurel32
574 1db09b84 aurel32
    /* If we're loading a kernel directly, we must load the device tree too. */
575 1db09b84 aurel32
    if (kernel_filename) {
576 5c145dac Alexander Graf
        struct boot_info *boot_info;
577 cba2026a Alexander Graf
        int dt_size;
578 5c145dac Alexander Graf
579 cba2026a Alexander Graf
        dt_base = (loadaddr + kernel_size + DTC_LOAD_PAD) & ~DTC_PAD_MASK;
580 cba2026a Alexander Graf
        dt_size = mpc8544_load_device_tree(env, dt_base, ram_size, initrd_base,
581 cba2026a Alexander Graf
                                           initrd_size, kernel_cmdline);
582 cba2026a Alexander Graf
        if (dt_size < 0) {
583 1db09b84 aurel32
            fprintf(stderr, "couldn't load device tree\n");
584 1db09b84 aurel32
            exit(1);
585 1db09b84 aurel32
        }
586 1db09b84 aurel32
587 e61c36d5 Alexander Graf
        boot_info = env->load_info;
588 3b989d49 Alexander Graf
        boot_info->entry = entry;
589 3b989d49 Alexander Graf
        boot_info->dt_base = dt_base;
590 cba2026a Alexander Graf
        boot_info->dt_size = dt_size;
591 1db09b84 aurel32
    }
592 1db09b84 aurel32
593 3b989d49 Alexander Graf
    if (kvm_enabled()) {
594 1db09b84 aurel32
        kvmppc_init();
595 3b989d49 Alexander Graf
    }
596 1db09b84 aurel32
}
597 1db09b84 aurel32
598 f80f9ec9 Anthony Liguori
static QEMUMachine mpc8544ds_machine = {
599 1db09b84 aurel32
    .name = "mpc8544ds",
600 1db09b84 aurel32
    .desc = "mpc8544ds",
601 1db09b84 aurel32
    .init = mpc8544ds_init,
602 a2a67420 Alexander Graf
    .max_cpus = 15,
603 1db09b84 aurel32
};
604 f80f9ec9 Anthony Liguori
605 f80f9ec9 Anthony Liguori
static void mpc8544ds_machine_init(void)
606 f80f9ec9 Anthony Liguori
{
607 f80f9ec9 Anthony Liguori
    qemu_register_machine(&mpc8544ds_machine);
608 f80f9ec9 Anthony Liguori
}
609 f80f9ec9 Anthony Liguori
610 f80f9ec9 Anthony Liguori
machine_init(mpc8544ds_machine_init);