|
|
1.1 root 1: /* 1.1.1.2 ! root 2: * Luminary Micro Stellaris peripherals 1.1 root 3: * 4: * Copyright (c) 2006 CodeSourcery. 5: * Written by Paul Brook 6: * 7: * This code is licenced under the GPL. 8: */ 9: 10: #include "hw.h" 11: #include "arm-misc.h" 12: #include "primecell.h" 13: #include "devices.h" 14: #include "qemu-timer.h" 15: #include "i2c.h" 16: #include "net.h" 17: #include "sd.h" 18: #include "sysemu.h" 19: #include "boards.h" 20: 21: #define GPIO_A 0 22: #define GPIO_B 1 23: #define GPIO_C 2 24: #define GPIO_D 3 25: #define GPIO_E 4 26: #define GPIO_F 5 27: #define GPIO_G 6 28: 29: #define BP_OLED_I2C 0x01 30: #define BP_OLED_SSI 0x02 31: #define BP_GAMEPAD 0x04 32: 33: typedef const struct { 34: const char *name; 35: uint32_t did0; 36: uint32_t did1; 37: uint32_t dc0; 38: uint32_t dc1; 39: uint32_t dc2; 40: uint32_t dc3; 41: uint32_t dc4; 42: uint32_t peripherals; 43: } stellaris_board_info; 44: 45: /* General purpose timer module. */ 46: 47: typedef struct gptm_state { 48: uint32_t config; 49: uint32_t mode[2]; 50: uint32_t control; 51: uint32_t state; 52: uint32_t mask; 53: uint32_t load[2]; 54: uint32_t match[2]; 55: uint32_t prescale[2]; 56: uint32_t match_prescale[2]; 57: uint32_t rtc; 58: int64_t tick[2]; 59: struct gptm_state *opaque[2]; 60: QEMUTimer *timer[2]; 61: /* The timers have an alternate output used to trigger the ADC. */ 62: qemu_irq trigger; 63: qemu_irq irq; 64: } gptm_state; 65: 66: static void gptm_update_irq(gptm_state *s) 67: { 68: int level; 69: level = (s->state & s->mask) != 0; 70: qemu_set_irq(s->irq, level); 71: } 72: 73: static void gptm_stop(gptm_state *s, int n) 74: { 75: qemu_del_timer(s->timer[n]); 76: } 77: 78: static void gptm_reload(gptm_state *s, int n, int reset) 79: { 80: int64_t tick; 81: if (reset) 82: tick = qemu_get_clock(vm_clock); 83: else 84: tick = s->tick[n]; 85: 86: if (s->config == 0) { 87: /* 32-bit CountDown. */ 88: uint32_t count; 89: count = s->load[0] | (s->load[1] << 16); 90: tick += (int64_t)count * system_clock_scale; 91: } else if (s->config == 1) { 92: /* 32-bit RTC. 1Hz tick. */ 93: tick += ticks_per_sec; 94: } else if (s->mode[n] == 0xa) { 95: /* PWM mode. Not implemented. */ 96: } else { 97: cpu_abort(cpu_single_env, "TODO: 16-bit timer mode 0x%x\n", 98: s->mode[n]); 99: } 100: s->tick[n] = tick; 101: qemu_mod_timer(s->timer[n], tick); 102: } 103: 104: static void gptm_tick(void *opaque) 105: { 106: gptm_state **p = (gptm_state **)opaque; 107: gptm_state *s; 108: int n; 109: 110: s = *p; 111: n = p - s->opaque; 112: if (s->config == 0) { 113: s->state |= 1; 114: if ((s->control & 0x20)) { 115: /* Output trigger. */ 116: qemu_irq_raise(s->trigger); 117: qemu_irq_lower(s->trigger); 118: } 119: if (s->mode[0] & 1) { 120: /* One-shot. */ 121: s->control &= ~1; 122: } else { 123: /* Periodic. */ 124: gptm_reload(s, 0, 0); 125: } 126: } else if (s->config == 1) { 127: /* RTC. */ 128: uint32_t match; 129: s->rtc++; 130: match = s->match[0] | (s->match[1] << 16); 131: if (s->rtc > match) 132: s->rtc = 0; 133: if (s->rtc == 0) { 134: s->state |= 8; 135: } 136: gptm_reload(s, 0, 0); 137: } else if (s->mode[n] == 0xa) { 138: /* PWM mode. Not implemented. */ 139: } else { 140: cpu_abort(cpu_single_env, "TODO: 16-bit timer mode 0x%x\n", 141: s->mode[n]); 142: } 143: gptm_update_irq(s); 144: } 145: 146: static uint32_t gptm_read(void *opaque, target_phys_addr_t offset) 147: { 148: gptm_state *s = (gptm_state *)opaque; 149: 150: switch (offset) { 151: case 0x00: /* CFG */ 152: return s->config; 153: case 0x04: /* TAMR */ 154: return s->mode[0]; 155: case 0x08: /* TBMR */ 156: return s->mode[1]; 157: case 0x0c: /* CTL */ 158: return s->control; 159: case 0x18: /* IMR */ 160: return s->mask; 161: case 0x1c: /* RIS */ 162: return s->state; 163: case 0x20: /* MIS */ 164: return s->state & s->mask; 165: case 0x24: /* CR */ 166: return 0; 167: case 0x28: /* TAILR */ 168: return s->load[0] | ((s->config < 4) ? (s->load[1] << 16) : 0); 169: case 0x2c: /* TBILR */ 170: return s->load[1]; 171: case 0x30: /* TAMARCHR */ 172: return s->match[0] | ((s->config < 4) ? (s->match[1] << 16) : 0); 173: case 0x34: /* TBMATCHR */ 174: return s->match[1]; 175: case 0x38: /* TAPR */ 176: return s->prescale[0]; 177: case 0x3c: /* TBPR */ 178: return s->prescale[1]; 179: case 0x40: /* TAPMR */ 180: return s->match_prescale[0]; 181: case 0x44: /* TBPMR */ 182: return s->match_prescale[1]; 183: case 0x48: /* TAR */ 184: if (s->control == 1) 185: return s->rtc; 186: case 0x4c: /* TBR */ 187: cpu_abort(cpu_single_env, "TODO: Timer value read\n"); 188: default: 189: cpu_abort(cpu_single_env, "gptm_read: Bad offset 0x%x\n", (int)offset); 190: return 0; 191: } 192: } 193: 194: static void gptm_write(void *opaque, target_phys_addr_t offset, uint32_t value) 195: { 196: gptm_state *s = (gptm_state *)opaque; 197: uint32_t oldval; 198: 199: /* The timers should be disabled before changing the configuration. 200: We take advantage of this and defer everything until the timer 201: is enabled. */ 202: switch (offset) { 203: case 0x00: /* CFG */ 204: s->config = value; 205: break; 206: case 0x04: /* TAMR */ 207: s->mode[0] = value; 208: break; 209: case 0x08: /* TBMR */ 210: s->mode[1] = value; 211: break; 212: case 0x0c: /* CTL */ 213: oldval = s->control; 214: s->control = value; 215: /* TODO: Implement pause. */ 216: if ((oldval ^ value) & 1) { 217: if (value & 1) { 218: gptm_reload(s, 0, 1); 219: } else { 220: gptm_stop(s, 0); 221: } 222: } 223: if (((oldval ^ value) & 0x100) && s->config >= 4) { 224: if (value & 0x100) { 225: gptm_reload(s, 1, 1); 226: } else { 227: gptm_stop(s, 1); 228: } 229: } 230: break; 231: case 0x18: /* IMR */ 232: s->mask = value & 0x77; 233: gptm_update_irq(s); 234: break; 235: case 0x24: /* CR */ 236: s->state &= ~value; 237: break; 238: case 0x28: /* TAILR */ 239: s->load[0] = value & 0xffff; 240: if (s->config < 4) { 241: s->load[1] = value >> 16; 242: } 243: break; 244: case 0x2c: /* TBILR */ 245: s->load[1] = value & 0xffff; 246: break; 247: case 0x30: /* TAMARCHR */ 248: s->match[0] = value & 0xffff; 249: if (s->config < 4) { 250: s->match[1] = value >> 16; 251: } 252: break; 253: case 0x34: /* TBMATCHR */ 254: s->match[1] = value >> 16; 255: break; 256: case 0x38: /* TAPR */ 257: s->prescale[0] = value; 258: break; 259: case 0x3c: /* TBPR */ 260: s->prescale[1] = value; 261: break; 262: case 0x40: /* TAPMR */ 263: s->match_prescale[0] = value; 264: break; 265: case 0x44: /* TBPMR */ 266: s->match_prescale[0] = value; 267: break; 268: default: 269: cpu_abort(cpu_single_env, "gptm_write: Bad offset 0x%x\n", (int)offset); 270: } 271: gptm_update_irq(s); 272: } 273: 274: static CPUReadMemoryFunc *gptm_readfn[] = { 275: gptm_read, 276: gptm_read, 277: gptm_read 278: }; 279: 280: static CPUWriteMemoryFunc *gptm_writefn[] = { 281: gptm_write, 282: gptm_write, 283: gptm_write 284: }; 285: 1.1.1.2 ! root 286: static void gptm_save(QEMUFile *f, void *opaque) ! 287: { ! 288: gptm_state *s = (gptm_state *)opaque; ! 289: ! 290: qemu_put_be32(f, s->config); ! 291: qemu_put_be32(f, s->mode[0]); ! 292: qemu_put_be32(f, s->mode[1]); ! 293: qemu_put_be32(f, s->control); ! 294: qemu_put_be32(f, s->state); ! 295: qemu_put_be32(f, s->mask); ! 296: qemu_put_be32(f, s->mode[0]); ! 297: qemu_put_be32(f, s->mode[0]); ! 298: qemu_put_be32(f, s->load[0]); ! 299: qemu_put_be32(f, s->load[1]); ! 300: qemu_put_be32(f, s->match[0]); ! 301: qemu_put_be32(f, s->match[1]); ! 302: qemu_put_be32(f, s->prescale[0]); ! 303: qemu_put_be32(f, s->prescale[1]); ! 304: qemu_put_be32(f, s->match_prescale[0]); ! 305: qemu_put_be32(f, s->match_prescale[1]); ! 306: qemu_put_be32(f, s->rtc); ! 307: qemu_put_be64(f, s->tick[0]); ! 308: qemu_put_be64(f, s->tick[1]); ! 309: qemu_put_timer(f, s->timer[0]); ! 310: qemu_put_timer(f, s->timer[1]); ! 311: } ! 312: ! 313: static int gptm_load(QEMUFile *f, void *opaque, int version_id) ! 314: { ! 315: gptm_state *s = (gptm_state *)opaque; ! 316: ! 317: if (version_id != 1) ! 318: return -EINVAL; ! 319: ! 320: s->config = qemu_get_be32(f); ! 321: s->mode[0] = qemu_get_be32(f); ! 322: s->mode[1] = qemu_get_be32(f); ! 323: s->control = qemu_get_be32(f); ! 324: s->state = qemu_get_be32(f); ! 325: s->mask = qemu_get_be32(f); ! 326: s->mode[0] = qemu_get_be32(f); ! 327: s->mode[0] = qemu_get_be32(f); ! 328: s->load[0] = qemu_get_be32(f); ! 329: s->load[1] = qemu_get_be32(f); ! 330: s->match[0] = qemu_get_be32(f); ! 331: s->match[1] = qemu_get_be32(f); ! 332: s->prescale[0] = qemu_get_be32(f); ! 333: s->prescale[1] = qemu_get_be32(f); ! 334: s->match_prescale[0] = qemu_get_be32(f); ! 335: s->match_prescale[1] = qemu_get_be32(f); ! 336: s->rtc = qemu_get_be32(f); ! 337: s->tick[0] = qemu_get_be64(f); ! 338: s->tick[1] = qemu_get_be64(f); ! 339: qemu_get_timer(f, s->timer[0]); ! 340: qemu_get_timer(f, s->timer[1]); ! 341: ! 342: return 0; ! 343: } ! 344: 1.1 root 345: static void stellaris_gptm_init(uint32_t base, qemu_irq irq, qemu_irq trigger) 346: { 347: int iomemtype; 348: gptm_state *s; 349: 350: s = (gptm_state *)qemu_mallocz(sizeof(gptm_state)); 351: s->irq = irq; 352: s->trigger = trigger; 353: s->opaque[0] = s->opaque[1] = s; 354: 355: iomemtype = cpu_register_io_memory(0, gptm_readfn, 356: gptm_writefn, s); 357: cpu_register_physical_memory(base, 0x00001000, iomemtype); 358: s->timer[0] = qemu_new_timer(vm_clock, gptm_tick, &s->opaque[0]); 359: s->timer[1] = qemu_new_timer(vm_clock, gptm_tick, &s->opaque[1]); 1.1.1.2 ! root 360: register_savevm("stellaris_gptm", -1, 1, gptm_save, gptm_load, s); 1.1 root 361: } 362: 363: 364: /* System controller. */ 365: 366: typedef struct { 367: uint32_t pborctl; 368: uint32_t ldopctl; 369: uint32_t int_status; 370: uint32_t int_mask; 371: uint32_t resc; 372: uint32_t rcc; 373: uint32_t rcgc[3]; 374: uint32_t scgc[3]; 375: uint32_t dcgc[3]; 376: uint32_t clkvclr; 377: uint32_t ldoarst; 378: uint32_t user0; 379: uint32_t user1; 380: qemu_irq irq; 381: stellaris_board_info *board; 382: } ssys_state; 383: 384: static void ssys_update(ssys_state *s) 385: { 386: qemu_set_irq(s->irq, (s->int_status & s->int_mask) != 0); 387: } 388: 389: static uint32_t pllcfg_sandstorm[16] = { 390: 0x31c0, /* 1 Mhz */ 391: 0x1ae0, /* 1.8432 Mhz */ 392: 0x18c0, /* 2 Mhz */ 393: 0xd573, /* 2.4576 Mhz */ 394: 0x37a6, /* 3.57954 Mhz */ 395: 0x1ae2, /* 3.6864 Mhz */ 396: 0x0c40, /* 4 Mhz */ 397: 0x98bc, /* 4.906 Mhz */ 398: 0x935b, /* 4.9152 Mhz */ 399: 0x09c0, /* 5 Mhz */ 400: 0x4dee, /* 5.12 Mhz */ 401: 0x0c41, /* 6 Mhz */ 402: 0x75db, /* 6.144 Mhz */ 403: 0x1ae6, /* 7.3728 Mhz */ 404: 0x0600, /* 8 Mhz */ 405: 0x585b /* 8.192 Mhz */ 406: }; 407: 408: static uint32_t pllcfg_fury[16] = { 409: 0x3200, /* 1 Mhz */ 410: 0x1b20, /* 1.8432 Mhz */ 411: 0x1900, /* 2 Mhz */ 412: 0xf42b, /* 2.4576 Mhz */ 413: 0x37e3, /* 3.57954 Mhz */ 414: 0x1b21, /* 3.6864 Mhz */ 415: 0x0c80, /* 4 Mhz */ 416: 0x98ee, /* 4.906 Mhz */ 417: 0xd5b4, /* 4.9152 Mhz */ 418: 0x0a00, /* 5 Mhz */ 419: 0x4e27, /* 5.12 Mhz */ 420: 0x1902, /* 6 Mhz */ 421: 0xec1c, /* 6.144 Mhz */ 422: 0x1b23, /* 7.3728 Mhz */ 423: 0x0640, /* 8 Mhz */ 424: 0xb11c /* 8.192 Mhz */ 425: }; 426: 427: static uint32_t ssys_read(void *opaque, target_phys_addr_t offset) 428: { 429: ssys_state *s = (ssys_state *)opaque; 430: 431: switch (offset) { 432: case 0x000: /* DID0 */ 433: return s->board->did0; 434: case 0x004: /* DID1 */ 435: return s->board->did1; 436: case 0x008: /* DC0 */ 437: return s->board->dc0; 438: case 0x010: /* DC1 */ 439: return s->board->dc1; 440: case 0x014: /* DC2 */ 441: return s->board->dc2; 442: case 0x018: /* DC3 */ 443: return s->board->dc3; 444: case 0x01c: /* DC4 */ 445: return s->board->dc4; 446: case 0x030: /* PBORCTL */ 447: return s->pborctl; 448: case 0x034: /* LDOPCTL */ 449: return s->ldopctl; 450: case 0x040: /* SRCR0 */ 451: return 0; 452: case 0x044: /* SRCR1 */ 453: return 0; 454: case 0x048: /* SRCR2 */ 455: return 0; 456: case 0x050: /* RIS */ 457: return s->int_status; 458: case 0x054: /* IMC */ 459: return s->int_mask; 460: case 0x058: /* MISC */ 461: return s->int_status & s->int_mask; 462: case 0x05c: /* RESC */ 463: return s->resc; 464: case 0x060: /* RCC */ 465: return s->rcc; 466: case 0x064: /* PLLCFG */ 467: { 468: int xtal; 469: xtal = (s->rcc >> 6) & 0xf; 470: if (s->board->did0 & (1 << 16)) { 471: return pllcfg_fury[xtal]; 472: } else { 473: return pllcfg_sandstorm[xtal]; 474: } 475: } 476: case 0x100: /* RCGC0 */ 477: return s->rcgc[0]; 478: case 0x104: /* RCGC1 */ 479: return s->rcgc[1]; 480: case 0x108: /* RCGC2 */ 481: return s->rcgc[2]; 482: case 0x110: /* SCGC0 */ 483: return s->scgc[0]; 484: case 0x114: /* SCGC1 */ 485: return s->scgc[1]; 486: case 0x118: /* SCGC2 */ 487: return s->scgc[2]; 488: case 0x120: /* DCGC0 */ 489: return s->dcgc[0]; 490: case 0x124: /* DCGC1 */ 491: return s->dcgc[1]; 492: case 0x128: /* DCGC2 */ 493: return s->dcgc[2]; 494: case 0x150: /* CLKVCLR */ 495: return s->clkvclr; 496: case 0x160: /* LDOARST */ 497: return s->ldoarst; 498: case 0x1e0: /* USER0 */ 499: return s->user0; 500: case 0x1e4: /* USER1 */ 501: return s->user1; 502: default: 503: cpu_abort(cpu_single_env, "ssys_read: Bad offset 0x%x\n", (int)offset); 504: return 0; 505: } 506: } 507: 1.1.1.2 ! root 508: static void ssys_calculate_system_clock(ssys_state *s) ! 509: { ! 510: system_clock_scale = 5 * (((s->rcc >> 23) & 0xf) + 1); ! 511: } ! 512: 1.1 root 513: static void ssys_write(void *opaque, target_phys_addr_t offset, uint32_t value) 514: { 515: ssys_state *s = (ssys_state *)opaque; 516: 517: switch (offset) { 518: case 0x030: /* PBORCTL */ 519: s->pborctl = value & 0xffff; 520: break; 521: case 0x034: /* LDOPCTL */ 522: s->ldopctl = value & 0x1f; 523: break; 524: case 0x040: /* SRCR0 */ 525: case 0x044: /* SRCR1 */ 526: case 0x048: /* SRCR2 */ 527: fprintf(stderr, "Peripheral reset not implemented\n"); 528: break; 529: case 0x054: /* IMC */ 530: s->int_mask = value & 0x7f; 531: break; 532: case 0x058: /* MISC */ 533: s->int_status &= ~value; 534: break; 535: case 0x05c: /* RESC */ 536: s->resc = value & 0x3f; 537: break; 538: case 0x060: /* RCC */ 539: if ((s->rcc & (1 << 13)) != 0 && (value & (1 << 13)) == 0) { 540: /* PLL enable. */ 541: s->int_status |= (1 << 6); 542: } 543: s->rcc = value; 1.1.1.2 ! root 544: ssys_calculate_system_clock(s); 1.1 root 545: break; 546: case 0x100: /* RCGC0 */ 547: s->rcgc[0] = value; 548: break; 549: case 0x104: /* RCGC1 */ 550: s->rcgc[1] = value; 551: break; 552: case 0x108: /* RCGC2 */ 553: s->rcgc[2] = value; 554: break; 555: case 0x110: /* SCGC0 */ 556: s->scgc[0] = value; 557: break; 558: case 0x114: /* SCGC1 */ 559: s->scgc[1] = value; 560: break; 561: case 0x118: /* SCGC2 */ 562: s->scgc[2] = value; 563: break; 564: case 0x120: /* DCGC0 */ 565: s->dcgc[0] = value; 566: break; 567: case 0x124: /* DCGC1 */ 568: s->dcgc[1] = value; 569: break; 570: case 0x128: /* DCGC2 */ 571: s->dcgc[2] = value; 572: break; 573: case 0x150: /* CLKVCLR */ 574: s->clkvclr = value; 575: break; 576: case 0x160: /* LDOARST */ 577: s->ldoarst = value; 578: break; 579: default: 580: cpu_abort(cpu_single_env, "ssys_write: Bad offset 0x%x\n", (int)offset); 581: } 582: ssys_update(s); 583: } 584: 585: static CPUReadMemoryFunc *ssys_readfn[] = { 586: ssys_read, 587: ssys_read, 588: ssys_read 589: }; 590: 591: static CPUWriteMemoryFunc *ssys_writefn[] = { 592: ssys_write, 593: ssys_write, 594: ssys_write 595: }; 596: 597: static void ssys_reset(void *opaque) 598: { 599: ssys_state *s = (ssys_state *)opaque; 600: 601: s->pborctl = 0x7ffd; 602: s->rcc = 0x078e3ac0; 603: s->rcgc[0] = 1; 604: s->scgc[0] = 1; 605: s->dcgc[0] = 1; 606: } 607: 1.1.1.2 ! root 608: static void ssys_save(QEMUFile *f, void *opaque) ! 609: { ! 610: ssys_state *s = (ssys_state *)opaque; ! 611: ! 612: qemu_put_be32(f, s->pborctl); ! 613: qemu_put_be32(f, s->ldopctl); ! 614: qemu_put_be32(f, s->int_mask); ! 615: qemu_put_be32(f, s->int_status); ! 616: qemu_put_be32(f, s->resc); ! 617: qemu_put_be32(f, s->rcc); ! 618: qemu_put_be32(f, s->rcgc[0]); ! 619: qemu_put_be32(f, s->rcgc[1]); ! 620: qemu_put_be32(f, s->rcgc[2]); ! 621: qemu_put_be32(f, s->scgc[0]); ! 622: qemu_put_be32(f, s->scgc[1]); ! 623: qemu_put_be32(f, s->scgc[2]); ! 624: qemu_put_be32(f, s->dcgc[0]); ! 625: qemu_put_be32(f, s->dcgc[1]); ! 626: qemu_put_be32(f, s->dcgc[2]); ! 627: qemu_put_be32(f, s->clkvclr); ! 628: qemu_put_be32(f, s->ldoarst); ! 629: } ! 630: ! 631: static int ssys_load(QEMUFile *f, void *opaque, int version_id) ! 632: { ! 633: ssys_state *s = (ssys_state *)opaque; ! 634: ! 635: if (version_id != 1) ! 636: return -EINVAL; ! 637: ! 638: s->pborctl = qemu_get_be32(f); ! 639: s->ldopctl = qemu_get_be32(f); ! 640: s->int_mask = qemu_get_be32(f); ! 641: s->int_status = qemu_get_be32(f); ! 642: s->resc = qemu_get_be32(f); ! 643: s->rcc = qemu_get_be32(f); ! 644: s->rcgc[0] = qemu_get_be32(f); ! 645: s->rcgc[1] = qemu_get_be32(f); ! 646: s->rcgc[2] = qemu_get_be32(f); ! 647: s->scgc[0] = qemu_get_be32(f); ! 648: s->scgc[1] = qemu_get_be32(f); ! 649: s->scgc[2] = qemu_get_be32(f); ! 650: s->dcgc[0] = qemu_get_be32(f); ! 651: s->dcgc[1] = qemu_get_be32(f); ! 652: s->dcgc[2] = qemu_get_be32(f); ! 653: s->clkvclr = qemu_get_be32(f); ! 654: s->ldoarst = qemu_get_be32(f); ! 655: ssys_calculate_system_clock(s); ! 656: ! 657: return 0; ! 658: } ! 659: 1.1 root 660: static void stellaris_sys_init(uint32_t base, qemu_irq irq, 661: stellaris_board_info * board, 662: uint8_t *macaddr) 663: { 664: int iomemtype; 665: ssys_state *s; 666: 667: s = (ssys_state *)qemu_mallocz(sizeof(ssys_state)); 668: s->irq = irq; 669: s->board = board; 670: /* Most devices come preprogrammed with a MAC address in the user data. */ 671: s->user0 = macaddr[0] | (macaddr[1] << 8) | (macaddr[2] << 16); 672: s->user1 = macaddr[3] | (macaddr[4] << 8) | (macaddr[5] << 16); 673: 674: iomemtype = cpu_register_io_memory(0, ssys_readfn, 675: ssys_writefn, s); 676: cpu_register_physical_memory(base, 0x00001000, iomemtype); 677: ssys_reset(s); 1.1.1.2 ! root 678: register_savevm("stellaris_sys", -1, 1, ssys_save, ssys_load, s); 1.1 root 679: } 680: 681: 682: /* I2C controller. */ 683: 684: typedef struct { 685: i2c_bus *bus; 686: qemu_irq irq; 687: uint32_t msa; 688: uint32_t mcs; 689: uint32_t mdr; 690: uint32_t mtpr; 691: uint32_t mimr; 692: uint32_t mris; 693: uint32_t mcr; 694: } stellaris_i2c_state; 695: 696: #define STELLARIS_I2C_MCS_BUSY 0x01 697: #define STELLARIS_I2C_MCS_ERROR 0x02 698: #define STELLARIS_I2C_MCS_ADRACK 0x04 699: #define STELLARIS_I2C_MCS_DATACK 0x08 700: #define STELLARIS_I2C_MCS_ARBLST 0x10 701: #define STELLARIS_I2C_MCS_IDLE 0x20 702: #define STELLARIS_I2C_MCS_BUSBSY 0x40 703: 704: static uint32_t stellaris_i2c_read(void *opaque, target_phys_addr_t offset) 705: { 706: stellaris_i2c_state *s = (stellaris_i2c_state *)opaque; 707: 708: switch (offset) { 709: case 0x00: /* MSA */ 710: return s->msa; 711: case 0x04: /* MCS */ 712: /* We don't emulate timing, so the controller is never busy. */ 713: return s->mcs | STELLARIS_I2C_MCS_IDLE; 714: case 0x08: /* MDR */ 715: return s->mdr; 716: case 0x0c: /* MTPR */ 717: return s->mtpr; 718: case 0x10: /* MIMR */ 719: return s->mimr; 720: case 0x14: /* MRIS */ 721: return s->mris; 722: case 0x18: /* MMIS */ 723: return s->mris & s->mimr; 724: case 0x20: /* MCR */ 725: return s->mcr; 726: default: 727: cpu_abort(cpu_single_env, "strllaris_i2c_read: Bad offset 0x%x\n", 728: (int)offset); 729: return 0; 730: } 731: } 732: 733: static void stellaris_i2c_update(stellaris_i2c_state *s) 734: { 735: int level; 736: 737: level = (s->mris & s->mimr) != 0; 738: qemu_set_irq(s->irq, level); 739: } 740: 741: static void stellaris_i2c_write(void *opaque, target_phys_addr_t offset, 742: uint32_t value) 743: { 744: stellaris_i2c_state *s = (stellaris_i2c_state *)opaque; 745: 746: switch (offset) { 747: case 0x00: /* MSA */ 748: s->msa = value & 0xff; 749: break; 750: case 0x04: /* MCS */ 751: if ((s->mcr & 0x10) == 0) { 752: /* Disabled. Do nothing. */ 753: break; 754: } 755: /* Grab the bus if this is starting a transfer. */ 756: if ((value & 2) && (s->mcs & STELLARIS_I2C_MCS_BUSBSY) == 0) { 757: if (i2c_start_transfer(s->bus, s->msa >> 1, s->msa & 1)) { 758: s->mcs |= STELLARIS_I2C_MCS_ARBLST; 759: } else { 760: s->mcs &= ~STELLARIS_I2C_MCS_ARBLST; 761: s->mcs |= STELLARIS_I2C_MCS_BUSBSY; 762: } 763: } 764: /* If we don't have the bus then indicate an error. */ 765: if (!i2c_bus_busy(s->bus) 766: || (s->mcs & STELLARIS_I2C_MCS_BUSBSY) == 0) { 767: s->mcs |= STELLARIS_I2C_MCS_ERROR; 768: break; 769: } 770: s->mcs &= ~STELLARIS_I2C_MCS_ERROR; 771: if (value & 1) { 772: /* Transfer a byte. */ 773: /* TODO: Handle errors. */ 774: if (s->msa & 1) { 775: /* Recv */ 776: s->mdr = i2c_recv(s->bus) & 0xff; 777: } else { 778: /* Send */ 779: i2c_send(s->bus, s->mdr); 780: } 781: /* Raise an interrupt. */ 782: s->mris |= 1; 783: } 784: if (value & 4) { 785: /* Finish transfer. */ 786: i2c_end_transfer(s->bus); 787: s->mcs &= ~STELLARIS_I2C_MCS_BUSBSY; 788: } 789: break; 790: case 0x08: /* MDR */ 791: s->mdr = value & 0xff; 792: break; 793: case 0x0c: /* MTPR */ 794: s->mtpr = value & 0xff; 795: break; 796: case 0x10: /* MIMR */ 797: s->mimr = 1; 798: break; 799: case 0x1c: /* MICR */ 800: s->mris &= ~value; 801: break; 802: case 0x20: /* MCR */ 803: if (value & 1) 804: cpu_abort(cpu_single_env, 805: "stellaris_i2c_write: Loopback not implemented\n"); 806: if (value & 0x20) 807: cpu_abort(cpu_single_env, 808: "stellaris_i2c_write: Slave mode not implemented\n"); 809: s->mcr = value & 0x31; 810: break; 811: default: 812: cpu_abort(cpu_single_env, "stellaris_i2c_write: Bad offset 0x%x\n", 813: (int)offset); 814: } 815: stellaris_i2c_update(s); 816: } 817: 818: static void stellaris_i2c_reset(stellaris_i2c_state *s) 819: { 820: if (s->mcs & STELLARIS_I2C_MCS_BUSBSY) 821: i2c_end_transfer(s->bus); 822: 823: s->msa = 0; 824: s->mcs = 0; 825: s->mdr = 0; 826: s->mtpr = 1; 827: s->mimr = 0; 828: s->mris = 0; 829: s->mcr = 0; 830: stellaris_i2c_update(s); 831: } 832: 833: static CPUReadMemoryFunc *stellaris_i2c_readfn[] = { 834: stellaris_i2c_read, 835: stellaris_i2c_read, 836: stellaris_i2c_read 837: }; 838: 839: static CPUWriteMemoryFunc *stellaris_i2c_writefn[] = { 840: stellaris_i2c_write, 841: stellaris_i2c_write, 842: stellaris_i2c_write 843: }; 844: 1.1.1.2 ! root 845: static void stellaris_i2c_save(QEMUFile *f, void *opaque) ! 846: { ! 847: stellaris_i2c_state *s = (stellaris_i2c_state *)opaque; ! 848: ! 849: qemu_put_be32(f, s->msa); ! 850: qemu_put_be32(f, s->mcs); ! 851: qemu_put_be32(f, s->mdr); ! 852: qemu_put_be32(f, s->mtpr); ! 853: qemu_put_be32(f, s->mimr); ! 854: qemu_put_be32(f, s->mris); ! 855: qemu_put_be32(f, s->mcr); ! 856: } ! 857: ! 858: static int stellaris_i2c_load(QEMUFile *f, void *opaque, int version_id) ! 859: { ! 860: stellaris_i2c_state *s = (stellaris_i2c_state *)opaque; ! 861: ! 862: if (version_id != 1) ! 863: return -EINVAL; ! 864: ! 865: s->msa = qemu_get_be32(f); ! 866: s->mcs = qemu_get_be32(f); ! 867: s->mdr = qemu_get_be32(f); ! 868: s->mtpr = qemu_get_be32(f); ! 869: s->mimr = qemu_get_be32(f); ! 870: s->mris = qemu_get_be32(f); ! 871: s->mcr = qemu_get_be32(f); ! 872: ! 873: return 0; ! 874: } ! 875: 1.1 root 876: static void stellaris_i2c_init(uint32_t base, qemu_irq irq, i2c_bus *bus) 877: { 878: stellaris_i2c_state *s; 879: int iomemtype; 880: 881: s = (stellaris_i2c_state *)qemu_mallocz(sizeof(stellaris_i2c_state)); 882: s->irq = irq; 883: s->bus = bus; 884: 885: iomemtype = cpu_register_io_memory(0, stellaris_i2c_readfn, 886: stellaris_i2c_writefn, s); 887: cpu_register_physical_memory(base, 0x00001000, iomemtype); 888: /* ??? For now we only implement the master interface. */ 889: stellaris_i2c_reset(s); 1.1.1.2 ! root 890: register_savevm("stellaris_i2c", -1, 1, ! 891: stellaris_i2c_save, stellaris_i2c_load, s); 1.1 root 892: } 893: 894: /* Analogue to Digital Converter. This is only partially implemented, 895: enough for applications that use a combined ADC and timer tick. */ 896: 897: #define STELLARIS_ADC_EM_CONTROLLER 0 898: #define STELLARIS_ADC_EM_COMP 1 899: #define STELLARIS_ADC_EM_EXTERNAL 4 900: #define STELLARIS_ADC_EM_TIMER 5 901: #define STELLARIS_ADC_EM_PWM0 6 902: #define STELLARIS_ADC_EM_PWM1 7 903: #define STELLARIS_ADC_EM_PWM2 8 904: 905: #define STELLARIS_ADC_FIFO_EMPTY 0x0100 906: #define STELLARIS_ADC_FIFO_FULL 0x1000 907: 908: typedef struct 909: { 910: uint32_t actss; 911: uint32_t ris; 912: uint32_t im; 913: uint32_t emux; 914: uint32_t ostat; 915: uint32_t ustat; 916: uint32_t sspri; 917: uint32_t sac; 918: struct { 919: uint32_t state; 920: uint32_t data[16]; 921: } fifo[4]; 922: uint32_t ssmux[4]; 923: uint32_t ssctl[4]; 1.1.1.2 ! root 924: uint32_t noise; 1.1 root 925: qemu_irq irq; 926: } stellaris_adc_state; 927: 928: static uint32_t stellaris_adc_fifo_read(stellaris_adc_state *s, int n) 929: { 930: int tail; 931: 932: tail = s->fifo[n].state & 0xf; 933: if (s->fifo[n].state & STELLARIS_ADC_FIFO_EMPTY) { 934: s->ustat |= 1 << n; 935: } else { 936: s->fifo[n].state = (s->fifo[n].state & ~0xf) | ((tail + 1) & 0xf); 937: s->fifo[n].state &= ~STELLARIS_ADC_FIFO_FULL; 938: if (tail + 1 == ((s->fifo[n].state >> 4) & 0xf)) 939: s->fifo[n].state |= STELLARIS_ADC_FIFO_EMPTY; 940: } 941: return s->fifo[n].data[tail]; 942: } 943: 944: static void stellaris_adc_fifo_write(stellaris_adc_state *s, int n, 945: uint32_t value) 946: { 947: int head; 948: 949: head = (s->fifo[n].state >> 4) & 0xf; 950: if (s->fifo[n].state & STELLARIS_ADC_FIFO_FULL) { 951: s->ostat |= 1 << n; 952: return; 953: } 954: s->fifo[n].data[head] = value; 955: head = (head + 1) & 0xf; 956: s->fifo[n].state &= ~STELLARIS_ADC_FIFO_EMPTY; 957: s->fifo[n].state = (s->fifo[n].state & ~0xf0) | (head << 4); 958: if ((s->fifo[n].state & 0xf) == head) 959: s->fifo[n].state |= STELLARIS_ADC_FIFO_FULL; 960: } 961: 962: static void stellaris_adc_update(stellaris_adc_state *s) 963: { 964: int level; 965: 966: level = (s->ris & s->im) != 0; 967: qemu_set_irq(s->irq, level); 968: } 969: 970: static void stellaris_adc_trigger(void *opaque, int irq, int level) 971: { 972: stellaris_adc_state *s = (stellaris_adc_state *)opaque; 973: 974: if ((s->actss & 1) == 0) { 975: return; 976: } 977: 1.1.1.2 ! root 978: /* Some applications use the ADC as a random number source, so introduce ! 979: some variation into the signal. */ ! 980: s->noise = s->noise * 314159 + 1; 1.1 root 981: /* ??? actual inputs not implemented. Return an arbitrary value. */ 1.1.1.2 ! root 982: stellaris_adc_fifo_write(s, 0, 0x200 + ((s->noise >> 16) & 7)); 1.1 root 983: s->ris |= 1; 984: stellaris_adc_update(s); 985: } 986: 987: static void stellaris_adc_reset(stellaris_adc_state *s) 988: { 989: int n; 990: 991: for (n = 0; n < 4; n++) { 992: s->ssmux[n] = 0; 993: s->ssctl[n] = 0; 994: s->fifo[n].state = STELLARIS_ADC_FIFO_EMPTY; 995: } 996: } 997: 998: static uint32_t stellaris_adc_read(void *opaque, target_phys_addr_t offset) 999: { 1000: stellaris_adc_state *s = (stellaris_adc_state *)opaque; 1001: 1002: /* TODO: Implement this. */ 1003: if (offset >= 0x40 && offset < 0xc0) { 1004: int n; 1005: n = (offset - 0x40) >> 5; 1006: switch (offset & 0x1f) { 1007: case 0x00: /* SSMUX */ 1008: return s->ssmux[n]; 1009: case 0x04: /* SSCTL */ 1010: return s->ssctl[n]; 1011: case 0x08: /* SSFIFO */ 1012: return stellaris_adc_fifo_read(s, n); 1013: case 0x0c: /* SSFSTAT */ 1014: return s->fifo[n].state; 1015: default: 1016: break; 1017: } 1018: } 1019: switch (offset) { 1020: case 0x00: /* ACTSS */ 1021: return s->actss; 1022: case 0x04: /* RIS */ 1023: return s->ris; 1024: case 0x08: /* IM */ 1025: return s->im; 1026: case 0x0c: /* ISC */ 1027: return s->ris & s->im; 1028: case 0x10: /* OSTAT */ 1029: return s->ostat; 1030: case 0x14: /* EMUX */ 1031: return s->emux; 1032: case 0x18: /* USTAT */ 1033: return s->ustat; 1034: case 0x20: /* SSPRI */ 1035: return s->sspri; 1036: case 0x30: /* SAC */ 1037: return s->sac; 1038: default: 1039: cpu_abort(cpu_single_env, "strllaris_adc_read: Bad offset 0x%x\n", 1040: (int)offset); 1041: return 0; 1042: } 1043: } 1044: 1045: static void stellaris_adc_write(void *opaque, target_phys_addr_t offset, 1046: uint32_t value) 1047: { 1048: stellaris_adc_state *s = (stellaris_adc_state *)opaque; 1049: 1050: /* TODO: Implement this. */ 1051: if (offset >= 0x40 && offset < 0xc0) { 1052: int n; 1053: n = (offset - 0x40) >> 5; 1054: switch (offset & 0x1f) { 1055: case 0x00: /* SSMUX */ 1056: s->ssmux[n] = value & 0x33333333; 1057: return; 1058: case 0x04: /* SSCTL */ 1059: if (value != 6) { 1060: cpu_abort(cpu_single_env, "ADC: Unimplemented sequence %x\n", 1061: value); 1062: } 1063: s->ssctl[n] = value; 1064: return; 1065: default: 1066: break; 1067: } 1068: } 1069: switch (offset) { 1070: case 0x00: /* ACTSS */ 1071: s->actss = value & 0xf; 1072: if (value & 0xe) { 1073: cpu_abort(cpu_single_env, 1074: "Not implemented: ADC sequencers 1-3\n"); 1075: } 1076: break; 1077: case 0x08: /* IM */ 1078: s->im = value; 1079: break; 1080: case 0x0c: /* ISC */ 1081: s->ris &= ~value; 1082: break; 1083: case 0x10: /* OSTAT */ 1084: s->ostat &= ~value; 1085: break; 1086: case 0x14: /* EMUX */ 1087: s->emux = value; 1088: break; 1089: case 0x18: /* USTAT */ 1090: s->ustat &= ~value; 1091: break; 1092: case 0x20: /* SSPRI */ 1093: s->sspri = value; 1094: break; 1095: case 0x28: /* PSSI */ 1096: cpu_abort(cpu_single_env, "Not implemented: ADC sample initiate\n"); 1097: break; 1098: case 0x30: /* SAC */ 1099: s->sac = value; 1100: break; 1101: default: 1102: cpu_abort(cpu_single_env, "stellaris_adc_write: Bad offset 0x%x\n", 1103: (int)offset); 1104: } 1105: stellaris_adc_update(s); 1106: } 1107: 1108: static CPUReadMemoryFunc *stellaris_adc_readfn[] = { 1109: stellaris_adc_read, 1110: stellaris_adc_read, 1111: stellaris_adc_read 1112: }; 1113: 1114: static CPUWriteMemoryFunc *stellaris_adc_writefn[] = { 1115: stellaris_adc_write, 1116: stellaris_adc_write, 1117: stellaris_adc_write 1118: }; 1119: 1.1.1.2 ! root 1120: static void stellaris_adc_save(QEMUFile *f, void *opaque) ! 1121: { ! 1122: stellaris_adc_state *s = (stellaris_adc_state *)opaque; ! 1123: int i; ! 1124: int j; ! 1125: ! 1126: qemu_put_be32(f, s->actss); ! 1127: qemu_put_be32(f, s->ris); ! 1128: qemu_put_be32(f, s->im); ! 1129: qemu_put_be32(f, s->emux); ! 1130: qemu_put_be32(f, s->ostat); ! 1131: qemu_put_be32(f, s->ustat); ! 1132: qemu_put_be32(f, s->sspri); ! 1133: qemu_put_be32(f, s->sac); ! 1134: for (i = 0; i < 4; i++) { ! 1135: qemu_put_be32(f, s->fifo[i].state); ! 1136: for (j = 0; j < 16; j++) { ! 1137: qemu_put_be32(f, s->fifo[i].data[j]); ! 1138: } ! 1139: qemu_put_be32(f, s->ssmux[i]); ! 1140: qemu_put_be32(f, s->ssctl[i]); ! 1141: } ! 1142: qemu_put_be32(f, s->noise); ! 1143: } ! 1144: ! 1145: static int stellaris_adc_load(QEMUFile *f, void *opaque, int version_id) ! 1146: { ! 1147: stellaris_adc_state *s = (stellaris_adc_state *)opaque; ! 1148: int i; ! 1149: int j; ! 1150: ! 1151: if (version_id != 1) ! 1152: return -EINVAL; ! 1153: ! 1154: s->actss = qemu_get_be32(f); ! 1155: s->ris = qemu_get_be32(f); ! 1156: s->im = qemu_get_be32(f); ! 1157: s->emux = qemu_get_be32(f); ! 1158: s->ostat = qemu_get_be32(f); ! 1159: s->ustat = qemu_get_be32(f); ! 1160: s->sspri = qemu_get_be32(f); ! 1161: s->sac = qemu_get_be32(f); ! 1162: for (i = 0; i < 4; i++) { ! 1163: s->fifo[i].state = qemu_get_be32(f); ! 1164: for (j = 0; j < 16; j++) { ! 1165: s->fifo[i].data[j] = qemu_get_be32(f); ! 1166: } ! 1167: s->ssmux[i] = qemu_get_be32(f); ! 1168: s->ssctl[i] = qemu_get_be32(f); ! 1169: } ! 1170: s->noise = qemu_get_be32(f); ! 1171: ! 1172: return 0; ! 1173: } ! 1174: 1.1 root 1175: static qemu_irq stellaris_adc_init(uint32_t base, qemu_irq irq) 1176: { 1177: stellaris_adc_state *s; 1178: int iomemtype; 1179: qemu_irq *qi; 1180: 1181: s = (stellaris_adc_state *)qemu_mallocz(sizeof(stellaris_adc_state)); 1182: s->irq = irq; 1183: 1184: iomemtype = cpu_register_io_memory(0, stellaris_adc_readfn, 1185: stellaris_adc_writefn, s); 1186: cpu_register_physical_memory(base, 0x00001000, iomemtype); 1187: stellaris_adc_reset(s); 1188: qi = qemu_allocate_irqs(stellaris_adc_trigger, s, 1); 1.1.1.2 ! root 1189: register_savevm("stellaris_adc", -1, 1, ! 1190: stellaris_adc_save, stellaris_adc_load, s); 1.1 root 1191: return qi[0]; 1192: } 1193: 1194: /* Some boards have both an OLED controller and SD card connected to 1195: the same SSI port, with the SD card chip select connected to a 1196: GPIO pin. Technically the OLED chip select is connected to the SSI 1197: Fss pin. We do not bother emulating that as both devices should 1198: never be selected simultaneously, and our OLED controller ignores stray 1199: 0xff commands that occur when deselecting the SD card. */ 1200: 1201: typedef struct { 1202: ssi_xfer_cb xfer_cb[2]; 1203: void *opaque[2]; 1204: qemu_irq irq; 1205: int current_dev; 1206: } stellaris_ssi_bus_state; 1207: 1208: static void stellaris_ssi_bus_select(void *opaque, int irq, int level) 1209: { 1210: stellaris_ssi_bus_state *s = (stellaris_ssi_bus_state *)opaque; 1211: 1212: s->current_dev = level; 1213: } 1214: 1215: static int stellaris_ssi_bus_xfer(void *opaque, int val) 1216: { 1217: stellaris_ssi_bus_state *s = (stellaris_ssi_bus_state *)opaque; 1218: 1219: return s->xfer_cb[s->current_dev](s->opaque[s->current_dev], val); 1220: } 1221: 1.1.1.2 ! root 1222: static void stellaris_ssi_bus_save(QEMUFile *f, void *opaque) ! 1223: { ! 1224: stellaris_ssi_bus_state *s = (stellaris_ssi_bus_state *)opaque; ! 1225: ! 1226: qemu_put_be32(f, s->current_dev); ! 1227: } ! 1228: ! 1229: static int stellaris_ssi_bus_load(QEMUFile *f, void *opaque, int version_id) ! 1230: { ! 1231: stellaris_ssi_bus_state *s = (stellaris_ssi_bus_state *)opaque; ! 1232: ! 1233: if (version_id != 1) ! 1234: return -EINVAL; ! 1235: ! 1236: s->current_dev = qemu_get_be32(f); ! 1237: ! 1238: return 0; ! 1239: } ! 1240: 1.1 root 1241: static void *stellaris_ssi_bus_init(qemu_irq *irqp, 1242: ssi_xfer_cb cb0, void *opaque0, 1243: ssi_xfer_cb cb1, void *opaque1) 1244: { 1245: qemu_irq *qi; 1246: stellaris_ssi_bus_state *s; 1247: 1248: s = (stellaris_ssi_bus_state *)qemu_mallocz(sizeof(stellaris_ssi_bus_state)); 1249: s->xfer_cb[0] = cb0; 1250: s->opaque[0] = opaque0; 1251: s->xfer_cb[1] = cb1; 1252: s->opaque[1] = opaque1; 1253: qi = qemu_allocate_irqs(stellaris_ssi_bus_select, s, 1); 1254: *irqp = *qi; 1.1.1.2 ! root 1255: register_savevm("stellaris_ssi_bus", -1, 1, ! 1256: stellaris_ssi_bus_save, stellaris_ssi_bus_load, s); 1.1 root 1257: return s; 1258: } 1259: 1260: /* Board init. */ 1261: static stellaris_board_info stellaris_boards[] = { 1262: { "LM3S811EVB", 1263: 0, 1264: 0x0032000e, 1265: 0x001f001f, /* dc0 */ 1266: 0x001132bf, 1267: 0x01071013, 1268: 0x3f0f01ff, 1269: 0x0000001f, 1270: BP_OLED_I2C 1271: }, 1272: { "LM3S6965EVB", 1273: 0x10010002, 1274: 0x1073402e, 1275: 0x00ff007f, /* dc0 */ 1276: 0x001133ff, 1277: 0x030f5317, 1278: 0x0f0f87ff, 1279: 0x5000007f, 1280: BP_OLED_SSI | BP_GAMEPAD 1281: } 1282: }; 1283: 1284: static void stellaris_init(const char *kernel_filename, const char *cpu_model, 1.1.1.2 ! root 1285: stellaris_board_info *board) 1.1 root 1286: { 1287: static const int uart_irq[] = {5, 6, 33, 34}; 1288: static const int timer_irq[] = {19, 21, 23, 35}; 1289: static const uint32_t gpio_addr[7] = 1290: { 0x40004000, 0x40005000, 0x40006000, 0x40007000, 1291: 0x40024000, 0x40025000, 0x40026000}; 1292: static const int gpio_irq[7] = {0, 1, 2, 3, 4, 30, 31}; 1293: 1294: qemu_irq *pic; 1.1.1.2 ! root 1295: qemu_irq *gpio_in[7]; ! 1296: qemu_irq *gpio_out[7]; 1.1 root 1297: qemu_irq adc; 1298: int sram_size; 1299: int flash_size; 1300: i2c_bus *i2c; 1301: int i; 1302: 1303: flash_size = ((board->dc0 & 0xffff) + 1) << 1; 1304: sram_size = (board->dc0 >> 18) + 1; 1305: pic = armv7m_init(flash_size, sram_size, kernel_filename, cpu_model); 1306: 1307: if (board->dc1 & (1 << 16)) { 1308: adc = stellaris_adc_init(0x40038000, pic[14]); 1309: } else { 1310: adc = NULL; 1311: } 1312: for (i = 0; i < 4; i++) { 1313: if (board->dc2 & (0x10000 << i)) { 1314: stellaris_gptm_init(0x40030000 + i * 0x1000, 1315: pic[timer_irq[i]], adc); 1316: } 1317: } 1318: 1319: stellaris_sys_init(0x400fe000, pic[28], board, nd_table[0].macaddr); 1320: 1321: for (i = 0; i < 7; i++) { 1322: if (board->dc4 & (1 << i)) { 1323: gpio_in[i] = pl061_init(gpio_addr[i], pic[gpio_irq[i]], 1324: &gpio_out[i]); 1325: } 1326: } 1327: 1328: if (board->dc2 & (1 << 12)) { 1329: i2c = i2c_init_bus(); 1330: stellaris_i2c_init(0x40020000, pic[8], i2c); 1331: if (board->peripherals & BP_OLED_I2C) { 1.1.1.2 ! root 1332: ssd0303_init(i2c, 0x3d); 1.1 root 1333: } 1334: } 1335: 1336: for (i = 0; i < 4; i++) { 1337: if (board->dc2 & (1 << i)) { 1338: pl011_init(0x4000c000 + i * 0x1000, pic[uart_irq[i]], 1339: serial_hds[i], PL011_LUMINARY); 1340: } 1341: } 1342: if (board->dc2 & (1 << 4)) { 1343: if (board->peripherals & BP_OLED_SSI) { 1344: void * oled; 1345: void * sd; 1346: void *ssi_bus; 1347: int index; 1348: 1.1.1.2 ! root 1349: oled = ssd0323_init(&gpio_out[GPIO_C][7]); 1.1 root 1350: index = drive_get_index(IF_SD, 0, 0); 1351: sd = ssi_sd_init(drives_table[index].bdrv); 1352: 1353: ssi_bus = stellaris_ssi_bus_init(&gpio_out[GPIO_D][0], 1354: ssi_sd_xfer, sd, 1355: ssd0323_xfer_ssi, oled); 1356: 1357: pl022_init(0x40008000, pic[7], stellaris_ssi_bus_xfer, ssi_bus); 1358: /* Make sure the select pin is high. */ 1359: qemu_irq_raise(gpio_out[GPIO_D][0]); 1360: } else { 1361: pl022_init(0x40008000, pic[7], NULL, NULL); 1362: } 1363: } 1.1.1.2 ! root 1364: if (board->dc4 & (1 << 28)) 1.1 root 1365: stellaris_enet_init(&nd_table[0], 0x40048000, pic[42]); 1366: if (board->peripherals & BP_GAMEPAD) { 1367: qemu_irq gpad_irq[5]; 1368: static const int gpad_keycode[5] = { 0xc8, 0xd0, 0xcb, 0xcd, 0x1d }; 1369: 1370: gpad_irq[0] = qemu_irq_invert(gpio_in[GPIO_E][0]); /* up */ 1371: gpad_irq[1] = qemu_irq_invert(gpio_in[GPIO_E][1]); /* down */ 1372: gpad_irq[2] = qemu_irq_invert(gpio_in[GPIO_E][2]); /* left */ 1373: gpad_irq[3] = qemu_irq_invert(gpio_in[GPIO_E][3]); /* right */ 1374: gpad_irq[4] = qemu_irq_invert(gpio_in[GPIO_F][1]); /* select */ 1375: 1376: stellaris_gamepad_init(5, gpad_irq, gpad_keycode); 1377: } 1378: } 1379: 1380: /* FIXME: Figure out how to generate these from stellaris_boards. */ 1.1.1.2 ! root 1381: static void lm3s811evb_init(ram_addr_t ram_size, int vga_ram_size, ! 1382: const char *boot_device, 1.1 root 1383: const char *kernel_filename, const char *kernel_cmdline, 1384: const char *initrd_filename, const char *cpu_model) 1385: { 1.1.1.2 ! root 1386: stellaris_init(kernel_filename, cpu_model, &stellaris_boards[0]); 1.1 root 1387: } 1388: 1.1.1.2 ! root 1389: static void lm3s6965evb_init(ram_addr_t ram_size, int vga_ram_size, ! 1390: const char *boot_device, 1.1 root 1391: const char *kernel_filename, const char *kernel_cmdline, 1392: const char *initrd_filename, const char *cpu_model) 1393: { 1.1.1.2 ! root 1394: stellaris_init(kernel_filename, cpu_model, &stellaris_boards[1]); 1.1 root 1395: } 1396: 1397: QEMUMachine lm3s811evb_machine = { 1.1.1.2 ! root 1398: .name = "lm3s811evb", ! 1399: .desc = "Stellaris LM3S811EVB", ! 1400: .init = lm3s811evb_init, ! 1401: .ram_require = (64 * 1024 + 8 * 1024) | RAMSIZE_FIXED, 1.1 root 1402: }; 1403: 1404: QEMUMachine lm3s6965evb_machine = { 1.1.1.2 ! root 1405: .name = "lm3s6965evb", ! 1406: .desc = "Stellaris LM3S6965EVB", ! 1407: .init = lm3s6965evb_init, ! 1408: .ram_require = (256 * 1024 + 64 * 1024) | RAMSIZE_FIXED, 1.1 root 1409: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.