Statistics
| Branch: | Revision:

root / hw / ppc440_bamboo.c @ 8ca209ad

History | View | Annotate | Download (5.8 kB)

1 2c9fade2 aurel32
/*
2 2c9fade2 aurel32
 * Qemu PowerPC 440 Bamboo board emulation
3 2c9fade2 aurel32
 *
4 2c9fade2 aurel32
 * Copyright 2007 IBM Corporation.
5 2c9fade2 aurel32
 * Authors:
6 2c9fade2 aurel32
 *         Jerone Young <jyoung5@us.ibm.com>
7 2c9fade2 aurel32
 *         Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
8 2c9fade2 aurel32
 *         Hollis Blanchard <hollisb@us.ibm.com>
9 2c9fade2 aurel32
 *
10 2c9fade2 aurel32
 * This work is licensed under the GNU GPL license version 2 or later.
11 2c9fade2 aurel32
 *
12 2c9fade2 aurel32
 */
13 2c9fade2 aurel32
14 2c9fade2 aurel32
#include "config.h"
15 2c9fade2 aurel32
#include "qemu-common.h"
16 2c9fade2 aurel32
#include "net.h"
17 2c9fade2 aurel32
#include "hw.h"
18 2c9fade2 aurel32
#include "pci.h"
19 2c9fade2 aurel32
#include "boards.h"
20 2c9fade2 aurel32
#include "sysemu.h"
21 2c9fade2 aurel32
#include "ppc440.h"
22 2c9fade2 aurel32
#include "kvm.h"
23 2c9fade2 aurel32
#include "kvm_ppc.h"
24 2c9fade2 aurel32
#include "device_tree.h"
25 ca20cf32 Blue Swirl
#include "loader.h"
26 ca20cf32 Blue Swirl
#include "elf.h"
27 2c9fade2 aurel32
28 2c9fade2 aurel32
#define BINARY_DEVICE_TREE_FILE "bamboo.dtb"
29 2c9fade2 aurel32
30 ceee6da6 Hollis Blanchard
/* from u-boot */
31 ceee6da6 Hollis Blanchard
#define KERNEL_ADDR  0x1000000
32 ceee6da6 Hollis Blanchard
#define FDT_ADDR     0x1800000
33 ceee6da6 Hollis Blanchard
#define RAMDISK_ADDR 0x1900000
34 ceee6da6 Hollis Blanchard
35 04088adb Liu Yu
static int bamboo_load_device_tree(target_phys_addr_t addr,
36 2c9fade2 aurel32
                                     uint32_t ramsize,
37 c227f099 Anthony Liguori
                                     target_phys_addr_t initrd_base,
38 c227f099 Anthony Liguori
                                     target_phys_addr_t initrd_size,
39 2c9fade2 aurel32
                                     const char *kernel_cmdline)
40 2c9fade2 aurel32
{
41 dbf916d8 Aurelien Jarno
    int ret = -1;
42 3f0855b1 Juan Quintela
#ifdef CONFIG_FDT
43 2c9fade2 aurel32
    uint32_t mem_reg_property[] = { 0, 0, ramsize };
44 5cea8590 Paul Brook
    char *filename;
45 7ec632b4 pbrook
    int fdt_size;
46 dbf916d8 Aurelien Jarno
    void *fdt;
47 2c9fade2 aurel32
48 5cea8590 Paul Brook
    filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, BINARY_DEVICE_TREE_FILE);
49 5cea8590 Paul Brook
    if (!filename) {
50 5cea8590 Paul Brook
        goto out;
51 5cea8590 Paul Brook
    }
52 5cea8590 Paul Brook
    fdt = load_device_tree(filename, &fdt_size);
53 5cea8590 Paul Brook
    qemu_free(filename);
54 5cea8590 Paul Brook
    if (fdt == NULL) {
55 2c9fade2 aurel32
        goto out;
56 5cea8590 Paul Brook
    }
57 2c9fade2 aurel32
58 2c9fade2 aurel32
    /* Manipulate device tree in memory. */
59 2c9fade2 aurel32
60 2c9fade2 aurel32
    ret = qemu_devtree_setprop(fdt, "/memory", "reg", mem_reg_property,
61 2c9fade2 aurel32
                               sizeof(mem_reg_property));
62 2c9fade2 aurel32
    if (ret < 0)
63 2c9fade2 aurel32
        fprintf(stderr, "couldn't set /memory/reg\n");
64 2c9fade2 aurel32
65 2c9fade2 aurel32
    ret = qemu_devtree_setprop_cell(fdt, "/chosen", "linux,initrd-start",
66 2c9fade2 aurel32
                                    initrd_base);
67 2c9fade2 aurel32
    if (ret < 0)
