Statistics
| Branch: | Revision:

root / hw / stellaris.c @ c227f099

History | View | Annotate | Download (39.1 kB)

1
/*
2
 * Luminary Micro Stellaris peripherals
3
 *
4
 * Copyright (c) 2006 CodeSourcery.
5
 * Written by Paul Brook
6
 *
7
 * This code is licenced under the GPL.
8
 */
9

    
10
#include "sysbus.h"
11
#include "ssi.h"
12
#include "arm-misc.h"
13
#include "devices.h"
14
#include "qemu-timer.h"
15
#include "i2c.h"
16
#include "net.h"
17
#include "sysemu.h"
18
#include "boards.h"
19

    
20
#define GPIO_A 0
21
#define GPIO_B 1
22
#define GPIO_C 2
23
#define GPIO_D 3
24
#define GPIO_E 4
25
#define GPIO_F 5
26
#define GPIO_G 6
27

    
28
#define BP_OLED_I2C  0x01
29
#define BP_OLED_SSI  0x02
30
#define BP_GAMEPAD   0x04
31

    
32
typedef const struct {
33
    const char *name;
34
    uint32_t did0;
35
    uint32_t did1;
36
    uint32_t dc0;
37
    uint32_t dc1;
38
    uint32_t dc2;
39
    uint32_t dc3;
40
    uint32_t dc4;
41
    uint32_t peripherals;
42
} stellaris_board_info;
43

    
44
/* General purpose timer module.  */
45

    
46
typedef struct gptm_state {
47
    SysBusDevice busdev;
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 += get_ticks_per_sec();
94
    } else if (s->mode[n] == 0xa) {
95
        /* PWM mode.  Not implemented.  */
96
    } else {
97
        hw_error("TODO: 16-bit timer mode 0x%x\n", s->mode[n]);
98
    }
99
    s->tick[n] = tick;
100
    qemu_mod_timer(s->timer[n], tick);
