~vcs-imports/qemu/git

« back to all changes in this revision

Viewing changes to hw/stellaris.c

  • Committer: ths
  • Date: 2007-06-17 15:32:30 UTC
  • Revision ID: git-v1:ffb04fcf089865952592f1f8855c2848d4514a89
Allow relative paths for the interpreter prefix in linux-user emulation.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2984 c046a42c-6fe2-441c-8c8c-71466251a162

Show diffs side-by-side

added added

removed removed

Lines of Context:
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 "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 gptm_save(QEMUFile *f, void *opaque)
290
 
{
291
 
    gptm_state *s = (gptm_state *)opaque;
292
 
 
293
 
    qemu_put_be32(f, s->config);
294
 
    qemu_put_be32(f, s->mode[0]);
295
 
    qemu_put_be32(f, s->mode[1]);
296
 
    qemu_put_be32(f, s->control);
297
 
    qemu_put_be32(f, s->state);
298
 
    qemu_put_be32(f, s->mask);
299
 
    qemu_put_be32(f, s->mode[0]);
300
 
    qemu_put_be32(f, s->mode[0]);
301
 
    qemu_put_be32(f, s->load[0]);
302
 
    qemu_put_be32(f, s->load[1]);
303
 
    qemu_put_be32(f, s->match[0]);
304
 
    qemu_put_be32(f, s->match[1]);
305
 
    qemu_put_be32(f, s->prescale[0]);
306
 
    qemu_put_be32(f, s->prescale[1]);
307
 
    qemu_put_be32(f, s->match_prescale[0]);
308
 
    qemu_put_be32(f, s->match_prescale[1]);
309
 
    qemu_put_be32(f, s->rtc);
310
 
    qemu_put_be64(f, s->tick[0]);
311
 
    qemu_put_be64(f, s->tick[1]);
312
 
    qemu_put_timer(f, s->timer[0]);
313
 
    qemu_put_timer(f, s->timer[1]);
314
 
}
315
 
 
316
 
static int gptm_load(QEMUFile *f, void *opaque, int version_id)
317
 
{
318
 
    gptm_state *s = (gptm_state *)opaque;
319
 
 
320
 
    if (version_id != 1)
321
 
        return -EINVAL;
322
 
 
323
 
    s->config = qemu_get_be32(f);
324
 
    s->mode[0] = qemu_get_be32(f);
325
 
    s->mode[1] = qemu_get_be32(f);
326
 
    s->control = qemu_get_be32(f);
327
 
    s->state = qemu_get_be32(f);
328
 
    s->mask = qemu_get_be32(f);
329
 
    s->mode[0] = qemu_get_be32(f);
330
 
    s->mode[0] = qemu_get_be32(f);
331
 
    s->load[0] = qemu_get_be32(f);
332
 
    s->load[1] = qemu_get_be32(f);
333
 
    s->match[0] = qemu_get_be32(f);
334
 
    s->match[1] = qemu_get_be32(f);
335
 
    s->prescale[0] = qemu_get_be32(f);
336
 
    s->prescale[1] = qemu_get_be32(f);
337
 
    s->match_prescale[0] = qemu_get_be32(f);
338
 
    s->match_prescale[1] = qemu_get_be32(f);
339
 
    s->rtc = qemu_get_be32(f);
340
 
    s->tick[0] = qemu_get_be64(f);
341
 
    s->tick[1] = qemu_get_be64(f);
342
 
    qemu_get_timer(f, s->timer[0]);
343
 
    qemu_get_timer(f, s->timer[1]);
344
 
 
345
 
    return 0;
346
 
}
347
 
 
348
 
static void stellaris_gptm_init(uint32_t base, qemu_irq irq, qemu_irq trigger)
349
 
{
350
 
    int iomemtype;
351
 
    gptm_state *s;
352
 
 
353
 
    s = (gptm_state *)qemu_mallocz(sizeof(gptm_state));
354
 
    s->base = base;
355
 
    s->irq = irq;
356
 
    s->trigger = trigger;
357
 
    s->opaque[0] = s->opaque[1] = s;
358
 
 
359
 
    iomemtype = cpu_register_io_memory(0, gptm_readfn,
360
 
                                       gptm_writefn, s);
361
 
    cpu_register_physical_memory(base, 0x00001000, iomemtype);
362
 
    s->timer[0] = qemu_new_timer(vm_clock, gptm_tick, &s->opaque[0]);
363
 
    s->timer[1] = qemu_new_timer(vm_clock, gptm_tick, &s->opaque[1]);
364
 
    register_savevm("stellaris_gptm", -1, 1, gptm_save, gptm_load, s);
365
 
}
366
 
 
367
 
 
368
 
/* System controller.  */
369
 
 
370
 
typedef struct {
371
 
    uint32_t base;
372
 
    uint32_t pborctl;
373
 
    uint32_t ldopctl;
374
 
    uint32_t int_status;
375
 
    uint32_t int_mask;
376
 
    uint32_t resc;
377
 
    uint32_t rcc;
378
 
    uint32_t rcgc[3];
379
 
    uint32_t scgc[3];
380
 
    uint32_t dcgc[3];
381
 
    uint32_t clkvclr;
382
 
    uint32_t ldoarst;
383
 
    uint32_t user0;
384
 
    uint32_t user1;
385
 
    qemu_irq irq;
386
 
    stellaris_board_info *board;
387
 
} ssys_state;
388
 
 
389
 
static void ssys_update(ssys_state *s)
390
 
{
391
 
  qemu_set_irq(s->irq, (s->int_status & s->int_mask) != 0);
392
 
}
393
 
 
394
 
static uint32_t pllcfg_sandstorm[16] = {
395
 
    0x31c0, /* 1 Mhz */
396
 
    0x1ae0, /* 1.8432 Mhz */
397
 
    0x18c0, /* 2 Mhz */
398
 
    0xd573, /* 2.4576 Mhz */
399
 
    0x37a6, /* 3.57954 Mhz */
400
 
    0x1ae2, /* 3.6864 Mhz */
401
 
    0x0c40, /* 4 Mhz */
402
 
    0x98bc, /* 4.906 Mhz */
403
 
    0x935b, /* 4.9152 Mhz */
404
 
    0x09c0, /* 5 Mhz */
405
 
    0x4dee, /* 5.12 Mhz */
406
 
    0x0c41, /* 6 Mhz */
407
 
    0x75db, /* 6.144 Mhz */
408
 
    0x1ae6, /* 7.3728 Mhz */
409
 
    0x0600, /* 8 Mhz */
410
 
    0x585b /* 8.192 Mhz */
411
 
};
412
 
 
413
 
