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];
61 /* The timers have an alternate output used to trigger the ADC. */
66 static void gptm_update_irq(gptm_state
*s
)
69 level
= (s
->state
& s
->mask
) != 0;
70 qemu_set_irq(s
->irq
, level
);
73 static void gptm_stop(gptm_state
*s
, int n
)
75 qemu_del_timer(s
->timer
[n
]);
78 static void gptm_reload(gptm_state
*s
, int n
, int reset
)
82 tick
= qemu_get_clock(vm_clock
);
87 /* 32-bit CountDown. */
89 count
= s
->load
[0] | (s
->load
[1] << 16);
90 tick
+= (int64_t)count
* system_clock_scale
;
91 } else if (s
->config
== 1) {
92 /* 32-bit RTC. 1Hz tick. */
93 tick
+= ticks_per_sec
;
94 } else if (s
->mode
[n
] == 0xa) {
95 /* PWM mode. Not implemented. */
97 hw_error("TODO: 16-bit timer mode 0x%x\n", s
->mode
[n
]);
100 qemu_mod_timer(s
->timer
[n
], tick
);
103 static void gptm_tick(void *opaque
)
105 gptm_state
**p
= (gptm_state
**)opaque
;
111 if (s
->config
== 0) {
113 if ((s
->control
& 0x20)) {
114 /* Output trigger. */
115 qemu_irq_raise(s
->trigger
);
116 qemu_irq_lower(s
->trigger
);
118 if (s
->mode
[0] & 1) {
123 gptm_reload(s
, 0, 0);
125 } else if (s
->config
== 1) {
129 match
= s
->match
[0] | (s
->match
[1] << 16);
135 gptm_reload(s
, 0, 0);
136 } else if (s
->mode
[n
] == 0xa) {
137 /* PWM mode. Not implemented. */
139 hw_error("TODO: 16-bit timer mode 0x%x\n", s
->mode
[n
]);
144 static uint32_t gptm_read(void *opaque
, target_phys_addr_t offset
)
146 gptm_state
*s
= (gptm_state
*)opaque
;
151 case 0x04: /* TAMR */
153 case 0x08: /* TBMR */
162 return s
->state
& s
->mask
;
165 case 0x28: /* TAILR */
166 return s
->load
[0] | ((s
->config
< 4) ? (s
->load
[1] << 16) : 0);
167 case 0x2c: /* TBILR */
169 case 0x30: /* TAMARCHR */
170 return s
->match
[0] | ((s
->config
< 4) ? (s
->match
[1] << 16) : 0);
171 case 0x34: /* TBMATCHR */
173 case 0x38: /* TAPR */
174 return s
->prescale
[0];
175 case 0x3c: /* TBPR */
176 return s
->prescale
[1];
177 case 0x40: /* TAPMR */
178 return s
->match_prescale
[0];
179 case 0x44: /* TBPMR */
180 return s
->match_prescale
[1];
185 hw_error("TODO: Timer value read\n");
187 hw_error("gptm_read: Bad offset 0x%x\n", (int)offset
);
192 static void gptm_write(void *opaque
, target_phys_addr_t offset
, uint32_t value
)
194 gptm_state
*s
= (gptm_state
*)opaque
;
197 /* The timers should be disabled before changing the configuration.
198 We take advantage of this and defer everything until the timer
204 case 0x04: /* TAMR */
207 case 0x08: /* TBMR */
213 /* TODO: Implement pause. */
214 if ((oldval
^ value
) & 1) {
216 gptm_reload(s
, 0, 1);
221 if (((oldval
^ value
) & 0x100) && s
->config
>= 4) {
223 gptm_reload(s
, 1, 1);
230 s
->mask
= value
& 0x77;
236 case 0x28: /* TAILR */
237 s
->load
[0] = value
& 0xffff;
239 s
->load
[1] = value
>> 16;
242 case 0x2c: /* TBILR */
243 s
->load
[1] = value
& 0xffff;
245 case 0x30: /* TAMARCHR */
246 s
->match
[0] = value
& 0xffff;
248 s
->match
[1] = value
>> 16;
251 case 0x34: /* TBMATCHR */
252 s
->match
[1] = value
>> 16;
254 case 0x38: /* TAPR */
255 s
->prescale
[0] = value
;
257 case 0x3c: /* TBPR */
258 s
->prescale
[1] = value
;
260 case 0x40: /* TAPMR */
261 s
->match_prescale
[0] = value
;
263 case 0x44: /* TBPMR */
264 s
->match_prescale
[0] = value
;
267 hw_error("gptm_write: Bad offset 0x%x\n", (int)offset
);
272 static CPUReadMemoryFunc
*gptm_readfn
[] = {
278 static CPUWriteMemoryFunc
*gptm_writefn
[] = {
284 static void gptm_save(QEMUFile
*f
, void *opaque
)
286 gptm_state
*s
= (gptm_state
*)opaque
;
288 qemu_put_be32(f
, s
->config
);
289 qemu_put_be32(f
, s
->mode
[0]);
290 qemu_put_be32(f
, s
->mode
[1]);
291 qemu_put_be32(f
, s
->control
);
292 qemu_put_be32(f
, s
->state
);
293 qemu_put_be32(f
, s
->mask
);
294 qemu_put_be32(f
, s
->mode
[0]);
295 qemu_put_be32(f
, s
->mode
[0]);
296 qemu_put_be32(f
, s
->load
[0]);
297 qemu_put_be32(f
, s
->load
[1]);
298 qemu_put_be32(f
, s
->match
[0]);
299 qemu_put_be32(f
, s
->match
[1]);
300 qemu_put_be32(f
, s
->prescale
[0]);
301 qemu_put_be32(f
, s
->prescale
[1]);
302 qemu_put_be32(f
, s
->match_prescale
[0]);
303 qemu_put_be32(f
, s
->match_prescale
[1]);
304 qemu_put_be32(f
, s
->rtc
);
305 qemu_put_be64(f
, s
->tick
[0]);
306 qemu_put_be64(f
, s
->tick
[1]);
307 qemu_put_timer(f
, s
->timer
[0]);
308 qemu_put_timer(f
, s
->timer
[1]);
311 static int gptm_load(QEMUFile
*f
, void *opaque
, int version_id
)
313 gptm_state
*s
= (gptm_state
*)opaque
;
318 s
->config
= qemu_get_be32(f
);
319 s
->mode
[0] = qemu_get_be32(f
);
320 s
->mode
[1] = qemu_get_be32(f
);
321 s
->control
= qemu_get_be32(f
);
322 s
->state
= qemu_get_be32(f
);
323 s
->mask
= qemu_get_be32(f
);
324 s
->mode
[0] = qemu_get_be32(f
);
325 s
->mode
[0] = qemu_get_be32(f
);
326 s
->load
[0] = qemu_get_be32(f
);
327 s
->load
[1] = qemu_get_be32(f
);
328 s
->match
[0] = qemu_get_be32(f
);
329 s
->match
[1] = qemu_get_be32(f
);
330 s
->prescale
[0] = qemu_get_be32(f
);
331 s
->prescale
[1] = qemu_get_be32(f
);
332 s
->match_prescale
[0] = qemu_get_be32(f
);
333 s
->match_prescale
[1] = qemu_get_be32(f
);
334 s
->rtc
= qemu_get_be32(f
);
335 s
->tick
[0] = qemu_get_be64(f
);
336 s
->tick
[1] = qemu_get_be64(f
);
337 qemu_get_timer(f
, s
->timer
[0]);
338 qemu_get_timer(f
, s
->timer
[1]);
343 static void stellaris_gptm_init(uint32_t base
, qemu_irq irq
, qemu_irq trigger
)
348 s
= (gptm_state
*)qemu_mallocz(sizeof(gptm_state
));
350 s
->trigger
= trigger
;
351 s
->opaque
[0] = s
->opaque
[1] = s
;
353 iomemtype
= cpu_register_io_memory(0, gptm_readfn
,
355 cpu_register_physical_memory(base
, 0x00001000, iomemtype
);
356 s
->timer
[0] = qemu_new_timer(vm_clock
, gptm_tick
, &s
->opaque
[0]);
357 s
->timer
[1] = qemu_new_timer(vm_clock
, gptm_tick
, &s
->opaque
[1]);
358 register_savevm("stellaris_gptm", -1, 1, gptm_save
, gptm_load
, s
);
362 /* System controller. */
379 stellaris_board_info
*board
;
382 static void ssys_update(ssys_state
*s
)
384 qemu_set_irq(s
->irq
, (s
->int_status
& s
->int_mask
) != 0);
387 static uint32_t pllcfg_sandstorm
[16] = {
389 0x1ae0, /* 1.8432 Mhz */
391 0xd573, /* 2.4576 Mhz */
392 0x37a6, /* 3.57954 Mhz */
393 0x1ae2, /* 3.6864 Mhz */
395 0x98bc, /* 4.906 Mhz */
396 0x935b, /* 4.9152 Mhz */
398 0x4dee, /* 5.12 Mhz */
400 0x75db, /* 6.144 Mhz */
401 0x1ae6, /* 7.3728 Mhz */
403 0x585b /* 8.192 Mhz */
406 static uint32_t pllcfg_fury
[16] = {
408 0x1b20, /* 1.8432 Mhz */
410 0xf42b, /* 2.4576 Mhz */
411 0x37e3, /* 3.57954 Mhz */
412 0x1b21, /* 3.6864 Mhz */
414 0x98ee, /* 4.906 Mhz */
415 0xd5b4, /* 4.9152 Mhz */
417 0x4e27, /* 5.12 Mhz */
419 0xec1c, /* 6.144 Mhz */
420 0x1b23, /* 7.3728 Mhz */
422 0xb11c /* 8.192 Mhz */
425 static uint32_t ssys_read(void *opaque
, target_phys_addr_t offset
)
427 ssys_state
*s
= (ssys_state
*)opaque
;
430 case 0x000: /* DID0 */
431 return s
->board
->did0
;
432 case 0x004: /* DID1 */
433 return s
->board
->did1
;
434 case 0x008: /* DC0 */
435 return s
->board
->dc0
;
436 case 0x010: /* DC1 */
437 return s
->board
->dc1
;
438 case 0x014: /* DC2 */
439 return s
->board
->dc2
;
440 case 0x018: /* DC3 */
441 return s
->board
->dc3
;
442 case 0x01c: /* DC4 */
443 return s
->board
->dc4
;
444 case 0x030: /* PBORCTL */
446 case 0x034: /* LDOPCTL */
448 case 0x040: /* SRCR0 */
450 case 0x044: /* SRCR1 */
452 case 0x048: /* SRCR2 */
454 case 0x050: /* RIS */
455 return s
->int_status
;
456 case 0x054: /* IMC */
458 case 0x058: /* MISC */
459 return s
->int_status
& s
->int_mask
;
460 case 0x05c: /* RESC */
462 case 0x060: /* RCC */
464 case 0x064: /* PLLCFG */
467 xtal
= (s
->rcc
>> 6) & 0xf;
468 if (s
->board
->did0
& (1 << 16)) {
469 return pllcfg_fury
[xtal
];
471 return pllcfg_sandstorm
[xtal
];
474 case 0x100: /* RCGC0 */
476 case 0x104: /* RCGC1 */
478 case 0x108: /* RCGC2 */
480 case 0x110: /* SCGC0 */
482 case 0x114: /* SCGC1 */
484 case 0x118: /* SCGC2 */
486 case 0x120: /* DCGC0 */
488 case 0x124: /* DCGC1 */
490 case 0x128: /* DCGC2 */
492 case 0x150: /* CLKVCLR */
494 case 0x160: /* LDOARST */
496 case 0x1e0: /* USER0 */
498 case 0x1e4: /* USER1 */
501 hw_error("ssys_read: Bad offset 0x%x\n", (int)offset
);
506 static void ssys_calculate_system_clock(ssys_state
*s
)
508 system_clock_scale
= 5 * (((s
->rcc
>> 23) & 0xf) + 1);
511 static void ssys_write(void *opaque
, target_phys_addr_t offset
, uint32_t value
)
513 ssys_state
*s
= (ssys_state
*)opaque
;
516 case 0x030: /* PBORCTL */
517 s
->pborctl
= value
& 0xffff;
519 case 0x034: /* LDOPCTL */
520 s
->ldopctl
= value
& 0x1f;
522 case 0x040: /* SRCR0 */
523 case 0x044: /* SRCR1 */
524 case 0x048: /* SRCR2 */
525 fprintf(stderr
, "Peripheral reset not implemented\n");
527 case 0x054: /* IMC */
528 s
->int_mask
= value
& 0x7f;
530 case 0x058: /* MISC */
531 s
->int_status
&= ~value
;
533 case 0x05c: /* RESC */
534 s
->resc
= value
& 0x3f;
536 case 0x060: /* RCC */
537 if ((s
->rcc
& (1 << 13)) != 0 && (value
& (1 << 13)) == 0) {
539 s
->int_status
|= (1 << 6);
542 ssys_calculate_system_clock(s
);
544 case 0x100: /* RCGC0 */
547 case 0x104: /* RCGC1 */
550 case 0x108: /* RCGC2 */
553 case 0x110: /* SCGC0 */
556 case 0x114: /* SCGC1 */
559 case 0x118: /* SCGC2 */
562 case 0x120: /* DCGC0 */
565 case 0x124: /* DCGC1 */
568 case 0x128: /* DCGC2 */
571 case 0x150: /* CLKVCLR */
574 case 0x160: /* LDOARST */
578 hw_error("ssys_write: Bad offset 0x%x\n", (int)offset
);
583 static CPUReadMemoryFunc
*ssys_readfn
[] = {
589 static CPUWriteMemoryFunc
*ssys_writefn
[] = {
595 static void ssys_reset(void *opaque
)
597 ssys_state
*s
= (ssys_state
*)opaque
;
606 static void ssys_save(QEMUFile
*f
, void *opaque
)
608 ssys_state
*s
= (ssys_state
*)opaque
;
610 qemu_put_be32(f
, s
->pborctl
);
611 qemu_put_be32(f
, s
->ldopctl
);
612 qemu_put_be32(f
, s
->int_mask
);
613 qemu_put_be32(f
, s
->int_status
);
614 qemu_put_be32(f
, s
->resc
);
615 qemu_put_be32(f
, s
->rcc
);
616 qemu_put_be32(f
, s
->rcgc
[0]);
617 qemu_put_be32(f
, s
->rcgc
[1]);
618 qemu_put_be32(f
, s
->rcgc
[2]);
619 qemu_put_be32(f
, s
->scgc
[0]);
620 qemu_put_be32(f
, s
->scgc
[1]);
621 qemu_put_be32(f
, s
->scgc
[2]);
622 qemu_put_be32(f
, s
->dcgc
[0]);
623 qemu_put_be32(f
, s
->dcgc
[1]);
624 qemu_put_be32(f
, s
->dcgc
[2]);
625 qemu_put_be32(f
, s
->clkvclr
);
626 qemu_put_be32(f
, s
->ldoarst
);
629 static int ssys_load(QEMUFile
*f
, void *opaque
, int version_id
)
631 ssys_state
*s
= (ssys_state
*)opaque
;
636 s
->pborctl
= qemu_get_be32(f
);
637 s
->ldopctl
= qemu_get_be32(f
);
638 s
->int_mask
= qemu_get_be32(f
);
639 s
->int_status
= qemu_get_be32(f
);
640 s
->resc
= qemu_get_be32(f
);
641 s
->rcc
= qemu_get_be32(f
);
642 s
->rcgc
[0] = qemu_get_be32(f
);
643 s
->rcgc
[1] = qemu_get_be32(f
);
644 s
->rcgc
[2] = qemu_get_be32(f
);
645 s
->scgc
[0] = qemu_get_be32(f
);
646 s
->scgc
[1] = qemu_get_be32(f
);
647 s
->scgc
[2] = qemu_get_be32(f
);
648 s
->dcgc
[0] = qemu_get_be32(f
);
649 s
->dcgc
[1] = qemu_get_be32(f
);
650 s
->dcgc
[2] = qemu_get_be32(f
);
651 s
->clkvclr
= qemu_get_be32(f
);
652 s
->ldoarst
= qemu_get_be32(f
);
653 ssys_calculate_system_clock(s
);
658 static void stellaris_sys_init(uint32_t base
, qemu_irq irq
,
659 stellaris_board_info
* board
,
665 s
= (ssys_state
*)qemu_mallocz(sizeof(ssys_state
));
668 /* Most devices come preprogrammed with a MAC address in the user data. */
669 s
->user0
= macaddr
[0] | (macaddr
[1] << 8) | (macaddr
[2] << 16);
670 s
->user1
= macaddr
[3] | (macaddr
[4] << 8) | (macaddr
[5] << 16);
672 iomemtype
= cpu_register_io_memory(0, ssys_readfn
,
674 cpu_register_physical_memory(base
, 0x00001000, iomemtype
);
676 register_savevm("stellaris_sys", -1, 1, ssys_save
, ssys_load
, s
);
680 /* I2C controller. */
692 } stellaris_i2c_state
;
694 #define STELLARIS_I2C_MCS_BUSY 0x01
695 #define STELLARIS_I2C_MCS_ERROR 0x02
696 #define STELLARIS_I2C_MCS_ADRACK 0x04
697 #define STELLARIS_I2C_MCS_DATACK 0x08
698 #define STELLARIS_I2C_MCS_ARBLST 0x10
699 #define STELLARIS_I2C_MCS_IDLE 0x20
700 #define STELLARIS_I2C_MCS_BUSBSY 0x40
702 static uint32_t stellaris_i2c_read(void *opaque
, target_phys_addr_t offset
)
704 stellaris_i2c_state
*s
= (stellaris_i2c_state
*)opaque
;
710 /* We don't emulate timing, so the controller is never busy. */
711 return s
->mcs
| STELLARIS_I2C_MCS_IDLE
;
714 case 0x0c: /* MTPR */
716 case 0x10: /* MIMR */
718 case 0x14: /* MRIS */
720 case 0x18: /* MMIS */
721 return s
->mris
& s
->mimr
;
725 hw_error("strllaris_i2c_read: Bad offset 0x%x\n", (int)offset
);
730 static void stellaris_i2c_update(stellaris_i2c_state
*s
)
734 level
= (s
->mris
& s
->mimr
) != 0;
735 qemu_set_irq(s
->irq
, level
);
738 static void stellaris_i2c_write(void *opaque
, target_phys_addr_t offset
,
741 stellaris_i2c_state
*s
= (stellaris_i2c_state
*)opaque
;
745 s
->msa
= value
& 0xff;
748 if ((s
->mcr
& 0x10) == 0) {
749 /* Disabled. Do nothing. */
752 /* Grab the bus if this is starting a transfer. */
753 if ((value
& 2) && (s
->mcs
& STELLARIS_I2C_MCS_BUSBSY
) == 0) {
754 if (i2c_start_transfer(s
->bus
, s
->msa
>> 1, s
->msa
& 1)) {
755 s
->mcs
|= STELLARIS_I2C_MCS_ARBLST
;
757 s
->mcs
&= ~STELLARIS_I2C_MCS_ARBLST
;
758 s
->mcs
|= STELLARIS_I2C_MCS_BUSBSY
;
761 /* If we don't have the bus then indicate an error. */
762 if (!i2c_bus_busy(s
->bus
)
763 || (s
->mcs
& STELLARIS_I2C_MCS_BUSBSY
) == 0) {
764 s
->mcs
|= STELLARIS_I2C_MCS_ERROR
;
767 s
->mcs
&= ~STELLARIS_I2C_MCS_ERROR
;
769 /* Transfer a byte. */
770 /* TODO: Handle errors. */
773 s
->mdr
= i2c_recv(s
->bus
) & 0xff;
776 i2c_send(s
->bus
, s
->mdr
);
778 /* Raise an interrupt. */
782 /* Finish transfer. */
783 i2c_end_transfer(s
->bus
);
784 s
->mcs
&= ~STELLARIS_I2C_MCS_BUSBSY
;
788 s
->mdr
= value
& 0xff;
790 case 0x0c: /* MTPR */
791 s
->mtpr
= value
& 0xff;
793 case 0x10: /* MIMR */
796 case 0x1c: /* MICR */
802 "stellaris_i2c_write: Loopback not implemented\n");
805 "stellaris_i2c_write: Slave mode not implemented\n");
806 s
->mcr
= value
& 0x31;
809 hw_error("stellaris_i2c_write: Bad offset 0x%x\n",
812 stellaris_i2c_update(s
);
815 static void stellaris_i2c_reset(stellaris_i2c_state
*s
)
817 if (s
->mcs
& STELLARIS_I2C_MCS_BUSBSY
)
818 i2c_end_transfer(s
->bus
);
827 stellaris_i2c_update(s
);
830 static CPUReadMemoryFunc
*stellaris_i2c_readfn
[] = {
836 static CPUWriteMemoryFunc
*stellaris_i2c_writefn
[] = {
842 static void stellaris_i2c_save(QEMUFile
*f
, void *opaque
)
844 stellaris_i2c_state
*s
= (stellaris_i2c_state
*)opaque
;
846 qemu_put_be32(f
, s
->msa
);
847 qemu_put_be32(f
, s
->mcs
);
848 qemu_put_be32(f
, s
->mdr
);
849 qemu_put_be32(f
, s
->mtpr
);
850 qemu_put_be32(f
, s
->mimr
);
851 qemu_put_be32(f
, s
->mris
);
852 qemu_put_be32(f
, s
->mcr
);
855 static int stellaris_i2c_load(QEMUFile
*f
, void *opaque
, int version_id
)
857 stellaris_i2c_state
*s
= (stellaris_i2c_state
*)opaque
;
862 s
->msa
= qemu_get_be32(f
);
863 s
->mcs
= qemu_get_be32(f
);
864 s
->mdr
= qemu_get_be32(f
);
865 s
->mtpr
= qemu_get_be32(f
);
866 s
->mimr
= qemu_get_be32(f
);
867 s
->mris
= qemu_get_be32(f
);
868 s
->mcr
= qemu_get_be32(f
);
873 static void stellaris_i2c_init(uint32_t base
, qemu_irq irq
, i2c_bus
*bus
)
875 stellaris_i2c_state
*s
;
878 s
= (stellaris_i2c_state
*)qemu_mallocz(sizeof(stellaris_i2c_state
));
882 iomemtype
= cpu_register_io_memory(0, stellaris_i2c_readfn
,
883 stellaris_i2c_writefn
, s
);
884 cpu_register_physical_memory(base
, 0x00001000, iomemtype
);
885 /* ??? For now we only implement the master interface. */
886 stellaris_i2c_reset(s
);
887 register_savevm("stellaris_i2c", -1, 1,
888 stellaris_i2c_save
, stellaris_i2c_load
, s
);
891 /* Analogue to Digital Converter. This is only partially implemented,
892 enough for applications that use a combined ADC and timer tick. */
894 #define STELLARIS_ADC_EM_CONTROLLER 0
895 #define STELLARIS_ADC_EM_COMP 1
896 #define STELLARIS_ADC_EM_EXTERNAL 4
897 #define STELLARIS_ADC_EM_TIMER 5
898 #define STELLARIS_ADC_EM_PWM0 6
899 #define STELLARIS_ADC_EM_PWM1 7
900 #define STELLARIS_ADC_EM_PWM2 8
902 #define STELLARIS_ADC_FIFO_EMPTY 0x0100
903 #define STELLARIS_ADC_FIFO_FULL 0x1000
923 } stellaris_adc_state
;
925 static uint32_t stellaris_adc_fifo_read(stellaris_adc_state
*s
, int n
)
929 tail
= s
->fifo
[n
].state
& 0xf;
930 if (s
->fifo
[n
].state
& STELLARIS_ADC_FIFO_EMPTY
) {
933 s
->fifo
[n
].state
= (s
->fifo
[n
].state
& ~0xf) | ((tail
+ 1) & 0xf);
934 s
->fifo
[n
].state
&= ~STELLARIS_ADC_FIFO_FULL
;
935 if (tail
+ 1 == ((s
->fifo
[n
].state
>> 4) & 0xf))
936 s
->fifo
[n
].state
|= STELLARIS_ADC_FIFO_EMPTY
;
938 return s
->fifo
[n
].data
[tail
];
941 static void stellaris_adc_fifo_write(stellaris_adc_state
*s
, int n
,
946 head
= (s
->fifo
[n
].state
>> 4) & 0xf;
947 if (s
->fifo
[n
].state
& STELLARIS_ADC_FIFO_FULL
) {
951 s
->fifo
[n
].data
[head
] = value
;
952 head
= (head
+ 1) & 0xf;
953 s
->fifo
[n
].state
&= ~STELLARIS_ADC_FIFO_EMPTY
;
954 s
->fifo
[n
].state
= (s
->fifo
[n
].state
& ~0xf0) | (head
<< 4);
955 if ((s
->fifo
[n
].state
& 0xf) == head
)
956 s
->fifo
[n
].state
|= STELLARIS_ADC_FIFO_FULL
;
959 static void stellaris_adc_update(stellaris_adc_state
*s
)
963 level
= (s
->ris
& s
->im
) != 0;
964 qemu_set_irq(s
->irq
, level
);
967 static void stellaris_adc_trigger(void *opaque
, int irq
, int level
)
969 stellaris_adc_state
*s
= (stellaris_adc_state
*)opaque
;
971 if ((s
->actss
& 1) == 0) {
975 /* Some applications use the ADC as a random number source, so introduce
976 some variation into the signal. */
977 s
->noise
= s
->noise
* 314159 + 1;
978 /* ??? actual inputs not implemented. Return an arbitrary value. */
979 stellaris_adc_fifo_write(s
, 0, 0x200 + ((s
->noise
>> 16) & 7));
981 stellaris_adc_update(s
);
984 static void stellaris_adc_reset(stellaris_adc_state
*s
)
988 for (n
= 0; n
< 4; n
++) {
991 s
->fifo
[n
].state
= STELLARIS_ADC_FIFO_EMPTY
;
995 static uint32_t stellaris_adc_read(void *opaque
, target_phys_addr_t offset
)
997 stellaris_adc_state
*s
= (stellaris_adc_state
*)opaque
;
999 /* TODO: Implement this. */
1000 if (offset
>= 0x40 && offset
< 0xc0) {
1002 n
= (offset
- 0x40) >> 5;
1003 switch (offset
& 0x1f) {
1004 case 0x00: /* SSMUX */
1006 case 0x04: /* SSCTL */
1008 case 0x08: /* SSFIFO */
1009 return stellaris_adc_fifo_read(s
, n
);
1010 case 0x0c: /* SSFSTAT */
1011 return s
->fifo
[n
].state
;
1017 case 0x00: /* ACTSS */
1019 case 0x04: /* RIS */
1023 case 0x0c: /* ISC */
1024 return s
->ris
& s
->im
;
1025 case 0x10: /* OSTAT */
1027 case 0x14: /* EMUX */
1029 case 0x18: /* USTAT */
1031 case 0x20: /* SSPRI */
1033 case 0x30: /* SAC */
1036 hw_error("strllaris_adc_read: Bad offset 0x%x\n",
1042 static void stellaris_adc_write(void *opaque
, target_phys_addr_t offset
,
1045 stellaris_adc_state
*s
= (stellaris_adc_state
*)opaque
;
1047 /* TODO: Implement this. */
1048 if (offset
>= 0x40 && offset
< 0xc0) {
1050 n
= (offset
- 0x40) >> 5;
1051 switch (offset
& 0x1f) {
1052 case 0x00: /* SSMUX */
1053 s
->ssmux
[n
] = value
& 0x33333333;
1055 case 0x04: /* SSCTL */
1057 hw_error("ADC: Unimplemented sequence %x\n",
1060 s
->ssctl
[n
] = value
;
1067 case 0x00: /* ACTSS */
1068 s
->actss
= value
& 0xf;
1070 hw_error("Not implemented: ADC sequencers 1-3\n");
1076 case 0x0c: /* ISC */
1079 case 0x10: /* OSTAT */
1082 case 0x14: /* EMUX */
1085 case 0x18: /* USTAT */
1088 case 0x20: /* SSPRI */
1091 case 0x28: /* PSSI */
1092 hw_error("Not implemented: ADC sample initiate\n");
1094 case 0x30: /* SAC */
1098 hw_error("stellaris_adc_write: Bad offset 0x%x\n", (int)offset
);
1100 stellaris_adc_update(s
);
1103 static CPUReadMemoryFunc
*stellaris_adc_readfn
[] = {
1109 static CPUWriteMemoryFunc
*stellaris_adc_writefn
[] = {
1110 stellaris_adc_write
,
1111 stellaris_adc_write
,
1115 static void stellaris_adc_save(QEMUFile
*f
, void *opaque
)
1117 stellaris_adc_state
*s
= (stellaris_adc_state
*)opaque
;
1121 qemu_put_be32(f
, s
->actss
);
1122 qemu_put_be32(f
, s
->ris
);
1123 qemu_put_be32(f
, s
->im
);
1124 qemu_put_be32(f
, s
->emux
);
1125 qemu_put_be32(f
, s
->ostat
);
1126 qemu_put_be32(f
, s
->ustat
);
1127 qemu_put_be32(f
, s
->sspri
);
1128 qemu_put_be32(f
, s
->sac
);
1129 for (i
= 0; i
< 4; i
++) {
1130 qemu_put_be32(f
, s
->fifo
[i
].state
);
1131 for (j
= 0; j
< 16; j
++) {
1132 qemu_put_be32(f
, s
->fifo
[i
].data
[j
]);
1134 qemu_put_be32(f
, s
->ssmux
[i
]);
1135 qemu_put_be32(f
, s
->ssctl
[i
]);
1137 qemu_put_be32(f
, s
->noise
);
1140 static int stellaris_adc_load(QEMUFile
*f
, void *opaque
, int version_id
)
1142 stellaris_adc_state
*s
= (stellaris_adc_state
*)opaque
;
1146 if (version_id
!= 1)
1149 s
->actss
= qemu_get_be32(f
);
1150 s
->ris
= qemu_get_be32(f
);
1151 s
->im
= qemu_get_be32(f
);
1152 s
->emux
= qemu_get_be32(f
);
1153 s
->ostat
= qemu_get_be32(f
);
1154 s
->ustat
= qemu_get_be32(f
);
1155 s
->sspri
= qemu_get_be32(f
);
1156 s
->sac
= qemu_get_be32(f
);
1157 for (i
= 0; i
< 4; i
++) {
1158 s
->fifo
[i
].state
= qemu_get_be32(f
);
1159 for (j
= 0; j
< 16; j
++) {
1160 s
->fifo
[i
].data
[j
] = qemu_get_be32(f
);
1162 s
->ssmux
[i
] = qemu_get_be32(f
);
1163 s
->ssctl
[i
] = qemu_get_be32(f
);
1165 s
->noise
= qemu_get_be32(f
);
1170 static qemu_irq
stellaris_adc_init(uint32_t base
, qemu_irq irq
)
1172 stellaris_adc_state
*s
;
1176 s
= (stellaris_adc_state
*)qemu_mallocz(sizeof(stellaris_adc_state
));
1179 iomemtype
= cpu_register_io_memory(0, stellaris_adc_readfn
,
1180 stellaris_adc_writefn
, s
);
1181 cpu_register_physical_memory(base
, 0x00001000, iomemtype
);
1182 stellaris_adc_reset(s
);
1183 qi
= qemu_allocate_irqs(stellaris_adc_trigger
, s
, 1);
1184 register_savevm("stellaris_adc", -1, 1,
1185 stellaris_adc_save
, stellaris_adc_load
, s
);
1189 /* Some boards have both an OLED controller and SD card connected to
1190 the same SSI port, with the SD card chip select connected to a
1191 GPIO pin. Technically the OLED chip select is connected to the SSI
1192 Fss pin. We do not bother emulating that as both devices should
1193 never be selected simultaneously, and our OLED controller ignores stray
1194 0xff commands that occur when deselecting the SD card. */
1197 ssi_xfer_cb xfer_cb
[2];
1201 } stellaris_ssi_bus_state
;
1203 static void stellaris_ssi_bus_select(void *opaque
, int irq
, int level
)
1205 stellaris_ssi_bus_state
*s
= (stellaris_ssi_bus_state
*)opaque
;
1207 s
->current_dev
= level
;
1210 static int stellaris_ssi_bus_xfer(void *opaque
, int val
)
1212 stellaris_ssi_bus_state
*s
= (stellaris_ssi_bus_state
*)opaque
;
1214 return s
->xfer_cb
[s
->current_dev
](s
->opaque
[s
->current_dev
], val
);
1217 static void stellaris_ssi_bus_save(QEMUFile
*f
, void *opaque
)
1219 stellaris_ssi_bus_state
*s
= (stellaris_ssi_bus_state
*)opaque
;
1221 qemu_put_be32(f
, s
->current_dev
);
1224 static int stellaris_ssi_bus_load(QEMUFile
*f
, void *opaque
, int version_id
)
1226 stellaris_ssi_bus_state
*s
= (stellaris_ssi_bus_state
*)opaque
;
1228 if (version_id
!= 1)
1231 s
->current_dev
= qemu_get_be32(f
);
1236 static void *stellaris_ssi_bus_init(qemu_irq
*irqp
,
1237 ssi_xfer_cb cb0
, void *opaque0
,
1238 ssi_xfer_cb cb1
, void *opaque1
)
1241 stellaris_ssi_bus_state
*s
;
1243 s
= (stellaris_ssi_bus_state
*)qemu_mallocz(sizeof(stellaris_ssi_bus_state
));
1244 s
->xfer_cb
[0] = cb0
;
1245 s
->opaque
[0] = opaque0
;
1246 s
->xfer_cb
[1] = cb1
;
1247 s
->opaque
[1] = opaque1
;
1248 qi
= qemu_allocate_irqs(stellaris_ssi_bus_select
, s
, 1);
1250 register_savevm("stellaris_ssi_bus", -1, 1,
1251 stellaris_ssi_bus_save
, stellaris_ssi_bus_load
, s
);
1256 static stellaris_board_info stellaris_boards
[] = {
1260 0x001f001f, /* dc0 */
1270 0x00ff007f, /* dc0 */
1275 BP_OLED_SSI
| BP_GAMEPAD
1279 static void stellaris_init(const char *kernel_filename
, const char *cpu_model
,
1280 stellaris_board_info
*board
)
1282 static const int uart_irq
[] = {5, 6, 33, 34};
1283 static const int timer_irq
[] = {19, 21, 23, 35};
1284 static const uint32_t gpio_addr
[7] =
1285 { 0x40004000, 0x40005000, 0x40006000, 0x40007000,
1286 0x40024000, 0x40025000, 0x40026000};
1287 static const int gpio_irq
[7] = {0, 1, 2, 3, 4, 30, 31};
1290 qemu_irq
*gpio_in
[7];
1291 qemu_irq
*gpio_out
[7];
1298 flash_size
= ((board
->dc0
& 0xffff) + 1) << 1;
1299 sram_size
= (board
->dc0
>> 18) + 1;
1300 pic
= armv7m_init(flash_size
, sram_size
, kernel_filename
, cpu_model
);
1302 if (board
->dc1
& (1 << 16)) {
1303 adc
= stellaris_adc_init(0x40038000, pic
[14]);
1307 for (i
= 0; i
< 4; i
++) {
1308 if (board
->dc2
& (0x10000 << i
)) {
1309 stellaris_gptm_init(0x40030000 + i
* 0x1000,
1310 pic
[timer_irq
[i
]], adc
);
1314 stellaris_sys_init(0x400fe000, pic
[28], board
, nd_table
[0].macaddr
);
1316 for (i
= 0; i
< 7; i
++) {
1317 if (board
->dc4
& (1 << i
)) {
1318 gpio_in
[i
] = pl061_init(gpio_addr
[i
], pic
[gpio_irq
[i
]],
1323 if (board
->dc2
& (1 << 12)) {
1324 i2c
= i2c_init_bus();
1325 stellaris_i2c_init(0x40020000, pic
[8], i2c
);
1326 if (board
->peripherals
& BP_OLED_I2C
) {
1327 ssd0303_init(i2c
, 0x3d);
1331 for (i
= 0; i
< 4; i
++) {
1332 if (board
->dc2
& (1 << i
)) {
1333 pl011_init(0x4000c000 + i
* 0x1000, pic
[uart_irq
[i
]],
1334 serial_hds
[i
], PL011_LUMINARY
);
1337 if (board
->dc2
& (1 << 4)) {
1338 if (board
->peripherals
& BP_OLED_SSI
) {
1344 oled
= ssd0323_init(&gpio_out
[GPIO_C
][7]);
1345 index
= drive_get_index(IF_SD
, 0, 0);
1346 sd
= ssi_sd_init(drives_table
[index
].bdrv
);
1348 ssi_bus
= stellaris_ssi_bus_init(&gpio_out
[GPIO_D
][0],
1350 ssd0323_xfer_ssi
, oled
);
1352 pl022_init(0x40008000, pic
[7], stellaris_ssi_bus_xfer
, ssi_bus
);
1353 /* Make sure the select pin is high. */
1354 qemu_irq_raise(gpio_out
[GPIO_D
][0]);
1356 pl022_init(0x40008000, pic
[7], NULL
, NULL
);
1359 if (board
->dc4
& (1 << 28))
1360 stellaris_enet_init(&nd_table
[0], 0x40048000, pic
[42]);
1361 if (board
->peripherals
& BP_GAMEPAD
) {
1362 qemu_irq gpad_irq
[5];
1363 static const int gpad_keycode
[5] = { 0xc8, 0xd0, 0xcb, 0xcd, 0x1d };
1365 gpad_irq
[0] = qemu_irq_invert(gpio_in
[GPIO_E
][0]); /* up */
1366 gpad_irq
[1] = qemu_irq_invert(gpio_in
[GPIO_E
][1]); /* down */
1367 gpad_irq
[2] = qemu_irq_invert(gpio_in
[GPIO_E
][2]); /* left */
1368 gpad_irq
[3] = qemu_irq_invert(gpio_in
[GPIO_E
][3]); /* right */
1369 gpad_irq
[4] = qemu_irq_invert(gpio_in
[GPIO_F
][1]); /* select */
1371 stellaris_gamepad_init(5, gpad_irq
, gpad_keycode
);
1375 /* FIXME: Figure out how to generate these from stellaris_boards. */
1376 static void lm3s811evb_init(ram_addr_t ram_size
, int vga_ram_size
,
1377 const char *boot_device
,
1378 const char *kernel_filename
, const char *kernel_cmdline
,
1379 const char *initrd_filename
, const char *cpu_model
)
1381 stellaris_init(kernel_filename
, cpu_model
, &stellaris_boards
[0]);
1384 static void lm3s6965evb_init(ram_addr_t ram_size
, int vga_ram_size
,
1385 const char *boot_device
,
1386 const char *kernel_filename
, const char *kernel_cmdline
,
1387 const char *initrd_filename
, const char *cpu_model
)
1389 stellaris_init(kernel_filename
, cpu_model
, &stellaris_boards
[1]);
1392 QEMUMachine lm3s811evb_machine
= {
1393 .name
= "lm3s811evb",
1394 .desc
= "Stellaris LM3S811EVB",
1395 .init
= lm3s811evb_init
,
1398 QEMUMachine lm3s6965evb_machine
= {
1399 .name
= "lm3s6965evb",
1400 .desc
= "Stellaris LM3S6965EVB",
1401 .init
= lm3s6965evb_init
,