101
}
102

    
103
static void gptm_tick(void *opaque)
104
{
105
    gptm_state **p = (gptm_state **)opaque;
106
    gptm_state *s;
107
    int n;
108

    
109
    s = *p;
110
    n = p - s->opaque;
111
    if (s->config == 0) {
112
        s->state |= 1;
113
        if ((s->control & 0x20)) {
114
            /* Output trigger.  */
115
            qemu_irq_pulse(s->trigger);
116
        }
117
        if (s->mode[0] & 1) {
118
            /* One-shot.  */
119
            s->control &= ~1;
120
        } else {
121
            /* Periodic.  */
122
            gptm_reload(s, 0, 0);
123
        }
124
    } else if (s->config == 1) {
125
        /* RTC.  */
126
        uint32_t match;
127
        s->rtc++;
128
        match = s->match[0] | (s->match[1] << 16);
129
        if (s->rtc > match)
130
            s->rtc = 0;
131
        if (s->rtc == 0) {
132
            s->state |= 8;
133
        }
134
        gptm_reload(s, 0, 0);
135
    } else if (s->mode[n] == 0xa) {
136
        /* PWM mode.  Not implemented.  */
137
    } else {
138
        hw_error("TODO: 16-bit timer mode 0x%x\n", s->mode[n]);
139
    }
140
    gptm_update_irq(s);
141
}
142

    
143
static uint32_t gptm_read(void *opaque, target_phys_addr_t offset)
144
{
145
    gptm_state *s = (gptm_state *)opaque;
146

    
147
    switch (offset) {
148
    case 0x00: /* CFG */
149
        return s->config;
150
    case 0x04: /* TAMR */
151
        return s->mode[0];
152
    case 0x08: /* TBMR */
153
        return s->mode[1];
154
    case 0x0c: /* CTL */
155
        return s->control;
156
    case 0x18: /* IMR */
157
        return s->mask;
158
    case 0x1c: /* RIS */
159
        return s->state;
160
    case 0x20: /* MIS */
161
        return s->state & s->mask;
162
    case 0x24: /* CR */
163
        return 0;
164
    case 0x28: /* TAILR */
165
        return s->load[0] | ((s->config < 4) ? (s->load[1] << 16) : 0);
166
    case 0x2c: /* TBILR */
167
        return s->load[1];
168
    case 0x30: /* TAMARCHR */
169
        return s->match[0] | ((s->config < 4) ? (s->match[1] << 16) : 0);
170
    case 0x34: /* TBMATCHR */
171
        return s->match[1];
172
    case 0x38: /* TAPR */
173
        return s->prescale[0];
174
    case 0x3c: /* TBPR */
175
        return s->prescale[1];
176
    case 0x40: /* TAPMR */
177
        return s->match_prescale[0];
178
    case 0x44: /* TBPMR */
179
        return s->match_prescale[1];
180
    case 0x48: /* TAR */
181
        if (s->control == 1)
182
            return s->rtc;
183
    case 0x4c: /* TBR */
184
        hw_error("TODO: Timer value read\n");
185
    default:
186
        hw_error("gptm_read: Bad offset 0x%x\n", (int)offset);
187
        return 0;
188
    }
189
}
190

    
191
static void gptm_write(void *opaque, target_phys_addr_t offset, uint32_t value)
192
{
193
    gptm_state *s = (gptm_state *)opaque;
194
    uint32_t oldval;
195

    
196
    /* The timers should be disabled before changing the configuration.
197
       We take advantage of this and defer everything until the timer
198
       is enabled.  */
199
    switch (offset) {
200
    case 0x00: /* CFG */
201
        s->config = value;
202
        break;
203
    case 0x04: /* TAMR */
204
        s->mode[0] = value;
205
        break;
206
    case 0x08: /* TBMR */
207
        s->mode[1] = value;
208
        break;
209
    case 0x0c: /* CTL */
210
        oldval = s->control;
211
        s->control = value;
212
        /* TODO: Implement pause.  */
213
        if ((oldval ^ value) & 1) {
214
            if (value & 1) {
215
                gptm_reload(s, 0, 1);
216
            } else {
217
                gptm_stop(s, 0);
218
            }
219
        }
220
        if (((oldval ^ value) & 0x100) && s->config >= 4) {
221
            if (value & 0x100) {
222
                gptm_reload(s, 1, 1);
223
            } else {
224
                gptm_stop(s, 1);
225
            }
226
        }
227
        break;
228
    case 0x18: /* IMR */
229
        s->mask = value & 0x77;
230
        gptm_update_irq(s);
231
        break;
232
    case 0x24: /* CR */
233
        s->state &= ~value;
234
        break;
235
    case 0x28: /* TAILR */
236
        s->load[0] = value & 0xffff;
237
        if (s->config < 4) {
238
            s->load[1] = value >> 16;
239
        }
240
        break;
241
    case 0x2c: /* TBILR */
242
        s->load[1] = value & 0xffff;
243
        break;
244
    case 0x30: /* TAMARCHR */
245
        s->match[0] = value & 0xffff;
246
        if (s->config < 4) {
247
            s->match[1] = value >> 16;
248
        }
249
        break;
250
    case 0x34: /* TBMATCHR */
251
        s->match[1] = value >> 16;
252
        break;
253
    case 0x38: /* TAPR */
254
        s->prescale[0] = value;
255
        break;
256
    case 0x3c: /* TBPR */
257
        s->prescale[1] = value;
258
        break;
259
    case 0x40: /* TAPMR */
260
        s->match_prescale[0] = value;
261
        break;
262
    case 0x44: /* TBPMR */
263
        s->match_prescale[0] = value;
264
        break;
265
    default:
266
        hw_error("gptm_write: Bad offset 0x%x\n", (int)offset);
267
    }
268
    gptm_update_irq(s);
269
}
270

    
271
static CPUReadMemoryFunc * const gptm_readfn[] = {
272
   gptm_read,
273
   gptm_read,
274
   gptm_read
275
};
276

    
277
static CPUWriteMemoryFunc * const gptm_writefn[] = {
278
   gptm_write,
279
   gptm_write,
280
   gptm_write
281
};
282

    
283
static void gptm_save(QEMUFile *f, void *opaque)
284
{
285
    gptm_state *s = (gptm_state *)opaque;
286

    
287
    qemu_put_be32(f, s->config);
288
    qemu_put_be32(f, s->mode[0]);
289
    qemu_put_be32(f, s->mode[1]);
290
    qemu_put_be32(f, s->control);
291
    qemu_put_be32(f, s->state);
292
    qemu_put_be32(f, s->mask);
293
    qemu_put_be32(f, s->mode[0]);
294
    qemu_put_be32(f, s->mode[0]);
295
    qemu_put_be32(f, s->load[0]);
296
    qemu_put_be32(f, s->load[1]);
297
    qemu_put_be32(f, s->match[0]);
298
    qemu_put_be32(f, s->match[1]);
299
    qemu_put_be32(f, s->prescale[0]);
300
    qemu_put_be32(f, s->prescale[1]);
301
    qemu_put_be32(f, s->match_prescale[0]);
302
    qemu_put_be32(f, s->match_prescale[1]);
303
    qemu_put_be32(f, s->rtc);
304
    qemu_put_be64(f, s->tick[0]);
305
    qemu_put_be64(f, s->tick[1]);
306
    qemu_put_timer(f, s->timer[0]);
307
    qemu_put_timer(f, s->timer[1]);
308
}
309

    
310
static int gptm_load(QEMUFile *f, void *opaque, int version_id)
311
{
312
    gptm_state *s = (gptm_state *)opaque;
313

    
314
    if (version_id != 1)
315
        return -EINVAL;
316

    
317
    s->config = qemu_get_be32(f);
318
    s->mode[0] = qemu_get_be32(f);
319
    s->mode[1] = qemu_get_be32(f);
320
    s->control = qemu_get_be32(f);
321
    s->state = qemu_get_be32(f);
322
    s->mask = qemu_get_be32(f);
323
    s->mode[0] = qemu_get_be32(f);
324
    s->mode[0] = qemu_get_be32(f);
325
    s->load[0] = qemu_get_be32(f);
326
    s->load[1] = qemu_get_be32(f);
327
    s->match[0] = qemu_get_be32(f);
328
    s->match[1] = qemu_get_be32(f);
329
    s->prescale[0] = qemu_get_be32(f);
330
    s->prescale[1] = qemu_get_be32(f);
331
    s->match_prescale[0] = qemu_get_be32(f);
332
    s->match_prescale[1] = qemu_get_be32(f);
333
    s->rtc = qemu_get_be32(f);
334
    s->tick[0] = qemu_get_be64(f);
335
    s->tick[1] = qemu_get_be64(f);
336
    qemu_get_timer(f, s->timer[0]);
337
    qemu_get_timer(f, s->timer[1]);
338

    
339
    return 0;
340
}
341

    
342
static int stellaris_gptm_init(SysBusDevice *dev)
343
{
344
    int iomemtype;
345
    gptm_state *s = FROM_SYSBUS(gptm_state, dev);
346

    
347
    sysbus_init_irq(dev, &s->irq);
348
    qdev_init_gpio_out(&dev->qdev, &s->trigger, 1);
349

    
350
    iomemtype = cpu_register_io_memory(gptm_readfn,
351
                                       gptm_writefn, s);
352
    sysbus_init_mmio(dev, 0x1000, iomemtype);
353

    
354
    s->opaque[0] = s->opaque[1] = s;
355
    s->timer[0] = qemu_new_timer(vm_clock, gptm_tick, &s->opaque[0]);
356
    s->timer[1] = qemu_new_timer(vm_clock, gptm_tick, &s->opaque[1]);
357
    register_savevm("stellaris_gptm", -1, 1, gptm_save, gptm_load, s);
358
    return 0;
359
}
360

    
361

    
362
/* System controller.  */
363

    
364
typedef struct {
365
    uint32_t pborctl;
366
    uint32_t ldopctl;
367
    uint32_t int_status;
368
    uint32_t int_mask;
369
    uint32_t resc;
370
    uint32_t rcc;
371
    uint32_t rcgc[3];
372
    uint32_t scgc[3];
373
    uint32_t dcgc[3];
374
    uint32_t clkvclr;
375
    uint32_t ldoarst;
376
    uint32_t user0;
377
    uint32_t user1;
378
    qemu_irq irq;
379
    stellaris_board_info *board;
380
} ssys_state;
381

    
382
static void ssys_update(ssys_state *s)
383
{
384
  qemu_set_irq(s->irq, (s->int_status & s->int_mask) != 0);
385
}
386

    
387
static uint32_t pllcfg_sandstorm[16] = {
388
    0x31c0, /* 1 Mhz */
389
    0x1ae0, /* 1.8432 Mhz */
390
    0x18c0, /* 2 Mhz */
391
    0xd573, /* 2.4576 Mhz */
392
    0x37a6, /* 3.57954 Mhz */
393
    0x1ae2, /* 3.6864 Mhz */
394
    0x0c40, /* 4 Mhz */
395
    0x98bc, /* 4.906 Mhz */
396
    0x935b, /* 4.9152 Mhz */
397
    0x09c0, /* 5 Mhz */
398
    0x4dee, /* 5.12 Mhz */
399
    0x0c41, /* 6 Mhz */
400
    0x75db, /* 6.144 Mhz */
401
    0x1ae6, /* 7.3728 Mhz */
402
    0x0600, /* 8 Mhz */
403
    0x585b /* 8.192 Mhz */
404
};
405

    
406
static uint32_t pllcfg_fury[16] = {
407
    0x3200, /* 1 Mhz */
408
    0x1b20, /* 1.8432 Mhz */
409
    0x1900, /* 2 Mhz */
410
    0xf42b, /* 2.4576 Mhz */
411
    0x37e3, /* 3.57954 Mhz */
412
    0x1b21, /* 3.6864 Mhz */
413
    0x0c80, /* 4 Mhz */
414
    0x98ee, /* 4.906 Mhz */
415
    0xd5b4, /* 4.9152 Mhz */
416
    0x0a00, /* 5 Mhz */
417
    0x4e27, /* 5.12 Mhz */
418
    0x1902, /* 6 Mhz */
419
    0xec1c, /* 6.144 Mhz */
420
    0x1b23, /* 7.3728 Mhz */
421
    0x0640, /* 8 Mhz */
422
    0xb11c /* 8.192 Mhz */
423
};
424

    
425
static uint32_t ssys_read(void *opaque, target_phys_addr_t offset)
426
{
427
    ssys_state *s = (ssys_state *)opaque;
428

    
429
    switch (offset) {
430
    case 0x000: /* DID0 */
431
        return s->board->did0;
432
    case 0x004: /* DID1 */
433
        return s->board->did1;
434
    case 0x008: /* DC0 */
435
        return s->board->dc0;
436
    case 0x010: /* DC1 */
437
        return s->board->dc1;
438
    case 0x014: /* DC2 */
439
        return s->board->dc2;
440
    case 0x018: /* DC3 */
441
        return s->board->dc3;
442
    case 0x01c: /* DC4 */
443
        return s->board->dc4;
444
    case 0x030: /* PBORCTL */
445
        return s->pborctl;
446
    case 0x034: /* LDOPCTL */
447
        return s->ldopctl;
448
    case 0x040: /* SRCR0 */
449
        return 0;
450
    case 0x044: /* SRCR1 */
451
        return 0;
452
    case 0x048: /* SRCR2 */
453
        return 0;
454
    case 0x050: /* RIS */
455
        return s->int_status;
456
    case 0x054: /* IMC */
457
        return s->int_mask;
458
    case 0x058: /* MISC */
459
        return s->int_status & s->int_mask;
460
    case 0x05c: /* RESC */
461
        return s->resc;
462
    case 0x060: /* RCC */
463
        return s->rcc;
464
    case 0x064: /* PLLCFG */
465
        {
466
            int xtal;
467
            xtal = (s->rcc >> 6) & 0xf;
468
            if (s->board->did0 & (1 << 16)) {
469
                return pllcfg_fury[xtal];
470
            } else {
471
                return pllcfg_sandstorm[xtal];
472
            }
473
        }
474
    case 0x100: /* RCGC0 */
475
        return s->rcgc[0];
476
    case 0x104: /* RCGC1 */
477
        return s->rcgc[1];
478
    case 0x108: /* RCGC2 */
479
        return s->rcgc[2];
480
    case 0x110: /* SCGC0 */
481
        return s->scgc[0];
482
    case 0x114: /* SCGC1 */
483
        return s->scgc[1];
484
    case 0x118: /* SCGC2 */
485
        return s->scgc[2];
486
    case 0x120: /* DCGC0 */
487
        return s->dcgc[0];
488
    case 0x124: /* DCGC1 */
489
        return s->dcgc[1];
490
    case 0x128: /* DCGC2 */
491
        return s->dcgc[2];
492
    case 0x150: /* CLKVCLR */
493
        return s->clkvclr;
494
    case 0x160: /* LDOARST */
495
        return s->ldoarst;
496
    case 0x1e0: /* USER0 */
497
        return s->user0;
498
    case 0x1e4: /* USER1 */
499
        return s->user1;
500
    default:
501
        hw_error("ssys_read: Bad offset 0x%x\n", (int)offset);
502
        return 0;
503
    }
504
}
505

    
506
static void ssys_calculate_system_clock(ssys_state *s)
507
{
508
    system_clock_scale = 5 * (((s->rcc >> 23) & 0xf) + 1);
509
}
510

    
511
static void ssys_write(void *opaque, target_phys_addr_t offset, uint32_t value)
512
{
513
    ssys_state *s = (ssys_state *)opaque;
514

    
515
    switch (offset) {
516
    case 0x030: /* PBORCTL */
517
        s->pborctl = value & 0xffff;
518
        break;
519
    case 0x034: /* LDOPCTL */
520
        s->ldopctl = value & 0x1f;
521
        break;
522
    case 0x040: /* SRCR0 */
523
    case 0x044: /* SRCR1 */
524
    case 0x048: /* SRCR2 */
525
        fprintf(stderr, "Peripheral reset not implemented\n");
526
        break;
527
    case 0x054: /* IMC */
528
        s->int_mask = value & 0x7f;
529
        break;
530
    case 0x058: /* MISC */
531
        s->int_status &= ~value;
532
        break;
533
    case 0x05c: /* RESC */
534
        s->resc = value & 0x3f;
535
        break;
536
    case 0x060: /* RCC */
537
        if ((s->rcc & (1 << 13)) != 0 && (value & (1 << 13)) == 0) {
538
            /* PLL enable.  */
539
            s->int_status |= (1 << 6);
540
        }
541
        s->rcc = value;
542
        ssys_calculate_system_clock(s);
543
        break;
544
    case 0x100: /* RCGC0 */
545
        s->rcgc[0] = value;
546
        break;
547
    case 0x104: /* RCGC1 */
548
        s->rcgc[1] = value;
549
        break;
550
    case 0x108: /* RCGC2 */
551
        s->rcgc[2] = value;
552
        break;
553
    case 0x110: /* SCGC0 */
554
        s->scgc[0] = value;
555
        break;
556
    case 0x114: /* SCGC1 */
557
        s->scgc[1] = value;
558
        break;
559
    case 0x118: /* SCGC2 */
560
        s->scgc[2] = value;
561
        break;
562
    case 0x120: /* DCGC0 */
563
        s->dcgc[0] = value;
564
        break;
565
    case 0x124: /* DCGC1 */
566
        s->dcgc[1] = value;
567
        break;
568
    case 0x128: /* DCGC2 */
569
        s->dcgc[2] = value;
570
        break;
571
    case 0x150: /* CLKVCLR */
572
        s->clkvclr = value;
573
        break;
574
    case 0x160: /* LDOARST */
575
        s->ldoarst = value;
576
        break;
577
    default:
578
        hw_error("ssys_write: Bad offset 0x%x\n", (int)offset);
579
    }
580
    ssys_update(s);
581
}
582

    
583
static CPUReadMemoryFunc * const ssys_readfn[] = {
584
   ssys_read,
585
   ssys_read,
586
   ssys_read
587
};
588

    
589
static CPUWriteMemoryFunc * const ssys_writefn[] = {
590
   ssys_write,
591
   ssys_write,
592
   ssys_write
593
};
594

    
595
static void ssys_reset(void *opaque)
596
{
597
    ssys_state *s = (ssys_state *)opaque;
598

    
599
    s->pborctl = 0x7ffd;
600
    s->rcc = 0x078e3ac0;
601
    s->rcgc[0] = 1;
602
    s->scgc[0] = 1;
603
    s->dcgc[0] = 1;
604
}
605

    
606
static void ssys_save(QEMUFile *f, void *opaque)
607
{
608
    ssys_state *s = (ssys_state *)opaque;
609

    
610
    qemu_put_be32(f, s->pborctl);
611
    qemu_put_be32(f, s->ldopctl);
612
    qemu_put_be32(f, s->int_mask);
613
    qemu_put_be32(f, s->int_status);
614
    qemu_put_be32(f, s->resc);
615
    qemu_put_be32(f, s->rcc);
616
    qemu_put_be32(f, s->rcgc[0]);
617
    qemu_put_be32(f, s->rcgc[1]);
618
    qemu_put_be32(f, s->rcgc[2]);
619
    qemu_put_be32(f, s->scgc[0]);
620
    qemu_put_be32(f, s->scgc[1]);
621
    qemu_put_be32(f, s->scgc[2]);
622
    qemu_put_be32(f, s->dcgc[0]);
623
    qemu_put_be32(f, s->dcgc[1]);
624
    qemu_put_be32(f, s->dcgc[2]);
625
    qemu_put_be32(f, s->clkvclr);
626
    qemu_put_be32(f, s->ldoarst);
627
}
628

    
629
static int ssys_load(QEMUFile *f, void *opaque, int version_id)
630
{
631
    ssys_state *s = (ssys_state *)opaque;
632

    
633
    if (version_id != 1)
634
        return -EINVAL;
635

    
636
    s->pborctl = qemu_get_be32(f);
637
    s->ldopctl = qemu_get_be32(f);
638
    s->int_mask = qemu_get_be32(f);
639
    s->int_status = qemu_get_be32(f);
640
    s->resc = qemu_get_be32(f);
641
    s->rcc = qemu_get_be32(f);
642
    s->rcgc[0] = qemu_get_be32(f);
643
    s->rcgc[1] = qemu_get_be32(f);
644
    s->rcgc[2] = qemu_get_be32(f);
645
    s->scgc[0] = qemu_get_be32(f);
646
    s->scgc[1] = qemu_get_be32(f);
647
    s->scgc[2] = qemu_get_be32(f);
648
    s->dcgc[0] = qemu_get_be32(f);
649
    s->dcgc[1] = qemu_get_be32(f);
650
    s->dcgc[2] = qemu_get_be32(f);
651
    s->clkvclr = qemu_get_be32(f);
652
    s->ldoarst = qemu_get_be32(f);
653
    ssys_calculate_system_clock(s);
654

    
655
    return 0;
656
}
657

    
658
static int stellaris_sys_init(uint32_t base, qemu_irq irq,
659
                              stellaris_board_info * board,
660
                              uint8_t *macaddr)