static uint32_t pllcfg_fury[16] = {
414
 
    0x3200, /* 1 Mhz */
415
 
    0x1b20, /* 1.8432 Mhz */
416
 
    0x1900, /* 2 Mhz */
417
 
    0xf42b, /* 2.4576 Mhz */
418
 
    0x37e3, /* 3.57954 Mhz */
419
 
    0x1b21, /* 3.6864 Mhz */
420
 
    0x0c80, /* 4 Mhz */
421
 
    0x98ee, /* 4.906 Mhz */
422
 
    0xd5b4, /* 4.9152 Mhz */
423
 
    0x0a00, /* 5 Mhz */
424
 
    0x4e27, /* 5.12 Mhz */
425
 
    0x1902, /* 6 Mhz */
426
 
    0xec1c, /* 6.144 Mhz */
427
 
    0x1b23, /* 7.3728 Mhz */
428
 
    0x0640, /* 8 Mhz */
429
 
    0xb11c /* 8.192 Mhz */
430
 
};
431
 
 
432
 
static uint32_t ssys_read(void *opaque, target_phys_addr_t offset)
433
 
{
434
 
    ssys_state *s = (ssys_state *)opaque;
435
 
 
436
 
    offset -= s->base;
437
 
    switch (offset) {
438
 
    case 0x000: /* DID0 */
439
 
        return s->board->did0;
440
 
    case 0x004: /* DID1 */
441
 
        return s->board->did1;
442
 
    case 0x008: /* DC0 */
443
 
        return s->board->dc0;
444
 
    case 0x010: /* DC1 */
445
 
        return s->board->dc1;
446
 
    case 0x014: /* DC2 */
447
 
        return s->board->dc2;
448
 
    case 0x018: /* DC3 */
449
 
        return s->board->dc3;
450
 
    case 0x01c: /* DC4 */
451
 
        return s->board->dc4;
452
 
    case 0x030: /* PBORCTL */
453
 
        return s->pborctl;
454
 
    case 0x034: /* LDOPCTL */
455
 
        return s->ldopctl;
456
 
    case 0x040: /* SRCR0 */
457
 
        return 0;
458
 
    case 0x044: /* SRCR1 */
459
 
        return 0;
460
 
    case 0x048: /* SRCR2 */
461
 
        return 0;
462
 
    case 0x050: /* RIS */
463
 
        return s->int_status;
464
 
    case 0x054: /* IMC */
465
 
        return s->int_mask;
466
 
    case 0x058: /* MISC */
467
 
        return s->int_status & s->int_mask;
468
 
    case 0x05c: /* RESC */
469
 
        return s->resc;
470
 
    case 0x060: /* RCC */
471
 
        return s->rcc;
472
 
    case 0x064: /* PLLCFG */
473
 
        {
474
 
            int xtal;
475
 
            xtal = (s->rcc >> 6) & 0xf;
476
 
            if (s->board->did0 & (1 << 16)) {
477
 
                return pllcfg_fury[xtal];
478
 
            } else {
479
 
                return pllcfg_sandstorm[xtal];
480
 
            }
481
 
        }
482
 
    case 0x100: /* RCGC0 */
483
 
        return s->rcgc[0];
484
 
    case 0x104: /* RCGC1 */
485
 
        return s->rcgc[1];
486
 
    case 0x108: /* RCGC2 */
487
 
        return s->rcgc[2];
488
 
    case 0x110: /* SCGC0 */
489
 
        return s->scgc[0];
490
 
    case 0x114: /* SCGC1 */
491
 
        return s->scgc[1];
492
 
    case 0x118: /* SCGC2 */
493
 
        return s->scgc[2];
494
 
    case 0x120: /* DCGC0 */
495
 
        return s->dcgc[0];
496
 
    case 0x124: /* DCGC1 */
497
 
        return s->dcgc[1];
498
 
    case 0x128: /* DCGC2 */
499
 
        return s->dcgc[2];
500
 
    case 0x150: /* CLKVCLR */
501
 
        return s->clkvclr;
502
 
    case 0x160: /* LDOARST */
503
 
        return s->ldoarst;
504
 
    case 0x1e0: /* USER0 */
505
 
        return s->user0;
506
 
    case 0x1e4: /* USER1 */
507
 
        return s->user1;
508
 
    default:
509
 
        cpu_abort(cpu_single_env, "ssys_read: Bad offset 0x%x\n", (int)offset);
510
 
        return 0;
511
 
    }
512
 
}
513
 
 
514
 
static void ssys_calculate_system_clock(ssys_state *s)
515
 
{
516
 
    system_clock_scale = 5 * (((s->rcc >> 23) & 0xf) + 1);
517
 
}
518
 
 
519
 
static void ssys_write(void *opaque, target_phys_addr_t offset, uint32_t value)
520
 
{
521
 
    ssys_state *s = (ssys_state *)opaque;
522
 
 
523
 
    offset -= s->base;
524
 
    switch (offset) {
525
 
    case 0x030: /* PBORCTL */
526
 
        s->pborctl = value & 0xffff;
527
 
        break;
528
 
    case 0x034: /* LDOPCTL */
529
 
        s->ldopctl = value & 0x1f;
530
 
        break;
531
 
    case 0x040: /* SRCR0 */
532
 
    case 0x044: /* SRCR1 */
533
 
    case 0x048: /* SRCR2 */
534
 
        fprintf(stderr, "Peripheral reset not implemented\n");
535
 
        break;
536
 
    case 0x054: /* IMC */
537
 
        s->int_mask = value & 0x7f;
538
 
        break;
539
 
    case 0x058: /* MISC */
540
 
        s->int_status &= ~value;
541
 
        break;
542
 
    case 0x05c: /* RESC */
543
 
        s->resc = value & 0x3f;
544
 
        break;
545
 
    case 0x060: /* RCC */
546
 
        if ((s->rcc & (1 << 13)) != 0 && (value & (1 << 13)) == 0) {
547
 
            /* PLL enable.  */
548
 
            s->int_status |= (1 << 6);
549
 
        }
550
 
        s->rcc = value;
551
 
        ssys_calculate_system_clock(s);
552
 
        break;
553
 
    case 0x100: /* RCGC0 */
554
 
        s->rcgc[0] = value;
555
 
        break;
556
 
    case 0x104: /* RCGC1 */
557
 
        s->rcgc[1] = value;
558
 
        break;
559
 
    case 0x108: /* RCGC2 */
560
 
        s->rcgc[2] = value;
561
 
        break;
562
 
    case 0x110: /* SCGC0 */
563
 
        s->scgc[0] = value;
564
 
        break;
565
 
    case 0x114: /* SCGC1 */
566
 
        s->scgc[1] = value;
567
 
        break;
568
 
    case 0x118: /* SCGC2 */
569
 
        s->scgc[2] = value;
570
 
        break;
571
 
    case 0x120: /* DCGC0 */
572
 
        s->dcgc[0] = value;
573
 
        break;
574
 
    case 0x124: /* DCGC1 */
575
 
        s->dcgc[1] = value;
576
 
        break;
577
 
    case 0x128: /* DCGC2 */
578
 
        s->dcgc[2] = value;
579
 
        break;
580
 
    case 0x150: /* CLKVCLR */
581
 
        s->clkvclr = value;
582
 
        break;
583
 
    case 0x160: /* LDOARST */
584
 
        s->ldoarst = value;
585
 
        break;
586
 
    default:
587
 
        cpu_abort(cpu_single_env, "ssys_write: Bad offset 0x%x\n", (int)offset);
588
 
    }
589
 
    ssys_update(s);
590
 
}
591
 
 
592
 
