1
2
3
4
5
6
7
8
9
10#include "qemu/osdep.h"
11#include "qapi/error.h"
12#include "hw/sysbus.h"
13#include "hw/ssi/ssi.h"
14#include "hw/arm/arm.h"
15#include "hw/devices.h"
16#include "qemu/timer.h"
17#include "hw/i2c/i2c.h"
18#include "net/net.h"
19#include "hw/boards.h"
20#include "exec/address-spaces.h"
21#include "sysemu/sysemu.h"
22
23#define GPIO_A 0
24#define GPIO_B 1
25#define GPIO_C 2
26#define GPIO_D 3
27#define GPIO_E 4
28#define GPIO_F 5
29#define GPIO_G 6
30
31#define BP_OLED_I2C 0x01
32#define BP_OLED_SSI 0x02
33#define BP_GAMEPAD 0x04
34
35#define NUM_IRQ_LINES 64
36
37typedef const struct {
38 const char *name;
39 uint32_t did0;
40 uint32_t did1;
41 uint32_t dc0;
42 uint32_t dc1;
43 uint32_t dc2;
44 uint32_t dc3;
45 uint32_t dc4;
46 uint32_t peripherals;
47} stellaris_board_info;
48
49
50
51#define TYPE_STELLARIS_GPTM "stellaris-gptm"
52#define STELLARIS_GPTM(obj) \
53 OBJECT_CHECK(gptm_state, (obj), TYPE_STELLARIS_GPTM)
54
55typedef struct gptm_state {
56 SysBusDevice parent_obj;
57
58 MemoryRegion iomem;
59 uint32_t config;
60 uint32_t mode[2];
61 uint32_t control;
62 uint32_t state;
63 uint32_t mask;
64 uint32_t load[2];
65 uint32_t match[2];
66 uint32_t prescale[2];
67 uint32_t match_prescale[2];
68 uint32_t rtc;
69 int64_t tick[2];
70 struct gptm_state *opaque[2];
71 QEMUTimer *timer[2];
72
73 qemu_irq trigger;
74 qemu_irq irq;
75} gptm_state;
76
77static void gptm_update_irq(gptm_state *s)
78{
79 int level;
80 level = (s->state & s->mask) != 0;
81 qemu_set_irq(s->irq, level);
82}
83
84static void gptm_stop(gptm_state *s, int n)
85{
86 timer_del(s->timer[n]);
87}
88
89static void gptm_reload(gptm_state *s, int n, int reset)
90{
91 int64_t tick;
92 if (reset)
93 tick = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
94 else
95 tick = s->tick[n];
96
97 if (s->config == 0) {
98
99 uint32_t count;
100 count = s->load[0] | (s->load[1] << 16);
101 tick += (int64_t)count * system_clock_scale;
102 } else if (s->config == 1) {
103
104 tick += NANOSECONDS_PER_SECOND;
105 } else if (s->mode[n] == 0xa) {
106
107 } else {
108 hw_error("TODO: 16-bit timer mode 0x%x\n", s->mode[n]);
109 }
110 s->tick[n] = tick;
111 timer_mod(s->timer[n], tick);
112}
113
114static void gptm_tick(void *opaque)
115{
116 gptm_state **p = (gptm_state **)opaque;
117 gptm_state *s;
118 int n;
119
120 s = *p;
121 n = p - s->opaque;
122 if (s->config == 0) {
123 s->state |= 1;
124 if ((s->control & 0x20)) {
125
126 qemu_irq_pulse(s->trigger);
127 }
128 if (s->mode[0] & 1) {
129
130 s->control &= ~1;
131 } else {
132
133 gptm_reload(s, 0, 0);
134 }
135 } else if (s->config == 1) {
136
137 uint32_t match;
138 s->rtc++;
139 match = s->match[0] | (s->match[1] << 16);
140 if (s->rtc > match)
141 s->rtc = 0;
142 if (s->rtc == 0) {
143 s->state |= 8;
144 }
145 gptm_reload(s, 0, 0);
146 } else if (s->mode[n] == 0xa) {
147
148 } else {
149 hw_error("TODO: 16-bit timer mode 0x%x\n", s->mode[n]);
150 }
151 gptm_update_irq(s);
152}
153
154static uint64_t gptm_read(void *opaque, hwaddr offset,
155 unsigned size)
156{
157 gptm_state *s = (gptm_state *)opaque;
158
159 switch (offset) {
160 case 0x00:
161 return s->config;
162 case 0x04:
163 return s->mode[0];
164 case 0x08:
165 return s->mode[1];
166 case 0x0c:
167 return s->control;
168 case 0x18:
169 return s->mask;
170 case 0x1c:
171 return s->state;
172 case 0x20:
173 return s->state & s->mask;
174 case 0x24:
175 return 0;
176 case 0x28:
177 return s->load[0] | ((s->config < 4) ? (s->load[1] << 16) : 0);
178 case 0x2c:
179 return s->load[1];
180 case 0x30:
181 return s->match[0] | ((s->config < 4) ? (s->match[1] << 16) : 0);
182 case 0x34:
183 return s->match[1];
184 case 0x38:
185 return s->prescale[0];
186 case 0x3c:
187 return s->prescale[1];
188 case 0x40:
189 return s->match_prescale[0];
190 case 0x44:
191 return s->match_prescale[1];
192 case 0x48:
193 if (s->config == 1) {
194 return s->rtc;
195 }
196 qemu_log_mask(LOG_UNIMP,
197 "GPTM: read of TAR but timer read not supported");
198 return 0;
199 case 0x4c:
200 qemu_log_mask(LOG_UNIMP,
201 "GPTM: read of TBR but timer read not supported");
202 return 0;
203 default:
204 qemu_log_mask(LOG_GUEST_ERROR,
205 "GPTM: read at bad offset 0x%x\n", (int)offset);
206 return 0;
207 }
208}
209
210static void gptm_write(void *opaque, hwaddr offset,
211 uint64_t value, unsigned size)
212{
213 gptm_state *s = (gptm_state *)opaque;
214 uint32_t oldval;
215
216
217
218
219 switch (offset) {
220 case 0x00:
221 s->config = value;
222 break;
223 case 0x04:
224 s->mode[0] = value;
225 break;
226 case 0x08:
227 s->mode[1] = value;
228 break;
229 case 0x0c:
230 oldval = s->control;
231 s->control = value;
232
233 if ((oldval ^ value) & 1) {
234 if (value & 1) {
235 gptm_reload(s, 0, 1);
236 } else {
237 gptm_stop(s, 0);
238 }
239 }
240 if (((oldval ^ value) & 0x100) && s->config >= 4) {
241 if (value & 0x100) {
242 gptm_reload(s, 1, 1);
243 } else {
244 gptm_stop(s, 1);
245 }
246 }
247 break;
248 case 0x18:
249 s->mask = value & 0x77;
250 gptm_update_irq(s);
251 break;
252 case 0x24:
253 s->state &= ~value;
254 break;
255 case 0x28:
256 s->load[0] = value & 0xffff;
257 if (s->config < 4) {
258 s->load[1] = value >> 16;
259 }
260 break;
261 case 0x2c:
262 s->load[1] = value & 0xffff;
263 break;
264 case 0x30:
265 s->match[0] = value & 0xffff;
266 if (s->config < 4) {
267 s->match[1] = value >> 16;
268 }
269 break;
270 case 0x34:
271 s->match[1] = value >> 16;
272 break;
273 case 0x38:
274 s->prescale[0] = value;
275 break;
276 case 0x3c:
277 s->prescale[1] = value;
278 break;
279 case 0x40:
280 s->match_prescale[0] = value;
281 break;
282 case 0x44:
283 s->match_prescale[0] = value;
284 break;
285 default:
286 hw_error("gptm_write: Bad offset 0x%x\n", (int)offset);
287 }
288 gptm_update_irq(s);
289}
290
291static const MemoryRegionOps gptm_ops = {
292 .read = gptm_read,
293 .write = gptm_write,
294 .endianness = DEVICE_NATIVE_ENDIAN,
295};
296
297static const VMStateDescription vmstate_stellaris_gptm = {
298 .name = "stellaris_gptm",
299 .version_id = 1,
300 .minimum_version_id = 1,
301 .fields = (VMStateField[]) {
302 VMSTATE_UINT32(config, gptm_state),
303 VMSTATE_UINT32_ARRAY(mode, gptm_state, 2),
304 VMSTATE_UINT32(control, gptm_state),
305 VMSTATE_UINT32(state, gptm_state),
306 VMSTATE_UINT32(mask, gptm_state),
307 VMSTATE_UNUSED(8),
308 VMSTATE_UINT32_ARRAY(load, gptm_state, 2),
309 VMSTATE_UINT32_ARRAY(match, gptm_state, 2),
310 VMSTATE_UINT32_ARRAY(prescale, gptm_state, 2),
311 VMSTATE_UINT32_ARRAY(match_prescale, gptm_state, 2),
312 VMSTATE_UINT32(rtc, gptm_state),
313 VMSTATE_INT64_ARRAY(tick, gptm_state, 2),
314 VMSTATE_TIMER_PTR_ARRAY(timer, gptm_state, 2),
315 VMSTATE_END_OF_LIST()
316 }
317};
318
319static int stellaris_gptm_init(SysBusDevice *sbd)
320{
321 DeviceState *dev = DEVICE(sbd);
322 gptm_state *s = STELLARIS_GPTM(dev);
323
324 sysbus_init_irq(sbd, &s->irq);
325 qdev_init_gpio_out(dev, &s->trigger, 1);
326
327 memory_region_init_io(&s->iomem, OBJECT(s), &gptm_ops, s,
328 "gptm", 0x1000);
329 sysbus_init_mmio(sbd, &s->iomem);
330
331 s->opaque[0] = s->opaque[1] = s;
332 s->timer[0] = timer_new_ns(QEMU_CLOCK_VIRTUAL, gptm_tick, &s->opaque[0]);
333 s->timer[1] = timer_new_ns(QEMU_CLOCK_VIRTUAL, gptm_tick, &s->opaque[1]);
334 vmstate_register(dev, -1, &vmstate_stellaris_gptm, s);
335 return 0;
336}
337
338
339
340
341typedef struct {
342 MemoryRegion iomem;
343 uint32_t pborctl;
344 uint32_t ldopctl;
345 uint32_t int_status;
346 uint32_t int_mask;
347 uint32_t resc;
348 uint32_t rcc;
349 uint32_t rcc2;
350 uint32_t rcgc[3];
351 uint32_t scgc[3];
352 uint32_t dcgc[3];
353 uint32_t clkvclr;
354 uint32_t ldoarst;
355 uint32_t user0;
356 uint32_t user1;
357 qemu_irq irq;
358 stellaris_board_info *board;
359} ssys_state;
360
361static void ssys_update(ssys_state *s)
362{
363 qemu_set_irq(s->irq, (s->int_status & s->int_mask) != 0);
364}
365
366static uint32_t pllcfg_sandstorm[16] = {
367 0x31c0,
368 0x1ae0,
369 0x18c0,
370 0xd573,
371 0x37a6,
372 0x1ae2,
373 0x0c40,
374 0x98bc,
375 0x935b,
376 0x09c0,
377 0x4dee,
378 0x0c41,
379 0x75db,
380 0x1ae6,
381 0x0600,
382 0x585b
383};
384
385static uint32_t pllcfg_fury[16] = {
386 0x3200,
387 0x1b20,
388 0x1900,
389 0xf42b,
390 0x37e3,
391 0x1b21,
392 0x0c80,
393 0x98ee,
394 0xd5b4,
395 0x0a00,
396 0x4e27,
397 0x1902,
398 0xec1c,
399 0x1b23,
400 0x0640,
401 0xb11c
402};
403
404#define DID0_VER_MASK 0x70000000
405#define DID0_VER_0 0x00000000
406#define DID0_VER_1 0x10000000
407
408#define DID0_CLASS_MASK 0x00FF0000
409#define DID0_CLASS_SANDSTORM 0x00000000
410#define DID0_CLASS_FURY 0x00010000
411
412static int ssys_board_class(const ssys_state *s)
413{
414 uint32_t did0 = s->board->did0;
415 switch (did0 & DID0_VER_MASK) {
416 case DID0_VER_0:
417 return DID0_CLASS_SANDSTORM;
418 case DID0_VER_1:
419 switch (did0 & DID0_CLASS_MASK) {
420 case DID0_CLASS_SANDSTORM:
421 case DID0_CLASS_FURY:
422 return did0 & DID0_CLASS_MASK;
423 }
424
425 default:
426 hw_error("ssys_board_class: Unknown class 0x%08x\n", did0);
427 }
428}
429
430static uint64_t ssys_read(void *opaque, hwaddr offset,
431 unsigned size)
432{
433 ssys_state *s = (ssys_state *)opaque;
434
435 switch (offset) {
436 case 0x000:
437 return s->board->did0;
438 case 0x004:
439 return s->board->did1;
440 case 0x008:
441 return s->board->dc0;
442 case 0x010:
443 return s->board->dc1;
444 case 0x014:
445 return s->board->dc2;
446 case 0x018:
447 return s->board->dc3;
448 case 0x01c:
449 return s->board->dc4;
450 case 0x030:
451 return s->pborctl;
452 case 0x034:
453 return s->ldopctl;
454 case 0x040:
455 return 0;
456 case 0x044:
457 return 0;
458 case 0x048:
459 return 0;
460 case 0x050:
461 return s->int_status;
462 case 0x054:
463 return s->int_mask;
464 case 0x058:
465 return s->int_status & s->int_mask;
466 case 0x05c:
467 return s->resc;
468 case 0x060:
469 return s->rcc;
470 case 0x064:
471 {
472 int xtal;
473 xtal = (s->rcc >> 6) & 0xf;
474 switch (ssys_board_class(s)) {
475 case DID0_CLASS_FURY:
476 return pllcfg_fury[xtal];
477 case DID0_CLASS_SANDSTORM:
478 return pllcfg_sandstorm[xtal];
479 default:
480 hw_error("ssys_read: Unhandled class for PLLCFG read.\n");
481 return 0;
482 }
483 }
484 case 0x070:
485 return s->rcc2;
486 case 0x100:
487 return s->rcgc[0];
488 case 0x104:
489 return s->rcgc[1];
490 case 0x108:
491 return s->rcgc[2];
492 case 0x110:
493 return s->scgc[0];
494 case 0x114:
495 return s->scgc[1];
496 case 0x118:
497 return s->scgc[2];
498 case 0x120:
499 return s->dcgc[0];
500 case 0x124:
501 return s->dcgc[1];
502 case 0x128:
503 return s->dcgc[2];
504 case 0x150:
505 return s->clkvclr;
506 case 0x160:
507 return s->ldoarst;
508 case 0x1e0:
509 return s->user0;
510 case 0x1e4:
511 return s->user1;
512 default:
513 hw_error("ssys_read: Bad offset 0x%x\n", (int)offset);
514 return 0;
515 }
516}
517
518static bool ssys_use_rcc2(ssys_state *s)
519{
520 return (s->rcc2 >> 31) & 0x1;
521}
522
523
524
525
526static void ssys_calculate_system_clock(ssys_state *s)
527{
528 if (ssys_use_rcc2(s)) {
529 system_clock_scale = 5 * (((s->rcc2 >> 23) & 0x3f) + 1);
530 } else {
531 system_clock_scale = 5 * (((s->rcc >> 23) & 0xf) + 1);
532 }
533}
534
535static void ssys_write(void *opaque, hwaddr offset,
536 uint64_t value, unsigned size)
537{
538 ssys_state *s = (ssys_state *)opaque;
539
540 switch (offset) {
541 case 0x030:
542 s->pborctl = value & 0xffff;
543 break;
544 case 0x034:
545 s->ldopctl = value & 0x1f;
546 break;
547 case 0x040:
548 case 0x044:
549 case 0x048:
550 fprintf(stderr, "Peripheral reset not implemented\n");
551 break;
552 case 0x054:
553 s->int_mask = value & 0x7f;
554 break;
555 case 0x058:
556 s->int_status &= ~value;
557 break;
558 case 0x05c:
559 s->resc = value & 0x3f;
560 break;
561 case 0x060:
562 if ((s->rcc & (1 << 13)) != 0 && (value & (1 << 13)) == 0) {
563
564 s->int_status |= (1 << 6);
565 }
566 s->rcc = value;
567 ssys_calculate_system_clock(s);
568 break;
569 case 0x070:
570 if (ssys_board_class(s) == DID0_CLASS_SANDSTORM) {
571 break;
572 }
573
574 if ((s->rcc2 & (1 << 13)) != 0 && (value & (1 << 13)) == 0) {
575
576 s->int_status |= (1 << 6);
577 }
578 s->rcc2 = value;
579 ssys_calculate_system_clock(s);
580 break;
581 case 0x100:
582 s->rcgc[0] = value;
583 break;
584 case 0x104:
585 s->rcgc[1] = value;
586 break;
587 case 0x108:
588 s->rcgc[2] = value;
589 break;
590 case 0x110:
591 s->scgc[0] = value;
592 break;
593 case 0x114:
594 s->scgc[1] = value;
595 break;
596 case 0x118:
597 s->scgc[2] = value;
598 break;
599 case 0x120:
600 s->dcgc[0] = value;
601 break;
602 case 0x124:
603 s->dcgc[1] = value;
604 break;
605 case 0x128:
606 s->dcgc[2] = value;
607 break;
608 case 0x150:
609 s->clkvclr = value;
610 break;
611 case 0x160:
612 s->ldoarst = value;
613 break;
614 default:
615 hw_error("ssys_write: Bad offset 0x%x\n", (int)offset);
616 }
617 ssys_update(s);
618}
619
620static const MemoryRegionOps ssys_ops = {
621 .read = ssys_read,
622 .write = ssys_write,
623 .endianness = DEVICE_NATIVE_ENDIAN,
624};
625
626static void ssys_reset(void *opaque)
627{
628 ssys_state *s = (ssys_state *)opaque;
629
630 s->pborctl = 0x7ffd;
631 s->rcc = 0x078e3ac0;
632
633 if (ssys_board_class(s) == DID0_CLASS_SANDSTORM) {
634 s->rcc2 = 0;
635 } else {
636 s->rcc2 = 0x07802810;
637 }
638 s->rcgc[0] = 1;
639 s->scgc[0] = 1;
640 s->dcgc[0] = 1;
641 ssys_calculate_system_clock(s);
642}
643
644static int stellaris_sys_post_load(void *opaque, int version_id)
645{
646 ssys_state *s = opaque;
647
648 ssys_calculate_system_clock(s);
649
650 return 0;
651}
652
653static const VMStateDescription vmstate_stellaris_sys = {
654 .name = "stellaris_sys",
655 .version_id = 2,
656 .minimum_version_id = 1,
657 .post_load = stellaris_sys_post_load,
658 .fields = (VMStateField[]) {
659 VMSTATE_UINT32(pborctl, ssys_state),
660 VMSTATE_UINT32(ldopctl, ssys_state),
661 VMSTATE_UINT32(int_mask, ssys_state),
662 VMSTATE_UINT32(int_status, ssys_state),
663 VMSTATE_UINT32(resc, ssys_state),
664 VMSTATE_UINT32(rcc, ssys_state),
665 VMSTATE_UINT32_V(rcc2, ssys_state, 2),
666 VMSTATE_UINT32_ARRAY(rcgc, ssys_state, 3),
667 VMSTATE_UINT32_ARRAY(scgc, ssys_state, 3),
668 VMSTATE_UINT32_ARRAY(dcgc, ssys_state, 3),
669 VMSTATE_UINT32(clkvclr, ssys_state),
670 VMSTATE_UINT32(ldoarst, ssys_state),
671 VMSTATE_END_OF_LIST()
672 }
673};
674
675static int stellaris_sys_init(uint32_t base, qemu_irq irq,
676 stellaris_board_info * board,
677 uint8_t *macaddr)
678{
679 ssys_state *s;
680
681 s = g_new0(ssys_state, 1);
682 s->irq = irq;
683 s->board = board;
684
685 s->user0 = macaddr[0] | (macaddr[1] << 8) | (macaddr[2] << 16);
686 s->user1 = macaddr[3] | (macaddr[4] << 8) | (macaddr[5] << 16);
687
688 memory_region_init_io(&s->iomem, NULL, &ssys_ops, s, "ssys", 0x00001000);
689 memory_region_add_subregion(get_system_memory(), base, &s->iomem);
690 ssys_reset(s);
691 vmstate_register(NULL, -1, &vmstate_stellaris_sys, s);
692 return 0;
693}
694
695
696
697
698#define TYPE_STELLARIS_I2C "stellaris-i2c"
699#define STELLARIS_I2C(obj) \
700 OBJECT_CHECK(stellaris_i2c_state, (obj), TYPE_STELLARIS_I2C)
701
702typedef struct {
703 SysBusDevice parent_obj;
704
705 I2CBus *bus;
706 qemu_irq irq;
707 MemoryRegion iomem;
708 uint32_t msa;
709 uint32_t mcs;
710 uint32_t mdr;
711 uint32_t mtpr;
712 uint32_t mimr;
713 uint32_t mris;
714 uint32_t mcr;
715} stellaris_i2c_state;
716
717#define STELLARIS_I2C_MCS_BUSY 0x01
718#define STELLARIS_I2C_MCS_ERROR 0x02
719#define STELLARIS_I2C_MCS_ADRACK 0x04
720#define STELLARIS_I2C_MCS_DATACK 0x08
721#define STELLARIS_I2C_MCS_ARBLST 0x10
722#define STELLARIS_I2C_MCS_IDLE 0x20
723#define STELLARIS_I2C_MCS_BUSBSY 0x40
724
725static uint64_t stellaris_i2c_read(void *opaque, hwaddr offset,
726 unsigned size)
727{
728 stellaris_i2c_state *s = (stellaris_i2c_state *)opaque;
729
730 switch (offset) {
731 case 0x00:
732 return s->msa;
733 case 0x04:
734
735 return s->mcs | STELLARIS_I2C_MCS_IDLE;
736 case 0x08:
737 return s->mdr;
738 case 0x0c:
739 return s->mtpr;
740 case 0x10:
741 return s->mimr;
742 case 0x14:
743 return s->mris;
744 case 0x18:
745 return s->mris & s->mimr;
746 case 0x20:
747 return s->mcr;
748 default:
749 hw_error("strllaris_i2c_read: Bad offset 0x%x\n", (int)offset);
750 return 0;
751 }
752}
753
754static void stellaris_i2c_update(stellaris_i2c_state *s)
755{
756 int level;
757
758 level = (s->mris & s->mimr) != 0;
759 qemu_set_irq(s->irq, level);
760}
761
762static void stellaris_i2c_write(void *opaque, hwaddr offset,
763 uint64_t value, unsigned size)
764{
765 stellaris_i2c_state *s = (stellaris_i2c_state *)opaque;
766
767 switch (offset) {
768 case 0x00:
769 s->msa = value & 0xff;
770 break;
771 case 0x04:
772 if ((s->mcr & 0x10) == 0) {
773
774 break;
775 }
776
777 if ((value & 2) && (s->mcs & STELLARIS_I2C_MCS_BUSBSY) == 0) {
778 if (i2c_start_transfer(s->bus, s->msa >> 1, s->msa & 1)) {
779 s->mcs |= STELLARIS_I2C_MCS_ARBLST;
780 } else {
781 s->mcs &= ~STELLARIS_I2C_MCS_ARBLST;
782 s->mcs |= STELLARIS_I2C_MCS_BUSBSY;
783 }
784 }
785
786 if (!i2c_bus_busy(s->bus)
787 || (s->mcs & STELLARIS_I2C_MCS_BUSBSY) == 0) {
788 s->mcs |= STELLARIS_I2C_MCS_ERROR;
789 break;
790 }
791 s->mcs &= ~STELLARIS_I2C_MCS_ERROR;
792 if (value & 1) {
793
794
795 if (s->msa & 1) {
796
797 s->mdr = i2c_recv(s->bus) & 0xff;
798 } else {
799
800 i2c_send(s->bus, s->mdr);
801 }
802
803 s->mris |= 1;
804 }
805 if (value & 4) {
806
807 i2c_end_transfer(s->bus);
808 s->mcs &= ~STELLARIS_I2C_MCS_BUSBSY;
809 }
810 break;
811 case 0x08:
812 s->mdr = value & 0xff;
813 break;
814 case 0x0c:
815 s->mtpr = value & 0xff;
816 break;
817 case 0x10:
818 s->mimr = 1;
819 break;
820 case 0x1c:
821 s->mris &= ~value;
822 break;
823 case 0x20:
824 if (value & 1)
825 hw_error(
826 "stellaris_i2c_write: Loopback not implemented\n");
827 if (value & 0x20)
828 hw_error(
829 "stellaris_i2c_write: Slave mode not implemented\n");
830 s->mcr = value & 0x31;
831 break;
832 default:
833 hw_error("stellaris_i2c_write: Bad offset 0x%x\n",
834 (int)offset);
835 }
836 stellaris_i2c_update(s);
837}
838
839static void stellaris_i2c_reset(stellaris_i2c_state *s)
840{
841 if (s->mcs & STELLARIS_I2C_MCS_BUSBSY)
842 i2c_end_transfer(s->bus);
843
844 s->msa = 0;
845 s->mcs = 0;
846 s->mdr = 0;
847 s->mtpr = 1;
848 s->mimr = 0;
849 s->mris = 0;
850 s->mcr = 0;
851 stellaris_i2c_update(s);
852}
853
854static const MemoryRegionOps stellaris_i2c_ops = {
855 .read = stellaris_i2c_read,
856 .write = stellaris_i2c_write,
857 .endianness = DEVICE_NATIVE_ENDIAN,
858};
859
860static const VMStateDescription vmstate_stellaris_i2c = {
861 .name = "stellaris_i2c",
862 .version_id = 1,
863 .minimum_version_id = 1,
864 .fields = (VMStateField[]) {
865 VMSTATE_UINT32(msa, stellaris_i2c_state),
866 VMSTATE_UINT32(mcs, stellaris_i2c_state),
867 VMSTATE_UINT32(mdr, stellaris_i2c_state),
868 VMSTATE_UINT32(mtpr, stellaris_i2c_state),
869 VMSTATE_UINT32(mimr, stellaris_i2c_state),
870 VMSTATE_UINT32(mris, stellaris_i2c_state),
871 VMSTATE_UINT32(mcr, stellaris_i2c_state),
872 VMSTATE_END_OF_LIST()
873 }
874};
875
876static int stellaris_i2c_init(SysBusDevice *sbd)
877{
878 DeviceState *dev = DEVICE(sbd);
879 stellaris_i2c_state *s = STELLARIS_I2C(dev);
880 I2CBus *bus;
881
882 sysbus_init_irq(sbd, &s->irq);
883 bus = i2c_init_bus(dev, "i2c");
884 s->bus = bus;
885
886 memory_region_init_io(&s->iomem, OBJECT(s), &stellaris_i2c_ops, s,
887 "i2c", 0x1000);
888 sysbus_init_mmio(sbd, &s->iomem);
889
890 stellaris_i2c_reset(s);
891 vmstate_register(dev, -1, &vmstate_stellaris_i2c, s);
892 return 0;
893}
894
895
896
897
898#define STELLARIS_ADC_EM_CONTROLLER 0
899#define STELLARIS_ADC_EM_COMP 1
900#define STELLARIS_ADC_EM_EXTERNAL 4
901#define STELLARIS_ADC_EM_TIMER 5
902#define STELLARIS_ADC_EM_PWM0 6
903#define STELLARIS_ADC_EM_PWM1 7
904#define STELLARIS_ADC_EM_PWM2 8
905
906#define STELLARIS_ADC_FIFO_EMPTY 0x0100
907#define STELLARIS_ADC_FIFO_FULL 0x1000
908
909#define TYPE_STELLARIS_ADC "stellaris-adc"
910#define STELLARIS_ADC(obj) \
911 OBJECT_CHECK(stellaris_adc_state, (obj), TYPE_STELLARIS_ADC)
912
913typedef struct StellarisADCState {
914 SysBusDevice parent_obj;
915
916 MemoryRegion iomem;
917 uint32_t actss;
918 uint32_t ris;
919 uint32_t im;
920 uint32_t emux;
921 uint32_t ostat;
922 uint32_t ustat;
923 uint32_t sspri;
924 uint32_t sac;
925 struct {
926 uint32_t state;
927 uint32_t data[16];
928 } fifo[4];
929 uint32_t ssmux[4];
930 uint32_t ssctl[4];
931 uint32_t noise;
932 qemu_irq irq[4];
933} stellaris_adc_state;
934
935static uint32_t stellaris_adc_fifo_read(stellaris_adc_state *s, int n)
936{
937 int tail;
938
939 tail = s->fifo[n].state & 0xf;
940 if (s->fifo[n].state & STELLARIS_ADC_FIFO_EMPTY) {
941 s->ustat |= 1 << n;
942 } else {
943 s->fifo[n].state = (s->fifo[n].state & ~0xf) | ((tail + 1) & 0xf);
944 s->fifo[n].state &= ~STELLARIS_ADC_FIFO_FULL;
945 if (tail + 1 == ((s->fifo[n].state >> 4) & 0xf))
946 s->fifo[n].state |= STELLARIS_ADC_FIFO_EMPTY;
947 }
948 return s->fifo[n].data[tail];
949}
950
951static void stellaris_adc_fifo_write(stellaris_adc_state *s, int n,
952 uint32_t value)
953{
954 int head;
955
956
957
958 head = (s->fifo[n].state >> 4) & 0xf;
959 if (s->fifo[n].state & STELLARIS_ADC_FIFO_FULL) {
960 s->ostat |= 1 << n;
961 return;
962 }
963 s->fifo[n].data[head] = value;
964 head = (head + 1) & 0xf;
965 s->fifo[n].state &= ~STELLARIS_ADC_FIFO_EMPTY;
966 s->fifo[n].state = (s->fifo[n].state & ~0xf0) | (head << 4);
967 if ((s->fifo[n].state & 0xf) == head)
968 s->fifo[n].state |= STELLARIS_ADC_FIFO_FULL;
969}
970
971static void stellaris_adc_update(stellaris_adc_state *s)
972{
973 int level;
974 int n;
975
976 for (n = 0; n < 4; n++) {
977 level = (s->ris & s->im & (1 << n)) != 0;
978 qemu_set_irq(s->irq[n], level);
979 }
980}
981
982static void stellaris_adc_trigger(void *opaque, int irq, int level)
983{
984 stellaris_adc_state *s = (stellaris_adc_state *)opaque;
985 int n;
986
987 for (n = 0; n < 4; n++) {
988 if ((s->actss & (1 << n)) == 0) {
989 continue;
990 }
991
992 if (((s->emux >> (n * 4)) & 0xff) != 5) {
993 continue;
994 }
995
996
997
998 s->noise = s->noise * 314159 + 1;
999
1000 stellaris_adc_fifo_write(s, n, 0x200 + ((s->noise >> 16) & 7));
1001 s->ris |= (1 << n);
1002 stellaris_adc_update(s);
1003 }
1004}
1005
1006static void stellaris_adc_reset(stellaris_adc_state *s)
1007{
1008 int n;
1009
1010 for (n = 0; n < 4; n++) {
1011 s->ssmux[n] = 0;
1012 s->ssctl[n] = 0;
1013 s->fifo[n].state = STELLARIS_ADC_FIFO_EMPTY;
1014 }
1015}
1016
1017static uint64_t stellaris_adc_read(void *opaque, hwaddr offset,
1018 unsigned size)
1019{
1020 stellaris_adc_state *s = (stellaris_adc_state *)opaque;
1021
1022
1023 if (offset >= 0x40 && offset < 0xc0) {
1024 int n;
1025 n = (offset - 0x40) >> 5;
1026 switch (offset & 0x1f) {
1027 case 0x00:
1028 return s->ssmux[n];
1029 case 0x04:
1030 return s->ssctl[n];
1031 case 0x08:
1032 return stellaris_adc_fifo_read(s, n);
1033 case 0x0c:
1034 return s->fifo[n].state;
1035 default:
1036 break;
1037 }
1038 }
1039 switch (offset) {
1040 case 0x00:
1041 return s->actss;
1042 case 0x04:
1043 return s->ris;
1044 case 0x08:
1045 return s->im;
1046 case 0x0c:
1047 return s->ris & s->im;
1048 case 0x10:
1049 return s->ostat;
1050 case 0x14:
1051 return s->emux;
1052 case 0x18:
1053 return s->ustat;
1054 case 0x20:
1055 return s->sspri;
1056 case 0x30:
1057 return s->sac;
1058 default:
1059 hw_error("strllaris_adc_read: Bad offset 0x%x\n",
1060 (int)offset);
1061 return 0;
1062 }
1063}
1064
1065static void stellaris_adc_write(void *opaque, hwaddr offset,
1066 uint64_t value, unsigned size)
1067{
1068 stellaris_adc_state *s = (stellaris_adc_state *)opaque;
1069
1070
1071 if (offset >= 0x40 && offset < 0xc0) {
1072 int n;
1073 n = (offset - 0x40) >> 5;
1074 switch (offset & 0x1f) {
1075 case 0x00:
1076 s->ssmux[n] = value & 0x33333333;
1077 return;
1078 case 0x04:
1079 if (value != 6) {
1080 hw_error("ADC: Unimplemented sequence %" PRIx64 "\n",
1081 value);
1082 }
1083 s->ssctl[n] = value;
1084 return;
1085 default:
1086 break;
1087 }
1088 }
1089 switch (offset) {
1090 case 0x00:
1091 s->actss = value & 0xf;
1092 break;
1093 case 0x08:
1094 s->im = value;
1095 break;
1096 case 0x0c:
1097 s->ris &= ~value;
1098 break;
1099 case 0x10:
1100 s->ostat &= ~value;
1101 break;
1102 case 0x14:
1103 s->emux = value;
1104 break;
1105 case 0x18:
1106 s->ustat &= ~value;
1107 break;
1108 case 0x20:
1109 s->sspri = value;
1110 break;
1111 case 0x28:
1112 hw_error("Not implemented: ADC sample initiate\n");
1113 break;
1114 case 0x30:
1115 s->sac = value;
1116 break;
1117 default:
1118 hw_error("stellaris_adc_write: Bad offset 0x%x\n", (int)offset);
1119 }
1120 stellaris_adc_update(s);
1121}
1122
1123static const MemoryRegionOps stellaris_adc_ops = {
1124 .read = stellaris_adc_read,
1125 .write = stellaris_adc_write,
1126 .endianness = DEVICE_NATIVE_ENDIAN,
1127};
1128
1129static const VMStateDescription vmstate_stellaris_adc = {
1130 .name = "stellaris_adc",
1131 .version_id = 1,
1132 .minimum_version_id = 1,
1133 .fields = (VMStateField[]) {
1134 VMSTATE_UINT32(actss, stellaris_adc_state),
1135 VMSTATE_UINT32(ris, stellaris_adc_state),
1136 VMSTATE_UINT32(im, stellaris_adc_state),
1137 VMSTATE_UINT32(emux, stellaris_adc_state),
1138 VMSTATE_UINT32(ostat, stellaris_adc_state),
1139 VMSTATE_UINT32(ustat, stellaris_adc_state),
1140 VMSTATE_UINT32(sspri, stellaris_adc_state),
1141 VMSTATE_UINT32(sac, stellaris_adc_state),
1142 VMSTATE_UINT32(fifo[0].state, stellaris_adc_state),
1143 VMSTATE_UINT32_ARRAY(fifo[0].data, stellaris_adc_state, 16),
1144 VMSTATE_UINT32(ssmux[0], stellaris_adc_state),
1145 VMSTATE_UINT32(ssctl[0], stellaris_adc_state),
1146 VMSTATE_UINT32(fifo[1].state, stellaris_adc_state),
1147 VMSTATE_UINT32_ARRAY(fifo[1].data, stellaris_adc_state, 16),
1148 VMSTATE_UINT32(ssmux[1], stellaris_adc_state),
1149 VMSTATE_UINT32(ssctl[1], stellaris_adc_state),
1150 VMSTATE_UINT32(fifo[2].state, stellaris_adc_state),
1151 VMSTATE_UINT32_ARRAY(fifo[2].data, stellaris_adc_state, 16),
1152 VMSTATE_UINT32(ssmux[2], stellaris_adc_state),
1153 VMSTATE_UINT32(ssctl[2], stellaris_adc_state),
1154 VMSTATE_UINT32(fifo[3].state, stellaris_adc_state),
1155 VMSTATE_UINT32_ARRAY(fifo[3].data, stellaris_adc_state, 16),
1156 VMSTATE_UINT32(ssmux[3], stellaris_adc_state),
1157 VMSTATE_UINT32(ssctl[3], stellaris_adc_state),
1158 VMSTATE_UINT32(noise, stellaris_adc_state),
1159 VMSTATE_END_OF_LIST()
1160 }
1161};
1162
1163static int stellaris_adc_init(SysBusDevice *sbd)
1164{
1165 DeviceState *dev = DEVICE(sbd);
1166 stellaris_adc_state *s = STELLARIS_ADC(dev);
1167 int n;
1168
1169 for (n = 0; n < 4; n++) {
1170 sysbus_init_irq(sbd, &s->irq[n]);
1171 }
1172
1173 memory_region_init_io(&s->iomem, OBJECT(s), &stellaris_adc_ops, s,
1174 "adc", 0x1000);
1175 sysbus_init_mmio(sbd, &s->iomem);
1176 stellaris_adc_reset(s);
1177 qdev_init_gpio_in(dev, stellaris_adc_trigger, 1);
1178 vmstate_register(dev, -1, &vmstate_stellaris_adc, s);
1179 return 0;
1180}
1181
1182static
1183void do_sys_reset(void *opaque, int n, int level)
1184{
1185 if (level) {
1186 qemu_system_reset_request();
1187 }
1188}
1189
1190
1191static stellaris_board_info stellaris_boards[] = {
1192 { "LM3S811EVB",
1193 0,
1194 0x0032000e,
1195 0x001f001f,
1196 0x001132bf,
1197 0x01071013,
1198 0x3f0f01ff,
1199 0x0000001f,
1200 BP_OLED_I2C
1201 },
1202 { "LM3S6965EVB",
1203 0x10010002,
1204 0x1073402e,
1205 0x00ff007f,
1206 0x001133ff,
1207 0x030f5317,
1208 0x0f0f87ff,
1209 0x5000007f,
1210 BP_OLED_SSI | BP_GAMEPAD
1211 }
1212};
1213
1214static void stellaris_init(const char *kernel_filename, const char *cpu_model,
1215 stellaris_board_info *board)
1216{
1217 static const int uart_irq[] = {5, 6, 33, 34};
1218 static const int timer_irq[] = {19, 21, 23, 35};
1219 static const uint32_t gpio_addr[7] =
1220 { 0x40004000, 0x40005000, 0x40006000, 0x40007000,
1221 0x40024000, 0x40025000, 0x40026000};
1222 static const int gpio_irq[7] = {0, 1, 2, 3, 4, 30, 31};
1223
1224 DeviceState *gpio_dev[7], *nvic;
1225 qemu_irq gpio_in[7][8];
1226 qemu_irq gpio_out[7][8];
1227 qemu_irq adc;
1228 int sram_size;
1229 int flash_size;
1230 I2CBus *i2c;
1231 DeviceState *dev;
1232 int i;
1233 int j;
1234
1235 MemoryRegion *sram = g_new(MemoryRegion, 1);
1236 MemoryRegion *flash = g_new(MemoryRegion, 1);
1237 MemoryRegion *system_memory = get_system_memory();
1238
1239 flash_size = (((board->dc0 & 0xffff) + 1) << 1) * 1024;
1240 sram_size = ((board->dc0 >> 18) + 1) * 1024;
1241
1242
1243 memory_region_init_ram(flash, NULL, "stellaris.flash", flash_size,
1244 &error_fatal);
1245 vmstate_register_ram_global(flash);
1246 memory_region_set_readonly(flash, true);
1247 memory_region_add_subregion(system_memory, 0, flash);
1248
1249 memory_region_init_ram(sram, NULL, "stellaris.sram", sram_size,
1250 &error_fatal);
1251 vmstate_register_ram_global(sram);
1252 memory_region_add_subregion(system_memory, 0x20000000, sram);
1253
1254 nvic = armv7m_init(system_memory, flash_size, NUM_IRQ_LINES,
1255 kernel_filename, cpu_model);
1256
1257 qdev_connect_gpio_out_named(nvic, "SYSRESETREQ", 0,
1258 qemu_allocate_irq(&do_sys_reset, NULL, 0));
1259
1260 if (board->dc1 & (1 << 16)) {
1261 dev = sysbus_create_varargs(TYPE_STELLARIS_ADC, 0x40038000,
1262 qdev_get_gpio_in(nvic, 14),
1263 qdev_get_gpio_in(nvic, 15),
1264 qdev_get_gpio_in(nvic, 16),
1265 qdev_get_gpio_in(nvic, 17),
1266 NULL);
1267 adc = qdev_get_gpio_in(dev, 0);
1268 } else {
1269 adc = NULL;
1270 }
1271 for (i = 0; i < 4; i++) {
1272 if (board->dc2 & (0x10000 << i)) {
1273 dev = sysbus_create_simple(TYPE_STELLARIS_GPTM,
1274 0x40030000 + i * 0x1000,
1275 qdev_get_gpio_in(nvic, timer_irq[i]));
1276
1277
1278 qdev_connect_gpio_out(dev, 0, adc);
1279 }
1280 }
1281
1282 stellaris_sys_init(0x400fe000, qdev_get_gpio_in(nvic, 28),
1283 board, nd_table[0].macaddr.a);
1284
1285 for (i = 0; i < 7; i++) {
1286 if (board->dc4 & (1 << i)) {
1287 gpio_dev[i] = sysbus_create_simple("pl061_luminary", gpio_addr[i],
1288 qdev_get_gpio_in(nvic,
1289 gpio_irq[i]));
1290 for (j = 0; j < 8; j++) {
1291 gpio_in[i][j] = qdev_get_gpio_in(gpio_dev[i], j);
1292 gpio_out[i][j] = NULL;
1293 }
1294 }
1295 }
1296
1297 if (board->dc2 & (1 << 12)) {
1298 dev = sysbus_create_simple(TYPE_STELLARIS_I2C, 0x40020000,
1299 qdev_get_gpio_in(nvic, 8));
1300 i2c = (I2CBus *)qdev_get_child_bus(dev, "i2c");
1301 if (board->peripherals & BP_OLED_I2C) {
1302 i2c_create_slave(i2c, "ssd0303", 0x3d);
1303 }
1304 }
1305
1306 for (i = 0; i < 4; i++) {
1307 if (board->dc2 & (1 << i)) {
1308 sysbus_create_simple("pl011_luminary", 0x4000c000 + i * 0x1000,
1309 qdev_get_gpio_in(nvic, uart_irq[i]));
1310 }
1311 }
1312 if (board->dc2 & (1 << 4)) {
1313 dev = sysbus_create_simple("pl022", 0x40008000,
1314 qdev_get_gpio_in(nvic, 7));
1315 if (board->peripherals & BP_OLED_SSI) {
1316 void *bus;
1317 DeviceState *sddev;
1318 DeviceState *ssddev;
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328 bus = qdev_get_child_bus(dev, "ssi");
1329
1330 sddev = ssi_create_slave(bus, "ssi-sd");
1331 ssddev = ssi_create_slave(bus, "ssd0323");
1332 gpio_out[GPIO_D][0] = qemu_irq_split(
1333 qdev_get_gpio_in_named(sddev, SSI_GPIO_CS, 0),
1334 qdev_get_gpio_in_named(ssddev, SSI_GPIO_CS, 0));
1335 gpio_out[GPIO_C][7] = qdev_get_gpio_in(ssddev, 0);
1336
1337
1338 qemu_irq_raise(gpio_out[GPIO_D][0]);
1339 }
1340 }
1341 if (board->dc4 & (1 << 28)) {
1342 DeviceState *enet;
1343
1344 qemu_check_nic_model(&nd_table[0], "stellaris");
1345
1346 enet = qdev_create(NULL, "stellaris_enet");
1347 qdev_set_nic_properties(enet, &nd_table[0]);
1348 qdev_init_nofail(enet);
1349 sysbus_mmio_map(SYS_BUS_DEVICE(enet), 0, 0x40048000);
1350 sysbus_connect_irq(SYS_BUS_DEVICE(enet), 0, qdev_get_gpio_in(nvic, 42));
1351 }
1352 if (board->peripherals & BP_GAMEPAD) {
1353 qemu_irq gpad_irq[5];
1354 static const int gpad_keycode[5] = { 0xc8, 0xd0, 0xcb, 0xcd, 0x1d };
1355
1356 gpad_irq[0] = qemu_irq_invert(gpio_in[GPIO_E][0]);
1357 gpad_irq[1] = qemu_irq_invert(gpio_in[GPIO_E][1]);
1358 gpad_irq[2] = qemu_irq_invert(gpio_in[GPIO_E][2]);
1359 gpad_irq[3] = qemu_irq_invert(gpio_in[GPIO_E][3]);
1360 gpad_irq[4] = qemu_irq_invert(gpio_in[GPIO_F][1]);
1361
1362 stellaris_gamepad_init(5, gpad_irq, gpad_keycode);
1363 }
1364 for (i = 0; i < 7; i++) {
1365 if (board->dc4 & (1 << i)) {
1366 for (j = 0; j < 8; j++) {
1367 if (gpio_out[i][j]) {
1368 qdev_connect_gpio_out(gpio_dev[i], j, gpio_out[i][j]);
1369 }
1370 }
1371 }
1372 }
1373}
1374
1375
1376static void lm3s811evb_init(MachineState *machine)
1377{
1378 const char *cpu_model = machine->cpu_model;
1379 const char *kernel_filename = machine->kernel_filename;
1380 stellaris_init(kernel_filename, cpu_model, &stellaris_boards[0]);
1381}
1382
1383static void lm3s6965evb_init(MachineState *machine)
1384{
1385 const char *cpu_model = machine->cpu_model;
1386 const char *kernel_filename = machine->kernel_filename;
1387 stellaris_init(kernel_filename, cpu_model, &stellaris_boards[1]);
1388}
1389
1390static void lm3s811evb_class_init(ObjectClass *oc, void *data)
1391{
1392 MachineClass *mc = MACHINE_CLASS(oc);
1393
1394 mc->desc = "Stellaris LM3S811EVB";
1395 mc->init = lm3s811evb_init;
1396}
1397
1398static const TypeInfo lm3s811evb_type = {
1399 .name = MACHINE_TYPE_NAME("lm3s811evb"),
1400 .parent = TYPE_MACHINE,
1401 .class_init = lm3s811evb_class_init,
1402};
1403
1404static void lm3s6965evb_class_init(ObjectClass *oc, void *data)
1405{
1406 MachineClass *mc = MACHINE_CLASS(oc);
1407
1408 mc->desc = "Stellaris LM3S6965EVB";
1409 mc->init = lm3s6965evb_init;
1410}
1411
1412static const TypeInfo lm3s6965evb_type = {
1413 .name = MACHINE_TYPE_NAME("lm3s6965evb"),
1414 .parent = TYPE_MACHINE,
1415 .class_init = lm3s6965evb_class_init,
1416};
1417
1418static void stellaris_machine_init(void)
1419{
1420 type_register_static(&lm3s811evb_type);
1421 type_register_static(&lm3s6965evb_type);
1422}
1423
1424type_init(stellaris_machine_init)
1425
1426static void stellaris_i2c_class_init(ObjectClass *klass, void *data)
1427{
1428 SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
1429
1430 sdc->init = stellaris_i2c_init;
1431}
1432
1433static const TypeInfo stellaris_i2c_info = {
1434 .name = TYPE_STELLARIS_I2C,
1435 .parent = TYPE_SYS_BUS_DEVICE,
1436 .instance_size = sizeof(stellaris_i2c_state),
1437 .class_init = stellaris_i2c_class_init,
1438};
1439
1440static void stellaris_gptm_class_init(ObjectClass *klass, void *data)
1441{
1442 SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
1443
1444 sdc->init = stellaris_gptm_init;
1445}
1446
1447static const TypeInfo stellaris_gptm_info = {
1448 .name = TYPE_STELLARIS_GPTM,
1449 .parent = TYPE_SYS_BUS_DEVICE,
1450 .instance_size = sizeof(gptm_state),
1451 .class_init = stellaris_gptm_class_init,
1452};
1453
1454static void stellaris_adc_class_init(ObjectClass *klass, void *data)
1455{
1456 SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
1457
1458 sdc->init = stellaris_adc_init;
1459}
1460
1461static const TypeInfo stellaris_adc_info = {
1462 .name = TYPE_STELLARIS_ADC,
1463 .parent = TYPE_SYS_BUS_DEVICE,
1464 .instance_size = sizeof(stellaris_adc_state),
1465 .class_init = stellaris_adc_class_init,
1466};
1467
1468static void stellaris_register_types(void)
1469{
1470 type_register_static(&stellaris_i2c_info);
1471 type_register_static(&stellaris_gptm_info);
1472 type_register_static(&stellaris_adc_info);
1473}
1474
1475type_init(stellaris_register_types)
1476