661
{
662
    int iomemtype;
663
    ssys_state *s;
664

    
665
    s = (ssys_state *)qemu_mallocz(sizeof(ssys_state));
666
    s->irq = irq;
667
    s->board = board;
668
    /* Most devices come preprogrammed with a MAC address in the user data. */
669
    s->user0 = macaddr[0] | (macaddr[1] << 8) | (macaddr[2] << 16);
670
    s->user1 = macaddr[3] | (macaddr[4] << 8) | (macaddr[5] << 16);
671

    
672
    iomemtype = cpu_register_io_memory(ssys_readfn,
673
                                       ssys_writefn, s);
674
    cpu_register_physical_memory(base, 0x00001000, iomemtype);
675
    ssys_reset(s);
676
    register_savevm("stellaris_sys", -1, 1, ssys_save, ssys_load, s);
677
    return 0;
678
}
679

    
680

    
681
/* I2C controller.  */
682

    
683
typedef struct {
684
    SysBusDevice busdev;
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
        hw_error("strllaris_i2c_read: Bad offset 0x%x\n", (int)offset);
728
        return 0;
729
    }
730
}
731

    
732
static void stellaris_i2c_update(stellaris_i2c_state *s)
733
{
734
    int level;
735

    
736
    level = (s->mris & s->mimr) != 0;
737
    qemu_set_irq(s->irq, level);
738
}
739

    
740
static void stellaris_i2c_write(void *opaque, target_phys_addr_t offset,
741
                                uint32_t value)
