Nicer debug output
[qemu/mini2440.git] / hw / stellaris.c
bloba32f86fe90e87f5a5a058f20af5ae35e83a653b1
1 /*
2 * Luminary Micro Stellaris peripherals
4 * Copyright (c) 2006 CodeSourcery.
5 * Written by Paul Brook
7 * This code is licenced under the GPL.
8 */
10 #include "hw.h"
11 #include "arm-misc.h"
12 #include "primecell.h"
13 #include "devices.h"
14 #include "qemu-timer.h"
15 #include "i2c.h"
16 #include "net.h"
17 #include "sd.h"
18 #include "sysemu.h"
19 #include "boards.h"
21 #define GPIO_A 0
22 #define GPIO_B 1
23 #define GPIO_C 2
24 #define GPIO_D 3
25 #define GPIO_E 4
26 #define GPIO_F 5
27 #define GPIO_G 6
29 #define BP_OLED_I2C 0x01
30 #define BP_OLED_SSI 0x02
31 #define BP_GAMEPAD 0x04
33 typedef const struct {
34 const char *name;
35 uint32_t did0;
36 uint32_t did1;
37 uint32_t dc0;
38 uint32_t dc1;
39 uint32_t dc2;
40 uint32_t dc3;
41 uint32_t dc4;
42 uint32_t peripherals;
43 } stellaris_board_info;
45 /* General purpose timer module. */
47 typedef struct gptm_state {
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];
60 uint32_t base;
61 QEMUTimer *timer[2];
62 /* The timers have an alternate output used to trigger the ADC. */
63 qemu_irq trigger;
64 qemu_irq irq;
65 } gptm_state;
67 static void gptm_update_irq(gptm_state *s)
69 int level;
70 level = (s->state & s->mask) != 0;
71 qemu_set_irq(s->irq, level);
74 static void gptm_stop(gptm_state *s, int n)
76 qemu_del_timer(s->timer[n]);
79 static void gptm_reload(gptm_state *s, int n, int reset)
81 int64_t tick;
82 if (reset)
83 tick = qemu_get_clock(vm_clock);
84 else
85 tick = s->tick[n];
87 if (s->config == 0) {
88 /* 32-bit CountDown. */
89 uint32_t count;
90 count = s->load[0] | (s->load[1] << 16);
91 tick += (int64_t)count * system_clock_scale;
92 } else if (s->config == 1) {
93 /* 32-bit RTC. 1Hz tick. */
94 tick += ticks_per_sec;
95 } else if (s->mode[n] == 0xa) {
96 /* PWM mode. Not implemented. */
97 } else {
98 cpu_abort(cpu_single_env, "TODO: 16-bit timer mode 0x%x\n",
99 s->mode[n]);
101 s->tick[n] = tick;
102 qemu_mod_timer(s->timer[n], tick);
105 static void gptm_tick(void *opaque)
107 gptm_state **p = (gptm_state **)opaque;
108 gptm_state *s;
109 int n;
111 s = *p;
112 n = p - s->opaque;
113 if (s->config == 0) {
114 s->state |= 1;
115 if ((s->control & 0x20)) {
116 /* Output trigger. */
117 qemu_irq_raise(s->trigger);
118 qemu_irq_lower(s->trigger);
120 if (s->mode[0] & 1) {
121 /* One-shot. */
122 s->control &= ~1;
123 } else {
124 /* Periodic. */
125 gptm_reload(s, 0, 0);
127 } else if (s->config == 1) {
128 /* RTC. */
129 uint32_t match;
130 s->rtc++;
131 match = s->match[0] | (s->match[1] << 16);
132 if (s->rtc > match)
133 s->rtc = 0;
134 if (s->rtc == 0) {
135 s->state |= 8;
137 gptm_reload(s, 0, 0);
138 } else if (s->mode[n] == 0xa) {
139 /* PWM mode. Not implemented. */
140 } else {
141 cpu_abort(cpu_single_env, "TODO: 16-bit timer mode 0x%x\n",
142 s->mode[n]);
144 gptm_update_irq(s);
147 static uint32_t gptm_read(void *opaque, target_phys_addr_t offset)
149 gptm_state *s = (gptm_state *)opaque;
151 offset -= s->base;
152 switch (offset) {
153 case 0x00: /* CFG */
154 return s->config;
155 case 0x04: /* TAMR */
156 return s->mode[0];
157 case 0x08: /* TBMR */
158 return s->mode[1];
159 case 0x0c: /* CTL */
160 return s->control;
161 case 0x18: /* IMR */
162 return s->mask;
163 case 0x1c: /* RIS */
164 return s->state;
165 case 0x20: /* MIS */
166 return s->state & s->mask;
167 case 0x24: /* CR */
168 return 0;
169 case 0x28: /* TAILR */
170 return s->load[0] | ((s->config < 4) ? (s->load[1] << 16) : 0);
171 case 0x2c: /* TBILR */
172 return s->load[1];
173 case 0x30: /* TAMARCHR */
174 return s->match[0] | ((s->config < 4) ? (s->match[1] << 16) : 0);
175 case 0x34: /* TBMATCHR */
176 return s->match[1];
177 case 0x38: /* TAPR */
178 return s->prescale[0];
179 case 0x3c: /* TBPR */
180 return s->prescale[1];
181 case 0x40: /* TAPMR */
182 return s->match_prescale[0];
183 case 0x44: /* TBPMR */
184 return s->match_prescale[1];
185 case 0x48: /* TAR */
186 if (s->control == 1)
187 return s->rtc;
188 case 0x4c: /* TBR */
189 cpu_abort(cpu_single_env, "TODO: Timer value read\n");
190 default:
191 cpu_abort(cpu_single_env, "gptm_read: Bad offset 0x%x\n", (int)offset);
192 return 0;
196 static void gptm_write(void *opaque, target_phys_addr_t offset, uint32_t value)
198 gptm_state *s = (gptm_state *)opaque;
199 uint32_t oldval;
201 offset -= s->base;
202 /* The timers should be disabled before changing the configuration.
203 We take advantage of this and defer everything until the timer
204 is enabled. */
205 switch (offset) {
206 case 0x00: /* CFG */
207 s->config = value;
208 break;
209 case 0x04: /* TAMR */
210 s->mode[0] = value;
211 break;
212 case 0x08: /* TBMR */
213 s->mode[1] = value;
214 break;
215 case 0x0c: /* CTL */
216 oldval = s->control;
217 s->control = value;
218 /* TODO: Implement pause. */
219 if ((oldval ^ value) & 1) {
220 if (value & 1) {
221 gptm_reload(s, 0, 1);
222 } else {
223 gptm_stop(s, 0);
226 if (((oldval ^ value) & 0x100) && s->config >= 4) {
227 if (value & 0x100) {
228 gptm_reload(s, 1, 1);
229 } else {
230 gptm_stop(s, 1);
233 break;
234 case 0x18: /* IMR */
235 s->mask = value & 0x77;
236 gptm_update_irq(s);
237 break;
238 case 0x24: /* CR */
239 s->state &= ~value;
240 break;
241 case 0x28: /* TAILR */
242 s->load[0] = value & 0xffff;
243 if (s->config < 4) {
244 s->load[1] = value >> 16;
246 break;
247 case 0x2c: /* TBILR */
248 s->load[1] = value & 0xffff;
249 break;
250 case 0x30: /* TAMARCHR */
251 s->match[0] = value & 0xffff;
252 if (s->config < 4) {
253 s->match[1] = value >> 16;
255 break;
256 case 0x34: /* TBMATCHR */
257 s->match[1] = value >> 16;
258 break;
259 case 0x38: /* TAPR */
260 s->prescale[0] = value;
261 break;
262 case 0x3c: /* TBPR */
263 s->prescale[1] = value;
264 break;
265 case 0x40: /* TAPMR */
266 s->match_prescale[0] = value;
267 break;
268 case 0x44: /* TBPMR */
269 s->match_prescale[0] = value;
270 break;
271 default:
272 cpu_abort(cpu_single_env, "gptm_write: Bad offset 0x%x\n", (int)offset);
274 gptm_update_irq(s);
277 static CPUReadMemoryFunc *gptm_readfn[] = {
278 gptm_read,
279 gptm_read,
280 gptm_read
283 static CPUWriteMemoryFunc *gptm_writefn[] = {
284 gptm_write,
285 gptm_write,
286 gptm_write
289 static void stellaris_gptm_init(uint32_t base, qemu_irq irq, qemu_irq trigger)
291 int iomemtype;
292 gptm_state *s;
294 s = (gptm_state *)qemu_mallocz(sizeof(gptm_state));
295 s->base = base;
296 s->irq = irq;
297 s->trigger = trigger;
298 s->opaque[0] = s->opaque[1] = s;
300 iomemtype = cpu_register_io_memory(0, gptm_readfn,
301 gptm_writefn, s);
302 cpu_register_physical_memory(base, 0x00001000, iomemtype);
303 s->timer[0] = qemu_new_timer(vm_clock, gptm_tick, &s->opaque[0]);
304 s->timer[1] = qemu_new_timer(vm_clock, gptm_tick, &s->opaque[1]);
305 /* ??? Save/restore. */
309 /* System controller. */
311 typedef struct {
312 uint32_t base;
313 uint32_t pborctl;
314 uint32_t ldopctl;
315 uint32_t int_status;
316 uint32_t int_mask;
317 uint32_t resc;
318 uint32_t rcc;
319 uint32_t rcgc[3];
320 uint32_t scgc[3];
321 uint32_t dcgc[3];
322 uint32_t clkvclr;
323 uint32_t ldoarst;
324 uint32_t user0;
325 uint32_t user1;
326 qemu_irq irq;
327 stellaris_board_info *board;
328 } ssys_state;
330 static void ssys_update(ssys_state *s)
332 qemu_set_irq(s->irq, (s->int_status & s->int_mask) != 0);
335 static uint32_t pllcfg_sandstorm[16] = {
336 0x31c0, /* 1 Mhz */
337 0x1ae0, /* 1.8432 Mhz */
338 0x18c0, /* 2 Mhz */
339 0xd573, /* 2.4576 Mhz */
340 0x37a6, /* 3.57954 Mhz */
341 0x1ae2, /* 3.6864 Mhz */
342 0x0c40, /* 4 Mhz */
343 0x98bc, /* 4.906 Mhz */
344 0x935b, /* 4.9152 Mhz */
345 0x09c0, /* 5 Mhz */
346 0x4dee, /* 5.12 Mhz */
347 0x0c41, /* 6 Mhz */
348 0x75db, /* 6.144 Mhz */
349 0x1ae6, /* 7.3728 Mhz */
350 0x0600, /* 8 Mhz */
351 0x585b /* 8.192 Mhz */
354 static uint32_t pllcfg_fury[16] = {
355 0x3200, /* 1 Mhz */
356 0x1b20, /* 1.8432 Mhz */
357 0x1900, /* 2 Mhz */
358 0xf42b, /* 2.4576 Mhz */
359 0x37e3, /* 3.57954 Mhz */
360 0x1b21, /* 3.6864 Mhz */
361 0x0c80, /* 4 Mhz */
362 0x98ee, /* 4.906 Mhz */
363 0xd5b4, /* 4.9152 Mhz */
364 0x0a00, /* 5 Mhz */
365 0x4e27, /* 5.12 Mhz */
366 0x1902, /* 6 Mhz */
367 0xec1c, /* 6.144 Mhz */
368 0x1b23, /* 7.3728 Mhz */
369 0x0640, /* 8 Mhz */
370 0xb11c /* 8.192 Mhz */
373 static uint32_t ssys_read(void *opaque, target_phys_addr_t offset)
375 ssys_state *s = (ssys_state *)opaque;
377 offset -= s->base;
378 switch (offset) {
379 case 0x000: /* DID0 */
380 return s->board->did0;
381 case 0x004: /* DID1 */
382 return s->board->did1;
383 case 0x008: /* DC0 */
384 return s->board->dc0;
385 case 0x010: /* DC1 */
386 return s->board->dc1;
387 case 0x014: /* DC2 */
388 return s->board->dc2;
389 case 0x018: /* DC3 */
390 return s->board->dc3;
391 case 0x01c: /* DC4 */
392 return s->board->dc4;
393 case 0x030: /* PBORCTL */
394 return s->pborctl;
395 case 0x034: /* LDOPCTL */
396 return s->ldopctl;
397 case 0x040: /* SRCR0 */
398 return 0;
399 case 0x044: /* SRCR1 */
400 return 0;
401 case 0x048: /* SRCR2 */
402 return 0;
403 case 0x050: /* RIS */
404 return s->int_status;
405 case 0x054: /* IMC */
406 return s->int_mask;
407 case 0x058: /* MISC */
408 return s->int_status & s->int_mask;
409 case 0x05c: /* RESC */
410 return s->resc;
411 case 0x060: /* RCC */
412 return s->rcc;
413 case 0x064: /* PLLCFG */
415 int xtal;
416 xtal = (s->rcc >> 6) & 0xf;
417 if (s->board->did0 & (1 << 16)) {
418 return pllcfg_fury[xtal];
419 } else {
420 return pllcfg_sandstorm[xtal];
423 case 0x100: /* RCGC0 */
424 return s->rcgc[0];
425 case 0x104: /* RCGC1 */
426 return s->rcgc[1];
427 case 0x108: /* RCGC2 */
428 return s->rcgc[2];
429 case 0x110: /* SCGC0 */
430 return s->scgc[0];
431 case 0x114: /* SCGC1 */
432 return s->scgc[1];
433 case 0x118: /* SCGC2 */
434 return s->scgc[2];
435 case 0x120: /* DCGC0 */
436 return s->dcgc[0];
437 case 0x124: /* DCGC1 */
438 return s->dcgc[1];
439 case 0x128: /* DCGC2 */
440 return s->dcgc[2];
441 case 0x150: /* CLKVCLR */
442 return s->clkvclr;
443 case 0x160: /* LDOARST */
444 return s->ldoarst;
445 case 0x1e0: /* USER0 */
446 return s->user0;
447 case 0x1e4: /* USER1 */
448 return s->user1;
449 default:
450 cpu_abort(cpu_single_env, "ssys_read: Bad offset 0x%x\n", (int)offset);
451 return 0;
455 static void ssys_write(void *opaque, target_phys_addr_t offset, uint32_t value)
457 ssys_state *s = (ssys_state *)opaque;
459 offset -= s->base;
460 switch (offset) {
461 case 0x030: /* PBORCTL */
462 s->pborctl = value & 0xffff;
463 break;
464 case 0x034: /* LDOPCTL */
465 s->ldopctl = value & 0x1f;
466 break;
467 case 0x040: /* SRCR0 */
468 case 0x044: /* SRCR1 */
469 case 0x048: /* SRCR2 */
470 fprintf(stderr, "Peripheral reset not implemented\n");
471 break;
472 case 0x054: /* IMC */
473 s->int_mask = value & 0x7f;
474 break;
475 case 0x058: /* MISC */
476 s->int_status &= ~value;
477 break;
478 case 0x05c: /* RESC */
479 s->resc = value & 0x3f;
480 break;
481 case 0x060: /* RCC */
482 if ((s->rcc & (1 << 13)) != 0 && (value & (1 << 13)) == 0) {
483 /* PLL enable. */
484 s->int_status |= (1 << 6);
486 s->rcc = value;
487 system_clock_scale = 5 * (((s->rcc >> 23) & 0xf) + 1);
488 break;
489 case 0x100: /* RCGC0 */
490 s->rcgc[0] = value;
491 break;
492 case 0x104: /* RCGC1 */
493 s->rcgc[1] = value;
494 break;
495 case 0x108: /* RCGC2 */
496 s->rcgc[2] = value;
497 break;
498 case 0x110: /* SCGC0 */
499 s->scgc[0] = value;
500 break;
501 case 0x114: /* SCGC1 */
502 s->scgc[1] = value;
503 break;
504 case 0x118: /* SCGC2 */
505 s->scgc[2] = value;
506 break;
507 case 0x120: /* DCGC0 */
508 s->dcgc[0] = value;
509 break;
510 case 0x124: /* DCGC1 */
511 s->dcgc[1] = value;
512 break;
513 case 0x128: /* DCGC2 */
514 s->dcgc[2] = value;
515 break;
516 case 0x150: /* CLKVCLR */
517 s->clkvclr = value;
518 break;
519 case 0x160: /* LDOARST */
520 s->ldoarst = value;
521 break;
522 default:
523 cpu_abort(cpu_single_env, "ssys_write: Bad offset 0x%x\n", (int)offset);
525 ssys_update(s);
528 static CPUReadMemoryFunc *ssys_readfn[] = {
529 ssys_read,
530 ssys_read,
531 ssys_read
534 static CPUWriteMemoryFunc *ssys_writefn[] = {
535 ssys_write,
536 ssys_write,
537 ssys_write
540 static void ssys_reset(void *opaque)
542 ssys_state *s = (ssys_state *)opaque;
544 s->pborctl = 0x7ffd;
545 s->rcc = 0x078e3ac0;
546 s->rcgc[0] = 1;
547 s->scgc[0] = 1;
548 s->dcgc[0] = 1;
551 static void stellaris_sys_init(uint32_t base, qemu_irq irq,
552 stellaris_board_info * board,
553 uint8_t *macaddr)
555 int iomemtype;
556 ssys_state *s;
558 s = (ssys_state *)qemu_mallocz(sizeof(ssys_state));
559 s->base = base;
560 s->irq = irq;
561 s->board = board;
562 /* Most devices come preprogrammed with a MAC address in the user data. */
563 s->user0 = macaddr[0] | (macaddr[1] << 8) | (macaddr[2] << 16);
564 s->user1 = macaddr[3] | (macaddr[4] << 8) | (macaddr[5] << 16);
566 iomemtype = cpu_register_io_memory(0, ssys_readfn,
567 ssys_writefn, s);
568 cpu_register_physical_memory(base, 0x00001000, iomemtype);
569 ssys_reset(s);
570 /* ??? Save/restore. */
574 /* I2C controller. */
576 typedef struct {
577 i2c_bus *bus;
578 qemu_irq irq;
579 uint32_t base;
580 uint32_t msa;
581 uint32_t mcs;
582 uint32_t mdr;
583 uint32_t mtpr;
584 uint32_t mimr;
585 uint32_t mris;
586 uint32_t mcr;
587 } stellaris_i2c_state;
589 #define STELLARIS_I2C_MCS_BUSY 0x01
590 #define STELLARIS_I2C_MCS_ERROR 0x02
591 #define STELLARIS_I2C_MCS_ADRACK 0x04
592 #define STELLARIS_I2C_MCS_DATACK 0x08
593 #define STELLARIS_I2C_MCS_ARBLST 0x10
594 #define STELLARIS_I2C_MCS_IDLE 0x20
595 #define STELLARIS_I2C_MCS_BUSBSY 0x40
597 static uint32_t stellaris_i2c_read(void *opaque, target_phys_addr_t offset)
599 stellaris_i2c_state *s = (stellaris_i2c_state *)opaque;
601 offset -= s->base;
602 switch (offset) {
603 case 0x00: /* MSA */
604 return s->msa;
605 case 0x04: /* MCS */
606 /* We don't emulate timing, so the controller is never busy. */
607 return s->mcs | STELLARIS_I2C_MCS_IDLE;
608 case 0x08: /* MDR */
609 return s->mdr;
610 case 0x0c: /* MTPR */
611 return s->mtpr;
612 case 0x10: /* MIMR */
613 return s->mimr;
614 case 0x14: /* MRIS */
615 return s->mris;
616 case 0x18: /* MMIS */
617 return s->mris & s->mimr;
618 case 0x20: /* MCR */
619 return s->mcr;
620 default:
621 cpu_abort(cpu_single_env, "strllaris_i2c_read: Bad offset 0x%x\n",
622 (int)offset);
623 return 0;
627 static void stellaris_i2c_update(stellaris_i2c_state *s)
629 int level;
631 level = (s->mris & s->mimr) != 0;
632 qemu_set_irq(s->irq, level);
635 static void stellaris_i2c_write(void *opaque, target_phys_addr_t offset,
636 uint32_t value)
638 stellaris_i2c_state *s = (stellaris_i2c_state *)opaque;
640 offset -= s->base;
641 switch (offset) {
642 case 0x00: /* MSA */
643 s->msa = value & 0xff;
644 break;
645 case 0x04: /* MCS */
646 if ((s->mcr & 0x10) == 0) {
647 /* Disabled. Do nothing. */
648 break;
650 /* Grab the bus if this is starting a transfer. */
651 if ((value & 2) && (s->mcs & STELLARIS_I2C_MCS_BUSBSY) == 0) {
652 if (i2c_start_transfer(s->bus, s->msa >> 1, s->msa & 1)) {
653 s->mcs |= STELLARIS_I2C_MCS_ARBLST;
654 } else {
655 s->mcs &= ~STELLARIS_I2C_MCS_ARBLST;
656 s->mcs |= STELLARIS_I2C_MCS_BUSBSY;
659 /* If we don't have the bus then indicate an error. */
660 if (!i2c_bus_busy(s->bus)
661 || (s->mcs & STELLARIS_I2C_MCS_BUSBSY) == 0) {
662 s->mcs |= STELLARIS_I2C_MCS_ERROR;
663 break;
665 s->mcs &= ~STELLARIS_I2C_MCS_ERROR;
666 if (value & 1) {
667 /* Transfer a byte. */
668 /* TODO: Handle errors. */
669 if (s->msa & 1) {
670 /* Recv */
671 s->mdr = i2c_recv(s->bus) & 0xff;
672 } else {
673 /* Send */
674 i2c_send(s->bus, s->mdr);
676 /* Raise an interrupt. */
677 s->mris |= 1;
679 if (value & 4) {
680 /* Finish transfer. */
681 i2c_end_transfer(s->bus);
682 s->mcs &= ~STELLARIS_I2C_MCS_BUSBSY;
684 break;
685 case 0x08: /* MDR */
686 s->mdr = value & 0xff;
687 break;
688 case 0x0c: /* MTPR */
689 s->mtpr = value & 0xff;
690 break;
691 case 0x10: /* MIMR */
692 s->mimr = 1;
693 break;
694 case 0x1c: /* MICR */
695 s->mris &= ~value;
696 break;
697 case 0x20: /* MCR */
698 if (value & 1)
699 cpu_abort(cpu_single_env,
700 "stellaris_i2c_write: Loopback not implemented\n");
701 if (value & 0x20)
702 cpu_abort(cpu_single_env,
703 "stellaris_i2c_write: Slave mode not implemented\n");
704 s->mcr = value & 0x31;
705 break;
706 default:
707 cpu_abort(cpu_single_env, "stellaris_i2c_write: Bad offset 0x%x\n",
708 (int)offset);
710 stellaris_i2c_update(s);
713 static void stellaris_i2c_reset(stellaris_i2c_state *s)
715 if (s->mcs & STELLARIS_I2C_MCS_BUSBSY)
716 i2c_end_transfer(s->bus);
718 s->msa = 0;
719 s->mcs = 0;
720 s->mdr = 0;
721 s->mtpr = 1;
722 s->mimr = 0;
723 s->mris = 0;
724 s->mcr = 0;
725 stellaris_i2c_update(s);
728 static CPUReadMemoryFunc *stellaris_i2c_readfn[] = {
729 stellaris_i2c_read,
730 stellaris_i2c_read,
731 stellaris_i2c_read
734 static CPUWriteMemoryFunc *stellaris_i2c_writefn[] = {
735 stellaris_i2c_write,
736 stellaris_i2c_write,
737 stellaris_i2c_write
740 static void stellaris_i2c_init(uint32_t base, qemu_irq irq, i2c_bus *bus)
742 stellaris_i2c_state *s;
743 int iomemtype;
745 s = (stellaris_i2c_state *)qemu_mallocz(sizeof(stellaris_i2c_state));
746 s->base = base;
747 s->irq = irq;
748 s->bus = bus;
750 iomemtype = cpu_register_io_memory(0, stellaris_i2c_readfn,
751 stellaris_i2c_writefn, s);
752 cpu_register_physical_memory(base, 0x00001000, iomemtype);
753 /* ??? For now we only implement the master interface. */
754 stellaris_i2c_reset(s);
757 /* Analogue to Digital Converter. This is only partially implemented,
758 enough for applications that use a combined ADC and timer tick. */
760 #define STELLARIS_ADC_EM_CONTROLLER 0
761 #define STELLARIS_ADC_EM_COMP 1
762 #define STELLARIS_ADC_EM_EXTERNAL 4
763 #define STELLARIS_ADC_EM_TIMER 5
764 #define STELLARIS_ADC_EM_PWM0 6
765 #define STELLARIS_ADC_EM_PWM1 7
766 #define STELLARIS_ADC_EM_PWM2 8
768 #define STELLARIS_ADC_FIFO_EMPTY 0x0100
769 #define STELLARIS_ADC_FIFO_FULL 0x1000
771 typedef struct
773 uint32_t base;
774 uint32_t actss;
775 uint32_t ris;
776 uint32_t im;
777 uint32_t emux;
778 uint32_t ostat;
779 uint32_t ustat;
780 uint32_t sspri;
781 uint32_t sac;
782 struct {
783 uint32_t state;
784 uint32_t data[16];
785 } fifo[4];
786 uint32_t ssmux[4];
787 uint32_t ssctl[4];
788 qemu_irq irq;
789 } stellaris_adc_state;
791 static uint32_t stellaris_adc_fifo_read(stellaris_adc_state *s, int n)
793 int tail;
795 tail = s->fifo[n].state & 0xf;
796 if (s->fifo[n].state & STELLARIS_ADC_FIFO_EMPTY) {
797 s->ustat |= 1 << n;
798 } else {
799 s->fifo[n].state = (s->fifo[n].state & ~0xf) | ((tail + 1) & 0xf);
800 s->fifo[n].state &= ~STELLARIS_ADC_FIFO_FULL;
801 if (tail + 1 == ((s->fifo[n].state >> 4) & 0xf))
802 s->fifo[n].state |= STELLARIS_ADC_FIFO_EMPTY;
804 return s->fifo[n].data[tail];
807 static void stellaris_adc_fifo_write(stellaris_adc_state *s, int n,
808 uint32_t value)
810 int head;
812 head = (s->fifo[n].state >> 4) & 0xf;
813 if (s->fifo[n].state & STELLARIS_ADC_FIFO_FULL) {
814 s->ostat |= 1 << n;
815 return;
817 s->fifo[n].data[head] = value;
818 head = (head + 1) & 0xf;
819 s->fifo[n].state &= ~STELLARIS_ADC_FIFO_EMPTY;
820 s->fifo[n].state = (s->fifo[n].state & ~0xf0) | (head << 4);
821 if ((s->fifo[n].state & 0xf) == head)
822 s->fifo[n].state |= STELLARIS_ADC_FIFO_FULL;
825 static void stellaris_adc_update(stellaris_adc_state *s)
827 int level;
829 level = (s->ris & s->im) != 0;
830 qemu_set_irq(s->irq, level);
833 static void stellaris_adc_trigger(void *opaque, int irq, int level)
835 stellaris_adc_state *s = (stellaris_adc_state *)opaque;
836 /* Some applications use the ADC as a random number source, so introduce
837 some variation into the signal. */
838 static uint32_t noise = 0;
840 if ((s->actss & 1) == 0) {
841 return;
844 noise = noise * 314159 + 1;
845 /* ??? actual inputs not implemented. Return an arbitrary value. */
846 stellaris_adc_fifo_write(s, 0, 0x200 + ((noise >> 16) & 7));
847 s->ris |= 1;
848 stellaris_adc_update(s);
851 static void stellaris_adc_reset(stellaris_adc_state *s)
853 int n;
855 for (n = 0; n < 4; n++) {
856 s->ssmux[n] = 0;
857 s->ssctl[n] = 0;
858 s->fifo[n].state = STELLARIS_ADC_FIFO_EMPTY;
862 static uint32_t stellaris_adc_read(void *opaque, target_phys_addr_t offset)
864 stellaris_adc_state *s = (stellaris_adc_state *)opaque;
866 /* TODO: Implement this. */
867 offset -= s->base;
868 if (offset >= 0x40 && offset < 0xc0) {
869 int n;
870 n = (offset - 0x40) >> 5;
871 switch (offset & 0x1f) {
872 case 0x00: /* SSMUX */
873 return s->ssmux[n];
874 case 0x04: /* SSCTL */
875 return s->ssctl[n];
876 case 0x08: /* SSFIFO */
877 return stellaris_adc_fifo_read(s, n);
878 case 0x0c: /* SSFSTAT */
879 return s->fifo[n].state;
880 default:
881 break;
884 switch (offset) {
885 case 0x00: /* ACTSS */
886 return s->actss;
887 case 0x04: /* RIS */
888 return s->ris;
889 case 0x08: /* IM */
890 return s->im;
891 case 0x0c: /* ISC */
892 return s->ris & s->im;
893 case 0x10: /* OSTAT */
894 return s->ostat;
895 case 0x14: /* EMUX */
896 return s->emux;
897 case 0x18: /* USTAT */
898 return s->ustat;
899 case 0x20: /* SSPRI */
900 return s->sspri;
901 case 0x30: /* SAC */
902 return s->sac;
903 default:
904 cpu_abort(cpu_single_env, "strllaris_adc_read: Bad offset 0x%x\n",
905 (int)offset);
906 return 0;
910 static void stellaris_adc_write(void *opaque, target_phys_addr_t offset,
911 uint32_t value)
913 stellaris_adc_state *s = (stellaris_adc_state *)opaque;
915 /* TODO: Implement this. */
916 offset -= s->base;
917 if (offset >= 0x40 && offset < 0xc0) {
918 int n;
919 n = (offset - 0x40) >> 5;
920 switch (offset & 0x1f) {
921 case 0x00: /* SSMUX */
922 s->ssmux[n] = value & 0x33333333;
923 return;
924 case 0x04: /* SSCTL */
925 if (value != 6) {
926 cpu_abort(cpu_single_env, "ADC: Unimplemented sequence %x\n",
927 value);
929 s->ssctl[n] = value;
930 return;
931 default:
932 break;
935 switch (offset) {
936 case 0x00: /* ACTSS */
937 s->actss = value & 0xf;
938 if (value & 0xe) {
939 cpu_abort(cpu_single_env,
940 "Not implemented: ADC sequencers 1-3\n");
942 break;
943 case 0x08: /* IM */
944 s->im = value;
945 break;
946 case 0x0c: /* ISC */
947 s->ris &= ~value;
948 break;
949 case 0x10: /* OSTAT */
950 s->ostat &= ~value;
951 break;
952 case 0x14: /* EMUX */
953 s->emux = value;
954 break;
955 case 0x18: /* USTAT */
956 s->ustat &= ~value;
957 break;
958 case 0x20: /* SSPRI */
959 s->sspri = value;
960 break;
961 case 0x28: /* PSSI */
962 cpu_abort(cpu_single_env, "Not implemented: ADC sample initiate\n");
963 break;
964 case 0x30: /* SAC */
965 s->sac = value;
966 break;
967 default:
968 cpu_abort(cpu_single_env, "stellaris_adc_write: Bad offset 0x%x\n",
969 (int)offset);
971 stellaris_adc_update(s);
974 static CPUReadMemoryFunc *stellaris_adc_readfn[] = {
975 stellaris_adc_read,
976 stellaris_adc_read,
977 stellaris_adc_read
980 static CPUWriteMemoryFunc *stellaris_adc_writefn[] = {
981 stellaris_adc_write,
982 stellaris_adc_write,
983 stellaris_adc_write
986 static qemu_irq stellaris_adc_init(uint32_t base, qemu_irq irq)
988 stellaris_adc_state *s;
989 int iomemtype;
990 qemu_irq *qi;
992 s = (stellaris_adc_state *)qemu_mallocz(sizeof(stellaris_adc_state));
993 s->base = base;
994 s->irq = irq;
996 iomemtype = cpu_register_io_memory(0, stellaris_adc_readfn,
997 stellaris_adc_writefn, s);
998 cpu_register_physical_memory(base, 0x00001000, iomemtype);
999 stellaris_adc_reset(s);
1000 qi = qemu_allocate_irqs(stellaris_adc_trigger, s, 1);
1001 return qi[0];
1004 /* Some boards have both an OLED controller and SD card connected to
1005 the same SSI port, with the SD card chip select connected to a
1006 GPIO pin. Technically the OLED chip select is connected to the SSI
1007 Fss pin. We do not bother emulating that as both devices should
1008 never be selected simultaneously, and our OLED controller ignores stray
1009 0xff commands that occur when deselecting the SD card. */
1011 typedef struct {
1012 ssi_xfer_cb xfer_cb[2];
1013 void *opaque[2];
1014 qemu_irq irq;
1015 int current_dev;
1016 } stellaris_ssi_bus_state;
1018 static void stellaris_ssi_bus_select(void *opaque, int irq, int level)
1020 stellaris_ssi_bus_state *s = (stellaris_ssi_bus_state *)opaque;
1022 s->current_dev = level;
1025 static int stellaris_ssi_bus_xfer(void *opaque, int val)
1027 stellaris_ssi_bus_state *s = (stellaris_ssi_bus_state *)opaque;
1029 return s->xfer_cb[s->current_dev](s->opaque[s->current_dev], val);
1032 static void *stellaris_ssi_bus_init(qemu_irq *irqp,
1033 ssi_xfer_cb cb0, void *opaque0,
1034 ssi_xfer_cb cb1, void *opaque1)
1036 qemu_irq *qi;
1037 stellaris_ssi_bus_state *s;
1039 s = (stellaris_ssi_bus_state *)qemu_mallocz(sizeof(stellaris_ssi_bus_state));
1040 s->xfer_cb[0] = cb0;
1041 s->opaque[0] = opaque0;
1042 s->xfer_cb[1] = cb1;
1043 s->opaque[1] = opaque1;
1044 qi = qemu_allocate_irqs(stellaris_ssi_bus_select, s, 1);
1045 *irqp = *qi;
1046 return s;
1049 /* Board init. */
1050 static stellaris_board_info stellaris_boards[] = {
1051 { "LM3S811EVB",
1053 0x0032000e,
1054 0x001f001f, /* dc0 */
1055 0x001132bf,
1056 0x01071013,
1057 0x3f0f01ff,
1058 0x0000001f,
1059 BP_OLED_I2C
1061 { "LM3S6965EVB",
1062 0x10010002,
1063 0x1073402e,
1064 0x00ff007f, /* dc0 */
1065 0x001133ff,
1066 0x030f5317,
1067 0x0f0f87ff,
1068 0x5000007f,
1069 BP_OLED_SSI | BP_GAMEPAD
1073 static void stellaris_init(const char *kernel_filename, const char *cpu_model,
1074 DisplayState *ds, stellaris_board_info *board)
1076 static const int uart_irq[] = {5, 6, 33, 34};
1077 static const int timer_irq[] = {19, 21, 23, 35};
1078 static const uint32_t gpio_addr[7] =
1079 { 0x40004000, 0x40005000, 0x40006000, 0x40007000,
1080 0x40024000, 0x40025000, 0x40026000};
1081 static const int gpio_irq[7] = {0, 1, 2, 3, 4, 30, 31};
1083 qemu_irq *pic;
1084 qemu_irq *gpio_in[5];
1085 qemu_irq *gpio_out[5];
1086 qemu_irq adc;
1087 int sram_size;
1088 int flash_size;
1089 i2c_bus *i2c;
1090 int i;
1092 flash_size = ((board->dc0 & 0xffff) + 1) << 1;
1093 sram_size = (board->dc0 >> 18) + 1;
1094 pic = armv7m_init(flash_size, sram_size, kernel_filename, cpu_model);
1096 if (board->dc1 & (1 << 16)) {
1097 adc = stellaris_adc_init(0x40038000, pic[14]);
1098 } else {
1099 adc = NULL;
1101 for (i = 0; i < 4; i++) {
1102 if (board->dc2 & (0x10000 << i)) {
1103 stellaris_gptm_init(0x40030000 + i * 0x1000,
1104 pic[timer_irq[i]], adc);
1108 stellaris_sys_init(0x400fe000, pic[28], board, nd_table[0].macaddr);
1110 for (i = 0; i < 7; i++) {
1111 if (board->dc4 & (1 << i)) {
1112 gpio_in[i] = pl061_init(gpio_addr[i], pic[gpio_irq[i]],
1113 &gpio_out[i]);
1117 if (board->dc2 & (1 << 12)) {
1118 i2c = i2c_init_bus();
1119 stellaris_i2c_init(0x40020000, pic[8], i2c);
1120 if (board->peripherals & BP_OLED_I2C) {
1121 ssd0303_init(ds, i2c, 0x3d);
1125 for (i = 0; i < 4; i++) {
1126 if (board->dc2 & (1 << i)) {
1127 pl011_init(0x4000c000 + i * 0x1000, pic[uart_irq[i]],
1128 serial_hds[i], PL011_LUMINARY);
1131 if (board->dc2 & (1 << 4)) {
1132 if (board->peripherals & BP_OLED_SSI) {
1133 void * oled;
1134 void * sd;
1135 void *ssi_bus;
1136 int index;
1138 oled = ssd0323_init(ds, &gpio_out[GPIO_C][7]);
1139 index = drive_get_index(IF_SD, 0, 0);
1140 sd = ssi_sd_init(drives_table[index].bdrv);
1142 ssi_bus = stellaris_ssi_bus_init(&gpio_out[GPIO_D][0],
1143 ssi_sd_xfer, sd,
1144 ssd0323_xfer_ssi, oled);
1146 pl022_init(0x40008000, pic[7], stellaris_ssi_bus_xfer, ssi_bus);
1147 /* Make sure the select pin is high. */
1148 qemu_irq_raise(gpio_out[GPIO_D][0]);
1149 } else {
1150 pl022_init(0x40008000, pic[7], NULL, NULL);
1153 if (board->dc4 & (1 << 28)) {
1154 /* FIXME: Obey network model. */
1155 stellaris_enet_init(&nd_table[0], 0x40048000, pic[42]);
1157 if (board->peripherals & BP_GAMEPAD) {
1158 qemu_irq gpad_irq[5];
1159 static const int gpad_keycode[5] = { 0xc8, 0xd0, 0xcb, 0xcd, 0x1d };
1161 gpad_irq[0] = qemu_irq_invert(gpio_in[GPIO_E][0]); /* up */
1162 gpad_irq[1] = qemu_irq_invert(gpio_in[GPIO_E][1]); /* down */
1163 gpad_irq[2] = qemu_irq_invert(gpio_in[GPIO_E][2]); /* left */
1164 gpad_irq[3] = qemu_irq_invert(gpio_in[GPIO_E][3]); /* right */
1165 gpad_irq[4] = qemu_irq_invert(gpio_in[GPIO_F][1]); /* select */
1167 stellaris_gamepad_init(5, gpad_irq, gpad_keycode);
1171 /* FIXME: Figure out how to generate these from stellaris_boards. */
1172 static void lm3s811evb_init(ram_addr_t ram_size, int vga_ram_size,
1173 const char *boot_device, DisplayState *ds,
1174 const char *kernel_filename, const char *kernel_cmdline,
1175 const char *initrd_filename, const char *cpu_model)
1177 stellaris_init(kernel_filename, cpu_model, ds, &stellaris_boards[0]);
1180 static void lm3s6965evb_init(ram_addr_t ram_size, int vga_ram_size,
1181 const char *boot_device, DisplayState *ds,
1182 const char *kernel_filename, const char *kernel_cmdline,
1183 const char *initrd_filename, const char *cpu_model)
1185 stellaris_init(kernel_filename, cpu_model, ds, &stellaris_boards[1]);
1188 QEMUMachine lm3s811evb_machine = {
1189 "lm3s811evb",
1190 "Stellaris LM3S811EVB",
1191 lm3s811evb_init,
1192 (64 * 1024 + 8 * 1024) | RAMSIZE_FIXED,
1195 QEMUMachine lm3s6965evb_machine = {
1196 "lm3s6965evb",
1197 "Stellaris LM3S6965EVB",
1198 lm3s6965evb_init,
1199 (256 * 1024 + 64 * 1024) | RAMSIZE_FIXED,