Statistics
| Branch: | Revision:

root / hw / ppc440_bamboo.c @ 5c3234c6

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