2 * Luminary Micro Stellaris peripherals
4 * Copyright (c) 2006 CodeSourcery.
5 * Written by Paul Brook
7 * This code is licensed under the GPL.
14 #include "qemu-timer.h"
27 #define BP_OLED_I2C 0x01
28 #define BP_OLED_SSI 0x02
29 #define BP_GAMEPAD 0x04
31 typedef const struct {
41 } stellaris_board_info;
43 /* General purpose timer module. */
45 typedef struct gptm_state {
55 uint32_t match_prescale[2];
58 struct gptm_state *opaque[2];
60 /* The timers have an alternate output used to trigger the ADC. */
65 static void gptm_update_irq(gptm_state *s)
68 level = (s->state & s->mask) != 0;
69 qemu_set_irq(s->irq, level);
72 static void gptm_stop(gptm_state *s, int n)
74 qemu_del_timer(s->timer[n]);
77 static void gptm_reload(gptm_state *s, int n, int reset)
81 tick = qemu_get_clock_ns(vm_clock);
86 /* 32-bit CountDown. */
88 count = s->load[0] | (s->load[1] << 16);
89 tick += (int64_t)count * system_clock_scale;
90 } else if (s->config == 1) {
91 /* 32-bit RTC. 1Hz tick. */
92 tick += get_ticks_per_sec();
93 } else if (s->mode[n] == 0xa) {
94 /* PWM mode. Not implemented. */
96 hw_error("TODO: 16-bit timer mode 0x%x\n", s->mode[n]);
99 qemu_mod_timer(s->timer[n], tick);
102 static void gptm_tick(void *opaque)
104 gptm_state **p = (gptm_state **)opaque;
110 if (s->config == 0) {
112 if ((s->control & 0x20)) {
113 /* Output trigger. */
114 qemu_irq_pulse(s->trigger);
116 if (s->mode[0] & 1) {
121 gptm_reload(s, 0, 0);
123 } else if (s->config == 1) {
127 match = s->match[0] | (s->match[1] << 16);
133 gptm_reload(s, 0, 0);
134 } else if (s->mode[n] == 0xa) {
135 /* PWM mode. Not implemented. */
137 hw_error("TODO: 16-bit timer mode 0x%x\n", s->mode[n]);
142 static uint32_t gptm_read(void *opaque, target_phys_addr_t offset)
144 gptm_state *s = (gptm_state *)opaque;
149 case 0x04: /* TAMR */
151 case 0x08: /* TBMR */
160 return s->state & s->mask;
163 case 0x28: /* TAILR */
164 return s->load[0] | ((s->config < 4) ? (s->load[1] << 16) : 0);
165 case 0x2c: /* TBILR */
167 case 0x30: /* TAMARCHR */
168 return s->match[0] | ((s->config < 4) ? (s->match[1] << 16) : 0);
169 case 0x34: /* TBMATCHR */
171 case 0x38: /* TAPR */
172 return s->prescale[0];
173 case 0x3c: /* TBPR */
174 return s->prescale[1];
175 case 0x40: /* TAPMR */
176 return s->match_prescale[0];
177 case 0x44: /* TBPMR */
178 return s->match_prescale[1];
183 hw_error("TODO: Timer value read\n");
185 hw_error("gptm_read: Bad offset 0x%x\n", (int)offset);
190 static void gptm_write(void *opaque, target_phys_addr_t offset, uint32_t value)
192 gptm_state *s = (gptm_state *)opaque;
195 /* The timers should be disabled before changing the configuration.
196 We take advantage of this and defer everything until the timer
202 case 0x04: /* TAMR */
205 case 0x08: /* TBMR */
211 /* TODO: Implement pause. */
212 if ((oldval ^ value) & 1) {
214 gptm_reload(s, 0, 1);
219 if (((oldval ^ value) & 0x100) && s->config >= 4) {
221 gptm_reload(s, 1, 1);
228 s->mask = value & 0x77;
234 case 0x28: /* TAILR */
235 s->load[0] = value & 0xffff;
237 s->load[1] = value >> 16;
240 case 0x2c: /* TBILR */
241 s->load[1] = value & 0xffff;
243 case 0x30: /* TAMARCHR */
244 s->match[0] = value & 0xffff;
246 s->match[1] = value >> 16;
249 case 0x34: /* TBMATCHR */
250 s->match[1] = value >> 16;
252 case 0x38: /* TAPR */
253 s->prescale[0] = value;
255 case 0x3c: /* TBPR */
256 s->prescale[1] = value;
258 case 0x40: /* TAPMR */
259 s->match_prescale[0] = value;
261 case 0x44: /* TBPMR */
262 s->match_prescale[0] = value;
265 hw_error("gptm_write: Bad offset 0x%x\n", (int)offset);
270 static CPUReadMemoryFunc * const gptm_readfn[] = {
276 static CPUWriteMemoryFunc * const gptm_writefn[] = {
282 static const VMStateDescription vmstate_stellaris_gptm = {
283 .name = "stellaris_gptm",
285 .minimum_version_id = 1,
286 .minimum_version_id_old = 1,
287 .fields = (VMStateField[]) {
288 VMSTATE_UINT32(config, gptm_state),
289 VMSTATE_UINT32_ARRAY(mode, gptm_state, 2),
290 VMSTATE_UINT32(control, gptm_state),
291 VMSTATE_UINT32(state, gptm_state),
292 VMSTATE_UINT32(mask, gptm_state),
294 VMSTATE_UINT32_ARRAY(load, gptm_state, 2),
295 VMSTATE_UINT32_ARRAY(match, gptm_state, 2),
296 VMSTATE_UINT32_ARRAY(prescale, gptm_state, 2),
297 VMSTATE_UINT32_ARRAY(match_prescale, gptm_state, 2),
298 VMSTATE_UINT32(rtc, gptm_state),
299 VMSTATE_INT64_ARRAY(tick, gptm_state, 2),
300 VMSTATE_TIMER_ARRAY(timer, gptm_state, 2),
301 VMSTATE_END_OF_LIST()
305 static int stellaris_gptm_init(SysBusDevice *dev)
308 gptm_state *s = FROM_SYSBUS(gptm_state, dev);
310 sysbus_init_irq(dev, &s->irq);
311 qdev_init_gpio_out(&dev->qdev, &s->trigger, 1);
313 iomemtype = cpu_register_io_memory(gptm_readfn,
315 DEVICE_NATIVE_ENDIAN);
316 sysbus_init_mmio(dev, 0x1000, iomemtype);
318 s->opaque[0] = s->opaque[1] = s;
319 s->timer[0] = qemu_new_timer_ns(vm_clock, gptm_tick, &s->opaque[0]);
320 s->timer[1] = qemu_new_timer_ns(vm_clock, gptm_tick, &s->opaque[1]);
321 vmstate_register(&dev->qdev, -1, &vmstate_stellaris_gptm, s);
326 /* System controller. */
344 stellaris_board_info *board;
347 static void ssys_update(ssys_state *s)
349 qemu_set_irq(s->irq, (s->int_status & s->int_mask) != 0);
352 static uint32_t pllcfg_sandstorm[16] = {
354 0x1ae0, /* 1.8432 Mhz */
356 0xd573, /* 2.4576 Mhz */
357 0x37a6, /* 3.57954 Mhz */
358 0x1ae2, /* 3.6864 Mhz */
360 0x98bc, /* 4.906 Mhz */
361 0x935b, /* 4.9152 Mhz */
363 0x4dee, /* 5.12 Mhz */
365 0x75db, /* 6.144 Mhz */
366 0x1ae6, /* 7.3728 Mhz */
368 0x585b /* 8.192 Mhz */
371 static uint32_t pllcfg_fury[16] = {
373 0x1b20, /* 1.8432 Mhz */
375 0xf42b, /* 2.4576 Mhz */
376 0x37e3, /* 3.57954 Mhz */
377 0x1b21, /* 3.6864 Mhz */
379 0x98ee, /* 4.906 Mhz */
380 0xd5b4, /* 4.9152 Mhz */
382 0x4e27, /* 5.12 Mhz */
384 0xec1c, /* 6.144 Mhz */
385 0x1b23, /* 7.3728 Mhz */
387 0xb11c /* 8.192 Mhz */
390 #define DID0_VER_MASK 0x70000000
391 #define DID0_VER_0 0x00000000
392 #define DID0_VER_1 0x10000000
394 #define DID0_CLASS_MASK 0x00FF0000
395 #define DID0_CLASS_SANDSTORM 0x00000000
396 #define DID0_CLASS_FURY 0x00010000
398 static int ssys_board_class(const ssys_state *s)
400 uint32_t did0 = s->board->did0;
401 switch (did0 & DID0_VER_MASK) {
403 return DID0_CLASS_SANDSTORM;
405 switch (did0 & DID0_CLASS_MASK) {
406 case DID0_CLASS_SANDSTORM:
407 case DID0_CLASS_FURY:
408 return did0 & DID0_CLASS_MASK;
410 /* for unknown classes, fall through */
412 hw_error("ssys_board_class: Unknown class 0x%08x\n", did0);
416 static uint32_t ssys_read(void *opaque, target_phys_addr_t offset)
418 ssys_state *s = (ssys_state *)opaque;
421 case 0x000: /* DID0 */
422 return s->board->did0;
423 case 0x004: /* DID1 */
424 return s->board->did1;
425 case 0x008: /* DC0 */
426 return s->board->dc0;
427 case 0x010: /* DC1 */
428 return s->board->dc1;
429 case 0x014: /* DC2 */
430 return s->board->dc2;
431 case 0x018: /* DC3 */
432 return s->board->dc3;
433 case 0x01c: /* DC4 */
434 return s->board->dc4;
435 case 0x030: /* PBORCTL */
437 case 0x034: /* LDOPCTL */
439 case 0x040: /* SRCR0 */
441 case 0x044: /* SRCR1 */
443 case 0x048: /* SRCR2 */
445 case 0x050: /* RIS */
446 return s->int_status;
447 case 0x054: /* IMC */
449 case 0x058: /* MISC */
450 return s->int_status & s->int_mask;
451 case 0x05c: /* RESC */
453 case 0x060: /* RCC */
455 case 0x064: /* PLLCFG */
458 xtal = (s->rcc >> 6) & 0xf;
459 switch (ssys_board_class(s)) {
460 case DID0_CLASS_FURY:
461 return pllcfg_fury[xtal];
462 case DID0_CLASS_SANDSTORM:
463 return pllcfg_sandstorm[xtal];
465 hw_error("ssys_read: Unhandled class for PLLCFG read.\n");
469 case 0x070: /* RCC2 */
471 case 0x100: /* RCGC0 */
473 case 0x104: /* RCGC1 */
475 case 0x108: /* RCGC2 */
477 case 0x110: /* SCGC0 */
479 case 0x114: /* SCGC1 */
481 case 0x118: /* SCGC2 */
483 case 0x120: /* DCGC0 */
485 case 0x124: /* DCGC1 */
487 case 0x128: /* DCGC2 */
489 case 0x150: /* CLKVCLR */
491 case 0x160: /* LDOARST */
493 case 0x1e0: /* USER0 */
495 case 0x1e4: /* USER1 */
498 hw_error("ssys_read: Bad offset 0x%x\n", (int)offset);
503 static bool ssys_use_rcc2(ssys_state *s)
505 return (s->rcc2 >> 31) & 0x1;
509 * Caculate the sys. clock period in ms.
511 static void ssys_calculate_system_clock(ssys_state *s)
513 if (ssys_use_rcc2(s)) {
514 system_clock_scale = 5 * (((s->rcc2 >> 23) & 0x3f) + 1);
516 system_clock_scale = 5 * (((s->rcc >> 23) & 0xf) + 1);
520 static void ssys_write(void *opaque, target_phys_addr_t offset, uint32_t value)
522 ssys_state *s = (ssys_state *)opaque;
525 case 0x030: /* PBORCTL */
526 s->pborctl = value & 0xffff;
528 case 0x034: /* LDOPCTL */
529 s->ldopctl = value & 0x1f;
531 case 0x040: /* SRCR0 */
532 case 0x044: /* SRCR1 */
533 case 0x048: /* SRCR2 */
534 fprintf(stderr, "Peripheral reset not implemented\n");
536 case 0x054: /* IMC */
537 s->int_mask = value & 0x7f;
539 case 0x058: /* MISC */
540 s->int_status &= ~value;
542 case 0x05c: /* RESC */
543 s->resc = value & 0x3f;
545 case 0x060: /* RCC */
546 if ((s->rcc & (1 << 13)) != 0 && (value & (1 << 13)) == 0) {
548 s->int_status |= (1 << 6);
551 ssys_calculate_system_clock(s);
553 case 0x070: /* RCC2 */
554 if (ssys_board_class(s) == DID0_CLASS_SANDSTORM) {
558 if ((s->rcc2 & (1 << 13)) != 0 && (value & (1 << 13)) == 0) {
560 s->int_status |= (1 << 6);
563 ssys_calculate_system_clock(s);
565 case 0x100: /* RCGC0 */
568 case 0x104: /* RCGC1 */
571 case 0x108: /* RCGC2 */
574 case 0x110: /* SCGC0 */
577 case 0x114: /* SCGC1 */
580 case 0x118: /* SCGC2 */
583 case 0x120: /* DCGC0 */
586 case 0x124: /* DCGC1 */
589 case 0x128: /* DCGC2 */
592 case 0x150: /* CLKVCLR */
595 case 0x160: /* LDOARST */
599 hw_error("ssys_write: Bad offset 0x%x\n", (int)offset);
604 static CPUReadMemoryFunc * const ssys_readfn[] = {
610 static CPUWriteMemoryFunc * const ssys_writefn[] = {
616 static void ssys_reset(void *opaque)
618 ssys_state *s = (ssys_state *)opaque;
623 if (ssys_board_class(s) == DID0_CLASS_SANDSTORM) {
626 s->rcc2 = 0x07802810;
633 static int stellaris_sys_post_load(void *opaque, int version_id)
635 ssys_state *s = opaque;
637 ssys_calculate_system_clock(s);
642 static const VMStateDescription vmstate_stellaris_sys = {
643 .name = "stellaris_sys",
645 .minimum_version_id = 1,
646 .minimum_version_id_old = 1,
647 .post_load = stellaris_sys_post_load,
648 .fields = (VMStateField[]) {
649 VMSTATE_UINT32(pborctl, ssys_state),
650 VMSTATE_UINT32(ldopctl, ssys_state),
651 VMSTATE_UINT32(int_mask, ssys_state),
652 VMSTATE_UINT32(int_status, ssys_state),
653 VMSTATE_UINT32(resc, ssys_state),
654 VMSTATE_UINT32(rcc, ssys_state),
655 VMSTATE_UINT32_V(rcc2, ssys_state, 2),
656 VMSTATE_UINT32_ARRAY(rcgc, ssys_state, 3),
657 VMSTATE_UINT32_ARRAY(scgc, ssys_state, 3),
658 VMSTATE_UINT32_ARRAY(dcgc, ssys_state, 3),
659 VMSTATE_UINT32(clkvclr, ssys_state),
660 VMSTATE_UINT32(ldoarst, ssys_state),
661 VMSTATE_END_OF_LIST()
665 static int stellaris_sys_init(uint32_t base, qemu_irq irq,
666 stellaris_board_info * board,
672 s = (ssys_state *)g_malloc0(sizeof(ssys_state));
675 /* Most devices come preprogrammed with a MAC address in the user data. */
676 s->user0 = macaddr[0] | (macaddr[1] << 8) | (macaddr[2] << 16);
677 s->user1 = macaddr[3] | (macaddr[4] << 8) | (macaddr[5] << 16);
679 iomemtype = cpu_register_io_memory(ssys_readfn,
681 DEVICE_NATIVE_ENDIAN);
682 cpu_register_physical_memory(base, 0x00001000, iomemtype);
684 vmstate_register(NULL, -1, &vmstate_stellaris_sys, s);
689 /* I2C controller. */
702 } stellaris_i2c_state;
704 #define STELLARIS_I2C_MCS_BUSY 0x01
705 #define STELLARIS_I2C_MCS_ERROR 0x02
706 #define STELLARIS_I2C_MCS_ADRACK 0x04
707 #define STELLARIS_I2C_MCS_DATACK 0x08
708 #define STELLARIS_I2C_MCS_ARBLST 0x10
709 #define STELLARIS_I2C_MCS_IDLE 0x20
710 #define STELLARIS_I2C_MCS_BUSBSY 0x40
712 static uint32_t stellaris_i2c_read(void *opaque, target_phys_addr_t offset)
714 stellaris_i2c_state *s = (stellaris_i2c_state *)opaque;
720 /* We don't emulate timing, so the controller is never busy. */
721 return s->mcs | STELLARIS_I2C_MCS_IDLE;
724 case 0x0c: /* MTPR */
726 case 0x10: /* MIMR */
728 case 0x14: /* MRIS */
730 case 0x18: /* MMIS */
731 return s->mris & s->mimr;
735 hw_error("strllaris_i2c_read: Bad offset 0x%x\n", (int)offset);
740 static void stellaris_i2c_update(stellaris_i2c_state *s)
744 level = (s->mris & s->mimr) != 0;
745 qemu_set_irq(s->irq, level);
748 static void stellaris_i2c_write(void *opaque, target_phys_addr_t offset,
751 stellaris_i2c_state *s = (stellaris_i2c_state *)opaque;
755 s->msa = value & 0xff;
758 if ((s->mcr & 0x10) == 0) {
759 /* Disabled. Do nothing. */
762 /* Grab the bus if this is starting a transfer. */
763 if ((value & 2) && (s->mcs & STELLARIS_I2C_MCS_BUSBSY) == 0) {
764 if (i2c_start_transfer(s->bus, s->msa >> 1, s->msa & 1)) {
765 s->mcs |= STELLARIS_I2C_MCS_ARBLST;
767 s->mcs &= ~STELLARIS_I2C_MCS_ARBLST;
768 s->mcs |= STELLARIS_I2C_MCS_BUSBSY;
771 /* If we don't have the bus then indicate an error. */
772 if (!i2c_bus_busy(s->bus)
773 || (s->mcs & STELLARIS_I2C_MCS_BUSBSY) == 0) {
774 s->mcs |= STELLARIS_I2C_MCS_ERROR;
777 s->mcs &= ~STELLARIS_I2C_MCS_ERROR;
779 /* Transfer a byte. */
780 /* TODO: Handle errors. */
783 s->mdr = i2c_recv(s->bus) & 0xff;
786 i2c_send(s->bus, s->mdr);
788 /* Raise an interrupt. */
792 /* Finish transfer. */
793 i2c_end_transfer(s->bus);
794 s->mcs &= ~STELLARIS_I2C_MCS_BUSBSY;
798 s->mdr = value & 0xff;
800 case 0x0c: /* MTPR */
801 s->mtpr = value & 0xff;
803 case 0x10: /* MIMR */
806 case 0x1c: /* MICR */
812 "stellaris_i2c_write: Loopback not implemented\n");
815 "stellaris_i2c_write: Slave mode not implemented\n");
816 s->mcr = value & 0x31;
819 hw_error("stellaris_i2c_write: Bad offset 0x%x\n",
822 stellaris_i2c_update(s);
825 static void stellaris_i2c_reset(stellaris_i2c_state *s)
827 if (s->mcs & STELLARIS_I2C_MCS_BUSBSY)
828 i2c_end_transfer(s->bus);
837 stellaris_i2c_update(s);
840 static CPUReadMemoryFunc * const stellaris_i2c_readfn[] = {
846 static CPUWriteMemoryFunc * const stellaris_i2c_writefn[] = {
852 static const VMStateDescription vmstate_stellaris_i2c = {
853 .name = "stellaris_i2c",
855 .minimum_version_id = 1,
856 .minimum_version_id_old = 1,
857 .fields = (VMStateField[]) {
858 VMSTATE_UINT32(msa, stellaris_i2c_state),
859 VMSTATE_UINT32(mcs, stellaris_i2c_state),
860 VMSTATE_UINT32(mdr, stellaris_i2c_state),
861 VMSTATE_UINT32(mtpr, stellaris_i2c_state),
862 VMSTATE_UINT32(mimr, stellaris_i2c_state),
863 VMSTATE_UINT32(mris, stellaris_i2c_state),
864 VMSTATE_UINT32(mcr, stellaris_i2c_state),
865 VMSTATE_END_OF_LIST()
869 static int stellaris_i2c_init(SysBusDevice * dev)
871 stellaris_i2c_state *s = FROM_SYSBUS(stellaris_i2c_state, dev);
875 sysbus_init_irq(dev, &s->irq);
876 bus = i2c_init_bus(&dev->qdev, "i2c");
879 iomemtype = cpu_register_io_memory(stellaris_i2c_readfn,
880 stellaris_i2c_writefn, s,
881 DEVICE_NATIVE_ENDIAN);
882 sysbus_init_mmio(dev, 0x1000, iomemtype);
883 /* ??? For now we only implement the master interface. */
884 stellaris_i2c_reset(s);
885 vmstate_register(&dev->qdev, -1, &vmstate_stellaris_i2c, s);
889 /* Analogue to Digital Converter. This is only partially implemented,
890 enough for applications that use a combined ADC and timer tick. */
892 #define STELLARIS_ADC_EM_CONTROLLER 0
893 #define STELLARIS_ADC_EM_COMP 1
894 #define STELLARIS_ADC_EM_EXTERNAL 4
895 #define STELLARIS_ADC_EM_TIMER 5
896 #define STELLARIS_ADC_EM_PWM0 6
897 #define STELLARIS_ADC_EM_PWM1 7
898 #define STELLARIS_ADC_EM_PWM2 8
900 #define STELLARIS_ADC_FIFO_EMPTY 0x0100
901 #define STELLARIS_ADC_FIFO_FULL 0x1000
922 } stellaris_adc_state;
924 static uint32_t stellaris_adc_fifo_read(stellaris_adc_state *s, int n)
928 tail = s->fifo[n].state & 0xf;
929 if (s->fifo[n].state & STELLARIS_ADC_FIFO_EMPTY) {
932 s->fifo[n].state = (s->fifo[n].state & ~0xf) | ((tail + 1) & 0xf);
933 s->fifo[n].state &= ~STELLARIS_ADC_FIFO_FULL;
934 if (tail + 1 == ((s->fifo[n].state >> 4) & 0xf))
935 s->fifo[n].state |= STELLARIS_ADC_FIFO_EMPTY;
937 return s->fifo[n].data[tail];
940 static void stellaris_adc_fifo_write(stellaris_adc_state *s, int n,
945 /* TODO: Real hardware has limited size FIFOs. We have a full 16 entry
946 FIFO fir each sequencer. */
947 head = (s->fifo[n].state >> 4) & 0xf;
948 if (s->fifo[n].state & STELLARIS_ADC_FIFO_FULL) {
952 s->fifo[n].data[head] = value;
953 head = (head + 1) & 0xf;
954 s->fifo[n].state &= ~STELLARIS_ADC_FIFO_EMPTY;
955 s->fifo[n].state = (s->fifo[n].state & ~0xf0) | (head << 4);
956 if ((s->fifo[n].state & 0xf) == head)
957 s->fifo[n].state |= STELLARIS_ADC_FIFO_FULL;
960 static void stellaris_adc_update(stellaris_adc_state *s)
965 for (n = 0; n < 4; n++) {
966 level = (s->ris & s->im & (1 << n)) != 0;
967 qemu_set_irq(s->irq[n], level);
971 static void stellaris_adc_trigger(void *opaque, int irq, int level)
973 stellaris_adc_state *s = (stellaris_adc_state *)opaque;
976 for (n = 0; n < 4; n++) {
977 if ((s->actss & (1 << n)) == 0) {
981 if (((s->emux >> (n * 4)) & 0xff) != 5) {
985 /* Some applications use the ADC as a random number source, so introduce
986 some variation into the signal. */
987 s->noise = s->noise * 314159 + 1;
988 /* ??? actual inputs not implemented. Return an arbitrary value. */
989 stellaris_adc_fifo_write(s, n, 0x200 + ((s->noise >> 16) & 7));
991 stellaris_adc_update(s);
995 static void stellaris_adc_reset(stellaris_adc_state *s)
999 for (n = 0; n < 4; n++) {
1002 s->fifo[n].state = STELLARIS_ADC_FIFO_EMPTY;
1006 static uint32_t stellaris_adc_read(void *opaque, target_phys_addr_t offset)
1008 stellaris_adc_state *s = (stellaris_adc_state *)opaque;
1010 /* TODO: Implement this. */
1011 if (offset >= 0x40 && offset < 0xc0) {
1013 n = (offset - 0x40) >> 5;
1014 switch (offset & 0x1f) {
1015 case 0x00: /* SSMUX */
1017 case 0x04: /* SSCTL */
1019 case 0x08: /* SSFIFO */
1020 return stellaris_adc_fifo_read(s, n);
1021 case 0x0c: /* SSFSTAT */
1022 return s->fifo[n].state;
1028 case 0x00: /* ACTSS */
1030 case 0x04: /* RIS */
1034 case 0x0c: /* ISC */
1035 return s->ris & s->im;
1036 case 0x10: /* OSTAT */
1038 case 0x14: /* EMUX */
1040 case 0x18: /* USTAT */
1042 case 0x20: /* SSPRI */
1044 case 0x30: /* SAC */
1047 hw_error("strllaris_adc_read: Bad offset 0x%x\n",
1053 static void stellaris_adc_write(void *opaque, target_phys_addr_t offset,
1056 stellaris_adc_state *s = (stellaris_adc_state *)opaque;
1058 /* TODO: Implement this. */
1059 if (offset >= 0x40 && offset < 0xc0) {
1061 n = (offset - 0x40) >> 5;
1062 switch (offset & 0x1f) {
1063 case 0x00: /* SSMUX */
1064 s->ssmux[n] = value & 0x33333333;
1066 case 0x04: /* SSCTL */
1068 hw_error("ADC: Unimplemented sequence %x\n",
1071 s->ssctl[n] = value;
1078 case 0x00: /* ACTSS */
1079 s->actss = value & 0xf;
1084 case 0x0c: /* ISC */
1087 case 0x10: /* OSTAT */
1090 case 0x14: /* EMUX */
1093 case 0x18: /* USTAT */
1096 case 0x20: /* SSPRI */
1099 case 0x28: /* PSSI */
1100 hw_error("Not implemented: ADC sample initiate\n");
1102 case 0x30: /* SAC */
1106 hw_error("stellaris_adc_write: Bad offset 0x%x\n", (int)offset);
1108 stellaris_adc_update(s);
1111 static CPUReadMemoryFunc * const stellaris_adc_readfn[] = {
1117 static CPUWriteMemoryFunc * const stellaris_adc_writefn[] = {
1118 stellaris_adc_write,
1119 stellaris_adc_write,
1123 static const VMStateDescription vmstate_stellaris_adc = {
1124 .name = "stellaris_adc",
1126 .minimum_version_id = 1,
1127 .minimum_version_id_old = 1,
1128 .fields = (VMStateField[]) {
1129 VMSTATE_UINT32(actss, stellaris_adc_state),
1130 VMSTATE_UINT32(ris, stellaris_adc_state),
1131 VMSTATE_UINT32(im, stellaris_adc_state),
1132 VMSTATE_UINT32(emux, stellaris_adc_state),
1133 VMSTATE_UINT32(ostat, stellaris_adc_state),
1134 VMSTATE_UINT32(ustat, stellaris_adc_state),
1135 VMSTATE_UINT32(sspri, stellaris_adc_state),
1136 VMSTATE_UINT32(sac, stellaris_adc_state),
1137 VMSTATE_UINT32(fifo[0].state, stellaris_adc_state),
1138 VMSTATE_UINT32_ARRAY(fifo[0].data, stellaris_adc_state, 16),
1139 VMSTATE_UINT32(ssmux[0], stellaris_adc_state),
1140 VMSTATE_UINT32(ssctl[0], stellaris_adc_state),
1141 VMSTATE_UINT32(fifo[1].state, stellaris_adc_state),
1142 VMSTATE_UINT32_ARRAY(fifo[1].data, stellaris_adc_state, 16),
1143 VMSTATE_UINT32(ssmux[1], stellaris_adc_state),
1144 VMSTATE_UINT32(ssctl[1], stellaris_adc_state),
1145 VMSTATE_UINT32(fifo[2].state, stellaris_adc_state),
1146 VMSTATE_UINT32_ARRAY(fifo[2].data, stellaris_adc_state, 16),
1147 VMSTATE_UINT32(ssmux[2], stellaris_adc_state),
1148 VMSTATE_UINT32(ssctl[2], stellaris_adc_state),
1149 VMSTATE_UINT32(fifo[3].state, stellaris_adc_state),
1150 VMSTATE_UINT32_ARRAY(fifo[3].data, stellaris_adc_state, 16),
1151 VMSTATE_UINT32(ssmux[3], stellaris_adc_state),
1152 VMSTATE_UINT32(ssctl[3], stellaris_adc_state),
1153 VMSTATE_UINT32(noise, stellaris_adc_state),
1154 VMSTATE_END_OF_LIST()
1158 static int stellaris_adc_init(SysBusDevice *dev)
1160 stellaris_adc_state *s = FROM_SYSBUS(stellaris_adc_state, dev);
1164 for (n = 0; n < 4; n++) {
1165 sysbus_init_irq(dev, &s->irq[n]);
1168 iomemtype = cpu_register_io_memory(stellaris_adc_readfn,
1169 stellaris_adc_writefn, s,
1170 DEVICE_NATIVE_ENDIAN);
1171 sysbus_init_mmio(dev, 0x1000, iomemtype);
1172 stellaris_adc_reset(s);
1173 qdev_init_gpio_in(&dev->qdev, stellaris_adc_trigger, 1);
1174 vmstate_register(&dev->qdev, -1, &vmstate_stellaris_adc, s);
1178 /* Some boards have both an OLED controller and SD card connected to
1179 the same SSI port, with the SD card chip select connected to a
1180 GPIO pin. Technically the OLED chip select is connected to the SSI
1181 Fss pin. We do not bother emulating that as both devices should
1182 never be selected simultaneously, and our OLED controller ignores stray
1183 0xff commands that occur when deselecting the SD card. */
1190 } stellaris_ssi_bus_state;
1192 static void stellaris_ssi_bus_select(void *opaque, int irq, int level)
1194 stellaris_ssi_bus_state *s = (stellaris_ssi_bus_state *)opaque;
1196 s->current_dev = level;
1199 static uint32_t stellaris_ssi_bus_transfer(SSISlave *dev, uint32_t val)
1201 stellaris_ssi_bus_state *s = FROM_SSI_SLAVE(stellaris_ssi_bus_state, dev);
1203 return ssi_transfer(s->bus[s->current_dev], val);
1206 static const VMStateDescription vmstate_stellaris_ssi_bus = {
1207 .name = "stellaris_ssi_bus",
1209 .minimum_version_id = 1,
1210 .minimum_version_id_old = 1,
1211 .fields = (VMStateField[]) {
1212 VMSTATE_INT32(current_dev, stellaris_ssi_bus_state),
1213 VMSTATE_END_OF_LIST()
1217 static int stellaris_ssi_bus_init(SSISlave *dev)
1219 stellaris_ssi_bus_state *s = FROM_SSI_SLAVE(stellaris_ssi_bus_state, dev);
1221 s->bus[0] = ssi_create_bus(&dev->qdev, "ssi0");
1222 s->bus[1] = ssi_create_bus(&dev->qdev, "ssi1");
1223 qdev_init_gpio_in(&dev->qdev, stellaris_ssi_bus_select, 1);
1225 vmstate_register(&dev->qdev, -1, &vmstate_stellaris_ssi_bus, s);
1230 static stellaris_board_info stellaris_boards[] = {
1234 0x001f001f, /* dc0 */
1244 0x00ff007f, /* dc0 */
1249 BP_OLED_SSI | BP_GAMEPAD
1253 static void stellaris_init(const char *kernel_filename, const char *cpu_model,
1254 stellaris_board_info *board)
1256 static const int uart_irq[] = {5, 6, 33, 34};
1257 static const int timer_irq[] = {19, 21, 23, 35};
1258 static const uint32_t gpio_addr[7] =
1259 { 0x40004000, 0x40005000, 0x40006000, 0x40007000,
1260 0x40024000, 0x40025000, 0x40026000};
1261 static const int gpio_irq[7] = {0, 1, 2, 3, 4, 30, 31};
1264 DeviceState *gpio_dev[7];
1265 qemu_irq gpio_in[7][8];
1266 qemu_irq gpio_out[7][8];
1275 flash_size = ((board->dc0 & 0xffff) + 1) << 1;
1276 sram_size = (board->dc0 >> 18) + 1;
1277 pic = armv7m_init(flash_size, sram_size, kernel_filename, cpu_model);
1279 if (board->dc1 & (1 << 16)) {
1280 dev = sysbus_create_varargs("stellaris-adc", 0x40038000,
1281 pic[14], pic[15], pic[16], pic[17], NULL);
1282 adc = qdev_get_gpio_in(dev, 0);
1286 for (i = 0; i < 4; i++) {
1287 if (board->dc2 & (0x10000 << i)) {
1288 dev = sysbus_create_simple("stellaris-gptm",
1289 0x40030000 + i * 0x1000,
1291 /* TODO: This is incorrect, but we get away with it because
1292 the ADC output is only ever pulsed. */
1293 qdev_connect_gpio_out(dev, 0, adc);
1297 stellaris_sys_init(0x400fe000, pic[28], board, nd_table[0].macaddr.a);
1299 for (i = 0; i < 7; i++) {
1300 if (board->dc4 & (1 << i)) {
1301 gpio_dev[i] = sysbus_create_simple("pl061_luminary", gpio_addr[i],
1303 for (j = 0; j < 8; j++) {
1304 gpio_in[i][j] = qdev_get_gpio_in(gpio_dev[i], j);
1305 gpio_out[i][j] = NULL;
1310 if (board->dc2 & (1 << 12)) {
1311 dev = sysbus_create_simple("stellaris-i2c", 0x40020000, pic[8]);
1312 i2c = (i2c_bus *)qdev_get_child_bus(dev, "i2c");
1313 if (board->peripherals & BP_OLED_I2C) {
1314 i2c_create_slave(i2c, "ssd0303", 0x3d);
1318 for (i = 0; i < 4; i++) {
1319 if (board->dc2 & (1 << i)) {
1320 sysbus_create_simple("pl011_luminary", 0x4000c000 + i * 0x1000,
1324 if (board->dc2 & (1 << 4)) {
1325 dev = sysbus_create_simple("pl022", 0x40008000, pic[7]);
1326 if (board->peripherals & BP_OLED_SSI) {
1330 bus = qdev_get_child_bus(dev, "ssi");
1331 mux = ssi_create_slave(bus, "evb6965-ssi");
1332 gpio_out[GPIO_D][0] = qdev_get_gpio_in(mux, 0);
1334 bus = qdev_get_child_bus(mux, "ssi0");
1335 ssi_create_slave(bus, "ssi-sd");
1337 bus = qdev_get_child_bus(mux, "ssi1");
1338 dev = ssi_create_slave(bus, "ssd0323");
1339 gpio_out[GPIO_C][7] = qdev_get_gpio_in(dev, 0);
1341 /* Make sure the select pin is high. */
1342 qemu_irq_raise(gpio_out[GPIO_D][0]);
1345 if (board->dc4 & (1 << 28)) {
1348 qemu_check_nic_model(&nd_table[0], "stellaris");
1350 enet = qdev_create(NULL, "stellaris_enet");
1351 qdev_set_nic_properties(enet, &nd_table[0]);
1352 qdev_init_nofail(enet);
1353 sysbus_mmio_map(sysbus_from_qdev(enet), 0, 0x40048000);
1354 sysbus_connect_irq(sysbus_from_qdev(enet), 0, pic[42]);
1356 if (board->peripherals & BP_GAMEPAD) {
1357 qemu_irq gpad_irq[5];
1358 static const int gpad_keycode[5] = { 0xc8, 0xd0, 0xcb, 0xcd, 0x1d };
1360 gpad_irq[0] = qemu_irq_invert(gpio_in[GPIO_E][0]); /* up */
1361 gpad_irq[1] = qemu_irq_invert(gpio_in[GPIO_E][1]); /* down */
1362 gpad_irq[2] = qemu_irq_invert(gpio_in[GPIO_E][2]); /* left */
1363 gpad_irq[3] = qemu_irq_invert(gpio_in[GPIO_E][3]); /* right */
1364 gpad_irq[4] = qemu_irq_invert(gpio_in[GPIO_F][1]); /* select */
1366 stellaris_gamepad_init(5, gpad_irq, gpad_keycode);
1368 for (i = 0; i < 7; i++) {
1369 if (board->dc4 & (1 << i)) {
1370 for (j = 0; j < 8; j++) {
1371 if (gpio_out[i][j]) {
1372 qdev_connect_gpio_out(gpio_dev[i], j, gpio_out[i][j]);
1379 /* FIXME: Figure out how to generate these from stellaris_boards. */
1380 static void lm3s811evb_init(ram_addr_t ram_size,
1381 const char *boot_device,
1382 const char *kernel_filename, const char *kernel_cmdline,
1383 const char *initrd_filename, const char *cpu_model)
1385 stellaris_init(kernel_filename, cpu_model, &stellaris_boards[0]);
1388 static void lm3s6965evb_init(ram_addr_t ram_size,
1389 const char *boot_device,
1390 const char *kernel_filename, const char *kernel_cmdline,
1391 const char *initrd_filename, const char *cpu_model)
1393 stellaris_init(kernel_filename, cpu_model, &stellaris_boards[1]);
1396 static QEMUMachine lm3s811evb_machine = {
1397 .name = "lm3s811evb",
1398 .desc = "Stellaris LM3S811EVB",
1399 .init = lm3s811evb_init,
1402 static QEMUMachine lm3s6965evb_machine = {
1403 .name = "lm3s6965evb",
1404 .desc = "Stellaris LM3S6965EVB",
1405 .init = lm3s6965evb_init,
1408 static void stellaris_machine_init(void)
1410 qemu_register_machine(&lm3s811evb_machine);
1411 qemu_register_machine(&lm3s6965evb_machine);
1414 machine_init(stellaris_machine_init);
1416 static SSISlaveInfo stellaris_ssi_bus_info = {
1417 .qdev.name = "evb6965-ssi",
1418 .qdev.size = sizeof(stellaris_ssi_bus_state),
1419 .init = stellaris_ssi_bus_init,
1420 .transfer = stellaris_ssi_bus_transfer
1423 static void stellaris_register_devices(void)
1425 sysbus_register_dev("stellaris-i2c", sizeof(stellaris_i2c_state),
1426 stellaris_i2c_init);
1427 sysbus_register_dev("stellaris-gptm", sizeof(gptm_state),
1428 stellaris_gptm_init);
1429 sysbus_register_dev("stellaris-adc", sizeof(stellaris_adc_state),
1430 stellaris_adc_init);
1431 ssi_register_slave(&stellaris_ssi_bus_info);
1434 device_init(stellaris_register_devices)