* Contributions after 2012-01-13 are licensed under the terms of the
* GNU GPL, version 2 or (at your option) any later version.
*/
+
+#include "qemu/osdep.h"
+#include "cpu.h"
+#include "hw/boards.h"
#include "hw/sysbus.h"
#include "strongarm.h"
#include "qemu/error-report.h"
#include "hw/arm/arm.h"
#include "sysemu/char.h"
#include "sysemu/sysemu.h"
-#include "hw/ssi.h"
+#include "hw/ssi/ssi.h"
+#include "qemu/cutils.h"
//#define DEBUG
};
/* Interrupt Controller */
-typedef struct {
- SysBusDevice busdev;
+
+#define TYPE_STRONGARM_PIC "strongarm_pic"
+#define STRONGARM_PIC(obj) \
+ OBJECT_CHECK(StrongARMPICState, (obj), TYPE_STRONGARM_PIC)
+
+typedef struct StrongARMPICState {
+ SysBusDevice parent_obj;
+
MemoryRegion iomem;
qemu_irq irq;
qemu_irq fiq;
.endianness = DEVICE_NATIVE_ENDIAN,
};
-static int strongarm_pic_initfn(SysBusDevice *dev)
+static int strongarm_pic_initfn(SysBusDevice *sbd)
{
- StrongARMPICState *s = FROM_SYSBUS(StrongARMPICState, dev);
+ DeviceState *dev = DEVICE(sbd);
+ StrongARMPICState *s = STRONGARM_PIC(dev);
- qdev_init_gpio_in(&dev->qdev, strongarm_pic_set_irq, SA_PIC_SRCS);
+ qdev_init_gpio_in(dev, strongarm_pic_set_irq, SA_PIC_SRCS);
memory_region_init_io(&s->iomem, OBJECT(s), &strongarm_pic_ops, s,
"pic", 0x1000);
- sysbus_init_mmio(dev, &s->iomem);
- sysbus_init_irq(dev, &s->irq);
- sysbus_init_irq(dev, &s->fiq);
+ sysbus_init_mmio(sbd, &s->iomem);
+ sysbus_init_irq(sbd, &s->irq);
+ sysbus_init_irq(sbd, &s->fiq);
return 0;
}
.name = "strongarm_pic",
.version_id = 0,
.minimum_version_id = 0,
- .minimum_version_id_old = 0,
.post_load = strongarm_pic_post_load,
.fields = (VMStateField[]) {
VMSTATE_UINT32(pending, StrongARMPICState),
}
static const TypeInfo strongarm_pic_info = {
- .name = "strongarm_pic",
+ .name = TYPE_STRONGARM_PIC,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(StrongARMPICState),
.class_init = strongarm_pic_class_init,
* trim delete isn't emulated, so
* f = 32 768 / (RTTR_trim + 1) */
-typedef struct {
- SysBusDevice busdev;
+#define TYPE_STRONGARM_RTC "strongarm-rtc"
+#define STRONGARM_RTC(obj) \
+ OBJECT_CHECK(StrongARMRTCState, (obj), TYPE_STRONGARM_RTC)
+
+typedef struct StrongARMRTCState {
+ SysBusDevice parent_obj;
+
MemoryRegion iomem;
uint32_t rttr;
uint32_t rtsr;
static void strongarm_rtc_hzupdate(StrongARMRTCState *s)
{
- int64_t rt = qemu_get_clock_ms(rtc_clock);
+ int64_t rt = qemu_clock_get_ms(rtc_clock);
s->last_rcnr += ((rt - s->last_hz) << 15) /
(1000 * ((s->rttr & 0xffff) + 1));
s->last_hz = rt;
static inline void strongarm_rtc_timer_update(StrongARMRTCState *s)
{
if ((s->rtsr & RTSR_HZE) && !(s->rtsr & RTSR_HZ)) {
- qemu_mod_timer(s->rtc_hz, s->last_hz + 1000);
+ timer_mod(s->rtc_hz, s->last_hz + 1000);
} else {
- qemu_del_timer(s->rtc_hz);
+ timer_del(s->rtc_hz);
}
if ((s->rtsr & RTSR_ALE) && !(s->rtsr & RTSR_AL)) {
- qemu_mod_timer(s->rtc_alarm, s->last_hz +
+ timer_mod(s->rtc_alarm, s->last_hz +
(((s->rtar - s->last_rcnr) * 1000 *
((s->rttr & 0xffff) + 1)) >> 15));
} else {
- qemu_del_timer(s->rtc_alarm);
+ timer_del(s->rtc_alarm);
}
}
return s->rtar;
case RCNR:
return s->last_rcnr +
- ((qemu_get_clock_ms(rtc_clock) - s->last_hz) << 15) /
+ ((qemu_clock_get_ms(rtc_clock) - s->last_hz) << 15) /
(1000 * ((s->rttr & 0xffff) + 1));
default:
printf("%s: Bad register 0x" TARGET_FMT_plx "\n", __func__, addr);
static int strongarm_rtc_init(SysBusDevice *dev)
{
- StrongARMRTCState *s = FROM_SYSBUS(StrongARMRTCState, dev);
+ StrongARMRTCState *s = STRONGARM_RTC(dev);
struct tm tm;
s->rttr = 0x0;
qemu_get_timedate(&tm, 0);
s->last_rcnr = (uint32_t) mktimegm(&tm);
- s->last_hz = qemu_get_clock_ms(rtc_clock);
+ s->last_hz = qemu_clock_get_ms(rtc_clock);
- s->rtc_alarm = qemu_new_timer_ms(rtc_clock, strongarm_rtc_alarm_tick, s);
- s->rtc_hz = qemu_new_timer_ms(rtc_clock, strongarm_rtc_hz_tick, s);
+ s->rtc_alarm = timer_new_ms(rtc_clock, strongarm_rtc_alarm_tick, s);
+ s->rtc_hz = timer_new_ms(rtc_clock, strongarm_rtc_hz_tick, s);
sysbus_init_irq(dev, &s->rtc_irq);
sysbus_init_irq(dev, &s->rtc_hz_irq);
.name = "strongarm-rtc",
.version_id = 0,
.minimum_version_id = 0,
- .minimum_version_id_old = 0,
.pre_save = strongarm_rtc_pre_save,
.post_load = strongarm_rtc_post_load,
.fields = (VMStateField[]) {
}
static const TypeInfo strongarm_rtc_sysbus_info = {
- .name = "strongarm-rtc",
+ .name = TYPE_STRONGARM_RTC,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(StrongARMRTCState),
.class_init = strongarm_rtc_sysbus_class_init,
#define GEDR 0x18
#define GAFR 0x1c
+#define TYPE_STRONGARM_GPIO "strongarm-gpio"
+#define STRONGARM_GPIO(obj) \
+ OBJECT_CHECK(StrongARMGPIOInfo, (obj), TYPE_STRONGARM_GPIO)
+
typedef struct StrongARMGPIOInfo StrongARMGPIOInfo;
struct StrongARMGPIOInfo {
SysBusDevice busdev;
uint32_t rising;
uint32_t falling;
uint32_t status;
- uint32_t gpsr;
uint32_t gafr;
uint32_t prev_level;
level = s->olevel & s->dir;
for (diff = s->prev_level ^ level; diff; diff ^= 1 << bit) {
- bit = ffs(diff) - 1;
+ bit = ctz32(diff);
qemu_set_irq(s->handler[bit], (level >> bit) & 1);
}
return s->dir;
case GPSR: /* GPIO Pin-Output Set registers */
- DPRINTF("%s: Read from a write-only register 0x" TARGET_FMT_plx "\n",
- __func__, offset);
- return s->gpsr; /* Return last written value. */
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "strongarm GPIO: read from write only register GPSR\n");
+ return 0;
case GPCR: /* GPIO Pin-Output Clear registers */
- DPRINTF("%s: Read from a write-only register 0x" TARGET_FMT_plx "\n",
- __func__, offset);
- return 31337; /* Specified as unpredictable in the docs. */
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "strongarm GPIO: read from write only register GPCR\n");
+ return 0;
case GRER: /* GPIO Rising-Edge Detect Enable registers */
return s->rising;
case GPSR: /* GPIO Pin-Output Set registers */
s->olevel |= value;
strongarm_gpio_handler_update(s);
- s->gpsr = value;
break;
case GPCR: /* GPIO Pin-Output Clear registers */
DeviceState *dev;
int i;
- dev = qdev_create(NULL, "strongarm-gpio");
+ dev = qdev_create(NULL, TYPE_STRONGARM_GPIO);
qdev_init_nofail(dev);
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
return dev;
}
-static int strongarm_gpio_initfn(SysBusDevice *dev)
+static int strongarm_gpio_initfn(SysBusDevice *sbd)
{
- StrongARMGPIOInfo *s;
+ DeviceState *dev = DEVICE(sbd);
+ StrongARMGPIOInfo *s = STRONGARM_GPIO(dev);
int i;
- s = FROM_SYSBUS(StrongARMGPIOInfo, dev);
-
- qdev_init_gpio_in(&dev->qdev, strongarm_gpio_set, 28);
- qdev_init_gpio_out(&dev->qdev, s->handler, 28);
+ qdev_init_gpio_in(dev, strongarm_gpio_set, 28);
+ qdev_init_gpio_out(dev, s->handler, 28);
memory_region_init_io(&s->iomem, OBJECT(s), &strongarm_gpio_ops, s,
"gpio", 0x1000);
- sysbus_init_mmio(dev, &s->iomem);
+ sysbus_init_mmio(sbd, &s->iomem);
for (i = 0; i < 11; i++) {
- sysbus_init_irq(dev, &s->irqs[i]);
+ sysbus_init_irq(sbd, &s->irqs[i]);
}
- sysbus_init_irq(dev, &s->irqX);
+ sysbus_init_irq(sbd, &s->irqX);
return 0;
}
.name = "strongarm-gpio",
.version_id = 0,
.minimum_version_id = 0,
- .minimum_version_id_old = 0,
.fields = (VMStateField[]) {
VMSTATE_UINT32(ilevel, StrongARMGPIOInfo),
VMSTATE_UINT32(olevel, StrongARMGPIOInfo),
VMSTATE_UINT32(falling, StrongARMGPIOInfo),
VMSTATE_UINT32(status, StrongARMGPIOInfo),
VMSTATE_UINT32(gafr, StrongARMGPIOInfo),
+ VMSTATE_UINT32(prev_level, StrongARMGPIOInfo),
VMSTATE_END_OF_LIST(),
},
};
k->init = strongarm_gpio_initfn;
dc->desc = "StrongARM GPIO controller";
+ dc->vmsd = &vmstate_strongarm_gpio_regs;
}
static const TypeInfo strongarm_gpio_info = {
- .name = "strongarm-gpio",
+ .name = TYPE_STRONGARM_GPIO,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(StrongARMGPIOInfo),
.class_init = strongarm_gpio_class_init,
#define PSDR 0x0c
#define PPFR 0x10
+#define TYPE_STRONGARM_PPC "strongarm-ppc"
+#define STRONGARM_PPC(obj) \
+ OBJECT_CHECK(StrongARMPPCInfo, (obj), TYPE_STRONGARM_PPC)
+
typedef struct StrongARMPPCInfo StrongARMPPCInfo;
struct StrongARMPPCInfo {
- SysBusDevice busdev;
+ SysBusDevice parent_obj;
+
MemoryRegion iomem;
qemu_irq handler[28];
level = s->olevel & s->dir;
for (diff = s->prev_level ^ level; diff; diff ^= 1 << bit) {
- bit = ffs(diff) - 1;
+ bit = ctz32(diff);
qemu_set_irq(s->handler[bit], (level >> bit) & 1);
}
.endianness = DEVICE_NATIVE_ENDIAN,
};
-static int strongarm_ppc_init(SysBusDevice *dev)
+static int strongarm_ppc_init(SysBusDevice *sbd)
{
- StrongARMPPCInfo *s;
-
- s = FROM_SYSBUS(StrongARMPPCInfo, dev);
+ DeviceState *dev = DEVICE(sbd);
+ StrongARMPPCInfo *s = STRONGARM_PPC(dev);
- qdev_init_gpio_in(&dev->qdev, strongarm_ppc_set, 22);
- qdev_init_gpio_out(&dev->qdev, s->handler, 22);
+ qdev_init_gpio_in(dev, strongarm_ppc_set, 22);
+ qdev_init_gpio_out(dev, s->handler, 22);
memory_region_init_io(&s->iomem, OBJECT(s), &strongarm_ppc_ops, s,
"ppc", 0x1000);
- sysbus_init_mmio(dev, &s->iomem);
+ sysbus_init_mmio(sbd, &s->iomem);
return 0;
}
.name = "strongarm-ppc",
.version_id = 0,
.minimum_version_id = 0,
- .minimum_version_id_old = 0,
.fields = (VMStateField[]) {
VMSTATE_UINT32(ilevel, StrongARMPPCInfo),
VMSTATE_UINT32(olevel, StrongARMPPCInfo),
VMSTATE_UINT32(ppar, StrongARMPPCInfo),
VMSTATE_UINT32(psdr, StrongARMPPCInfo),
VMSTATE_UINT32(ppfr, StrongARMPPCInfo),
+ VMSTATE_UINT32(prev_level, StrongARMPPCInfo),
VMSTATE_END_OF_LIST(),
},
};
k->init = strongarm_ppc_init;
dc->desc = "StrongARM PPC controller";
+ dc->vmsd = &vmstate_strongarm_ppc_regs;
}
static const TypeInfo strongarm_ppc_info = {
- .name = "strongarm-ppc",
+ .name = TYPE_STRONGARM_PPC,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(StrongARMPPCInfo),
.class_init = strongarm_ppc_class_init,
#define RX_FIFO_FRE (1 << 9)
#define RX_FIFO_ROR (1 << 10)
-typedef struct {
- SysBusDevice busdev;
+#define TYPE_STRONGARM_UART "strongarm-uart"
+#define STRONGARM_UART(obj) \
+ OBJECT_CHECK(StrongARMUARTState, (obj), TYPE_STRONGARM_UART)
+
+typedef struct StrongARMUARTState {
+ SysBusDevice parent_obj;
+
MemoryRegion iomem;
CharDriverState *chr;
qemu_irq irq;
ssp.parity = parity;
ssp.data_bits = data_bits;
ssp.stop_bits = stop_bits;
- s->char_transmit_time = (get_ticks_per_sec() / speed) * frame_size;
+ s->char_transmit_time = (NANOSECONDS_PER_SECOND / speed) * frame_size;
if (s->chr) {
qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
}
}
/* call the timeout receive callback in 3 char transmit time */
- qemu_mod_timer(s->rx_timeout_timer,
- qemu_get_clock_ns(vm_clock) + s->char_transmit_time * 3);
+ timer_mod(s->rx_timeout_timer,
+ qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + s->char_transmit_time * 3);
strongarm_uart_update_status(s);
strongarm_uart_update_int_status(s);
static void strongarm_uart_tx(void *opaque)
{
StrongARMUARTState *s = opaque;
- uint64_t new_xmit_ts = qemu_get_clock_ns(vm_clock);
+ uint64_t new_xmit_ts = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
if (s->utcr3 & UTCR3_LBM) /* loopback */ {
strongarm_uart_receive(s, &s->tx_fifo[s->tx_start], 1);
s->tx_start = (s->tx_start + 1) % 8;
s->tx_len--;
if (s->tx_len) {
- qemu_mod_timer(s->tx_timer, new_xmit_ts + s->char_transmit_time);
+ timer_mod(s->tx_timer, new_xmit_ts + s->char_transmit_time);
}
strongarm_uart_update_status(s);
strongarm_uart_update_int_status(s);
static int strongarm_uart_init(SysBusDevice *dev)
{
- StrongARMUARTState *s = FROM_SYSBUS(StrongARMUARTState, dev);
+ StrongARMUARTState *s = STRONGARM_UART(dev);
memory_region_init_io(&s->iomem, OBJECT(s), &strongarm_uart_ops, s,
"uart", 0x10000);
sysbus_init_mmio(dev, &s->iomem);
sysbus_init_irq(dev, &s->irq);
- s->rx_timeout_timer = qemu_new_timer_ns(vm_clock, strongarm_uart_rx_to, s);
- s->tx_timer = qemu_new_timer_ns(vm_clock, strongarm_uart_tx, s);
+ s->rx_timeout_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, strongarm_uart_rx_to, s);
+ s->tx_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, strongarm_uart_tx, s);
if (s->chr) {
qemu_chr_add_handlers(s->chr,
static void strongarm_uart_reset(DeviceState *dev)
{
- StrongARMUARTState *s = DO_UPCAST(StrongARMUARTState, busdev.qdev, dev);
+ StrongARMUARTState *s = STRONGARM_UART(dev);
s->utcr0 = UTCR0_DSS; /* 8 data, no parity */
s->brd = 23; /* 9600 */
/* restart rx timeout timer */
if (s->rx_len) {
- qemu_mod_timer(s->rx_timeout_timer,
- qemu_get_clock_ns(vm_clock) + s->char_transmit_time * 3);
+ timer_mod(s->rx_timeout_timer,
+ qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + s->char_transmit_time * 3);
}
return 0;
.name = "strongarm-uart",
.version_id = 0,
.minimum_version_id = 0,
- .minimum_version_id_old = 0,
.post_load = strongarm_uart_post_load,
.fields = (VMStateField[]) {
VMSTATE_UINT8(utcr0, StrongARMUARTState),
}
static const TypeInfo strongarm_uart_info = {
- .name = "strongarm-uart",
+ .name = TYPE_STRONGARM_UART,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(StrongARMUARTState),
.class_init = strongarm_uart_class_init,
};
/* Synchronous Serial Ports */
-typedef struct {
- SysBusDevice busdev;
+
+#define TYPE_STRONGARM_SSP "strongarm-ssp"
+#define STRONGARM_SSP(obj) \
+ OBJECT_CHECK(StrongARMSSPState, (obj), TYPE_STRONGARM_SSP)
+
+typedef struct StrongARMSSPState {
+ SysBusDevice parent_obj;
+
MemoryRegion iomem;
qemu_irq irq;
SSIBus *bus;
return 0;
}
-static int strongarm_ssp_init(SysBusDevice *dev)
+static int strongarm_ssp_init(SysBusDevice *sbd)
{
- StrongARMSSPState *s = FROM_SYSBUS(StrongARMSSPState, dev);
+ DeviceState *dev = DEVICE(sbd);
+ StrongARMSSPState *s = STRONGARM_SSP(dev);
- sysbus_init_irq(dev, &s->irq);
+ sysbus_init_irq(sbd, &s->irq);
memory_region_init_io(&s->iomem, OBJECT(s), &strongarm_ssp_ops, s,
"ssp", 0x1000);
- sysbus_init_mmio(dev, &s->iomem);
+ sysbus_init_mmio(sbd, &s->iomem);
- s->bus = ssi_create_bus(&dev->qdev, "ssi");
+ s->bus = ssi_create_bus(dev, "ssi");
return 0;
}
static void strongarm_ssp_reset(DeviceState *dev)
{
- StrongARMSSPState *s = DO_UPCAST(StrongARMSSPState, busdev.qdev, dev);
+ StrongARMSSPState *s = STRONGARM_SSP(dev);
+
s->sssr = 0x03; /* 3 bit data, SPI, disabled */
s->rx_start = 0;
s->rx_level = 0;
.name = "strongarm-ssp",
.version_id = 0,
.minimum_version_id = 0,
- .minimum_version_id_old = 0,
.post_load = strongarm_ssp_post_load,
.fields = (VMStateField[]) {
VMSTATE_UINT16_ARRAY(sscr, StrongARMSSPState, 2),
}
static const TypeInfo strongarm_ssp_info = {
- .name = "strongarm-ssp",
+ .name = TYPE_STRONGARM_SSP,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(StrongARMSSPState),
.class_init = strongarm_ssp_class_init,
unsigned int sdram_size, const char *rev)
{
StrongARMState *s;
- qemu_irq *pic;
int i;
- s = g_malloc0(sizeof(StrongARMState));
+ s = g_new0(StrongARMState, 1);
if (!rev) {
rev = "sa1110-b5";
exit(1);
}
- memory_region_init_ram(&s->sdram, NULL, "strongarm.sdram", sdram_size);
- vmstate_register_ram_global(&s->sdram);
+ memory_region_allocate_system_memory(&s->sdram, NULL, "strongarm.sdram",
+ sdram_size);
memory_region_add_subregion(sysmem, SA_SDCS0, &s->sdram);
- pic = arm_pic_init_cpu(s->cpu);
s->pic = sysbus_create_varargs("strongarm_pic", 0x90050000,
- pic[ARM_PIC_CPU_IRQ], pic[ARM_PIC_CPU_FIQ], NULL);
+ qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_IRQ),
+ qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_FIQ),
+ NULL);
sysbus_create_varargs("pxa25x-timer", 0x90000000,
qdev_get_gpio_in(s->pic, SA_PIC_OSTC0),
qdev_get_gpio_in(s->pic, SA_PIC_OSTC3),
NULL);
- sysbus_create_simple("strongarm-rtc", 0x90010000,
+ sysbus_create_simple(TYPE_STRONGARM_RTC, 0x90010000,
qdev_get_gpio_in(s->pic, SA_PIC_RTC_ALARM));
s->gpio = strongarm_gpio_init(0x90040000, s->pic);
- s->ppc = sysbus_create_varargs("strongarm-ppc", 0x90060000, NULL);
+ s->ppc = sysbus_create_varargs(TYPE_STRONGARM_PPC, 0x90060000, NULL);
for (i = 0; sa_serial[i].io_base; i++) {
- DeviceState *dev = qdev_create(NULL, "strongarm-uart");
+ DeviceState *dev = qdev_create(NULL, TYPE_STRONGARM_UART);
qdev_prop_set_chr(dev, "chardev", serial_hds[i]);
qdev_init_nofail(dev);
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0,
qdev_get_gpio_in(s->pic, sa_serial[i].irq));
}
- s->ssp = sysbus_create_varargs("strongarm-ssp", 0x80070000,
+ s->ssp = sysbus_create_varargs(TYPE_STRONGARM_SSP, 0x80070000,
qdev_get_gpio_in(s->pic, SA_PIC_SSP), NULL);
s->ssp_bus = (SSIBus *)qdev_get_child_bus(s->ssp, "ssi");