742
{
743
    stellaris_i2c_state *s = (stellaris_i2c_state *)opaque;
744

    
745
    switch (offset) {
746
    case 0x00: /* MSA */
747
        s->msa = value & 0xff;
748
        break;
749
    case 0x04: /* MCS */
750
        if ((s->mcr & 0x10) == 0) {
751
            /* Disabled.  Do nothing.  */
752
            break;
753
        }
754
        /* Grab the bus if this is starting a transfer.  */
755
        if ((value & 2) && (s->mcs & STELLARIS_I2C_MCS_BUSBSY) == 0) {
756
            if (i2c_start_transfer(s->bus, s->msa >> 1, s->msa & 1)) {
757
                s->mcs |= STELLARIS_I2C_MCS_ARBLST;
758
            } else {
759
                s->mcs &= ~STELLARIS_I2C_MCS_ARBLST;
760
                s->mcs |= STELLARIS_I2C_MCS_BUSBSY;
761
            }
762
        }
763
        /* If we don't have the bus then indicate an error.  */
764
        if (!i2c_bus_busy(s->bus)
765
                || (s->mcs & STELLARIS_I2C_MCS_BUSBSY) == 0) {
766
            s->mcs |= STELLARIS_I2C_MCS_ERROR;
767
            break;
768
        }
769
        s->mcs &= ~STELLARIS_I2C_MCS_ERROR;
770
        if (value & 1) {
771
            /* Transfer a byte.  */
772
            /* TODO: Handle errors.  */
773
            if (s->msa & 1) {
774
                /* Recv */
775
                s->mdr = i2c_recv(s->bus) & 0xff;
776
            } else {
777
                /* Send */
778
                i2c_send(s->bus, s->mdr);
779
            }
780
            /* Raise an interrupt.  */
781
            s->mris |= 1;
782
        }
783
        if (value & 4) {
784
            /* Finish transfer.  */
785
            i2c_end_transfer(s->bus);
786
            s->mcs &= ~STELLARIS_I2C_MCS_BUSBSY;
787
        }
788
        break;
789
    case 0x08: /* MDR */
790
        s->mdr = value & 0xff;
791
        break;
792
    case 0x0c: /* MTPR */
793
        s->mtpr = value & 0xff;
794
        break;
795
    case 0x10: /* MIMR */
796
        s->mimr = 1;
797
        break;
798
    case 0x1c: /* MICR */
799
        s->mris &= ~value;
800
        break;
801
    case 0x20: /* MCR */
802
        if (value & 1)
803
            hw_error(
804
                      "stellaris_i2c_write: Loopback not implemented\n");
805
        if (value & 0x20)
806
            hw_error(
807
                      "stellaris_i2c_write: Slave mode not implemented\n");
808
        s->mcr = value & 0x31;
809
        break;
810
    default:
811
        hw_error("stellaris_i2c_write: Bad offset 0x%x\n",
812
                  (int)offset);
813
    }
814
    stellaris_i2c_update(s);
815
}
816

    
817
static void stellaris_i2c_reset(stellaris_i2c_state *s)
818
{
819
    if (s->mcs & STELLARIS_I2C_MCS_BUSBSY)
820
        i2c_end_transfer(s->bus);
821

    
822
    s->msa = 0;
823
    s->mcs = 0;
824
    s->mdr = 0;
825
    s->mtpr = 1;
826
    s->mimr = 0;
827
    s->mris = 0;
828
    s->mcr = 0;
829
    stellaris_i2c_update(s);
830
}
831

    
832
static CPUReadMemoryFunc * const stellaris_i2c_readfn[] = {
833
   stellaris_i2c_read,
834
   stellaris_i2c_read,
835
   stellaris_i2c_read
836
};
837

    
838
static CPUWriteMemoryFunc * const stellaris_i2c_writefn[] = {
839
   stellaris_i2c_write,
840
   stellaris_i2c_write,
841
   stellaris_i2c_write
842
};
843

    
844
static void stellaris_i2c_save(QEMUFile *f, void *opaque)
845
{
846
    stellaris_i2c_state *s = (stellaris_i2c_state *)opaque;
847

    
848
    qemu_put_be32(f, s->msa);
849
    qemu_put_be32(f, s->mcs);
850
    qemu_put_be32(f, s->mdr);
851
    qemu_put_be32(f, s->mtpr);
852
    qemu_put_be32(f, s->mimr);
853
    qemu_put_be32(f, s->mris);
854
    qemu_put_be32(f, s->mcr);
855
}
856

    
857
static int stellaris_i2c_load(QEMUFile *f, void *opaque, int version_id)
858
{
859
    stellaris_i2c_state *s = (stellaris_i2c_state *)opaque;
860

    
861
    if (version_id != 1)
862
        return -EINVAL;
863

    
864
    s->msa = qemu_get_be32(f);
865
    s->mcs = qemu_get_be32(f);
866
    s->mdr = qemu_get_be32(f);
867
    s->mtpr = qemu_get_be32(f);
868
    s->mimr = qemu_get_be32(f);
869
    s->mris = qemu_get_be32(f);
870
    s->mcr = qemu_get_be32(f);
871

    
872
    return 0;
873
}
874

    
875
static int stellaris_i2c_init(SysBusDevice * dev)
876
{
877
    stellaris_i2c_state *s = FROM_SYSBUS(stellaris_i2c_state, dev);
878
    i2c_bus *bus;
879
    int iomemtype;
880

    
881
    sysbus_init_irq(dev, &s->irq);
882
    bus = i2c_init_bus(&dev->qdev, "i2c");
883
    s->bus = bus;
884

    
885
    iomemtype = cpu_register_io_memory(stellaris_i2c_readfn,
886
                                       stellaris_i2c_writefn, s);
887
    sysbus_init_mmio(dev, 0x1000, iomemtype);
888
    /* ??? For now we only implement the master interface.  */
889
    stellaris_i2c_reset(s);
890
    register_savevm("stellaris_i2c", -1, 1,
891
                    stellaris_i2c_save, stellaris_i2c_load, s);
892
    return 0;
893
}
894

    
895
/* Analogue to Digital Converter.  This is only partially implemented,
896
   enough for applications that use a combined ADC and timer tick.  */
