Annotation of qemu/hw/stellaris.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.