Statistics
| Branch: | Revision:

root / hw / ppce500_mpc8544ds.c @ 2a7a47fc

History | View | Annotate | Download (21.5 kB)

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

    
17
#include "config.h"
18
#include "qemu-common.h"
19
#include "net.h"
20
#include "hw.h"
21
#include "pc.h"
22
#include "pci.h"
23
#include "boards.h"
24
#include "sysemu.h"
25
#include "kvm.h"
26
#include "kvm_ppc.h"
27
#include "device_tree.h"
28
#include "openpic.h"
29
#include "ppc.h"
30
#include "loader.h"
31
#include "elf.h"
32
#include "sysbus.h"
33
#include "exec-memory.h"
34
#include "host-utils.h"
35

    
36
#define BINARY_DEVICE_TREE_FILE    "mpc8544ds.dtb"
37
#define UIMAGE_LOAD_BASE           0
38
#define DTC_LOAD_PAD               0x500000
39
#define DTC_PAD_MASK               0xFFFFF
40
#define INITRD_LOAD_PAD            0x2000000
41
#define INITRD_PAD_MASK            0xFFFFFF
42

    
43
#define RAM_SIZES_ALIGN            (64UL << 20)
44

    
45
#define MPC8544_CCSRBAR_BASE       0xE0000000ULL
46
#define MPC8544_CCSRBAR_SIZE       0x00100000ULL
47
#define MPC8544_MPIC_REGS_BASE     (MPC8544_CCSRBAR_BASE + 0x40000ULL)
48
#define MPC8544_SERIAL0_REGS_BASE  (MPC8544_CCSRBAR_BASE + 0x4500ULL)
49
#define MPC8544_SERIAL1_REGS_BASE  (MPC8544_CCSRBAR_BASE + 0x4600ULL)
50
#define MPC8544_PCI_REGS_BASE      (MPC8544_CCSRBAR_BASE + 0x8000ULL)
51
#define MPC8544_PCI_REGS_SIZE      0x1000ULL
52
#define MPC8544_PCI_IO             0xE1000000ULL
53
#define MPC8544_PCI_IOLEN          0x10000ULL
54
#define MPC8544_UTIL_BASE          (MPC8544_CCSRBAR_BASE + 0xe0000ULL)
55
#define MPC8544_SPIN_BASE          0xEF000000ULL
56

    
57
struct boot_info
58
{
59
    uint32_t dt_base;
60
    uint32_t dt_size;
61
    uint32_t entry;
62
};
63

    
64
static void pci_map_create(void *fdt, uint32_t *pci_map, uint32_t mpic)
65
{
66
    int i;
67
    const uint32_t tmp[] = {
68
                             /* IDSEL 0x11 J17 Slot 1 */
69
                             0x8800, 0x0, 0x0, 0x1, mpic, 0x2, 0x1, 0x0, 0x0,
70
                             0x8800, 0x0, 0x0, 0x2, mpic, 0x3, 0x1, 0x0, 0x0,
71
                             0x8800, 0x0, 0x0, 0x3, mpic, 0x4, 0x1, 0x0, 0x0,
72
                             0x8800, 0x0, 0x0, 0x4, mpic, 0x1, 0x1, 0x0, 0x0,
73

    
74
                             /* IDSEL 0x12 J16 Slot 2 */
75
                             0x9000, 0x0, 0x0, 0x1, mpic, 0x3, 0x1, 0x0, 0x0,
76
                             0x9000, 0x0, 0x0, 0x2, mpic, 0x4, 0x1, 0x0, 0x0,
77
                             0x9000, 0x0, 0x0, 0x3, mpic, 0x2, 0x1, 0x0, 0x0,
78
                             0x9000, 0x0, 0x0, 0x4, mpic, 0x1, 0x1, 0x0, 0x0,
79
                           };
80
    for (i = 0; i < ARRAY_SIZE(tmp); i++) {
81
        pci_map[i] = cpu_to_be32(tmp[i]);
82
    }
83
}
84

    
85
static void dt_serial_create(void *fdt, unsigned long long offset,
86
                             const char *soc, const char *mpic,
87
                             const char *alias, int idx, bool defcon)