897

    
898
#define STELLARIS_ADC_EM_CONTROLLER 0
899
#define STELLARIS_ADC_EM_COMP       1
900
#define STELLARIS_ADC_EM_EXTERNAL   4
901
#define STELLARIS_ADC_EM_TIMER      5
902
#define STELLARIS_ADC_EM_PWM0       6
903
#define STELLARIS_ADC_EM_PWM1       7
904
#define STELLARIS_ADC_EM_PWM2       8
905

    
906
#define STELLARIS_ADC_FIFO_EMPTY    0x0100
907
#define STELLARIS_ADC_FIFO_FULL     0x1000
908

    
909
typedef struct
910
{
911
    SysBusDevice busdev;
912
    uint32_t actss;
913
    uint32_t ris;
914
    uint32_t im;
915
    uint32_t emux;
916
    uint32_t ostat;
917
    uint32_t ustat;
918
    uint32_t sspri;
919
    uint32_t sac;
920
    struct {
921
        uint32_t state;
922
        uint32_t data[16];
923
    } fifo[4];
924
    uint32_t ssmux[4];
925
    uint32_t ssctl[4];
926
    uint32_t noise;
927
    qemu_irq irq[4];
928
} stellaris_adc_state;
929

    
930
static uint32_t stellaris_adc_fifo_read(stellaris_adc_state *s, int n)
931
{
932
    int tail;
933

    
934
    tail = s->fifo[n].state & 0xf;
935
    if (s->fifo[n].state & STELLARIS_ADC_FIFO_EMPTY) {
936
        s->ustat |= 1 << n;
937
    } else {
938
        s->fifo[n].state = (s->fifo[n].state & ~0xf) | ((tail + 1) & 0xf);
939
        s->fifo[n].state &= ~STELLARIS_ADC_FIFO_FULL;
940
        if (tail + 1 == ((s->fifo[n].state >> 4) & 0xf))
941
            s->fifo[n].state |= STELLARIS_ADC_FIFO_EMPTY;
942
    }
943
    return s->fifo[n].data[tail];
944
}
945

    
946
static void stellaris_adc_fifo_write(stellaris_adc_state *s, int n,
947
                                     uint32_t value)
