|
|
1.1 root 1: /*
2: * ARM Integrator CP System emulation.
3: *
4: * Copyright (c) 2005 CodeSourcery, LLC.
5: * Written by Paul Brook
6: *
7: * This code is licenced under the GPL
8: */
9:
10: #include <vl.h>
11:
12: #define KERNEL_ARGS_ADDR 0x100
13: #define KERNEL_LOAD_ADDR 0x00010000
14: #define INITRD_LOAD_ADDR 0x00800000
15:
16: /* Stub functions for hardware that doesn't exist. */
17: void pic_set_irq(int irq, int level)
18: {
19: cpu_abort (cpu_single_env, "pic_set_irq");
20: }
21:
22: void pic_info(void)
23: {
24: }
25:
26: void irq_info(void)
27: {
28: }
29:
30: void vga_update_display(void)
31: {
32: }
33:
34: void vga_screen_dump(const char *filename)
35: {
36: }
37:
38: void vga_invalidate_display(void)
39: {
40: }
41:
42: void DMA_run (void)
43: {
44: }
45:
46: typedef struct {
47: uint32_t flash_offset;
48: uint32_t cm_osc;
49: uint32_t cm_ctrl;
50: uint32_t cm_lock;
51: uint32_t cm_auxosc;
52: uint32_t cm_sdram;
53: uint32_t cm_init;
54: uint32_t cm_flags;
55: uint32_t cm_nvflags;
56: uint32_t int_level;
57: uint32_t irq_enabled;
58: uint32_t fiq_enabled;
59: } integratorcm_state;
60:
61: static uint8_t integrator_spd[128] = {
62: 128, 8, 4, 11, 9, 1, 64, 0, 2, 0xa0, 0xa0, 0, 0, 8, 0, 1,
63: 0xe, 4, 0x1c, 1, 2, 0x20, 0xc0, 0, 0, 0, 0, 0x30, 0x28, 0x30, 0x28, 0x40
64: };
65:
66: static uint32_t integratorcm_read(void *opaque, target_phys_addr_t offset)
67: {
68: integratorcm_state *s = (integratorcm_state *)opaque;
69: offset -= 0x10000000;
70: if (offset >= 0x100 && offset < 0x200) {
71: /* CM_SPD */
72: if (offset >= 0x180)
73: return 0;
74: return integrator_spd[offset >> 2];
75: }
76: switch (offset >> 2) {
77: case 0: /* CM_ID */
78: return 0x411a3001;
79: case 1: /* CM_PROC */
80: return 0;
81: case 2: /* CM_OSC */
82: return s->cm_osc;
83: case 3: /* CM_CTRL */
84: return s->cm_ctrl;
85: case 4: /* CM_STAT */
86: return 0x00100000;
87: case 5: /* CM_LOCK */
88: if (s->cm_lock == 0xa05f) {
89: return 0x1a05f;
90: } else {
91: return s->cm_lock;
92: }
93: case 6: /* CM_LMBUSCNT */
94: /* ??? High frequency timer. */
95: cpu_abort(cpu_single_env, "integratorcm_read: CM_LMBUSCNT");
96: case 7: /* CM_AUXOSC */
97: return s->cm_auxosc;
98: case 8: /* CM_SDRAM */
99: return s->cm_sdram;
100: case 9: /* CM_INIT */
101: return s->cm_init;
102: case 10: /* CM_REFCT */
103: /* ??? High frequency timer. */
104: cpu_abort(cpu_single_env, "integratorcm_read: CM_REFCT");
105: case 12: /* CM_FLAGS */
106: return s->cm_flags;
107: case 14: /* CM_NVFLAGS */
108: return s->cm_nvflags;
109: case 16: /* CM_IRQ_STAT */
110: return s->int_level & s->irq_enabled;
111: case 17: /* CM_IRQ_RSTAT */
112: return s->int_level;
113: case 18: /* CM_IRQ_ENSET */
114: return s->irq_enabled;
115: case 20: /* CM_SOFT_INTSET */
116: return s->int_level & 1;
117: case 24: /* CM_FIQ_STAT */
118: return s->int_level & s->fiq_enabled;
119: case 25: /* CM_FIQ_RSTAT */
120: return s->int_level;
121: case 26: /* CM_FIQ_ENSET */
122: return s->fiq_enabled;
123: case 32: /* CM_VOLTAGE_CTL0 */
124: case 33: /* CM_VOLTAGE_CTL1 */
125: case 34: /* CM_VOLTAGE_CTL2 */
126: case 35: /* CM_VOLTAGE_CTL3 */
127: /* ??? Voltage control unimplemented. */
128: return 0;
129: default:
130: cpu_abort (cpu_single_env,
131: "integratorcm_read: Unimplemented offset 0x%x\n", offset);
132: return 0;
133: }
134: }
135:
136: static void integratorcm_do_remap(integratorcm_state *s, int flash)
137: {
138: if (flash) {
139: cpu_register_physical_memory(0, 0x100000, IO_MEM_RAM);
140: } else {
141: cpu_register_physical_memory(0, 0x100000, s->flash_offset | IO_MEM_RAM);
142: }
143: //??? tlb_flush (cpu_single_env, 1);
144: }
145:
146: static void integratorcm_set_ctrl(integratorcm_state *s, uint32_t value)
147: {
148: if (value & 8) {
149: cpu_abort(cpu_single_env, "Board reset\n");
150: }
151: if ((s->cm_init ^ value) & 4) {
152: integratorcm_do_remap(s, (value & 4) == 0);
153: }
154: if ((s->cm_init ^ value) & 1) {
155: printf("Green LED %s\n", (value & 1) ? "on" : "off");
156: }
157: s->cm_init = (s->cm_init & ~ 5) | (value ^ 5);
158: }
159:
160: static void integratorcm_update(integratorcm_state *s)
161: {
162: /* ??? The CPU irq/fiq is raised when either the core module or base PIC
163: are active. */
164: if (s->int_level & (s->irq_enabled | s->fiq_enabled))
165: cpu_abort(cpu_single_env, "Core module interrupt\n");
166: }
167:
168: static void integratorcm_write(void *opaque, target_phys_addr_t offset,
169: uint32_t value)
170: {
171: integratorcm_state *s = (integratorcm_state *)opaque;
172: offset -= 0x10000000;
173: switch (offset >> 2) {
174: case 2: /* CM_OSC */
175: if (s->cm_lock == 0xa05f)
176: s->cm_osc = value;
177: break;
178: case 3: /* CM_CTRL */
179: integratorcm_set_ctrl(s, value);
180: break;
181: case 5: /* CM_LOCK */
182: s->cm_lock = value & 0xffff;
183: break;
184: case 7: /* CM_AUXOSC */
185: if (s->cm_lock == 0xa05f)
186: s->cm_auxosc = value;
187: break;
188: case 8: /* CM_SDRAM */
189: s->cm_sdram = value;
190: break;
191: case 9: /* CM_INIT */
192: /* ??? This can change the memory bus frequency. */
193: s->cm_init = value;
194: break;
195: case 12: /* CM_FLAGSS */
196: s->cm_flags |= value;
197: break;
198: case 13: /* CM_FLAGSC */
199: s->cm_flags &= ~value;
200: break;
201: case 14: /* CM_NVFLAGSS */
202: s->cm_nvflags |= value;
203: break;
204: case 15: /* CM_NVFLAGSS */
205: s->cm_nvflags &= ~value;
206: break;
207: case 18: /* CM_IRQ_ENSET */
208: s->irq_enabled |= value;
209: integratorcm_update(s);
210: break;
211: case 19: /* CM_IRQ_ENCLR */
212: s->irq_enabled &= ~value;
213: integratorcm_update(s);
214: break;
215: case 20: /* CM_SOFT_INTSET */
216: s->int_level |= (value & 1);
217: integratorcm_update(s);
218: break;
219: case 21: /* CM_SOFT_INTCLR */
220: s->int_level &= ~(value & 1);
221: integratorcm_update(s);
222: break;
223: case 26: /* CM_FIQ_ENSET */
224: s->fiq_enabled |= value;
225: integratorcm_update(s);
226: break;
227: case 27: /* CM_FIQ_ENCLR */
228: s->fiq_enabled &= ~value;
229: integratorcm_update(s);
230: break;
231: case 32: /* CM_VOLTAGE_CTL0 */
232: case 33: /* CM_VOLTAGE_CTL1 */
233: case 34: /* CM_VOLTAGE_CTL2 */
234: case 35: /* CM_VOLTAGE_CTL3 */
235: /* ??? Voltage control unimplemented. */
236: break;
237: default:
238: cpu_abort (cpu_single_env,
239: "integratorcm_write: Unimplemented offset 0x%x\n", offset);
240: break;
241: }
242: }
243:
244: /* Integrator/CM control registers. */
245:
246: static CPUReadMemoryFunc *integratorcm_readfn[] = {
247: integratorcm_read,
248: integratorcm_read,
249: integratorcm_read
250: };
251:
252: static CPUWriteMemoryFunc *integratorcm_writefn[] = {
253: integratorcm_write,
254: integratorcm_write,
255: integratorcm_write
256: };
257:
258: static void integratorcm_init(int memsz, uint32_t flash_offset)
259: {
260: int iomemtype;
261: integratorcm_state *s;
262:
263: s = (integratorcm_state *)qemu_mallocz(sizeof(integratorcm_state));
264: s->cm_osc = 0x01000048;
265: /* ??? What should the high bits of this value be? */
266: s->cm_auxosc = 0x0007feff;
267: s->cm_sdram = 0x00011122;
268: if (memsz >= 256) {
269: integrator_spd[31] = 64;
270: s->cm_sdram |= 0x10;
271: } else if (memsz >= 128) {
272: integrator_spd[31] = 32;
273: s->cm_sdram |= 0x0c;
274: } else if (memsz >= 64) {
275: integrator_spd[31] = 16;
276: s->cm_sdram |= 0x08;
277: } else if (memsz >= 32) {
278: integrator_spd[31] = 4;
279: s->cm_sdram |= 0x04;
280: } else {
281: integrator_spd[31] = 2;
282: }
283: memcpy(integrator_spd + 73, "QEMU-MEMORY", 11);
284: s->cm_init = 0x00000112;
285: s->flash_offset = flash_offset;
286:
287: iomemtype = cpu_register_io_memory(0, integratorcm_readfn,
288: integratorcm_writefn, s);
289: cpu_register_physical_memory(0x10000000, 0x007fffff, iomemtype);
290: integratorcm_do_remap(s, 1);
291: /* ??? Save/restore. */
292: }
293:
294: /* Integrator/CP hardware emulation. */
295: /* Primary interrupt controller. */
296:
297: typedef struct icp_pic_state
298: {
299: uint32_t base;
300: uint32_t level;
301: uint32_t irq_enabled;
302: uint32_t fiq_enabled;
303: void *parent;
304: /* -1 if parent is a cpu, otherwise IRQ number on parent PIC. */
305: int parent_irq;
306: } icp_pic_state;
307:
308: static void icp_pic_update(icp_pic_state *s)
309: {
310: CPUState *env;
311: if (s->parent_irq != -1) {
312: uint32_t flags;
313:
314: flags = (s->level & s->irq_enabled);
315: pic_set_irq_new(s->parent, s->parent_irq,
316: flags != 0);
317: return;
318: }
319: /* Raise CPU interrupt. */
320: env = (CPUState *)s->parent;
321: if (s->level & s->fiq_enabled) {
322: cpu_interrupt (env, CPU_INTERRUPT_FIQ);
323: } else {
324: cpu_reset_interrupt (env, CPU_INTERRUPT_FIQ);
325: }
326: if (s->level & s->irq_enabled) {
327: cpu_interrupt (env, CPU_INTERRUPT_HARD);
328: } else {
329: cpu_reset_interrupt (env, CPU_INTERRUPT_HARD);
330: }
331: }
332:
333: void pic_set_irq_new(void *opaque, int irq, int level)
334: {
335: icp_pic_state *s = (icp_pic_state *)opaque;
336: if (level)
337: s->level |= 1 << irq;
338: else
339: s->level &= ~(1 << irq);
340: icp_pic_update(s);
341: }
342:
343: static uint32_t icp_pic_read(void *opaque, target_phys_addr_t offset)
344: {
345: icp_pic_state *s = (icp_pic_state *)opaque;
346:
347: offset -= s->base;
348: switch (offset >> 2) {
349: case 0: /* IRQ_STATUS */
350: return s->level & s->irq_enabled;
351: case 1: /* IRQ_RAWSTAT */
352: return s->level;
353: case 2: /* IRQ_ENABLESET */
354: return s->irq_enabled;
355: case 4: /* INT_SOFTSET */
356: return s->level & 1;
357: case 8: /* FRQ_STATUS */
358: return s->level & s->fiq_enabled;
359: case 9: /* FRQ_RAWSTAT */
360: return s->level;
361: case 10: /* FRQ_ENABLESET */
362: return s->fiq_enabled;
363: case 3: /* IRQ_ENABLECLR */
364: case 5: /* INT_SOFTCLR */
365: case 11: /* FRQ_ENABLECLR */
366: default:
367: printf ("icp_pic_read: Bad register offset 0x%x\n", offset);
368: return 0;
369: }
370: }
371:
372: static void icp_pic_write(void *opaque, target_phys_addr_t offset,
373: uint32_t value)
374: {
375: icp_pic_state *s = (icp_pic_state *)opaque;
376: offset -= s->base;
377:
378: switch (offset >> 2) {
379: case 2: /* IRQ_ENABLESET */
380: s->irq_enabled |= value;
381: break;
382: case 3: /* IRQ_ENABLECLR */
383: s->irq_enabled &= ~value;
384: break;
385: case 4: /* INT_SOFTSET */
386: if (value & 1)
387: pic_set_irq_new(s, 0, 1);
388: break;
389: case 5: /* INT_SOFTCLR */
390: if (value & 1)
391: pic_set_irq_new(s, 0, 0);
392: break;
393: case 10: /* FRQ_ENABLESET */
394: s->fiq_enabled |= value;
395: break;
396: case 11: /* FRQ_ENABLECLR */
397: s->fiq_enabled &= ~value;
398: break;
399: case 0: /* IRQ_STATUS */
400: case 1: /* IRQ_RAWSTAT */
401: case 8: /* FRQ_STATUS */
402: case 9: /* FRQ_RAWSTAT */
403: default:
404: printf ("icp_pic_write: Bad register offset 0x%x\n", offset);
405: return;
406: }
407: icp_pic_update(s);
408: }
409:
410: static CPUReadMemoryFunc *icp_pic_readfn[] = {
411: icp_pic_read,
412: icp_pic_read,
413: icp_pic_read
414: };
415:
416: static CPUWriteMemoryFunc *icp_pic_writefn[] = {
417: icp_pic_write,
418: icp_pic_write,
419: icp_pic_write
420: };
421:
422: static icp_pic_state *icp_pic_init(uint32_t base, void *parent,
423: int parent_irq)
424: {
425: icp_pic_state *s;
426: int iomemtype;
427:
428: s = (icp_pic_state *)qemu_mallocz(sizeof(icp_pic_state));
429: if (!s)
430: return NULL;
431:
432: s->base = base;
433: s->parent = parent;
434: s->parent_irq = parent_irq;
435: iomemtype = cpu_register_io_memory(0, icp_pic_readfn,
436: icp_pic_writefn, s);
437: cpu_register_physical_memory(base, 0x007fffff, iomemtype);
438: /* ??? Save/restore. */
439: return s;
440: }
441:
442: /* Timers. */
443:
444: /* System bus clock speed (40MHz) for timer 0. Not sure about this value. */
445: #define ICP_BUS_FREQ 40000000
446:
447: typedef struct {
448: int64_t next_time;
449: int64_t expires[3];
450: int64_t loaded[3];
451: QEMUTimer *timer;
452: icp_pic_state *pic;
453: uint32_t base;
454: uint32_t control[3];
455: uint32_t count[3];
456: uint32_t limit[3];
457: int freq[3];
458: int int_level[3];
459: } icp_pit_state;
460:
461: /* Calculate the new expiry time of the given timer. */
462:
463: static void icp_pit_reload(icp_pit_state *s, int n)
464: {
465: int64_t delay;
466:
467: s->loaded[n] = s->expires[n];
468: delay = muldiv64(s->count[n], ticks_per_sec, s->freq[n]);
469: if (delay == 0)
470: delay = 1;
471: s->expires[n] += delay;
472: }
473:
474: /* Check all active timers, and schedule the next timer interrupt. */
475:
476: static void icp_pit_update(icp_pit_state *s, int64_t now)
477: {
478: int n;
479: int64_t next;
480:
481: next = now;
482: for (n = 0; n < 3; n++) {
483: /* Ignore disabled timers. */
484: if ((s->control[n] & 0x80) == 0)
485: continue;
486: /* Ignore expired one-shot timers. */
487: if (s->count[n] == 0 && s->control[n] & 1)
488: continue;
489: if (s->expires[n] - now <= 0) {
490: /* Timer has expired. */
491: s->int_level[n] = 1;
492: if (s->control[n] & 1) {
493: /* One-shot. */
494: s->count[n] = 0;
495: } else {
496: if ((s->control[n] & 0x40) == 0) {
497: /* Free running. */
498: if (s->control[n] & 2)
499: s->count[n] = 0xffffffff;
500: else
501: s->count[n] = 0xffff;
502: } else {
503: /* Periodic. */
504: s->count[n] = s->limit[n];
505: }
506: }
507: }
508: while (s->expires[n] - now <= 0) {
509: icp_pit_reload(s, n);
510: }
511: }
512: /* Update interrupts. */
513: for (n = 0; n < 3; n++) {
514: if (s->int_level[n] && (s->control[n] & 0x20)) {
515: pic_set_irq_new(s->pic, 5 + n, 1);
516: } else {
517: pic_set_irq_new(s->pic, 5 + n, 0);
518: }
519: if (next - s->expires[n] < 0)
520: next = s->expires[n];
521: }
522: /* Schedule the next timer interrupt. */
523: if (next == now) {
524: qemu_del_timer(s->timer);
525: s->next_time = 0;
526: } else if (next != s->next_time) {
527: qemu_mod_timer(s->timer, next);
528: s->next_time = next;
529: }
530: }
531:
532: /* Return the current value of the timer. */
533: static uint32_t icp_pit_getcount(icp_pit_state *s, int n, int64_t now)
534: {
535: int64_t elapsed;
536: int64_t period;
537:
538: if (s->count[n] == 0)
539: return 0;
540: if ((s->control[n] & 0x80) == 0)
541: return s->count[n];
542: elapsed = now - s->loaded[n];
543: period = s->expires[n] - s->loaded[n];
544: /* If the timer should have expired then return 0. This can happen
545: when the host timer signal doesnt occur immediately. It's better to
546: have a timer appear to sit at zero for a while than have it wrap
547: around before the guest interrupt is raised. */
548: /* ??? Could we trigger the interrupt here? */
549: if (elapsed > period)
550: return 0;
551: /* We need to calculate count * elapsed / period without overfowing.
552: Scale both elapsed and period so they fit in a 32-bit int. */
553: while (period != (int32_t)period) {
554: period >>= 1;
555: elapsed >>= 1;
556: }
557: return ((uint64_t)s->count[n] * (uint64_t)(int32_t)elapsed)
558: / (int32_t)period;
559: }
560:
561: static uint32_t icp_pit_read(void *opaque, target_phys_addr_t offset)
562: {
563: int n;
564: icp_pit_state *s = (icp_pit_state *)opaque;
565:
566: offset -= s->base;
567: n = offset >> 8;
568: if (n > 2)
569: cpu_abort (cpu_single_env, "icp_pit_read: Bad timer %x\n", offset);
570: switch ((offset & 0xff) >> 2) {
571: case 0: /* TimerLoad */
572: case 6: /* TimerBGLoad */
573: return s->limit[n];
574: case 1: /* TimerValue */
575: return icp_pit_getcount(s, n, qemu_get_clock(vm_clock));
576: case 2: /* TimerControl */
577: return s->control[n];
578: case 4: /* TimerRIS */
579: return s->int_level[n];
580: case 5: /* TimerMIS */
581: if ((s->control[n] & 0x20) == 0)
582: return 0;
583: return s->int_level[n];
584: default:
585: cpu_abort (cpu_single_env, "icp_pit_read: Bad offset %x\n", offset);
586: return 0;
587: }
588: }
589:
590: static void icp_pit_write(void *opaque, target_phys_addr_t offset,
591: uint32_t value)
592: {
593: icp_pit_state *s = (icp_pit_state *)opaque;
594: int n;
595: int64_t now;
596:
597: now = qemu_get_clock(vm_clock);
598: offset -= s->base;
599: n = offset >> 8;
600: if (n > 2)
601: cpu_abort (cpu_single_env, "icp_pit_write: Bad offset %x\n", offset);
602:
603: switch ((offset & 0xff) >> 2) {
604: case 0: /* TimerLoad */
605: s->limit[n] = value;
606: s->count[n] = value;
607: s->expires[n] = now;
608: icp_pit_reload(s, n);
609: break;
610: case 1: /* TimerValue */
611: /* ??? Linux seems to want to write to this readonly register.
612: Ignore it. */
613: break;
614: case 2: /* TimerControl */
615: if (s->control[n] & 0x80) {
616: /* Pause the timer if it is running. This may cause some
617: inaccuracy dure to rounding, but avoids a whole lot of other
618: messyness. */
619: s->count[n] = icp_pit_getcount(s, n, now);
620: }
621: s->control[n] = value;
622: if (n == 0)
623: s->freq[n] = ICP_BUS_FREQ;
624: else
625: s->freq[n] = 1000000;
626: /* ??? Need to recalculate expiry time after changing divisor. */
627: switch ((value >> 2) & 3) {
628: case 1: s->freq[n] >>= 4; break;
629: case 2: s->freq[n] >>= 8; break;
630: }
631: if (s->control[n] & 0x80) {
632: /* Restart the timer if still enabled. */
633: s->expires[n] = now;
634: icp_pit_reload(s, n);
635: }
636: break;
637: case 3: /* TimerIntClr */
638: s->int_level[n] = 0;
639: break;
640: case 6: /* TimerBGLoad */
641: s->limit[n] = value;
642: break;
643: default:
644: cpu_abort (cpu_single_env, "icp_pit_write: Bad offset %x\n", offset);
645: }
646: icp_pit_update(s, now);
647: }
648:
649: static void icp_pit_tick(void *opaque)
650: {
651: int64_t now;
652:
653: now = qemu_get_clock(vm_clock);
654: icp_pit_update((icp_pit_state *)opaque, now);
655: }
656:
657: static CPUReadMemoryFunc *icp_pit_readfn[] = {
658: icp_pit_read,
659: icp_pit_read,
660: icp_pit_read
661: };
662:
663: static CPUWriteMemoryFunc *icp_pit_writefn[] = {
664: icp_pit_write,
665: icp_pit_write,
666: icp_pit_write
667: };
668:
669: static void icp_pit_init(uint32_t base, icp_pic_state *pic)
670: {
671: int iomemtype;
672: icp_pit_state *s;
673: int n;
674:
675: s = (icp_pit_state *)qemu_mallocz(sizeof(icp_pit_state));
676: s->base = base;
677: s->pic = pic;
678: s->freq[0] = ICP_BUS_FREQ;
679: s->freq[1] = 1000000;
680: s->freq[2] = 1000000;
681: for (n = 0; n < 3; n++) {
682: s->control[n] = 0x20;
683: s->count[n] = 0xffffffff;
684: }
685:
686: iomemtype = cpu_register_io_memory(0, icp_pit_readfn,
687: icp_pit_writefn, s);
688: cpu_register_physical_memory(base, 0x007fffff, iomemtype);
689: s->timer = qemu_new_timer(vm_clock, icp_pit_tick, s);
690: /* ??? Save/restore. */
691: }
692:
693: /* ARM PrimeCell PL011 UART */
694:
695: typedef struct {
696: uint32_t base;
697: uint32_t readbuff;
698: uint32_t flags;
699: uint32_t lcr;
700: uint32_t cr;
701: uint32_t dmacr;
702: uint32_t int_enabled;
703: uint32_t int_level;
704: uint32_t read_fifo[16];
705: uint32_t ilpr;
706: uint32_t ibrd;
707: uint32_t fbrd;
708: uint32_t ifl;
709: int read_pos;
710: int read_count;
711: int read_trigger;
712: CharDriverState *chr;
713: icp_pic_state *pic;
714: int irq;
715: } pl011_state;
716:
717: #define PL011_INT_TX 0x20
718: #define PL011_INT_RX 0x10
719:
720: #define PL011_FLAG_TXFE 0x80
721: #define PL011_FLAG_RXFF 0x40
722: #define PL011_FLAG_TXFF 0x20
723: #define PL011_FLAG_RXFE 0x10
724:
725: static const unsigned char pl011_id[] =
726: { 0x11, 0x10, 0x14, 0x00, 0x0d, 0xf0, 0x05, 0xb1 };
727:
728: static void pl011_update(pl011_state *s)
729: {
730: uint32_t flags;
731:
732: flags = s->int_level & s->int_enabled;
733: pic_set_irq_new(s->pic, s->irq, flags != 0);
734: }
735:
736: static uint32_t pl011_read(void *opaque, target_phys_addr_t offset)
737: {
738: pl011_state *s = (pl011_state *)opaque;
739: uint32_t c;
740:
741: offset -= s->base;
742: if (offset >= 0xfe0 && offset < 0x1000) {
743: return pl011_id[(offset - 0xfe0) >> 2];
744: }
745: switch (offset >> 2) {
746: case 0: /* UARTDR */
747: s->flags &= ~PL011_FLAG_RXFF;
748: c = s->read_fifo[s->read_pos];
749: if (s->read_count > 0) {
750: s->read_count--;
751: if (++s->read_pos == 16)
752: s->read_pos = 0;
753: }
754: if (s->read_count == 0) {
755: s->flags |= PL011_FLAG_RXFE;
756: }
757: if (s->read_count == s->read_trigger - 1)
758: s->int_level &= ~ PL011_INT_RX;
759: pl011_update(s);
760: return c;
761: case 1: /* UARTCR */
762: return 0;
763: case 6: /* UARTFR */
764: return s->flags;
765: case 8: /* UARTILPR */
766: return s->ilpr;
767: case 9: /* UARTIBRD */
768: return s->ibrd;
769: case 10: /* UARTFBRD */
770: return s->fbrd;
771: case 11: /* UARTLCR_H */
772: return s->lcr;
773: case 12: /* UARTCR */
774: return s->cr;
775: case 13: /* UARTIFLS */
776: return s->ifl;
777: case 14: /* UARTIMSC */
778: return s->int_enabled;
779: case 15: /* UARTRIS */
780: return s->int_level;
781: case 16: /* UARTMIS */
782: return s->int_level & s->int_enabled;
783: case 18: /* UARTDMACR */
784: return s->dmacr;
785: default:
786: cpu_abort (cpu_single_env, "pl011_read: Bad offset %x\n", offset);
787: return 0;
788: }
789: }
790:
791: static void pl011_set_read_trigger(pl011_state *s)
792: {
793: #if 0
794: /* The docs say the RX interrupt is triggered when the FIFO exceeds
795: the threshold. However linux only reads the FIFO in response to an
796: interrupt. Triggering the interrupt when the FIFO is non-empty seems
797: to make things work. */
798: if (s->lcr & 0x10)
799: s->read_trigger = (s->ifl >> 1) & 0x1c;
800: else
801: #endif
802: s->read_trigger = 1;
803: }
804:
805: static void pl011_write(void *opaque, target_phys_addr_t offset,
806: uint32_t value)
807: {
808: pl011_state *s = (pl011_state *)opaque;
809: unsigned char ch;
810:
811: offset -= s->base;
812: switch (offset >> 2) {
813: case 0: /* UARTDR */
814: /* ??? Check if transmitter is enabled. */
815: ch = value;
816: if (s->chr)
817: qemu_chr_write(s->chr, &ch, 1);
818: s->int_level |= PL011_INT_TX;
819: pl011_update(s);
820: break;
821: case 1: /* UARTCR */
822: s->cr = value;
823: break;
824: case 8: /* UARTUARTILPR */
825: s->ilpr = value;
826: break;
827: case 9: /* UARTIBRD */
828: s->ibrd = value;
829: break;
830: case 10: /* UARTFBRD */
831: s->fbrd = value;
832: break;
833: case 11: /* UARTLCR_H */
834: s->lcr = value;
835: pl011_set_read_trigger(s);
836: break;
837: case 12: /* UARTCR */
838: /* ??? Need to implement the enable and loopback bits. */
839: s->cr = value;
840: break;
841: case 13: /* UARTIFS */
842: s->ifl = value;
843: pl011_set_read_trigger(s);
844: break;
845: case 14: /* UARTIMSC */
846: s->int_enabled = value;
847: pl011_update(s);
848: break;
849: case 17: /* UARTICR */
850: s->int_level &= ~value;
851: pl011_update(s);
852: break;
853: case 18: /* UARTDMACR */
854: s->dmacr = value;
855: if (value & 3)
856: cpu_abort(cpu_single_env, "PL011: DMA not implemented\n");
857: break;
858: default:
859: cpu_abort (cpu_single_env, "pl011_write: Bad offset %x\n", offset);
860: }
861: }
862:
863: static int pl011_can_recieve(void *opaque)
864: {
865: pl011_state *s = (pl011_state *)opaque;
866:
867: if (s->lcr & 0x10)
868: return s->read_count < 16;
869: else
870: return s->read_count < 1;
871: }
872:
873: static void pl011_recieve(void *opaque, const uint8_t *buf, int size)
874: {
875: pl011_state *s = (pl011_state *)opaque;
876: int slot;
877:
878: slot = s->read_pos + s->read_count;
879: if (slot >= 16)
880: slot -= 16;
881: s->read_fifo[slot] = *buf;
882: s->read_count++;
883: s->flags &= ~PL011_FLAG_RXFE;
884: if (s->cr & 0x10 || s->read_count == 16) {
885: s->flags |= PL011_FLAG_RXFF;
886: }
887: if (s->read_count == s->read_trigger) {
888: s->int_level |= PL011_INT_RX;
889: pl011_update(s);
890: }
891: }
892:
893: static void pl011_event(void *opaque, int event)
894: {
895: /* ??? Should probably implement break. */
896: }
897:
898: static CPUReadMemoryFunc *pl011_readfn[] = {
899: pl011_read,
900: pl011_read,
901: pl011_read
902: };
903:
904: static CPUWriteMemoryFunc *pl011_writefn[] = {
905: pl011_write,
906: pl011_write,
907: pl011_write
908: };
909:
910: static void pl011_init(uint32_t base, icp_pic_state *pic, int irq,
911: CharDriverState *chr)
912: {
913: int iomemtype;
914: pl011_state *s;
915:
916: s = (pl011_state *)qemu_mallocz(sizeof(pl011_state));
917: iomemtype = cpu_register_io_memory(0, pl011_readfn,
918: pl011_writefn, s);
919: cpu_register_physical_memory(base, 0x007fffff, iomemtype);
920: s->base = base;
921: s->pic = pic;
922: s->irq = irq;
923: s->chr = chr;
924: s->read_trigger = 1;
925: s->ifl = 0x12;
926: s->cr = 0x300;
927: s->flags = 0x90;
928: if (chr){
929: qemu_chr_add_read_handler(chr, pl011_can_recieve, pl011_recieve, s);
930: qemu_chr_add_event_handler(chr, pl011_event);
931: }
932: /* ??? Save/restore. */
933: }
934:
935: /* CP control registers. */
936: typedef struct {
937: uint32_t base;
938: } icp_control_state;
939:
940: static uint32_t icp_control_read(void *opaque, target_phys_addr_t offset)
941: {
942: icp_control_state *s = (icp_control_state *)opaque;
943: offset -= s->base;
944: switch (offset >> 2) {
945: case 0: /* CP_IDFIELD */
946: return 0x41034003;
947: case 1: /* CP_FLASHPROG */
948: return 0;
949: case 2: /* CP_INTREG */
950: return 0;
951: case 3: /* CP_DECODE */
952: return 0x11;
953: default:
954: cpu_abort (cpu_single_env, "icp_control_read: Bad offset %x\n", offset);
955: return 0;
956: }
957: }
958:
959: static void icp_control_write(void *opaque, target_phys_addr_t offset,
960: uint32_t value)
961: {
962: icp_control_state *s = (icp_control_state *)opaque;
963: offset -= s->base;
964: switch (offset >> 2) {
965: case 1: /* CP_FLASHPROG */
966: case 2: /* CP_INTREG */
967: case 3: /* CP_DECODE */
968: /* Nothing interesting implemented yet. */
969: break;
970: default:
971: cpu_abort (cpu_single_env, "icp_control_write: Bad offset %x\n", offset);
972: }
973: }
974: static CPUReadMemoryFunc *icp_control_readfn[] = {
975: icp_control_read,
976: icp_control_read,
977: icp_control_read
978: };
979:
980: static CPUWriteMemoryFunc *icp_control_writefn[] = {
981: icp_control_write,
982: icp_control_write,
983: icp_control_write
984: };
985:
986: static void icp_control_init(uint32_t base)
987: {
988: int iomemtype;
989: icp_control_state *s;
990:
991: s = (icp_control_state *)qemu_mallocz(sizeof(icp_control_state));
992: iomemtype = cpu_register_io_memory(0, icp_control_readfn,
993: icp_control_writefn, s);
994: cpu_register_physical_memory(base, 0x007fffff, iomemtype);
995: s->base = base;
996: /* ??? Save/restore. */
997: }
998:
999:
1000: /* Keyboard/Mouse Interface. */
1001:
1002: typedef struct {
1003: void *dev;
1004: uint32_t base;
1005: uint32_t cr;
1006: uint32_t clk;
1007: uint32_t last;
1008: icp_pic_state *pic;
1009: int pending;
1010: int irq;
1011: int is_mouse;
1012: } icp_kmi_state;
1013:
1014: static void icp_kmi_update(void *opaque, int level)
1015: {
1016: icp_kmi_state *s = (icp_kmi_state *)opaque;
1017: int raise;
1018:
1019: s->pending = level;
1020: raise = (s->pending && (s->cr & 0x10) != 0)
1021: || (s->cr & 0x08) != 0;
1022: pic_set_irq_new(s->pic, s->irq, raise);
1023: }
1024:
1025: static uint32_t icp_kmi_read(void *opaque, target_phys_addr_t offset)
1026: {
1027: icp_kmi_state *s = (icp_kmi_state *)opaque;
1028: offset -= s->base;
1029: if (offset >= 0xfe0 && offset < 0x1000)
1030: return 0;
1031:
1032: switch (offset >> 2) {
1033: case 0: /* KMICR */
1034: return s->cr;
1035: case 1: /* KMISTAT */
1036: /* KMIC and KMID bits not implemented. */
1037: if (s->pending) {
1038: return 0x10;
1039: } else {
1040: return 0;
1041: }
1042: case 2: /* KMIDATA */
1043: if (s->pending)
1044: s->last = ps2_read_data(s->dev);
1045: return s->last;
1046: case 3: /* KMICLKDIV */
1047: return s->clk;
1048: case 4: /* KMIIR */
1049: return s->pending | 2;
1050: default:
1051: cpu_abort (cpu_single_env, "icp_kmi_read: Bad offset %x\n", offset);
1052: return 0;
1053: }
1054: }
1055:
1056: static void icp_kmi_write(void *opaque, target_phys_addr_t offset,
1057: uint32_t value)
1058: {
1059: icp_kmi_state *s = (icp_kmi_state *)opaque;
1060: offset -= s->base;
1061: switch (offset >> 2) {
1062: case 0: /* KMICR */
1063: s->cr = value;
1064: icp_kmi_update(s, s->pending);
1065: /* ??? Need to implement the enable/disable bit. */
1066: break;
1067: case 2: /* KMIDATA */
1068: /* ??? This should toggle the TX interrupt line. */
1069: /* ??? This means kbd/mouse can block each other. */
1070: if (s->is_mouse) {
1071: ps2_write_mouse(s->dev, value);
1072: } else {
1073: ps2_write_keyboard(s->dev, value);
1074: }
1075: break;
1076: case 3: /* KMICLKDIV */
1077: s->clk = value;
1078: return;
1079: default:
1080: cpu_abort (cpu_single_env, "icp_kmi_write: Bad offset %x\n", offset);
1081: }
1082: }
1083: static CPUReadMemoryFunc *icp_kmi_readfn[] = {
1084: icp_kmi_read,
1085: icp_kmi_read,
1086: icp_kmi_read
1087: };
1088:
1089: static CPUWriteMemoryFunc *icp_kmi_writefn[] = {
1090: icp_kmi_write,
1091: icp_kmi_write,
1092: icp_kmi_write
1093: };
1094:
1095: static void icp_kmi_init(uint32_t base, icp_pic_state * pic, int irq,
1096: int is_mouse)
1097: {
1098: int iomemtype;
1099: icp_kmi_state *s;
1100:
1101: s = (icp_kmi_state *)qemu_mallocz(sizeof(icp_kmi_state));
1102: iomemtype = cpu_register_io_memory(0, icp_kmi_readfn,
1103: icp_kmi_writefn, s);
1104: cpu_register_physical_memory(base, 0x007fffff, iomemtype);
1105: s->base = base;
1106: s->pic = pic;
1107: s->irq = irq;
1108: s->is_mouse = is_mouse;
1109: if (is_mouse)
1110: s->dev = ps2_mouse_init(icp_kmi_update, s);
1111: else
1112: s->dev = ps2_kbd_init(icp_kmi_update, s);
1113: /* ??? Save/restore. */
1114: }
1115:
1116: /* The worlds second smallest bootloader. Set r0-r2, then jump to kernel. */
1117: static uint32_t bootloader[] = {
1118: 0xe3a00000, /* mov r0, #0 */
1119: 0xe3a01013, /* mov r1, #0x13 */
1120: 0xe3811c01, /* orr r1, r1, #0x100 */
1121: 0xe59f2000, /* ldr r2, [pc, #0] */
1122: 0xe59ff000, /* ldr pc, [pc, #0] */
1123: 0, /* Address of kernel args. Set by integratorcp_init. */
1124: 0 /* Kernel entry point. Set by integratorcp_init. */
1125: };
1126:
1127: static void set_kernel_args(uint32_t ram_size, int initrd_size,
1128: const char *kernel_cmdline)
1129: {
1130: uint32_t *p;
1131:
1132: p = (uint32_t *)(phys_ram_base + KERNEL_ARGS_ADDR);
1133: /* ATAG_CORE */
1134: *(p++) = 5;
1135: *(p++) = 0x54410001;
1136: *(p++) = 1;
1137: *(p++) = 0x1000;
1138: *(p++) = 0;
1139: /* ATAG_MEM */
1140: *(p++) = 4;
1141: *(p++) = 0x54410002;
1142: *(p++) = ram_size;
1143: *(p++) = 0;
1144: if (initrd_size) {
1145: /* ATAG_INITRD2 */
1146: *(p++) = 4;
1147: *(p++) = 0x54420005;
1148: *(p++) = INITRD_LOAD_ADDR;
1149: *(p++) = initrd_size;
1150: }
1151: if (kernel_cmdline && *kernel_cmdline) {
1152: /* ATAG_CMDLINE */
1153: int cmdline_size;
1154:
1155: cmdline_size = strlen(kernel_cmdline);
1156: memcpy (p + 2, kernel_cmdline, cmdline_size + 1);
1157: cmdline_size = (cmdline_size >> 2) + 1;
1158: *(p++) = cmdline_size + 2;
1159: *(p++) = 0x54410009;
1160: p += cmdline_size;
1161: }
1162: /* ATAG_END */
1163: *(p++) = 0;
1164: *(p++) = 0;
1165: }
1166:
1167: /* Board init. */
1168:
1169: static void integratorcp_init(int ram_size, int vga_ram_size, int boot_device,
1170: DisplayState *ds, const char **fd_filename, int snapshot,
1171: const char *kernel_filename, const char *kernel_cmdline,
1172: const char *initrd_filename)
1173: {
1174: CPUState *env;
1175: uint32_t bios_offset;
1176: icp_pic_state *pic;
1177: int kernel_size;
1178: int initrd_size;
1179:
1180: env = cpu_init();
1181: bios_offset = ram_size + vga_ram_size;
1182: /* ??? On a real system the first 1Mb is mapped as SSRAM or boot flash. */
1183: /* ??? RAM shoud repeat to fill physical memory space. */
1184: /* SDRAM at address zero*/
1185: cpu_register_physical_memory(0, ram_size, IO_MEM_RAM);
1186: /* And again at address 0x80000000 */
1187: cpu_register_physical_memory(0x80000000, ram_size, IO_MEM_RAM);
1188:
1189: integratorcm_init(ram_size >> 20, bios_offset);
1190: pic = icp_pic_init(0x14000000, env, -1);
1191: icp_pic_init(0xca000000, pic, 26);
1192: icp_pit_init(0x13000000, pic);
1193: pl011_init(0x16000000, pic, 1, serial_hds[0]);
1194: pl011_init(0x17000000, pic, 2, serial_hds[1]);
1195: icp_control_init(0xcb000000);
1196: icp_kmi_init(0x18000000, pic, 3, 0);
1197: icp_kmi_init(0x19000000, pic, 4, 1);
1198: if (nd_table[0].vlan)
1199: smc91c111_init(&nd_table[0], 0xc8000000, pic, 27);
1200:
1201: /* Load the kernel. */
1202: if (!kernel_filename) {
1203: fprintf(stderr, "Kernel image must be specified\n");
1204: exit(1);
1205: }
1206: kernel_size = load_image(kernel_filename,
1207: phys_ram_base + KERNEL_LOAD_ADDR);
1208: if (kernel_size < 0) {
1209: fprintf(stderr, "qemu: could not load kernel '%s'\n", kernel_filename);
1210: exit(1);
1211: }
1212: if (initrd_filename) {
1213: initrd_size = load_image(initrd_filename,
1214: phys_ram_base + INITRD_LOAD_ADDR);
1215: if (initrd_size < 0) {
1216: fprintf(stderr, "qemu: could not load initrd '%s'\n",
1217: initrd_filename);
1218: exit(1);
1219: }
1220: } else {
1221: initrd_size = 0;
1222: }
1223: bootloader[5] = KERNEL_ARGS_ADDR;
1224: bootloader[6] = KERNEL_LOAD_ADDR;
1225: memcpy(phys_ram_base, bootloader, sizeof(bootloader));
1226: set_kernel_args(ram_size, initrd_size, kernel_cmdline);
1227: }
1228:
1229: QEMUMachine integratorcp_machine = {
1230: "integratorcp",
1231: "ARM Integrator/CP",
1232: integratorcp_init,
1233: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.