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