948
{
949
    int head;
950

    
951
    /* TODO: Real hardware has limited size FIFOs.  We have a full 16 entry 
952
       FIFO fir each sequencer.  */
953
    head = (s->fifo[n].state >> 4) & 0xf;
954
    if (s->fifo[n].state & STELLARIS_ADC_FIFO_FULL) {
955
        s->ostat |= 1 << n;
956
        return;
957
    }
958
    s->fifo[n].data[head] = value;
959
    head = (head + 1) & 0xf;
960
    s->fifo[n].state &= ~STELLARIS_ADC_FIFO_EMPTY;
961
    s->fifo[n].state = (s->fifo[n].state & ~0xf0) | (head << 4);
962
    if ((s->fifo[n].state & 0xf) == head)
963
        s->fifo[n].state |= STELLARIS_ADC_FIFO_FULL;
964
}
965

    
966
static void stellaris_adc_update(stellaris_adc_state *s)
967
{
968
    int level;
969
    int n;
970

    
971
    for (n = 0; n < 4; n++) {
972
        level = (s->ris & s->im & (1 << n)) != 0;
973
        qemu_set_irq(s->irq[n], level);
974
    }
975
}
976

    
977
static void stellaris_adc_trigger(void *opaque, int irq, int level)
978
{
979
    stellaris_adc_state *s = (stellaris_adc_state *)opaque;
980
    int n;
981

    
982
    for (n = 0; n < 4; n++) {
983
        if ((s->actss & (1 << n)) == 0) {
984
            continue;
985
        }
986

    
987
        if (((s->emux >> (n * 4)) & 0xff) != 5) {
988
            continue;
989
        }
990

    
991
        /* Some applications use the ADC as a random number source, so introduce
992
           some variation into the signal.  */
993
        s->noise = s->noise * 314159 + 1;
994
        /* ??? actual inputs not implemented.  Return an arbitrary value.  */
995
        stellaris_adc_fifo_write(s, n, 0x200 + ((s->noise >> 16) & 7));
996
        s->ris |= (1 << n);
997
        stellaris_adc_update(s);
998
    }
999
}
1000

    
1001
static void stellaris_adc_reset(stellaris_adc_state *s)
1002
{
1003
    int n;
1004

    
1005
    for (n = 0; n < 4; n++) {
1006
        s->ssmux[n] = 0;
1007
        s->ssctl[n] = 0;
1008
        s->fifo[n].state = STELLARIS_ADC_FIFO_EMPTY;
1009
    }
1010
}
1011

    
1012
static uint32_t stellaris_adc_read(void *opaque, target_phys_addr_t offset)
1013
{
1014
    stellaris_adc_state *s = (stellaris_adc_state *)opaque;
1015

    
1016
    /* TODO: Implement this.  */
1017
    if (offset >= 0x40 && offset < 0xc0) {
1018
        int n;
1019
        n = (offset - 0x40) >> 5;
1020
        switch (offset & 0x1f) {
1021
        case 0x00: /* SSMUX */
1022
            return s->ssmux[n];
1023
        case 0x04: /* SSCTL */
1024
            return s->ssctl[n];
1025
        case 0x08: /* SSFIFO */
1026
            return stellaris_adc_fifo_read(s, n);
1027
        case 0x0c: /* SSFSTAT */
1028
            return s->fifo[n].state;
1029
        default:
1030
            break;
1031
        }
1032
    }
1033
    switch (offset) {
1034
    case 0x00: /* ACTSS */
1035
        return s->actss;
1036
    case 0x04: /* RIS */
1037
        return s->ris;
1038
    case 0x08: /* IM */
1039
        return s->im;
1040
    case 0x0c: /* ISC */
1041
        return s->ris & s->im;
1042
    case 0x10: /* OSTAT */
1043
        return s->ostat;
1044
    case 0x14: /* EMUX */
1045
        return s->emux;
1046
    case 0x18: /* USTAT */
1047
        return s->ustat;
1048
    case 0x20: /* SSPRI */
1049
        return s->sspri;
1050
    case 0x30: /* SAC */
1051
        return s->sac;
1052
    default:
1053
        hw_error("strllaris_adc_read: Bad offset 0x%x\n",
1054
                  (int)offset);
1055
        return 0;
1056
    }
1057
}
1058

    
1059
static void stellaris_adc_write(void *opaque, target_phys_addr_t offset,
1060
                                uint32_t value)
1061
{
1062
    stellaris_adc_state *s = (stellaris_adc_state *)opaque;
1063

    
1064
    /* TODO: Implement this.  */
1065
    if (offset >= 0x40 && offset < 0xc0) {
1066
        int n;
1067
        n = (offset - 0x40) >> 5;
1068
        switch (offset & 0x1f) {
1069
        case 0x00: /* SSMUX */
1070
            s->ssmux[n] = value & 0x33333333;
1071
            return;
1072
        case 0x04: /* SSCTL */
1073
            if (value != 6) {
1074
                hw_error("ADC: Unimplemented sequence %x\n",
1075
                          value);
1076
            }
1077
            s->ssctl[n] = value;
1078
            return;
1079
        default:
1080
            break;
1081
        }
1082
    }
1083
    switch (offset) {
1084
    case 0x00: /* ACTSS */
1085
        s->actss = value & 0xf;
1086
        break;
1087
    case 0x08: /* IM */
1088
        s->im = value;
1089
        break;
1090
    case 0x0c: /* ISC */
1091
        s->ris &= ~value;
1092
        break;
1093
    case 0x10: /* OSTAT */
1094
        s->ostat &= ~value;
1095
        break;
1096
    case 0x14: /* EMUX */
1097
        s->emux = value;
1098
        break;
1099
    case 0x18: /* USTAT */
1100
        s->ustat &= ~value;
1101
        break;
1102
    case 0x20: /* SSPRI */
1103
        s->sspri = value;
1104
        break;
1105
    case 0x28: /* PSSI */
1106
        hw_error("Not implemented:  ADC sample initiate\n");
1107
        break;
1108
    case 0x30: /* SAC */
1109
        s->sac = value;
1110
        break;
1111
    default:
1112
        hw_error("stellaris_adc_write: Bad offset 0x%x\n", (int)offset);
1113
    }
1114
    stellaris_adc_update(s);
1115
}
1116

    
1117
static CPUReadMemoryFunc * const stellaris_adc_readfn[] = {
1118
   stellaris_adc_read,
1119
   stellaris_adc_read,
1120
   stellaris_adc_read
1121
};
1122

    
1123
static CPUWriteMemoryFunc * const stellaris_adc_writefn[] = {
1124
   stellaris_adc_write,
1125
   stellaris_adc_write,
1126
   stellaris_adc_write
1127
};
1128

    
1129
static void stellaris_adc_save(QEMUFile *f, void *opaque)
1130
{
1131
    stellaris_adc_state *s = (stellaris_adc_state *)opaque;
1132
    int i;
1133
    int j;
1134

    
1135
    qemu_put_be32(f, s->actss);
1136
    qemu_put_be32(f, s->ris);
1137
    qemu_put_be32(f, s->im);
1138
    qemu_put_be32(f, s->emux);
1139
    qemu_put_be32(f, s->ostat);
1140
    qemu_put_be32(f, s->ustat);
1141
    qemu_put_be32(f, s->sspri);
1142
    qemu_put_be32(f, s->sac);
1143
    for (i = 0; i < 4; i++) {
1144
        qemu_put_be32(f, s->fifo[i].state);
1145
        for (j = 0; j < 16; j++) {
1146
            qemu_put_be32(f, s->fifo[i].data[j]);
1147
        }
1148
        qemu_put_be32(f, s->ssmux[i]);
1149
        qemu_put_be32(f, s->ssctl[i]);
1150
    }
1151
    qemu_put_be32(f, s->noise);
1152
}
1153

    
1154
static int stellaris_adc_load(QEMUFile *f, void *opaque, int version_id)
1155
{
1156
    stellaris_adc_state *s = (stellaris_adc_state *)opaque;
1157
    int i;
1158
    int j;
1159

    
1160
    if (version_id != 1)
1161
        return -EINVAL;
1162

    
1163
    s->actss = qemu_get_be32(f);
1164
    s->ris = qemu_get_be32(f);
1165
    s->im = qemu_get_be32(f);
1166
    s->emux = qemu_get_be32(f);
1167
    s->ostat = qemu_get_be32(f);
1168
    s->ustat = qemu_get_be32(f);
1169
    s->sspri = qemu_get_be32(f);
1170
    s->sac = qemu_get_be32(f);
1171
    for (i = 0; i < 4; i++) {
1172
        s->fifo[i].state = qemu_get_be32(f);
1173
        for (j = 0; j < 16; j++) {
1174
            s->fifo[i].data[j] = qemu_get_be32(f);
1175
        }
1176
        s->ssmux[i] = qemu_get_be32(f);
1177
        s->ssctl[i] = qemu_get_be32(f);
1178
    }
1179
    s->noise = qemu_get_be32(f);
1180

    
1181
    return 0;
1182
}
1183

    
1184
static int stellaris_adc_init(SysBusDevice *dev)
1185
{
1186
    stellaris_adc_state *s = FROM_SYSBUS(stellaris_adc_state, dev);
1187
    int iomemtype;
1188
    int n;
1189

    
1190
    for (n = 0; n < 4; n++) {
1191
        sysbus_init_irq(dev, &s->irq[n]);
1192
    }
1193

    
1194
    iomemtype = cpu_register_io_memory(stellaris_adc_readfn,
1195
                                       stellaris_adc_writefn, s);
1196
    sysbus_init_mmio(dev, 0x1000, iomemtype);
1197
    stellaris_adc_reset(s);
1198
    qdev_init_gpio_in(&dev->qdev, stellaris_adc_trigger, 1);
1199
    register_savevm("stellaris_adc", -1, 1,
1200
                    stellaris_adc_save, stellaris_adc_load, s);
1201
    return 0;
1202
}
1203

    
1204
/* Some boards have both an OLED controller and SD card connected to
1205
   the same SSI port, with the SD card chip select connected to a
1206
   GPIO pin.  Technically the OLED chip select is connected to the SSI
1207
   Fss pin.  We do not bother emulating that as both devices should
1208
   never be selected simultaneously, and our OLED controller ignores stray
1209
   0xff commands that occur when deselecting the SD card.  */
