|
|
1.1.1.4 ! root 1: /* 1.1 root 2: * ARM Integrator CP System emulation. 3: * 1.1.1.4 ! root 4: * Copyright (c) 2005-2007 CodeSourcery. 1.1 root 5: * Written by Paul Brook 6: * 7: * This code is licenced under the GPL 8: */ 9: 1.1.1.4 ! root 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" 1.1 root 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: /* CM_SPD */ 48: if (offset >= 0x180) 49: return 0; 50: return integrator_spd[offset >> 2]; 51: } 52: switch (offset >> 2) { 53: case 0: /* CM_ID */ 54: return 0x411a3001; 55: case 1: /* CM_PROC */ 56: return 0; 57: case 2: /* CM_OSC */ 58: return s->cm_osc; 59: case 3: /* CM_CTRL */ 60: return s->cm_ctrl; 61: case 4: /* CM_STAT */ 62: return 0x00100000; 63: case 5: /* CM_LOCK */ 64: if (s->cm_lock == 0xa05f) { 65: return 0x1a05f; 66: } else { 67: return s->cm_lock; 68: } 69: case 6: /* CM_LMBUSCNT */ 70: /* ??? High frequency timer. */ 71: cpu_abort(cpu_single_env, "integratorcm_read: CM_LMBUSCNT"); 72: case 7: /* CM_AUXOSC */ 73: return s->cm_auxosc; 74: case 8: /* CM_SDRAM */ 75: return s->cm_sdram; 76: case 9: /* CM_INIT */ 77: return s->cm_init; 78: case 10: /* CM_REFCT */ 79: /* ??? High frequency timer. */ 80: cpu_abort(cpu_single_env, "integratorcm_read: CM_REFCT"); 81: case 12: /* CM_FLAGS */ 82: return s->cm_flags; 83: case 14: /* CM_NVFLAGS */ 84: return s->cm_nvflags; 85: case 16: /* CM_IRQ_STAT */ 86: return s->int_level & s->irq_enabled; 87: case 17: /* CM_IRQ_RSTAT */ 88: return s->int_level; 89: case 18: /* CM_IRQ_ENSET */ 90: return s->irq_enabled; 91: case 20: /* CM_SOFT_INTSET */ 92: return s->int_level & 1; 93: case 24: /* CM_FIQ_STAT */ 94: return s->int_level & s->fiq_enabled; 95: case 25: /* CM_FIQ_RSTAT */ 96: return s->int_level; 97: case 26: /* CM_FIQ_ENSET */ 98: return s->fiq_enabled; 99: case 32: /* CM_VOLTAGE_CTL0 */ 100: case 33: /* CM_VOLTAGE_CTL1 */ 101: case 34: /* CM_VOLTAGE_CTL2 */ 102: case 35: /* CM_VOLTAGE_CTL3 */ 103: /* ??? Voltage control unimplemented. */ 104: return 0; 105: default: 106: cpu_abort (cpu_single_env, 1.1.1.4 ! root 107: "integratorcm_read: Unimplemented offset 0x%x\n", (int)offset); 1.1 root 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: //??? tlb_flush (cpu_single_env, 1); 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: /* ??? The CPU irq/fiq is raised when either the core module or base PIC 139: are active. */ 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: /* CM_OSC */ 151: if (s->cm_lock == 0xa05f) 152: s->cm_osc = value; 153: break; 154: case 3: /* CM_CTRL */ 155: integratorcm_set_ctrl(s, value); 156: break; 157: case 5: /* CM_LOCK */ 158: s->cm_lock = value & 0xffff; 159: break; 160: case 7: /* CM_AUXOSC */ 161: if (s->cm_lock == 0xa05f) 162: s->cm_auxosc = value; 163: break; 164: case 8: /* CM_SDRAM */ 165: s->cm_sdram = value; 166: break; 167: case 9: /* CM_INIT */ 168: /* ??? This can change the memory bus frequency. */ 169: s->cm_init = value; 170: break; 171: case 12: /* CM_FLAGSS */ 172: s->cm_flags |= value; 173: break; 174: case 13: /* CM_FLAGSC */ 175: s->cm_flags &= ~value; 176: break; 177: case 14: /* CM_NVFLAGSS */ 178: s->cm_nvflags |= value; 179: break; 180: case 15: /* CM_NVFLAGSS */ 181: s->cm_nvflags &= ~value; 182: break; 183: case 18: /* CM_IRQ_ENSET */ 184: s->irq_enabled |= value; 185: integratorcm_update(s); 186: break; 187: case 19: /* CM_IRQ_ENCLR */ 188: s->irq_enabled &= ~value; 189: integratorcm_update(s); 190: break; 191: case 20: /* CM_SOFT_INTSET */ 192: s->int_level |= (value & 1); 193: integratorcm_update(s); 194: break; 195: case 21: /* CM_SOFT_INTCLR */ 196: s->int_level &= ~(value & 1); 197: integratorcm_update(s); 198: break; 199: case 26: /* CM_FIQ_ENSET */ 200: s->fiq_enabled |= value; 201: integratorcm_update(s); 202: break; 203: case 27: /* CM_FIQ_ENCLR */ 204: s->fiq_enabled &= ~value; 205: integratorcm_update(s); 206: break; 207: case 32: /* CM_VOLTAGE_CTL0 */ 208: case 33: /* CM_VOLTAGE_CTL1 */ 209: case 34: /* CM_VOLTAGE_CTL2 */ 210: case 35: /* CM_VOLTAGE_CTL3 */ 211: /* ??? Voltage control unimplemented. */ 212: break; 213: default: 214: cpu_abort (cpu_single_env, 1.1.1.4 ! root 215: "integratorcm_write: Unimplemented offset 0x%x\n", (int)offset); 1.1 root 216: break; 217: } 218: } 219: 220: /* Integrator/CM control registers. */ 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: /* ??? What should the high bits of this value be? */ 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); 1.1.1.4 ! root 265: cpu_register_physical_memory(0x10000000, 0x00800000, iomemtype); 1.1 root 266: integratorcm_do_remap(s, 1); 267: /* ??? Save/restore. */ 268: } 269: 270: /* Integrator/CP hardware emulation. */ 271: /* Primary interrupt controller. */ 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; 1.1.1.4 ! root 279: qemu_irq parent_irq; ! 280: qemu_irq parent_fiq; 1.1 root 281: } icp_pic_state; 282: 283: static void icp_pic_update(icp_pic_state *s) 284: { 1.1.1.2 root 285: uint32_t flags; 1.1 root 286: 1.1.1.4 ! root 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); 1.1 root 291: } 292: 1.1.1.2 root 293: static void icp_pic_set_irq(void *opaque, int irq, int level) 1.1 root 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: /* IRQ_STATUS */ 310: return s->level & s->irq_enabled; 311: case 1: /* IRQ_RAWSTAT */ 312: return s->level; 313: case 2: /* IRQ_ENABLESET */ 314: return s->irq_enabled; 315: case 4: /* INT_SOFTSET */ 316: return s->level & 1; 317: case 8: /* FRQ_STATUS */ 318: return s->level & s->fiq_enabled; 319: case 9: /* FRQ_RAWSTAT */ 320: return s->level; 321: case 10: /* FRQ_ENABLESET */ 322: return s->fiq_enabled; 323: case 3: /* IRQ_ENABLECLR */ 324: case 5: /* INT_SOFTCLR */ 325: case 11: /* FRQ_ENABLECLR */ 326: default: 1.1.1.3 root 327: printf ("icp_pic_read: Bad register offset 0x%x\n", (int)offset); 1.1 root 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: /* IRQ_ENABLESET */ 340: s->irq_enabled |= value; 341: break; 342: case 3: /* IRQ_ENABLECLR */ 343: s->irq_enabled &= ~value; 344: break; 345: case 4: /* INT_SOFTSET */ 346: if (value & 1) 1.1.1.4 ! root 347: icp_pic_set_irq(s, 0, 1); 1.1 root 348: break; 349: case 5: /* INT_SOFTCLR */ 350: if (value & 1) 1.1.1.4 ! root 351: icp_pic_set_irq(s, 0, 0); 1.1 root 352: break; 353: case 10: /* FRQ_ENABLESET */ 354: s->fiq_enabled |= value; 355: break; 356: case 11: /* FRQ_ENABLECLR */ 357: s->fiq_enabled &= ~value; 358: break; 359: case 0: /* IRQ_STATUS */ 360: case 1: /* IRQ_RAWSTAT */ 361: case 8: /* FRQ_STATUS */ 362: case 9: /* FRQ_RAWSTAT */ 363: default: 1.1.1.3 root 364: printf ("icp_pic_write: Bad register offset 0x%x\n", (int)offset); 1.1 root 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: 1.1.1.4 ! root 382: static qemu_irq *icp_pic_init(uint32_t base, ! 383: qemu_irq parent_irq, qemu_irq parent_fiq) 1.1 root 384: { 385: icp_pic_state *s; 386: int iomemtype; 1.1.1.4 ! root 387: qemu_irq *qi; 1.1 root 388: 389: s = (icp_pic_state *)qemu_mallocz(sizeof(icp_pic_state)); 390: if (!s) 391: return NULL; 1.1.1.4 ! root 392: qi = qemu_allocate_irqs(icp_pic_set_irq, s, 32); 1.1 root 393: s->base = base; 394: s->parent_irq = parent_irq; 1.1.1.2 root 395: s->parent_fiq = parent_fiq; 1.1 root 396: iomemtype = cpu_register_io_memory(0, icp_pic_readfn, 397: icp_pic_writefn, s); 1.1.1.4 ! root 398: cpu_register_physical_memory(base, 0x00800000, iomemtype); 1.1 root 399: /* ??? Save/restore. */ 1.1.1.4 ! root 400: return qi; 1.1 root 401: } 402: 403: /* CP control registers. */ 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: /* 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: 1.1.1.4 ! root 422: cpu_abort (cpu_single_env, "icp_control_read: Bad offset %x\n", ! 423: (int)offset); 1.1 root 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: /* CP_FLASHPROG */ 435: case 2: /* CP_INTREG */ 436: case 3: /* CP_DECODE */ 437: /* Nothing interesting implemented yet. */ 438: break; 439: default: 1.1.1.4 ! root 440: cpu_abort (cpu_single_env, "icp_control_write: Bad offset %x\n", ! 441: (int)offset); 1.1 root 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); 1.1.1.4 ! root 464: cpu_register_physical_memory(base, 0x00800000, iomemtype); 1.1 root 465: s->base = base; 466: /* ??? Save/restore. */ 467: } 468: 469: 470: /* Board init. */ 471: 1.1.1.4 ! root 472: static void integratorcp_init(int ram_size, int vga_ram_size, ! 473: const char *boot_device, DisplayState *ds, 1.1 root 474: const char *kernel_filename, const char *kernel_cmdline, 1.1.1.4 ! root 475: const char *initrd_filename, const char *cpu_model) 1.1 root 476: { 477: CPUState *env; 478: uint32_t bios_offset; 1.1.1.4 ! root 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: } 1.1 root 490: bios_offset = ram_size + vga_ram_size; 491: /* ??? On a real system the first 1Mb is mapped as SSRAM or boot flash. */ 492: /* ??? RAM shoud repeat to fill physical memory space. */ 493: /* SDRAM at address zero*/ 494: cpu_register_physical_memory(0, ram_size, IO_MEM_RAM); 495: /* And again at address 0x80000000 */ 496: cpu_register_physical_memory(0x80000000, ram_size, IO_MEM_RAM); 497: 498: integratorcm_init(ram_size >> 20, bios_offset); 1.1.1.2 root 499: cpu_pic = arm_pic_init_cpu(env); 1.1.1.4 ! root 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); 1.1.1.2 root 503: icp_pit_init(0x13000000, pic, 5); 1.1.1.4 ! root 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); 1.1 root 507: icp_control_init(0xcb000000); 1.1.1.4 ! root 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]); 1.1.1.2 root 516: if (nd_table[0].vlan) { 517: if (nd_table[0].model == NULL 518: || strcmp(nd_table[0].model, "smc91c111") == 0) { 1.1.1.4 ! root 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); 1.1.1.2 root 523: } else { 524: fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd_table[0].model); 525: exit (1); 1.1 root 526: } 527: } 1.1.1.4 ! root 528: pl110_init(ds, 0xc0000000, pic[22], 0); 1.1.1.2 root 529: 1.1.1.3 root 530: arm_load_kernel(env, ram_size, kernel_filename, kernel_cmdline, 1.1.1.4 ! root 531: initrd_filename, 0x113, 0x0); 1.1.1.2 root 532: } 533: 1.1.1.4 ! root 534: QEMUMachine integratorcp_machine = { ! 535: "integratorcp", 1.1.1.2 root 536: "ARM Integrator/CP (ARM926EJ-S)", 1.1.1.4 ! root 537: integratorcp_init, 1.1 root 538: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.