88
{
89
    char ser[128];
90

    
91
    snprintf(ser, sizeof(ser), "%s/serial@%llx", soc, offset);
92
    qemu_devtree_add_subnode(fdt, ser);
93
    qemu_devtree_setprop_string(fdt, ser, "device_type", "serial");
94
    qemu_devtree_setprop_string(fdt, ser, "compatible", "ns16550");
95
    qemu_devtree_setprop_cells(fdt, ser, "reg", offset, 0x100);
96
    qemu_devtree_setprop_cell(fdt, ser, "cell-index", idx);
97
    qemu_devtree_setprop_cell(fdt, ser, "clock-frequency", 0);
98
    qemu_devtree_setprop_cells(fdt, ser, "interrupts", 42, 2, 0, 0);
99
    qemu_devtree_setprop_phandle(fdt, ser, "interrupt-parent", mpic);
100
    qemu_devtree_setprop_string(fdt, "/aliases", alias, ser);
101

    
102
    if (defcon) {
103
        qemu_devtree_setprop_string(fdt, "/chosen", "linux,stdout-path", ser);
104
    }
105
}
106

    
107
static int mpc8544_load_device_tree(CPUPPCState *env,
108
                                    target_phys_addr_t addr,
109
                                    target_phys_addr_t ramsize,
110
                                    target_phys_addr_t initrd_base,
111
                                    target_phys_addr_t initrd_size,
112
                                    const char *kernel_cmdline)
113
{
114
    int ret = -1;
115
    uint64_t mem_reg_property[] = { 0, cpu_to_be64(ramsize) };
116
    int fdt_size;
117
    void *fdt;
118
    uint8_t hypercall[16];
119
    uint32_t clock_freq = 400000000;
120
    uint32_t tb_freq = 400000000;
121
    int i;
122
    const char *compatible = "MPC8544DS\0MPC85xxDS";
123
    int compatible_len = sizeof("MPC8544DS\0MPC85xxDS");
124
    char compatible_sb[] = "fsl,mpc8544-immr\0simple-bus";
125
    char model[] = "MPC8544DS";
126
    char soc[128];
127
    char mpic[128];
128
    uint32_t mpic_ph;
129
    char gutil[128];
130
    char pci[128];
131
    uint32_t pci_map[9 * 8];
132
    uint32_t pci_ranges[14] =
133
        {
134
            0x2000000, 0x0, 0xc0000000,
135
            0x0, 0xc0000000,
136
            0x0, 0x20000000,
137

    
138
            0x1000000, 0x0, 0x0,
139
            0x0, 0xe1000000,
140
            0x0, 0x10000,
141
        };
142
    QemuOpts *machine_opts;
143
    const char *dumpdtb = NULL;
144
    const char *dtb_file = NULL;
145

    
146
    machine_opts = qemu_opts_find(qemu_find_opts("machine"), 0);
147
    if (machine_opts) {
148
        const char *tmp;
149
        dumpdtb = qemu_opt_get(machine_opts, "dumpdtb");
150
        dtb_file = qemu_opt_get(machine_opts, "dtb");
151
        tmp = qemu_opt_get(machine_opts, "dt_compatible");
152
        if (tmp) {
153
            compatible = tmp;
154
            compatible_len = strlen(compatible) + 1;
155
        }
156
    }
157

    
158
    if (dtb_file) {
159
        char *filename;
160
        filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, dtb_file);
161
        if (!filename) {
162
            goto out;
163
        }
164

    
165
        fdt = load_device_tree(filename, &fdt_size);
166
        if (!fdt) {
167
            goto out;
168
        }
169
        goto done;
170
    }
171

    
172
    fdt = create_device_tree(&fdt_size);
173
    if (fdt == NULL) {
174
        goto out;
175
    }
176

    
177
    /* Manipulate device tree in memory. */
178
    qemu_devtree_setprop_string(fdt, "/", "model", model);
179
    qemu_devtree_setprop(fdt, "/", "compatible", compatible, compatible_len);
180
    qemu_devtree_setprop_cell(fdt, "/", "#address-cells", 2);
181
    qemu_devtree_setprop_cell(fdt, "/", "#size-cells", 2);
182

    
183
    qemu_devtree_add_subnode(fdt, "/memory");
184
    qemu_devtree_setprop_string(fdt, "/memory", "device_type", "memory");
185
    qemu_devtree_setprop(fdt, "/memory", "reg", mem_reg_property,
186
                         sizeof(mem_reg_property));