1210

    
1211
typedef struct {
1212
    SSISlave ssidev;
1213
    qemu_irq irq;
1214
    int current_dev;
1215
    SSIBus *bus[2];
1216
} stellaris_ssi_bus_state;
1217

    
1218
static void stellaris_ssi_bus_select(void *opaque, int irq, int level)
1219
{
1220
    stellaris_ssi_bus_state *s = (stellaris_ssi_bus_state *)opaque;
1221

    
1222
    s->current_dev = level;
1223
}
1224

    
1225
static uint32_t stellaris_ssi_bus_transfer(SSISlave *dev, uint32_t val)
1226
{
1227
    stellaris_ssi_bus_state *s = FROM_SSI_SLAVE(stellaris_ssi_bus_state, dev);
1228

    
1229
    return ssi_transfer(s->bus[s->current_dev], val);
1230
}
1231

    
1232
static void stellaris_ssi_bus_save(QEMUFile *f, void *opaque)
1233
{
1234
    stellaris_ssi_bus_state *s = (stellaris_ssi_bus_state *)opaque;
1235

    
1236
    qemu_put_be32(f, s->current_dev);
1237
}
1238

    
1239
static int stellaris_ssi_bus_load(QEMUFile *f, void *opaque, int version_id)
1240
{
1241
    stellaris_ssi_bus_state *s = (stellaris_ssi_bus_state *)opaque;
1242

    
1243
    if (version_id != 1)
1244
        return -EINVAL;
1245

    
1246
    s->current_dev = qemu_get_be32(f);
1247

    
1248
    return 0;
1249
}
1250

    
1251
static int stellaris_ssi_bus_init(SSISlave *dev)
1252
{
1253
    stellaris_ssi_bus_state *s = FROM_SSI_SLAVE(stellaris_ssi_bus_state, dev);
1254

    
1255
    s->bus[0] = ssi_create_bus(&dev->qdev, "ssi0");
1256
    s->bus[1] = ssi_create_bus(&dev->qdev, "ssi1");
1257
    qdev_init_gpio_in(&dev->qdev, stellaris_ssi_bus_select, 1);
1258

    
1259
    register_savevm("stellaris_ssi_bus", -1, 1,
1260
                    stellaris_ssi_bus_save, stellaris_ssi_bus_load, s);
1261
    return 0;
1262
}
1263

    
1264
/* Board init.  */
1265
static stellaris_board_info stellaris_boards[] = {
1266
  { "LM3S811EVB",
1267
    0,
1268
    0x0032000e,
1269
    0x001f001f, /* dc0 */
1270
    0x001132bf,
1271
    0x01071013,
1272
    0x3f0f01ff,
1273
    0x0000001f,
1274
    BP_OLED_I2C
1275
  },
1276
  { "LM3S6965EVB",
1277
    0x10010002,
1278
    0x1073402e,
1279
    0x00ff007f, /* dc0 */
1280
    0x001133ff,
1281
    0x030f5317,
1282
    0x0f0f87ff,
1283
    0x5000007f,
1284
    BP_OLED_SSI | BP_GAMEPAD
1285
  }
1286
};
1287

    
1288
static void stellaris_init(const char *kernel_filename, const char *cpu_model,
1289
                           stellaris_board_info *board)
