]> git.ipfire.org Git - thirdparty/qemu.git/blame - hw/arm/integratorcp.c
error: Use error_report_err() where appropriate
[thirdparty/qemu.git] / hw / arm / integratorcp.c
CommitLineData
5fafdf24 1/*
b5ff1b31
FB
2 * ARM Integrator CP System emulation.
3 *
a1bb27b1 4 * Copyright (c) 2005-2007 CodeSourcery.
b5ff1b31
FB
5 * Written by Paul Brook
6 *
8e31bf38 7 * This code is licensed under the GPL
b5ff1b31
FB
8 */
9
83c9f4ca 10#include "hw/sysbus.h"
bd2be150 11#include "hw/devices.h"
83c9f4ca 12#include "hw/boards.h"
bd2be150 13#include "hw/arm/arm.h"
b8616055 14#include "hw/misc/arm_integrator_debug.h"
1422e32d 15#include "net/net.h"
022c62cb 16#include "exec/address-spaces.h"
9c17d615 17#include "sysemu/sysemu.h"
223a72f1 18#include "qemu/error-report.h"
b5ff1b31 19
257ec289
AF
20#define TYPE_INTEGRATOR_CM "integrator_core"
21#define INTEGRATOR_CM(obj) \
22 OBJECT_CHECK(IntegratorCMState, (obj), TYPE_INTEGRATOR_CM)
23
24typedef struct IntegratorCMState {
25 /*< private >*/
26 SysBusDevice parent_obj;
27 /*< public >*/
28
71d9bc50 29 MemoryRegion iomem;
ee6847d1 30 uint32_t memsz;
211adf4d 31 MemoryRegion flash;
b5ff1b31
FB
32 uint32_t cm_osc;
33 uint32_t cm_ctrl;
34 uint32_t cm_lock;
35 uint32_t cm_auxosc;
36 uint32_t cm_sdram;
37 uint32_t cm_init;
38 uint32_t cm_flags;
39 uint32_t cm_nvflags;
f53977f7 40 uint32_t cm_refcnt_offset;
b5ff1b31
FB
41 uint32_t int_level;
42 uint32_t irq_enabled;
43 uint32_t fiq_enabled;
257ec289 44} IntegratorCMState;
b5ff1b31
FB
45
46static uint8_t integrator_spd[128] = {
47 128, 8, 4, 11, 9, 1, 64, 0, 2, 0xa0, 0xa0, 0, 0, 8, 0, 1,
48 0xe, 4, 0x1c, 1, 2, 0x20, 0xc0, 0, 0, 0, 0, 0x30, 0x28, 0x30, 0x28, 0x40
49};
50
a8170e5e 51static uint64_t integratorcm_read(void *opaque, hwaddr offset,
71d9bc50 52 unsigned size)
b5ff1b31 53{
257ec289 54 IntegratorCMState *s = opaque;
b5ff1b31
FB
55 if (offset >= 0x100 && offset < 0x200) {
56 /* CM_SPD */
57 if (offset >= 0x180)
58 return 0;
59 return integrator_spd[offset >> 2];
60 }
61 switch (offset >> 2) {
62 case 0: /* CM_ID */
63 return 0x411a3001;
64 case 1: /* CM_PROC */
65 return 0;
66 case 2: /* CM_OSC */
67 return s->cm_osc;
68 case 3: /* CM_CTRL */
69 return s->cm_ctrl;
70 case 4: /* CM_STAT */
71 return 0x00100000;
72 case 5: /* CM_LOCK */
73 if (s->cm_lock == 0xa05f) {
74 return 0x1a05f;
75 } else {
76 return s->cm_lock;
77 }
78 case 6: /* CM_LMBUSCNT */
79 /* ??? High frequency timer. */
2ac71179 80 hw_error("integratorcm_read: CM_LMBUSCNT");
b5ff1b31
FB
81 case 7: /* CM_AUXOSC */
82 return s->cm_auxosc;
83 case 8: /* CM_SDRAM */
84 return s->cm_sdram;
85 case 9: /* CM_INIT */
86 return s->cm_init;
f53977f7
JP
87 case 10: /* CM_REFCNT */
88 /* This register, CM_REFCNT, provides a 32-bit count value.
89 * The count increments at the fixed reference clock frequency of 24MHz
90 * and can be used as a real-time counter.
91 */
92 return (uint32_t)muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), 24,
93 1000) - s->cm_refcnt_offset;
b5ff1b31
FB
94 case 12: /* CM_FLAGS */
95 return s->cm_flags;
96 case 14: /* CM_NVFLAGS */
97 return s->cm_nvflags;
98 case 16: /* CM_IRQ_STAT */
99 return s->int_level & s->irq_enabled;
100 case 17: /* CM_IRQ_RSTAT */
101 return s->int_level;
102 case 18: /* CM_IRQ_ENSET */
103 return s->irq_enabled;
104 case 20: /* CM_SOFT_INTSET */
105 return s->int_level & 1;
106 case 24: /* CM_FIQ_STAT */
107 return s->int_level & s->fiq_enabled;
108 case 25: /* CM_FIQ_RSTAT */
109 return s->int_level;
110 case 26: /* CM_FIQ_ENSET */
111 return s->fiq_enabled;
112 case 32: /* CM_VOLTAGE_CTL0 */
113 case 33: /* CM_VOLTAGE_CTL1 */
114 case 34: /* CM_VOLTAGE_CTL2 */
115 case 35: /* CM_VOLTAGE_CTL3 */
116 /* ??? Voltage control unimplemented. */
117 return 0;
118 default:
2ac71179
PB
119 hw_error("integratorcm_read: Unimplemented offset 0x%x\n",
120 (int)offset);
b5ff1b31
FB
121 return 0;
122 }
123}
124
257ec289 125static void integratorcm_do_remap(IntegratorCMState *s)
b5ff1b31 126{
563c2bf3
PM
127 /* Sync memory region state with CM_CTRL REMAP bit:
128 * bit 0 => flash at address 0; bit 1 => RAM
129 */
130 memory_region_set_enabled(&s->flash, !(s->cm_ctrl & 4));
b5ff1b31
FB
131}
132
257ec289 133static void integratorcm_set_ctrl(IntegratorCMState *s, uint32_t value)
b5ff1b31
FB
134{
135 if (value & 8) {
df3f457b 136 qemu_system_reset_request();
b5ff1b31 137 }
df3f457b
PM
138 if ((s->cm_ctrl ^ value) & 1) {
139 /* (value & 1) != 0 means the green "MISC LED" is lit.
140 * We don't have any nice place to display LEDs. printf is a bad
141 * idea because Linux uses the LED as a heartbeat and the output
142 * will swamp anything else on the terminal.
143 */
b5ff1b31 144 }
df3f457b
PM
145 /* Note that the RESET bit [3] always reads as zero */
146 s->cm_ctrl = (s->cm_ctrl & ~5) | (value & 5);
563c2bf3 147 integratorcm_do_remap(s);
b5ff1b31
FB
148}
149
257ec289 150static void integratorcm_update(IntegratorCMState *s)
b5ff1b31
FB
151{
152 /* ??? The CPU irq/fiq is raised when either the core module or base PIC
153 are active. */
154 if (s->int_level & (s->irq_enabled | s->fiq_enabled))
2ac71179 155 hw_error("Core module interrupt\n");
b5ff1b31
FB
156}
157
a8170e5e 158static void integratorcm_write(void *opaque, hwaddr offset,
71d9bc50 159 uint64_t value, unsigned size)
b5ff1b31 160{
257ec289 161 IntegratorCMState *s = opaque;
b5ff1b31
FB
162 switch (offset >> 2) {
163 case 2: /* CM_OSC */
164 if (s->cm_lock == 0xa05f)
165 s->cm_osc = value;
166 break;
167 case 3: /* CM_CTRL */
168 integratorcm_set_ctrl(s, value);
169 break;
170 case 5: /* CM_LOCK */
171 s->cm_lock = value & 0xffff;
172 break;
173 case 7: /* CM_AUXOSC */
174 if (s->cm_lock == 0xa05f)
175 s->cm_auxosc = value;
176 break;
177 case 8: /* CM_SDRAM */
178 s->cm_sdram = value;
179 break;
180 case 9: /* CM_INIT */
181 /* ??? This can change the memory bus frequency. */
182 s->cm_init = value;
183 break;
184 case 12: /* CM_FLAGSS */
185 s->cm_flags |= value;
186 break;
187 case 13: /* CM_FLAGSC */
188 s->cm_flags &= ~value;
189 break;
190 case 14: /* CM_NVFLAGSS */
191 s->cm_nvflags |= value;
192 break;
193 case 15: /* CM_NVFLAGSS */
194 s->cm_nvflags &= ~value;
195 break;
196 case 18: /* CM_IRQ_ENSET */
197 s->irq_enabled |= value;
198 integratorcm_update(s);
199 break;
200 case 19: /* CM_IRQ_ENCLR */
201 s->irq_enabled &= ~value;
202 integratorcm_update(s);
203 break;
204 case 20: /* CM_SOFT_INTSET */
205 s->int_level |= (value & 1);
206 integratorcm_update(s);
207 break;
208 case 21: /* CM_SOFT_INTCLR */
209 s->int_level &= ~(value & 1);
210 integratorcm_update(s);
211 break;
212 case 26: /* CM_FIQ_ENSET */
213 s->fiq_enabled |= value;
214 integratorcm_update(s);
215 break;
216 case 27: /* CM_FIQ_ENCLR */
217 s->fiq_enabled &= ~value;
218 integratorcm_update(s);
219 break;
220 case 32: /* CM_VOLTAGE_CTL0 */
221 case 33: /* CM_VOLTAGE_CTL1 */
222 case 34: /* CM_VOLTAGE_CTL2 */
223 case 35: /* CM_VOLTAGE_CTL3 */
224 /* ??? Voltage control unimplemented. */
225 break;
226 default:
2ac71179
PB
227 hw_error("integratorcm_write: Unimplemented offset 0x%x\n",
228 (int)offset);
b5ff1b31
FB
229 break;
230 }
231}
232
233/* Integrator/CM control registers. */
234
71d9bc50
BC
235static const MemoryRegionOps integratorcm_ops = {
236 .read = integratorcm_read,
237 .write = integratorcm_write,
238 .endianness = DEVICE_NATIVE_ENDIAN,
b5ff1b31
FB
239};
240
81a322d4 241static int integratorcm_init(SysBusDevice *dev)
b5ff1b31 242{
257ec289 243 IntegratorCMState *s = INTEGRATOR_CM(dev);
b5ff1b31 244
b5ff1b31
FB
245 s->cm_osc = 0x01000048;
246 /* ??? What should the high bits of this value be? */
247 s->cm_auxosc = 0x0007feff;
248 s->cm_sdram = 0x00011122;
ee6847d1 249 if (s->memsz >= 256) {
b5ff1b31
FB
250 integrator_spd[31] = 64;
251 s->cm_sdram |= 0x10;
ee6847d1 252 } else if (s->memsz >= 128) {
b5ff1b31
FB
253 integrator_spd[31] = 32;
254 s->cm_sdram |= 0x0c;
ee6847d1 255 } else if (s->memsz >= 64) {
b5ff1b31
FB
256 integrator_spd[31] = 16;
257 s->cm_sdram |= 0x08;
ee6847d1 258 } else if (s->memsz >= 32) {
b5ff1b31
FB
259 integrator_spd[31] = 4;
260 s->cm_sdram |= 0x04;
261 } else {
262 integrator_spd[31] = 2;
263 }
264 memcpy(integrator_spd + 73, "QEMU-MEMORY", 11);
265 s->cm_init = 0x00000112;
f53977f7
JP
266 s->cm_refcnt_offset = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), 24,
267 1000);
49946538
HT
268 memory_region_init_ram(&s->flash, OBJECT(s), "integrator.flash", 0x100000,
269 &error_abort);
c5705a77 270 vmstate_register_ram_global(&s->flash);
b5ff1b31 271
64bde0f3 272 memory_region_init_io(&s->iomem, OBJECT(s), &integratorcm_ops, s,
71d9bc50 273 "integratorcm", 0x00800000);
750ecd44 274 sysbus_init_mmio(dev, &s->iomem);
71d9bc50 275
563c2bf3 276 integratorcm_do_remap(s);
b5ff1b31 277 /* ??? Save/restore. */
81a322d4 278 return 0;
b5ff1b31
FB
279}
280
281/* Integrator/CP hardware emulation. */
282/* Primary interrupt controller. */
283
91b64626
AF
284#define TYPE_INTEGRATOR_PIC "integrator_pic"
285#define INTEGRATOR_PIC(obj) \
286 OBJECT_CHECK(icp_pic_state, (obj), TYPE_INTEGRATOR_PIC)
287
288typedef struct icp_pic_state {
289 /*< private >*/
290 SysBusDevice parent_obj;
291 /*< public >*/
292
293 MemoryRegion iomem;
294 uint32_t level;
295 uint32_t irq_enabled;
296 uint32_t fiq_enabled;
297 qemu_irq parent_irq;
298 qemu_irq parent_fiq;
b5ff1b31
FB
299} icp_pic_state;
300
b5ff1b31
FB
301static void icp_pic_update(icp_pic_state *s)
302{
cdbdb648 303 uint32_t flags;
b5ff1b31 304
d537cf6c
PB
305 flags = (s->level & s->irq_enabled);
306 qemu_set_irq(s->parent_irq, flags != 0);
307 flags = (s->level & s->fiq_enabled);
308 qemu_set_irq(s->parent_fiq, flags != 0);
b5ff1b31
FB
309}
310
cdbdb648 311static void icp_pic_set_irq(void *opaque, int irq, int level)
b5ff1b31 312{
80337b66 313 icp_pic_state *s = (icp_pic_state *)opaque;
b5ff1b31 314 if (level)
80337b66 315 s->level |= 1 << irq;
b5ff1b31 316 else
80337b66 317 s->level &= ~(1 << irq);
b5ff1b31
FB
318 icp_pic_update(s);
319}
320
a8170e5e 321static uint64_t icp_pic_read(void *opaque, hwaddr offset,
61074e46 322 unsigned size)
b5ff1b31
FB
323{
324 icp_pic_state *s = (icp_pic_state *)opaque;
325
b5ff1b31
FB
326 switch (offset >> 2) {
327 case 0: /* IRQ_STATUS */
328 return s->level & s->irq_enabled;
329 case 1: /* IRQ_RAWSTAT */
330 return s->level;
331 case 2: /* IRQ_ENABLESET */
332 return s->irq_enabled;
333 case 4: /* INT_SOFTSET */
334 return s->level & 1;
335 case 8: /* FRQ_STATUS */
336 return s->level & s->fiq_enabled;
337 case 9: /* FRQ_RAWSTAT */
338 return s->level;
339 case 10: /* FRQ_ENABLESET */
340 return s->fiq_enabled;
341 case 3: /* IRQ_ENABLECLR */
342 case 5: /* INT_SOFTCLR */
343 case 11: /* FRQ_ENABLECLR */
344 default:
29bfb117 345 printf ("icp_pic_read: Bad register offset 0x%x\n", (int)offset);
b5ff1b31
FB
346 return 0;
347 }
348}
349
a8170e5e 350static void icp_pic_write(void *opaque, hwaddr offset,
61074e46 351 uint64_t value, unsigned size)
b5ff1b31
FB
352{
353 icp_pic_state *s = (icp_pic_state *)opaque;
b5ff1b31
FB
354
355 switch (offset >> 2) {
356 case 2: /* IRQ_ENABLESET */
357 s->irq_enabled |= value;
358 break;
359 case 3: /* IRQ_ENABLECLR */
360 s->irq_enabled &= ~value;
361 break;
362 case 4: /* INT_SOFTSET */
363 if (value & 1)
d537cf6c 364 icp_pic_set_irq(s, 0, 1);
b5ff1b31
FB
365 break;
366 case 5: /* INT_SOFTCLR */
367 if (value & 1)
d537cf6c 368 icp_pic_set_irq(s, 0, 0);
b5ff1b31
FB
369 break;
370 case 10: /* FRQ_ENABLESET */
371 s->fiq_enabled |= value;
372 break;
373 case 11: /* FRQ_ENABLECLR */
374 s->fiq_enabled &= ~value;
375 break;
376 case 0: /* IRQ_STATUS */
377 case 1: /* IRQ_RAWSTAT */
378 case 8: /* FRQ_STATUS */
379 case 9: /* FRQ_RAWSTAT */
380 default:
29bfb117 381 printf ("icp_pic_write: Bad register offset 0x%x\n", (int)offset);
b5ff1b31
FB
382 return;
383 }
384 icp_pic_update(s);
385}
386
61074e46
BC
387static const MemoryRegionOps icp_pic_ops = {
388 .read = icp_pic_read,
389 .write = icp_pic_write,
390 .endianness = DEVICE_NATIVE_ENDIAN,
b5ff1b31
FB
391};
392
91b64626 393static int icp_pic_init(SysBusDevice *sbd)
b5ff1b31 394{
91b64626
AF
395 DeviceState *dev = DEVICE(sbd);
396 icp_pic_state *s = INTEGRATOR_PIC(dev);
b5ff1b31 397
91b64626
AF
398 qdev_init_gpio_in(dev, icp_pic_set_irq, 32);
399 sysbus_init_irq(sbd, &s->parent_irq);
400 sysbus_init_irq(sbd, &s->parent_fiq);
64bde0f3
PB
401 memory_region_init_io(&s->iomem, OBJECT(s), &icp_pic_ops, s,
402 "icp-pic", 0x00800000);
91b64626 403 sysbus_init_mmio(sbd, &s->iomem);
81a322d4 404 return 0;
b5ff1b31
FB
405}
406
b5ff1b31 407/* CP control registers. */
0c36493e 408
a8170e5e 409static uint64_t icp_control_read(void *opaque, hwaddr offset,
0c36493e 410 unsigned size)
b5ff1b31 411{
b5ff1b31
FB
412 switch (offset >> 2) {
413 case 0: /* CP_IDFIELD */
414 return 0x41034003;
415 case 1: /* CP_FLASHPROG */
416 return 0;
417 case 2: /* CP_INTREG */
418 return 0;
419 case 3: /* CP_DECODE */
420 return 0x11;
421 default:
2ac71179 422 hw_error("icp_control_read: Bad offset %x\n", (int)offset);
b5ff1b31
FB
423 return 0;
424 }
425}
426
a8170e5e 427static void icp_control_write(void *opaque, hwaddr offset,
0c36493e 428 uint64_t value, unsigned size)
b5ff1b31 429{
b5ff1b31
FB
430 switch (offset >> 2) {
431 case 1: /* CP_FLASHPROG */
432 case 2: /* CP_INTREG */
433 case 3: /* CP_DECODE */
434 /* Nothing interesting implemented yet. */
435 break;
436 default:
2ac71179 437 hw_error("icp_control_write: Bad offset %x\n", (int)offset);
b5ff1b31
FB
438 }
439}
b5ff1b31 440
0c36493e
BC
441static const MemoryRegionOps icp_control_ops = {
442 .read = icp_control_read,
443 .write = icp_control_write,
444 .endianness = DEVICE_NATIVE_ENDIAN,
b5ff1b31
FB
445};
446
a8170e5e 447static void icp_control_init(hwaddr base)
b5ff1b31 448{
0c36493e 449 MemoryRegion *io;
b5ff1b31 450
0c36493e 451 io = (MemoryRegion *)g_malloc0(sizeof(MemoryRegion));
2c9b15ca 452 memory_region_init_io(io, NULL, &icp_control_ops, NULL,
0c36493e
BC
453 "control", 0x00800000);
454 memory_region_add_subregion(get_system_memory(), base, io);
b5ff1b31
FB
455 /* ??? Save/restore. */
456}
457
458
b5ff1b31
FB
459/* Board init. */
460
f93eb9ff
AZ
461static struct arm_boot_info integrator_binfo = {
462 .loader_start = 0x0,
463 .board_id = 0x113,
464};
465
3ef96221 466static void integratorcp_init(MachineState *machine)
b5ff1b31 467{
3ef96221
MA
468 ram_addr_t ram_size = machine->ram_size;
469 const char *cpu_model = machine->cpu_model;
470 const char *kernel_filename = machine->kernel_filename;
471 const char *kernel_cmdline = machine->kernel_cmdline;
472 const char *initrd_filename = machine->initrd_filename;
223a72f1
GB
473 ObjectClass *cpu_oc;
474 Object *cpuobj;
393a9eab 475 ARMCPU *cpu;
211adf4d
AK
476 MemoryRegion *address_space_mem = get_system_memory();
477 MemoryRegion *ram = g_new(MemoryRegion, 1);
478 MemoryRegion *ram_alias = g_new(MemoryRegion, 1);
a7086888 479 qemu_irq pic[32];
a7086888
PB
480 DeviceState *dev;
481 int i;
223a72f1 482 Error *err = NULL;
b5ff1b31 483
393a9eab 484 if (!cpu_model) {
3371d272 485 cpu_model = "arm926";
393a9eab 486 }
223a72f1
GB
487
488 cpu_oc = cpu_class_by_name(TYPE_ARM_CPU, cpu_model);
489 if (!cpu_oc) {
aaed909a
FB
490 fprintf(stderr, "Unable to find CPU definition\n");
491 exit(1);
492 }
393a9eab 493
223a72f1
GB
494 cpuobj = object_new(object_class_get_name(cpu_oc));
495
61e2f352
GB
496 /* By default ARM1176 CPUs have EL3 enabled. This board does not
497 * currently support EL3 so the CPU EL3 property is disabled before
498 * realization.
499 */
500 if (object_property_find(cpuobj, "has_el3", NULL)) {
501 object_property_set_bool(cpuobj, false, "has_el3", &err);
502 if (err) {
565f65d2 503 error_report_err(err);
61e2f352
GB
504 exit(1);
505 }
506 }
507
223a72f1
GB
508 object_property_set_bool(cpuobj, true, "realized", &err);
509 if (err) {
565f65d2 510 error_report_err(err);
223a72f1
GB
511 exit(1);
512 }
513
514 cpu = ARM_CPU(cpuobj);
515
49946538 516 memory_region_init_ram(ram, NULL, "integrator.ram", ram_size, &error_abort);
c5705a77 517 vmstate_register_ram_global(ram);
b5ff1b31 518 /* ??? On a real system the first 1Mb is mapped as SSRAM or boot flash. */
1235fc06 519 /* ??? RAM should repeat to fill physical memory space. */
b5ff1b31 520 /* SDRAM at address zero*/
211adf4d 521 memory_region_add_subregion(address_space_mem, 0, ram);
b5ff1b31 522 /* And again at address 0x80000000 */
2c9b15ca 523 memory_region_init_alias(ram_alias, NULL, "ram.alias", ram, 0, ram_size);
211adf4d 524 memory_region_add_subregion(address_space_mem, 0x80000000, ram_alias);
b5ff1b31 525
257ec289 526 dev = qdev_create(NULL, TYPE_INTEGRATOR_CM);
ee6847d1 527 qdev_prop_set_uint32(dev, "memsz", ram_size >> 20);
e23a1b33 528 qdev_init_nofail(dev);
a7086888
PB
529 sysbus_mmio_map((SysBusDevice *)dev, 0, 0x10000000);
530
91b64626 531 dev = sysbus_create_varargs(TYPE_INTEGRATOR_PIC, 0x14000000,
99d228d6
PM
532 qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ),
533 qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_FIQ),
534 NULL);
a7086888 535 for (i = 0; i < 32; i++) {
067a3ddc 536 pic[i] = qdev_get_gpio_in(dev, i);
a7086888 537 }
91b64626 538 sysbus_create_simple(TYPE_INTEGRATOR_PIC, 0xca000000, pic[26]);
6a824ec3
PB
539 sysbus_create_varargs("integrator_pit", 0x13000000,
540 pic[5], pic[6], pic[7], NULL);
a63bdb31 541 sysbus_create_simple("pl031", 0x15000000, pic[8]);
a7d518a6
PB
542 sysbus_create_simple("pl011", 0x16000000, pic[1]);
543 sysbus_create_simple("pl011", 0x17000000, pic[2]);
b5ff1b31 544 icp_control_init(0xcb000000);
86394e96
PB
545 sysbus_create_simple("pl050_keyboard", 0x18000000, pic[3]);
546 sysbus_create_simple("pl050_mouse", 0x19000000, pic[4]);
b8616055 547 sysbus_create_simple(TYPE_INTEGRATOR_DEBUG, 0x1a000000, 0);
aa9311d8 548 sysbus_create_varargs("pl181", 0x1c000000, pic[23], pic[24], NULL);
a005d073 549 if (nd_table[0].used)
0ae18cee 550 smc91c111_init(&nd_table[0], 0xc8000000, pic[27]);
2e9bdce5
PB
551
552 sysbus_create_simple("pl110", 0xc0000000, pic[22]);
b5ff1b31 553
f93eb9ff
AZ
554 integrator_binfo.ram_size = ram_size;
555 integrator_binfo.kernel_filename = kernel_filename;
556 integrator_binfo.kernel_cmdline = kernel_cmdline;
557 integrator_binfo.initrd_filename = initrd_filename;
3aaa8dfa 558 arm_load_kernel(cpu, &integrator_binfo);
b5ff1b31
FB
559}
560
f80f9ec9 561static QEMUMachine integratorcp_machine = {
4b32e168
AL
562 .name = "integratorcp",
563 .desc = "ARM Integrator/CP (ARM926EJ-S)",
564 .init = integratorcp_init,
b5ff1b31 565};
a7086888 566
f80f9ec9
AL
567static void integratorcp_machine_init(void)
568{
569 qemu_register_machine(&integratorcp_machine);
570}
571
572machine_init(integratorcp_machine_init);
573
999e12bb 574static Property core_properties[] = {
257ec289 575 DEFINE_PROP_UINT32("memsz", IntegratorCMState, memsz, 0),
999e12bb
AL
576 DEFINE_PROP_END_OF_LIST(),
577};
578
579static void core_class_init(ObjectClass *klass, void *data)
580{
39bffca2 581 DeviceClass *dc = DEVICE_CLASS(klass);
999e12bb
AL
582 SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
583
584 k->init = integratorcm_init;
39bffca2 585 dc->props = core_properties;
999e12bb
AL
586}
587
8c43a6f0 588static const TypeInfo core_info = {
257ec289 589 .name = TYPE_INTEGRATOR_CM,
39bffca2 590 .parent = TYPE_SYS_BUS_DEVICE,
257ec289 591 .instance_size = sizeof(IntegratorCMState),
39bffca2 592 .class_init = core_class_init,
999e12bb
AL
593};
594
595static void icp_pic_class_init(ObjectClass *klass, void *data)
596{
597 SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
598
599 sdc->init = icp_pic_init;
600}
601
8c43a6f0 602static const TypeInfo icp_pic_info = {
91b64626 603 .name = TYPE_INTEGRATOR_PIC,
39bffca2
AL
604 .parent = TYPE_SYS_BUS_DEVICE,
605 .instance_size = sizeof(icp_pic_state),
606 .class_init = icp_pic_class_init,
ee6847d1
GH
607};
608
83f7d43a 609static void integratorcp_register_types(void)
a7086888 610{
39bffca2
AL
611 type_register_static(&icp_pic_info);
612 type_register_static(&core_info);
a7086888
PB
613}
614
83f7d43a 615type_init(integratorcp_register_types)