187

    
188
    qemu_devtree_add_subnode(fdt, "/chosen");
189
    if (initrd_size) {
190
        ret = qemu_devtree_setprop_cell(fdt, "/chosen", "linux,initrd-start",
191
                                        initrd_base);
192
        if (ret < 0) {
193
            fprintf(stderr, "couldn't set /chosen/linux,initrd-start\n");
194
        }
195

    
196
        ret = qemu_devtree_setprop_cell(fdt, "/chosen", "linux,initrd-end",
197
                                        (initrd_base + initrd_size));
198
        if (ret < 0) {
199
            fprintf(stderr, "couldn't set /chosen/linux,initrd-end\n");
200
        }
201
    }
202

    
203
    ret = qemu_devtree_setprop_string(fdt, "/chosen", "bootargs",
204
                                      kernel_cmdline);
205
    if (ret < 0)
206
        fprintf(stderr, "couldn't set /chosen/bootargs\n");
207

    
208
    if (kvm_enabled()) {
209
        /* Read out host's frequencies */
210
        clock_freq = kvmppc_get_clockfreq();
211
        tb_freq = kvmppc_get_tbfreq();
212

    
213
        /* indicate KVM hypercall interface */
214
        qemu_devtree_add_subnode(fdt, "/hypervisor");
215
        qemu_devtree_setprop_string(fdt, "/hypervisor", "compatible",
216
                                    "linux,kvm");
217
        kvmppc_get_hypercall(env, hypercall, sizeof(hypercall));
218
        qemu_devtree_setprop(fdt, "/hypervisor", "hcall-instructions",
219
                             hypercall, sizeof(hypercall));
220
    }
221

    
222
    /* Create CPU nodes */
223
    qemu_devtree_add_subnode(fdt, "/cpus");
224
    qemu_devtree_setprop_cell(fdt, "/cpus", "#address-cells", 1);
225
    qemu_devtree_setprop_cell(fdt, "/cpus", "#size-cells", 0);
226

    
227
    /* We need to generate the cpu nodes in reverse order, so Linux can pick
228
       the first node as boot node and be happy */
229
    for (i = smp_cpus - 1; i >= 0; i--) {
230
        char cpu_name[128];
231
        uint64_t cpu_release_addr = MPC8544_SPIN_BASE + (i * 0x20);
232

    
233
        for (env = first_cpu; env != NULL; env = env->next_cpu) {
234
            if (env->cpu_index == i) {
235
                break;
236
            }
237
        }
238

    
239
        if (!env) {
240
            continue;
241
        }
242

    
243
        snprintf(cpu_name, sizeof(cpu_name), "/cpus/PowerPC,8544@%x", env->cpu_index);
244
        qemu_devtree_add_subnode(fdt, cpu_name);
245
        qemu_devtree_setprop_cell(fdt, cpu_name, "clock-frequency", clock_freq);
246
        qemu_devtree_setprop_cell(fdt, cpu_name, "timebase-frequency", tb_freq);
247
        qemu_devtree_setprop_string(fdt, cpu_name, "device_type", "cpu");
248
        qemu_devtree_setprop_cell(fdt, cpu_name, "reg", env->cpu_index);
249
        qemu_devtree_setprop_cell(fdt, cpu_name, "d-cache-line-size",
250
                                  env->dcache_line_size);
251
        qemu_devtree_setprop_cell(fdt, cpu_name, "i-cache-line-size",
252
                                  env->icache_line_size);
253
        qemu_devtree_setprop_cell(fdt, cpu_name, "d-cache-size", 0x8000);
254
        qemu_devtree_setprop_cell(fdt, cpu_name, "i-cache-size", 0x8000);
255
        qemu_devtree_setprop_cell(fdt, cpu_name, "bus-frequency", 0);
256
        if (env->cpu_index) {
257
            qemu_devtree_setprop_string(fdt, cpu_name, "status", "disabled");
258
            qemu_devtree_setprop_string(fdt, cpu_name, "enable-method", "spin-table");
259
            qemu_devtree_setprop_u64(fdt, cpu_name, "cpu-release-addr",
260
                                     cpu_release_addr);
261
        } else {
262
            qemu_devtree_setprop_string(fdt, cpu_name, "status", "okay");
263
        }
264
    }
