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