1290
{
1291
    static const int uart_irq[] = {5, 6, 33, 34};
1292
    static const int timer_irq[] = {19, 21, 23, 35};
1293
    static const uint32_t gpio_addr[7] =
1294
      { 0x40004000, 0x40005000, 0x40006000, 0x40007000,
1295
        0x40024000, 0x40025000, 0x40026000};
1296
    static const int gpio_irq[7] = {0, 1, 2, 3, 4, 30, 31};
1297

    
1298
    qemu_irq *pic;
1299
    DeviceState *gpio_dev[7];
1300
    qemu_irq gpio_in[7][8];
1301
    qemu_irq gpio_out[7][8];
1302
    qemu_irq adc;
1303
    int sram_size;
1304
    int flash_size;
1305
    i2c_bus *i2c;
1306
    DeviceState *dev;
1307
    int i;
1308
    int j;
1309

    
1310
    flash_size = ((board->dc0 & 0xffff) + 1) << 1;
1311
    sram_size = (board->dc0 >> 18) + 1;
1312
    pic = armv7m_init(flash_size, sram_size, kernel_filename, cpu_model);
1313

    
1314
    if (board->dc1 & (1 << 16)) {
1315
        dev = sysbus_create_varargs("stellaris-adc", 0x40038000,
1316
                                    pic[14], pic[15], pic[16], pic[17], NULL);
1317
        adc = qdev_get_gpio_in(dev, 0);
1318
    } else {
1319
        adc = NULL;
1320
    }
1321
    for (i = 0; i < 4; i++) {
1322
        if (board->dc2 & (0x10000 << i)) {
1323
            dev = sysbus_create_simple("stellaris-gptm",
1324
                                       0x40030000 + i * 0x1000,
1325
                                       pic[timer_irq[i]]);
1326
            /* TODO: This is incorrect, but we get away with it because
1327
               the ADC output is only ever pulsed.  */
1328
            qdev_connect_gpio_out(dev, 0, adc);
1329
        }
1330
    }
1331

    
1332
    stellaris_sys_init(0x400fe000, pic[28], board, nd_table[0].macaddr);
1333

    
1334
    for (i = 0; i < 7; i++) {
1335
        if (board->dc4 & (1 << i)) {
1336
            gpio_dev[i] = sysbus_create_simple("pl061", gpio_addr[i],
1337
                                               pic[gpio_irq[i]]);
1338
            for (j = 0; j < 8; j++) {
1339
                gpio_in[i][j] = qdev_get_gpio_in(gpio_dev[i], j);
1340
                gpio_out[i][j] = NULL;
1341
            }
1342
        }
1343
    }
1344

    
1345
    if (board->dc2 & (1 << 12)) {
1346
        dev = sysbus_create_simple("stellaris-i2c", 0x40020000, pic[8]);
1347
        i2c = (i2c_bus *)qdev_get_child_bus(dev, "i2c");
1348
        if (board->peripherals & BP_OLED_I2C) {
1349
            i2c_create_slave(i2c, "ssd0303", 0x3d);
1350
        }
1351
    }
1352

    
1353
    for (i = 0; i < 4; i++) {
1354
        if (board->dc2 & (1 << i)) {
1355
            sysbus_create_simple("pl011_luminary", 0x4000c000 + i * 0x1000,
1356
                                 pic[uart_irq[i]]);
1357
        }
1358
    }
1359
    if (board->dc2 & (1 << 4)) {
1360
        dev = sysbus_create_simple("pl022", 0x40008000, pic[7]);
1361
        if (board->peripherals & BP_OLED_SSI) {
1362
            DeviceState *mux;
1363
            void *bus;
1364

    
1365
            bus = qdev_get_child_bus(dev, "ssi");
1366
            mux = ssi_create_slave(bus, "evb6965-ssi");
1367
            gpio_out[GPIO_D][0] = qdev_get_gpio_in(mux, 0);
1368

    
1369
            bus = qdev_get_child_bus(mux, "ssi0");
1370
            dev = ssi_create_slave(bus, "ssi-sd");
1371

    
1372
            bus = qdev_get_child_bus(mux, "ssi1");
1373
            dev = ssi_create_slave(bus, "ssd0323");
1374
            gpio_out[GPIO_C][7] = qdev_get_gpio_in(dev, 0);
1375

    
1376
            /* Make sure the select pin is high.  */
1377
            qemu_irq_raise(gpio_out[GPIO_D][0]);
1378
        }
1379
    }
1380
    if (board->dc4 & (1 << 28)) {
1381
        DeviceState *enet;
1382

    
1383
        qemu_check_nic_model(&nd_table[0], "stellaris");
1384

    
1385
        enet = qdev_create(NULL, "stellaris_enet");
1386
        enet->nd = &nd_table[0];
1387
        qdev_init(enet);
1388
        sysbus_mmio_map(sysbus_from_qdev(enet), 0, 0x40048000);
1389
        sysbus_connect_irq(sysbus_from_qdev(enet), 0, pic[42]);
1390
    }
1391
    if (board->peripherals & BP_GAMEPAD) {
1392
        qemu_irq gpad_irq[5];
1393
        static const int gpad_keycode[5] = { 0xc8, 0xd0, 0xcb, 0xcd, 0x1d };
1394

    
1395
        gpad_irq[0] = qemu_irq_invert(gpio_in[GPIO_E][0]); /* up */
1396
        gpad_irq[1] = qemu_irq_invert(gpio_in[GPIO_E][1]); /* down */
1397
        gpad_irq[2] = qemu_irq_invert(gpio_in[GPIO_E][2]); /* left */
1398
        gpad_irq[3] = qemu_irq_invert(gpio_in[GPIO_E][3]); /* right */
1399
        gpad_irq[4] = qemu_irq_invert(gpio_in[GPIO_F][1]); /* select */
1400

    
1401
        stellaris_gamepad_init(5, gpad_irq, gpad_keycode);
1402
    }
1403
    for (i = 0; i < 7; i++) {
1404
        if (board->dc4 & (1 << i)) {
1405
            for (j = 0; j < 8; j++) {
1406
                if (gpio_out[i][j]) {
1407
                    qdev_connect_gpio_out(gpio_dev[i], j, gpio_out[i][j]);
1408
                }
1409
            }
1410
        }
1411
    }
1412
}
1413

    
1414
/* FIXME: Figure out how to generate these from stellaris_boards.  */
1415
static void lm3s811evb_init(ram_addr_t ram_size,
1416
                     const char *boot_device,
1417
                     const char *kernel_filename, const char *kernel_cmdline,
1418
                     const char *initrd_filename, const char *cpu_model)
1419
{
1420
    stellaris_init(kernel_filename, cpu_model, &stellaris_boards[0]);
1421
}
1422

    
1423
static void lm3s6965evb_init(ram_addr_t ram_size,
1424
                     const char *boot_device,
1425
                     const char *kernel_filename, const char *kernel_cmdline,
1426
                     const char *initrd_filename, const char *cpu_model)
1427
{
1428
    stellaris_init(kernel_filename, cpu_model, &stellaris_boards[1]);
1429
}
1430

    
1431
static QEMUMachine lm3s811evb_machine = {
1432
    .name = "lm3s811evb",
1433
    .desc = "Stellaris LM3S811EVB",
1434
    .init = lm3s811evb_init,
1435
};
1436

    
1437
static QEMUMachine lm3s6965evb_machine = {
1438
    .name = "lm3s6965evb",
1439
    .desc = "Stellaris LM3S6965EVB",
1440
    .init = lm3s6965evb_init,
1441
};
1442

    
1443
static void stellaris_machine_init(void)
1444
{
1445
    qemu_register_machine(&lm3s811evb_machine);
1446
    qemu_register_machine(&lm3s6965evb_machine);
1447
}
1448

    
1449
machine_init(stellaris_machine_init);
1450

    
1451
static SSISlaveInfo stellaris_ssi_bus_info = {
1452
    .qdev.name = "evb6965-ssi",
1453
    .qdev.size = sizeof(stellaris_ssi_bus_state),
1454
    .init = stellaris_ssi_bus_init,
1455
    .transfer = stellaris_ssi_bus_transfer
1456
};
1457

    
1458
static void stellaris_register_devices(void)
1459
{
1460
    sysbus_register_dev("stellaris-i2c", sizeof(stellaris_i2c_state),
1461
                        stellaris_i2c_init);
1462
    sysbus_register_dev("stellaris-gptm", sizeof(gptm_state),
1463
                        stellaris_gptm_init);
1464
    sysbus_register_dev("stellaris-adc", sizeof(stellaris_adc_state),
1465
                        stellaris_adc_init);
1466
    ssi_register_slave(&stellaris_ssi_bus_info);
1467
}
1468

    
1469
device_init(stellaris_register_devices)