265

    
266
    qemu_devtree_add_subnode(fdt, "/aliases");
267
    /* XXX These should go into their respective devices' code */
268
    snprintf(soc, sizeof(soc), "/soc@%llx", MPC8544_CCSRBAR_BASE);
269
    qemu_devtree_add_subnode(fdt, soc);
270
    qemu_devtree_setprop_string(fdt, soc, "device_type", "soc");
271
    qemu_devtree_setprop(fdt, soc, "compatible", compatible_sb,
272
                         sizeof(compatible_sb));
273
    qemu_devtree_setprop_cell(fdt, soc, "#address-cells", 1);
274
    qemu_devtree_setprop_cell(fdt, soc, "#size-cells", 1);
275
    qemu_devtree_setprop_cells(fdt, soc, "ranges", 0x0,
276
                               MPC8544_CCSRBAR_BASE >> 32, MPC8544_CCSRBAR_BASE,
277
                               MPC8544_CCSRBAR_SIZE);
278
    /* XXX should contain a reasonable value */
279
    qemu_devtree_setprop_cell(fdt, soc, "bus-frequency", 0);
280

    
281
    snprintf(mpic, sizeof(mpic), "%s/pic@%llx", soc,
282
             MPC8544_MPIC_REGS_BASE - MPC8544_CCSRBAR_BASE);
283
    qemu_devtree_add_subnode(fdt, mpic);
284
    qemu_devtree_setprop_string(fdt, mpic, "device_type", "open-pic");
285
    qemu_devtree_setprop_string(fdt, mpic, "compatible", "fsl,mpic");
286
    qemu_devtree_setprop_cells(fdt, mpic, "reg", MPC8544_MPIC_REGS_BASE -
287
                               MPC8544_CCSRBAR_BASE, 0x40000);
288
    qemu_devtree_setprop_cell(fdt, mpic, "#address-cells", 0);
289
    qemu_devtree_setprop_cell(fdt, mpic, "#interrupt-cells", 4);
290
    mpic_ph = qemu_devtree_alloc_phandle(fdt);
291
    qemu_devtree_setprop_cell(fdt, mpic, "phandle", mpic_ph);
292
    qemu_devtree_setprop_cell(fdt, mpic, "linux,phandle", mpic_ph);
293
    qemu_devtree_setprop(fdt, mpic, "interrupt-controller", NULL, 0);
294
    qemu_devtree_setprop(fdt, mpic, "big-endian", NULL, 0);
295
    qemu_devtree_setprop(fdt, mpic, "single-cpu-affinity", NULL, 0);
296
    qemu_devtree_setprop_cell(fdt, mpic, "last-interrupt-source", 255);
297

    
298
    /*
299
     * We have to generate ser1 first, because Linux takes the first
300
     * device it finds in the dt as serial output device. And we generate
301
     * devices in reverse order to the dt.
302
     */
303
    dt_serial_create(fdt, MPC8544_SERIAL1_REGS_BASE - MPC8544_CCSRBAR_BASE,
304
                     soc, mpic, "serial1", 1, false);
305
    dt_serial_create(fdt, MPC8544_SERIAL0_REGS_BASE - MPC8544_CCSRBAR_BASE,
306
                     soc, mpic, "serial0", 0, true);
307

    
308
    snprintf(gutil, sizeof(gutil), "%s/global-utilities@%llx", soc,
309
             MPC8544_UTIL_BASE - MPC8544_CCSRBAR_BASE);
310
    qemu_devtree_add_subnode(fdt, gutil);
311
    qemu_devtree_setprop_string(fdt, gutil, "compatible", "fsl,mpc8544-guts");
312
    qemu_devtree_setprop_cells(fdt, gutil, "reg", MPC8544_UTIL_BASE -
313
                               MPC8544_CCSRBAR_BASE, 0x1000);
314
    qemu_devtree_setprop(fdt, gutil, "fsl,has-rstcr", NULL, 0);
315

    
316
    snprintf(pci, sizeof(pci), "/pci@%llx", MPC8544_PCI_REGS_BASE);
317
    qemu_devtree_add_subnode(fdt, pci);
318
    qemu_devtree_setprop_cell(fdt, pci, "cell-index", 0);
319
    qemu_devtree_setprop_string(fdt, pci, "compatible", "fsl,mpc8540-pci");
