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