68 2c9fade2 aurel32
        fprintf(stderr, "couldn't set /chosen/linux,initrd-start\n");
69 2c9fade2 aurel32
70 2c9fade2 aurel32
    ret = qemu_devtree_setprop_cell(fdt, "/chosen", "linux,initrd-end",
71 2c9fade2 aurel32
                                    (initrd_base + initrd_size));
72 2c9fade2 aurel32
    if (ret < 0)
73 2c9fade2 aurel32
        fprintf(stderr, "couldn't set /chosen/linux,initrd-end\n");
74 2c9fade2 aurel32
75 2c9fade2 aurel32
    ret = qemu_devtree_setprop_string(fdt, "/chosen", "bootargs",
76 2c9fade2 aurel32
                                      kernel_cmdline);
77 2c9fade2 aurel32
    if (ret < 0)
78 2c9fade2 aurel32
        fprintf(stderr, "couldn't set /chosen/bootargs\n");
79 2c9fade2 aurel32
80 2c9fade2 aurel32
    if (kvm_enabled())
81 2c9fade2 aurel32
        kvmppc_fdt_update(fdt);
82 2c9fade2 aurel32
83 04088adb Liu Yu
    ret = rom_add_blob_fixed(BINARY_DEVICE_TREE_FILE, fdt, fdt_size, addr);
84 04088adb Liu Yu
    qemu_free(fdt);
85 7ec632b4 pbrook
86 2c9fade2 aurel32
out:
87 2c9fade2 aurel32
#endif
88 2c9fade2 aurel32
89 04088adb Liu Yu
    return ret;
90 2c9fade2 aurel32
}
91 2c9fade2 aurel32
92 c227f099 Anthony Liguori
static void bamboo_init(ram_addr_t ram_size,
93 a147d62b blueswir1
                        const char *boot_device,
94 2c9fade2 aurel32
                        const char *kernel_filename,
95 2c9fade2 aurel32
                        const char *kernel_cmdline,
96 2c9fade2 aurel32
                        const char *initrd_filename,
97 2c9fade2 aurel32
                        const char *cpu_model)
