1
2
3
4
5
6
7
8
9
10#include "qemu/osdep.h"
11#include "qapi/error.h"
12#include "qemu-common.h"
13#include "cpu.h"
14#include "hw/sysbus.h"
15#include "hw/arm/arm.h"
16#include "hw/arm/primecell.h"
17#include "hw/devices.h"
18#include "hw/pci/pci.h"
19#include "net/net.h"
20#include "sysemu/sysemu.h"
21#include "hw/boards.h"
22#include "hw/i2c/i2c.h"
23#include "sysemu/block-backend.h"
24#include "exec/address-spaces.h"
25#include "qemu/error-report.h"
26
27#define SMP_BOOT_ADDR 0xe0000000
28#define SMP_BOOTREG_ADDR 0x10000030
29
30
31
32static struct arm_boot_info realview_binfo = {
33 .smp_loader_start = SMP_BOOT_ADDR,
34 .smp_bootreg_addr = SMP_BOOTREG_ADDR,
35};
36
37
38enum realview_board_type {
39 BOARD_EB,
40 BOARD_EB_MPCORE,
41 BOARD_PB_A8,
42 BOARD_PBX_A9,
43};
44
45static const int realview_board_id[] = {
46 0x33b,
47 0x33b,
48 0x769,
49 0x76d
50};
51
52static void realview_init(MachineState *machine,
53 enum realview_board_type board_type)
54{
55 ARMCPU *cpu = NULL;
56 CPUARMState *env;
57 ObjectClass *cpu_oc;
58 MemoryRegion *sysmem = get_system_memory();
59 MemoryRegion *ram_lo;
60 MemoryRegion *ram_hi = g_new(MemoryRegion, 1);
61 MemoryRegion *ram_alias = g_new(MemoryRegion, 1);
62 MemoryRegion *ram_hack = g_new(MemoryRegion, 1);
63 DeviceState *dev, *sysctl, *gpio2, *pl041;
64 SysBusDevice *busdev;
65 qemu_irq pic[64];
66 qemu_irq mmc_irq[2];
67 PCIBus *pci_bus = NULL;
68 NICInfo *nd;
69 I2CBus *i2c;
70 int n;
71 int done_nic = 0;
72 qemu_irq cpu_irq[4];
73 int is_mpcore = 0;
74 int is_pb = 0;
75 uint32_t proc_id = 0;
76 uint32_t sys_id;
77 ram_addr_t low_ram_size;
78 ram_addr_t ram_size = machine->ram_size;
79 hwaddr periphbase = 0;
80
81 switch (board_type) {
82 case BOARD_EB:
83 break;
84 case BOARD_EB_MPCORE:
85 is_mpcore = 1;
86 periphbase = 0x10100000;
87 break;
88 case BOARD_PB_A8:
89 is_pb = 1;
90 break;
91 case BOARD_PBX_A9:
92 is_mpcore = 1;
93 is_pb = 1;
94 periphbase = 0x1f000000;
95 break;
96 }
97
98 cpu_oc = cpu_class_by_name(TYPE_ARM_CPU, machine->cpu_model);
99 if (!cpu_oc) {
100 fprintf(stderr, "Unable to find CPU definition\n");
101 exit(1);
102 }
103
104 for (n = 0; n < smp_cpus; n++) {
105 Object *cpuobj = object_new(object_class_get_name(cpu_oc));
106
107
108
109
110
111 if (object_property_find(cpuobj, "has_el3", NULL)) {
112 object_property_set_bool(cpuobj, false, "has_el3", &error_fatal);
113 }
114
115 if (is_pb && is_mpcore) {
116 object_property_set_int(cpuobj, periphbase, "reset-cbar",
117 &error_fatal);
118 }
119
120 object_property_set_bool(cpuobj, true, "realized", &error_fatal);
121
122 cpu_irq[n] = qdev_get_gpio_in(DEVICE(cpuobj), ARM_CPU_IRQ);
123 }
124 cpu = ARM_CPU(first_cpu);
125 env = &cpu->env;
126 if (arm_feature(env, ARM_FEATURE_V7)) {
127 if (is_mpcore) {
128 proc_id = 0x0c000000;
129 } else {
130 proc_id = 0x0e000000;
131 }
132 } else if (arm_feature(env, ARM_FEATURE_V6K)) {
133 proc_id = 0x06000000;
134 } else if (arm_feature(env, ARM_FEATURE_V6)) {
135 proc_id = 0x04000000;
136 } else {
137 proc_id = 0x02000000;
138 }
139
140 if (is_pb && ram_size > 0x20000000) {
141
142 ram_lo = g_new(MemoryRegion, 1);
143 low_ram_size = ram_size - 0x20000000;
144 ram_size = 0x20000000;
145 memory_region_init_ram(ram_lo, NULL, "realview.lowmem", low_ram_size,
146 &error_fatal);
147 vmstate_register_ram_global(ram_lo);
148 memory_region_add_subregion(sysmem, 0x20000000, ram_lo);
149 }
150
151 memory_region_init_ram(ram_hi, NULL, "realview.highmem", ram_size,
152 &error_fatal);
153 vmstate_register_ram_global(ram_hi);
154 low_ram_size = ram_size;
155 if (low_ram_size > 0x10000000)
156 low_ram_size = 0x10000000;
157
158 memory_region_init_alias(ram_alias, NULL, "realview.alias",
159 ram_hi, 0, low_ram_size);
160 memory_region_add_subregion(sysmem, 0, ram_alias);
161 if (is_pb) {
162
163 memory_region_add_subregion(sysmem, 0x70000000, ram_hi);
164 } else {
165 ram_size = low_ram_size;
166 }
167
168 sys_id = is_pb ? 0x01780500 : 0xc1400400;
169 sysctl = qdev_create(NULL, "realview_sysctl");
170 qdev_prop_set_uint32(sysctl, "sys_id", sys_id);
171 qdev_prop_set_uint32(sysctl, "proc_id", proc_id);
172 qdev_init_nofail(sysctl);
173 sysbus_mmio_map(SYS_BUS_DEVICE(sysctl), 0, 0x10000000);
174
175 if (is_mpcore) {
176 dev = qdev_create(NULL, is_pb ? "a9mpcore_priv": "realview_mpcore");
177 qdev_prop_set_uint32(dev, "num-cpu", smp_cpus);
178 qdev_init_nofail(dev);
179 busdev = SYS_BUS_DEVICE(dev);
180 sysbus_mmio_map(busdev, 0, periphbase);
181 for (n = 0; n < smp_cpus; n++) {
182 sysbus_connect_irq(busdev, n, cpu_irq[n]);
183 }
184 sysbus_create_varargs("l2x0", periphbase + 0x2000, NULL);
185
186 realview_binfo.gic_cpu_if_addr = periphbase + 0x100;
187 } else {
188 uint32_t gic_addr = is_pb ? 0x1e000000 : 0x10040000;
189
190 dev = sysbus_create_simple("realview_gic", gic_addr, cpu_irq[0]);
191 }
192 for (n = 0; n < 64; n++) {
193 pic[n] = qdev_get_gpio_in(dev, n);
194 }
195
196 pl041 = qdev_create(NULL, "pl041");
197 qdev_prop_set_uint32(pl041, "nc_fifo_depth", 512);
198 qdev_init_nofail(pl041);
199 sysbus_mmio_map(SYS_BUS_DEVICE(pl041), 0, 0x10004000);
200 sysbus_connect_irq(SYS_BUS_DEVICE(pl041), 0, pic[19]);
201
202 sysbus_create_simple("pl050_keyboard", 0x10006000, pic[20]);
203 sysbus_create_simple("pl050_mouse", 0x10007000, pic[21]);
204
205 sysbus_create_simple("pl011", 0x10009000, pic[12]);
206 sysbus_create_simple("pl011", 0x1000a000, pic[13]);
207 sysbus_create_simple("pl011", 0x1000b000, pic[14]);
208 sysbus_create_simple("pl011", 0x1000c000, pic[15]);
209
210
211 sysbus_create_simple("pl081", 0x10030000, pic[24]);
212
213 sysbus_create_simple("sp804", 0x10011000, pic[4]);
214 sysbus_create_simple("sp804", 0x10012000, pic[5]);
215
216 sysbus_create_simple("pl061", 0x10013000, pic[6]);
217 sysbus_create_simple("pl061", 0x10014000, pic[7]);
218 gpio2 = sysbus_create_simple("pl061", 0x10015000, pic[8]);
219
220 sysbus_create_simple("pl111", 0x10020000, pic[23]);
221
222 dev = sysbus_create_varargs("pl181", 0x10005000, pic[17], pic[18], NULL);
223
224
225
226
227
228
229 mmc_irq[0] = qemu_irq_split(
230 qdev_get_gpio_in(sysctl, ARM_SYSCTL_GPIO_MMC_WPROT),
231 qdev_get_gpio_in(gpio2, 1));
232 mmc_irq[1] = qemu_irq_split(
233 qdev_get_gpio_in(sysctl, ARM_SYSCTL_GPIO_MMC_CARDIN),
234 qemu_irq_invert(qdev_get_gpio_in(gpio2, 0)));
235 qdev_connect_gpio_out(dev, 0, mmc_irq[0]);
236 qdev_connect_gpio_out(dev, 1, mmc_irq[1]);
237
238 sysbus_create_simple("pl031", 0x10017000, pic[10]);
239
240 if (!is_pb) {
241 dev = qdev_create(NULL, "realview_pci");
242 busdev = SYS_BUS_DEVICE(dev);
243 qdev_init_nofail(dev);
244 sysbus_mmio_map(busdev, 0, 0x10019000);
245 sysbus_mmio_map(busdev, 1, 0x60000000);
246 sysbus_mmio_map(busdev, 2, 0x61000000);
247 sysbus_mmio_map(busdev, 3, 0x62000000);
248 sysbus_mmio_map(busdev, 4, 0x63000000);
249 sysbus_mmio_map(busdev, 5, 0x64000000);
250 sysbus_mmio_map(busdev, 6, 0x68000000);
251 sysbus_connect_irq(busdev, 0, pic[48]);
252 sysbus_connect_irq(busdev, 1, pic[49]);
253 sysbus_connect_irq(busdev, 2, pic[50]);
254 sysbus_connect_irq(busdev, 3, pic[51]);
255 pci_bus = (PCIBus *)qdev_get_child_bus(dev, "pci");
256 if (usb_enabled()) {
257 pci_create_simple(pci_bus, -1, "pci-ohci");
258 }
259 n = drive_get_max_bus(IF_SCSI);
260 while (n >= 0) {
261 pci_create_simple(pci_bus, -1, "lsi53c895a");
262 n--;
263 }
264 }
265 for(n = 0; n < nb_nics; n++) {
266 nd = &nd_table[n];
267
268 if (!done_nic && (!nd->model ||
269 strcmp(nd->model, is_pb ? "lan9118" : "smc91c111") == 0)) {
270 if (is_pb) {
271 lan9118_init(nd, 0x4e000000, pic[28]);
272 } else {
273 smc91c111_init(nd, 0x4e000000, pic[28]);
274 }
275 done_nic = 1;
276 } else {
277 if (pci_bus) {
278 pci_nic_init_nofail(nd, pci_bus, "rtl8139", NULL);
279 }
280 }
281 }
282
283 dev = sysbus_create_simple("versatile_i2c", 0x10002000, NULL);
284 i2c = (I2CBus *)qdev_get_child_bus(dev, "i2c");
285 i2c_create_slave(i2c, "ds1338", 0x68);
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347 memory_region_init_ram(ram_hack, NULL, "realview.hack", 0x1000,
348 &error_fatal);
349 vmstate_register_ram_global(ram_hack);
350 memory_region_add_subregion(sysmem, SMP_BOOT_ADDR, ram_hack);
351
352 realview_binfo.ram_size = ram_size;
353 realview_binfo.kernel_filename = machine->kernel_filename;
354 realview_binfo.kernel_cmdline = machine->kernel_cmdline;
355 realview_binfo.initrd_filename = machine->initrd_filename;
356 realview_binfo.nb_cpus = smp_cpus;
357 realview_binfo.board_id = realview_board_id[board_type];
358 realview_binfo.loader_start = (board_type == BOARD_PB_A8 ? 0x70000000 : 0);
359 arm_load_kernel(ARM_CPU(first_cpu), &realview_binfo);
360}
361
362static void realview_eb_init(MachineState *machine)
363{
364 if (!machine->cpu_model) {
365 machine->cpu_model = "arm926";
366 }
367 realview_init(machine, BOARD_EB);
368}
369
370static void realview_eb_mpcore_init(MachineState *machine)
371{
372 if (!machine->cpu_model) {
373 machine->cpu_model = "arm11mpcore";
374 }
375 realview_init(machine, BOARD_EB_MPCORE);
376}
377
378static void realview_pb_a8_init(MachineState *machine)
379{
380 if (!machine->cpu_model) {
381 machine->cpu_model = "cortex-a8";
382 }
383 realview_init(machine, BOARD_PB_A8);
384}
385
386static void realview_pbx_a9_init(MachineState *machine)
387{
388 if (!machine->cpu_model) {
389 machine->cpu_model = "cortex-a9";
390 }
391 realview_init(machine, BOARD_PBX_A9);
392}
393
394static void realview_eb_class_init(ObjectClass *oc, void *data)
395{
396 MachineClass *mc = MACHINE_CLASS(oc);
397
398 mc->desc = "ARM RealView Emulation Baseboard (ARM926EJ-S)";
399 mc->init = realview_eb_init;
400 mc->block_default_type = IF_SCSI;
401}
402
403static const TypeInfo realview_eb_type = {
404 .name = MACHINE_TYPE_NAME("realview-eb"),
405 .parent = TYPE_MACHINE,
406 .class_init = realview_eb_class_init,
407};
408
409static void realview_eb_mpcore_class_init(ObjectClass *oc, void *data)
410{
411 MachineClass *mc = MACHINE_CLASS(oc);
412
413 mc->desc = "ARM RealView Emulation Baseboard (ARM11MPCore)";
414 mc->init = realview_eb_mpcore_init;
415 mc->block_default_type = IF_SCSI;
416 mc->max_cpus = 4;
417}
418
419static const TypeInfo realview_eb_mpcore_type = {
420 .name = MACHINE_TYPE_NAME("realview-eb-mpcore"),
421 .parent = TYPE_MACHINE,
422 .class_init = realview_eb_mpcore_class_init,
423};
424
425static void realview_pb_a8_class_init(ObjectClass *oc, void *data)
426{
427 MachineClass *mc = MACHINE_CLASS(oc);
428
429 mc->desc = "ARM RealView Platform Baseboard for Cortex-A8";
430 mc->init = realview_pb_a8_init;
431}
432
433static const TypeInfo realview_pb_a8_type = {
434 .name = MACHINE_TYPE_NAME("realview-pb-a8"),
435 .parent = TYPE_MACHINE,
436 .class_init = realview_pb_a8_class_init,
437};
438
439static void realview_pbx_a9_class_init(ObjectClass *oc, void *data)
440{
441 MachineClass *mc = MACHINE_CLASS(oc);
442
443 mc->desc = "ARM RealView Platform Baseboard Explore for Cortex-A9";
444 mc->init = realview_pbx_a9_init;
445 mc->block_default_type = IF_SCSI;
446 mc->max_cpus = 4;
447}
448
449static const TypeInfo realview_pbx_a9_type = {
450 .name = MACHINE_TYPE_NAME("realview-pbx-a9"),
451 .parent = TYPE_MACHINE,
452 .class_init = realview_pbx_a9_class_init,
453};
454
455static void realview_machine_init(void)
456{
457 type_register_static(&realview_eb_type);
458 type_register_static(&realview_eb_mpcore_type);
459 type_register_static(&realview_pb_a8_type);
460 type_register_static(&realview_pbx_a9_type);
461}
462
463type_init(realview_machine_init)
464