Add fd_readv handler to tap
[qemu-kvm/fedora.git] / hw / ppc440_bamboo.c
blob29210f05ca39cef62d367ad0e3a0fa3dd26358dc
1 /*
2 * Qemu PowerPC 440 board emualtion
4 * Copyright 2007 IBM Corporation.
5 * Authors: Jerone Young <jyoung5@us.ibm.com>
7 * This work is licensed under the GNU GPL license version 2 or later.
9 */
11 #include "config.h"
12 #include "qemu-common.h"
13 #include "net.h"
14 #include "hw.h"
15 #include "pci.h"
16 #include "sysemu.h"
17 #include "ppc440.h"
18 #include "qemu-kvm.h"
19 #include "device_tree.h"
21 #define BINARY_DEVICE_TREE_FILE "bamboo.dtb"
23 #define bytes_to_mb(a) (a>>20)
25 void bamboo_init(ram_addr_t ram_size, int vga_ram_size,
26 const char *boot_device, DisplayState *ds,
27 const char *kernel_filename,
28 const char *kernel_cmdline,
29 const char *initrd_filename,
30 const char *cpu_model)
32 char *buf=NULL;
33 target_phys_addr_t ram_bases[4], ram_sizes[4];
34 NICInfo *nd;
35 qemu_irq *pic;
36 ppc4xx_pci_t *pci;
37 CPUState *env;
38 target_ulong ep=0;
39 target_ulong la=0;
40 int is_linux=1; /* Will assume allways is Linux for now */
41 target_long kernel_size=0;
42 target_ulong initrd_base=0;
43 target_long initrd_size=0;
44 target_ulong dt_base=0;
45 void *fdt;
46 int ret;
47 int ram_stick_sizes[] = {256<<20, 128<<20, 64<<20,
48 32<<20, 16<<20, 8<<20 }; /* in bytes */
49 ram_addr_t tmp_ram_size;
50 int i=0, k=0;
51 uint32_t cpu_freq;
52 uint32_t timebase_freq;
53 uint32_t mem_reg_property[]={0, 0, ram_size};
55 printf("%s: START\n", __func__);
57 /* Setup Memory */
58 printf("Ram size passed is: %i MB\n",
59 bytes_to_mb((int)ram_size));
61 tmp_ram_size = ram_size;
63 for (i=0; i < (sizeof(ram_sizes)/sizeof(ram_sizes[0])); i++) {
64 for (k=0; k < (sizeof(ram_stick_sizes)/sizeof(ram_stick_sizes[0])); k++) {
65 if ((tmp_ram_size/ram_stick_sizes[k]) > 0) {
66 ram_sizes[i] = ram_stick_sizes[k];
67 tmp_ram_size -= ram_stick_sizes[k];
68 break;
73 if (tmp_ram_size) {
74 printf("WARNING: %i MB left over memory is ram\n",
75 bytes_to_mb((int)tmp_ram_size));
76 ram_size -= tmp_ram_size;
77 mem_reg_property[2] = ram_size;
80 /* Setup CPU */
81 env = cpu_ppc_init("440");
82 if (!env) {
83 fprintf(stderr, "Unable to initilize CPU!\n");
84 exit(1);
87 /* call init */
88 printf("Calling function ppc440_init\n");
89 ppc440ep_init(env, ram_bases, ram_sizes, &pic, &pci, 1);
90 printf("Done calling ppc440_init\n");
92 /* Register mem */
93 cpu_register_physical_memory(0, ram_size, 0);
94 if (kvm_enabled())
95 kvm_cpu_register_physical_memory(0, ram_size, 0);
97 /* load kernel with uboot loader */
98 printf("%s: load kernel\n", __func__);
99 ret = load_uimage(kernel_filename, &ep, &la, &kernel_size, &is_linux);
100 if (ret < 0) {
101 fprintf(stderr, "qemu: could not load kernel '%s'\n",
102 kernel_filename);
103 exit(1);
105 printf("kernel is at guest address: 0x%lx\n", (unsigned long)la);
107 /* load initrd */
108 if (initrd_filename) {
109 initrd_base = kernel_size + la;
110 printf("%s: load initrd\n", __func__);
111 initrd_size = load_image(initrd_filename,
112 phys_ram_base + initrd_base);
114 printf("initrd is at guest address: 0x%lx\n",
115 (unsigned long) initrd_base);
117 if (initrd_size < 0) {
118 fprintf(stderr,
119 "qemu: could not load initial ram disk '%s'\n",
120 initrd_filename);
121 exit(1);
125 #ifdef CONFIG_LIBFDT
126 /* get variable for device tree */
127 cpu_freq = read_proc_dt_prop_cell("cpus/cpu@0/clock-frequency");
128 timebase_freq = read_proc_dt_prop_cell("cpus/cpu@0/timebase-frequency");
130 /* load binary device tree into qemu (not guest memory) */
131 printf("%s: load device tree file\n", __func__);
133 /* get string size */
134 ret = asprintf(&buf, "%s/%s", bios_dir,
135 BINARY_DEVICE_TREE_FILE);
137 if (ret < 0) {
138 printf("%s: Unable to malloc string buffer buf\n",
139 __func__);
140 exit(1);
143 /* set base for device tree that will be in guest memory */
144 if (initrd_base)
145 dt_base = initrd_base + initrd_size;
146 else
147 dt_base = kernel_size + la;
149 fdt = load_device_tree(buf, (unsigned long)(phys_ram_base + dt_base));
150 if (fdt == NULL) {
151 printf("Loading device tree failed!\n");
152 exit(1);
155 printf("device tree address is at guest address: 0x%lx\n",
156 (unsigned long) dt_base);
158 free(buf);
160 /* manipulate device tree in memory */
161 dt_cell(fdt, "/cpus/cpu@0", "clock-frequency", cpu_freq);
162 dt_cell(fdt, "/cpus/cpu@0", "timebase-frequency", timebase_freq);
163 dt_cell_multi(fdt, "/memory", "reg", mem_reg_property,
164 sizeof(mem_reg_property));
165 dt_cell(fdt, "/chosen", "linux,initrd-start", initrd_base);
166 dt_cell(fdt, "/chosen", "linux,initrd-end",
167 (initrd_base + initrd_size));
168 dt_string(fdt, "/chosen", "bootargs", (char *)kernel_cmdline);
169 #endif
171 if (kvm_enabled()) {
172 /* XXX insert TLB entries */
173 env->gpr[1] = (16<<20) - 8;
175 #ifdef CONFIG_LIBFDT
176 /* location of device tree in register */
177 env->gpr[3] = dt_base;
178 #endif
179 env->nip = ep;
182 if (pci) {
183 int unit_id = 0;
185 /* Add virtio block devices. */
186 while ((i = drive_get_index(IF_VIRTIO, 0, unit_id)) != -1) {
187 virtio_blk_init(pci->bus, 0x1AF4, 0x1001,
188 drives_table[i].bdrv);
189 unit_id++;
192 /* Register network interfaces. */
193 for (i = 0; i < nb_nics; i++) {
194 nd = &nd_table[i];
195 if (!nd->model)
196 nd->model = "virtio";
197 pci_nic_init(pci->bus, nd, -1);
201 printf("%s: DONE\n", __func__);
204 QEMUMachine bamboo_machine = {
205 "bamboo",
206 "bamboo",
207 bamboo_init,