static CPUReadMemoryFunc *ssys_readfn[] = {
593
 
   ssys_read,
594
 
   ssys_read,
595
 
   ssys_read
596
 
};
597
 
 
598
 
static CPUWriteMemoryFunc *ssys_writefn[] = {
599
 
   ssys_write,
600
 
   ssys_write,
601
 
   ssys_write
602
 
};
603
 
 
604
 
static void ssys_reset(void *opaque)
605
 
{
606
 
    ssys_state *s = (ssys_state *)opaque;
607
 
 
608
 
    s->pborctl = 0x7ffd;
609
 
    s->rcc = 0x078e3ac0;
610
 
    s->rcgc[0] = 1;
611
 
    s->scgc[0] = 1;
612
 
    s->dcgc[0] = 1;
613
 
}
614
 
 
615
 
static void ssys_save(QEMUFile *f, void *opaque)
616
 
{
617
 
    ssys_state *s = (ssys_state *)opaque;
618
 
 
619
 
    qemu_put_be32(f, s->pborctl);
620
 
    qemu_put_be32(f, s->ldopctl);
621
 
    qemu_put_be32(f, s->int_mask);
622
 
    qemu_put_be32(f, s->int_status);
623
 
    qemu_put_be32(f, s->resc);
624
 
    qemu_put_be32(f, s->rcc);
625
 
    qemu_put_be32(f, s->rcgc[0]);
626
 
    qemu_put_be32(f, s->rcgc[1]);
627
 
    qemu_put_be32(f, s->rcgc[2]);
628
 
    qemu_put_be32(f, s->scgc[0]);
629
 
    qemu_put_be32(f, s->scgc[1]);
630
 
    qemu_put_be32(f, s->scgc[2]);
631
 
    qemu_put_be32(f, s->dcgc[0]);
632
 
    qemu_put_be32(f, s->dcgc[1]);
633
 
    qemu_put_be32(f, s->dcgc[2]);
634
 
    qemu_put_be32(f, s->clkvclr);
635
 
    qemu_put_be32(f, s->ldoarst);
636
 
}
637
 
 
638
 
static int ssys_load(QEMUFile *f, void *opaque, int version_id)
639
 
{
640
 
    ssys_state *s = (ssys_state *)opaque;
641
 
 
642
 
    if (version_id != 1)
643
 
        return -EINVAL;
644
 
 
645
 
    s->pborctl = qemu_get_be32(f);
646
 
    s->ldopctl = qemu_get_be32(f);
647
 
    s->int_mask = qemu_get_be32(f);
648
 
    s->int_status = qemu_get_be32(f);
649
 
    s->resc = qemu_get_be32(f);
650
 
    s->rcc = qemu_get_be32(f);
651
 
    s->rcgc[0] = qemu_get_be32(f);
652
 
    s->rcgc[1] = qemu_get_be32(f);
653
 
    s->rcgc[2] = qemu_get_be32(f);
654
 
    s->scgc[0] = qemu_get_be32(f);
655
 
    s->scgc[1] = qemu_get_be32(f);
656
 
    s->scgc[2] = qemu_get_be32(f);
657
 
    s->dcgc[0] = qemu_get_be32(f);
658
 
    s->dcgc[1] = qemu_get_be32(f);
659
 
    s->dcgc[2] = qemu_get_be32(f);
660
 
    s->clkvclr = qemu_get_be32(f);
661
 
    s->ldoarst = qemu_get_be32(f);
662
 
    ssys_calculate_system_clock(s);
663
 
 
664
 
    return 0;
665
 
}
666
 
 
667
 
static void stellaris_sys_init(uint32_t base, qemu_irq irq,
668
 
                               stellaris_board_info * board,
669
 
                               uint8_t *macaddr)
670
 
{
671
 
    int iomemtype;
672
 
    ssys_state *s;
673
 
 
674
 
    s = (ssys_state *)qemu_mallocz(sizeof(ssys_state));
675
 
    s->base = base;
676
 
    s->irq = irq;
677
 
    s->board = board;
678
 
    /* Most devices come preprogrammed with a MAC address in the user data. */
679
 
    s->user0 = macaddr[0] | (macaddr[1] << 8) | (macaddr[2] << 16);
680
 
    s->user1 = macaddr[3] | (macaddr[4] << 8) | (macaddr[5] << 16);
681
 
 
682
 
    iomemtype = cpu_register_io_memory(0, ssys_readfn,
683
 
                                       ssys_writefn, s);
684
 
    cpu_register_physical_memory(base, 0x00001000, iomemtype);
685
 
    ssys_reset(s);
686
 
    register_savevm("stellaris_sys", -1, 1, ssys_save, ssys_load, s);
687
 
}
688
 
 
689
 
 
690
 
/* I2C controller.  */
691
 
 
692
 
typedef struct {
693
 
    i2c_bus *bus;
694
 
    qemu_irq irq;
695
 
    uint32_t base;
696
 
    uint32_t msa;
697
 
    uint32_t mcs;
698
 
    uint32_t mdr;
699
 
    uint32_t mtpr;
700
 
    uint32_t mimr;
701
 
    uint32_t mris;
702
 
    uint32_t mcr;
703
 
} stellaris_i2c_state;
704
 
 
705
 
