Statistics
| Branch: | Revision:

root / hw / ppce500_mpc8544ds.c @ 3627757e

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