Statistics
| Branch: | Revision:

root / hw / stellaris.c @ 775616c3

History | View | Annotate | Download (31.4 kB)

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

    
1137
            oled = ssd0323_init(ds, &gpio_out[GPIO_C][7]);
1138
            sd = ssi_sd_init(sd_bdrv);
1139

    
1140
            ssi_bus = stellaris_ssi_bus_init(&gpio_out[GPIO_D][0],
1141
                                             ssi_sd_xfer, sd,
1142
                                             ssd0323_xfer_ssi, oled);
1143

    
1144
            pl022_init(0x40008000, pic[7], stellaris_ssi_bus_xfer, ssi_bus);
1145
            /* Make sure the select pin is high.  */
1146
            qemu_irq_raise(gpio_out[GPIO_D][0]);
1147
        } else {
1148
            pl022_init(0x40008000, pic[7], NULL, NULL);
1149
        }
1150
    }
1151
    if (board->dc4 & (1 << 28)) {
1152
        /* FIXME: Obey network model.  */
1153
        stellaris_enet_init(&nd_table[0], 0x40048000, pic[42]);
1154
    }
1155
    if (board->peripherals & BP_GAMEPAD) {
1156
        qemu_irq gpad_irq[5];
1157
        static const int gpad_keycode[5] = { 0xc8, 0xd0, 0xcb, 0xcd, 0x1d };
1158

    
1159
        gpad_irq[0] = qemu_irq_invert(gpio_in[GPIO_E][0]); /* up */
1160
        gpad_irq[1] = qemu_irq_invert(gpio_in[GPIO_E][1]); /* down */
1161
        gpad_irq[2] = qemu_irq_invert(gpio_in[GPIO_E][2]); /* left */
1162
        gpad_irq[3] = qemu_irq_invert(gpio_in[GPIO_E][3]); /* right */
1163
        gpad_irq[4] = qemu_irq_invert(gpio_in[GPIO_F][1]); /* select */
1164

    
1165
        stellaris_gamepad_init(5, gpad_irq, gpad_keycode);
1166
    }
1167
}
1168

    
1169
/* FIXME: Figure out how to generate these from stellaris_boards.  */
1170
static void lm3s811evb_init(int ram_size, int vga_ram_size,
1171
                     const char *boot_device, DisplayState *ds,
1172
                     const char *kernel_filename, const char *kernel_cmdline,
1173
                     const char *initrd_filename, const char *cpu_model)
1174
{
1175
    stellaris_init(kernel_filename, cpu_model, ds, &stellaris_boards[0]);
1176
}
1177

    
1178
static void lm3s6965evb_init(int ram_size, int vga_ram_size,
1179
                     const char *boot_device, DisplayState *ds,
1180
                     const char *kernel_filename, const char *kernel_cmdline,
1181
                     const char *initrd_filename, const char *cpu_model)
1182
{
1183
    stellaris_init(kernel_filename, cpu_model, ds, &stellaris_boards[1]);
1184
}
1185

    
1186
QEMUMachine lm3s811evb_machine = {
1187
    "lm3s811evb",
1188
    "Stellaris LM3S811EVB",
1189
    lm3s811evb_init,
1190
};
1191

    
1192
QEMUMachine lm3s6965evb_machine = {
1193
    "lm3s6965evb",
1194
    "Stellaris LM3S6965EVB",
1195
    lm3s6965evb_init,
1196
};