98 2c9fade2 aurel32
{
99 2c9fade2 aurel32
    unsigned int pci_irq_nrs[4] = { 28, 27, 26, 25 };
100 2c9fade2 aurel32
    PCIBus *pcibus;
101 2c9fade2 aurel32
    CPUState *env;
102 2c9fade2 aurel32
    uint64_t elf_entry;
103 2c9fade2 aurel32
    uint64_t elf_lowaddr;
104 c227f099 Anthony Liguori
    target_phys_addr_t entry = 0;
105 c227f099 Anthony Liguori
    target_phys_addr_t loadaddr = 0;
106 2c9fade2 aurel32
    target_long initrd_size = 0;
107 ceee6da6 Hollis Blanchard
    int success;
108 2c9fade2 aurel32
    int i;
109 2c9fade2 aurel32
110 2c9fade2 aurel32
    /* Setup CPU. */
111 727170b6 Blue Swirl
    env = ppc440ep_init(&ram_size, &pcibus, pci_irq_nrs, 1, cpu_model);
112 2c9fade2 aurel32
113 2c9fade2 aurel32
    if (pcibus) {
114 2c9fade2 aurel32
        /* Register network interfaces. */
115 2c9fade2 aurel32
        for (i = 0; i < nb_nics; i++) {
116 cb457d76 aliguori
            /* There are no PCI NICs on the Bamboo board, but there are
117 cb457d76 aliguori
             * PCI slots, so we can pick whatever default model we want. */
118 07caea31 Markus Armbruster
            pci_nic_init_nofail(&nd_table[i], "e1000", NULL);
119 2c9fade2 aurel32
        }
120 2c9fade2 aurel32
    }
121 2c9fade2 aurel32
122 2c9fade2 aurel32
    /* Load kernel. */
123 2c9fade2 aurel32
    if (kernel_filename) {
124 ceee6da6 Hollis Blanchard
        success = load_uimage(kernel_filename, &entry, &loadaddr, NULL);
125 ceee6da6 Hollis Blanchard
        if (success < 0) {
126 ceee6da6 Hollis Blanchard
            success = load_elf(kernel_filename, NULL, NULL, &elf_entry,
127 ceee6da6 Hollis Blanchard
                               &elf_lowaddr, NULL, 1, ELF_MACHINE, 0);
128 2c9fade2 aurel32
            entry = elf_entry;
129 2c9fade2 aurel32
            loadaddr = elf_lowaddr;
130 2c9fade2 aurel32
        }
131 2c9fade2 aurel32
        /* XXX try again as binary */
132 ceee6da6 Hollis Blanchard
        if (success < 0) {
133 2c9fade2 aurel32
            fprintf(stderr, "qemu: could not load kernel '%s'\n",
134 2c9fade2 aurel32
                    kernel_filename);
135 2c9fade2 aurel32
            exit(1);
136 2c9fade2 aurel32
        }
137 2c9fade2 aurel32
    }
138 2c9fade2 aurel32
139 2c9fade2 aurel32
    /* Load initrd. */
140 2c9fade2 aurel32
    if (initrd_filename) {
141 ceee6da6 Hollis Blanchard
        initrd_size = load_image_targphys(initrd_filename, RAMDISK_ADDR,
142 ceee6da6 Hollis Blanchard
                                          ram_size - RAMDISK_ADDR);
143 2c9fade2 aurel32
144 2c9fade2 aurel32
        if (initrd_size < 0) {
145 ceee6da6 Hollis Blanchard
            fprintf(stderr, "qemu: could not load ram disk '%s' at %x\n",
146 ceee6da6 Hollis Blanchard
                    initrd_filename, RAMDISK_ADDR);
147 2c9fade2 aurel32
            exit(1);
148 2c9fade2 aurel32
        }
149 2c9fade2 aurel32
    }
150 2c9fade2 aurel32
151 2c9fade2 aurel32
    /* If we're loading a kernel directly, we must load the device tree too. */
152 2c9fade2 aurel32
    if (kernel_filename) {
153 ceee6da6 Hollis Blanchard
        if (bamboo_load_device_tree(FDT_ADDR, ram_size, RAMDISK_ADDR,
154 ceee6da6 Hollis Blanchard
                                    initrd_size, kernel_cmdline) < 0) {
155 2c9fade2 aurel32
            fprintf(stderr, "couldn't load device tree\n");
156 2c9fade2 aurel32
            exit(1);
157 2c9fade2 aurel32
        }
158 2c9fade2 aurel32
159 c4963817 Liu Yu
        cpu_synchronize_state(env);
160 c4963817 Liu Yu
161 2c9fade2 aurel32
        /* Set initial guest state. */
162 2c9fade2 aurel32
        env->gpr[1] = (16<<20) - 8;
163 ceee6da6 Hollis Blanchard
        env->gpr[3] = FDT_ADDR;
164 2c9fade2 aurel32
        env->nip = entry;
165 2c9fade2 aurel32
        /* XXX we currently depend on KVM to create some initial TLB entries. */
166 2c9fade2 aurel32
    }
167 2c9fade2 aurel32
168 2c9fade2 aurel32
    if (kvm_enabled())
169 2c9fade2 aurel32
        kvmppc_init();
170 2c9fade2 aurel32
}
171 2c9fade2 aurel32
172 f80f9ec9 Anthony Liguori
static QEMUMachine bamboo_machine = {
173 977b6b91 Amit Shah
    .name = "bamboo-0.13",
174 977b6b91 Amit Shah
    .alias = "bamboo",
175 977b6b91 Amit Shah
    .desc = "bamboo",
176 977b6b91 Amit Shah
    .init = bamboo_init,
177 977b6b91 Amit Shah
};
178 977b6b91 Amit Shah
179 977b6b91 Amit Shah
static QEMUMachine bamboo_machine_v0_12 = {
180 977b6b91 Amit Shah
    .name = "bamboo-0.12",
181 2c9fade2 aurel32
    .desc = "bamboo",
182 2c9fade2 aurel32
    .init = bamboo_init,
183 21be440c Amit Shah
    .compat_props = (GlobalProperty[]) {
184 21be440c Amit Shah
        {
185 21be440c Amit Shah
            .driver   = "virtio-serial-pci",
186 1e29a009 Amit Shah
            .property = "max_ports",
187 21be440c Amit Shah
            .value    = stringify(1),
188 21be440c Amit Shah
        },{
189 21be440c Amit Shah
            .driver   = "virtio-serial-pci",
190 21be440c Amit Shah
            .property = "vectors",
191 21be440c Amit Shah
            .value    = stringify(0),
192 21be440c Amit Shah
        },
193 21be440c Amit Shah
        { /* end of list */ }
194 21be440c Amit Shah
    },
195 2c9fade2 aurel32
};
196 f80f9ec9 Anthony Liguori
197 f80f9ec9 Anthony Liguori
static void bamboo_machine_init(void)
198 f80f9ec9 Anthony Liguori
{
199 f80f9ec9 Anthony Liguori
    qemu_register_machine(&bamboo_machine);
200 977b6b91 Amit Shah
    qemu_register_machine(&bamboo_machine_v0_12);
201 f80f9ec9 Anthony Liguori
}
202 f80f9ec9 Anthony Liguori
203 f80f9ec9 Anthony Liguori
machine_init(bamboo_machine_init);