320
    qemu_devtree_setprop_string(fdt, pci, "device_type", "pci");
321
    qemu_devtree_setprop_cells(fdt, pci, "interrupt-map-mask", 0xf800, 0x0,
322
                               0x0, 0x7);
323
    pci_map_create(fdt, pci_map, qemu_devtree_get_phandle(fdt, mpic));
324
    qemu_devtree_setprop(fdt, pci, "interrupt-map", pci_map, sizeof(pci_map));
325
    qemu_devtree_setprop_phandle(fdt, pci, "interrupt-parent", mpic);
326
    qemu_devtree_setprop_cells(fdt, pci, "interrupts", 24, 2, 0, 0);
327
    qemu_devtree_setprop_cells(fdt, pci, "bus-range", 0, 255);
328
    for (i = 0; i < 14; i++) {
329
        pci_ranges[i] = cpu_to_be32(pci_ranges[i]);
330
    }
331
    qemu_devtree_setprop(fdt, pci, "ranges", pci_ranges, sizeof(pci_ranges));
332
    qemu_devtree_setprop_cells(fdt, pci, "reg", MPC8544_PCI_REGS_BASE >> 32,
333
                               MPC8544_PCI_REGS_BASE, 0, 0x1000);
334
    qemu_devtree_setprop_cell(fdt, pci, "clock-frequency", 66666666);
335
    qemu_devtree_setprop_cell(fdt, pci, "#interrupt-cells", 1);
336
    qemu_devtree_setprop_cell(fdt, pci, "#size-cells", 2);
337
    qemu_devtree_setprop_cell(fdt, pci, "#address-cells", 3);
338
    qemu_devtree_setprop_string(fdt, "/aliases", "pci0", pci);
339

    
340
done:
341
    if (dumpdtb) {
342
        /* Dump the dtb to a file and quit */
343
        FILE *f = fopen(dumpdtb, "wb");
344
        size_t len;
345
        len = fwrite(fdt, fdt_size, 1, f);
346
        fclose(f);
347
        if (len != fdt_size) {
348
            exit(1);
349
        }
350
        exit(0);
351
    }
352

    
353
    ret = rom_add_blob_fixed(BINARY_DEVICE_TREE_FILE, fdt, fdt_size, addr);
354
    if (ret < 0) {
355
        goto out;
356
    }
357
    g_free(fdt);
358
    ret = fdt_size;
359

    
360
out:
361

    
362
    return ret;
363
}
364

    
365
/* Create -kernel TLB entries for BookE.  */
366
static inline target_phys_addr_t booke206_page_size_to_tlb(uint64_t size)
367
{
368
    return 63 - clz64(size >> 10);
369
}
370

    
371
static void mmubooke_create_initial_mapping(CPUPPCState *env)
372
{
373
    struct boot_info *bi = env->load_info;
374
    ppcmas_tlb_t *tlb = booke206_get_tlbm(env, 1, 0, 0);
375
    target_phys_addr_t size, dt_end;
376
    int ps;
377

    
378
    /* Our initial TLB entry needs to cover everything from 0 to
379
       the device tree top */
380
    dt_end = bi->dt_base + bi->dt_size;
381
    ps = booke206_page_size_to_tlb(dt_end) + 1;
382
    size = (ps << MAS1_TSIZE_SHIFT);
383
    tlb->mas1 = MAS1_VALID | size;
384
    tlb->mas2 = 0;
385
    tlb->mas7_3 = 0;
386
    tlb->mas7_3 |= MAS3_UR | MAS3_UW | MAS3_UX | MAS3_SR | MAS3_SW | MAS3_SX;
387

    
388
    env->tlb_dirty = true;
389
}
390

    
391
static void mpc8544ds_cpu_reset_sec(void *opaque)
392
{
393
    PowerPCCPU *cpu = opaque;
394
    CPUPPCState *env = &cpu->env;
395

    
396
    cpu_reset(CPU(cpu));
397

    
398
    /* Secondary CPU starts in halted state for now. Needs to change when
399
       implementing non-kernel boot. */
400
    env->halted = 1;
401
    env->exception_index = EXCP_HLT;
402
}
403

    
404
static void mpc8544ds_cpu_reset(void *opaque)
405
{
406
    PowerPCCPU *cpu = opaque;
407
    CPUPPCState *env = &cpu->env;
408
    struct boot_info *bi = env->load_info;
409

    
410
    cpu_reset(CPU(cpu));
411

    
412
    /* Set initial guest state. */
413
    env->halted = 0;
414
    env->gpr[1] = (16<<20) - 8;
415
    env->gpr[3] = bi->dt_base;
416
    env->nip = bi->entry;
417
    mmubooke_create_initial_mapping(env);
418
}
419

    
420
static void mpc8544ds_init(ram_addr_t ram_size,
421
                         const char *boot_device,
422
                         const char *kernel_filename,
423
                         const char *kernel_cmdline,
424
                         const char *initrd_filename,
425
                         const char *cpu_model)
