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