2 * ARM Integrator CP System emulation.
4 * Copyright (c) 2005 CodeSourcery, LLC.
5 * Written by Paul Brook
7 * This code is licenced under the GPL
12 #define KERNEL_ARGS_ADDR 0x100
13 #define KERNEL_LOAD_ADDR 0x00010000
14 #define INITRD_LOAD_ADDR 0x00800000
16 /* Stub functions for hardware that doesn't exist. */
17 void pic_set_irq(int irq
, int level
)
19 cpu_abort (cpu_single_env
, "pic_set_irq");
32 void vga_update_display(void)
34 pl110_update_display(lcd
);
37 void vga_screen_dump(const char *filename
)
41 void vga_invalidate_display(void)
43 pl110_invalidate_display(lcd
);
51 uint32_t flash_offset
;
65 static uint8_t integrator_spd
[128] = {
66 128, 8, 4, 11, 9, 1, 64, 0, 2, 0xa0, 0xa0, 0, 0, 8, 0, 1,
67 0xe, 4, 0x1c, 1, 2, 0x20, 0xc0, 0, 0, 0, 0, 0x30, 0x28, 0x30, 0x28, 0x40
70 static uint32_t integratorcm_read(void *opaque
, target_phys_addr_t offset
)
72 integratorcm_state
*s
= (integratorcm_state
*)opaque
;
74 if (offset
>= 0x100 && offset
< 0x200) {
78 return integrator_spd
[offset
>> 2];
80 switch (offset
>> 2) {
92 if (s
->cm_lock
== 0xa05f) {
97 case 6: /* CM_LMBUSCNT */
98 /* ??? High frequency timer. */
99 cpu_abort(cpu_single_env
, "integratorcm_read: CM_LMBUSCNT");
100 case 7: /* CM_AUXOSC */
102 case 8: /* CM_SDRAM */
104 case 9: /* CM_INIT */
106 case 10: /* CM_REFCT */
107 /* ??? High frequency timer. */
108 cpu_abort(cpu_single_env
, "integratorcm_read: CM_REFCT");
109 case 12: /* CM_FLAGS */
111 case 14: /* CM_NVFLAGS */
112 return s
->cm_nvflags
;
113 case 16: /* CM_IRQ_STAT */
114 return s
->int_level
& s
->irq_enabled
;
115 case 17: /* CM_IRQ_RSTAT */
117 case 18: /* CM_IRQ_ENSET */
118 return s
->irq_enabled
;
119 case 20: /* CM_SOFT_INTSET */
120 return s
->int_level
& 1;
121 case 24: /* CM_FIQ_STAT */
122 return s
->int_level
& s
->fiq_enabled
;
123 case 25: /* CM_FIQ_RSTAT */
125 case 26: /* CM_FIQ_ENSET */
126 return s
->fiq_enabled
;
127 case 32: /* CM_VOLTAGE_CTL0 */
128 case 33: /* CM_VOLTAGE_CTL1 */
129 case 34: /* CM_VOLTAGE_CTL2 */
130 case 35: /* CM_VOLTAGE_CTL3 */
131 /* ??? Voltage control unimplemented. */
134 cpu_abort (cpu_single_env
,
135 "integratorcm_read: Unimplemented offset 0x%x\n", offset
);
140 static void integratorcm_do_remap(integratorcm_state
*s
, int flash
)
143 cpu_register_physical_memory(0, 0x100000, IO_MEM_RAM
);
145 cpu_register_physical_memory(0, 0x100000, s
->flash_offset
| IO_MEM_RAM
);
147 //??? tlb_flush (cpu_single_env, 1);
150 static void integratorcm_set_ctrl(integratorcm_state
*s
, uint32_t value
)
153 cpu_abort(cpu_single_env
, "Board reset\n");
155 if ((s
->cm_init
^ value
) & 4) {
156 integratorcm_do_remap(s
, (value
& 4) == 0);
158 if ((s
->cm_init
^ value
) & 1) {
159 printf("Green LED %s\n", (value
& 1) ? "on" : "off");
161 s
->cm_init
= (s
->cm_init
& ~ 5) | (value
^ 5);
164 static void integratorcm_update(integratorcm_state
*s
)
166 /* ??? The CPU irq/fiq is raised when either the core module or base PIC
168 if (s
->int_level
& (s
->irq_enabled
| s
->fiq_enabled
))
169 cpu_abort(cpu_single_env
, "Core module interrupt\n");
172 static void integratorcm_write(void *opaque
, target_phys_addr_t offset
,
175 integratorcm_state
*s
= (integratorcm_state
*)opaque
;
176 offset
-= 0x10000000;
177 switch (offset
>> 2) {
179 if (s
->cm_lock
== 0xa05f)
182 case 3: /* CM_CTRL */
183 integratorcm_set_ctrl(s
, value
);
185 case 5: /* CM_LOCK */
186 s
->cm_lock
= value
& 0xffff;
188 case 7: /* CM_AUXOSC */
189 if (s
->cm_lock
== 0xa05f)
190 s
->cm_auxosc
= value
;
192 case 8: /* CM_SDRAM */
195 case 9: /* CM_INIT */
196 /* ??? This can change the memory bus frequency. */
199 case 12: /* CM_FLAGSS */
200 s
->cm_flags
|= value
;
202 case 13: /* CM_FLAGSC */
203 s
->cm_flags
&= ~value
;
205 case 14: /* CM_NVFLAGSS */
206 s
->cm_nvflags
|= value
;
208 case 15: /* CM_NVFLAGSS */
209 s
->cm_nvflags
&= ~value
;
211 case 18: /* CM_IRQ_ENSET */
212 s
->irq_enabled
|= value
;
213 integratorcm_update(s
);
215 case 19: /* CM_IRQ_ENCLR */
216 s
->irq_enabled
&= ~value
;
217 integratorcm_update(s
);
219 case 20: /* CM_SOFT_INTSET */
220 s
->int_level
|= (value
& 1);
221 integratorcm_update(s
);
223 case 21: /* CM_SOFT_INTCLR */
224 s
->int_level
&= ~(value
& 1);
225 integratorcm_update(s
);
227 case 26: /* CM_FIQ_ENSET */
228 s
->fiq_enabled
|= value
;
229 integratorcm_update(s
);
231 case 27: /* CM_FIQ_ENCLR */
232 s
->fiq_enabled
&= ~value
;
233 integratorcm_update(s
);
235 case 32: /* CM_VOLTAGE_CTL0 */
236 case 33: /* CM_VOLTAGE_CTL1 */
237 case 34: /* CM_VOLTAGE_CTL2 */
238 case 35: /* CM_VOLTAGE_CTL3 */
239 /* ??? Voltage control unimplemented. */
242 cpu_abort (cpu_single_env
,
243 "integratorcm_write: Unimplemented offset 0x%x\n", offset
);
248 /* Integrator/CM control registers. */
250 static CPUReadMemoryFunc
*integratorcm_readfn
[] = {
256 static CPUWriteMemoryFunc
*integratorcm_writefn
[] = {
262 static void integratorcm_init(int memsz
, uint32_t flash_offset
)
265 integratorcm_state
*s
;
267 s
= (integratorcm_state
*)qemu_mallocz(sizeof(integratorcm_state
));
268 s
->cm_osc
= 0x01000048;
269 /* ??? What should the high bits of this value be? */
270 s
->cm_auxosc
= 0x0007feff;
271 s
->cm_sdram
= 0x00011122;
273 integrator_spd
[31] = 64;
275 } else if (memsz
>= 128) {
276 integrator_spd
[31] = 32;
278 } else if (memsz
>= 64) {
279 integrator_spd
[31] = 16;
281 } else if (memsz
>= 32) {
282 integrator_spd
[31] = 4;
285 integrator_spd
[31] = 2;
287 memcpy(integrator_spd
+ 73, "QEMU-MEMORY", 11);
288 s
->cm_init
= 0x00000112;
289 s
->flash_offset
= flash_offset
;
291 iomemtype
= cpu_register_io_memory(0, integratorcm_readfn
,
292 integratorcm_writefn
, s
);
293 cpu_register_physical_memory(0x10000000, 0x007fffff, iomemtype
);
294 integratorcm_do_remap(s
, 1);
295 /* ??? Save/restore. */
298 /* Integrator/CP hardware emulation. */
299 /* Primary interrupt controller. */
301 typedef struct icp_pic_state
305 uint32_t irq_enabled
;
306 uint32_t fiq_enabled
;
308 /* -1 if parent is a cpu, otherwise IRQ number on parent PIC. */
312 static void icp_pic_update(icp_pic_state
*s
)
315 if (s
->parent_irq
!= -1) {
318 flags
= (s
->level
& s
->irq_enabled
);
319 pic_set_irq_new(s
->parent
, s
->parent_irq
,
323 /* Raise CPU interrupt. */
324 env
= (CPUState
*)s
->parent
;
325 if (s
->level
& s
->fiq_enabled
) {
326 cpu_interrupt (env
, CPU_INTERRUPT_FIQ
);
328 cpu_reset_interrupt (env
, CPU_INTERRUPT_FIQ
);
330 if (s
->level
& s
->irq_enabled
) {
331 cpu_interrupt (env
, CPU_INTERRUPT_HARD
);
333 cpu_reset_interrupt (env
, CPU_INTERRUPT_HARD
);
337 void pic_set_irq_new(void *opaque
, int irq
, int level
)
339 icp_pic_state
*s
= (icp_pic_state
*)opaque
;
341 s
->level
|= 1 << irq
;
343 s
->level
&= ~(1 << irq
);
347 static uint32_t icp_pic_read(void *opaque
, target_phys_addr_t offset
)
349 icp_pic_state
*s
= (icp_pic_state
*)opaque
;
352 switch (offset
>> 2) {
353 case 0: /* IRQ_STATUS */
354 return s
->level
& s
->irq_enabled
;
355 case 1: /* IRQ_RAWSTAT */
357 case 2: /* IRQ_ENABLESET */
358 return s
->irq_enabled
;
359 case 4: /* INT_SOFTSET */
361 case 8: /* FRQ_STATUS */
362 return s
->level
& s
->fiq_enabled
;
363 case 9: /* FRQ_RAWSTAT */
365 case 10: /* FRQ_ENABLESET */
366 return s
->fiq_enabled
;
367 case 3: /* IRQ_ENABLECLR */
368 case 5: /* INT_SOFTCLR */
369 case 11: /* FRQ_ENABLECLR */
371 printf ("icp_pic_read: Bad register offset 0x%x\n", offset
);
376 static void icp_pic_write(void *opaque
, target_phys_addr_t offset
,
379 icp_pic_state
*s
= (icp_pic_state
*)opaque
;
382 switch (offset
>> 2) {
383 case 2: /* IRQ_ENABLESET */
384 s
->irq_enabled
|= value
;
386 case 3: /* IRQ_ENABLECLR */
387 s
->irq_enabled
&= ~value
;
389 case 4: /* INT_SOFTSET */
391 pic_set_irq_new(s
, 0, 1);
393 case 5: /* INT_SOFTCLR */
395 pic_set_irq_new(s
, 0, 0);
397 case 10: /* FRQ_ENABLESET */
398 s
->fiq_enabled
|= value
;
400 case 11: /* FRQ_ENABLECLR */
401 s
->fiq_enabled
&= ~value
;
403 case 0: /* IRQ_STATUS */
404 case 1: /* IRQ_RAWSTAT */
405 case 8: /* FRQ_STATUS */
406 case 9: /* FRQ_RAWSTAT */
408 printf ("icp_pic_write: Bad register offset 0x%x\n", offset
);
414 static CPUReadMemoryFunc
*icp_pic_readfn
[] = {
420 static CPUWriteMemoryFunc
*icp_pic_writefn
[] = {
426 static icp_pic_state
*icp_pic_init(uint32_t base
, void *parent
,
432 s
= (icp_pic_state
*)qemu_mallocz(sizeof(icp_pic_state
));
438 s
->parent_irq
= parent_irq
;
439 iomemtype
= cpu_register_io_memory(0, icp_pic_readfn
,
441 cpu_register_physical_memory(base
, 0x007fffff, iomemtype
);
442 /* ??? Save/restore. */
448 /* System bus clock speed (40MHz) for timer 0. Not sure about this value. */
449 #define ICP_BUS_FREQ 40000000
465 /* Calculate the new expiry time of the given timer. */
467 static void icp_pit_reload(icp_pit_state
*s
, int n
)
471 s
->loaded
[n
] = s
->expires
[n
];
472 delay
= muldiv64(s
->count
[n
], ticks_per_sec
, s
->freq
[n
]);
475 s
->expires
[n
] += delay
;
478 /* Check all active timers, and schedule the next timer interrupt. */
480 static void icp_pit_update(icp_pit_state
*s
, int64_t now
)
486 for (n
= 0; n
< 3; n
++) {
487 /* Ignore disabled timers. */
488 if ((s
->control
[n
] & 0x80) == 0)
490 /* Ignore expired one-shot timers. */
491 if (s
->count
[n
] == 0 && s
->control
[n
] & 1)
493 if (s
->expires
[n
] - now
<= 0) {
494 /* Timer has expired. */
496 if (s
->control
[n
] & 1) {
500 if ((s
->control
[n
] & 0x40) == 0) {
502 if (s
->control
[n
] & 2)
503 s
->count
[n
] = 0xffffffff;
505 s
->count
[n
] = 0xffff;
508 s
->count
[n
] = s
->limit
[n
];
512 while (s
->expires
[n
] - now
<= 0) {
513 icp_pit_reload(s
, n
);
516 /* Update interrupts. */
517 for (n
= 0; n
< 3; n
++) {
518 if (s
->int_level
[n
] && (s
->control
[n
] & 0x20)) {
519 pic_set_irq_new(s
->pic
, 5 + n
, 1);
521 pic_set_irq_new(s
->pic
, 5 + n
, 0);
523 if (next
- s
->expires
[n
] < 0)
524 next
= s
->expires
[n
];
526 /* Schedule the next timer interrupt. */
528 qemu_del_timer(s
->timer
);
530 } else if (next
!= s
->next_time
) {
531 qemu_mod_timer(s
->timer
, next
);
536 /* Return the current value of the timer. */
537 static uint32_t icp_pit_getcount(icp_pit_state
*s
, int n
, int64_t now
)
542 if (s
->count
[n
] == 0)
544 if ((s
->control
[n
] & 0x80) == 0)
546 elapsed
= now
- s
->loaded
[n
];
547 period
= s
->expires
[n
] - s
->loaded
[n
];
548 /* If the timer should have expired then return 0. This can happen
549 when the host timer signal doesnt occur immediately. It's better to
550 have a timer appear to sit at zero for a while than have it wrap
551 around before the guest interrupt is raised. */
552 /* ??? Could we trigger the interrupt here? */
553 if (elapsed
> period
)
555 /* We need to calculate count * elapsed / period without overfowing.
556 Scale both elapsed and period so they fit in a 32-bit int. */
557 while (period
!= (int32_t)period
) {
561 return ((uint64_t)s
->count
[n
] * (uint64_t)(int32_t)elapsed
)
565 static uint32_t icp_pit_read(void *opaque
, target_phys_addr_t offset
)
568 icp_pit_state
*s
= (icp_pit_state
*)opaque
;
573 cpu_abort (cpu_single_env
, "icp_pit_read: Bad timer %x\n", offset
);
574 switch ((offset
& 0xff) >> 2) {
575 case 0: /* TimerLoad */
576 case 6: /* TimerBGLoad */
578 case 1: /* TimerValue */
579 return icp_pit_getcount(s
, n
, qemu_get_clock(vm_clock
));
580 case 2: /* TimerControl */
581 return s
->control
[n
];
582 case 4: /* TimerRIS */
583 return s
->int_level
[n
];
584 case 5: /* TimerMIS */
585 if ((s
->control
[n
] & 0x20) == 0)
587 return s
->int_level
[n
];
589 cpu_abort (cpu_single_env
, "icp_pit_read: Bad offset %x\n", offset
);
594 static void icp_pit_write(void *opaque
, target_phys_addr_t offset
,
597 icp_pit_state
*s
= (icp_pit_state
*)opaque
;
601 now
= qemu_get_clock(vm_clock
);
605 cpu_abort (cpu_single_env
, "icp_pit_write: Bad offset %x\n", offset
);
607 switch ((offset
& 0xff) >> 2) {
608 case 0: /* TimerLoad */
612 icp_pit_reload(s
, n
);
614 case 1: /* TimerValue */
615 /* ??? Linux seems to want to write to this readonly register.
618 case 2: /* TimerControl */
619 if (s
->control
[n
] & 0x80) {
620 /* Pause the timer if it is running. This may cause some
621 inaccuracy dure to rounding, but avoids a whole lot of other
623 s
->count
[n
] = icp_pit_getcount(s
, n
, now
);
625 s
->control
[n
] = value
;
627 s
->freq
[n
] = ICP_BUS_FREQ
;
629 s
->freq
[n
] = 1000000;
630 /* ??? Need to recalculate expiry time after changing divisor. */
631 switch ((value
>> 2) & 3) {
632 case 1: s
->freq
[n
] >>= 4; break;
633 case 2: s
->freq
[n
] >>= 8; break;
635 if (s
->control
[n
] & 0x80) {
636 /* Restart the timer if still enabled. */
638 icp_pit_reload(s
, n
);
641 case 3: /* TimerIntClr */
644 case 6: /* TimerBGLoad */
648 cpu_abort (cpu_single_env
, "icp_pit_write: Bad offset %x\n", offset
);
650 icp_pit_update(s
, now
);
653 static void icp_pit_tick(void *opaque
)
657 now
= qemu_get_clock(vm_clock
);
658 icp_pit_update((icp_pit_state
*)opaque
, now
);
661 static CPUReadMemoryFunc
*icp_pit_readfn
[] = {
667 static CPUWriteMemoryFunc
*icp_pit_writefn
[] = {
673 static void icp_pit_init(uint32_t base
, icp_pic_state
*pic
)
679 s
= (icp_pit_state
*)qemu_mallocz(sizeof(icp_pit_state
));
682 s
->freq
[0] = ICP_BUS_FREQ
;
683 s
->freq
[1] = 1000000;
684 s
->freq
[2] = 1000000;
685 for (n
= 0; n
< 3; n
++) {
686 s
->control
[n
] = 0x20;
687 s
->count
[n
] = 0xffffffff;
690 iomemtype
= cpu_register_io_memory(0, icp_pit_readfn
,
692 cpu_register_physical_memory(base
, 0x007fffff, iomemtype
);
693 s
->timer
= qemu_new_timer(vm_clock
, icp_pit_tick
, s
);
694 /* ??? Save/restore. */
697 /* ARM PrimeCell PL011 UART */
706 uint32_t int_enabled
;
708 uint32_t read_fifo
[16];
716 CharDriverState
*chr
;
721 #define PL011_INT_TX 0x20
722 #define PL011_INT_RX 0x10
724 #define PL011_FLAG_TXFE 0x80
725 #define PL011_FLAG_RXFF 0x40
726 #define PL011_FLAG_TXFF 0x20
727 #define PL011_FLAG_RXFE 0x10
729 static const unsigned char pl011_id
[] =
730 { 0x11, 0x10, 0x14, 0x00, 0x0d, 0xf0, 0x05, 0xb1 };
732 static void pl011_update(pl011_state
*s
)
736 flags
= s
->int_level
& s
->int_enabled
;
737 pic_set_irq_new(s
->pic
, s
->irq
, flags
!= 0);
740 static uint32_t pl011_read(void *opaque
, target_phys_addr_t offset
)
742 pl011_state
*s
= (pl011_state
*)opaque
;
746 if (offset
>= 0xfe0 && offset
< 0x1000) {
747 return pl011_id
[(offset
- 0xfe0) >> 2];
749 switch (offset
>> 2) {
751 s
->flags
&= ~PL011_FLAG_RXFF
;
752 c
= s
->read_fifo
[s
->read_pos
];
753 if (s
->read_count
> 0) {
755 if (++s
->read_pos
== 16)
758 if (s
->read_count
== 0) {
759 s
->flags
|= PL011_FLAG_RXFE
;
761 if (s
->read_count
== s
->read_trigger
- 1)
762 s
->int_level
&= ~ PL011_INT_RX
;
769 case 8: /* UARTILPR */
771 case 9: /* UARTIBRD */
773 case 10: /* UARTFBRD */
775 case 11: /* UARTLCR_H */
777 case 12: /* UARTCR */
779 case 13: /* UARTIFLS */
781 case 14: /* UARTIMSC */
782 return s
->int_enabled
;
783 case 15: /* UARTRIS */
785 case 16: /* UARTMIS */
786 return s
->int_level
& s
->int_enabled
;
787 case 18: /* UARTDMACR */
790 cpu_abort (cpu_single_env
, "pl011_read: Bad offset %x\n", offset
);
795 static void pl011_set_read_trigger(pl011_state
*s
)
798 /* The docs say the RX interrupt is triggered when the FIFO exceeds
799 the threshold. However linux only reads the FIFO in response to an
800 interrupt. Triggering the interrupt when the FIFO is non-empty seems
801 to make things work. */
803 s
->read_trigger
= (s
->ifl
>> 1) & 0x1c;
809 static void pl011_write(void *opaque
, target_phys_addr_t offset
,
812 pl011_state
*s
= (pl011_state
*)opaque
;
816 switch (offset
>> 2) {
818 /* ??? Check if transmitter is enabled. */
821 qemu_chr_write(s
->chr
, &ch
, 1);
822 s
->int_level
|= PL011_INT_TX
;
828 case 8: /* UARTUARTILPR */
831 case 9: /* UARTIBRD */
834 case 10: /* UARTFBRD */
837 case 11: /* UARTLCR_H */
839 pl011_set_read_trigger(s
);
841 case 12: /* UARTCR */
842 /* ??? Need to implement the enable and loopback bits. */
845 case 13: /* UARTIFS */
847 pl011_set_read_trigger(s
);
849 case 14: /* UARTIMSC */
850 s
->int_enabled
= value
;
853 case 17: /* UARTICR */
854 s
->int_level
&= ~value
;
857 case 18: /* UARTDMACR */
860 cpu_abort(cpu_single_env
, "PL011: DMA not implemented\n");
863 cpu_abort (cpu_single_env
, "pl011_write: Bad offset %x\n", offset
);
867 static int pl011_can_recieve(void *opaque
)
869 pl011_state
*s
= (pl011_state
*)opaque
;
872 return s
->read_count
< 16;
874 return s
->read_count
< 1;
877 static void pl011_recieve(void *opaque
, const uint8_t *buf
, int size
)
879 pl011_state
*s
= (pl011_state
*)opaque
;
882 slot
= s
->read_pos
+ s
->read_count
;
885 s
->read_fifo
[slot
] = *buf
;
887 s
->flags
&= ~PL011_FLAG_RXFE
;
888 if (s
->cr
& 0x10 || s
->read_count
== 16) {
889 s
->flags
|= PL011_FLAG_RXFF
;
891 if (s
->read_count
== s
->read_trigger
) {
892 s
->int_level
|= PL011_INT_RX
;
897 static void pl011_event(void *opaque
, int event
)
899 /* ??? Should probably implement break. */
902 static CPUReadMemoryFunc
*pl011_readfn
[] = {
908 static CPUWriteMemoryFunc
*pl011_writefn
[] = {
914 static void pl011_init(uint32_t base
, icp_pic_state
*pic
, int irq
,
915 CharDriverState
*chr
)
920 s
= (pl011_state
*)qemu_mallocz(sizeof(pl011_state
));
921 iomemtype
= cpu_register_io_memory(0, pl011_readfn
,
923 cpu_register_physical_memory(base
, 0x007fffff, iomemtype
);
933 qemu_chr_add_read_handler(chr
, pl011_can_recieve
, pl011_recieve
, s
);
934 qemu_chr_add_event_handler(chr
, pl011_event
);
936 /* ??? Save/restore. */
939 /* CP control registers. */
944 static uint32_t icp_control_read(void *opaque
, target_phys_addr_t offset
)
946 icp_control_state
*s
= (icp_control_state
*)opaque
;
948 switch (offset
>> 2) {
949 case 0: /* CP_IDFIELD */
951 case 1: /* CP_FLASHPROG */
953 case 2: /* CP_INTREG */
955 case 3: /* CP_DECODE */
958 cpu_abort (cpu_single_env
, "icp_control_read: Bad offset %x\n", offset
);
963 static void icp_control_write(void *opaque
, target_phys_addr_t offset
,
966 icp_control_state
*s
= (icp_control_state
*)opaque
;
968 switch (offset
>> 2) {
969 case 1: /* CP_FLASHPROG */
970 case 2: /* CP_INTREG */
971 case 3: /* CP_DECODE */
972 /* Nothing interesting implemented yet. */
975 cpu_abort (cpu_single_env
, "icp_control_write: Bad offset %x\n", offset
);
978 static CPUReadMemoryFunc
*icp_control_readfn
[] = {
984 static CPUWriteMemoryFunc
*icp_control_writefn
[] = {
990 static void icp_control_init(uint32_t base
)
993 icp_control_state
*s
;
995 s
= (icp_control_state
*)qemu_mallocz(sizeof(icp_control_state
));
996 iomemtype
= cpu_register_io_memory(0, icp_control_readfn
,
997 icp_control_writefn
, s
);
998 cpu_register_physical_memory(base
, 0x007fffff, iomemtype
);
1000 /* ??? Save/restore. */
1004 /* Keyboard/Mouse Interface. */
1018 static void icp_kmi_update(void *opaque
, int level
)
1020 icp_kmi_state
*s
= (icp_kmi_state
*)opaque
;
1024 raise
= (s
->pending
&& (s
->cr
& 0x10) != 0)
1025 || (s
->cr
& 0x08) != 0;
1026 pic_set_irq_new(s
->pic
, s
->irq
, raise
);
1029 static uint32_t icp_kmi_read(void *opaque
, target_phys_addr_t offset
)
1031 icp_kmi_state
*s
= (icp_kmi_state
*)opaque
;
1033 if (offset
>= 0xfe0 && offset
< 0x1000)
1036 switch (offset
>> 2) {
1039 case 1: /* KMISTAT */
1040 /* KMIC and KMID bits not implemented. */
1046 case 2: /* KMIDATA */
1048 s
->last
= ps2_read_data(s
->dev
);
1050 case 3: /* KMICLKDIV */
1053 return s
->pending
| 2;
1055 cpu_abort (cpu_single_env
, "icp_kmi_read: Bad offset %x\n", offset
);
1060 static void icp_kmi_write(void *opaque
, target_phys_addr_t offset
,
1063 icp_kmi_state
*s
= (icp_kmi_state
*)opaque
;
1065 switch (offset
>> 2) {
1068 icp_kmi_update(s
, s
->pending
);
1069 /* ??? Need to implement the enable/disable bit. */
1071 case 2: /* KMIDATA */
1072 /* ??? This should toggle the TX interrupt line. */
1073 /* ??? This means kbd/mouse can block each other. */
1075 ps2_write_mouse(s
->dev
, value
);
1077 ps2_write_keyboard(s
->dev
, value
);
1080 case 3: /* KMICLKDIV */
1084 cpu_abort (cpu_single_env
, "icp_kmi_write: Bad offset %x\n", offset
);
1087 static CPUReadMemoryFunc
*icp_kmi_readfn
[] = {
1093 static CPUWriteMemoryFunc
*icp_kmi_writefn
[] = {
1099 static void icp_kmi_init(uint32_t base
, icp_pic_state
* pic
, int irq
,
1105 s
= (icp_kmi_state
*)qemu_mallocz(sizeof(icp_kmi_state
));
1106 iomemtype
= cpu_register_io_memory(0, icp_kmi_readfn
,
1107 icp_kmi_writefn
, s
);
1108 cpu_register_physical_memory(base
, 0x007fffff, iomemtype
);
1112 s
->is_mouse
= is_mouse
;
1114 s
->dev
= ps2_mouse_init(icp_kmi_update
, s
);
1116 s
->dev
= ps2_kbd_init(icp_kmi_update
, s
);
1117 /* ??? Save/restore. */
1120 /* The worlds second smallest bootloader. Set r0-r2, then jump to kernel. */
1121 static uint32_t bootloader
[] = {
1122 0xe3a00000, /* mov r0, #0 */
1123 0xe3a01013, /* mov r1, #0x13 */
1124 0xe3811c01, /* orr r1, r1, #0x100 */
1125 0xe59f2000, /* ldr r2, [pc, #0] */
1126 0xe59ff000, /* ldr pc, [pc, #0] */
1127 0, /* Address of kernel args. Set by integratorcp_init. */
1128 0 /* Kernel entry point. Set by integratorcp_init. */
1131 static void set_kernel_args(uint32_t ram_size
, int initrd_size
,
1132 const char *kernel_cmdline
)
1136 p
= (uint32_t *)(phys_ram_base
+ KERNEL_ARGS_ADDR
);
1139 stl_raw(p
++, 0x54410001);
1141 stl_raw(p
++, 0x1000);
1145 stl_raw(p
++, 0x54410002);
1146 stl_raw(p
++, ram_size
);
1151 stl_raw(p
++, 0x54420005);
1152 stl_raw(p
++, INITRD_LOAD_ADDR
);
1153 stl_raw(p
++, initrd_size
);
1155 if (kernel_cmdline
&& *kernel_cmdline
) {
1159 cmdline_size
= strlen(kernel_cmdline
);
1160 memcpy (p
+ 2, kernel_cmdline
, cmdline_size
+ 1);
1161 cmdline_size
= (cmdline_size
>> 2) + 1;
1162 stl_raw(p
++, cmdline_size
+ 2);
1163 stl_raw(p
++, 0x54410009);
1173 static void integratorcp_init(int ram_size
, int vga_ram_size
, int boot_device
,
1174 DisplayState
*ds
, const char **fd_filename
, int snapshot
,
1175 const char *kernel_filename
, const char *kernel_cmdline
,
1176 const char *initrd_filename
, uint32_t cpuid
)
1179 uint32_t bios_offset
;
1186 cpu_arm_set_model(env
, cpuid
);
1187 bios_offset
= ram_size
+ vga_ram_size
;
1188 /* ??? On a real system the first 1Mb is mapped as SSRAM or boot flash. */
1189 /* ??? RAM shoud repeat to fill physical memory space. */
1190 /* SDRAM at address zero*/
1191 cpu_register_physical_memory(0, ram_size
, IO_MEM_RAM
);
1192 /* And again at address 0x80000000 */
1193 cpu_register_physical_memory(0x80000000, ram_size
, IO_MEM_RAM
);
1195 integratorcm_init(ram_size
>> 20, bios_offset
);
1196 pic
= icp_pic_init(0x14000000, env
, -1);
1197 icp_pic_init(0xca000000, pic
, 26);
1198 icp_pit_init(0x13000000, pic
);
1199 pl011_init(0x16000000, pic
, 1, serial_hds
[0]);
1200 pl011_init(0x17000000, pic
, 2, serial_hds
[1]);
1201 icp_control_init(0xcb000000);
1202 icp_kmi_init(0x18000000, pic
, 3, 0);
1203 icp_kmi_init(0x19000000, pic
, 4, 1);
1204 if (nd_table
[0].vlan
) {
1205 if (nd_table
[0].model
== NULL
1206 || strcmp(nd_table
[0].model
, "smc91c111") == 0) {
1207 smc91c111_init(&nd_table
[0], 0xc8000000, pic
, 27);
1209 fprintf(stderr
, "qemu: Unsupported NIC: %s\n", nd_table
[0].model
);
1213 lcd
= pl110_init(ds
, 0xc0000000, pic
, 22);
1215 /* Load the kernel. */
1216 if (!kernel_filename
) {
1217 fprintf(stderr
, "Kernel image must be specified\n");
1220 kernel_size
= load_image(kernel_filename
,
1221 phys_ram_base
+ KERNEL_LOAD_ADDR
);
1222 if (kernel_size
< 0) {
1223 fprintf(stderr
, "qemu: could not load kernel '%s'\n", kernel_filename
);
1226 if (initrd_filename
) {
1227 initrd_size
= load_image(initrd_filename
,
1228 phys_ram_base
+ INITRD_LOAD_ADDR
);
1229 if (initrd_size
< 0) {
1230 fprintf(stderr
, "qemu: could not load initrd '%s'\n",
1237 bootloader
[5] = KERNEL_ARGS_ADDR
;
1238 bootloader
[6] = KERNEL_LOAD_ADDR
;
1239 for (n
= 0; n
< sizeof(bootloader
) / 4; n
++)
1240 stl_raw(phys_ram_base
+ (n
* 4), bootloader
[n
]);
1241 set_kernel_args(ram_size
, initrd_size
, kernel_cmdline
);
1244 static void integratorcp926_init(int ram_size
, int vga_ram_size
,
1245 int boot_device
, DisplayState
*ds
, const char **fd_filename
, int snapshot
,
1246 const char *kernel_filename
, const char *kernel_cmdline
,
1247 const char *initrd_filename
)
1249 integratorcp_init(ram_size
, vga_ram_size
, boot_device
, ds
, fd_filename
,
1250 snapshot
, kernel_filename
, kernel_cmdline
,
1251 initrd_filename
, ARM_CPUID_ARM926
);
1254 static void integratorcp1026_init(int ram_size
, int vga_ram_size
,
1255 int boot_device
, DisplayState
*ds
, const char **fd_filename
, int snapshot
,
1256 const char *kernel_filename
, const char *kernel_cmdline
,
1257 const char *initrd_filename
)
1259 integratorcp_init(ram_size
, vga_ram_size
, boot_device
, ds
, fd_filename
,
1260 snapshot
, kernel_filename
, kernel_cmdline
,
1261 initrd_filename
, ARM_CPUID_ARM1026
);
1264 QEMUMachine integratorcp926_machine
= {
1266 "ARM Integrator/CP (ARM926EJ-S)",
1267 integratorcp926_init
,
1270 QEMUMachine integratorcp1026_machine
= {
1272 "ARM Integrator/CP (ARM1026EJ-S)",
1273 integratorcp1026_init
,