426
{
427
    MemoryRegion *address_space_mem = get_system_memory();
428
    MemoryRegion *ram = g_new(MemoryRegion, 1);
429
    PCIBus *pci_bus;
430
    CPUPPCState *env = NULL;
431
    uint64_t elf_entry;
432
    uint64_t elf_lowaddr;
433
    target_phys_addr_t entry=0;
434
    target_phys_addr_t loadaddr=UIMAGE_LOAD_BASE;
435
    target_long kernel_size=0;
436
    target_ulong dt_base = 0;
437
    target_ulong initrd_base = 0;
438
    target_long initrd_size=0;
439
    int i=0;
440
    unsigned int pci_irq_nrs[4] = {1, 2, 3, 4};
441
    qemu_irq **irqs, *mpic;
442
    DeviceState *dev;
443
    CPUPPCState *firstenv = NULL;
444

    
445
    /* Setup CPUs */
446
    if (cpu_model == NULL) {
447
        cpu_model = "e500v2_v30";
448
    }
449

    
450
    irqs = g_malloc0(smp_cpus * sizeof(qemu_irq *));
451
    irqs[0] = g_malloc0(smp_cpus * sizeof(qemu_irq) * OPENPIC_OUTPUT_NB);
452
    for (i = 0; i < smp_cpus; i++) {
453
        PowerPCCPU *cpu;
454
        qemu_irq *input;
455

    
456
        cpu = cpu_ppc_init(cpu_model);
457
        if (cpu == NULL) {
458
            fprintf(stderr, "Unable to initialize CPU!\n");
459
            exit(1);
460
        }
461
        env = &cpu->env;
462

    
463
        if (!firstenv) {
464
            firstenv = env;
465
        }
466

    
467
        irqs[i] = irqs[0] + (i * OPENPIC_OUTPUT_NB);
468
        input = (qemu_irq *)env->irq_inputs;
469
        irqs[i][OPENPIC_OUTPUT_INT] = input[PPCE500_INPUT_INT];
470
        irqs[i][OPENPIC_OUTPUT_CINT] = input[PPCE500_INPUT_CINT];
471
        env->spr[SPR_BOOKE_PIR] = env->cpu_index = i;
472
        env->mpic_cpu_base = MPC8544_MPIC_REGS_BASE + 0x20000;
473

    
474
        ppc_booke_timers_init(env, 400000000, PPC_TIMER_E500);
475

    
476
        /* Register reset handler */
477
        if (!i) {
478
            /* Primary CPU */
479
            struct boot_info *boot_info;
480
            boot_info = g_malloc0(sizeof(struct boot_info));
481
            qemu_register_reset(mpc8544ds_cpu_reset, cpu);
482
            env->load_info = boot_info;
483
        } else {
484
            /* Secondary CPUs */
485
            qemu_register_reset(mpc8544ds_cpu_reset_sec, cpu);
486
        }
487
    }
488

    
489
    env = firstenv;
490

    
491
    /* Fixup Memory size on a alignment boundary */
492
    ram_size &= ~(RAM_SIZES_ALIGN - 1);
493

    
494
    /* Register Memory */
495
    memory_region_init_ram(ram, "mpc8544ds.ram", ram_size);
496
    vmstate_register_ram_global(ram);
497
    memory_region_add_subregion(address_space_mem, 0, ram);
498

    
499
    /* MPIC */
500
    mpic = mpic_init(address_space_mem, MPC8544_MPIC_REGS_BASE,
501
                     smp_cpus, irqs, NULL);
502

    
503
    if (!mpic) {
504
        cpu_abort(env, "MPIC failed to initialize\n");
505
    }
506

    
507
    /* Serial */
508
    if (serial_hds[0]) {
509
        serial_mm_init(address_space_mem, MPC8544_SERIAL0_REGS_BASE,
510
                       0, mpic[12+26], 399193,
511
                       serial_hds[0], DEVICE_BIG_ENDIAN);
512
    }
513

    
514
    if (serial_hds[1]) {
515
        serial_mm_init(address_space_mem, MPC8544_SERIAL1_REGS_BASE,
516
                       0, mpic[12+26], 399193,
517
                       serial_hds[0], DEVICE_BIG_ENDIAN);
518
    }
519

    
520
    /* General Utility device */
521
    sysbus_create_simple("mpc8544-guts", MPC8544_UTIL_BASE, NULL);
522

    
523
    /* PCI */
524
    dev = sysbus_create_varargs("e500-pcihost", MPC8544_PCI_REGS_BASE,
525
                                mpic[pci_irq_nrs[0]], mpic[pci_irq_nrs[1]],
526
                                mpic[pci_irq_nrs[2]], mpic[pci_irq_nrs[3]],
527
                                NULL);
528
    pci_bus = (PCIBus *)qdev_get_child_bus(dev, "pci.0");
529
    if (!pci_bus)
530
        printf("couldn't create PCI controller!\n");
531

    
532
    isa_mmio_init(MPC8544_PCI_IO, MPC8544_PCI_IOLEN);
533

    
534
    if (pci_bus) {
535
        /* Register network interfaces. */
536
        for (i = 0; i < nb_nics; i++) {
537
            pci_nic_init_nofail(&nd_table[i], "virtio", NULL);
538
        }
539
    }
540

    
541
    /* Register spinning region */
542
    sysbus_create_simple("e500-spin", MPC8544_SPIN_BASE, NULL);
543

    
544
    /* Load kernel. */
545
    if (kernel_filename) {
546
        kernel_size = load_uimage(kernel_filename, &entry, &loadaddr, NULL);
547
        if (kernel_size < 0) {
548
            kernel_size = load_elf(kernel_filename, NULL, NULL, &elf_entry,
549
                                   &elf_lowaddr, NULL, 1, ELF_MACHINE, 0);
550
            entry = elf_entry;
551
            loadaddr = elf_lowaddr;
552
        }
553
        /* XXX try again as binary */
554
        if (kernel_size < 0) {
555
            fprintf(stderr, "qemu: could not load kernel '%s'\n",
556
                    kernel_filename);
557
            exit(1);
558
        }
559
    }
560

    
561
    /* Load initrd. */
562
    if (initrd_filename) {
563
        initrd_base = (kernel_size + INITRD_LOAD_PAD) & ~INITRD_PAD_MASK;
564
        initrd_size = load_image_targphys(initrd_filename, initrd_base,
565
                                          ram_size - initrd_base);
566

    
567
        if (initrd_size < 0) {
568
            fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
569
                    initrd_filename);
570
            exit(1);
571
        }
572
    }
