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