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.
12 #include "qemu-common.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
)
33 target_phys_addr_t ram_bases
[4], ram_sizes
[4];
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;
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
;
52 uint32_t timebase_freq
;
53 uint32_t mem_reg_property
[]={0, 0, ram_size
};
55 printf("%s: START\n", __func__
);
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
];
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
;
81 * XXX Since qemu doesn't implement 440, we just say it's a 405. Since
82 * we don't use qemu's CPU emulation it seems to be working OK. */
83 env
= cpu_ppc_init("405");
85 fprintf(stderr
, "Unable to initialize CPU!\n");
90 printf("Calling function ppc440_init\n");
91 ppc440ep_init(env
, ram_bases
, ram_sizes
, &pic
, &pci
, 1);
92 printf("Done calling ppc440_init\n");
95 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
);
101 ret
= load_elf(kernel_filename
, 0, &ep
, &la
, NULL
);
104 fprintf(stderr
, "qemu: could not load kernel '%s'\n",
108 printf("kernel is at guest address: 0x%lx\n", (unsigned long)la
);
111 if (initrd_filename
) {
112 initrd_base
= kernel_size
+ la
;
113 printf("%s: load initrd\n", __func__
);
114 initrd_size
= load_image(initrd_filename
,
115 phys_ram_base
+ initrd_base
);
117 printf("initrd is at guest address: 0x%lx\n",
118 (unsigned long) initrd_base
);
120 if (initrd_size
< 0) {
122 "qemu: could not load initial ram disk '%s'\n",
129 /* get variable for device tree */
130 cpu_freq
= read_proc_dt_prop_cell("cpus/cpu@0/clock-frequency");
131 timebase_freq
= read_proc_dt_prop_cell("cpus/cpu@0/timebase-frequency");
133 /* load binary device tree into qemu (not guest memory) */
134 printf("%s: load device tree file\n", __func__
);
136 /* get string size */
137 ret
= asprintf(&buf
, "%s/%s", bios_dir
,
138 BINARY_DEVICE_TREE_FILE
);
141 printf("%s: Unable to malloc string buffer buf\n",
146 /* set base for device tree that will be in guest memory */
148 dt_base
= initrd_base
+ initrd_size
;
150 dt_base
= kernel_size
+ la
;
152 fdt
= load_device_tree(buf
, (unsigned long)(phys_ram_base
+ dt_base
));
154 printf("Loading device tree failed!\n");
158 printf("device tree address is at guest address: 0x%lx\n",
159 (unsigned long) dt_base
);
163 /* manipulate device tree in memory */
164 dt_cell(fdt
, "/cpus/cpu@0", "clock-frequency", cpu_freq
);
165 dt_cell(fdt
, "/cpus/cpu@0", "timebase-frequency", timebase_freq
);
166 dt_cell_multi(fdt
, "/memory", "reg", mem_reg_property
,
167 sizeof(mem_reg_property
));
168 dt_cell(fdt
, "/chosen", "linux,initrd-start", initrd_base
);
169 dt_cell(fdt
, "/chosen", "linux,initrd-end",
170 (initrd_base
+ initrd_size
));
171 dt_string(fdt
, "/chosen", "bootargs", (char *)kernel_cmdline
);
175 /* XXX insert TLB entries */
176 env
->gpr
[1] = (16<<20) - 8;
179 /* location of device tree in register */
180 env
->gpr
[3] = dt_base
;
188 /* Add virtio block devices. */
189 while ((i
= drive_get_index(IF_VIRTIO
, 0, unit_id
)) != -1) {
190 virtio_blk_init(pci
->bus
, 0x1AF4, 0x1001,
191 drives_table
[i
].bdrv
);
195 /* Register network interfaces. */
196 for (i
= 0; i
< nb_nics
; i
++) {
199 nd
->model
= "virtio";
200 pci_nic_init(pci
->bus
, nd
, -1);
204 printf("%s: DONE\n", __func__
);
207 QEMUMachine bamboo_machine
= {