#define STELLARIS_I2C_MCS_BUSY    0x01
706
 
#define STELLARIS_I2C_MCS_ERROR   0x02
707
 
#define STELLARIS_I2C_MCS_ADRACK  0x04
708
 
#define STELLARIS_I2C_MCS_DATACK  0x08
709
 
#define STELLARIS_I2C_MCS_ARBLST  0x10
710
 
#define STELLARIS_I2C_MCS_IDLE    0x20
711
 
#define STELLARIS_I2C_MCS_BUSBSY  0x40
712
 
 
713
 
static uint32_t stellaris_i2c_read(void *opaque, target_phys_addr_t offset)
714
 
{
715
 
    stellaris_i2c_state *s = (stellaris_i2c_state *)opaque;
716
 
 
717
 
    offset -= s->base;
718
 
    switch (offset) {
719
 
    case 0x00: /* MSA */
720
 
        return s->msa;
721
 
    case 0x04: /* MCS */
722
 
        /* We don't emulate timing, so the controller is never busy.  */
723
 
        return s->mcs | STELLARIS_I2C_MCS_IDLE;
724
 
    case 0x08: /* MDR */
725
 
        return s->mdr;
726
 
    case 0x0c: /* MTPR */
727
 
        return s->mtpr;
728
 
    case 0x10: /* MIMR */
729
 
        return s->mimr;
730
 
    case 0x14: /* MRIS */
731
 
        return s->mris;
732
 
    case 0x18: /* MMIS */
733
 
        return s->mris & s->mimr;
734
 
    case 0x20: /* MCR */
735
 
        return s->mcr;
736
 
    default:
737
 
        cpu_abort(cpu_single_env, "strllaris_i2c_read: Bad offset 0x%x\n",
738
 
                  (int)offset);
739
 
        return 0;
740
 
    }
741
 
}
742
 
 
743
 
static void stellaris_i2c_update(stellaris_i2c_state *s)
744
 
{
745
 
    int level;
746
 
 
747
 
    level = (s->mris & s->mimr) != 0;
748
 
    qemu_set_irq(s->irq, level);
749
 
}
750
 
 
751
 
static void stellaris_i2c_write(void *opaque, target_phys_addr_t offset,
752
 
                                uint32_t value)
753
 
{
754
 
    stellaris_i2c_state *s = (stellaris_i2c_state *)opaque;
755
 
 
756
 
    offset -= s->base;
757
 
    switch (offset) {
758
 
    case 0x00: /* MSA */
759
 
        s->msa = value & 0xff;
760
 
        break;
761
 
    case 0x04: /* MCS */
762
 
        if ((s->mcr & 0x10) == 0) {
763
 
            /* Disabled.  Do nothing.  */
764
 
            break;
765
 
        }
766
 
        /* Grab the bus if this is starting a transfer.  */
767
 
        if ((value & 2) && (s->mcs & STELLARIS_I2C_MCS_BUSBSY) == 0) {
768
 
            if (i2c_start_transfer(s->bus, s->msa >> 1, s->msa & 1)) {
769
 
                s->mcs |= STELLARIS_I2C_MCS_ARBLST;
770
 
            } else {
771
 
                s->mcs &= ~STELLARIS_I2C_MCS_ARBLST;
772
 
                s->mcs |= STELLARIS_I2C_MCS_BUSBSY;
773
 
            }
774
 
        }
775
 
        /* If we don't have the bus then indicate an error.  */
776
 
        if (!i2c_bus_busy(s->bus)
777
 
                || (s->mcs & STELLARIS_I2C_MCS_BUSBSY) == 0) {
778
 
            s->mcs |= STELLARIS_I2C_MCS_ERROR;
779
 
            break;
780
 
        }
781
 
        s->mcs &= ~STELLARIS_I2C_MCS_ERROR;
782
 
        if (value & 1) {
783
 
            /* Transfer a byte.  */
784
 
            /* TODO: Handle errors.  */
785
 
            if (s->msa & 1) {
786
 
                /* Recv */
787
 
                s->mdr = i2c_recv(s->bus) & 0xff;
788
 
            } else {
789
 
                /* Send */
790
 
                i2c_send(s->bus, s->mdr);
791
 
            }
792
 
            /* Raise an interrupt.  */
793
 
            s->mris |= 1;
794
 
        }
795
 
        if (value & 4) {
796
 
            /* Finish transfer.  */
797
 
            i2c_end_transfer(s->bus);
798
 
            s->mcs &= ~STELLARIS_I2C_MCS_BUSBSY;
799
 
        }
800
 
        break;
801
 
    case 0x08: /* MDR */
802
 
        s->mdr = value & 0xff;
803
 
        break;
804
 
    case 0x0c: /* MTPR */
805
 
        s->mtpr = value & 0xff;
806
 
        break;
807
 
    case 0x10: /* MIMR */
808
 
        s->mimr = 1;
809
 
        break;
810
 
    case 0x1c: /* MICR */
811
 
        s->mris &= ~value;
812
 
        break;
813
 
    case 0x20: /* MCR */
814
 
        if (value & 1)
815
 
            cpu_abort(cpu_single_env,
816
 
                      "stellaris_i2c_write: Loopback not implemented\n");
817
 
        if (value & 0x20)
818
 
            cpu_abort(cpu_single_env,
819
 
                      "stellaris_i2c_write: Slave mode not implemented\n");
820
 
        s->mcr = value & 0x31;
821
 
        break;
822
 
    default:
823
 
        cpu_abort(cpu_single_env, "stellaris_i2c_write: Bad offset 0x%x\n",
824
 
                  (int)offset);
825
 
    }
826
 
    stellaris_i2c_update(s);
827
 
}
828
 
 
829
 
static void stellaris_i2c_reset(stellaris_i2c_state *s)
830
 
{
831
 
    if (s->mcs & STELLARIS_I2C_MCS_BUSBSY)
832
 
        i2c_end_transfer(s->bus);
833
 
 
834
 
    s->msa = 0;
835
 
    s->mcs = 0;
836
 
    s->mdr = 0;
837
 
    s->mtpr = 1;
838
 
    s->mimr = 0;
839
 
    s->mris = 0;
840
 
    s->mcr = 0;
841
 
    stellaris_i2c_update(s);
842
 
}
843
 
 
844
 
