1
2
3
4
5
6
7
8
9
10#include "qemu/osdep.h"
11#include "qapi/error.h"
12#include "cpu.h"
13#include "hw/sysbus.h"
14#include "migration/vmstate.h"
15#include "hw/arm/boot.h"
16#include "hw/net/smc91c111.h"
17#include "net/net.h"
18#include "sysemu/sysemu.h"
19#include "hw/pci/pci.h"
20#include "hw/i2c/i2c.h"
21#include "hw/i2c/arm_sbcon_i2c.h"
22#include "hw/irq.h"
23#include "hw/boards.h"
24#include "exec/address-spaces.h"
25#include "hw/block/flash.h"
26#include "qemu/error-report.h"
27#include "hw/char/pl011.h"
28#include "hw/sd/sd.h"
29#include "qom/object.h"
30
31#define VERSATILE_FLASH_ADDR 0x34000000
32#define VERSATILE_FLASH_SIZE (64 * 1024 * 1024)
33#define VERSATILE_FLASH_SECT_SIZE (256 * 1024)
34
35
36
37#define TYPE_VERSATILE_PB_SIC "versatilepb_sic"
38OBJECT_DECLARE_SIMPLE_TYPE(vpb_sic_state, VERSATILE_PB_SIC)
39
40struct vpb_sic_state {
41 SysBusDevice parent_obj;
42
43 MemoryRegion iomem;
44 uint32_t level;
45 uint32_t mask;
46 uint32_t pic_enable;
47 qemu_irq parent[32];
48 int irq;
49};
50
51static const VMStateDescription vmstate_vpb_sic = {
52 .name = "versatilepb_sic",
53 .version_id = 1,
54 .minimum_version_id = 1,
55 .fields = (VMStateField[]) {
56 VMSTATE_UINT32(level, vpb_sic_state),
57 VMSTATE_UINT32(mask, vpb_sic_state),
58 VMSTATE_UINT32(pic_enable, vpb_sic_state),
59 VMSTATE_END_OF_LIST()
60 }
61};
62
63static void vpb_sic_update(vpb_sic_state *s)
64{
65 uint32_t flags;
66
67 flags = s->level & s->mask;
68 qemu_set_irq(s->parent[s->irq], flags != 0);
69}
70
71static void vpb_sic_update_pic(vpb_sic_state *s)
72{
73 int i;
74 uint32_t mask;
75
76 for (i = 21; i <= 30; i++) {
77 mask = 1u << i;
78 if (!(s->pic_enable & mask))
79 continue;
80 qemu_set_irq(s->parent[i], (s->level & mask) != 0);
81 }
82}
83
84static void vpb_sic_set_irq(void *opaque, int irq, int level)
85{
86 vpb_sic_state *s = (vpb_sic_state *)opaque;
87 if (level)
88 s->level |= 1u << irq;
89 else
90 s->level &= ~(1u << irq);
91 if (s->pic_enable & (1u << irq))
92 qemu_set_irq(s->parent[irq], level);
93 vpb_sic_update(s);
94}
95
96static uint64_t vpb_sic_read(void *opaque, hwaddr offset,
97 unsigned size)
98{
99 vpb_sic_state *s = (vpb_sic_state *)opaque;
100
101 switch (offset >> 2) {
102 case 0:
103 return s->level & s->mask;
104 case 1:
105 return s->level;
106 case 2:
107 return s->mask;
108 case 4:
109 return s->level & 1;
110 case 8:
111 return s->pic_enable;
112 default:
113 printf ("vpb_sic_read: Bad register offset 0x%x\n", (int)offset);
114 return 0;
115 }
116}
117
118static void vpb_sic_write(void *opaque, hwaddr offset,
119 uint64_t value, unsigned size)
120{
121 vpb_sic_state *s = (vpb_sic_state *)opaque;
122
123 switch (offset >> 2) {
124 case 2:
125 s->mask |= value;
126 break;
127 case 3:
128 s->mask &= ~value;
129 break;
130 case 4:
131 if (value)
132 s->mask |= 1;
133 break;
134 case 5:
135 if (value)
136 s->mask &= ~1u;
137 break;
138 case 8:
139 s->pic_enable |= (value & 0x7fe00000);
140 vpb_sic_update_pic(s);
141 break;
142 case 9:
143 s->pic_enable &= ~value;
144 vpb_sic_update_pic(s);
145 break;
146 default:
147 printf ("vpb_sic_write: Bad register offset 0x%x\n", (int)offset);
148 return;
149 }
150 vpb_sic_update(s);
151}
152
153static const MemoryRegionOps vpb_sic_ops = {
154 .read = vpb_sic_read,
155 .write = vpb_sic_write,
156 .endianness = DEVICE_NATIVE_ENDIAN,
157};
158
159static void vpb_sic_init(Object *obj)
160{
161 DeviceState *dev = DEVICE(obj);
162 vpb_sic_state *s = VERSATILE_PB_SIC(obj);
163 SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
164 int i;
165
166 qdev_init_gpio_in(dev, vpb_sic_set_irq, 32);
167 for (i = 0; i < 32; i++) {
168 sysbus_init_irq(sbd, &s->parent[i]);
169 }
170 s->irq = 31;
171 memory_region_init_io(&s->iomem, obj, &vpb_sic_ops, s,
172 "vpb-sic", 0x1000);
173 sysbus_init_mmio(sbd, &s->iomem);
174}
175
176
177
178
179
180
181
182static struct arm_boot_info versatile_binfo;
183
184static void versatile_init(MachineState *machine, int board_id)
185{
186 Object *cpuobj;
187 ARMCPU *cpu;
188 MemoryRegion *sysmem = get_system_memory();
189 qemu_irq pic[32];
190 qemu_irq sic[32];
191 DeviceState *dev, *sysctl;
192 SysBusDevice *busdev;
193 DeviceState *pl041;
194 PCIBus *pci_bus;
195 NICInfo *nd;
196 I2CBus *i2c;
197 int n;
198 int done_smc = 0;
199 DriveInfo *dinfo;
200
201 if (machine->ram_size > 0x10000000) {
202
203
204
205
206 error_report("versatilepb: memory size must not exceed 256MB");
207 exit(1);
208 }
209
210 cpuobj = object_new(machine->cpu_type);
211
212
213
214
215
216 if (object_property_find(cpuobj, "has_el3")) {
217 object_property_set_bool(cpuobj, "has_el3", false, &error_fatal);
218 }
219
220 qdev_realize(DEVICE(cpuobj), NULL, &error_fatal);
221
222 cpu = ARM_CPU(cpuobj);
223
224
225
226 memory_region_add_subregion(sysmem, 0, machine->ram);
227
228 sysctl = qdev_new("realview_sysctl");
229 qdev_prop_set_uint32(sysctl, "sys_id", 0x41007004);
230 qdev_prop_set_uint32(sysctl, "proc_id", 0x02000000);
231 sysbus_realize_and_unref(SYS_BUS_DEVICE(sysctl), &error_fatal);
232 sysbus_mmio_map(SYS_BUS_DEVICE(sysctl), 0, 0x10000000);
233
234 dev = sysbus_create_varargs("pl190", 0x10140000,
235 qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ),
236 qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_FIQ),
237 NULL);
238 for (n = 0; n < 32; n++) {
239 pic[n] = qdev_get_gpio_in(dev, n);
240 }
241 dev = sysbus_create_simple(TYPE_VERSATILE_PB_SIC, 0x10003000, NULL);
242 for (n = 0; n < 32; n++) {
243 sysbus_connect_irq(SYS_BUS_DEVICE(dev), n, pic[n]);
244 sic[n] = qdev_get_gpio_in(dev, n);
245 }
246
247 sysbus_create_simple("pl050_keyboard", 0x10006000, sic[3]);
248 sysbus_create_simple("pl050_mouse", 0x10007000, sic[4]);
249
250 dev = qdev_new("versatile_pci");
251 busdev = SYS_BUS_DEVICE(dev);
252 sysbus_realize_and_unref(busdev, &error_fatal);
253 sysbus_mmio_map(busdev, 0, 0x10001000);
254 sysbus_mmio_map(busdev, 1, 0x41000000);
255 sysbus_mmio_map(busdev, 2, 0x42000000);
256 sysbus_mmio_map(busdev, 3, 0x43000000);
257 sysbus_mmio_map(busdev, 4, 0x44000000);
258 sysbus_mmio_map(busdev, 5, 0x50000000);
259 sysbus_mmio_map(busdev, 6, 0x60000000);
260 sysbus_connect_irq(busdev, 0, sic[27]);
261 sysbus_connect_irq(busdev, 1, sic[28]);
262 sysbus_connect_irq(busdev, 2, sic[29]);
263 sysbus_connect_irq(busdev, 3, sic[30]);
264 pci_bus = (PCIBus *)qdev_get_child_bus(dev, "pci");
265
266 for(n = 0; n < nb_nics; n++) {
267 nd = &nd_table[n];
268
269 if (!done_smc && (!nd->model || strcmp(nd->model, "smc91c111") == 0)) {
270 smc91c111_init(nd, 0x10010000, sic[25]);
271 done_smc = 1;
272 } else {
273 pci_nic_init_nofail(nd, pci_bus, "rtl8139", NULL);
274 }
275 }
276 if (machine_usb(machine)) {
277 pci_create_simple(pci_bus, -1, "pci-ohci");
278 }
279 n = drive_get_max_bus(IF_SCSI);
280 while (n >= 0) {
281 dev = DEVICE(pci_create_simple(pci_bus, -1, "lsi53c895a"));
282 lsi53c8xx_handle_legacy_cmdline(dev);
283 n--;
284 }
285
286 pl011_create(0x101f1000, pic[12], serial_hd(0));
287 pl011_create(0x101f2000, pic[13], serial_hd(1));
288 pl011_create(0x101f3000, pic[14], serial_hd(2));
289 pl011_create(0x10009000, sic[6], serial_hd(3));
290
291 dev = qdev_new("pl080");
292 object_property_set_link(OBJECT(dev), "downstream", OBJECT(sysmem),
293 &error_fatal);
294 busdev = SYS_BUS_DEVICE(dev);
295 sysbus_realize_and_unref(busdev, &error_fatal);
296 sysbus_mmio_map(busdev, 0, 0x10130000);
297 sysbus_connect_irq(busdev, 0, pic[17]);
298
299 sysbus_create_simple("sp804", 0x101e2000, pic[4]);
300 sysbus_create_simple("sp804", 0x101e3000, pic[5]);
301
302 sysbus_create_simple("pl061", 0x101e4000, pic[6]);
303 sysbus_create_simple("pl061", 0x101e5000, pic[7]);
304 sysbus_create_simple("pl061", 0x101e6000, pic[8]);
305 sysbus_create_simple("pl061", 0x101e7000, pic[9]);
306
307
308
309 dev = sysbus_create_simple("pl110_versatile", 0x10120000, pic[16]);
310
311 qdev_connect_gpio_out(sysctl, 0, qdev_get_gpio_in(dev, 0));
312
313 dev = sysbus_create_varargs("pl181", 0x10005000, sic[22], sic[1], NULL);
314 dinfo = drive_get_next(IF_SD);
315 if (dinfo) {
316 DeviceState *card;
317
318 card = qdev_new(TYPE_SD_CARD);
319 qdev_prop_set_drive_err(card, "drive", blk_by_legacy_dinfo(dinfo),
320 &error_fatal);
321 qdev_realize_and_unref(card, qdev_get_child_bus(dev, "sd-bus"),
322 &error_fatal);
323 }
324
325 dev = sysbus_create_varargs("pl181", 0x1000b000, sic[23], sic[2], NULL);
326 dinfo = drive_get_next(IF_SD);
327 if (dinfo) {
328 DeviceState *card;
329
330 card = qdev_new(TYPE_SD_CARD);
331 qdev_prop_set_drive_err(card, "drive", blk_by_legacy_dinfo(dinfo),
332 &error_fatal);
333 qdev_realize_and_unref(card, qdev_get_child_bus(dev, "sd-bus"),
334 &error_fatal);
335 }
336
337
338 sysbus_create_simple("pl031", 0x101e8000, pic[10]);
339
340 dev = sysbus_create_simple(TYPE_VERSATILE_I2C, 0x10002000, NULL);
341 i2c = (I2CBus *)qdev_get_child_bus(dev, "i2c");
342 i2c_slave_create_simple(i2c, "ds1338", 0x68);
343
344
345 pl041 = qdev_new("pl041");
346 qdev_prop_set_uint32(pl041, "nc_fifo_depth", 512);
347 sysbus_realize_and_unref(SYS_BUS_DEVICE(pl041), &error_fatal);
348 sysbus_mmio_map(SYS_BUS_DEVICE(pl041), 0, 0x10004000);
349 sysbus_connect_irq(SYS_BUS_DEVICE(pl041), 0, sic[24]);
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388 dinfo = drive_get(IF_PFLASH, 0, 0);
389 if (!pflash_cfi01_register(VERSATILE_FLASH_ADDR, "versatile.flash",
390 VERSATILE_FLASH_SIZE,
391 dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
392 VERSATILE_FLASH_SECT_SIZE,
393 4, 0x0089, 0x0018, 0x0000, 0x0, 0)) {
394 fprintf(stderr, "qemu: Error registering flash memory.\n");
395 }
396
397 versatile_binfo.ram_size = machine->ram_size;
398 versatile_binfo.board_id = board_id;
399 arm_load_kernel(cpu, machine, &versatile_binfo);
400}
401
402static void vpb_init(MachineState *machine)
403{
404 versatile_init(machine, 0x183);
405}
406
407static void vab_init(MachineState *machine)
408{
409 versatile_init(machine, 0x25e);
410}
411
412static void versatilepb_class_init(ObjectClass *oc, void *data)
413{
414 MachineClass *mc = MACHINE_CLASS(oc);
415
416 mc->desc = "ARM Versatile/PB (ARM926EJ-S)";
417 mc->init = vpb_init;
418 mc->block_default_type = IF_SCSI;
419 mc->ignore_memory_transaction_failures = true;
420 mc->default_cpu_type = ARM_CPU_TYPE_NAME("arm926");
421 mc->default_ram_id = "versatile.ram";
422}
423
424static const TypeInfo versatilepb_type = {
425 .name = MACHINE_TYPE_NAME("versatilepb"),
426 .parent = TYPE_MACHINE,
427 .class_init = versatilepb_class_init,
428};
429
430static void versatileab_class_init(ObjectClass *oc, void *data)
431{
432 MachineClass *mc = MACHINE_CLASS(oc);
433
434 mc->desc = "ARM Versatile/AB (ARM926EJ-S)";
435 mc->init = vab_init;
436 mc->block_default_type = IF_SCSI;
437 mc->ignore_memory_transaction_failures = true;
438 mc->default_cpu_type = ARM_CPU_TYPE_NAME("arm926");
439 mc->default_ram_id = "versatile.ram";
440}
441
442static const TypeInfo versatileab_type = {
443 .name = MACHINE_TYPE_NAME("versatileab"),
444 .parent = TYPE_MACHINE,
445 .class_init = versatileab_class_init,
446};
447
448static void versatile_machine_init(void)
449{
450 type_register_static(&versatilepb_type);
451 type_register_static(&versatileab_type);
452}
453
454type_init(versatile_machine_init)
455
456static void vpb_sic_class_init(ObjectClass *klass, void *data)
457{
458 DeviceClass *dc = DEVICE_CLASS(klass);
459
460 dc->vmsd = &vmstate_vpb_sic;
461}
462
463static const TypeInfo vpb_sic_info = {
464 .name = TYPE_VERSATILE_PB_SIC,
465 .parent = TYPE_SYS_BUS_DEVICE,
466 .instance_size = sizeof(vpb_sic_state),
467 .instance_init = vpb_sic_init,
468 .class_init = vpb_sic_class_init,
469};
470
471static void versatilepb_register_types(void)
472{
473 type_register_static(&vpb_sic_info);
474}
475
476type_init(versatilepb_register_types)
477