573

    
574
    /* If we're loading a kernel directly, we must load the device tree too. */
575
    if (kernel_filename) {
576
        struct boot_info *boot_info;
577
        int dt_size;
578

    
579
        dt_base = (loadaddr + kernel_size + DTC_LOAD_PAD) & ~DTC_PAD_MASK;
580
        dt_size = mpc8544_load_device_tree(env, dt_base, ram_size, initrd_base,
581
                                           initrd_size, kernel_cmdline);
582
        if (dt_size < 0) {
583
            fprintf(stderr, "couldn't load device tree\n");
584
            exit(1);
585
        }
586

    
587
        boot_info = env->load_info;
588
        boot_info->entry = entry;
589
        boot_info->dt_base = dt_base;
590
        boot_info->dt_size = dt_size;
591
    }
592

    
593
    if (kvm_enabled()) {
594
        kvmppc_init();
595
    }
596
}
597

    
598
static QEMUMachine mpc8544ds_machine = {
599
    .name = "mpc8544ds",
600
    .desc = "mpc8544ds",
601
    .init = mpc8544ds_init,
602
    .max_cpus = 15,
603
};
604

    
605
static void mpc8544ds_machine_init(void)
606
{
607
    qemu_register_machine(&mpc8544ds_machine);
608
}
609

    
610
machine_init(mpc8544ds_machine_init);