static CPUReadMemoryFunc *stellaris_i2c_readfn[] = {
845
 
   stellaris_i2c_read,
846
 
   stellaris_i2c_read,
847
 
   stellaris_i2c_read
848
 
};
849
 
 
850
 
static CPUWriteMemoryFunc *stellaris_i2c_writefn[] = {
851
 
   stellaris_i2c_write,
852
 
   stellaris_i2c_write,
853
 
   stellaris_i2c_write
854
 
};
855
 
 
856
 
static void stellaris_i2c_save(QEMUFile *f, void *opaque)
857
 
{
858
 
    stellaris_i2c_state *s = (stellaris_i2c_state *)opaque;
859
 
 
860
 
    qemu_put_be32(f, s->msa);
861
 
    qemu_put_be32(f, s->mcs);
862
 
    qemu_put_be32(f, s->mdr);
863
 
    qemu_put_be32(f, s->mtpr);
864
 
    qemu_put_be32(f, s->mimr);
865
 
    qemu_put_be32(f, s->mris);
866
 
    qemu_put_be32(f, s->mcr);
867
 
}
868
 
 
869
 
static int stellaris_i2c_load(QEMUFile *f, void *opaque, int version_id)
870
 
{
871
 
    stellaris_i2c_state *s = (stellaris_i2c_state *)opaque;
872
 
 
873
 
    if (version_id != 1)
874
 
        return -EINVAL;
875
 
 
876
 
    s->msa = qemu_get_be32(f);
877
 
    s->mcs = qemu_get_be32(f);
878
 
    s->mdr = qemu_get_be32(f);
879
 
    s->mtpr = qemu_get_be32(f);
880
 
    s->mimr = qemu_get_be32(f);
881
 
    s->mris = qemu_get_be32(f);
882
 
    s->mcr = qemu_get_be32(f);
883
 
 
884
 
    return 0;
885
 
}
886
 
 
887
 
static void stellaris_i2c_init(uint32_t base, qemu_irq irq, i2c_bus *bus)
888
 
{
889
 
    stellaris_i2c_state *s;
890
 
    int iomemtype;
891
 
 
892
 
    s = (stellaris_i2c_state *)qemu_mallocz(sizeof(stellaris_i2c_state));
893
 
    s->base = base;
894
 
    s->irq = irq;
895
 
    s->bus = bus;
896
 
 
897
 
    iomemtype = cpu_register_io_memory(0, stellaris_i2c_readfn,
898
 
                                       stellaris_i2c_writefn, s);
899
 
    cpu_register_physical_memory(base, 0x00001000, iomemtype);
900
 
    /* ??? For now we only implement the master interface.  */
901
 
    stellaris_i2c_reset(s);
902
 
    register_savevm("stellaris_i2c", -1, 1,
903
 
                    stellaris_i2c_save, stellaris_i2c_load, s);
904
 
}
905
 
 
906
 
/* Analogue to Digital Converter.  This is only partially implemented,
907
 
   enough for applications that use a combined ADC and timer tick.  */
908
 
 
909
 
#define STELLARIS_ADC_EM_CONTROLLER 0
910
 
#define STELLARIS_ADC_EM_COMP       1
911
 
#define STELLARIS_ADC_EM_EXTERNAL   4
912
 
#define STELLARIS_ADC_EM_TIMER      5
913
 
#define STELLARIS_ADC_EM_PWM0       6
914
 
#define STELLARIS_ADC_EM_PWM1       7
915
 
#define STELLARIS_ADC_EM_PWM2       8
916
 
 
917
 
#define STELLARIS_ADC_FIFO_EMPTY    0x0100
918
 
#define STELLARIS_ADC_FIFO_FULL     0x1000
919
 
 
920
 
typedef struct
921
 
{
922
 
    uint32_t base;
923
 
    uint32_t actss;
924
 
    uint32_t ris;
925
 
    uint32_t im;
926
 
    uint32_t emux;
927
 
    uint32_t ostat;
928
 
    uint32_t ustat;
929
 
    uint32_t sspri;
930
 
    uint32_t sac;
931
 
    struct {
932
 
        uint32_t state;
933
 
        uint32_t data[16];
934
 
    } fifo[4];
935
 
    uint32_t ssmux[4];
936
 
    uint32_t ssctl[4];
937
 
    uint32_t noise;
938
 
    qemu_irq irq;
939
 
} stellaris_adc_state;
940
 
 
941
 
static uint32_t stellaris_adc_fifo_read(stellaris_adc_state *s, int n)
942
 
{
943
 
    int tail;
944
 
 
945
 
    tail = s->fifo[n].state & 0xf;
946
 
    if (s->fifo[n].state & STELLARIS_ADC_FIFO_EMPTY) {
947
 
        s->ustat |= 1 << n;
948
 
    } else {
949
 
        s->fifo[n].state = (s->fifo[n].state & ~0xf) | ((tail + 1) & 0xf);
950
 
        s->fifo[n].state &= ~STELLARIS_ADC_FIFO_FULL;
951
 
        if (tail + 1 == ((s->fifo[n].state >> 4) & 0xf))
952
 
            s->fifo[n].state |= STELLARIS_ADC_FIFO_EMPTY;
953
 
    }
954
 
    return s->fifo[n].data[tail];
955
 
}
956
 
 
957
 
static void stellaris_adc_fifo_write(stellaris_adc_state *s, int n,
958
 
                                     uint32_t value)
959
 
{
960
 
    int head;
961
 
 
962
 
    head = (s->fifo[n].state >> 4) & 0xf;
963
 
    if (s->fifo[n].state & STELLARIS_ADC_FIFO_FULL) {
964
 
        s->ostat |= 1 << n;
965
 
        return;
966
 
    }
967
 
    s->fifo[n].data[head] = value;
968
 
    head = (head + 1) & 0xf;
969
 
    s->fifo[n].state &= ~STELLARIS_ADC_FIFO_EMPTY;
970
 
    s->fifo[n].state = (s->fifo[n].state & ~0xf0) | (head << 4);
971
 
    if ((s->fifo[n].state & 0xf) == head)
972
 
        s->fifo[n].state |= STELLARIS_ADC_FIFO_FULL;
973
 
}
974
 
 
975
 
static void stellaris_adc_update(stellaris_adc_state *s)
976
 
