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. */
343 stellaris_board_info
*board
;
346 static void ssys_update(ssys_state
*s
)
348 qemu_set_irq(s
->irq
, (s
->int_status
& s
->int_mask
) != 0);
351 static uint32_t pllcfg_sandstorm
[16] = {
353 0x1ae0, /* 1.8432 Mhz */
355 0xd573, /* 2.4576 Mhz */
356 0x37a6, /* 3.57954 Mhz */
357 0x1ae2, /* 3.6864 Mhz */
359 0x98bc, /* 4.906 Mhz */
360 0x935b, /* 4.9152 Mhz */
362 0x4dee, /* 5.12 Mhz */
364 0x75db, /* 6.144 Mhz */
365 0x1ae6, /* 7.3728 Mhz */
367 0x585b /* 8.192 Mhz */
370 static uint32_t pllcfg_fury
[16] = {
372 0x1b20, /* 1.8432 Mhz */
374 0xf42b, /* 2.4576 Mhz */
375 0x37e3, /* 3.57954 Mhz */
376 0x1b21, /* 3.6864 Mhz */
378 0x98ee, /* 4.906 Mhz */
379 0xd5b4, /* 4.9152 Mhz */
381 0x4e27, /* 5.12 Mhz */
383 0xec1c, /* 6.144 Mhz */
384 0x1b23, /* 7.3728 Mhz */
386 0xb11c /* 8.192 Mhz */
389 static uint32_t ssys_read(void *opaque
, target_phys_addr_t offset
)
391 ssys_state
*s
= (ssys_state
*)opaque
;
394 case 0x000: /* DID0 */
395 return s
->board
->did0
;
396 case 0x004: /* DID1 */
397 return s
->board
->did1
;
398 case 0x008: /* DC0 */
399 return s
->board
->dc0
;
400 case 0x010: /* DC1 */
401 return s
->board
->dc1
;
402 case 0x014: /* DC2 */
403 return s
->board
->dc2
;
404 case 0x018: /* DC3 */
405 return s
->board
->dc3
;
406 case 0x01c: /* DC4 */
407 return s
->board
->dc4
;
408 case 0x030: /* PBORCTL */
410 case 0x034: /* LDOPCTL */
412 case 0x040: /* SRCR0 */
414 case 0x044: /* SRCR1 */
416 case 0x048: /* SRCR2 */
418 case 0x050: /* RIS */
419 return s
->int_status
;
420 case 0x054: /* IMC */
422 case 0x058: /* MISC */
423 return s
->int_status
& s
->int_mask
;
424 case 0x05c: /* RESC */
426 case 0x060: /* RCC */
428 case 0x064: /* PLLCFG */
431 xtal
= (s
->rcc
>> 6) & 0xf;
432 if (s
->board
->did0
& (1 << 16)) {
433 return pllcfg_fury
[xtal
];
435 return pllcfg_sandstorm
[xtal
];
438 case 0x100: /* RCGC0 */
440 case 0x104: /* RCGC1 */
442 case 0x108: /* RCGC2 */
444 case 0x110: /* SCGC0 */
446 case 0x114: /* SCGC1 */
448 case 0x118: /* SCGC2 */
450 case 0x120: /* DCGC0 */
452 case 0x124: /* DCGC1 */
454 case 0x128: /* DCGC2 */
456 case 0x150: /* CLKVCLR */
458 case 0x160: /* LDOARST */
460 case 0x1e0: /* USER0 */
462 case 0x1e4: /* USER1 */
465 hw_error("ssys_read: Bad offset 0x%x\n", (int)offset
);
470 static void ssys_calculate_system_clock(ssys_state
*s
)
472 system_clock_scale
= 5 * (((s
->rcc
>> 23) & 0xf) + 1);
475 static void ssys_write(void *opaque
, target_phys_addr_t offset
, uint32_t value
)
477 ssys_state
*s
= (ssys_state
*)opaque
;
480 case 0x030: /* PBORCTL */
481 s
->pborctl
= value
& 0xffff;
483 case 0x034: /* LDOPCTL */
484 s
->ldopctl
= value
& 0x1f;
486 case 0x040: /* SRCR0 */
487 case 0x044: /* SRCR1 */
488 case 0x048: /* SRCR2 */
489 fprintf(stderr
, "Peripheral reset not implemented\n");
491 case 0x054: /* IMC */
492 s
->int_mask
= value
& 0x7f;
494 case 0x058: /* MISC */
495 s
->int_status
&= ~value
;
497 case 0x05c: /* RESC */
498 s
->resc
= value
& 0x3f;
500 case 0x060: /* RCC */
501 if ((s
->rcc
& (1 << 13)) != 0 && (value
& (1 << 13)) == 0) {
503 s
->int_status
|= (1 << 6);
506 ssys_calculate_system_clock(s
);
508 case 0x100: /* RCGC0 */
511 case 0x104: /* RCGC1 */
514 case 0x108: /* RCGC2 */
517 case 0x110: /* SCGC0 */
520 case 0x114: /* SCGC1 */
523 case 0x118: /* SCGC2 */
526 case 0x120: /* DCGC0 */
529 case 0x124: /* DCGC1 */
532 case 0x128: /* DCGC2 */
535 case 0x150: /* CLKVCLR */
538 case 0x160: /* LDOARST */
542 hw_error("ssys_write: Bad offset 0x%x\n", (int)offset
);
547 static CPUReadMemoryFunc
* const ssys_readfn
[] = {
553 static CPUWriteMemoryFunc
* const ssys_writefn
[] = {
559 static void ssys_reset(void *opaque
)
561 ssys_state
*s
= (ssys_state
*)opaque
;
570 static int stellaris_sys_post_load(void *opaque
, int version_id
)
572 ssys_state
*s
= opaque
;
574 ssys_calculate_system_clock(s
);
579 static const VMStateDescription vmstate_stellaris_sys
= {
580 .name
= "stellaris_sys",
582 .minimum_version_id
= 1,
583 .minimum_version_id_old
= 1,
584 .post_load
= stellaris_sys_post_load
,
585 .fields
= (VMStateField
[]) {
586 VMSTATE_UINT32(pborctl
, ssys_state
),
587 VMSTATE_UINT32(ldopctl
, ssys_state
),
588 VMSTATE_UINT32(int_mask
, ssys_state
),
589 VMSTATE_UINT32(int_status
, ssys_state
),
590 VMSTATE_UINT32(resc
, ssys_state
),
591 VMSTATE_UINT32(rcc
, ssys_state
),
592 VMSTATE_UINT32_ARRAY(rcgc
, ssys_state
, 3),
593 VMSTATE_UINT32_ARRAY(scgc
, ssys_state
, 3),
594 VMSTATE_UINT32_ARRAY(dcgc
, ssys_state
, 3),
595 VMSTATE_UINT32(clkvclr
, ssys_state
),
596 VMSTATE_UINT32(ldoarst
, ssys_state
),
597 VMSTATE_END_OF_LIST()
601 static int stellaris_sys_init(uint32_t base
, qemu_irq irq
,
602 stellaris_board_info
* board
,
608 s
= (ssys_state
*)g_malloc0(sizeof(ssys_state
));
611 /* Most devices come preprogrammed with a MAC address in the user data. */
612 s
->user0
= macaddr
[0] | (macaddr
[1] << 8) | (macaddr
[2] << 16);
613 s
->user1
= macaddr
[3] | (macaddr
[4] << 8) | (macaddr
[5] << 16);
615 iomemtype
= cpu_register_io_memory(ssys_readfn
,
617 DEVICE_NATIVE_ENDIAN
);
618 cpu_register_physical_memory(base
, 0x00001000, iomemtype
);
620 vmstate_register(NULL
, -1, &vmstate_stellaris_sys
, s
);
625 /* I2C controller. */
638 } stellaris_i2c_state
;
640 #define STELLARIS_I2C_MCS_BUSY 0x01
641 #define STELLARIS_I2C_MCS_ERROR 0x02
642 #define STELLARIS_I2C_MCS_ADRACK 0x04
643 #define STELLARIS_I2C_MCS_DATACK 0x08
644 #define STELLARIS_I2C_MCS_ARBLST 0x10
645 #define STELLARIS_I2C_MCS_IDLE 0x20
646 #define STELLARIS_I2C_MCS_BUSBSY 0x40
648 static uint32_t stellaris_i2c_read(void *opaque
, target_phys_addr_t offset
)
650 stellaris_i2c_state
*s
= (stellaris_i2c_state
*)opaque
;
656 /* We don't emulate timing, so the controller is never busy. */
657 return s
->mcs
| STELLARIS_I2C_MCS_IDLE
;
660 case 0x0c: /* MTPR */
662 case 0x10: /* MIMR */
664 case 0x14: /* MRIS */
666 case 0x18: /* MMIS */
667 return s
->mris
& s
->mimr
;
671 hw_error("strllaris_i2c_read: Bad offset 0x%x\n", (int)offset
);
676 static void stellaris_i2c_update(stellaris_i2c_state
*s
)
680 level
= (s
->mris
& s
->mimr
) != 0;
681 qemu_set_irq(s
->irq
, level
);
684 static void stellaris_i2c_write(void *opaque
, target_phys_addr_t offset
,
687 stellaris_i2c_state
*s
= (stellaris_i2c_state
*)opaque
;
691 s
->msa
= value
& 0xff;
694 if ((s
->mcr
& 0x10) == 0) {
695 /* Disabled. Do nothing. */
698 /* Grab the bus if this is starting a transfer. */
699 if ((value
& 2) && (s
->mcs
& STELLARIS_I2C_MCS_BUSBSY
) == 0) {
700 if (i2c_start_transfer(s
->bus
, s
->msa
>> 1, s
->msa
& 1)) {
701 s
->mcs
|= STELLARIS_I2C_MCS_ARBLST
;
703 s
->mcs
&= ~STELLARIS_I2C_MCS_ARBLST
;
704 s
->mcs
|= STELLARIS_I2C_MCS_BUSBSY
;
707 /* If we don't have the bus then indicate an error. */
708 if (!i2c_bus_busy(s
->bus
)
709 || (s
->mcs
& STELLARIS_I2C_MCS_BUSBSY
) == 0) {
710 s
->mcs
|= STELLARIS_I2C_MCS_ERROR
;
713 s
->mcs
&= ~STELLARIS_I2C_MCS_ERROR
;
715 /* Transfer a byte. */
716 /* TODO: Handle errors. */
719 s
->mdr
= i2c_recv(s
->bus
) & 0xff;
722 i2c_send(s
->bus
, s
->mdr
);
724 /* Raise an interrupt. */
728 /* Finish transfer. */
729 i2c_end_transfer(s
->bus
);
730 s
->mcs
&= ~STELLARIS_I2C_MCS_BUSBSY
;
734 s
->mdr
= value
& 0xff;
736 case 0x0c: /* MTPR */
737 s
->mtpr
= value
& 0xff;
739 case 0x10: /* MIMR */
742 case 0x1c: /* MICR */
748 "stellaris_i2c_write: Loopback not implemented\n");
751 "stellaris_i2c_write: Slave mode not implemented\n");
752 s
->mcr
= value
& 0x31;
755 hw_error("stellaris_i2c_write: Bad offset 0x%x\n",
758 stellaris_i2c_update(s
);
761 static void stellaris_i2c_reset(stellaris_i2c_state
*s
)
763 if (s
->mcs
& STELLARIS_I2C_MCS_BUSBSY
)
764 i2c_end_transfer(s
->bus
);
773 stellaris_i2c_update(s
);
776 static CPUReadMemoryFunc
* const stellaris_i2c_readfn
[] = {
782 static CPUWriteMemoryFunc
* const stellaris_i2c_writefn
[] = {
788 static const VMStateDescription vmstate_stellaris_i2c
= {
789 .name
= "stellaris_i2c",
791 .minimum_version_id
= 1,
792 .minimum_version_id_old
= 1,
793 .fields
= (VMStateField
[]) {
794 VMSTATE_UINT32(msa
, stellaris_i2c_state
),
795 VMSTATE_UINT32(mcs
, stellaris_i2c_state
),
796 VMSTATE_UINT32(mdr
, stellaris_i2c_state
),
797 VMSTATE_UINT32(mtpr
, stellaris_i2c_state
),
798 VMSTATE_UINT32(mimr
, stellaris_i2c_state
),
799 VMSTATE_UINT32(mris
, stellaris_i2c_state
),
800 VMSTATE_UINT32(mcr
, stellaris_i2c_state
),
801 VMSTATE_END_OF_LIST()
805 static int stellaris_i2c_init(SysBusDevice
* dev
)
807 stellaris_i2c_state
*s
= FROM_SYSBUS(stellaris_i2c_state
, dev
);
811 sysbus_init_irq(dev
, &s
->irq
);
812 bus
= i2c_init_bus(&dev
->qdev
, "i2c");
815 iomemtype
= cpu_register_io_memory(stellaris_i2c_readfn
,
816 stellaris_i2c_writefn
, s
,
817 DEVICE_NATIVE_ENDIAN
);
818 sysbus_init_mmio(dev
, 0x1000, iomemtype
);
819 /* ??? For now we only implement the master interface. */
820 stellaris_i2c_reset(s
);
821 vmstate_register(&dev
->qdev
, -1, &vmstate_stellaris_i2c
, s
);
825 /* Analogue to Digital Converter. This is only partially implemented,
826 enough for applications that use a combined ADC and timer tick. */
828 #define STELLARIS_ADC_EM_CONTROLLER 0
829 #define STELLARIS_ADC_EM_COMP 1
830 #define STELLARIS_ADC_EM_EXTERNAL 4
831 #define STELLARIS_ADC_EM_TIMER 5
832 #define STELLARIS_ADC_EM_PWM0 6
833 #define STELLARIS_ADC_EM_PWM1 7
834 #define STELLARIS_ADC_EM_PWM2 8
836 #define STELLARIS_ADC_FIFO_EMPTY 0x0100
837 #define STELLARIS_ADC_FIFO_FULL 0x1000
858 } stellaris_adc_state
;
860 static uint32_t stellaris_adc_fifo_read(stellaris_adc_state
*s
, int n
)
864 tail
= s
->fifo
[n
].state
& 0xf;
865 if (s
->fifo
[n
].state
& STELLARIS_ADC_FIFO_EMPTY
) {
868 s
->fifo
[n
].state
= (s
->fifo
[n
].state
& ~0xf) | ((tail
+ 1) & 0xf);
869 s
->fifo
[n
].state
&= ~STELLARIS_ADC_FIFO_FULL
;
870 if (tail
+ 1 == ((s
->fifo
[n
].state
>> 4) & 0xf))
871 s
->fifo
[n
].state
|= STELLARIS_ADC_FIFO_EMPTY
;
873 return s
->fifo
[n
].data
[tail
];
876 static void stellaris_adc_fifo_write(stellaris_adc_state
*s
, int n
,
881 /* TODO: Real hardware has limited size FIFOs. We have a full 16 entry
882 FIFO fir each sequencer. */
883 head
= (s
->fifo
[n
].state
>> 4) & 0xf;
884 if (s
->fifo
[n
].state
& STELLARIS_ADC_FIFO_FULL
) {
888 s
->fifo
[n
].data
[head
] = value
;
889 head
= (head
+ 1) & 0xf;
890 s
->fifo
[n
].state
&= ~STELLARIS_ADC_FIFO_EMPTY
;
891 s
->fifo
[n
].state
= (s
->fifo
[n
].state
& ~0xf0) | (head
<< 4);
892 if ((s
->fifo
[n
].state
& 0xf) == head
)
893 s
->fifo
[n
].state
|= STELLARIS_ADC_FIFO_FULL
;
896 static void stellaris_adc_update(stellaris_adc_state
*s
)
901 for (n
= 0; n
< 4; n
++) {
902 level
= (s
->ris
& s
->im
& (1 << n
)) != 0;
903 qemu_set_irq(s
->irq
[n
], level
);
907 static void stellaris_adc_trigger(void *opaque
, int irq
, int level
)
909 stellaris_adc_state
*s
= (stellaris_adc_state
*)opaque
;
912 for (n
= 0; n
< 4; n
++) {
913 if ((s
->actss
& (1 << n
)) == 0) {
917 if (((s
->emux
>> (n
* 4)) & 0xff) != 5) {
921 /* Some applications use the ADC as a random number source, so introduce
922 some variation into the signal. */
923 s
->noise
= s
->noise
* 314159 + 1;
924 /* ??? actual inputs not implemented. Return an arbitrary value. */
925 stellaris_adc_fifo_write(s
, n
, 0x200 + ((s
->noise
>> 16) & 7));
927 stellaris_adc_update(s
);
931 static void stellaris_adc_reset(stellaris_adc_state
*s
)
935 for (n
= 0; n
< 4; n
++) {
938 s
->fifo
[n
].state
= STELLARIS_ADC_FIFO_EMPTY
;
942 static uint32_t stellaris_adc_read(void *opaque
, target_phys_addr_t offset
)
944 stellaris_adc_state
*s
= (stellaris_adc_state
*)opaque
;
946 /* TODO: Implement this. */
947 if (offset
>= 0x40 && offset
< 0xc0) {
949 n
= (offset
- 0x40) >> 5;
950 switch (offset
& 0x1f) {
951 case 0x00: /* SSMUX */
953 case 0x04: /* SSCTL */
955 case 0x08: /* SSFIFO */
956 return stellaris_adc_fifo_read(s
, n
);
957 case 0x0c: /* SSFSTAT */
958 return s
->fifo
[n
].state
;
964 case 0x00: /* ACTSS */
971 return s
->ris
& s
->im
;
972 case 0x10: /* OSTAT */
974 case 0x14: /* EMUX */
976 case 0x18: /* USTAT */
978 case 0x20: /* SSPRI */
983 hw_error("strllaris_adc_read: Bad offset 0x%x\n",
989 static void stellaris_adc_write(void *opaque
, target_phys_addr_t offset
,
992 stellaris_adc_state
*s
= (stellaris_adc_state
*)opaque
;
994 /* TODO: Implement this. */
995 if (offset
>= 0x40 && offset
< 0xc0) {
997 n
= (offset
- 0x40) >> 5;
998 switch (offset
& 0x1f) {
999 case 0x00: /* SSMUX */
1000 s
->ssmux
[n
] = value
& 0x33333333;
1002 case 0x04: /* SSCTL */
1004 hw_error("ADC: Unimplemented sequence %x\n",
1007 s
->ssctl
[n
] = value
;
1014 case 0x00: /* ACTSS */
1015 s
->actss
= value
& 0xf;
1020 case 0x0c: /* ISC */
1023 case 0x10: /* OSTAT */
1026 case 0x14: /* EMUX */
1029 case 0x18: /* USTAT */
1032 case 0x20: /* SSPRI */
1035 case 0x28: /* PSSI */
1036 hw_error("Not implemented: ADC sample initiate\n");
1038 case 0x30: /* SAC */
1042 hw_error("stellaris_adc_write: Bad offset 0x%x\n", (int)offset
);
1044 stellaris_adc_update(s
);
1047 static CPUReadMemoryFunc
* const stellaris_adc_readfn
[] = {
1053 static CPUWriteMemoryFunc
* const stellaris_adc_writefn
[] = {
1054 stellaris_adc_write
,
1055 stellaris_adc_write
,
1059 static const VMStateDescription vmstate_stellaris_adc
= {
1060 .name
= "stellaris_adc",
1062 .minimum_version_id
= 1,
1063 .minimum_version_id_old
= 1,
1064 .fields
= (VMStateField
[]) {
1065 VMSTATE_UINT32(actss
, stellaris_adc_state
),
1066 VMSTATE_UINT32(ris
, stellaris_adc_state
),
1067 VMSTATE_UINT32(im
, stellaris_adc_state
),
1068 VMSTATE_UINT32(emux
, stellaris_adc_state
),
1069 VMSTATE_UINT32(ostat
, stellaris_adc_state
),
1070 VMSTATE_UINT32(ustat
, stellaris_adc_state
),
1071 VMSTATE_UINT32(sspri
, stellaris_adc_state
),
1072 VMSTATE_UINT32(sac
, stellaris_adc_state
),
1073 VMSTATE_UINT32(fifo
[0].state
, stellaris_adc_state
),
1074 VMSTATE_UINT32_ARRAY(fifo
[0].data
, stellaris_adc_state
, 16),
1075 VMSTATE_UINT32(ssmux
[0], stellaris_adc_state
),
1076 VMSTATE_UINT32(ssctl
[0], stellaris_adc_state
),
1077 VMSTATE_UINT32(fifo
[1].state
, stellaris_adc_state
),
1078 VMSTATE_UINT32_ARRAY(fifo
[1].data
, stellaris_adc_state
, 16),
1079 VMSTATE_UINT32(ssmux
[1], stellaris_adc_state
),
1080 VMSTATE_UINT32(ssctl
[1], stellaris_adc_state
),
1081 VMSTATE_UINT32(fifo
[2].state
, stellaris_adc_state
),
1082 VMSTATE_UINT32_ARRAY(fifo
[2].data
, stellaris_adc_state
, 16),
1083 VMSTATE_UINT32(ssmux
[2], stellaris_adc_state
),
1084 VMSTATE_UINT32(ssctl
[2], stellaris_adc_state
),
1085 VMSTATE_UINT32(fifo
[3].state
, stellaris_adc_state
),
1086 VMSTATE_UINT32_ARRAY(fifo
[3].data
, stellaris_adc_state
, 16),
1087 VMSTATE_UINT32(ssmux
[3], stellaris_adc_state
),
1088 VMSTATE_UINT32(ssctl
[3], stellaris_adc_state
),
1089 VMSTATE_UINT32(noise
, stellaris_adc_state
),
1090 VMSTATE_END_OF_LIST()
1094 static int stellaris_adc_init(SysBusDevice
*dev
)
1096 stellaris_adc_state
*s
= FROM_SYSBUS(stellaris_adc_state
, dev
);
1100 for (n
= 0; n
< 4; n
++) {
1101 sysbus_init_irq(dev
, &s
->irq
[n
]);
1104 iomemtype
= cpu_register_io_memory(stellaris_adc_readfn
,
1105 stellaris_adc_writefn
, s
,
1106 DEVICE_NATIVE_ENDIAN
);
1107 sysbus_init_mmio(dev
, 0x1000, iomemtype
);
1108 stellaris_adc_reset(s
);
1109 qdev_init_gpio_in(&dev
->qdev
, stellaris_adc_trigger
, 1);
1110 vmstate_register(&dev
->qdev
, -1, &vmstate_stellaris_adc
, s
);
1114 /* Some boards have both an OLED controller and SD card connected to
1115 the same SSI port, with the SD card chip select connected to a
1116 GPIO pin. Technically the OLED chip select is connected to the SSI
1117 Fss pin. We do not bother emulating that as both devices should
1118 never be selected simultaneously, and our OLED controller ignores stray
1119 0xff commands that occur when deselecting the SD card. */
1126 } stellaris_ssi_bus_state
;
1128 static void stellaris_ssi_bus_select(void *opaque
, int irq
, int level
)
1130 stellaris_ssi_bus_state
*s
= (stellaris_ssi_bus_state
*)opaque
;
1132 s
->current_dev
= level
;
1135 static uint32_t stellaris_ssi_bus_transfer(SSISlave
*dev
, uint32_t val
)
1137 stellaris_ssi_bus_state
*s
= FROM_SSI_SLAVE(stellaris_ssi_bus_state
, dev
);
1139 return ssi_transfer(s
->bus
[s
->current_dev
], val
);
1142 static const VMStateDescription vmstate_stellaris_ssi_bus
= {
1143 .name
= "stellaris_ssi_bus",
1145 .minimum_version_id
= 1,
1146 .minimum_version_id_old
= 1,
1147 .fields
= (VMStateField
[]) {
1148 VMSTATE_INT32(current_dev
, stellaris_ssi_bus_state
),
1149 VMSTATE_END_OF_LIST()
1153 static int stellaris_ssi_bus_init(SSISlave
*dev
)
1155 stellaris_ssi_bus_state
*s
= FROM_SSI_SLAVE(stellaris_ssi_bus_state
, dev
);
1157 s
->bus
[0] = ssi_create_bus(&dev
->qdev
, "ssi0");
1158 s
->bus
[1] = ssi_create_bus(&dev
->qdev
, "ssi1");
1159 qdev_init_gpio_in(&dev
->qdev
, stellaris_ssi_bus_select
, 1);
1161 vmstate_register(&dev
->qdev
, -1, &vmstate_stellaris_ssi_bus
, s
);
1166 static stellaris_board_info stellaris_boards
[] = {
1170 0x001f001f, /* dc0 */
1180 0x00ff007f, /* dc0 */
1185 BP_OLED_SSI
| BP_GAMEPAD
1189 static void stellaris_init(const char *kernel_filename
, const char *cpu_model
,
1190 stellaris_board_info
*board
)
1192 static const int uart_irq
[] = {5, 6, 33, 34};
1193 static const int timer_irq
[] = {19, 21, 23, 35};
1194 static const uint32_t gpio_addr
[7] =
1195 { 0x40004000, 0x40005000, 0x40006000, 0x40007000,
1196 0x40024000, 0x40025000, 0x40026000};
1197 static const int gpio_irq
[7] = {0, 1, 2, 3, 4, 30, 31};
1200 DeviceState
*gpio_dev
[7];
1201 qemu_irq gpio_in
[7][8];
1202 qemu_irq gpio_out
[7][8];
1211 flash_size
= ((board
->dc0
& 0xffff) + 1) << 1;
1212 sram_size
= (board
->dc0
>> 18) + 1;
1213 pic
= armv7m_init(flash_size
, sram_size
, kernel_filename
, cpu_model
);
1215 if (board
->dc1
& (1 << 16)) {
1216 dev
= sysbus_create_varargs("stellaris-adc", 0x40038000,
1217 pic
[14], pic
[15], pic
[16], pic
[17], NULL
);
1218 adc
= qdev_get_gpio_in(dev
, 0);
1222 for (i
= 0; i
< 4; i
++) {
1223 if (board
->dc2
& (0x10000 << i
)) {
1224 dev
= sysbus_create_simple("stellaris-gptm",
1225 0x40030000 + i
* 0x1000,
1227 /* TODO: This is incorrect, but we get away with it because
1228 the ADC output is only ever pulsed. */
1229 qdev_connect_gpio_out(dev
, 0, adc
);
1233 stellaris_sys_init(0x400fe000, pic
[28], board
, nd_table
[0].macaddr
.a
);
1235 for (i
= 0; i
< 7; i
++) {
1236 if (board
->dc4
& (1 << i
)) {
1237 gpio_dev
[i
] = sysbus_create_simple("pl061_luminary", gpio_addr
[i
],
1239 for (j
= 0; j
< 8; j
++) {
1240 gpio_in
[i
][j
] = qdev_get_gpio_in(gpio_dev
[i
], j
);
1241 gpio_out
[i
][j
] = NULL
;
1246 if (board
->dc2
& (1 << 12)) {
1247 dev
= sysbus_create_simple("stellaris-i2c", 0x40020000, pic
[8]);
1248 i2c
= (i2c_bus
*)qdev_get_child_bus(dev
, "i2c");
1249 if (board
->peripherals
& BP_OLED_I2C
) {
1250 i2c_create_slave(i2c
, "ssd0303", 0x3d);
1254 for (i
= 0; i
< 4; i
++) {
1255 if (board
->dc2
& (1 << i
)) {
1256 sysbus_create_simple("pl011_luminary", 0x4000c000 + i
* 0x1000,
1260 if (board
->dc2
& (1 << 4)) {
1261 dev
= sysbus_create_simple("pl022", 0x40008000, pic
[7]);
1262 if (board
->peripherals
& BP_OLED_SSI
) {
1266 bus
= qdev_get_child_bus(dev
, "ssi");
1267 mux
= ssi_create_slave(bus
, "evb6965-ssi");
1268 gpio_out
[GPIO_D
][0] = qdev_get_gpio_in(mux
, 0);
1270 bus
= qdev_get_child_bus(mux
, "ssi0");
1271 ssi_create_slave(bus
, "ssi-sd");
1273 bus
= qdev_get_child_bus(mux
, "ssi1");
1274 dev
= ssi_create_slave(bus
, "ssd0323");
1275 gpio_out
[GPIO_C
][7] = qdev_get_gpio_in(dev
, 0);
1277 /* Make sure the select pin is high. */
1278 qemu_irq_raise(gpio_out
[GPIO_D
][0]);
1281 if (board
->dc4
& (1 << 28)) {
1284 qemu_check_nic_model(&nd_table
[0], "stellaris");
1286 enet
= qdev_create(NULL
, "stellaris_enet");
1287 qdev_set_nic_properties(enet
, &nd_table
[0]);
1288 qdev_init_nofail(enet
);
1289 sysbus_mmio_map(sysbus_from_qdev(enet
), 0, 0x40048000);
1290 sysbus_connect_irq(sysbus_from_qdev(enet
), 0, pic
[42]);
1292 if (board
->peripherals
& BP_GAMEPAD
) {
1293 qemu_irq gpad_irq
[5];
1294 static const int gpad_keycode
[5] = { 0xc8, 0xd0, 0xcb, 0xcd, 0x1d };
1296 gpad_irq
[0] = qemu_irq_invert(gpio_in
[GPIO_E
][0]); /* up */
1297 gpad_irq
[1] = qemu_irq_invert(gpio_in
[GPIO_E
][1]); /* down */
1298 gpad_irq
[2] = qemu_irq_invert(gpio_in
[GPIO_E
][2]); /* left */
1299 gpad_irq
[3] = qemu_irq_invert(gpio_in
[GPIO_E
][3]); /* right */
1300 gpad_irq
[4] = qemu_irq_invert(gpio_in
[GPIO_F
][1]); /* select */
1302 stellaris_gamepad_init(5, gpad_irq
, gpad_keycode
);
1304 for (i
= 0; i
< 7; i
++) {
1305 if (board
->dc4
& (1 << i
)) {
1306 for (j
= 0; j
< 8; j
++) {
1307 if (gpio_out
[i
][j
]) {
1308 qdev_connect_gpio_out(gpio_dev
[i
], j
, gpio_out
[i
][j
]);
1315 /* FIXME: Figure out how to generate these from stellaris_boards. */
1316 static void lm3s811evb_init(ram_addr_t ram_size
,
1317 const char *boot_device
,
1318 const char *kernel_filename
, const char *kernel_cmdline
,
1319 const char *initrd_filename
, const char *cpu_model
)
1321 stellaris_init(kernel_filename
, cpu_model
, &stellaris_boards
[0]);
1324 static void lm3s6965evb_init(ram_addr_t ram_size
,
1325 const char *boot_device
,
1326 const char *kernel_filename
, const char *kernel_cmdline
,
1327 const char *initrd_filename
, const char *cpu_model
)
1329 stellaris_init(kernel_filename
, cpu_model
, &stellaris_boards
[1]);
1332 static QEMUMachine lm3s811evb_machine
= {
1333 .name
= "lm3s811evb",
1334 .desc
= "Stellaris LM3S811EVB",
1335 .init
= lm3s811evb_init
,
1338 static QEMUMachine lm3s6965evb_machine
= {
1339 .name
= "lm3s6965evb",
1340 .desc
= "Stellaris LM3S6965EVB",
1341 .init
= lm3s6965evb_init
,
1344 static void stellaris_machine_init(void)
1346 qemu_register_machine(&lm3s811evb_machine
);
1347 qemu_register_machine(&lm3s6965evb_machine
);
1350 machine_init(stellaris_machine_init
);
1352 static SSISlaveInfo stellaris_ssi_bus_info
= {
1353 .qdev
.name
= "evb6965-ssi",
1354 .qdev
.size
= sizeof(stellaris_ssi_bus_state
),
1355 .init
= stellaris_ssi_bus_init
,
1356 .transfer
= stellaris_ssi_bus_transfer
1359 static void stellaris_register_devices(void)
1361 sysbus_register_dev("stellaris-i2c", sizeof(stellaris_i2c_state
),
1362 stellaris_i2c_init
);
1363 sysbus_register_dev("stellaris-gptm", sizeof(gptm_state
),
1364 stellaris_gptm_init
);
1365 sysbus_register_dev("stellaris-adc", sizeof(stellaris_adc_state
),
1366 stellaris_adc_init
);
1367 ssi_register_slave(&stellaris_ssi_bus_info
);
1370 device_init(stellaris_register_devices
)