2 * Luminary Micro Stellaris peripherals
4 * Copyright (c) 2006 CodeSourcery.
5 * Written by Paul Brook
7 * This code is licenced under the GPL.
12 #include "primecell.h"
14 #include "qemu-timer.h"
29 #define BP_OLED_I2C 0x01
30 #define BP_OLED_SSI 0x02
31 #define BP_GAMEPAD 0x04
33 typedef const struct {
43 } stellaris_board_info
;
45 /* General purpose timer module. */
47 typedef struct gptm_state
{
56 uint32_t match_prescale
[2];
59 struct gptm_state
*opaque
[2];
62 /* The timers have an alternate output used to trigger the ADC. */
67 static void gptm_update_irq(gptm_state
*s
)
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
)
83 tick
= qemu_get_clock(vm_clock
);
88 /* 32-bit CountDown. */
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. */
98 cpu_abort(cpu_single_env
, "TODO: 16-bit timer mode 0x%x\n",
102 qemu_mod_timer(s
->timer
[n
], tick
);
105 static void gptm_tick(void *opaque
)
107 gptm_state
**p
= (gptm_state
**)opaque
;
113 if (s
->config
== 0) {
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) {
125 gptm_reload(s
, 0, 0);
127 } else if (s
->config
== 1) {
131 match
= s
->match
[0] | (s
->match
[1] << 16);
137 gptm_reload(s
, 0, 0);
138 } else if (s
->mode
[n
] == 0xa) {
139 /* PWM mode. Not implemented. */
141 cpu_abort(cpu_single_env
, "TODO: 16-bit timer mode 0x%x\n",
147 static uint32_t gptm_read(void *opaque
, target_phys_addr_t offset
)
149 gptm_state
*s
= (gptm_state
*)opaque
;
155 case 0x04: /* TAMR */
157 case 0x08: /* TBMR */
166 return s
->state
& s
->mask
;
169 case 0x28: /* TAILR */
170 return s
->load
[0] | ((s
->config
< 4) ? (s
->load
[1] << 16) : 0);
171 case 0x2c: /* TBILR */
173 case 0x30: /* TAMARCHR */
174 return s
->match
[0] | ((s
->config
< 4) ? (s
->match
[1] << 16) : 0);
175 case 0x34: /* TBMATCHR */
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];
189 cpu_abort(cpu_single_env
, "TODO: Timer value read\n");
191 cpu_abort(cpu_single_env
, "gptm_read: Bad offset 0x%x\n", (int)offset
);
196 static void gptm_write(void *opaque
, target_phys_addr_t offset
, uint32_t value
)
198 gptm_state
*s
= (gptm_state
*)opaque
;
202 /* The timers should be disabled before changing the configuration.
203 We take advantage of this and defer everything until the timer
209 case 0x04: /* TAMR */
212 case 0x08: /* TBMR */
218 /* TODO: Implement pause. */
219 if ((oldval
^ value
) & 1) {
221 gptm_reload(s
, 0, 1);
226 if (((oldval
^ value
) & 0x100) && s
->config
>= 4) {
228 gptm_reload(s
, 1, 1);
235 s
->mask
= value
& 0x77;
241 case 0x28: /* TAILR */
242 s
->load
[0] = value
& 0xffff;
244 s
->load
[1] = value
>> 16;
247 case 0x2c: /* TBILR */
248 s
->load
[1] = value
& 0xffff;
250 case 0x30: /* TAMARCHR */
251 s
->match
[0] = value
& 0xffff;
253 s
->match
[1] = value
>> 16;
256 case 0x34: /* TBMATCHR */
257 s
->match
[1] = value
>> 16;
259 case 0x38: /* TAPR */
260 s
->prescale
[0] = value
;
262 case 0x3c: /* TBPR */
263 s
->prescale
[1] = value
;
265 case 0x40: /* TAPMR */
266 s
->match_prescale
[0] = value
;
268 case 0x44: /* TBPMR */
269 s
->match_prescale
[0] = value
;
272 cpu_abort(cpu_single_env
, "gptm_write: Bad offset 0x%x\n", (int)offset
);
277 static CPUReadMemoryFunc
*gptm_readfn
[] = {
283 static CPUWriteMemoryFunc
*gptm_writefn
[] = {
289 static void gptm_save(QEMUFile
*f
, void *opaque
)
291 gptm_state
*s
= (gptm_state
*)opaque
;
293 qemu_put_be32(f
, s
->config
);
294 qemu_put_be32(f
, s
->mode
[0]);
295 qemu_put_be32(f
, s
->mode
[1]);
296 qemu_put_be32(f
, s
->control
);
297 qemu_put_be32(f
, s
->state
);
298 qemu_put_be32(f
, s
->mask
);
299 qemu_put_be32(f
, s
->mode
[0]);
300 qemu_put_be32(f
, s
->mode
[0]);
301 qemu_put_be32(f
, s
->load
[0]);
302 qemu_put_be32(f
, s
->load
[1]);
303 qemu_put_be32(f
, s
->match
[0]);
304 qemu_put_be32(f
, s
->match
[1]);
305 qemu_put_be32(f
, s
->prescale
[0]);
306 qemu_put_be32(f
, s
->prescale
[1]);
307 qemu_put_be32(f
, s
->match_prescale
[0]);
308 qemu_put_be32(f
, s
->match_prescale
[1]);
309 qemu_put_be32(f
, s
->rtc
);
310 qemu_put_be64(f
, s
->tick
[0]);
311 qemu_put_be64(f
, s
->tick
[1]);
312 qemu_put_timer(f
, s
->timer
[0]);
313 qemu_put_timer(f
, s
->timer
[1]);
316 static int gptm_load(QEMUFile
*f
, void *opaque
, int version_id
)
318 gptm_state
*s
= (gptm_state
*)opaque
;
323 s
->config
= qemu_get_be32(f
);
324 s
->mode
[0] = qemu_get_be32(f
);
325 s
->mode
[1] = qemu_get_be32(f
);
326 s
->control
= qemu_get_be32(f
);
327 s
->state
= qemu_get_be32(f
);
328 s
->mask
= qemu_get_be32(f
);
329 s
->mode
[0] = qemu_get_be32(f
);
330 s
->mode
[0] = qemu_get_be32(f
);
331 s
->load
[0] = qemu_get_be32(f
);
332 s
->load
[1] = qemu_get_be32(f
);
333 s
->match
[0] = qemu_get_be32(f
);
334 s
->match
[1] = qemu_get_be32(f
);
335 s
->prescale
[0] = qemu_get_be32(f
);
336 s
->prescale
[1] = qemu_get_be32(f
);
337 s
->match_prescale
[0] = qemu_get_be32(f
);
338 s
->match_prescale
[1] = qemu_get_be32(f
);
339 s
->rtc
= qemu_get_be32(f
);
340 s
->tick
[0] = qemu_get_be64(f
);
341 s
->tick
[1] = qemu_get_be64(f
);
342 qemu_get_timer(f
, s
->timer
[0]);
343 qemu_get_timer(f
, s
->timer
[1]);
348 static void stellaris_gptm_init(uint32_t base
, qemu_irq irq
, qemu_irq trigger
)
353 s
= (gptm_state
*)qemu_mallocz(sizeof(gptm_state
));
356 s
->trigger
= trigger
;
357 s
->opaque
[0] = s
->opaque
[1] = s
;
359 iomemtype
= cpu_register_io_memory(0, gptm_readfn
,
361 cpu_register_physical_memory(base
, 0x00001000, iomemtype
);
362 s
->timer
[0] = qemu_new_timer(vm_clock
, gptm_tick
, &s
->opaque
[0]);
363 s
->timer
[1] = qemu_new_timer(vm_clock
, gptm_tick
, &s
->opaque
[1]);
364 register_savevm("stellaris_gptm", -1, 1, gptm_save
, gptm_load
, s
);
368 /* System controller. */
386 stellaris_board_info
*board
;
389 static void ssys_update(ssys_state
*s
)
391 qemu_set_irq(s
->irq
, (s
->int_status
& s
->int_mask
) != 0);
394 static uint32_t pllcfg_sandstorm
[16] = {
396 0x1ae0, /* 1.8432 Mhz */
398 0xd573, /* 2.4576 Mhz */
399 0x37a6, /* 3.57954 Mhz */
400 0x1ae2, /* 3.6864 Mhz */
402 0x98bc, /* 4.906 Mhz */
403 0x935b, /* 4.9152 Mhz */
405 0x4dee, /* 5.12 Mhz */
407 0x75db, /* 6.144 Mhz */
408 0x1ae6, /* 7.3728 Mhz */
410 0x585b /* 8.192 Mhz */
413 static uint32_t pllcfg_fury
[16] = {
415 0x1b20, /* 1.8432 Mhz */
417 0xf42b, /* 2.4576 Mhz */
418 0x37e3, /* 3.57954 Mhz */
419 0x1b21, /* 3.6864 Mhz */
421 0x98ee, /* 4.906 Mhz */
422 0xd5b4, /* 4.9152 Mhz */
424 0x4e27, /* 5.12 Mhz */
426 0xec1c, /* 6.144 Mhz */
427 0x1b23, /* 7.3728 Mhz */
429 0xb11c /* 8.192 Mhz */
432 static uint32_t ssys_read(void *opaque
, target_phys_addr_t offset
)
434 ssys_state
*s
= (ssys_state
*)opaque
;
438 case 0x000: /* DID0 */
439 return s
->board
->did0
;
440 case 0x004: /* DID1 */
441 return s
->board
->did1
;
442 case 0x008: /* DC0 */
443 return s
->board
->dc0
;
444 case 0x010: /* DC1 */
445 return s
->board
->dc1
;
446 case 0x014: /* DC2 */
447 return s
->board
->dc2
;
448 case 0x018: /* DC3 */
449 return s
->board
->dc3
;
450 case 0x01c: /* DC4 */
451 return s
->board
->dc4
;
452 case 0x030: /* PBORCTL */
454 case 0x034: /* LDOPCTL */
456 case 0x040: /* SRCR0 */
458 case 0x044: /* SRCR1 */
460 case 0x048: /* SRCR2 */
462 case 0x050: /* RIS */
463 return s
->int_status
;
464 case 0x054: /* IMC */
466 case 0x058: /* MISC */
467 return s
->int_status
& s
->int_mask
;
468 case 0x05c: /* RESC */
470 case 0x060: /* RCC */
472 case 0x064: /* PLLCFG */
475 xtal
= (s
->rcc
>> 6) & 0xf;
476 if (s
->board
->did0
& (1 << 16)) {
477 return pllcfg_fury
[xtal
];
479 return pllcfg_sandstorm
[xtal
];
482 case 0x100: /* RCGC0 */
484 case 0x104: /* RCGC1 */
486 case 0x108: /* RCGC2 */
488 case 0x110: /* SCGC0 */
490 case 0x114: /* SCGC1 */
492 case 0x118: /* SCGC2 */
494 case 0x120: /* DCGC0 */
496 case 0x124: /* DCGC1 */
498 case 0x128: /* DCGC2 */
500 case 0x150: /* CLKVCLR */
502 case 0x160: /* LDOARST */
504 case 0x1e0: /* USER0 */
506 case 0x1e4: /* USER1 */
509 cpu_abort(cpu_single_env
, "ssys_read: Bad offset 0x%x\n", (int)offset
);
514 static void ssys_calculate_system_clock(ssys_state
*s
)
516 system_clock_scale
= 5 * (((s
->rcc
>> 23) & 0xf) + 1);
519 static void ssys_write(void *opaque
, target_phys_addr_t offset
, uint32_t value
)
521 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 0x100: /* RCGC0 */
556 case 0x104: /* RCGC1 */
559 case 0x108: /* RCGC2 */
562 case 0x110: /* SCGC0 */
565 case 0x114: /* SCGC1 */
568 case 0x118: /* SCGC2 */
571 case 0x120: /* DCGC0 */
574 case 0x124: /* DCGC1 */
577 case 0x128: /* DCGC2 */
580 case 0x150: /* CLKVCLR */
583 case 0x160: /* LDOARST */
587 cpu_abort(cpu_single_env
, "ssys_write: Bad offset 0x%x\n", (int)offset
);
592 static CPUReadMemoryFunc
*ssys_readfn
[] = {
598 static CPUWriteMemoryFunc
*ssys_writefn
[] = {
604 static void ssys_reset(void *opaque
)
606 ssys_state
*s
= (ssys_state
*)opaque
;
615 static void ssys_save(QEMUFile
*f
, void *opaque
)
617 ssys_state
*s
= (ssys_state
*)opaque
;
619 qemu_put_be32(f
, s
->pborctl
);
620 qemu_put_be32(f
, s
->ldopctl
);
621 qemu_put_be32(f
, s
->int_mask
);
622 qemu_put_be32(f
, s
->int_status
);
623 qemu_put_be32(f
, s
->resc
);
624 qemu_put_be32(f
, s
->rcc
);
625 qemu_put_be32(f
, s
->rcgc
[0]);
626 qemu_put_be32(f
, s
->rcgc
[1]);
627 qemu_put_be32(f
, s
->rcgc
[2]);
628 qemu_put_be32(f
, s
->scgc
[0]);
629 qemu_put_be32(f
, s
->scgc
[1]);
630 qemu_put_be32(f
, s
->scgc
[2]);
631 qemu_put_be32(f
, s
->dcgc
[0]);
632 qemu_put_be32(f
, s
->dcgc
[1]);
633 qemu_put_be32(f
, s
->dcgc
[2]);
634 qemu_put_be32(f
, s
->clkvclr
);
635 qemu_put_be32(f
, s
->ldoarst
);
638 static int ssys_load(QEMUFile
*f
, void *opaque
, int version_id
)
640 ssys_state
*s
= (ssys_state
*)opaque
;
645 s
->pborctl
= qemu_get_be32(f
);
646 s
->ldopctl
= qemu_get_be32(f
);
647 s
->int_mask
= qemu_get_be32(f
);
648 s
->int_status
= qemu_get_be32(f
);
649 s
->resc
= qemu_get_be32(f
);
650 s
->rcc
= qemu_get_be32(f
);
651 s
->rcgc
[0] = qemu_get_be32(f
);
652 s
->rcgc
[1] = qemu_get_be32(f
);
653 s
->rcgc
[2] = qemu_get_be32(f
);
654 s
->scgc
[0] = qemu_get_be32(f
);
655 s
->scgc
[1] = qemu_get_be32(f
);
656 s
->scgc
[2] = qemu_get_be32(f
);
657 s
->dcgc
[0] = qemu_get_be32(f
);
658 s
->dcgc
[1] = qemu_get_be32(f
);
659 s
->dcgc
[2] = qemu_get_be32(f
);
660 s
->clkvclr
= qemu_get_be32(f
);
661 s
->ldoarst
= qemu_get_be32(f
);
662 ssys_calculate_system_clock(s
);
667 static void stellaris_sys_init(uint32_t base
, qemu_irq irq
,
668 stellaris_board_info
* board
,
674 s
= (ssys_state
*)qemu_mallocz(sizeof(ssys_state
));
678 /* Most devices come preprogrammed with a MAC address in the user data. */
679 s
->user0
= macaddr
[0] | (macaddr
[1] << 8) | (macaddr
[2] << 16);
680 s
->user1
= macaddr
[3] | (macaddr
[4] << 8) | (macaddr
[5] << 16);
682 iomemtype
= cpu_register_io_memory(0, ssys_readfn
,
684 cpu_register_physical_memory(base
, 0x00001000, iomemtype
);
686 register_savevm("stellaris_sys", -1, 1, ssys_save
, ssys_load
, s
);
690 /* I2C controller. */
703 } stellaris_i2c_state
;
705 #define STELLARIS_I2C_MCS_BUSY 0x01
706 #define STELLARIS_I2C_MCS_ERROR 0x02
707 #define STELLARIS_I2C_MCS_ADRACK 0x04
708 #define STELLARIS_I2C_MCS_DATACK 0x08
709 #define STELLARIS_I2C_MCS_ARBLST 0x10
710 #define STELLARIS_I2C_MCS_IDLE 0x20
711 #define STELLARIS_I2C_MCS_BUSBSY 0x40
713 static uint32_t stellaris_i2c_read(void *opaque
, target_phys_addr_t offset
)
715 stellaris_i2c_state
*s
= (stellaris_i2c_state
*)opaque
;
722 /* We don't emulate timing, so the controller is never busy. */
723 return s
->mcs
| STELLARIS_I2C_MCS_IDLE
;
726 case 0x0c: /* MTPR */
728 case 0x10: /* MIMR */
730 case 0x14: /* MRIS */
732 case 0x18: /* MMIS */
733 return s
->mris
& s
->mimr
;
737 cpu_abort(cpu_single_env
, "strllaris_i2c_read: Bad offset 0x%x\n",
743 static void stellaris_i2c_update(stellaris_i2c_state
*s
)
747 level
= (s
->mris
& s
->mimr
) != 0;
748 qemu_set_irq(s
->irq
, level
);
751 static void stellaris_i2c_write(void *opaque
, target_phys_addr_t offset
,
754 stellaris_i2c_state
*s
= (stellaris_i2c_state
*)opaque
;
759 s
->msa
= value
& 0xff;
762 if ((s
->mcr
& 0x10) == 0) {
763 /* Disabled. Do nothing. */
766 /* Grab the bus if this is starting a transfer. */
767 if ((value
& 2) && (s
->mcs
& STELLARIS_I2C_MCS_BUSBSY
) == 0) {
768 if (i2c_start_transfer(s
->bus
, s
->msa
>> 1, s
->msa
& 1)) {
769 s
->mcs
|= STELLARIS_I2C_MCS_ARBLST
;
771 s
->mcs
&= ~STELLARIS_I2C_MCS_ARBLST
;
772 s
->mcs
|= STELLARIS_I2C_MCS_BUSBSY
;
775 /* If we don't have the bus then indicate an error. */
776 if (!i2c_bus_busy(s
->bus
)
777 || (s
->mcs
& STELLARIS_I2C_MCS_BUSBSY
) == 0) {
778 s
->mcs
|= STELLARIS_I2C_MCS_ERROR
;
781 s
->mcs
&= ~STELLARIS_I2C_MCS_ERROR
;
783 /* Transfer a byte. */
784 /* TODO: Handle errors. */
787 s
->mdr
= i2c_recv(s
->bus
) & 0xff;
790 i2c_send(s
->bus
, s
->mdr
);
792 /* Raise an interrupt. */
796 /* Finish transfer. */
797 i2c_end_transfer(s
->bus
);
798 s
->mcs
&= ~STELLARIS_I2C_MCS_BUSBSY
;
802 s
->mdr
= value
& 0xff;
804 case 0x0c: /* MTPR */
805 s
->mtpr
= value
& 0xff;
807 case 0x10: /* MIMR */
810 case 0x1c: /* MICR */
815 cpu_abort(cpu_single_env
,
816 "stellaris_i2c_write: Loopback not implemented\n");
818 cpu_abort(cpu_single_env
,
819 "stellaris_i2c_write: Slave mode not implemented\n");
820 s
->mcr
= value
& 0x31;
823 cpu_abort(cpu_single_env
, "stellaris_i2c_write: Bad offset 0x%x\n",
826 stellaris_i2c_update(s
);
829 static void stellaris_i2c_reset(stellaris_i2c_state
*s
)
831 if (s
->mcs
& STELLARIS_I2C_MCS_BUSBSY
)
832 i2c_end_transfer(s
->bus
);
841 stellaris_i2c_update(s
);
844 static CPUReadMemoryFunc
*stellaris_i2c_readfn
[] = {
850 static CPUWriteMemoryFunc
*stellaris_i2c_writefn
[] = {
856 static void stellaris_i2c_save(QEMUFile
*f
, void *opaque
)
858 stellaris_i2c_state
*s
= (stellaris_i2c_state
*)opaque
;
860 qemu_put_be32(f
, s
->msa
);
861 qemu_put_be32(f
, s
->mcs
);
862 qemu_put_be32(f
, s
->mdr
);
863 qemu_put_be32(f
, s
->mtpr
);
864 qemu_put_be32(f
, s
->mimr
);
865 qemu_put_be32(f
, s
->mris
);
866 qemu_put_be32(f
, s
->mcr
);
869 static int stellaris_i2c_load(QEMUFile
*f
, void *opaque
, int version_id
)
871 stellaris_i2c_state
*s
= (stellaris_i2c_state
*)opaque
;
876 s
->msa
= qemu_get_be32(f
);
877 s
->mcs
= qemu_get_be32(f
);
878 s
->mdr
= qemu_get_be32(f
);
879 s
->mtpr
= qemu_get_be32(f
);
880 s
->mimr
= qemu_get_be32(f
);
881 s
->mris
= qemu_get_be32(f
);
882 s
->mcr
= qemu_get_be32(f
);
887 static void stellaris_i2c_init(uint32_t base
, qemu_irq irq
, i2c_bus
*bus
)
889 stellaris_i2c_state
*s
;
892 s
= (stellaris_i2c_state
*)qemu_mallocz(sizeof(stellaris_i2c_state
));
897 iomemtype
= cpu_register_io_memory(0, stellaris_i2c_readfn
,
898 stellaris_i2c_writefn
, s
);
899 cpu_register_physical_memory(base
, 0x00001000, iomemtype
);
900 /* ??? For now we only implement the master interface. */
901 stellaris_i2c_reset(s
);
902 register_savevm("stellaris_i2c", -1, 1,
903 stellaris_i2c_save
, stellaris_i2c_load
, s
);
906 /* Analogue to Digital Converter. This is only partially implemented,
907 enough for applications that use a combined ADC and timer tick. */
909 #define STELLARIS_ADC_EM_CONTROLLER 0
910 #define STELLARIS_ADC_EM_COMP 1
911 #define STELLARIS_ADC_EM_EXTERNAL 4
912 #define STELLARIS_ADC_EM_TIMER 5
913 #define STELLARIS_ADC_EM_PWM0 6
914 #define STELLARIS_ADC_EM_PWM1 7
915 #define STELLARIS_ADC_EM_PWM2 8
917 #define STELLARIS_ADC_FIFO_EMPTY 0x0100
918 #define STELLARIS_ADC_FIFO_FULL 0x1000
939 } stellaris_adc_state
;
941 static uint32_t stellaris_adc_fifo_read(stellaris_adc_state
*s
, int n
)
945 tail
= s
->fifo
[n
].state
& 0xf;
946 if (s
->fifo
[n
].state
& STELLARIS_ADC_FIFO_EMPTY
) {
949 s
->fifo
[n
].state
= (s
->fifo
[n
].state
& ~0xf) | ((tail
+ 1) & 0xf);
950 s
->fifo
[n
].state
&= ~STELLARIS_ADC_FIFO_FULL
;
951 if (tail
+ 1 == ((s
->fifo
[n
].state
>> 4) & 0xf))
952 s
->fifo
[n
].state
|= STELLARIS_ADC_FIFO_EMPTY
;
954 return s
->fifo
[n
].data
[tail
];
957 static void stellaris_adc_fifo_write(stellaris_adc_state
*s
, int n
,
962 head
= (s
->fifo
[n
].state
>> 4) & 0xf;
963 if (s
->fifo
[n
].state
& STELLARIS_ADC_FIFO_FULL
) {
967 s
->fifo
[n
].data
[head
] = value
;
968 head
= (head
+ 1) & 0xf;
969 s
->fifo
[n
].state
&= ~STELLARIS_ADC_FIFO_EMPTY
;
970 s
->fifo
[n
].state
= (s
->fifo
[n
].state
& ~0xf0) | (head
<< 4);
971 if ((s
->fifo
[n
].state
& 0xf) == head
)
972 s
->fifo
[n
].state
|= STELLARIS_ADC_FIFO_FULL
;
975 static void stellaris_adc_update(stellaris_adc_state
*s
)
979 level
= (s
->ris
& s
->im
) != 0;
980 qemu_set_irq(s
->irq
, level
);
983 static void stellaris_adc_trigger(void *opaque
, int irq
, int level
)
985 stellaris_adc_state
*s
= (stellaris_adc_state
*)opaque
;
987 if ((s
->actss
& 1) == 0) {
991 /* Some applications use the ADC as a random number source, so introduce
992 some variation into the signal. */
993 s
->noise
= s
->noise
* 314159 + 1;
994 /* ??? actual inputs not implemented. Return an arbitrary value. */
995 stellaris_adc_fifo_write(s
, 0, 0x200 + ((s
->noise
>> 16) & 7));
997 stellaris_adc_update(s
);
1000 static void stellaris_adc_reset(stellaris_adc_state
*s
)
1004 for (n
= 0; n
< 4; n
++) {
1007 s
->fifo
[n
].state
= STELLARIS_ADC_FIFO_EMPTY
;
1011 static uint32_t stellaris_adc_read(void *opaque
, target_phys_addr_t offset
)
1013 stellaris_adc_state
*s
= (stellaris_adc_state
*)opaque
;
1015 /* TODO: Implement this. */
1017 if (offset
>= 0x40 && offset
< 0xc0) {
1019 n
= (offset
- 0x40) >> 5;
1020 switch (offset
& 0x1f) {
1021 case 0x00: /* SSMUX */
1023 case 0x04: /* SSCTL */
1025 case 0x08: /* SSFIFO */
1026 return stellaris_adc_fifo_read(s
, n
);
1027 case 0x0c: /* SSFSTAT */
1028 return s
->fifo
[n
].state
;
1034 case 0x00: /* ACTSS */
1036 case 0x04: /* RIS */
1040 case 0x0c: /* ISC */
1041 return s
->ris
& s
->im
;
1042 case 0x10: /* OSTAT */
1044 case 0x14: /* EMUX */
1046 case 0x18: /* USTAT */
1048 case 0x20: /* SSPRI */
1050 case 0x30: /* SAC */
1053 cpu_abort(cpu_single_env
, "strllaris_adc_read: Bad offset 0x%x\n",
1059 static void stellaris_adc_write(void *opaque
, target_phys_addr_t offset
,
1062 stellaris_adc_state
*s
= (stellaris_adc_state
*)opaque
;
1064 /* TODO: Implement this. */
1066 if (offset
>= 0x40 && offset
< 0xc0) {
1068 n
= (offset
- 0x40) >> 5;
1069 switch (offset
& 0x1f) {
1070 case 0x00: /* SSMUX */
1071 s
->ssmux
[n
] = value
& 0x33333333;
1073 case 0x04: /* SSCTL */
1075 cpu_abort(cpu_single_env
, "ADC: Unimplemented sequence %x\n",
1078 s
->ssctl
[n
] = value
;
1085 case 0x00: /* ACTSS */
1086 s
->actss
= value
& 0xf;
1088 cpu_abort(cpu_single_env
,
1089 "Not implemented: ADC sequencers 1-3\n");
1095 case 0x0c: /* ISC */
1098 case 0x10: /* OSTAT */
1101 case 0x14: /* EMUX */
1104 case 0x18: /* USTAT */
1107 case 0x20: /* SSPRI */
1110 case 0x28: /* PSSI */
1111 cpu_abort(cpu_single_env
, "Not implemented: ADC sample initiate\n");
1113 case 0x30: /* SAC */
1117 cpu_abort(cpu_single_env
, "stellaris_adc_write: Bad offset 0x%x\n",
1120 stellaris_adc_update(s
);
1123 static CPUReadMemoryFunc
*stellaris_adc_readfn
[] = {
1129 static CPUWriteMemoryFunc
*stellaris_adc_writefn
[] = {
1130 stellaris_adc_write
,
1131 stellaris_adc_write
,
1135 static void stellaris_adc_save(QEMUFile
*f
, void *opaque
)
1137 stellaris_adc_state
*s
= (stellaris_adc_state
*)opaque
;
1141 qemu_put_be32(f
, s
->actss
);
1142 qemu_put_be32(f
, s
->ris
);
1143 qemu_put_be32(f
, s
->im
);
1144 qemu_put_be32(f
, s
->emux
);
1145 qemu_put_be32(f
, s
->ostat
);
1146 qemu_put_be32(f
, s
->ustat
);
1147 qemu_put_be32(f
, s
->sspri
);
1148 qemu_put_be32(f
, s
->sac
);
1149 for (i
= 0; i
< 4; i
++) {
1150 qemu_put_be32(f
, s
->fifo
[i
].state
);
1151 for (j
= 0; j
< 16; j
++) {
1152 qemu_put_be32(f
, s
->fifo
[i
].data
[j
]);
1154 qemu_put_be32(f
, s
->ssmux
[i
]);
1155 qemu_put_be32(f
, s
->ssctl
[i
]);
1157 qemu_put_be32(f
, s
->noise
);
1160 static int stellaris_adc_load(QEMUFile
*f
, void *opaque
, int version_id
)
1162 stellaris_adc_state
*s
= (stellaris_adc_state
*)opaque
;
1166 if (version_id
!= 1)
1169 s
->actss
= qemu_get_be32(f
);
1170 s
->ris
= qemu_get_be32(f
);
1171 s
->im
= qemu_get_be32(f
);
1172 s
->emux
= qemu_get_be32(f
);
1173 s
->ostat
= qemu_get_be32(f
);
1174 s
->ustat
= qemu_get_be32(f
);
1175 s
->sspri
= qemu_get_be32(f
);
1176 s
->sac
= qemu_get_be32(f
);
1177 for (i
= 0; i
< 4; i
++) {
1178 s
->fifo
[i
].state
= qemu_get_be32(f
);
1179 for (j
= 0; j
< 16; j
++) {
1180 s
->fifo
[i
].data
[j
] = qemu_get_be32(f
);
1182 s
->ssmux
[i
] = qemu_get_be32(f
);
1183 s
->ssctl
[i
] = qemu_get_be32(f
);
1185 s
->noise
= qemu_get_be32(f
);
1190 static qemu_irq
stellaris_adc_init(uint32_t base
, qemu_irq irq
)
1192 stellaris_adc_state
*s
;
1196 s
= (stellaris_adc_state
*)qemu_mallocz(sizeof(stellaris_adc_state
));
1200 iomemtype
= cpu_register_io_memory(0, stellaris_adc_readfn
,
1201 stellaris_adc_writefn
, s
);
1202 cpu_register_physical_memory(base
, 0x00001000, iomemtype
);
1203 stellaris_adc_reset(s
);
1204 qi
= qemu_allocate_irqs(stellaris_adc_trigger
, s
, 1);
1205 register_savevm("stellaris_adc", -1, 1,
1206 stellaris_adc_save
, stellaris_adc_load
, s
);
1210 /* Some boards have both an OLED controller and SD card connected to
1211 the same SSI port, with the SD card chip select connected to a
1212 GPIO pin. Technically the OLED chip select is connected to the SSI
1213 Fss pin. We do not bother emulating that as both devices should
1214 never be selected simultaneously, and our OLED controller ignores stray
1215 0xff commands that occur when deselecting the SD card. */
1218 ssi_xfer_cb xfer_cb
[2];
1222 } stellaris_ssi_bus_state
;
1224 static void stellaris_ssi_bus_select(void *opaque
, int irq
, int level
)
1226 stellaris_ssi_bus_state
*s
= (stellaris_ssi_bus_state
*)opaque
;
1228 s
->current_dev
= level
;
1231 static int stellaris_ssi_bus_xfer(void *opaque
, int val
)
1233 stellaris_ssi_bus_state
*s
= (stellaris_ssi_bus_state
*)opaque
;
1235 return s
->xfer_cb
[s
->current_dev
](s
->opaque
[s
->current_dev
], val
);
1238 static void stellaris_ssi_bus_save(QEMUFile
*f
, void *opaque
)
1240 stellaris_ssi_bus_state
*s
= (stellaris_ssi_bus_state
*)opaque
;
1242 qemu_put_be32(f
, s
->current_dev
);
1245 static int stellaris_ssi_bus_load(QEMUFile
*f
, void *opaque
, int version_id
)
1247 stellaris_ssi_bus_state
*s
= (stellaris_ssi_bus_state
*)opaque
;
1249 if (version_id
!= 1)
1252 s
->current_dev
= qemu_get_be32(f
);
1257 static void *stellaris_ssi_bus_init(qemu_irq
*irqp
,
1258 ssi_xfer_cb cb0
, void *opaque0
,
1259 ssi_xfer_cb cb1
, void *opaque1
)
1262 stellaris_ssi_bus_state
*s
;
1264 s
= (stellaris_ssi_bus_state
*)qemu_mallocz(sizeof(stellaris_ssi_bus_state
));
1265 s
->xfer_cb
[0] = cb0
;
1266 s
->opaque
[0] = opaque0
;
1267 s
->xfer_cb
[1] = cb1
;
1268 s
->opaque
[1] = opaque1
;
1269 qi
= qemu_allocate_irqs(stellaris_ssi_bus_select
, s
, 1);
1271 register_savevm("stellaris_ssi_bus", -1, 1,
1272 stellaris_ssi_bus_save
, stellaris_ssi_bus_load
, s
);
1277 static stellaris_board_info stellaris_boards
[] = {
1281 0x001f001f, /* dc0 */
1291 0x00ff007f, /* dc0 */
1296 BP_OLED_SSI
| BP_GAMEPAD
1300 static void stellaris_init(const char *kernel_filename
, const char *cpu_model
,
1301 DisplayState
*ds
, stellaris_board_info
*board
)
1303 static const int uart_irq
[] = {5, 6, 33, 34};
1304 static const int timer_irq
[] = {19, 21, 23, 35};
1305 static const uint32_t gpio_addr
[7] =
1306 { 0x40004000, 0x40005000, 0x40006000, 0x40007000,
1307 0x40024000, 0x40025000, 0x40026000};
1308 static const int gpio_irq
[7] = {0, 1, 2, 3, 4, 30, 31};
1311 qemu_irq
*gpio_in
[7];
1312 qemu_irq
*gpio_out
[7];
1319 flash_size
= ((board
->dc0
& 0xffff) + 1) << 1;
1320 sram_size
= (board
->dc0
>> 18) + 1;
1321 pic
= armv7m_init(flash_size
, sram_size
, kernel_filename
, cpu_model
);
1323 if (board
->dc1
& (1 << 16)) {
1324 adc
= stellaris_adc_init(0x40038000, pic
[14]);
1328 for (i
= 0; i
< 4; i
++) {
1329 if (board
->dc2
& (0x10000 << i
)) {
1330 stellaris_gptm_init(0x40030000 + i
* 0x1000,
1331 pic
[timer_irq
[i
]], adc
);
1335 stellaris_sys_init(0x400fe000, pic
[28], board
, nd_table
[0].macaddr
);
1337 for (i
= 0; i
< 7; i
++) {
1338 if (board
->dc4
& (1 << i
)) {
1339 gpio_in
[i
] = pl061_init(gpio_addr
[i
], pic
[gpio_irq
[i
]],
1344 if (board
->dc2
& (1 << 12)) {
1345 i2c
= i2c_init_bus();
1346 stellaris_i2c_init(0x40020000, pic
[8], i2c
);
1347 if (board
->peripherals
& BP_OLED_I2C
) {
1348 ssd0303_init(ds
, i2c
, 0x3d);
1352 for (i
= 0; i
< 4; i
++) {
1353 if (board
->dc2
& (1 << i
)) {
1354 pl011_init(0x4000c000 + i
* 0x1000, pic
[uart_irq
[i
]],
1355 serial_hds
[i
], PL011_LUMINARY
);
1358 if (board
->dc2
& (1 << 4)) {
1359 if (board
->peripherals
& BP_OLED_SSI
) {
1365 oled
= ssd0323_init(ds
, &gpio_out
[GPIO_C
][7]);
1366 index
= drive_get_index(IF_SD
, 0, 0);
1367 sd
= ssi_sd_init(drives_table
[index
].bdrv
);
1369 ssi_bus
= stellaris_ssi_bus_init(&gpio_out
[GPIO_D
][0],
1371 ssd0323_xfer_ssi
, oled
);
1373 pl022_init(0x40008000, pic
[7], stellaris_ssi_bus_xfer
, ssi_bus
);
1374 /* Make sure the select pin is high. */
1375 qemu_irq_raise(gpio_out
[GPIO_D
][0]);
1377 pl022_init(0x40008000, pic
[7], NULL
, NULL
);
1380 if (board
->dc4
& (1 << 28)) {
1381 /* FIXME: Obey network model. */
1382 stellaris_enet_init(&nd_table
[0], 0x40048000, pic
[42]);
1384 if (board
->peripherals
& BP_GAMEPAD
) {
1385 qemu_irq gpad_irq
[5];
1386 static const int gpad_keycode
[5] = { 0xc8, 0xd0, 0xcb, 0xcd, 0x1d };
1388 gpad_irq
[0] = qemu_irq_invert(gpio_in
[GPIO_E
][0]); /* up */
1389 gpad_irq
[1] = qemu_irq_invert(gpio_in
[GPIO_E
][1]); /* down */
1390 gpad_irq
[2] = qemu_irq_invert(gpio_in
[GPIO_E
][2]); /* left */
1391 gpad_irq
[3] = qemu_irq_invert(gpio_in
[GPIO_E
][3]); /* right */
1392 gpad_irq
[4] = qemu_irq_invert(gpio_in
[GPIO_F
][1]); /* select */
1394 stellaris_gamepad_init(5, gpad_irq
, gpad_keycode
);
1398 /* FIXME: Figure out how to generate these from stellaris_boards. */
1399 static void lm3s811evb_init(ram_addr_t ram_size
, int vga_ram_size
,
1400 const char *boot_device
, DisplayState
*ds
,
1401 const char *kernel_filename
, const char *kernel_cmdline
,
1402 const char *initrd_filename
, const char *cpu_model
)
1404 stellaris_init(kernel_filename
, cpu_model
, ds
, &stellaris_boards
[0]);
1407 static void lm3s6965evb_init(ram_addr_t ram_size
, int vga_ram_size
,
1408 const char *boot_device
, DisplayState
*ds
,
1409 const char *kernel_filename
, const char *kernel_cmdline
,
1410 const char *initrd_filename
, const char *cpu_model
)
1412 stellaris_init(kernel_filename
, cpu_model
, ds
, &stellaris_boards
[1]);
1415 QEMUMachine lm3s811evb_machine
= {
1417 "Stellaris LM3S811EVB",
1419 (64 * 1024 + 8 * 1024) | RAMSIZE_FIXED
,
1422 QEMUMachine lm3s6965evb_machine
= {
1424 "Stellaris LM3S6965EVB",
1426 (256 * 1024 + 64 * 1024) | RAMSIZE_FIXED
,