{
977
 
    int level;
978
 
 
979
 
    level = (s->ris & s->im) != 0;
980
 
    qemu_set_irq(s->irq, level);
981
 
}
982
 
 
983
 
static void stellaris_adc_trigger(void *opaque, int irq, int level)
984
 
{
985
 
    stellaris_adc_state *s = (stellaris_adc_state *)opaque;
986
 
 
987
 
    if ((s->actss & 1) == 0) {
988
 
        return;
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, 0, 0x200 + ((s->noise >> 16) & 7));
996
 
    s->ris |= 1;
997
 
    stellaris_adc_update(s);
998
 
}
999
 
 
1000
 
static void stellaris_adc_reset(stellaris_adc_state *s)
1001
 
{
1002
 
    int n;
1003
 
 
1004
 
    for (n = 0; n < 4; n++) {
1005
 
        s->ssmux[n] = 0;
1006
 
        s->ssctl[n] = 0;
1007
 
        s->fifo[n].state = STELLARIS_ADC_FIFO_EMPTY;
1008
 
    }
1009
 
}
1010
 
 
1011
 
static uint32_t stellaris_adc_read(void *opaque, target_phys_addr_t offset)
1012
 
{
1013
 
    stellaris_adc_state *s = (stellaris_adc_state *)opaque;
1014
 
 
1015
 
    /* TODO: Implement this.  */
1016
 
    offset -= s->base;
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
 
        cpu_abort(cpu_single_env, "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
 
    offset -= s->base;
1066
 
    if (offset >= 0x40 && offset < 0xc0) {
1067
 
        int n;
1068
 
        n = (offset - 0x40) >> 5;
1069
 
        switch (offset & 0x1f) {
1070
 
        case 0x00: /* SSMUX */
1071
 
            s->ssmux[n] = value & 0x33333333;
1072
 
            return;
1073
 
        case 0x04: /* SSCTL */
1074
 
            if (value != 6) {
1075
 
                cpu_abort(cpu_single_env, "ADC: Unimplemented sequence %x\n",
1076
 
                          value);
1077
 
            }
1078
 
            s->ssctl[n] = value;
1079
 
            return;
1080
 
        default:
1081
 
            break;
1082
 
        }
1083
 
    }
1084
 
    switch (offset) {
1085
 
    case 0x00: /* ACTSS */
1086
 
        s->actss = value & 0xf;
1087
 
        if (value & 0xe) {
1088
 
            cpu_abort(cpu_single_env,
1089
 
                      "Not implemented:  ADC sequencers 1-3\n");
1090
 
        }
1091
 
        break;
1092
 
    case 0x08: /* IM */
1093
 
        s->im = value;
1094
 
        break;
1095
 
    case 0x0c: /* ISC */
1096
 
        s->ris &= ~value;
1097
 
        break;
1098
 
    case 0x10: /* OSTAT */
1099
 
        s->ostat &= ~value;
1100
 
        break;
1101
 
    case 0x14: /* EMUX */
1102
 
        s->emux = value;
1103
 
        break;
1104
 
    case 0x18: /* USTAT */
1105
 
        s->ustat &= ~value;
1106
 
        break;
1107
 
    case 0x20: /* SSPRI */
1108
 
        s->sspri = value;
1109
 
        break;
1110
 
    case 0x28: /* PSSI */
1111
 
        cpu_abort(cpu_single_env, "Not implemented:  ADC sample initiate\n");
1112
 
        break;
1113
 
    case 0x30: /* SAC */
1114
 
        s->sac = value;
1115
 
        break;
1116
 
    default:
1117
 
        cpu_abort(cpu_single_env, "stellaris_adc_write: Bad offset 0x%x\n",
1118
 
                  (int)offset);
1119
 
    }
1120
 
    stellaris_adc_update(s);
1121
 
}
1122
 
 
1123
 
static CPUReadMemoryFunc *stellaris_adc_readfn[] = {
1124
 
   stellaris_adc_read,
1125
 
   stellaris_adc_read,
1126
 
   stellaris_adc_read
1127
 
};
1128
 
 
1129
 
static CPUWriteMemoryFunc *stellaris_adc_writefn[] = {
1130
 
   stellaris_adc_write,
1131
 
   stellaris_adc_write,
1132
 
   stellaris_adc_write
1133
 
};
1134
 
 
1135
 
static void stellaris_adc_save(QEMUFile *f, void *opaque)
1136
 
{
1137
 
    stellaris_adc_state *s = (stellaris_adc_state *)opaque;
1138
 
    int i;
1139
 
    int j;
1140
 
 
1141
 
    qemu_put_be32(f, s->actss);
1142
 
    qemu_put_be32(f, s->ris);
1143
 
    qemu_put_be32(f, s->im);
1144
 
    qemu_put_be32(f, s->emux);
1145
 
    qemu_put_be32(f, s->ostat);
1146
 
    qemu_put_be32(f, s->ustat);
1147
 
    qemu_put_be32(f, s->sspri);
1148
 
    qemu_put_be32(f, s->sac);
1149
 
    for (i = 0; i < 4; i++) {
1150
 
        qemu_put_be32(f, s->fifo[i].state);
1151
 
        for (j = 0; j < 16; j++) {
1152
 
            qemu_put_be32(f, s->fifo[i].data[j]);
1153
 
        }
1154
 
        qemu_put_be32(f, s->ssmux[i]);
1155
 
        qemu_put_be32(f, s->ssctl[i]);
1156
 
    }
1157
 
    qemu_put_be32(f, s->noise);
1158
 
}
1159
 
 
1160
 
static int stellaris_adc_load(QEMUFile *f, void *opaque, int version_id)
1161
 
{
1162
 
    stellaris_adc_state *s = (stellaris_adc_state *)opaque;
1163
 
    int i;
1164
 
    int j;
1165
 
 
1166
 
    if (version_id != 1)
1167
 
        return -EINVAL;
1168
 
 
1169
 
    s->actss = qemu_get_be32(f);
1170
 
    s->ris = qemu_get_be32(f);
1171
 
    s->im = qemu_get_be32(f);
1172
 
    s->emux = qemu_get_be32(f);
1173
 
    s->ostat = qemu_get_be32(f);
1174
 
    s->ustat = qemu_get_be32(f);
1175
 
    s->sspri = qemu_get_be32(f);
1176
 
    s->sac = qemu_get_be32(f);
1177
 
    for (i = 0; i < 4; i++) {
1178
 
        s->fifo[i].state = qemu_get_be32(f);
1179
 
        for (j = 0; j < 16; j++) {
1180
 
            s->fifo[i].data[j] = qemu_get_be32(f);
1181
 
        }
1182
 
        s->ssmux[i] = qemu_get_be32(f);
1183
 
        s->ssctl[i] = qemu_get_be32(f);
1184
 
    }
1185
 
    s->noise = qemu_get_be32(f);
1186
 
 
1187
 
    return 0;
1188
 
}
1189
 
 
1190
 
static qemu_irq stellaris_adc_init(uint32_t base, qemu_irq irq)
1191
 
{
1192
 
    stellaris_adc_state *s;
1193
 
    int iomemtype;
1194
 
    qemu_irq *qi;
1195
 
 
1196
 
    s = (stellaris_adc_state *)qemu_mallocz(sizeof(stellaris_adc_state));
1197
 
    s->base = base;
1198
 
    s->irq = irq;
1199
 
 
1200
 
    iomemtype = cpu_register_io_memory(0, stellaris_adc_readfn,
1201
 
                                       stellaris_adc_writefn, s);
1202
 
    cpu_register_physical_memory(base, 0x00001000, iomemtype);
1203
 
    stellaris_adc_reset(s);
1204
 
    qi = qemu_allocate_irqs(stellaris_adc_trigger, s, 1);
1205
 
    register_savevm("stellaris_adc", -1, 1,
1206
 
                    stellaris_adc_save, stellaris_adc_load, s);
1207
 
    return qi[0];
1208
 
}
1209
 
 
1210
 
/* Some boards have both an OLED controller and SD card connected to
1211
 
   the same SSI port, with the SD card chip select connected to a
1212
 
   GPIO pin.  Technically the OLED chip select is connected to the SSI
1213
 
   Fss pin.  We do not bother emulating that as both devices should
1214
 
   never be selected simultaneously, and our OLED controller ignores stray
1215
 
   0xff commands that occur when deselecting the SD card.  */
1216
 
 
1217
 
typedef struct {
1218
 
    ssi_xfer_cb xfer_cb[2];
1219
 
    void *opaque[2];
1220
 
    qemu_irq irq;
1221
 
    int current_dev;
1222
 
} stellaris_ssi_bus_state;
1223
 
 
1224
 
static void stellaris_ssi_bus_select(void *opaque, int irq, int level)
1225
 
{
1226
 
    stellaris_ssi_bus_state *s = (stellaris_ssi_bus_state *)opaque;
1227
 
 
1228
 
    s->current_dev = level;
1229
 
}
1230
 
 
1231
 
static int stellaris_ssi_bus_xfer(void *opaque, int val)
1232
 
{
1233
 
    stellaris_ssi_bus_state *s = (stellaris_ssi_bus_state *)opaque;
1234
 
 
1235
 
    return s->xfer_cb[s->current_dev](s->opaque[s->current_dev], val);
1236
 
}
1237
 
 
1238
 
static void stellaris_ssi_bus_save(QEMUFile *f, void *opaque)
1239
 
{
1240
 
    stellaris_ssi_bus_state *s = (stellaris_ssi_bus_state *)opaque;
1241
 
 
1242
 
    qemu_put_be32(f, s->current_dev);
1243
 
}
1244
 
 
1245
 
static int stellaris_ssi_bus_load(QEMUFile *f, void *opaque, int version_id)
1246
 
{
1247
 
    stellaris_ssi_bus_state *s = (stellaris_ssi_bus_state *)opaque;
1248
 
 
1249
 
    if (version_id != 1)
1250
 
        return -EINVAL;
1251
 
 
1252
 
    s->current_dev = qemu_get_be32(f);
1253
 
 
1254
 
    return 0;
1255
 
}
1256
 
 
1257
 
static void *stellaris_ssi_bus_init(qemu_irq *irqp,
1258
 
                                    ssi_xfer_cb cb0, void *opaque0,
1259
 
                                    ssi_xfer_cb cb1, void *opaque1)
1260
 
{
1261
 
    qemu_irq *qi;
1262
 
    stellaris_ssi_bus_state *s;
1263
 
 
1264
 
    s = (stellaris_ssi_bus_state *)qemu_mallocz(sizeof(stellaris_ssi_bus_state));
1265
 
    s->xfer_cb[0] = cb0;
1266
 
    s->opaque[0] = opaque0;
1267
 
    s->xfer_cb[1] = cb1;
1268
 
    s->opaque[1] = opaque1;
1269
 
    qi = qemu_allocate_irqs(stellaris_ssi_bus_select, s, 1);
1270
 
    *irqp = *qi;
1271
 
    register_savevm("stellaris_ssi_bus", -1, 1,
1272
 
                    stellaris_ssi_bus_save, stellaris_ssi_bus_load, s);
1273
 
    return s;
1274
 
}
1275
 
 
1276
 
/* Board init.  */
1277
 
static stellaris_board_info stellaris_boards[] = {
1278
 
  { "LM3S811EVB",
1279
 
    0,
1280
 
    0x0032000e,
1281
 
    0x001f001f, /* dc0 */
1282
 
    0x001132bf,
1283
 
    0x01071013,
1284
 
    0x3f0f01ff,
1285
 
    0x0000001f,
1286
 
    BP_OLED_I2C
1287
 
  },
1288
 
  { "LM3S6965EVB",
1289
 
    0x10010002,
1290
 
    0x1073402e,
1291
 
    0x00ff007f, /* dc0 */
1292
 
    0x001133ff,
1293
 
    0x030f5317,
1294
 
    0x0f0f87ff,
1295
 
    0x5000007f,
1296
 
    BP_OLED_SSI | BP_GAMEPAD
1297
 
  }
1298
 
};
1299
 
 
1300
 
static void stellaris_init(const char *kernel_filename, const char *cpu_model,
1301
 
                           DisplayState *ds, stellaris_board_info *board)
1302
 
{
1303
 
    static const int uart_irq[] = {5, 6, 33, 34};
1304
 
    static const int timer_irq[] = {19, 21, 23, 35};
1305
 
    static const uint32_t gpio_addr[7] =
1306
 
      { 0x40004000, 0x40005000, 0x40006000, 0x40007000,
1307
 
        0x40024000, 0x40025000, 0x40026000};
1308
 
    static const int gpio_irq[7] = {0, 1, 2, 3, 4, 30, 31};
1309
 
 
1310
 
    qemu_irq *pic;
1311
 
    qemu_irq *gpio_in[7];
1312
 
    qemu_irq *gpio_out[7];
1313
 
    qemu_irq adc;
1314
 
    int sram_size;
1315
 
    int flash_size;
1316
 
    i2c_bus *i2c;
1317
 
    int i;
1318
 
 
1319
 
    flash_size = ((board->dc0 & 0xffff) + 1) << 1;
1320
 
    sram_size = (board->dc0 >> 18) + 1;
1321
 
    pic = armv7m_init(flash_size, sram_size, kernel_filename, cpu_model);
1322
 
 
1323
 
    if (board->dc1 & (1 << 16)) {
1324
 
        adc = stellaris_adc_init(0x40038000, pic[14]);
1325
 
    } else {
1326
 
        adc = NULL;
1327
 
    }
1328
 
    for (i = 0; i < 4; i++) {
1329
 
        if (board->dc2 & (0x10000 << i)) {
1330
 
            stellaris_gptm_init(0x40030000 + i * 0x1000,
1331
 
                                pic[timer_irq[i]], adc);
1332
 
        }
1333
 
    }
1334
 
 
1335
 
    stellaris_sys_init(0x400fe000, pic[28], board, nd_table[0].macaddr);
1336
 
 
1337
 
    for (i = 0; i < 7; i++) {
1338
 
        if (board->dc4 & (1 << i)) {
1339
 
            gpio_in[i] = pl061_init(gpio_addr[i], pic[gpio_irq[i]],
1340
 
                                    &gpio_out[i]);
1341
 
        }
1342
 
    }
1343
 
 
1344
 
    if (board->dc2 & (1 << 12)) {
1345
 
        i2c = i2c_init_bus();
1346
 
        stellaris_i2c_init(0x40020000, pic[8], i2c);
1347
 
        if (board->peripherals & BP_OLED_I2C) {
1348
 
            ssd0303_init(ds, i2c, 0x3d);
1349
 
        }
1350
 
    }
1351
 
 
1352
 
    for (i = 0; i < 4; i++) {
1353
 
        if (board->dc2 & (1 << i)) {
1354
 
            pl011_init(0x4000c000 + i * 0x1000, pic[uart_irq[i]],
1355
 
                       serial_hds[i], PL011_LUMINARY);
1356
 
        }
1357
 
    }
1358
 
    if (board->dc2 & (1 << 4)) {
1359
 
        if (board->peripherals & BP_OLED_SSI) {
1360
 
            void * oled;
1361
 
            void * sd;
1362
 
            void *ssi_bus;
1363
 
            int index;
1364
 
 
1365
 
            oled = ssd0323_init(ds, &gpio_out[GPIO_C][7]);
1366
 
            index = drive_get_index(IF_SD, 0, 0);
1367
 
            sd = ssi_sd_init(drives_table[index].bdrv);
1368
 
 
1369
 
            ssi_bus = stellaris_ssi_bus_init(&gpio_out[GPIO_D][0],
1370
 
                                             ssi_sd_xfer, sd,
1371
 
                                             ssd0323_xfer_ssi, oled);
1372
 
 
1373
 
            pl022_init(0x40008000, pic[7], stellaris_ssi_bus_xfer, ssi_bus);
1374
 
            /* Make sure the select pin is high.  */
1375
 
            qemu_irq_raise(gpio_out[GPIO_D][0]);
1376
 
        } else {
1377
 
            pl022_init(0x40008000, pic[7], NULL, NULL);
1378
 
        }
1379
 
    }
1380
 
    if (board->dc4 & (1 << 28)) {
1381
 
        /* FIXME: Obey network model.  */
1382
 
        stellaris_enet_init(&nd_table[0], 0x40048000, pic[42]);
1383
 
    }
1384
 
    if (board->peripherals & BP_GAMEPAD) {
1385
 
        qemu_irq gpad_irq[5];
1386
 
        static const int gpad_keycode[5] = { 0xc8, 0xd0, 0xcb, 0xcd, 0x1d };
1387
 
 
1388
 
        gpad_irq[0] = qemu_irq_invert(gpio_in[GPIO_E][0]); /* up */
1389
 
        gpad_irq[1] = qemu_irq_invert(gpio_in[GPIO_E][1]); /* down */
1390
 
        gpad_irq[2] = qemu_irq_invert(gpio_in[GPIO_E][2]); /* left */
1391
 
        gpad_irq[3] = qemu_irq_invert(gpio_in[GPIO_E][3]); /* right */
1392
 
        gpad_irq[4] = qemu_irq_invert(gpio_in[GPIO_F][1]); /* select */
1393
 
 
1394
 
        stellaris_gamepad_init(5, gpad_irq, gpad_keycode);
1395
 
    }
1396
 
}
1397
 
 
1398
 
/* FIXME: Figure out how to generate these from stellaris_boards.  */
1399
 
static void lm3s811evb_init(ram_addr_t ram_size, int vga_ram_size,
1400
 
                     const char *boot_device, DisplayState *ds,
1401
 
                     const char *kernel_filename, const char *kernel_cmdline,
1402
 
                     const char *initrd_filename, const char *cpu_model)
1403
 
{
1404
 
    stellaris_init(kernel_filename, cpu_model, ds, &stellaris_boards[0]);
1405
 
}
1406
 
 
1407
 
static void lm3s6965evb_init(ram_addr_t ram_size, int vga_ram_size,
1408
 
                     const char *boot_device, DisplayState *ds,
1409
 
                     const char *kernel_filename, const char *kernel_cmdline,
1410
 
                     const char *initrd_filename, const char *cpu_model)
1411
 
{
1412
 
    stellaris_init(kernel_filename, cpu_model, ds, &stellaris_boards[1]);
1413
 
}
1414
 
 
1415
 
QEMUMachine lm3s811evb_machine = {
1416
 
    .name = "lm3s811evb",
1417
 
    .desc = "Stellaris LM3S811EVB",
1418
 
    .init = lm3s811evb_init,
1419
 
    .ram_require = (64 * 1024 + 8 * 1024) | RAMSIZE_FIXED,
1420
 
};
1421
 
 
1422
 
QEMUMachine lm3s6965evb_machine = {
1423
 
    .name = "lm3s6965evb",
1424
 
    .desc = "Stellaris LM3S6965EVB",
1425
 
    .init = lm3s6965evb_init,
1426
 
    .ram_require = (256 * 1024 + 64 * 1024) | RAMSIZE_FIXED,
1427
 
};