1:
2:
3:
4:
5:
6:
7:
8:
9:
10: #include "hw.h"
11: #include "primecell.h"
12: #include "devices.h"
13: #include "sysemu.h"
14: #include "boards.h"
15: #include "arm-misc.h"
16: #include "net.h"
17:
18: void DMA_run (void)
19: {
20: }
21:
22: typedef struct {
23: uint32_t flash_offset;
24: uint32_t cm_osc;
25: uint32_t cm_ctrl;
26: uint32_t cm_lock;
27: uint32_t cm_auxosc;
28: uint32_t cm_sdram;
29: uint32_t cm_init;
30: uint32_t cm_flags;
31: uint32_t cm_nvflags;
32: uint32_t int_level;
33: uint32_t irq_enabled;
34: uint32_t fiq_enabled;
35: } integratorcm_state;
36:
37: static uint8_t integrator_spd[128] = {
38: 128, 8, 4, 11, 9, 1, 64, 0, 2, 0xa0, 0xa0, 0, 0, 8, 0, 1,
39: 0xe, 4, 0x1c, 1, 2, 0x20, 0xc0, 0, 0, 0, 0, 0x30, 0x28, 0x30, 0x28, 0x40
40: };
41:
42: static uint32_t integratorcm_read(void *opaque, target_phys_addr_t offset)
43: {
44: integratorcm_state *s = (integratorcm_state *)opaque;
45: offset -= 0x10000000;
46: if (offset >= 0x100 && offset < 0x200) {
47:
48: if (offset >= 0x180)
49: return 0;
50: return integrator_spd[offset >> 2];
51: }
52: switch (offset >> 2) {
53: case 0:
54: return 0x411a3001;
55: case 1:
56: return 0;
57: case 2:
58: return s->cm_osc;
59: case 3:
60: return s->cm_ctrl;
61: case 4:
62: return 0x00100000;
63: case 5:
64: if (s->cm_lock == 0xa05f) {
65: return 0x1a05f;
66: } else {
67: return s->cm_lock;
68: }
69: case 6:
70:
71: cpu_abort(cpu_single_env, "integratorcm_read: CM_LMBUSCNT");
72: case 7:
73: return s->cm_auxosc;
74: case 8:
75: return s->cm_sdram;
76: case 9:
77: return s->cm_init;
78: case 10:
79:
80: cpu_abort(cpu_single_env, "integratorcm_read: CM_REFCT");
81: case 12:
82: return s->cm_flags;
83: case 14:
84: return s->cm_nvflags;
85: case 16:
86: return s->int_level & s->irq_enabled;
87: case 17:
88: return s->int_level;
89: case 18:
90: return s->irq_enabled;
91: case 20:
92: return s->int_level & 1;
93: case 24:
94: return s->int_level & s->fiq_enabled;
95: case 25:
96: return s->int_level;
97: case 26:
98: return s->fiq_enabled;
99: case 32:
100: case 33:
101: case 34:
102: case 35:
103:
104: return 0;
105: default:
106: cpu_abort (cpu_single_env,
107: "integratorcm_read: Unimplemented offset 0x%x\n", (int)offset);
108: return 0;
109: }
110: }
111:
112: static void integratorcm_do_remap(integratorcm_state *s, int flash)
113: {
114: if (flash) {
115: cpu_register_physical_memory(0, 0x100000, IO_MEM_RAM);
116: } else {
117: cpu_register_physical_memory(0, 0x100000, s->flash_offset | IO_MEM_RAM);
118: }
119:
120: }
121:
122: static void integratorcm_set_ctrl(integratorcm_state *s, uint32_t value)
123: {
124: if (value & 8) {
125: cpu_abort(cpu_single_env, "Board reset\n");
126: }
127: if ((s->cm_init ^ value) & 4) {
128: integratorcm_do_remap(s, (value & 4) == 0);
129: }
130: if ((s->cm_init ^ value) & 1) {
131: printf("Green LED %s\n", (value & 1) ? "on" : "off");
132: }
133: s->cm_init = (s->cm_init & ~ 5) | (value ^ 5);
134: }
135:
136: static void integratorcm_update(integratorcm_state *s)
137: {
138:
139:
140: if (s->int_level & (s->irq_enabled | s->fiq_enabled))
141: cpu_abort(cpu_single_env, "Core module interrupt\n");
142: }
143:
144: static void integratorcm_write(void *opaque, target_phys_addr_t offset,
145: uint32_t value)
146: {
147: integratorcm_state *s = (integratorcm_state *)opaque;
148: offset -= 0x10000000;
149: switch (offset >> 2) {
150: case 2:
151: if (s->cm_lock == 0xa05f)
152: s->cm_osc = value;
153: break;
154: case 3:
155: integratorcm_set_ctrl(s, value);
156: break;
157: case 5:
158: s->cm_lock = value & 0xffff;
159: break;
160: case 7:
161: if (s->cm_lock == 0xa05f)
162: s->cm_auxosc = value;
163: break;
164: case 8:
165: s->cm_sdram = value;
166: break;
167: case 9:
168:
169: s->cm_init = value;
170: break;
171: case 12:
172: s->cm_flags |= value;
173: break;
174: case 13:
175: s->cm_flags &= ~value;
176: break;
177: case 14:
178: s->cm_nvflags |= value;
179: break;
180: case 15:
181: s->cm_nvflags &= ~value;
182: break;
183: case 18:
184: s->irq_enabled |= value;
185: integratorcm_update(s);
186: break;
187: case 19:
188: s->irq_enabled &= ~value;
189: integratorcm_update(s);
190: break;
191: case 20:
192: s->int_level |= (value & 1);
193: integratorcm_update(s);
194: break;
195: case 21:
196: s->int_level &= ~(value & 1);
197: integratorcm_update(s);
198: break;
199: case 26:
200: s->fiq_enabled |= value;
201: integratorcm_update(s);
202: break;
203: case 27:
204: s->fiq_enabled &= ~value;
205: integratorcm_update(s);
206: break;
207: case 32:
208: case 33:
209: case 34:
210: case 35:
211:
212: break;
213: default:
214: cpu_abort (cpu_single_env,
215: "integratorcm_write: Unimplemented offset 0x%x\n", (int)offset);
216: break;
217: }
218: }
219:
220:
221:
222: static CPUReadMemoryFunc *integratorcm_readfn[] = {
223: integratorcm_read,
224: integratorcm_read,
225: integratorcm_read
226: };
227:
228: static CPUWriteMemoryFunc *integratorcm_writefn[] = {
229: integratorcm_write,
230: integratorcm_write,
231: integratorcm_write
232: };
233:
234: static void integratorcm_init(int memsz, uint32_t flash_offset)
235: {
236: int iomemtype;
237: integratorcm_state *s;
238:
239: s = (integratorcm_state *)qemu_mallocz(sizeof(integratorcm_state));
240: s->cm_osc = 0x01000048;
241:
242: s->cm_auxosc = 0x0007feff;
243: s->cm_sdram = 0x00011122;
244: if (memsz >= 256) {
245: integrator_spd[31] = 64;
246: s->cm_sdram |= 0x10;
247: } else if (memsz >= 128) {
248: integrator_spd[31] = 32;
249: s->cm_sdram |= 0x0c;
250: } else if (memsz >= 64) {
251: integrator_spd[31] = 16;
252: s->cm_sdram |= 0x08;
253: } else if (memsz >= 32) {
254: integrator_spd[31] = 4;
255: s->cm_sdram |= 0x04;
256: } else {
257: integrator_spd[31] = 2;
258: }
259: memcpy(integrator_spd + 73, "QEMU-MEMORY", 11);
260: s->cm_init = 0x00000112;
261: s->flash_offset = flash_offset;
262:
263: iomemtype = cpu_register_io_memory(0, integratorcm_readfn,
264: integratorcm_writefn, s);
265: cpu_register_physical_memory(0x10000000, 0x00800000, iomemtype);
266: integratorcm_do_remap(s, 1);
267:
268: }
269:
270:
271:
272:
273: typedef struct icp_pic_state
274: {
275: uint32_t base;
276: uint32_t level;
277: uint32_t irq_enabled;
278: uint32_t fiq_enabled;
279: qemu_irq parent_irq;
280: qemu_irq parent_fiq;
281: } icp_pic_state;
282:
283: static void icp_pic_update(icp_pic_state *s)
284: {
285: uint32_t flags;
286:
287: flags = (s->level & s->irq_enabled);
288: qemu_set_irq(s->parent_irq, flags != 0);
289: flags = (s->level & s->fiq_enabled);
290: qemu_set_irq(s->parent_fiq, flags != 0);
291: }
292:
293: static void icp_pic_set_irq(void *opaque, int irq, int level)
294: {
295: icp_pic_state *s = (icp_pic_state *)opaque;
296: if (level)
297: s->level |= 1 << irq;
298: else
299: s->level &= ~(1 << irq);
300: icp_pic_update(s);
301: }
302:
303: static uint32_t icp_pic_read(void *opaque, target_phys_addr_t offset)
304: {
305: icp_pic_state *s = (icp_pic_state *)opaque;
306:
307: offset -= s->base;
308: switch (offset >> 2) {
309: case 0:
310: return s->level & s->irq_enabled;
311: case 1:
312: return s->level;
313: case 2:
314: return s->irq_enabled;
315: case 4:
316: return s->level & 1;
317: case 8:
318: return s->level & s->fiq_enabled;
319: case 9:
320: return s->level;
321: case 10:
322: return s->fiq_enabled;
323: case 3:
324: case 5:
325: case 11:
326: default:
327: printf ("icp_pic_read: Bad register offset 0x%x\n", (int)offset);
328: return 0;
329: }
330: }
331:
332: static void icp_pic_write(void *opaque, target_phys_addr_t offset,
333: uint32_t value)
334: {
335: icp_pic_state *s = (icp_pic_state *)opaque;
336: offset -= s->base;
337:
338: switch (offset >> 2) {
339: case 2:
340: s->irq_enabled |= value;
341: break;
342: case 3:
343: s->irq_enabled &= ~value;
344: break;
345: case 4:
346: if (value & 1)
347: icp_pic_set_irq(s, 0, 1);
348: break;
349: case 5:
350: if (value & 1)
351: icp_pic_set_irq(s, 0, 0);
352: break;
353: case 10:
354: s->fiq_enabled |= value;
355: break;
356: case 11:
357: s->fiq_enabled &= ~value;
358: break;
359: case 0:
360: case 1:
361: case 8:
362: case 9:
363: default:
364: printf ("icp_pic_write: Bad register offset 0x%x\n", (int)offset);
365: return;
366: }
367: icp_pic_update(s);
368: }
369:
370: static CPUReadMemoryFunc *icp_pic_readfn[] = {
371: icp_pic_read,
372: icp_pic_read,
373: icp_pic_read
374: };
375:
376: static CPUWriteMemoryFunc *icp_pic_writefn[] = {
377: icp_pic_write,
378: icp_pic_write,
379: icp_pic_write
380: };
381:
382: static qemu_irq *icp_pic_init(uint32_t base,
383: qemu_irq parent_irq, qemu_irq parent_fiq)
384: {
385: icp_pic_state *s;
386: int iomemtype;
387: qemu_irq *qi;
388:
389: s = (icp_pic_state *)qemu_mallocz(sizeof(icp_pic_state));
390: if (!s)
391: return NULL;
392: qi = qemu_allocate_irqs(icp_pic_set_irq, s, 32);
393: s->base = base;
394: s->parent_irq = parent_irq;
395: s->parent_fiq = parent_fiq;
396: iomemtype = cpu_register_io_memory(0, icp_pic_readfn,
397: icp_pic_writefn, s);
398: cpu_register_physical_memory(base, 0x00800000, iomemtype);
399:
400: return qi;
401: }
402:
403:
404: typedef struct {
405: uint32_t base;
406: } icp_control_state;
407:
408: static uint32_t icp_control_read(void *opaque, target_phys_addr_t offset)
409: {
410: icp_control_state *s = (icp_control_state *)opaque;
411: offset -= s->base;
412: switch (offset >> 2) {
413: case 0:
414: return 0x41034003;
415: case 1:
416: return 0;
417: case 2:
418: return 0;
419: case 3:
420: return 0x11;
421: default:
422: cpu_abort (cpu_single_env, "icp_control_read: Bad offset %x\n",
423: (int)offset);
424: return 0;
425: }
426: }
427:
428: static void icp_control_write(void *opaque, target_phys_addr_t offset,
429: uint32_t value)
430: {
431: icp_control_state *s = (icp_control_state *)opaque;
432: offset -= s->base;
433: switch (offset >> 2) {
434: case 1:
435: case 2:
436: case 3:
437:
438: break;
439: default:
440: cpu_abort (cpu_single_env, "icp_control_write: Bad offset %x\n",
441: (int)offset);
442: }
443: }
444: static CPUReadMemoryFunc *icp_control_readfn[] = {
445: icp_control_read,
446: icp_control_read,
447: icp_control_read
448: };
449:
450: static CPUWriteMemoryFunc *icp_control_writefn[] = {
451: icp_control_write,
452: icp_control_write,
453: icp_control_write
454: };
455:
456: static void icp_control_init(uint32_t base)
457: {
458: int iomemtype;
459: icp_control_state *s;
460:
461: s = (icp_control_state *)qemu_mallocz(sizeof(icp_control_state));
462: iomemtype = cpu_register_io_memory(0, icp_control_readfn,
463: icp_control_writefn, s);
464: cpu_register_physical_memory(base, 0x00800000, iomemtype);
465: s->base = base;
466:
467: }
468:
469:
470:
471:
472: static void integratorcp_init(int ram_size, int vga_ram_size,
473: const char *boot_device, DisplayState *ds,
474: const char *kernel_filename, const char *kernel_cmdline,
475: const char *initrd_filename, const char *cpu_model)
476: {
477: CPUState *env;
478: uint32_t bios_offset;
479: qemu_irq *pic;
480: qemu_irq *cpu_pic;
481: int sd;
482:
483: if (!cpu_model)
484: cpu_model = "arm926";
485: env = cpu_init(cpu_model);
486: if (!env) {
487: fprintf(stderr, "Unable to find CPU definition\n");
488: exit(1);
489: }
490: bios_offset = ram_size + vga_ram_size;
491:
492:
493:
494: cpu_register_physical_memory(0, ram_size, IO_MEM_RAM);
495:
496: cpu_register_physical_memory(0x80000000, ram_size, IO_MEM_RAM);
497:
498: integratorcm_init(ram_size >> 20, bios_offset);
499: cpu_pic = arm_pic_init_cpu(env);
500: pic = icp_pic_init(0x14000000, cpu_pic[ARM_PIC_CPU_IRQ],
501: cpu_pic[ARM_PIC_CPU_FIQ]);
502: icp_pic_init(0xca000000, pic[26], NULL);
503: icp_pit_init(0x13000000, pic, 5);
504: pl031_init(0x15000000, pic[8]);
505: pl011_init(0x16000000, pic[1], serial_hds[0], PL011_ARM);
506: pl011_init(0x17000000, pic[2], serial_hds[1], PL011_ARM);
507: icp_control_init(0xcb000000);
508: pl050_init(0x18000000, pic[3], 0);
509: pl050_init(0x19000000, pic[4], 1);
510: sd = drive_get_index(IF_SD, 0, 0);
511: if (sd == -1) {
512: fprintf(stderr, "qemu: missing SecureDigital card\n");
513: exit(1);
514: }
515: pl181_init(0x1c000000, drives_table[sd].bdrv, pic[23], pic[24]);
516: if (nd_table[0].vlan) {
517: if (nd_table[0].model == NULL
518: || strcmp(nd_table[0].model, "smc91c111") == 0) {
519: smc91c111_init(&nd_table[0], 0xc8000000, pic[27]);
520: } else if (strcmp(nd_table[0].model, "?") == 0) {
521: fprintf(stderr, "qemu: Supported NICs: smc91c111\n");
522: exit (1);
523: } else {
524: fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd_table[0].model);
525: exit (1);
526: }
527: }
528: pl110_init(ds, 0xc0000000, pic[22], 0);
529:
530: arm_load_kernel(env, ram_size, kernel_filename, kernel_cmdline,
531: initrd_filename, 0x113, 0x0);
532: }
533:
534: QEMUMachine integratorcp_machine = {
535: "integratorcp",
536: "ARM Integrator/CP (ARM926EJ-S)",
537: integratorcp_init,
538: };