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