]> git.proxmox.com Git - mirror_qemu.git/blame - hw/stellaris.c
savevm: Add DeviceState param
[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
PB
17#include "sysemu.h"
18#include "boards.h"
9ee6e8bb 19
cf0dbb21
PB
20#define GPIO_A 0
21#define GPIO_B 1
22#define GPIO_C 2
23#define GPIO_D 3
24#define GPIO_E 4
25#define GPIO_F 5
26#define GPIO_G 6
27
28#define BP_OLED_I2C 0x01
29#define BP_OLED_SSI 0x02
30#define BP_GAMEPAD 0x04
31
9ee6e8bb
PB
32typedef const struct {
33 const char *name;
34 uint32_t did0;
35 uint32_t did1;
36 uint32_t dc0;
37 uint32_t dc1;
38 uint32_t dc2;
39 uint32_t dc3;
40 uint32_t dc4;
cf0dbb21 41 uint32_t peripherals;
9ee6e8bb
PB
42} stellaris_board_info;
43
44/* General purpose timer module. */
45
9ee6e8bb 46typedef struct gptm_state {
40905a6a 47 SysBusDevice busdev;
9ee6e8bb
PB
48 uint32_t config;
49 uint32_t mode[2];
50 uint32_t control;
51 uint32_t state;
52 uint32_t mask;
53 uint32_t load[2];
54 uint32_t match[2];
55 uint32_t prescale[2];
56 uint32_t match_prescale[2];
57 uint32_t rtc;
58 int64_t tick[2];
59 struct gptm_state *opaque[2];
9ee6e8bb
PB
60 QEMUTimer *timer[2];
61 /* The timers have an alternate output used to trigger the ADC. */
62 qemu_irq trigger;
63 qemu_irq irq;
64} gptm_state;
65
66static void gptm_update_irq(gptm_state *s)
67{
68 int level;
69 level = (s->state & s->mask) != 0;
70 qemu_set_irq(s->irq, level);
71}
72
73static void gptm_stop(gptm_state *s, int n)
74{
75 qemu_del_timer(s->timer[n]);
76}
77
78static void gptm_reload(gptm_state *s, int n, int reset)
79{
80 int64_t tick;
81 if (reset)
82 tick = qemu_get_clock(vm_clock);
83 else
84 tick = s->tick[n];
85
86 if (s->config == 0) {
87 /* 32-bit CountDown. */
88 uint32_t count;
89 count = s->load[0] | (s->load[1] << 16);
e57ec016 90 tick += (int64_t)count * system_clock_scale;
9ee6e8bb
PB
91 } else if (s->config == 1) {
92 /* 32-bit RTC. 1Hz tick. */
6ee093c9 93 tick += get_ticks_per_sec();
9ee6e8bb
PB
94 } else if (s->mode[n] == 0xa) {
95 /* PWM mode. Not implemented. */
96 } else {
2ac71179 97 hw_error("TODO: 16-bit timer mode 0x%x\n", s->mode[n]);
9ee6e8bb
PB
98 }
99 s->tick[n] = tick;
100 qemu_mod_timer(s->timer[n], tick);
101}
102
103static void gptm_tick(void *opaque)
104{
105 gptm_state **p = (gptm_state **)opaque;
106 gptm_state *s;
107 int n;
108
109 s = *p;
110 n = p - s->opaque;
111 if (s->config == 0) {
112 s->state |= 1;
113 if ((s->control & 0x20)) {
114 /* Output trigger. */
40905a6a 115 qemu_irq_pulse(s->trigger);
9ee6e8bb
PB
116 }
117 if (s->mode[0] & 1) {
118 /* One-shot. */
119 s->control &= ~1;
120 } else {
121 /* Periodic. */
122 gptm_reload(s, 0, 0);
123 }
124 } else if (s->config == 1) {
125 /* RTC. */
126 uint32_t match;
127 s->rtc++;
128 match = s->match[0] | (s->match[1] << 16);
129 if (s->rtc > match)
130 s->rtc = 0;
131 if (s->rtc == 0) {
132 s->state |= 8;
133 }
134 gptm_reload(s, 0, 0);
135 } else if (s->mode[n] == 0xa) {
136 /* PWM mode. Not implemented. */
137 } else {
2ac71179 138 hw_error("TODO: 16-bit timer mode 0x%x\n", s->mode[n]);
9ee6e8bb
PB
139 }
140 gptm_update_irq(s);
141}
142
c227f099 143static uint32_t gptm_read(void *opaque, target_phys_addr_t offset)
9ee6e8bb
PB
144{
145 gptm_state *s = (gptm_state *)opaque;
146
9ee6e8bb
PB
147 switch (offset) {
148 case 0x00: /* CFG */
149 return s->config;
150 case 0x04: /* TAMR */
151 return s->mode[0];
152 case 0x08: /* TBMR */
153 return s->mode[1];
154 case 0x0c: /* CTL */
155 return s->control;
156 case 0x18: /* IMR */
157 return s->mask;
158 case 0x1c: /* RIS */
159 return s->state;
160 case 0x20: /* MIS */
161 return s->state & s->mask;
162 case 0x24: /* CR */
163 return 0;
164 case 0x28: /* TAILR */
165 return s->load[0] | ((s->config < 4) ? (s->load[1] << 16) : 0);
166 case 0x2c: /* TBILR */
167 return s->load[1];
168 case 0x30: /* TAMARCHR */
169 return s->match[0] | ((s->config < 4) ? (s->match[1] << 16) : 0);
170 case 0x34: /* TBMATCHR */
171 return s->match[1];
172 case 0x38: /* TAPR */
173 return s->prescale[0];
174 case 0x3c: /* TBPR */
175 return s->prescale[1];
176 case 0x40: /* TAPMR */
177 return s->match_prescale[0];
178 case 0x44: /* TBPMR */
179 return s->match_prescale[1];
180 case 0x48: /* TAR */
181 if (s->control == 1)
182 return s->rtc;
183 case 0x4c: /* TBR */
2ac71179 184 hw_error("TODO: Timer value read\n");
9ee6e8bb 185 default:
2ac71179 186 hw_error("gptm_read: Bad offset 0x%x\n", (int)offset);
9ee6e8bb
PB
187 return 0;
188 }
189}
190
c227f099 191static void gptm_write(void *opaque, target_phys_addr_t offset, uint32_t value)
9ee6e8bb
PB
192{
193 gptm_state *s = (gptm_state *)opaque;
194 uint32_t oldval;
195
9ee6e8bb
PB
196 /* The timers should be disabled before changing the configuration.
197 We take advantage of this and defer everything until the timer
198 is enabled. */
199 switch (offset) {
200 case 0x00: /* CFG */
201 s->config = value;
202 break;
203 case 0x04: /* TAMR */
204 s->mode[0] = value;
205 break;
206 case 0x08: /* TBMR */
207 s->mode[1] = value;
208 break;
209 case 0x0c: /* CTL */
210 oldval = s->control;
211 s->control = value;
212 /* TODO: Implement pause. */
213 if ((oldval ^ value) & 1) {
214 if (value & 1) {
215 gptm_reload(s, 0, 1);
216 } else {
217 gptm_stop(s, 0);
218 }
219 }
220 if (((oldval ^ value) & 0x100) && s->config >= 4) {
221 if (value & 0x100) {
222 gptm_reload(s, 1, 1);
223 } else {
224 gptm_stop(s, 1);
225 }
226 }
227 break;
228 case 0x18: /* IMR */
229 s->mask = value & 0x77;
230 gptm_update_irq(s);
231 break;
232 case 0x24: /* CR */
233 s->state &= ~value;
234 break;
235 case 0x28: /* TAILR */
236 s->load[0] = value & 0xffff;
237 if (s->config < 4) {
238 s->load[1] = value >> 16;
239 }
240 break;
241 case 0x2c: /* TBILR */
242 s->load[1] = value & 0xffff;
243 break;
244 case 0x30: /* TAMARCHR */
245 s->match[0] = value & 0xffff;
246 if (s->config < 4) {
247 s->match[1] = value >> 16;
248 }
249 break;
250 case 0x34: /* TBMATCHR */
251 s->match[1] = value >> 16;
252 break;
253 case 0x38: /* TAPR */
254 s->prescale[0] = value;
255 break;
256 case 0x3c: /* TBPR */
257 s->prescale[1] = value;
258 break;
259 case 0x40: /* TAPMR */
260 s->match_prescale[0] = value;
261 break;
262 case 0x44: /* TBPMR */
263 s->match_prescale[0] = value;
264 break;
265 default:
2ac71179 266 hw_error("gptm_write: Bad offset 0x%x\n", (int)offset);
9ee6e8bb
PB
267 }
268 gptm_update_irq(s);
269}
270
d60efc6b 271static CPUReadMemoryFunc * const gptm_readfn[] = {
9ee6e8bb
PB
272 gptm_read,
273 gptm_read,
274 gptm_read
275};
276
d60efc6b 277static CPUWriteMemoryFunc * const gptm_writefn[] = {
9ee6e8bb
PB
278 gptm_write,
279 gptm_write,
280 gptm_write
281};
282
23e39294
PB
283static void gptm_save(QEMUFile *f, void *opaque)
284{
285 gptm_state *s = (gptm_state *)opaque;
286
287 qemu_put_be32(f, s->config);
288 qemu_put_be32(f, s->mode[0]);
289 qemu_put_be32(f, s->mode[1]);
290 qemu_put_be32(f, s->control);
291 qemu_put_be32(f, s->state);
292 qemu_put_be32(f, s->mask);
293 qemu_put_be32(f, s->mode[0]);
294 qemu_put_be32(f, s->mode[0]);
295 qemu_put_be32(f, s->load[0]);
296 qemu_put_be32(f, s->load[1]);
297 qemu_put_be32(f, s->match[0]);
298 qemu_put_be32(f, s->match[1]);
299 qemu_put_be32(f, s->prescale[0]);
300 qemu_put_be32(f, s->prescale[1]);
301 qemu_put_be32(f, s->match_prescale[0]);
302 qemu_put_be32(f, s->match_prescale[1]);
303 qemu_put_be32(f, s->rtc);
304 qemu_put_be64(f, s->tick[0]);
305 qemu_put_be64(f, s->tick[1]);
306 qemu_put_timer(f, s->timer[0]);
307 qemu_put_timer(f, s->timer[1]);
308}
309
310static int gptm_load(QEMUFile *f, void *opaque, int version_id)
311{
312 gptm_state *s = (gptm_state *)opaque;
313
314 if (version_id != 1)
315 return -EINVAL;
316
317 s->config = qemu_get_be32(f);
318 s->mode[0] = qemu_get_be32(f);
319 s->mode[1] = qemu_get_be32(f);
320 s->control = qemu_get_be32(f);
321 s->state = qemu_get_be32(f);
322 s->mask = qemu_get_be32(f);
323 s->mode[0] = qemu_get_be32(f);
324 s->mode[0] = qemu_get_be32(f);
325 s->load[0] = qemu_get_be32(f);
326 s->load[1] = qemu_get_be32(f);
327 s->match[0] = qemu_get_be32(f);
328 s->match[1] = qemu_get_be32(f);
329 s->prescale[0] = qemu_get_be32(f);
330 s->prescale[1] = qemu_get_be32(f);
331 s->match_prescale[0] = qemu_get_be32(f);
332 s->match_prescale[1] = qemu_get_be32(f);
333 s->rtc = qemu_get_be32(f);
334 s->tick[0] = qemu_get_be64(f);
335 s->tick[1] = qemu_get_be64(f);
336 qemu_get_timer(f, s->timer[0]);
337 qemu_get_timer(f, s->timer[1]);
338
339 return 0;
340}
341
81a322d4 342static int stellaris_gptm_init(SysBusDevice *dev)
9ee6e8bb
PB
343{
344 int iomemtype;
40905a6a 345 gptm_state *s = FROM_SYSBUS(gptm_state, dev);
9ee6e8bb 346
40905a6a
PB
347 sysbus_init_irq(dev, &s->irq);
348 qdev_init_gpio_out(&dev->qdev, &s->trigger, 1);
9ee6e8bb 349
1eed09cb 350 iomemtype = cpu_register_io_memory(gptm_readfn,
9ee6e8bb 351 gptm_writefn, s);
40905a6a
PB
352 sysbus_init_mmio(dev, 0x1000, iomemtype);
353
354 s->opaque[0] = s->opaque[1] = s;
9ee6e8bb
PB
355 s->timer[0] = qemu_new_timer(vm_clock, gptm_tick, &s->opaque[0]);
356 s->timer[1] = qemu_new_timer(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,
9ee6e8bb
PB
674 ssys_writefn, s);
675 cpu_register_physical_memory(base, 0x00001000, iomemtype);
676 ssys_reset(s);
0be71e32 677 register_savevm(NULL, "stellaris_sys", -1, 1, ssys_save, ssys_load, s);
81a322d4 678 return 0;
9ee6e8bb
PB
679}
680
681
682/* I2C controller. */
683
684typedef struct {
1de9610c 685 SysBusDevice busdev;
9ee6e8bb
PB
686 i2c_bus *bus;
687 qemu_irq irq;
9ee6e8bb
PB
688 uint32_t msa;
689 uint32_t mcs;
690 uint32_t mdr;
691 uint32_t mtpr;
692 uint32_t mimr;
693 uint32_t mris;
694 uint32_t mcr;
695} stellaris_i2c_state;
696
697#define STELLARIS_I2C_MCS_BUSY 0x01
698#define STELLARIS_I2C_MCS_ERROR 0x02
699#define STELLARIS_I2C_MCS_ADRACK 0x04
700#define STELLARIS_I2C_MCS_DATACK 0x08
701#define STELLARIS_I2C_MCS_ARBLST 0x10
702#define STELLARIS_I2C_MCS_IDLE 0x20
703#define STELLARIS_I2C_MCS_BUSBSY 0x40
704
c227f099 705static uint32_t stellaris_i2c_read(void *opaque, target_phys_addr_t offset)
9ee6e8bb
PB
706{
707 stellaris_i2c_state *s = (stellaris_i2c_state *)opaque;
708
9ee6e8bb
PB
709 switch (offset) {
710 case 0x00: /* MSA */
711 return s->msa;
712 case 0x04: /* MCS */
713 /* We don't emulate timing, so the controller is never busy. */
714 return s->mcs | STELLARIS_I2C_MCS_IDLE;
715 case 0x08: /* MDR */
716 return s->mdr;
717 case 0x0c: /* MTPR */
718 return s->mtpr;
719 case 0x10: /* MIMR */
720 return s->mimr;
721 case 0x14: /* MRIS */
722 return s->mris;
723 case 0x18: /* MMIS */
724 return s->mris & s->mimr;
725 case 0x20: /* MCR */
726 return s->mcr;
727 default:
2ac71179 728 hw_error("strllaris_i2c_read: Bad offset 0x%x\n", (int)offset);
9ee6e8bb
PB
729 return 0;
730 }
731}
732
733static void stellaris_i2c_update(stellaris_i2c_state *s)
734{
735 int level;
736
737 level = (s->mris & s->mimr) != 0;
738 qemu_set_irq(s->irq, level);
739}
740
c227f099 741static void stellaris_i2c_write(void *opaque, target_phys_addr_t offset,
9ee6e8bb
PB
742 uint32_t value)
743{
744 stellaris_i2c_state *s = (stellaris_i2c_state *)opaque;
745
9ee6e8bb
PB
746 switch (offset) {
747 case 0x00: /* MSA */
748 s->msa = value & 0xff;
749 break;
750 case 0x04: /* MCS */
751 if ((s->mcr & 0x10) == 0) {
752 /* Disabled. Do nothing. */
753 break;
754 }
755 /* Grab the bus if this is starting a transfer. */
756 if ((value & 2) && (s->mcs & STELLARIS_I2C_MCS_BUSBSY) == 0) {
757 if (i2c_start_transfer(s->bus, s->msa >> 1, s->msa & 1)) {
758 s->mcs |= STELLARIS_I2C_MCS_ARBLST;
759 } else {
760 s->mcs &= ~STELLARIS_I2C_MCS_ARBLST;
761 s->mcs |= STELLARIS_I2C_MCS_BUSBSY;
762 }
763 }
764 /* If we don't have the bus then indicate an error. */
765 if (!i2c_bus_busy(s->bus)
766 || (s->mcs & STELLARIS_I2C_MCS_BUSBSY) == 0) {
767 s->mcs |= STELLARIS_I2C_MCS_ERROR;
768 break;
769 }
770 s->mcs &= ~STELLARIS_I2C_MCS_ERROR;
771 if (value & 1) {
772 /* Transfer a byte. */
773 /* TODO: Handle errors. */
774 if (s->msa & 1) {
775 /* Recv */
776 s->mdr = i2c_recv(s->bus) & 0xff;
777 } else {
778 /* Send */
779 i2c_send(s->bus, s->mdr);
780 }
781 /* Raise an interrupt. */
782 s->mris |= 1;
783 }
784 if (value & 4) {
785 /* Finish transfer. */
786 i2c_end_transfer(s->bus);
787 s->mcs &= ~STELLARIS_I2C_MCS_BUSBSY;
788 }
789 break;
790 case 0x08: /* MDR */
791 s->mdr = value & 0xff;
792 break;
793 case 0x0c: /* MTPR */
794 s->mtpr = value & 0xff;
795 break;
796 case 0x10: /* MIMR */
797 s->mimr = 1;
798 break;
799 case 0x1c: /* MICR */
800 s->mris &= ~value;
801 break;
802 case 0x20: /* MCR */
803 if (value & 1)
2ac71179 804 hw_error(
9ee6e8bb
PB
805 "stellaris_i2c_write: Loopback not implemented\n");
806 if (value & 0x20)
2ac71179 807 hw_error(
9ee6e8bb
PB
808 "stellaris_i2c_write: Slave mode not implemented\n");
809 s->mcr = value & 0x31;
810 break;
811 default:
2ac71179 812 hw_error("stellaris_i2c_write: Bad offset 0x%x\n",
9ee6e8bb
PB
813 (int)offset);
814 }
815 stellaris_i2c_update(s);
816}
817
818static void stellaris_i2c_reset(stellaris_i2c_state *s)
819{
820 if (s->mcs & STELLARIS_I2C_MCS_BUSBSY)
821 i2c_end_transfer(s->bus);
822
823 s->msa = 0;
824 s->mcs = 0;
825 s->mdr = 0;
826 s->mtpr = 1;
827 s->mimr = 0;
828 s->mris = 0;
829 s->mcr = 0;
830 stellaris_i2c_update(s);
831}
832
d60efc6b 833static CPUReadMemoryFunc * const stellaris_i2c_readfn[] = {
9ee6e8bb
PB
834 stellaris_i2c_read,
835 stellaris_i2c_read,
836 stellaris_i2c_read
837};
838
d60efc6b 839static CPUWriteMemoryFunc * const stellaris_i2c_writefn[] = {
9ee6e8bb
PB
840 stellaris_i2c_write,
841 stellaris_i2c_write,
842 stellaris_i2c_write
843};
844
23e39294
PB
845static void stellaris_i2c_save(QEMUFile *f, void *opaque)
846{
847 stellaris_i2c_state *s = (stellaris_i2c_state *)opaque;
848
849 qemu_put_be32(f, s->msa);
850 qemu_put_be32(f, s->mcs);
851 qemu_put_be32(f, s->mdr);
852 qemu_put_be32(f, s->mtpr);
853 qemu_put_be32(f, s->mimr);
854 qemu_put_be32(f, s->mris);
855 qemu_put_be32(f, s->mcr);
856}
857
858static int stellaris_i2c_load(QEMUFile *f, void *opaque, int version_id)
859{
860 stellaris_i2c_state *s = (stellaris_i2c_state *)opaque;
861
862 if (version_id != 1)
863 return -EINVAL;
864
865 s->msa = qemu_get_be32(f);
866 s->mcs = qemu_get_be32(f);
867 s->mdr = qemu_get_be32(f);
868 s->mtpr = qemu_get_be32(f);
869 s->mimr = qemu_get_be32(f);
870 s->mris = qemu_get_be32(f);
871 s->mcr = qemu_get_be32(f);
872
873 return 0;
874}
875
81a322d4 876static int stellaris_i2c_init(SysBusDevice * dev)
9ee6e8bb 877{
1de9610c 878 stellaris_i2c_state *s = FROM_SYSBUS(stellaris_i2c_state, dev);
02e2da45 879 i2c_bus *bus;
9ee6e8bb
PB
880 int iomemtype;
881
1de9610c 882 sysbus_init_irq(dev, &s->irq);
02e2da45 883 bus = i2c_init_bus(&dev->qdev, "i2c");
9ee6e8bb
PB
884 s->bus = bus;
885
1eed09cb 886 iomemtype = cpu_register_io_memory(stellaris_i2c_readfn,
9ee6e8bb 887 stellaris_i2c_writefn, s);
1de9610c 888 sysbus_init_mmio(dev, 0x1000, iomemtype);
9ee6e8bb
PB
889 /* ??? For now we only implement the master interface. */
890 stellaris_i2c_reset(s);
0be71e32 891 register_savevm(&dev->qdev, "stellaris_i2c", -1, 1,
23e39294 892 stellaris_i2c_save, stellaris_i2c_load, s);
81a322d4 893 return 0;
9ee6e8bb
PB
894}
895
896/* Analogue to Digital Converter. This is only partially implemented,
897 enough for applications that use a combined ADC and timer tick. */
898
899#define STELLARIS_ADC_EM_CONTROLLER 0
900#define STELLARIS_ADC_EM_COMP 1
901#define STELLARIS_ADC_EM_EXTERNAL 4
902#define STELLARIS_ADC_EM_TIMER 5
903#define STELLARIS_ADC_EM_PWM0 6
904#define STELLARIS_ADC_EM_PWM1 7
905#define STELLARIS_ADC_EM_PWM2 8
906
907#define STELLARIS_ADC_FIFO_EMPTY 0x0100
908#define STELLARIS_ADC_FIFO_FULL 0x1000
909
910typedef struct
911{
40905a6a 912 SysBusDevice busdev;
9ee6e8bb
PB
913 uint32_t actss;
914 uint32_t ris;
915 uint32_t im;
916 uint32_t emux;
917 uint32_t ostat;
918 uint32_t ustat;
919 uint32_t sspri;
920 uint32_t sac;
921 struct {
922 uint32_t state;
923 uint32_t data[16];
924 } fifo[4];
925 uint32_t ssmux[4];
926 uint32_t ssctl[4];
23e39294 927 uint32_t noise;
2c6554bc 928 qemu_irq irq[4];
9ee6e8bb
PB
929} stellaris_adc_state;
930
931static uint32_t stellaris_adc_fifo_read(stellaris_adc_state *s, int n)
932{
933 int tail;
934
935 tail = s->fifo[n].state & 0xf;
936 if (s->fifo[n].state & STELLARIS_ADC_FIFO_EMPTY) {
937 s->ustat |= 1 << n;
938 } else {
939 s->fifo[n].state = (s->fifo[n].state & ~0xf) | ((tail + 1) & 0xf);
940 s->fifo[n].state &= ~STELLARIS_ADC_FIFO_FULL;
941 if (tail + 1 == ((s->fifo[n].state >> 4) & 0xf))
942 s->fifo[n].state |= STELLARIS_ADC_FIFO_EMPTY;
943 }
944 return s->fifo[n].data[tail];
945}
946
947static void stellaris_adc_fifo_write(stellaris_adc_state *s, int n,
948 uint32_t value)
949{
950 int head;
951
2c6554bc
PB
952 /* TODO: Real hardware has limited size FIFOs. We have a full 16 entry
953 FIFO fir each sequencer. */
9ee6e8bb
PB
954 head = (s->fifo[n].state >> 4) & 0xf;
955 if (s->fifo[n].state & STELLARIS_ADC_FIFO_FULL) {
956 s->ostat |= 1 << n;
957 return;
958 }
959 s->fifo[n].data[head] = value;
960 head = (head + 1) & 0xf;
961 s->fifo[n].state &= ~STELLARIS_ADC_FIFO_EMPTY;
962 s->fifo[n].state = (s->fifo[n].state & ~0xf0) | (head << 4);
963 if ((s->fifo[n].state & 0xf) == head)
964 s->fifo[n].state |= STELLARIS_ADC_FIFO_FULL;
965}
966
967static void stellaris_adc_update(stellaris_adc_state *s)
968{
969 int level;
2c6554bc 970 int n;
9ee6e8bb 971
2c6554bc
PB
972 for (n = 0; n < 4; n++) {
973 level = (s->ris & s->im & (1 << n)) != 0;
974 qemu_set_irq(s->irq[n], level);
975 }
9ee6e8bb
PB
976}
977
978static void stellaris_adc_trigger(void *opaque, int irq, int level)
979{
980 stellaris_adc_state *s = (stellaris_adc_state *)opaque;
2c6554bc 981 int n;
9ee6e8bb 982
2c6554bc
PB
983 for (n = 0; n < 4; n++) {
984 if ((s->actss & (1 << n)) == 0) {
985 continue;
986 }
9ee6e8bb 987
2c6554bc
PB
988 if (((s->emux >> (n * 4)) & 0xff) != 5) {
989 continue;
990 }
991
992 /* Some applications use the ADC as a random number source, so introduce
993 some variation into the signal. */
994 s->noise = s->noise * 314159 + 1;
995 /* ??? actual inputs not implemented. Return an arbitrary value. */
996 stellaris_adc_fifo_write(s, n, 0x200 + ((s->noise >> 16) & 7));
997 s->ris |= (1 << n);
998 stellaris_adc_update(s);
999 }
9ee6e8bb
PB
1000}
1001
1002static void stellaris_adc_reset(stellaris_adc_state *s)
1003{
1004 int n;
1005
1006 for (n = 0; n < 4; n++) {
1007 s->ssmux[n] = 0;
1008 s->ssctl[n] = 0;
1009 s->fifo[n].state = STELLARIS_ADC_FIFO_EMPTY;
1010 }
1011}
1012
c227f099 1013static uint32_t stellaris_adc_read(void *opaque, target_phys_addr_t offset)
9ee6e8bb
PB
1014{
1015 stellaris_adc_state *s = (stellaris_adc_state *)opaque;
1016
1017 /* TODO: Implement this. */
9ee6e8bb
PB
1018 if (offset >= 0x40 && offset < 0xc0) {
1019 int n;
1020 n = (offset - 0x40) >> 5;
1021 switch (offset & 0x1f) {
1022 case 0x00: /* SSMUX */
1023 return s->ssmux[n];
1024 case 0x04: /* SSCTL */
1025 return s->ssctl[n];
1026 case 0x08: /* SSFIFO */
1027 return stellaris_adc_fifo_read(s, n);
1028 case 0x0c: /* SSFSTAT */
1029 return s->fifo[n].state;
1030 default:
1031 break;
1032 }
1033 }
1034 switch (offset) {
1035 case 0x00: /* ACTSS */
1036 return s->actss;
1037 case 0x04: /* RIS */
1038 return s->ris;
1039 case 0x08: /* IM */
1040 return s->im;
1041 case 0x0c: /* ISC */
1042 return s->ris & s->im;
1043 case 0x10: /* OSTAT */
1044 return s->ostat;
1045 case 0x14: /* EMUX */
1046 return s->emux;
1047 case 0x18: /* USTAT */
1048 return s->ustat;
1049 case 0x20: /* SSPRI */
1050 return s->sspri;
1051 case 0x30: /* SAC */
1052 return s->sac;
1053 default:
2ac71179 1054 hw_error("strllaris_adc_read: Bad offset 0x%x\n",
9ee6e8bb
PB
1055 (int)offset);
1056 return 0;
1057 }
1058}
1059
c227f099 1060static void stellaris_adc_write(void *opaque, target_phys_addr_t offset,
9ee6e8bb
PB
1061 uint32_t value)
1062{
1063 stellaris_adc_state *s = (stellaris_adc_state *)opaque;
1064
1065 /* TODO: Implement this. */
9ee6e8bb
PB
1066 if (offset >= 0x40 && offset < 0xc0) {
1067 int n;
1068 n = (offset - 0x40) >> 5;
1069 switch (offset & 0x1f) {
1070 case 0x00: /* SSMUX */
1071 s->ssmux[n] = value & 0x33333333;
1072 return;
1073 case 0x04: /* SSCTL */
1074 if (value != 6) {
2ac71179 1075 hw_error("ADC: Unimplemented sequence %x\n",
9ee6e8bb
PB
1076 value);
1077 }
1078 s->ssctl[n] = value;
1079 return;
1080 default:
1081 break;
1082 }
1083 }
1084 switch (offset) {
1085 case 0x00: /* ACTSS */
1086 s->actss = value & 0xf;
9ee6e8bb
PB
1087 break;
1088 case 0x08: /* IM */
1089 s->im = value;
1090 break;
1091 case 0x0c: /* ISC */
1092 s->ris &= ~value;
1093 break;
1094 case 0x10: /* OSTAT */
1095 s->ostat &= ~value;
1096 break;
1097 case 0x14: /* EMUX */
1098 s->emux = value;
1099 break;
1100 case 0x18: /* USTAT */
1101 s->ustat &= ~value;
1102 break;
1103 case 0x20: /* SSPRI */
1104 s->sspri = value;
1105 break;
1106 case 0x28: /* PSSI */
2ac71179 1107 hw_error("Not implemented: ADC sample initiate\n");
9ee6e8bb
PB
1108 break;
1109 case 0x30: /* SAC */
1110 s->sac = value;
1111 break;
1112 default:
2ac71179 1113 hw_error("stellaris_adc_write: Bad offset 0x%x\n", (int)offset);
9ee6e8bb
PB
1114 }
1115 stellaris_adc_update(s);
1116}
1117
d60efc6b 1118static CPUReadMemoryFunc * const stellaris_adc_readfn[] = {
9ee6e8bb
PB
1119 stellaris_adc_read,
1120 stellaris_adc_read,
1121 stellaris_adc_read
1122};
1123
d60efc6b 1124static CPUWriteMemoryFunc * const stellaris_adc_writefn[] = {
9ee6e8bb
PB
1125 stellaris_adc_write,
1126 stellaris_adc_write,
1127 stellaris_adc_write
1128};
1129
23e39294
PB
1130static void stellaris_adc_save(QEMUFile *f, void *opaque)
1131{
1132 stellaris_adc_state *s = (stellaris_adc_state *)opaque;
1133 int i;
1134 int j;
1135
1136 qemu_put_be32(f, s->actss);
1137 qemu_put_be32(f, s->ris);
1138 qemu_put_be32(f, s->im);
1139 qemu_put_be32(f, s->emux);
1140 qemu_put_be32(f, s->ostat);
1141 qemu_put_be32(f, s->ustat);
1142 qemu_put_be32(f, s->sspri);
1143 qemu_put_be32(f, s->sac);
1144 for (i = 0; i < 4; i++) {
1145 qemu_put_be32(f, s->fifo[i].state);
1146 for (j = 0; j < 16; j++) {
1147 qemu_put_be32(f, s->fifo[i].data[j]);
1148 }
1149 qemu_put_be32(f, s->ssmux[i]);
1150 qemu_put_be32(f, s->ssctl[i]);
1151 }
1152 qemu_put_be32(f, s->noise);
1153}
1154
1155static int stellaris_adc_load(QEMUFile *f, void *opaque, int version_id)
1156{
1157 stellaris_adc_state *s = (stellaris_adc_state *)opaque;
1158 int i;
1159 int j;
1160
1161 if (version_id != 1)
1162 return -EINVAL;
1163
1164 s->actss = qemu_get_be32(f);
1165 s->ris = qemu_get_be32(f);
1166 s->im = qemu_get_be32(f);
1167 s->emux = qemu_get_be32(f);
1168 s->ostat = qemu_get_be32(f);
1169 s->ustat = qemu_get_be32(f);
1170 s->sspri = qemu_get_be32(f);
1171 s->sac = qemu_get_be32(f);
1172 for (i = 0; i < 4; i++) {
1173 s->fifo[i].state = qemu_get_be32(f);
1174 for (j = 0; j < 16; j++) {
1175 s->fifo[i].data[j] = qemu_get_be32(f);
1176 }
1177 s->ssmux[i] = qemu_get_be32(f);
1178 s->ssctl[i] = qemu_get_be32(f);
1179 }
1180 s->noise = qemu_get_be32(f);
1181
1182 return 0;
1183}
1184
81a322d4 1185static int stellaris_adc_init(SysBusDevice *dev)
9ee6e8bb 1186{
40905a6a 1187 stellaris_adc_state *s = FROM_SYSBUS(stellaris_adc_state, dev);
9ee6e8bb 1188 int iomemtype;
2c6554bc 1189 int n;
9ee6e8bb 1190
2c6554bc 1191 for (n = 0; n < 4; n++) {
40905a6a 1192 sysbus_init_irq(dev, &s->irq[n]);
2c6554bc 1193 }
9ee6e8bb 1194
1eed09cb 1195 iomemtype = cpu_register_io_memory(stellaris_adc_readfn,
9ee6e8bb 1196 stellaris_adc_writefn, s);
40905a6a 1197 sysbus_init_mmio(dev, 0x1000, iomemtype);
9ee6e8bb 1198 stellaris_adc_reset(s);
40905a6a 1199 qdev_init_gpio_in(&dev->qdev, stellaris_adc_trigger, 1);
0be71e32 1200 register_savevm(&dev->qdev, "stellaris_adc", -1, 1,
23e39294 1201 stellaris_adc_save, stellaris_adc_load, s);
81a322d4 1202 return 0;
9ee6e8bb
PB
1203}
1204
775616c3
PB
1205/* Some boards have both an OLED controller and SD card connected to
1206 the same SSI port, with the SD card chip select connected to a
1207 GPIO pin. Technically the OLED chip select is connected to the SSI
1208 Fss pin. We do not bother emulating that as both devices should
1209 never be selected simultaneously, and our OLED controller ignores stray
1210 0xff commands that occur when deselecting the SD card. */
1211
1212typedef struct {
5493e33f 1213 SSISlave ssidev;
775616c3
PB
1214 qemu_irq irq;
1215 int current_dev;
5493e33f 1216 SSIBus *bus[2];
775616c3
PB
1217} stellaris_ssi_bus_state;
1218
1219static void stellaris_ssi_bus_select(void *opaque, int irq, int level)
1220{
1221 stellaris_ssi_bus_state *s = (stellaris_ssi_bus_state *)opaque;
1222
1223 s->current_dev = level;
1224}
1225
5493e33f 1226static uint32_t stellaris_ssi_bus_transfer(SSISlave *dev, uint32_t val)
775616c3 1227{
5493e33f 1228 stellaris_ssi_bus_state *s = FROM_SSI_SLAVE(stellaris_ssi_bus_state, dev);
775616c3 1229
5493e33f 1230 return ssi_transfer(s->bus[s->current_dev], val);
775616c3
PB
1231}
1232
23e39294
PB
1233static void stellaris_ssi_bus_save(QEMUFile *f, void *opaque)
1234{
1235 stellaris_ssi_bus_state *s = (stellaris_ssi_bus_state *)opaque;
1236
1237 qemu_put_be32(f, s->current_dev);
1238}
1239
1240static int stellaris_ssi_bus_load(QEMUFile *f, void *opaque, int version_id)
1241{
1242 stellaris_ssi_bus_state *s = (stellaris_ssi_bus_state *)opaque;
1243
1244 if (version_id != 1)
1245 return -EINVAL;
1246
1247 s->current_dev = qemu_get_be32(f);
1248
1249 return 0;
1250}
1251
81a322d4 1252static int stellaris_ssi_bus_init(SSISlave *dev)
775616c3 1253{
5493e33f
PB
1254 stellaris_ssi_bus_state *s = FROM_SSI_SLAVE(stellaris_ssi_bus_state, dev);
1255
02e2da45
PB
1256 s->bus[0] = ssi_create_bus(&dev->qdev, "ssi0");
1257 s->bus[1] = ssi_create_bus(&dev->qdev, "ssi1");
5493e33f
PB
1258 qdev_init_gpio_in(&dev->qdev, stellaris_ssi_bus_select, 1);
1259
0be71e32 1260 register_savevm(&dev->qdev, "stellaris_ssi_bus", -1, 1,
23e39294 1261 stellaris_ssi_bus_save, stellaris_ssi_bus_load, s);
81a322d4 1262 return 0;
775616c3
PB
1263}
1264
9ee6e8bb
PB
1265/* Board init. */
1266static stellaris_board_info stellaris_boards[] = {
1267 { "LM3S811EVB",
1268 0,
1269 0x0032000e,
1270 0x001f001f, /* dc0 */
1271 0x001132bf,
1272 0x01071013,
1273 0x3f0f01ff,
1274 0x0000001f,
cf0dbb21 1275 BP_OLED_I2C
9ee6e8bb
PB
1276 },
1277 { "LM3S6965EVB",
1278 0x10010002,
1279 0x1073402e,
1280 0x00ff007f, /* dc0 */
1281 0x001133ff,
1282 0x030f5317,
1283 0x0f0f87ff,
1284 0x5000007f,
cf0dbb21 1285 BP_OLED_SSI | BP_GAMEPAD
9ee6e8bb
PB
1286 }
1287};
1288
1289static void stellaris_init(const char *kernel_filename, const char *cpu_model,
3023f332 1290 stellaris_board_info *board)
9ee6e8bb
PB
1291{
1292 static const int uart_irq[] = {5, 6, 33, 34};
1293 static const int timer_irq[] = {19, 21, 23, 35};
1294 static const uint32_t gpio_addr[7] =
1295 { 0x40004000, 0x40005000, 0x40006000, 0x40007000,
1296 0x40024000, 0x40025000, 0x40026000};
1297 static const int gpio_irq[7] = {0, 1, 2, 3, 4, 30, 31};
1298
1299 qemu_irq *pic;
40905a6a
PB
1300 DeviceState *gpio_dev[7];
1301 qemu_irq gpio_in[7][8];
1302 qemu_irq gpio_out[7][8];
9ee6e8bb
PB
1303 qemu_irq adc;
1304 int sram_size;
1305 int flash_size;
1306 i2c_bus *i2c;
40905a6a 1307 DeviceState *dev;
9ee6e8bb 1308 int i;
40905a6a 1309 int j;
9ee6e8bb
PB
1310
1311 flash_size = ((board->dc0 & 0xffff) + 1) << 1;
1312 sram_size = (board->dc0 >> 18) + 1;
1313 pic = armv7m_init(flash_size, sram_size, kernel_filename, cpu_model);
1314
1315 if (board->dc1 & (1 << 16)) {
40905a6a
PB
1316 dev = sysbus_create_varargs("stellaris-adc", 0x40038000,
1317 pic[14], pic[15], pic[16], pic[17], NULL);
1318 adc = qdev_get_gpio_in(dev, 0);
9ee6e8bb
PB
1319 } else {
1320 adc = NULL;
1321 }
1322 for (i = 0; i < 4; i++) {
1323 if (board->dc2 & (0x10000 << i)) {
40905a6a
PB
1324 dev = sysbus_create_simple("stellaris-gptm",
1325 0x40030000 + i * 0x1000,
1326 pic[timer_irq[i]]);
1327 /* TODO: This is incorrect, but we get away with it because
1328 the ADC output is only ever pulsed. */
1329 qdev_connect_gpio_out(dev, 0, adc);
9ee6e8bb
PB
1330 }
1331 }
1332
eea589cc 1333 stellaris_sys_init(0x400fe000, pic[28], board, nd_table[0].macaddr);
9ee6e8bb
PB
1334
1335 for (i = 0; i < 7; i++) {
1336 if (board->dc4 & (1 << i)) {
40905a6a
PB
1337 gpio_dev[i] = sysbus_create_simple("pl061", gpio_addr[i],
1338 pic[gpio_irq[i]]);
1339 for (j = 0; j < 8; j++) {
1340 gpio_in[i][j] = qdev_get_gpio_in(gpio_dev[i], j);
1341 gpio_out[i][j] = NULL;
1342 }
9ee6e8bb
PB
1343 }
1344 }
1345
1346 if (board->dc2 & (1 << 12)) {
1de9610c 1347 dev = sysbus_create_simple("stellaris-i2c", 0x40020000, pic[8]);
02e2da45 1348 i2c = (i2c_bus *)qdev_get_child_bus(dev, "i2c");
cf0dbb21 1349 if (board->peripherals & BP_OLED_I2C) {
d2199005 1350 i2c_create_slave(i2c, "ssd0303", 0x3d);
9ee6e8bb
PB
1351 }
1352 }
1353
1354 for (i = 0; i < 4; i++) {
1355 if (board->dc2 & (1 << i)) {
a7d518a6
PB
1356 sysbus_create_simple("pl011_luminary", 0x4000c000 + i * 0x1000,
1357 pic[uart_irq[i]]);
9ee6e8bb
PB
1358 }
1359 }
1360 if (board->dc2 & (1 << 4)) {
5493e33f 1361 dev = sysbus_create_simple("pl022", 0x40008000, pic[7]);
cf0dbb21 1362 if (board->peripherals & BP_OLED_SSI) {
5493e33f
PB
1363 DeviceState *mux;
1364 void *bus;
775616c3 1365
5493e33f
PB
1366 bus = qdev_get_child_bus(dev, "ssi");
1367 mux = ssi_create_slave(bus, "evb6965-ssi");
1368 gpio_out[GPIO_D][0] = qdev_get_gpio_in(mux, 0);
775616c3 1369
5493e33f 1370 bus = qdev_get_child_bus(mux, "ssi0");
22ed1d34 1371 ssi_create_slave(bus, "ssi-sd");
5493e33f
PB
1372
1373 bus = qdev_get_child_bus(mux, "ssi1");
1374 dev = ssi_create_slave(bus, "ssd0323");
1375 gpio_out[GPIO_C][7] = qdev_get_gpio_in(dev, 0);
775616c3 1376
775616c3
PB
1377 /* Make sure the select pin is high. */
1378 qemu_irq_raise(gpio_out[GPIO_D][0]);
9ee6e8bb
PB
1379 }
1380 }
a5580466
PB
1381 if (board->dc4 & (1 << 28)) {
1382 DeviceState *enet;
1383
1384 qemu_check_nic_model(&nd_table[0], "stellaris");
1385
1386 enet = qdev_create(NULL, "stellaris_enet");
540f006a 1387 qdev_set_nic_properties(enet, &nd_table[0]);
e23a1b33 1388 qdev_init_nofail(enet);
a5580466
PB
1389 sysbus_mmio_map(sysbus_from_qdev(enet), 0, 0x40048000);
1390 sysbus_connect_irq(sysbus_from_qdev(enet), 0, pic[42]);
1391 }
cf0dbb21
PB
1392 if (board->peripherals & BP_GAMEPAD) {
1393 qemu_irq gpad_irq[5];
1394 static const int gpad_keycode[5] = { 0xc8, 0xd0, 0xcb, 0xcd, 0x1d };
1395
1396 gpad_irq[0] = qemu_irq_invert(gpio_in[GPIO_E][0]); /* up */
1397 gpad_irq[1] = qemu_irq_invert(gpio_in[GPIO_E][1]); /* down */
1398 gpad_irq[2] = qemu_irq_invert(gpio_in[GPIO_E][2]); /* left */
1399 gpad_irq[3] = qemu_irq_invert(gpio_in[GPIO_E][3]); /* right */
1400 gpad_irq[4] = qemu_irq_invert(gpio_in[GPIO_F][1]); /* select */
1401
1402 stellaris_gamepad_init(5, gpad_irq, gpad_keycode);
1403 }
40905a6a
PB
1404 for (i = 0; i < 7; i++) {
1405 if (board->dc4 & (1 << i)) {
1406 for (j = 0; j < 8; j++) {
1407 if (gpio_out[i][j]) {
1408 qdev_connect_gpio_out(gpio_dev[i], j, gpio_out[i][j]);
1409 }
1410 }
1411 }
1412 }
9ee6e8bb
PB
1413}
1414
1415/* FIXME: Figure out how to generate these from stellaris_boards. */
c227f099 1416static void lm3s811evb_init(ram_addr_t ram_size,
3023f332 1417 const char *boot_device,
9ee6e8bb
PB
1418 const char *kernel_filename, const char *kernel_cmdline,
1419 const char *initrd_filename, const char *cpu_model)
1420{
3023f332 1421 stellaris_init(kernel_filename, cpu_model, &stellaris_boards[0]);
9ee6e8bb
PB
1422}
1423
c227f099 1424static void lm3s6965evb_init(ram_addr_t ram_size,
3023f332 1425 const char *boot_device,
9ee6e8bb
PB
1426 const char *kernel_filename, const char *kernel_cmdline,
1427 const char *initrd_filename, const char *cpu_model)
1428{
3023f332 1429 stellaris_init(kernel_filename, cpu_model, &stellaris_boards[1]);
9ee6e8bb
PB
1430}
1431
f80f9ec9 1432static QEMUMachine lm3s811evb_machine = {
4b32e168
AL
1433 .name = "lm3s811evb",
1434 .desc = "Stellaris LM3S811EVB",
1435 .init = lm3s811evb_init,
9ee6e8bb
PB
1436};
1437
f80f9ec9 1438static QEMUMachine lm3s6965evb_machine = {
4b32e168
AL
1439 .name = "lm3s6965evb",
1440 .desc = "Stellaris LM3S6965EVB",
1441 .init = lm3s6965evb_init,
9ee6e8bb 1442};
1de9610c 1443
f80f9ec9
AL
1444static void stellaris_machine_init(void)
1445{
1446 qemu_register_machine(&lm3s811evb_machine);
1447 qemu_register_machine(&lm3s6965evb_machine);
1448}
1449
1450machine_init(stellaris_machine_init);
1451
5493e33f 1452static SSISlaveInfo stellaris_ssi_bus_info = {
074f2fff
GH
1453 .qdev.name = "evb6965-ssi",
1454 .qdev.size = sizeof(stellaris_ssi_bus_state),
5493e33f
PB
1455 .init = stellaris_ssi_bus_init,
1456 .transfer = stellaris_ssi_bus_transfer
1457};
1458
1de9610c
PB
1459static void stellaris_register_devices(void)
1460{
1461 sysbus_register_dev("stellaris-i2c", sizeof(stellaris_i2c_state),
1462 stellaris_i2c_init);
40905a6a
PB
1463 sysbus_register_dev("stellaris-gptm", sizeof(gptm_state),
1464 stellaris_gptm_init);
1465 sysbus_register_dev("stellaris-adc", sizeof(stellaris_adc_state),
1466 stellaris_adc_init);
074f2fff 1467 ssi_register_slave(&stellaris_ssi_bus_info);
1de9610c
PB
1468}
1469
1470device_init(stellaris_register_devices)