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