]> git.proxmox.com Git - mirror_qemu.git/blame - hw/stellaris.c
stellaris: convert sys to memory API
[mirror_qemu.git] / hw / stellaris.c
CommitLineData
9ee6e8bb 1/*
1654b2d6 2 * Luminary Micro Stellaris peripherals
9ee6e8bb
PB
3 *
4 * Copyright (c) 2006 CodeSourcery.
5 * Written by Paul Brook
6 *
8e31bf38 7 * This code is licensed under the GPL.
9ee6e8bb
PB
8 */
9
a7d518a6 10#include "sysbus.h"
5493e33f 11#include "ssi.h"
87ecb68b 12#include "arm-misc.h"
87ecb68b
PB
13#include "devices.h"
14#include "qemu-timer.h"
15#include "i2c.h"
eea589cc 16#include "net.h"
87ecb68b 17#include "boards.h"
7d6f78cf 18#include "exec-memory.h"
9ee6e8bb 19
cf0dbb21
PB
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
9ee6e8bb
PB
32typedef 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;
cf0dbb21 41 uint32_t peripherals;
9ee6e8bb
PB
42} stellaris_board_info;
43
44/* General purpose timer module. */
45
9ee6e8bb 46typedef struct gptm_state {
40905a6a 47 SysBusDevice busdev;
9ee6e8bb
PB
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];
9ee6e8bb
PB
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
66static 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
73static void gptm_stop(gptm_state *s, int n)
74{
75 qemu_del_timer(s->timer[n]);
76}
77
78static void gptm_reload(gptm_state *s, int n, int reset)
79{
80 int64_t tick;
81 if (reset)
74475455 82 tick = qemu_get_clock_ns(vm_clock);
9ee6e8bb
PB
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);
e57ec016 90 tick += (int64_t)count * system_clock_scale;
9ee6e8bb
PB
91 } else if (s->config == 1) {
92 /* 32-bit RTC. 1Hz tick. */
6ee093c9 93 tick += get_ticks_per_sec();
9ee6e8bb
PB
94 } else if (s->mode[n] == 0xa) {
95 /* PWM mode. Not implemented. */
96 } else {
2ac71179 97 hw_error("TODO: 16-bit timer mode 0x%x\n", s->mode[n]);
9ee6e8bb
PB
98 }
99 s->tick[n] = tick;
100 qemu_mod_timer(s->timer[n], tick);
101}
102
103static 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. */
40905a6a 115 qemu_irq_pulse(s->trigger);
9ee6e8bb
PB
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 {
2ac71179 138 hw_error("TODO: 16-bit timer mode 0x%x\n", s->mode[n]);
9ee6e8bb
PB
139 }
140 gptm_update_irq(s);
141}
142
c227f099 143static uint32_t gptm_read(void *opaque, target_phys_addr_t offset)
9ee6e8bb
PB
144{
145 gptm_state *s = (gptm_state *)opaque;
146
9ee6e8bb
PB
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 */
2ac71179 184 hw_error("TODO: Timer value read\n");
9ee6e8bb 185 default:
2ac71179 186 hw_error("gptm_read: Bad offset 0x%x\n", (int)offset);
9ee6e8bb
PB
187 return 0;
188 }
189}
190
c227f099 191static void gptm_write(void *opaque, target_phys_addr_t offset, uint32_t value)
9ee6e8bb
PB
192{
193 gptm_state *s = (gptm_state *)opaque;
194 uint32_t oldval;
195
9ee6e8bb
PB
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:
2ac71179 266 hw_error("gptm_write: Bad offset 0x%x\n", (int)offset);
9ee6e8bb
PB
267 }
268 gptm_update_irq(s);
269}
270
d60efc6b 271static CPUReadMemoryFunc * const gptm_readfn[] = {
9ee6e8bb
PB
272 gptm_read,
273 gptm_read,
274 gptm_read
275};
276
d60efc6b 277static CPUWriteMemoryFunc * const gptm_writefn[] = {
9ee6e8bb
PB
278 gptm_write,
279 gptm_write,
280 gptm_write
281};
282
10f85a29
JQ
283static const VMStateDescription vmstate_stellaris_gptm = {
284 .name = "stellaris_gptm",
285 .version_id = 1,
286 .minimum_version_id = 1,
287 .minimum_version_id_old = 1,
288 .fields = (VMStateField[]) {
289 VMSTATE_UINT32(config, gptm_state),
290 VMSTATE_UINT32_ARRAY(mode, gptm_state, 2),
291 VMSTATE_UINT32(control, gptm_state),
292 VMSTATE_UINT32(state, gptm_state),
293 VMSTATE_UINT32(mask, gptm_state),
dd8a4dcd 294 VMSTATE_UNUSED(8),
10f85a29
JQ
295 VMSTATE_UINT32_ARRAY(load, gptm_state, 2),
296 VMSTATE_UINT32_ARRAY(match, gptm_state, 2),
297 VMSTATE_UINT32_ARRAY(prescale, gptm_state, 2),
298 VMSTATE_UINT32_ARRAY(match_prescale, gptm_state, 2),
299 VMSTATE_UINT32(rtc, gptm_state),
300 VMSTATE_INT64_ARRAY(tick, gptm_state, 2),
301 VMSTATE_TIMER_ARRAY(timer, gptm_state, 2),
302 VMSTATE_END_OF_LIST()
303 }
304};
23e39294 305
81a322d4 306static int stellaris_gptm_init(SysBusDevice *dev)
9ee6e8bb
PB
307{
308 int iomemtype;
40905a6a 309 gptm_state *s = FROM_SYSBUS(gptm_state, dev);
9ee6e8bb 310
40905a6a
PB
311 sysbus_init_irq(dev, &s->irq);
312 qdev_init_gpio_out(&dev->qdev, &s->trigger, 1);
9ee6e8bb 313
1eed09cb 314 iomemtype = cpu_register_io_memory(gptm_readfn,
2507c12a
AG
315 gptm_writefn, s,
316 DEVICE_NATIVE_ENDIAN);
40905a6a
PB
317 sysbus_init_mmio(dev, 0x1000, iomemtype);
318
319 s->opaque[0] = s->opaque[1] = s;
74475455
PB
320 s->timer[0] = qemu_new_timer_ns(vm_clock, gptm_tick, &s->opaque[0]);
321 s->timer[1] = qemu_new_timer_ns(vm_clock, gptm_tick, &s->opaque[1]);
10f85a29 322 vmstate_register(&dev->qdev, -1, &vmstate_stellaris_gptm, s);
81a322d4 323 return 0;
9ee6e8bb
PB
324}
325
326
327/* System controller. */
328
329typedef struct {
5699301f 330 MemoryRegion iomem;
9ee6e8bb
PB
331 uint32_t pborctl;
332 uint32_t ldopctl;
333 uint32_t int_status;
334 uint32_t int_mask;
335 uint32_t resc;
336 uint32_t rcc;
dc804ab7 337 uint32_t rcc2;
9ee6e8bb
PB
338 uint32_t rcgc[3];
339 uint32_t scgc[3];
340 uint32_t dcgc[3];
341 uint32_t clkvclr;
342 uint32_t ldoarst;
eea589cc
PB
343 uint32_t user0;
344 uint32_t user1;
9ee6e8bb
PB
345 qemu_irq irq;
346 stellaris_board_info *board;
347} ssys_state;
348
349static void ssys_update(ssys_state *s)
350{
351 qemu_set_irq(s->irq, (s->int_status & s->int_mask) != 0);
352}
353
354static uint32_t pllcfg_sandstorm[16] = {
355 0x31c0, /* 1 Mhz */
356 0x1ae0, /* 1.8432 Mhz */
357 0x18c0, /* 2 Mhz */
358 0xd573, /* 2.4576 Mhz */
359 0x37a6, /* 3.57954 Mhz */
360 0x1ae2, /* 3.6864 Mhz */
361 0x0c40, /* 4 Mhz */
362 0x98bc, /* 4.906 Mhz */
363 0x935b, /* 4.9152 Mhz */
364 0x09c0, /* 5 Mhz */
365 0x4dee, /* 5.12 Mhz */
366 0x0c41, /* 6 Mhz */
367 0x75db, /* 6.144 Mhz */
368 0x1ae6, /* 7.3728 Mhz */
369 0x0600, /* 8 Mhz */
370 0x585b /* 8.192 Mhz */
371};
372
373static uint32_t pllcfg_fury[16] = {
374 0x3200, /* 1 Mhz */
375 0x1b20, /* 1.8432 Mhz */
376 0x1900, /* 2 Mhz */
377 0xf42b, /* 2.4576 Mhz */
378 0x37e3, /* 3.57954 Mhz */
379 0x1b21, /* 3.6864 Mhz */
380 0x0c80, /* 4 Mhz */
381 0x98ee, /* 4.906 Mhz */
382 0xd5b4, /* 4.9152 Mhz */
383 0x0a00, /* 5 Mhz */
384 0x4e27, /* 5.12 Mhz */
385 0x1902, /* 6 Mhz */
386 0xec1c, /* 6.144 Mhz */
387 0x1b23, /* 7.3728 Mhz */
388 0x0640, /* 8 Mhz */
389 0xb11c /* 8.192 Mhz */
390};
391
dc804ab7
EA
392#define DID0_VER_MASK 0x70000000
393#define DID0_VER_0 0x00000000
394#define DID0_VER_1 0x10000000
395
396#define DID0_CLASS_MASK 0x00FF0000
397#define DID0_CLASS_SANDSTORM 0x00000000
398#define DID0_CLASS_FURY 0x00010000
399
400static int ssys_board_class(const ssys_state *s)
401{
402 uint32_t did0 = s->board->did0;
403 switch (did0 & DID0_VER_MASK) {
404 case DID0_VER_0:
405 return DID0_CLASS_SANDSTORM;
406 case DID0_VER_1:
407 switch (did0 & DID0_CLASS_MASK) {
408 case DID0_CLASS_SANDSTORM:
409 case DID0_CLASS_FURY:
410 return did0 & DID0_CLASS_MASK;
411 }
412 /* for unknown classes, fall through */
413 default:
414 hw_error("ssys_board_class: Unknown class 0x%08x\n", did0);
415 }
416}
417
5699301f
BC
418static uint64_t ssys_read(void *opaque, target_phys_addr_t offset,
419 unsigned size)
9ee6e8bb
PB
420{
421 ssys_state *s = (ssys_state *)opaque;
422
9ee6e8bb
PB
423 switch (offset) {
424 case 0x000: /* DID0 */
425 return s->board->did0;
426 case 0x004: /* DID1 */
427 return s->board->did1;
428 case 0x008: /* DC0 */
429 return s->board->dc0;
430 case 0x010: /* DC1 */
431 return s->board->dc1;
432 case 0x014: /* DC2 */
433 return s->board->dc2;
434 case 0x018: /* DC3 */
435 return s->board->dc3;
436 case 0x01c: /* DC4 */
437 return s->board->dc4;
438 case 0x030: /* PBORCTL */
439 return s->pborctl;
440 case 0x034: /* LDOPCTL */
441 return s->ldopctl;
442 case 0x040: /* SRCR0 */
443 return 0;
444 case 0x044: /* SRCR1 */
445 return 0;
446 case 0x048: /* SRCR2 */
447 return 0;
448 case 0x050: /* RIS */
449 return s->int_status;
450 case 0x054: /* IMC */
451 return s->int_mask;
452 case 0x058: /* MISC */
453 return s->int_status & s->int_mask;
454 case 0x05c: /* RESC */
455 return s->resc;
456 case 0x060: /* RCC */
457 return s->rcc;
458 case 0x064: /* PLLCFG */
459 {
460 int xtal;
461 xtal = (s->rcc >> 6) & 0xf;
dc804ab7
EA
462 switch (ssys_board_class(s)) {
463 case DID0_CLASS_FURY:
9ee6e8bb 464 return pllcfg_fury[xtal];
dc804ab7 465 case DID0_CLASS_SANDSTORM:
9ee6e8bb 466 return pllcfg_sandstorm[xtal];
dc804ab7
EA
467 default:
468 hw_error("ssys_read: Unhandled class for PLLCFG read.\n");
469 return 0;
9ee6e8bb
PB
470 }
471 }
dc804ab7
EA
472 case 0x070: /* RCC2 */
473 return s->rcc2;
9ee6e8bb
PB
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;
eea589cc
PB
496 case 0x1e0: /* USER0 */
497 return s->user0;
498 case 0x1e4: /* USER1 */
499 return s->user1;
9ee6e8bb 500 default:
2ac71179 501 hw_error("ssys_read: Bad offset 0x%x\n", (int)offset);
9ee6e8bb
PB
502 return 0;
503 }
504}
505
dc804ab7
EA
506static bool ssys_use_rcc2(ssys_state *s)
507{
508 return (s->rcc2 >> 31) & 0x1;
509}
510
511/*
512 * Caculate the sys. clock period in ms.
513 */
23e39294
PB
514static void ssys_calculate_system_clock(ssys_state *s)
515{
dc804ab7
EA
516 if (ssys_use_rcc2(s)) {
517 system_clock_scale = 5 * (((s->rcc2 >> 23) & 0x3f) + 1);
518 } else {
519 system_clock_scale = 5 * (((s->rcc >> 23) & 0xf) + 1);
520 }
23e39294
PB
521}
522
5699301f
BC
523static void ssys_write(void *opaque, target_phys_addr_t offset,
524 uint64_t value, unsigned size)
9ee6e8bb
PB
525{
526 ssys_state *s = (ssys_state *)opaque;
527
9ee6e8bb
PB
528 switch (offset) {
529 case 0x030: /* PBORCTL */
530 s->pborctl = value & 0xffff;
531 break;
532 case 0x034: /* LDOPCTL */
533 s->ldopctl = value & 0x1f;
534 break;
535 case 0x040: /* SRCR0 */
536 case 0x044: /* SRCR1 */
537 case 0x048: /* SRCR2 */
538 fprintf(stderr, "Peripheral reset not implemented\n");
539 break;
540 case 0x054: /* IMC */
541 s->int_mask = value & 0x7f;
542 break;
543 case 0x058: /* MISC */
544 s->int_status &= ~value;
545 break;
546 case 0x05c: /* RESC */
547 s->resc = value & 0x3f;
548 break;
549 case 0x060: /* RCC */
550 if ((s->rcc & (1 << 13)) != 0 && (value & (1 << 13)) == 0) {
551 /* PLL enable. */
552 s->int_status |= (1 << 6);
553 }
554 s->rcc = value;
23e39294 555 ssys_calculate_system_clock(s);
9ee6e8bb 556 break;
dc804ab7
EA
557 case 0x070: /* RCC2 */
558 if (ssys_board_class(s) == DID0_CLASS_SANDSTORM) {
559 break;
560 }
561
562 if ((s->rcc2 & (1 << 13)) != 0 && (value & (1 << 13)) == 0) {
563 /* PLL enable. */
564 s->int_status |= (1 << 6);
565 }
566 s->rcc2 = value;
567 ssys_calculate_system_clock(s);
568 break;
9ee6e8bb
PB
569 case 0x100: /* RCGC0 */
570 s->rcgc[0] = value;
571 break;
572 case 0x104: /* RCGC1 */
573 s->rcgc[1] = value;
574 break;
575 case 0x108: /* RCGC2 */
576 s->rcgc[2] = value;
577 break;
578 case 0x110: /* SCGC0 */
579 s->scgc[0] = value;
580 break;
581 case 0x114: /* SCGC1 */
582 s->scgc[1] = value;
583 break;
584 case 0x118: /* SCGC2 */
585 s->scgc[2] = value;
586 break;
587 case 0x120: /* DCGC0 */
588 s->dcgc[0] = value;
589 break;
590 case 0x124: /* DCGC1 */
591 s->dcgc[1] = value;
592 break;
593 case 0x128: /* DCGC2 */
594 s->dcgc[2] = value;
595 break;
596 case 0x150: /* CLKVCLR */
597 s->clkvclr = value;
598 break;
599 case 0x160: /* LDOARST */
600 s->ldoarst = value;
601 break;
602 default:
2ac71179 603 hw_error("ssys_write: Bad offset 0x%x\n", (int)offset);
9ee6e8bb
PB
604 }
605 ssys_update(s);
606}
607
5699301f
BC
608static const MemoryRegionOps ssys_ops = {
609 .read = ssys_read,
610 .write = ssys_write,
611 .endianness = DEVICE_NATIVE_ENDIAN,
9ee6e8bb
PB
612};
613
9596ebb7 614static void ssys_reset(void *opaque)
9ee6e8bb
PB
615{
616 ssys_state *s = (ssys_state *)opaque;
617
618 s->pborctl = 0x7ffd;
619 s->rcc = 0x078e3ac0;
dc804ab7
EA
620
621 if (ssys_board_class(s) == DID0_CLASS_SANDSTORM) {
622 s->rcc2 = 0;
623 } else {
624 s->rcc2 = 0x07802810;
625 }
9ee6e8bb
PB
626 s->rcgc[0] = 1;
627 s->scgc[0] = 1;
628 s->dcgc[0] = 1;
629}
630
293c16aa 631static int stellaris_sys_post_load(void *opaque, int version_id)
23e39294 632{
293c16aa 633 ssys_state *s = opaque;
23e39294 634
23e39294
PB
635 ssys_calculate_system_clock(s);
636
637 return 0;
638}
639
293c16aa
JQ
640static const VMStateDescription vmstate_stellaris_sys = {
641 .name = "stellaris_sys",
dc804ab7 642 .version_id = 2,
293c16aa
JQ
643 .minimum_version_id = 1,
644 .minimum_version_id_old = 1,
645 .post_load = stellaris_sys_post_load,
646 .fields = (VMStateField[]) {
647 VMSTATE_UINT32(pborctl, ssys_state),
648 VMSTATE_UINT32(ldopctl, ssys_state),
649 VMSTATE_UINT32(int_mask, ssys_state),
650 VMSTATE_UINT32(int_status, ssys_state),
651 VMSTATE_UINT32(resc, ssys_state),
652 VMSTATE_UINT32(rcc, ssys_state),
dc804ab7 653 VMSTATE_UINT32_V(rcc2, ssys_state, 2),
293c16aa
JQ
654 VMSTATE_UINT32_ARRAY(rcgc, ssys_state, 3),
655 VMSTATE_UINT32_ARRAY(scgc, ssys_state, 3),
656 VMSTATE_UINT32_ARRAY(dcgc, ssys_state, 3),
657 VMSTATE_UINT32(clkvclr, ssys_state),
658 VMSTATE_UINT32(ldoarst, ssys_state),
659 VMSTATE_END_OF_LIST()
660 }
661};
662
81a322d4
GH
663static int stellaris_sys_init(uint32_t base, qemu_irq irq,
664 stellaris_board_info * board,
665 uint8_t *macaddr)
9ee6e8bb 666{
9ee6e8bb
PB
667 ssys_state *s;
668
7267c094 669 s = (ssys_state *)g_malloc0(sizeof(ssys_state));
9ee6e8bb
PB
670 s->irq = irq;
671 s->board = board;
eea589cc
PB
672 /* Most devices come preprogrammed with a MAC address in the user data. */
673 s->user0 = macaddr[0] | (macaddr[1] << 8) | (macaddr[2] << 16);
674 s->user1 = macaddr[3] | (macaddr[4] << 8) | (macaddr[5] << 16);
9ee6e8bb 675
5699301f
BC
676 memory_region_init_io(&s->iomem, &ssys_ops, s, "ssys", 0x00001000);
677 memory_region_add_subregion(get_system_memory(), base, &s->iomem);
9ee6e8bb 678 ssys_reset(s);
293c16aa 679 vmstate_register(NULL, -1, &vmstate_stellaris_sys, s);
81a322d4 680 return 0;
9ee6e8bb
PB
681}
682
683
684/* I2C controller. */
685
686typedef struct {
1de9610c 687 SysBusDevice busdev;
9ee6e8bb
PB
688 i2c_bus *bus;
689 qemu_irq irq;
9ee6e8bb
PB
690 uint32_t msa;
691 uint32_t mcs;
692 uint32_t mdr;
693 uint32_t mtpr;
694 uint32_t mimr;
695 uint32_t mris;
696 uint32_t mcr;
697} stellaris_i2c_state;
698
699#define STELLARIS_I2C_MCS_BUSY 0x01
700#define STELLARIS_I2C_MCS_ERROR 0x02
701#define STELLARIS_I2C_MCS_ADRACK 0x04
702#define STELLARIS_I2C_MCS_DATACK 0x08
703#define STELLARIS_I2C_MCS_ARBLST 0x10
704#define STELLARIS_I2C_MCS_IDLE 0x20
705#define STELLARIS_I2C_MCS_BUSBSY 0x40
706
c227f099 707static uint32_t stellaris_i2c_read(void *opaque, target_phys_addr_t offset)
9ee6e8bb
PB
708{
709 stellaris_i2c_state *s = (stellaris_i2c_state *)opaque;
710
9ee6e8bb
PB
711 switch (offset) {
712 case 0x00: /* MSA */
713 return s->msa;
714 case 0x04: /* MCS */
715 /* We don't emulate timing, so the controller is never busy. */
716 return s->mcs | STELLARIS_I2C_MCS_IDLE;
717 case 0x08: /* MDR */
718 return s->mdr;
719 case 0x0c: /* MTPR */
720 return s->mtpr;
721 case 0x10: /* MIMR */
722 return s->mimr;
723 case 0x14: /* MRIS */
724 return s->mris;
725 case 0x18: /* MMIS */
726 return s->mris & s->mimr;
727 case 0x20: /* MCR */
728 return s->mcr;
729 default:
2ac71179 730 hw_error("strllaris_i2c_read: Bad offset 0x%x\n", (int)offset);
9ee6e8bb
PB
731 return 0;
732 }
733}
734
735static void stellaris_i2c_update(stellaris_i2c_state *s)
736{
737 int level;
738
739 level = (s->mris & s->mimr) != 0;
740 qemu_set_irq(s->irq, level);
741}
742
c227f099 743static void stellaris_i2c_write(void *opaque, target_phys_addr_t offset,
9ee6e8bb
PB
744 uint32_t value)
745{
746 stellaris_i2c_state *s = (stellaris_i2c_state *)opaque;
747
9ee6e8bb
PB
748 switch (offset) {
749 case 0x00: /* MSA */
750 s->msa = value & 0xff;
751 break;
752 case 0x04: /* MCS */
753 if ((s->mcr & 0x10) == 0) {
754 /* Disabled. Do nothing. */
755 break;
756 }
757 /* Grab the bus if this is starting a transfer. */
758 if ((value & 2) && (s->mcs & STELLARIS_I2C_MCS_BUSBSY) == 0) {
759 if (i2c_start_transfer(s->bus, s->msa >> 1, s->msa & 1)) {
760 s->mcs |= STELLARIS_I2C_MCS_ARBLST;
761 } else {
762 s->mcs &= ~STELLARIS_I2C_MCS_ARBLST;
763 s->mcs |= STELLARIS_I2C_MCS_BUSBSY;
764 }
765 }
766 /* If we don't have the bus then indicate an error. */
767 if (!i2c_bus_busy(s->bus)
768 || (s->mcs & STELLARIS_I2C_MCS_BUSBSY) == 0) {
769 s->mcs |= STELLARIS_I2C_MCS_ERROR;
770 break;
771 }
772 s->mcs &= ~STELLARIS_I2C_MCS_ERROR;
773 if (value & 1) {
774 /* Transfer a byte. */
775 /* TODO: Handle errors. */
776 if (s->msa & 1) {
777 /* Recv */
778 s->mdr = i2c_recv(s->bus) & 0xff;
779 } else {
780 /* Send */
781 i2c_send(s->bus, s->mdr);
782 }
783 /* Raise an interrupt. */
784 s->mris |= 1;
785 }
786 if (value & 4) {
787 /* Finish transfer. */
788 i2c_end_transfer(s->bus);
789 s->mcs &= ~STELLARIS_I2C_MCS_BUSBSY;
790 }
791 break;
792 case 0x08: /* MDR */
793 s->mdr = value & 0xff;
794 break;
795 case 0x0c: /* MTPR */
796 s->mtpr = value & 0xff;
797 break;
798 case 0x10: /* MIMR */
799 s->mimr = 1;
800 break;
801 case 0x1c: /* MICR */
802 s->mris &= ~value;
803 break;
804 case 0x20: /* MCR */
805 if (value & 1)
2ac71179 806 hw_error(
9ee6e8bb
PB
807 "stellaris_i2c_write: Loopback not implemented\n");
808 if (value & 0x20)
2ac71179 809 hw_error(
9ee6e8bb
PB
810 "stellaris_i2c_write: Slave mode not implemented\n");
811 s->mcr = value & 0x31;
812 break;
813 default:
2ac71179 814 hw_error("stellaris_i2c_write: Bad offset 0x%x\n",
9ee6e8bb
PB
815 (int)offset);
816 }
817 stellaris_i2c_update(s);
818}
819
820static void stellaris_i2c_reset(stellaris_i2c_state *s)
821{
822 if (s->mcs & STELLARIS_I2C_MCS_BUSBSY)
823 i2c_end_transfer(s->bus);
824
825 s->msa = 0;
826 s->mcs = 0;
827 s->mdr = 0;
828 s->mtpr = 1;
829 s->mimr = 0;
830 s->mris = 0;
831 s->mcr = 0;
832 stellaris_i2c_update(s);
833}
834
d60efc6b 835static CPUReadMemoryFunc * const stellaris_i2c_readfn[] = {
9ee6e8bb
PB
836 stellaris_i2c_read,
837 stellaris_i2c_read,
838 stellaris_i2c_read
839};
840
d60efc6b 841static CPUWriteMemoryFunc * const stellaris_i2c_writefn[] = {
9ee6e8bb
PB
842 stellaris_i2c_write,
843 stellaris_i2c_write,
844 stellaris_i2c_write
845};
846
ff269cd0
JQ
847static const VMStateDescription vmstate_stellaris_i2c = {
848 .name = "stellaris_i2c",
849 .version_id = 1,
850 .minimum_version_id = 1,
851 .minimum_version_id_old = 1,
852 .fields = (VMStateField[]) {
853 VMSTATE_UINT32(msa, stellaris_i2c_state),
854 VMSTATE_UINT32(mcs, stellaris_i2c_state),
855 VMSTATE_UINT32(mdr, stellaris_i2c_state),
856 VMSTATE_UINT32(mtpr, stellaris_i2c_state),
857 VMSTATE_UINT32(mimr, stellaris_i2c_state),
858 VMSTATE_UINT32(mris, stellaris_i2c_state),
859 VMSTATE_UINT32(mcr, stellaris_i2c_state),
860 VMSTATE_END_OF_LIST()
861 }
862};
23e39294 863
81a322d4 864static int stellaris_i2c_init(SysBusDevice * dev)
9ee6e8bb 865{
1de9610c 866 stellaris_i2c_state *s = FROM_SYSBUS(stellaris_i2c_state, dev);
02e2da45 867 i2c_bus *bus;
9ee6e8bb
PB
868 int iomemtype;
869
1de9610c 870 sysbus_init_irq(dev, &s->irq);
02e2da45 871 bus = i2c_init_bus(&dev->qdev, "i2c");
9ee6e8bb
PB
872 s->bus = bus;
873
1eed09cb 874 iomemtype = cpu_register_io_memory(stellaris_i2c_readfn,
2507c12a
AG
875 stellaris_i2c_writefn, s,
876 DEVICE_NATIVE_ENDIAN);
1de9610c 877 sysbus_init_mmio(dev, 0x1000, iomemtype);
9ee6e8bb
PB
878 /* ??? For now we only implement the master interface. */
879 stellaris_i2c_reset(s);
ff269cd0 880 vmstate_register(&dev->qdev, -1, &vmstate_stellaris_i2c, s);
81a322d4 881 return 0;
9ee6e8bb
PB
882}
883
884/* Analogue to Digital Converter. This is only partially implemented,
885 enough for applications that use a combined ADC and timer tick. */
886
887#define STELLARIS_ADC_EM_CONTROLLER 0
888#define STELLARIS_ADC_EM_COMP 1
889#define STELLARIS_ADC_EM_EXTERNAL 4
890#define STELLARIS_ADC_EM_TIMER 5
891#define STELLARIS_ADC_EM_PWM0 6
892#define STELLARIS_ADC_EM_PWM1 7
893#define STELLARIS_ADC_EM_PWM2 8
894
895#define STELLARIS_ADC_FIFO_EMPTY 0x0100
896#define STELLARIS_ADC_FIFO_FULL 0x1000
897
898typedef struct
899{
40905a6a 900 SysBusDevice busdev;
9ee6e8bb
PB
901 uint32_t actss;
902 uint32_t ris;
903 uint32_t im;
904 uint32_t emux;
905 uint32_t ostat;
906 uint32_t ustat;
907 uint32_t sspri;
908 uint32_t sac;
909 struct {
910 uint32_t state;
911 uint32_t data[16];
912 } fifo[4];
913 uint32_t ssmux[4];
914 uint32_t ssctl[4];
23e39294 915 uint32_t noise;
2c6554bc 916 qemu_irq irq[4];
9ee6e8bb
PB
917} stellaris_adc_state;
918
919static uint32_t stellaris_adc_fifo_read(stellaris_adc_state *s, int n)
920{
921 int tail;
922
923 tail = s->fifo[n].state & 0xf;
924 if (s->fifo[n].state & STELLARIS_ADC_FIFO_EMPTY) {
925 s->ustat |= 1 << n;
926 } else {
927 s->fifo[n].state = (s->fifo[n].state & ~0xf) | ((tail + 1) & 0xf);
928 s->fifo[n].state &= ~STELLARIS_ADC_FIFO_FULL;
929 if (tail + 1 == ((s->fifo[n].state >> 4) & 0xf))
930 s->fifo[n].state |= STELLARIS_ADC_FIFO_EMPTY;
931 }
932 return s->fifo[n].data[tail];
933}
934
935static void stellaris_adc_fifo_write(stellaris_adc_state *s, int n,
936 uint32_t value)
937{
938 int head;
939
2c6554bc
PB
940 /* TODO: Real hardware has limited size FIFOs. We have a full 16 entry
941 FIFO fir each sequencer. */
9ee6e8bb
PB
942 head = (s->fifo[n].state >> 4) & 0xf;
943 if (s->fifo[n].state & STELLARIS_ADC_FIFO_FULL) {
944 s->ostat |= 1 << n;
945 return;
946 }
947 s->fifo[n].data[head] = value;
948 head = (head + 1) & 0xf;
949 s->fifo[n].state &= ~STELLARIS_ADC_FIFO_EMPTY;
950 s->fifo[n].state = (s->fifo[n].state & ~0xf0) | (head << 4);
951 if ((s->fifo[n].state & 0xf) == head)
952 s->fifo[n].state |= STELLARIS_ADC_FIFO_FULL;
953}
954
955static void stellaris_adc_update(stellaris_adc_state *s)
956{
957 int level;
2c6554bc 958 int n;
9ee6e8bb 959
2c6554bc
PB
960 for (n = 0; n < 4; n++) {
961 level = (s->ris & s->im & (1 << n)) != 0;
962 qemu_set_irq(s->irq[n], level);
963 }
9ee6e8bb
PB
964}
965
966static void stellaris_adc_trigger(void *opaque, int irq, int level)
967{
968 stellaris_adc_state *s = (stellaris_adc_state *)opaque;
2c6554bc 969 int n;
9ee6e8bb 970
2c6554bc
PB
971 for (n = 0; n < 4; n++) {
972 if ((s->actss & (1 << n)) == 0) {
973 continue;
974 }
9ee6e8bb 975
2c6554bc
PB
976 if (((s->emux >> (n * 4)) & 0xff) != 5) {
977 continue;
978 }
979
980 /* Some applications use the ADC as a random number source, so introduce
981 some variation into the signal. */
982 s->noise = s->noise * 314159 + 1;
983 /* ??? actual inputs not implemented. Return an arbitrary value. */
984 stellaris_adc_fifo_write(s, n, 0x200 + ((s->noise >> 16) & 7));
985 s->ris |= (1 << n);
986 stellaris_adc_update(s);
987 }
9ee6e8bb
PB
988}
989
990static void stellaris_adc_reset(stellaris_adc_state *s)
991{
992 int n;
993
994 for (n = 0; n < 4; n++) {
995 s->ssmux[n] = 0;
996 s->ssctl[n] = 0;
997 s->fifo[n].state = STELLARIS_ADC_FIFO_EMPTY;
998 }
999}
1000
c227f099 1001static uint32_t stellaris_adc_read(void *opaque, target_phys_addr_t offset)
9ee6e8bb
PB
1002{
1003 stellaris_adc_state *s = (stellaris_adc_state *)opaque;
1004
1005 /* TODO: Implement this. */
9ee6e8bb
PB
1006 if (offset >= 0x40 && offset < 0xc0) {
1007 int n;
1008 n = (offset - 0x40) >> 5;
1009 switch (offset & 0x1f) {
1010 case 0x00: /* SSMUX */
1011 return s->ssmux[n];
1012 case 0x04: /* SSCTL */
1013 return s->ssctl[n];
1014 case 0x08: /* SSFIFO */
1015 return stellaris_adc_fifo_read(s, n);
1016 case 0x0c: /* SSFSTAT */
1017 return s->fifo[n].state;
1018 default:
1019 break;
1020 }
1021 }
1022 switch (offset) {
1023 case 0x00: /* ACTSS */
1024 return s->actss;
1025 case 0x04: /* RIS */
1026 return s->ris;
1027 case 0x08: /* IM */
1028 return s->im;
1029 case 0x0c: /* ISC */
1030 return s->ris & s->im;
1031 case 0x10: /* OSTAT */
1032 return s->ostat;
1033 case 0x14: /* EMUX */
1034 return s->emux;
1035 case 0x18: /* USTAT */
1036 return s->ustat;
1037 case 0x20: /* SSPRI */
1038 return s->sspri;
1039 case 0x30: /* SAC */
1040 return s->sac;
1041 default:
2ac71179 1042 hw_error("strllaris_adc_read: Bad offset 0x%x\n",
9ee6e8bb
PB
1043 (int)offset);
1044 return 0;
1045 }
1046}
1047
c227f099 1048static void stellaris_adc_write(void *opaque, target_phys_addr_t offset,
9ee6e8bb
PB
1049 uint32_t value)
1050{
1051 stellaris_adc_state *s = (stellaris_adc_state *)opaque;
1052
1053 /* TODO: Implement this. */
9ee6e8bb
PB
1054 if (offset >= 0x40 && offset < 0xc0) {
1055 int n;
1056 n = (offset - 0x40) >> 5;
1057 switch (offset & 0x1f) {
1058 case 0x00: /* SSMUX */
1059 s->ssmux[n] = value & 0x33333333;
1060 return;
1061 case 0x04: /* SSCTL */
1062 if (value != 6) {
2ac71179 1063 hw_error("ADC: Unimplemented sequence %x\n",
9ee6e8bb
PB
1064 value);
1065 }
1066 s->ssctl[n] = value;
1067 return;
1068 default:
1069 break;
1070 }
1071 }
1072 switch (offset) {
1073 case 0x00: /* ACTSS */
1074 s->actss = value & 0xf;
9ee6e8bb
PB
1075 break;
1076 case 0x08: /* IM */
1077 s->im = value;
1078 break;
1079 case 0x0c: /* ISC */
1080 s->ris &= ~value;
1081 break;
1082 case 0x10: /* OSTAT */
1083 s->ostat &= ~value;
1084 break;
1085 case 0x14: /* EMUX */
1086 s->emux = value;
1087 break;
1088 case 0x18: /* USTAT */
1089 s->ustat &= ~value;
1090 break;
1091 case 0x20: /* SSPRI */
1092 s->sspri = value;
1093 break;
1094 case 0x28: /* PSSI */
2ac71179 1095 hw_error("Not implemented: ADC sample initiate\n");
9ee6e8bb
PB
1096 break;
1097 case 0x30: /* SAC */
1098 s->sac = value;
1099 break;
1100 default:
2ac71179 1101 hw_error("stellaris_adc_write: Bad offset 0x%x\n", (int)offset);
9ee6e8bb
PB
1102 }
1103 stellaris_adc_update(s);
1104}
1105
d60efc6b 1106static CPUReadMemoryFunc * const stellaris_adc_readfn[] = {
9ee6e8bb
PB
1107 stellaris_adc_read,
1108 stellaris_adc_read,
1109 stellaris_adc_read
1110};
1111
d60efc6b 1112static CPUWriteMemoryFunc * const stellaris_adc_writefn[] = {
9ee6e8bb
PB
1113 stellaris_adc_write,
1114 stellaris_adc_write,
1115 stellaris_adc_write
1116};
1117
cf1d31dc
JQ
1118static const VMStateDescription vmstate_stellaris_adc = {
1119 .name = "stellaris_adc",
1120 .version_id = 1,
1121 .minimum_version_id = 1,
1122 .minimum_version_id_old = 1,
1123 .fields = (VMStateField[]) {
1124 VMSTATE_UINT32(actss, stellaris_adc_state),
1125 VMSTATE_UINT32(ris, stellaris_adc_state),
1126 VMSTATE_UINT32(im, stellaris_adc_state),
1127 VMSTATE_UINT32(emux, stellaris_adc_state),
1128 VMSTATE_UINT32(ostat, stellaris_adc_state),
1129 VMSTATE_UINT32(ustat, stellaris_adc_state),
1130 VMSTATE_UINT32(sspri, stellaris_adc_state),
1131 VMSTATE_UINT32(sac, stellaris_adc_state),
1132 VMSTATE_UINT32(fifo[0].state, stellaris_adc_state),
1133 VMSTATE_UINT32_ARRAY(fifo[0].data, stellaris_adc_state, 16),
1134 VMSTATE_UINT32(ssmux[0], stellaris_adc_state),
1135 VMSTATE_UINT32(ssctl[0], stellaris_adc_state),
1136 VMSTATE_UINT32(fifo[1].state, stellaris_adc_state),
1137 VMSTATE_UINT32_ARRAY(fifo[1].data, stellaris_adc_state, 16),
1138 VMSTATE_UINT32(ssmux[1], stellaris_adc_state),
1139 VMSTATE_UINT32(ssctl[1], stellaris_adc_state),
1140 VMSTATE_UINT32(fifo[2].state, stellaris_adc_state),
1141 VMSTATE_UINT32_ARRAY(fifo[2].data, stellaris_adc_state, 16),
1142 VMSTATE_UINT32(ssmux[2], stellaris_adc_state),
1143 VMSTATE_UINT32(ssctl[2], stellaris_adc_state),
1144 VMSTATE_UINT32(fifo[3].state, stellaris_adc_state),
1145 VMSTATE_UINT32_ARRAY(fifo[3].data, stellaris_adc_state, 16),
1146 VMSTATE_UINT32(ssmux[3], stellaris_adc_state),
1147 VMSTATE_UINT32(ssctl[3], stellaris_adc_state),
1148 VMSTATE_UINT32(noise, stellaris_adc_state),
1149 VMSTATE_END_OF_LIST()
23e39294 1150 }
cf1d31dc 1151};
23e39294 1152
81a322d4 1153static int stellaris_adc_init(SysBusDevice *dev)
9ee6e8bb 1154{
40905a6a 1155 stellaris_adc_state *s = FROM_SYSBUS(stellaris_adc_state, dev);
9ee6e8bb 1156 int iomemtype;
2c6554bc 1157 int n;
9ee6e8bb 1158
2c6554bc 1159 for (n = 0; n < 4; n++) {
40905a6a 1160 sysbus_init_irq(dev, &s->irq[n]);
2c6554bc 1161 }
9ee6e8bb 1162
1eed09cb 1163 iomemtype = cpu_register_io_memory(stellaris_adc_readfn,
2507c12a
AG
1164 stellaris_adc_writefn, s,
1165 DEVICE_NATIVE_ENDIAN);
40905a6a 1166 sysbus_init_mmio(dev, 0x1000, iomemtype);
9ee6e8bb 1167 stellaris_adc_reset(s);
40905a6a 1168 qdev_init_gpio_in(&dev->qdev, stellaris_adc_trigger, 1);
cf1d31dc 1169 vmstate_register(&dev->qdev, -1, &vmstate_stellaris_adc, s);
81a322d4 1170 return 0;
9ee6e8bb
PB
1171}
1172
775616c3
PB
1173/* Some boards have both an OLED controller and SD card connected to
1174 the same SSI port, with the SD card chip select connected to a
1175 GPIO pin. Technically the OLED chip select is connected to the SSI
1176 Fss pin. We do not bother emulating that as both devices should
1177 never be selected simultaneously, and our OLED controller ignores stray
1178 0xff commands that occur when deselecting the SD card. */
1179
1180typedef struct {
5493e33f 1181 SSISlave ssidev;
775616c3
PB
1182 qemu_irq irq;
1183 int current_dev;
5493e33f 1184 SSIBus *bus[2];
775616c3
PB
1185} stellaris_ssi_bus_state;
1186
1187static void stellaris_ssi_bus_select(void *opaque, int irq, int level)
1188{
1189 stellaris_ssi_bus_state *s = (stellaris_ssi_bus_state *)opaque;
1190
1191 s->current_dev = level;
1192}
1193
5493e33f 1194static uint32_t stellaris_ssi_bus_transfer(SSISlave *dev, uint32_t val)
775616c3 1195{
5493e33f 1196 stellaris_ssi_bus_state *s = FROM_SSI_SLAVE(stellaris_ssi_bus_state, dev);
775616c3 1197
5493e33f 1198 return ssi_transfer(s->bus[s->current_dev], val);
775616c3
PB
1199}
1200
a4dec1d0
JQ
1201static const VMStateDescription vmstate_stellaris_ssi_bus = {
1202 .name = "stellaris_ssi_bus",
1203 .version_id = 1,
1204 .minimum_version_id = 1,
1205 .minimum_version_id_old = 1,
1206 .fields = (VMStateField[]) {
1207 VMSTATE_INT32(current_dev, stellaris_ssi_bus_state),
1208 VMSTATE_END_OF_LIST()
1209 }
1210};
23e39294 1211
81a322d4 1212static int stellaris_ssi_bus_init(SSISlave *dev)
775616c3 1213{
5493e33f
PB
1214 stellaris_ssi_bus_state *s = FROM_SSI_SLAVE(stellaris_ssi_bus_state, dev);
1215
02e2da45
PB
1216 s->bus[0] = ssi_create_bus(&dev->qdev, "ssi0");
1217 s->bus[1] = ssi_create_bus(&dev->qdev, "ssi1");
5493e33f
PB
1218 qdev_init_gpio_in(&dev->qdev, stellaris_ssi_bus_select, 1);
1219
a4dec1d0 1220 vmstate_register(&dev->qdev, -1, &vmstate_stellaris_ssi_bus, s);
81a322d4 1221 return 0;
775616c3
PB
1222}
1223
9ee6e8bb
PB
1224/* Board init. */
1225static stellaris_board_info stellaris_boards[] = {
1226 { "LM3S811EVB",
1227 0,
1228 0x0032000e,
1229 0x001f001f, /* dc0 */
1230 0x001132bf,
1231 0x01071013,
1232 0x3f0f01ff,
1233 0x0000001f,
cf0dbb21 1234 BP_OLED_I2C
9ee6e8bb
PB
1235 },
1236 { "LM3S6965EVB",
1237 0x10010002,
1238 0x1073402e,
1239 0x00ff007f, /* dc0 */
1240 0x001133ff,
1241 0x030f5317,
1242 0x0f0f87ff,
1243 0x5000007f,
cf0dbb21 1244 BP_OLED_SSI | BP_GAMEPAD
9ee6e8bb
PB
1245 }
1246};
1247
1248static void stellaris_init(const char *kernel_filename, const char *cpu_model,
3023f332 1249 stellaris_board_info *board)
9ee6e8bb
PB
1250{
1251 static const int uart_irq[] = {5, 6, 33, 34};
1252 static const int timer_irq[] = {19, 21, 23, 35};
1253 static const uint32_t gpio_addr[7] =
1254 { 0x40004000, 0x40005000, 0x40006000, 0x40007000,
1255 0x40024000, 0x40025000, 0x40026000};
1256 static const int gpio_irq[7] = {0, 1, 2, 3, 4, 30, 31};
1257
7d6f78cf 1258 MemoryRegion *address_space_mem = get_system_memory();
9ee6e8bb 1259 qemu_irq *pic;
40905a6a
PB
1260 DeviceState *gpio_dev[7];
1261 qemu_irq gpio_in[7][8];
1262 qemu_irq gpio_out[7][8];
9ee6e8bb
PB
1263 qemu_irq adc;
1264 int sram_size;
1265 int flash_size;
1266 i2c_bus *i2c;
40905a6a 1267 DeviceState *dev;
9ee6e8bb 1268 int i;
40905a6a 1269 int j;
9ee6e8bb
PB
1270
1271 flash_size = ((board->dc0 & 0xffff) + 1) << 1;
1272 sram_size = (board->dc0 >> 18) + 1;
7d6f78cf
AK
1273 pic = armv7m_init(address_space_mem,
1274 flash_size, sram_size, kernel_filename, cpu_model);
9ee6e8bb
PB
1275
1276 if (board->dc1 & (1 << 16)) {
40905a6a
PB
1277 dev = sysbus_create_varargs("stellaris-adc", 0x40038000,
1278 pic[14], pic[15], pic[16], pic[17], NULL);
1279 adc = qdev_get_gpio_in(dev, 0);
9ee6e8bb
PB
1280 } else {
1281 adc = NULL;
1282 }
1283 for (i = 0; i < 4; i++) {
1284 if (board->dc2 & (0x10000 << i)) {
40905a6a
PB
1285 dev = sysbus_create_simple("stellaris-gptm",
1286 0x40030000 + i * 0x1000,
1287 pic[timer_irq[i]]);
1288 /* TODO: This is incorrect, but we get away with it because
1289 the ADC output is only ever pulsed. */
1290 qdev_connect_gpio_out(dev, 0, adc);
9ee6e8bb
PB
1291 }
1292 }
1293
6eed1856 1294 stellaris_sys_init(0x400fe000, pic[28], board, nd_table[0].macaddr.a);
9ee6e8bb
PB
1295
1296 for (i = 0; i < 7; i++) {
1297 if (board->dc4 & (1 << i)) {
7063f49f 1298 gpio_dev[i] = sysbus_create_simple("pl061_luminary", gpio_addr[i],
40905a6a
PB
1299 pic[gpio_irq[i]]);
1300 for (j = 0; j < 8; j++) {
1301 gpio_in[i][j] = qdev_get_gpio_in(gpio_dev[i], j);
1302 gpio_out[i][j] = NULL;
1303 }
9ee6e8bb
PB
1304 }
1305 }
1306
1307 if (board->dc2 & (1 << 12)) {
1de9610c 1308 dev = sysbus_create_simple("stellaris-i2c", 0x40020000, pic[8]);
02e2da45 1309 i2c = (i2c_bus *)qdev_get_child_bus(dev, "i2c");
cf0dbb21 1310 if (board->peripherals & BP_OLED_I2C) {
d2199005 1311 i2c_create_slave(i2c, "ssd0303", 0x3d);
9ee6e8bb
PB
1312 }
1313 }
1314
1315 for (i = 0; i < 4; i++) {
1316 if (board->dc2 & (1 << i)) {
a7d518a6
PB
1317 sysbus_create_simple("pl011_luminary", 0x4000c000 + i * 0x1000,
1318 pic[uart_irq[i]]);
9ee6e8bb
PB
1319 }
1320 }
1321 if (board->dc2 & (1 << 4)) {
5493e33f 1322 dev = sysbus_create_simple("pl022", 0x40008000, pic[7]);
cf0dbb21 1323 if (board->peripherals & BP_OLED_SSI) {
5493e33f
PB
1324 DeviceState *mux;
1325 void *bus;
775616c3 1326
5493e33f
PB
1327 bus = qdev_get_child_bus(dev, "ssi");
1328 mux = ssi_create_slave(bus, "evb6965-ssi");
1329 gpio_out[GPIO_D][0] = qdev_get_gpio_in(mux, 0);
775616c3 1330
5493e33f 1331 bus = qdev_get_child_bus(mux, "ssi0");
22ed1d34 1332 ssi_create_slave(bus, "ssi-sd");
5493e33f
PB
1333
1334 bus = qdev_get_child_bus(mux, "ssi1");
1335 dev = ssi_create_slave(bus, "ssd0323");
1336 gpio_out[GPIO_C][7] = qdev_get_gpio_in(dev, 0);
775616c3 1337
775616c3
PB
1338 /* Make sure the select pin is high. */
1339 qemu_irq_raise(gpio_out[GPIO_D][0]);
9ee6e8bb
PB
1340 }
1341 }
a5580466
PB
1342 if (board->dc4 & (1 << 28)) {
1343 DeviceState *enet;
1344
1345 qemu_check_nic_model(&nd_table[0], "stellaris");
1346
1347 enet = qdev_create(NULL, "stellaris_enet");
540f006a 1348 qdev_set_nic_properties(enet, &nd_table[0]);
e23a1b33 1349 qdev_init_nofail(enet);
a5580466
PB
1350 sysbus_mmio_map(sysbus_from_qdev(enet), 0, 0x40048000);
1351 sysbus_connect_irq(sysbus_from_qdev(enet), 0, pic[42]);
1352 }
cf0dbb21
PB
1353 if (board->peripherals & BP_GAMEPAD) {
1354 qemu_irq gpad_irq[5];
1355 static const int gpad_keycode[5] = { 0xc8, 0xd0, 0xcb, 0xcd, 0x1d };
1356
1357 gpad_irq[0] = qemu_irq_invert(gpio_in[GPIO_E][0]); /* up */
1358 gpad_irq[1] = qemu_irq_invert(gpio_in[GPIO_E][1]); /* down */
1359 gpad_irq[2] = qemu_irq_invert(gpio_in[GPIO_E][2]); /* left */
1360 gpad_irq[3] = qemu_irq_invert(gpio_in[GPIO_E][3]); /* right */
1361 gpad_irq[4] = qemu_irq_invert(gpio_in[GPIO_F][1]); /* select */
1362
1363 stellaris_gamepad_init(5, gpad_irq, gpad_keycode);
1364 }
40905a6a
PB
1365 for (i = 0; i < 7; i++) {
1366 if (board->dc4 & (1 << i)) {
1367 for (j = 0; j < 8; j++) {
1368 if (gpio_out[i][j]) {
1369 qdev_connect_gpio_out(gpio_dev[i], j, gpio_out[i][j]);
1370 }
1371 }
1372 }
1373 }
9ee6e8bb
PB
1374}
1375
1376/* FIXME: Figure out how to generate these from stellaris_boards. */
c227f099 1377static void lm3s811evb_init(ram_addr_t ram_size,
3023f332 1378 const char *boot_device,
9ee6e8bb
PB
1379 const char *kernel_filename, const char *kernel_cmdline,
1380 const char *initrd_filename, const char *cpu_model)
1381{
3023f332 1382 stellaris_init(kernel_filename, cpu_model, &stellaris_boards[0]);
9ee6e8bb
PB
1383}
1384
c227f099 1385static void lm3s6965evb_init(ram_addr_t ram_size,
3023f332 1386 const char *boot_device,
9ee6e8bb
PB
1387 const char *kernel_filename, const char *kernel_cmdline,
1388 const char *initrd_filename, const char *cpu_model)
1389{
3023f332 1390 stellaris_init(kernel_filename, cpu_model, &stellaris_boards[1]);
9ee6e8bb
PB
1391}
1392
f80f9ec9 1393static QEMUMachine lm3s811evb_machine = {
4b32e168
AL
1394 .name = "lm3s811evb",
1395 .desc = "Stellaris LM3S811EVB",
1396 .init = lm3s811evb_init,
9ee6e8bb
PB
1397};
1398
f80f9ec9 1399static QEMUMachine lm3s6965evb_machine = {
4b32e168
AL
1400 .name = "lm3s6965evb",
1401 .desc = "Stellaris LM3S6965EVB",
1402 .init = lm3s6965evb_init,
9ee6e8bb 1403};
1de9610c 1404
f80f9ec9
AL
1405static void stellaris_machine_init(void)
1406{
1407 qemu_register_machine(&lm3s811evb_machine);
1408 qemu_register_machine(&lm3s6965evb_machine);
1409}
1410
1411machine_init(stellaris_machine_init);
1412
5493e33f 1413static SSISlaveInfo stellaris_ssi_bus_info = {
074f2fff
GH
1414 .qdev.name = "evb6965-ssi",
1415 .qdev.size = sizeof(stellaris_ssi_bus_state),
5493e33f
PB
1416 .init = stellaris_ssi_bus_init,
1417 .transfer = stellaris_ssi_bus_transfer
1418};
1419
1de9610c
PB
1420static void stellaris_register_devices(void)
1421{
1422 sysbus_register_dev("stellaris-i2c", sizeof(stellaris_i2c_state),
1423 stellaris_i2c_init);
40905a6a
PB
1424 sysbus_register_dev("stellaris-gptm", sizeof(gptm_state),
1425 stellaris_gptm_init);
1426 sysbus_register_dev("stellaris-adc", sizeof(stellaris_adc_state),
1427 stellaris_adc_init);
074f2fff 1428 ssi_register_slave(&stellaris_ssi_bus_info);
1de9610c
PB
1429}
1430
1431device_init(stellaris_register_devices)