diff options
author | RajithaY <rajithax.yerrumsetty@intel.com> | 2017-04-25 03:31:15 -0700 |
---|---|---|
committer | Rajitha Yerrumchetty <rajithax.yerrumsetty@intel.com> | 2017-05-22 06:48:08 +0000 |
commit | bb756eebdac6fd24e8919e2c43f7d2c8c4091f59 (patch) | |
tree | ca11e03542edf2d8f631efeca5e1626d211107e3 /qemu/hw/arm/strongarm.c | |
parent | a14b48d18a9ed03ec191cf16b162206998a895ce (diff) |
Adding qemu as a submodule of KVMFORNFV
This Patch includes the changes to add qemu as a submodule to
kvmfornfv repo and make use of the updated latest qemu for the
execution of all testcase
Change-Id: I1280af507a857675c7f81d30c95255635667bdd7
Signed-off-by:RajithaY<rajithax.yerrumsetty@intel.com>
Diffstat (limited to 'qemu/hw/arm/strongarm.c')
-rw-r--r-- | qemu/hw/arm/strongarm.c | 1662 |
1 files changed, 0 insertions, 1662 deletions
diff --git a/qemu/hw/arm/strongarm.c b/qemu/hw/arm/strongarm.c deleted file mode 100644 index 1eeb1ab39..000000000 --- a/qemu/hw/arm/strongarm.c +++ /dev/null @@ -1,1662 +0,0 @@ -/* - * StrongARM SA-1100/SA-1110 emulation - * - * Copyright (C) 2011 Dmitry Eremin-Solenikov - * - * Largely based on StrongARM emulation: - * Copyright (c) 2006 Openedhand Ltd. - * Written by Andrzej Zaborowski <balrog@zabor.org> - * - * UART code based on QEMU 16550A UART emulation - * Copyright (c) 2003-2004 Fabrice Bellard - * Copyright (c) 2008 Citrix Systems, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, see <http://www.gnu.org/licenses/>. - * - * 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/ssi.h" -#include "qemu/cutils.h" - -//#define DEBUG - -/* - TODO - - Implement cp15, c14 ? - - Implement cp15, c15 !!! (idle used in L) - - Implement idle mode handling/DIM - - Implement sleep mode/Wake sources - - Implement reset control - - Implement memory control regs - - PCMCIA handling - - Maybe support MBGNT/MBREQ - - DMA channels - - GPCLK - - IrDA - - MCP - - Enhance UART with modem signals - */ - -#ifdef DEBUG -# define DPRINTF(format, ...) printf(format , ## __VA_ARGS__) -#else -# define DPRINTF(format, ...) do { } while (0) -#endif - -static struct { - hwaddr io_base; - int irq; -} sa_serial[] = { - { 0x80010000, SA_PIC_UART1 }, - { 0x80030000, SA_PIC_UART2 }, - { 0x80050000, SA_PIC_UART3 }, - { 0, 0 } -}; - -/* Interrupt Controller */ - -#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; - - uint32_t pending; - uint32_t enabled; - uint32_t is_fiq; - uint32_t int_idle; -} StrongARMPICState; - -#define ICIP 0x00 -#define ICMR 0x04 -#define ICLR 0x08 -#define ICFP 0x10 -#define ICPR 0x20 -#define ICCR 0x0c - -#define SA_PIC_SRCS 32 - - -static void strongarm_pic_update(void *opaque) -{ - StrongARMPICState *s = opaque; - - /* FIXME: reflect DIM */ - qemu_set_irq(s->fiq, s->pending & s->enabled & s->is_fiq); - qemu_set_irq(s->irq, s->pending & s->enabled & ~s->is_fiq); -} - -static void strongarm_pic_set_irq(void *opaque, int irq, int level) -{ - StrongARMPICState *s = opaque; - - if (level) { - s->pending |= 1 << irq; - } else { - s->pending &= ~(1 << irq); - } - - strongarm_pic_update(s); -} - -static uint64_t strongarm_pic_mem_read(void *opaque, hwaddr offset, - unsigned size) -{ - StrongARMPICState *s = opaque; - - switch (offset) { - case ICIP: - return s->pending & ~s->is_fiq & s->enabled; - case ICMR: - return s->enabled; - case ICLR: - return s->is_fiq; - case ICCR: - return s->int_idle == 0; - case ICFP: - return s->pending & s->is_fiq & s->enabled; - case ICPR: - return s->pending; - default: - printf("%s: Bad register offset 0x" TARGET_FMT_plx "\n", - __func__, offset); - return 0; - } -} - -static void strongarm_pic_mem_write(void *opaque, hwaddr offset, - uint64_t value, unsigned size) -{ - StrongARMPICState *s = opaque; - - switch (offset) { - case ICMR: - s->enabled = value; - break; - case ICLR: - s->is_fiq = value; - break; - case ICCR: - s->int_idle = (value & 1) ? 0 : ~0; - break; - default: - printf("%s: Bad register offset 0x" TARGET_FMT_plx "\n", - __func__, offset); - break; - } - strongarm_pic_update(s); -} - -static const MemoryRegionOps strongarm_pic_ops = { - .read = strongarm_pic_mem_read, - .write = strongarm_pic_mem_write, - .endianness = DEVICE_NATIVE_ENDIAN, -}; - -static int strongarm_pic_initfn(SysBusDevice *sbd) -{ - DeviceState *dev = DEVICE(sbd); - StrongARMPICState *s = STRONGARM_PIC(dev); - - 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(sbd, &s->iomem); - sysbus_init_irq(sbd, &s->irq); - sysbus_init_irq(sbd, &s->fiq); - - return 0; -} - -static int strongarm_pic_post_load(void *opaque, int version_id) -{ - strongarm_pic_update(opaque); - return 0; -} - -static VMStateDescription vmstate_strongarm_pic_regs = { - .name = "strongarm_pic", - .version_id = 0, - .minimum_version_id = 0, - .post_load = strongarm_pic_post_load, - .fields = (VMStateField[]) { - VMSTATE_UINT32(pending, StrongARMPICState), - VMSTATE_UINT32(enabled, StrongARMPICState), - VMSTATE_UINT32(is_fiq, StrongARMPICState), - VMSTATE_UINT32(int_idle, StrongARMPICState), - VMSTATE_END_OF_LIST(), - }, -}; - -static void strongarm_pic_class_init(ObjectClass *klass, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(klass); - SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); - - k->init = strongarm_pic_initfn; - dc->desc = "StrongARM PIC"; - dc->vmsd = &vmstate_strongarm_pic_regs; -} - -static const TypeInfo strongarm_pic_info = { - .name = TYPE_STRONGARM_PIC, - .parent = TYPE_SYS_BUS_DEVICE, - .instance_size = sizeof(StrongARMPICState), - .class_init = strongarm_pic_class_init, -}; - -/* Real-Time Clock */ -#define RTAR 0x00 /* RTC Alarm register */ -#define RCNR 0x04 /* RTC Counter register */ -#define RTTR 0x08 /* RTC Timer Trim register */ -#define RTSR 0x10 /* RTC Status register */ - -#define RTSR_AL (1 << 0) /* RTC Alarm detected */ -#define RTSR_HZ (1 << 1) /* RTC 1Hz detected */ -#define RTSR_ALE (1 << 2) /* RTC Alarm enable */ -#define RTSR_HZE (1 << 3) /* RTC 1Hz enable */ - -/* 16 LSB of RTTR are clockdiv for internal trim logic, - * trim delete isn't emulated, so - * f = 32 768 / (RTTR_trim + 1) */ - -#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; - uint32_t rtar; - uint32_t last_rcnr; - int64_t last_hz; - QEMUTimer *rtc_alarm; - QEMUTimer *rtc_hz; - qemu_irq rtc_irq; - qemu_irq rtc_hz_irq; -} StrongARMRTCState; - -static inline void strongarm_rtc_int_update(StrongARMRTCState *s) -{ - qemu_set_irq(s->rtc_irq, s->rtsr & RTSR_AL); - qemu_set_irq(s->rtc_hz_irq, s->rtsr & RTSR_HZ); -} - -static void strongarm_rtc_hzupdate(StrongARMRTCState *s) -{ - 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)) { - timer_mod(s->rtc_hz, s->last_hz + 1000); - } else { - timer_del(s->rtc_hz); - } - - if ((s->rtsr & RTSR_ALE) && !(s->rtsr & RTSR_AL)) { - timer_mod(s->rtc_alarm, s->last_hz + - (((s->rtar - s->last_rcnr) * 1000 * - ((s->rttr & 0xffff) + 1)) >> 15)); - } else { - timer_del(s->rtc_alarm); - } -} - -static inline void strongarm_rtc_alarm_tick(void *opaque) -{ - StrongARMRTCState *s = opaque; - s->rtsr |= RTSR_AL; - strongarm_rtc_timer_update(s); - strongarm_rtc_int_update(s); -} - -static inline void strongarm_rtc_hz_tick(void *opaque) -{ - StrongARMRTCState *s = opaque; - s->rtsr |= RTSR_HZ; - strongarm_rtc_timer_update(s); - strongarm_rtc_int_update(s); -} - -static uint64_t strongarm_rtc_read(void *opaque, hwaddr addr, - unsigned size) -{ - StrongARMRTCState *s = opaque; - - switch (addr) { - case RTTR: - return s->rttr; - case RTSR: - return s->rtsr; - case RTAR: - return s->rtar; - case RCNR: - return s->last_rcnr + - ((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); - return 0; - } -} - -static void strongarm_rtc_write(void *opaque, hwaddr addr, - uint64_t value, unsigned size) -{ - StrongARMRTCState *s = opaque; - uint32_t old_rtsr; - - switch (addr) { - case RTTR: - strongarm_rtc_hzupdate(s); - s->rttr = value; - strongarm_rtc_timer_update(s); - break; - - case RTSR: - old_rtsr = s->rtsr; - s->rtsr = (value & (RTSR_ALE | RTSR_HZE)) | - (s->rtsr & ~(value & (RTSR_AL | RTSR_HZ))); - - if (s->rtsr != old_rtsr) { - strongarm_rtc_timer_update(s); - } - - strongarm_rtc_int_update(s); - break; - - case RTAR: - s->rtar = value; - strongarm_rtc_timer_update(s); - break; - - case RCNR: - strongarm_rtc_hzupdate(s); - s->last_rcnr = value; - strongarm_rtc_timer_update(s); - break; - - default: - printf("%s: Bad register 0x" TARGET_FMT_plx "\n", __func__, addr); - } -} - -static const MemoryRegionOps strongarm_rtc_ops = { - .read = strongarm_rtc_read, - .write = strongarm_rtc_write, - .endianness = DEVICE_NATIVE_ENDIAN, -}; - -static int strongarm_rtc_init(SysBusDevice *dev) -{ - StrongARMRTCState *s = STRONGARM_RTC(dev); - struct tm tm; - - s->rttr = 0x0; - s->rtsr = 0; - - qemu_get_timedate(&tm, 0); - - s->last_rcnr = (uint32_t) mktimegm(&tm); - s->last_hz = qemu_clock_get_ms(rtc_clock); - - 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); - - memory_region_init_io(&s->iomem, OBJECT(s), &strongarm_rtc_ops, s, - "rtc", 0x10000); - sysbus_init_mmio(dev, &s->iomem); - - return 0; -} - -static void strongarm_rtc_pre_save(void *opaque) -{ - StrongARMRTCState *s = opaque; - - strongarm_rtc_hzupdate(s); -} - -static int strongarm_rtc_post_load(void *opaque, int version_id) -{ - StrongARMRTCState *s = opaque; - - strongarm_rtc_timer_update(s); - strongarm_rtc_int_update(s); - - return 0; -} - -static const VMStateDescription vmstate_strongarm_rtc_regs = { - .name = "strongarm-rtc", - .version_id = 0, - .minimum_version_id = 0, - .pre_save = strongarm_rtc_pre_save, - .post_load = strongarm_rtc_post_load, - .fields = (VMStateField[]) { - VMSTATE_UINT32(rttr, StrongARMRTCState), - VMSTATE_UINT32(rtsr, StrongARMRTCState), - VMSTATE_UINT32(rtar, StrongARMRTCState), - VMSTATE_UINT32(last_rcnr, StrongARMRTCState), - VMSTATE_INT64(last_hz, StrongARMRTCState), - VMSTATE_END_OF_LIST(), - }, -}; - -static void strongarm_rtc_sysbus_class_init(ObjectClass *klass, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(klass); - SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); - - k->init = strongarm_rtc_init; - dc->desc = "StrongARM RTC Controller"; - dc->vmsd = &vmstate_strongarm_rtc_regs; -} - -static const TypeInfo strongarm_rtc_sysbus_info = { - .name = TYPE_STRONGARM_RTC, - .parent = TYPE_SYS_BUS_DEVICE, - .instance_size = sizeof(StrongARMRTCState), - .class_init = strongarm_rtc_sysbus_class_init, -}; - -/* GPIO */ -#define GPLR 0x00 -#define GPDR 0x04 -#define GPSR 0x08 -#define GPCR 0x0c -#define GRER 0x10 -#define GFER 0x14 -#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; - MemoryRegion iomem; - qemu_irq handler[28]; - qemu_irq irqs[11]; - qemu_irq irqX; - - uint32_t ilevel; - uint32_t olevel; - uint32_t dir; - uint32_t rising; - uint32_t falling; - uint32_t status; - uint32_t gafr; - - uint32_t prev_level; -}; - - -static void strongarm_gpio_irq_update(StrongARMGPIOInfo *s) -{ - int i; - for (i = 0; i < 11; i++) { - qemu_set_irq(s->irqs[i], s->status & (1 << i)); - } - - qemu_set_irq(s->irqX, (s->status & ~0x7ff)); -} - -static void strongarm_gpio_set(void *opaque, int line, int level) -{ - StrongARMGPIOInfo *s = opaque; - uint32_t mask; - - mask = 1 << line; - - if (level) { - s->status |= s->rising & mask & - ~s->ilevel & ~s->dir; - s->ilevel |= mask; - } else { - s->status |= s->falling & mask & - s->ilevel & ~s->dir; - s->ilevel &= ~mask; - } - - if (s->status & mask) { - strongarm_gpio_irq_update(s); - } -} - -static void strongarm_gpio_handler_update(StrongARMGPIOInfo *s) -{ - uint32_t level, diff; - int bit; - - level = s->olevel & s->dir; - - for (diff = s->prev_level ^ level; diff; diff ^= 1 << bit) { - bit = ctz32(diff); - qemu_set_irq(s->handler[bit], (level >> bit) & 1); - } - - s->prev_level = level; -} - -static uint64_t strongarm_gpio_read(void *opaque, hwaddr offset, - unsigned size) -{ - StrongARMGPIOInfo *s = opaque; - - switch (offset) { - case GPDR: /* GPIO Pin-Direction registers */ - return s->dir; - - case GPSR: /* GPIO Pin-Output Set registers */ - qemu_log_mask(LOG_GUEST_ERROR, - "strongarm GPIO: read from write only register GPSR\n"); - return 0; - - case GPCR: /* GPIO Pin-Output Clear registers */ - 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 GFER: /* GPIO Falling-Edge Detect Enable registers */ - return s->falling; - - case GAFR: /* GPIO Alternate Function registers */ - return s->gafr; - - case GPLR: /* GPIO Pin-Level registers */ - return (s->olevel & s->dir) | - (s->ilevel & ~s->dir); - - case GEDR: /* GPIO Edge Detect Status registers */ - return s->status; - - default: - printf("%s: Bad offset 0x" TARGET_FMT_plx "\n", __func__, offset); - } - - return 0; -} - -static void strongarm_gpio_write(void *opaque, hwaddr offset, - uint64_t value, unsigned size) -{ - StrongARMGPIOInfo *s = opaque; - - switch (offset) { - case GPDR: /* GPIO Pin-Direction registers */ - s->dir = value; - strongarm_gpio_handler_update(s); - break; - - case GPSR: /* GPIO Pin-Output Set registers */ - s->olevel |= value; - strongarm_gpio_handler_update(s); - break; - - case GPCR: /* GPIO Pin-Output Clear registers */ - s->olevel &= ~value; - strongarm_gpio_handler_update(s); - break; - - case GRER: /* GPIO Rising-Edge Detect Enable registers */ - s->rising = value; - break; - - case GFER: /* GPIO Falling-Edge Detect Enable registers */ - s->falling = value; - break; - - case GAFR: /* GPIO Alternate Function registers */ - s->gafr = value; - break; - - case GEDR: /* GPIO Edge Detect Status registers */ - s->status &= ~value; - strongarm_gpio_irq_update(s); - break; - - default: - printf("%s: Bad offset 0x" TARGET_FMT_plx "\n", __func__, offset); - } -} - -static const MemoryRegionOps strongarm_gpio_ops = { - .read = strongarm_gpio_read, - .write = strongarm_gpio_write, - .endianness = DEVICE_NATIVE_ENDIAN, -}; - -static DeviceState *strongarm_gpio_init(hwaddr base, - DeviceState *pic) -{ - DeviceState *dev; - int i; - - dev = qdev_create(NULL, TYPE_STRONGARM_GPIO); - qdev_init_nofail(dev); - - sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base); - for (i = 0; i < 12; i++) - sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, - qdev_get_gpio_in(pic, SA_PIC_GPIO0_EDGE + i)); - - return dev; -} - -static int strongarm_gpio_initfn(SysBusDevice *sbd) -{ - DeviceState *dev = DEVICE(sbd); - StrongARMGPIOInfo *s = STRONGARM_GPIO(dev); - int i; - - 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(sbd, &s->iomem); - for (i = 0; i < 11; i++) { - sysbus_init_irq(sbd, &s->irqs[i]); - } - sysbus_init_irq(sbd, &s->irqX); - - return 0; -} - -static const VMStateDescription vmstate_strongarm_gpio_regs = { - .name = "strongarm-gpio", - .version_id = 0, - .minimum_version_id = 0, - .fields = (VMStateField[]) { - VMSTATE_UINT32(ilevel, StrongARMGPIOInfo), - VMSTATE_UINT32(olevel, StrongARMGPIOInfo), - VMSTATE_UINT32(dir, StrongARMGPIOInfo), - VMSTATE_UINT32(rising, StrongARMGPIOInfo), - VMSTATE_UINT32(falling, StrongARMGPIOInfo), - VMSTATE_UINT32(status, StrongARMGPIOInfo), - VMSTATE_UINT32(gafr, StrongARMGPIOInfo), - VMSTATE_UINT32(prev_level, StrongARMGPIOInfo), - VMSTATE_END_OF_LIST(), - }, -}; - -static void strongarm_gpio_class_init(ObjectClass *klass, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(klass); - SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); - - k->init = strongarm_gpio_initfn; - dc->desc = "StrongARM GPIO controller"; - dc->vmsd = &vmstate_strongarm_gpio_regs; -} - -static const TypeInfo strongarm_gpio_info = { - .name = TYPE_STRONGARM_GPIO, - .parent = TYPE_SYS_BUS_DEVICE, - .instance_size = sizeof(StrongARMGPIOInfo), - .class_init = strongarm_gpio_class_init, -}; - -/* Peripheral Pin Controller */ -#define PPDR 0x00 -#define PPSR 0x04 -#define PPAR 0x08 -#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 parent_obj; - - MemoryRegion iomem; - qemu_irq handler[28]; - - uint32_t ilevel; - uint32_t olevel; - uint32_t dir; - uint32_t ppar; - uint32_t psdr; - uint32_t ppfr; - - uint32_t prev_level; -}; - -static void strongarm_ppc_set(void *opaque, int line, int level) -{ - StrongARMPPCInfo *s = opaque; - - if (level) { - s->ilevel |= 1 << line; - } else { - s->ilevel &= ~(1 << line); - } -} - -static void strongarm_ppc_handler_update(StrongARMPPCInfo *s) -{ - uint32_t level, diff; - int bit; - - level = s->olevel & s->dir; - - for (diff = s->prev_level ^ level; diff; diff ^= 1 << bit) { - bit = ctz32(diff); - qemu_set_irq(s->handler[bit], (level >> bit) & 1); - } - - s->prev_level = level; -} - -static uint64_t strongarm_ppc_read(void *opaque, hwaddr offset, - unsigned size) -{ - StrongARMPPCInfo *s = opaque; - - switch (offset) { - case PPDR: /* PPC Pin Direction registers */ - return s->dir | ~0x3fffff; - - case PPSR: /* PPC Pin State registers */ - return (s->olevel & s->dir) | - (s->ilevel & ~s->dir) | - ~0x3fffff; - - case PPAR: - return s->ppar | ~0x41000; - - case PSDR: - return s->psdr; - - case PPFR: - return s->ppfr | ~0x7f001; - - default: - printf("%s: Bad offset 0x" TARGET_FMT_plx "\n", __func__, offset); - } - - return 0; -} - -static void strongarm_ppc_write(void *opaque, hwaddr offset, - uint64_t value, unsigned size) -{ - StrongARMPPCInfo *s = opaque; - - switch (offset) { - case PPDR: /* PPC Pin Direction registers */ - s->dir = value & 0x3fffff; - strongarm_ppc_handler_update(s); - break; - - case PPSR: /* PPC Pin State registers */ - s->olevel = value & s->dir & 0x3fffff; - strongarm_ppc_handler_update(s); - break; - - case PPAR: - s->ppar = value & 0x41000; - break; - - case PSDR: - s->psdr = value & 0x3fffff; - break; - - case PPFR: - s->ppfr = value & 0x7f001; - break; - - default: - printf("%s: Bad offset 0x" TARGET_FMT_plx "\n", __func__, offset); - } -} - -static const MemoryRegionOps strongarm_ppc_ops = { - .read = strongarm_ppc_read, - .write = strongarm_ppc_write, - .endianness = DEVICE_NATIVE_ENDIAN, -}; - -static int strongarm_ppc_init(SysBusDevice *sbd) -{ - DeviceState *dev = DEVICE(sbd); - StrongARMPPCInfo *s = STRONGARM_PPC(dev); - - 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(sbd, &s->iomem); - - return 0; -} - -static const VMStateDescription vmstate_strongarm_ppc_regs = { - .name = "strongarm-ppc", - .version_id = 0, - .minimum_version_id = 0, - .fields = (VMStateField[]) { - VMSTATE_UINT32(ilevel, StrongARMPPCInfo), - VMSTATE_UINT32(olevel, StrongARMPPCInfo), - VMSTATE_UINT32(dir, StrongARMPPCInfo), - VMSTATE_UINT32(ppar, StrongARMPPCInfo), - VMSTATE_UINT32(psdr, StrongARMPPCInfo), - VMSTATE_UINT32(ppfr, StrongARMPPCInfo), - VMSTATE_UINT32(prev_level, StrongARMPPCInfo), - VMSTATE_END_OF_LIST(), - }, -}; - -static void strongarm_ppc_class_init(ObjectClass *klass, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(klass); - SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); - - k->init = strongarm_ppc_init; - dc->desc = "StrongARM PPC controller"; - dc->vmsd = &vmstate_strongarm_ppc_regs; -} - -static const TypeInfo strongarm_ppc_info = { - .name = TYPE_STRONGARM_PPC, - .parent = TYPE_SYS_BUS_DEVICE, - .instance_size = sizeof(StrongARMPPCInfo), - .class_init = strongarm_ppc_class_init, -}; - -/* UART Ports */ -#define UTCR0 0x00 -#define UTCR1 0x04 -#define UTCR2 0x08 -#define UTCR3 0x0c -#define UTDR 0x14 -#define UTSR0 0x1c -#define UTSR1 0x20 - -#define UTCR0_PE (1 << 0) /* Parity enable */ -#define UTCR0_OES (1 << 1) /* Even parity */ -#define UTCR0_SBS (1 << 2) /* 2 stop bits */ -#define UTCR0_DSS (1 << 3) /* 8-bit data */ - -#define UTCR3_RXE (1 << 0) /* Rx enable */ -#define UTCR3_TXE (1 << 1) /* Tx enable */ -#define UTCR3_BRK (1 << 2) /* Force Break */ -#define UTCR3_RIE (1 << 3) /* Rx int enable */ -#define UTCR3_TIE (1 << 4) /* Tx int enable */ -#define UTCR3_LBM (1 << 5) /* Loopback */ - -#define UTSR0_TFS (1 << 0) /* Tx FIFO nearly empty */ -#define UTSR0_RFS (1 << 1) /* Rx FIFO nearly full */ -#define UTSR0_RID (1 << 2) /* Receiver Idle */ -#define UTSR0_RBB (1 << 3) /* Receiver begin break */ -#define UTSR0_REB (1 << 4) /* Receiver end break */ -#define UTSR0_EIF (1 << 5) /* Error in FIFO */ - -#define UTSR1_RNE (1 << 1) /* Receive FIFO not empty */ -#define UTSR1_TNF (1 << 2) /* Transmit FIFO not full */ -#define UTSR1_PRE (1 << 3) /* Parity error */ -#define UTSR1_FRE (1 << 4) /* Frame error */ -#define UTSR1_ROR (1 << 5) /* Receive Over Run */ - -#define RX_FIFO_PRE (1 << 8) -#define RX_FIFO_FRE (1 << 9) -#define RX_FIFO_ROR (1 << 10) - -#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; - - uint8_t utcr0; - uint16_t brd; - uint8_t utcr3; - uint8_t utsr0; - uint8_t utsr1; - - uint8_t tx_fifo[8]; - uint8_t tx_start; - uint8_t tx_len; - uint16_t rx_fifo[12]; /* value + error flags in high bits */ - uint8_t rx_start; - uint8_t rx_len; - - uint64_t char_transmit_time; /* time to transmit a char in ticks*/ - bool wait_break_end; - QEMUTimer *rx_timeout_timer; - QEMUTimer *tx_timer; -} StrongARMUARTState; - -static void strongarm_uart_update_status(StrongARMUARTState *s) -{ - uint16_t utsr1 = 0; - - if (s->tx_len != 8) { - utsr1 |= UTSR1_TNF; - } - - if (s->rx_len != 0) { - uint16_t ent = s->rx_fifo[s->rx_start]; - - utsr1 |= UTSR1_RNE; - if (ent & RX_FIFO_PRE) { - s->utsr1 |= UTSR1_PRE; - } - if (ent & RX_FIFO_FRE) { - s->utsr1 |= UTSR1_FRE; - } - if (ent & RX_FIFO_ROR) { - s->utsr1 |= UTSR1_ROR; - } - } - - s->utsr1 = utsr1; -} - -static void strongarm_uart_update_int_status(StrongARMUARTState *s) -{ - uint16_t utsr0 = s->utsr0 & - (UTSR0_REB | UTSR0_RBB | UTSR0_RID); - int i; - - if ((s->utcr3 & UTCR3_TXE) && - (s->utcr3 & UTCR3_TIE) && - s->tx_len <= 4) { - utsr0 |= UTSR0_TFS; - } - - if ((s->utcr3 & UTCR3_RXE) && - (s->utcr3 & UTCR3_RIE) && - s->rx_len > 4) { - utsr0 |= UTSR0_RFS; - } - - for (i = 0; i < s->rx_len && i < 4; i++) - if (s->rx_fifo[(s->rx_start + i) % 12] & ~0xff) { - utsr0 |= UTSR0_EIF; - break; - } - - s->utsr0 = utsr0; - qemu_set_irq(s->irq, utsr0); -} - -static void strongarm_uart_update_parameters(StrongARMUARTState *s) -{ - int speed, parity, data_bits, stop_bits, frame_size; - QEMUSerialSetParams ssp; - - /* Start bit. */ - frame_size = 1; - if (s->utcr0 & UTCR0_PE) { - /* Parity bit. */ - frame_size++; - if (s->utcr0 & UTCR0_OES) { - parity = 'E'; - } else { - parity = 'O'; - } - } else { - parity = 'N'; - } - if (s->utcr0 & UTCR0_SBS) { - stop_bits = 2; - } else { - stop_bits = 1; - } - - data_bits = (s->utcr0 & UTCR0_DSS) ? 8 : 7; - frame_size += data_bits + stop_bits; - speed = 3686400 / 16 / (s->brd + 1); - ssp.speed = speed; - ssp.parity = parity; - ssp.data_bits = data_bits; - ssp.stop_bits = stop_bits; - 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); - } - - DPRINTF(stderr, "%s speed=%d parity=%c data=%d stop=%d\n", s->chr->label, - speed, parity, data_bits, stop_bits); -} - -static void strongarm_uart_rx_to(void *opaque) -{ - StrongARMUARTState *s = opaque; - - if (s->rx_len) { - s->utsr0 |= UTSR0_RID; - strongarm_uart_update_int_status(s); - } -} - -static void strongarm_uart_rx_push(StrongARMUARTState *s, uint16_t c) -{ - if ((s->utcr3 & UTCR3_RXE) == 0) { - /* rx disabled */ - return; - } - - if (s->wait_break_end) { - s->utsr0 |= UTSR0_REB; - s->wait_break_end = false; - } - - if (s->rx_len < 12) { - s->rx_fifo[(s->rx_start + s->rx_len) % 12] = c; - s->rx_len++; - } else - s->rx_fifo[(s->rx_start + 11) % 12] |= RX_FIFO_ROR; -} - -static int strongarm_uart_can_receive(void *opaque) -{ - StrongARMUARTState *s = opaque; - - if (s->rx_len == 12) { - return 0; - } - /* It's best not to get more than 2/3 of RX FIFO, so advertise that much */ - if (s->rx_len < 8) { - return 8 - s->rx_len; - } - return 1; -} - -static void strongarm_uart_receive(void *opaque, const uint8_t *buf, int size) -{ - StrongARMUARTState *s = opaque; - int i; - - for (i = 0; i < size; i++) { - strongarm_uart_rx_push(s, buf[i]); - } - - /* call the timeout receive callback in 3 char transmit time */ - 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_event(void *opaque, int event) -{ - StrongARMUARTState *s = opaque; - if (event == CHR_EVENT_BREAK) { - s->utsr0 |= UTSR0_RBB; - strongarm_uart_rx_push(s, RX_FIFO_FRE); - s->wait_break_end = true; - 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_clock_get_ns(QEMU_CLOCK_VIRTUAL); - - if (s->utcr3 & UTCR3_LBM) /* loopback */ { - strongarm_uart_receive(s, &s->tx_fifo[s->tx_start], 1); - } else if (s->chr) { - qemu_chr_fe_write(s->chr, &s->tx_fifo[s->tx_start], 1); - } - - s->tx_start = (s->tx_start + 1) % 8; - s->tx_len--; - if (s->tx_len) { - timer_mod(s->tx_timer, new_xmit_ts + s->char_transmit_time); - } - strongarm_uart_update_status(s); - strongarm_uart_update_int_status(s); -} - -static uint64_t strongarm_uart_read(void *opaque, hwaddr addr, - unsigned size) -{ - StrongARMUARTState *s = opaque; - uint16_t ret; - - switch (addr) { - case UTCR0: - return s->utcr0; - - case UTCR1: - return s->brd >> 8; - - case UTCR2: - return s->brd & 0xff; - - case UTCR3: - return s->utcr3; - - case UTDR: - if (s->rx_len != 0) { - ret = s->rx_fifo[s->rx_start]; - s->rx_start = (s->rx_start + 1) % 12; - s->rx_len--; - strongarm_uart_update_status(s); - strongarm_uart_update_int_status(s); - return ret; - } - return 0; - - case UTSR0: - return s->utsr0; - - case UTSR1: - return s->utsr1; - - default: - printf("%s: Bad register 0x" TARGET_FMT_plx "\n", __func__, addr); - return 0; - } -} - -static void strongarm_uart_write(void *opaque, hwaddr addr, - uint64_t value, unsigned size) -{ - StrongARMUARTState *s = opaque; - - switch (addr) { - case UTCR0: - s->utcr0 = value & 0x7f; - strongarm_uart_update_parameters(s); - break; - - case UTCR1: - s->brd = (s->brd & 0xff) | ((value & 0xf) << 8); - strongarm_uart_update_parameters(s); - break; - - case UTCR2: - s->brd = (s->brd & 0xf00) | (value & 0xff); - strongarm_uart_update_parameters(s); - break; - - case UTCR3: - s->utcr3 = value & 0x3f; - if ((s->utcr3 & UTCR3_RXE) == 0) { - s->rx_len = 0; - } - if ((s->utcr3 & UTCR3_TXE) == 0) { - s->tx_len = 0; - } - strongarm_uart_update_status(s); - strongarm_uart_update_int_status(s); - break; - - case UTDR: - if ((s->utcr3 & UTCR3_TXE) && s->tx_len != 8) { - s->tx_fifo[(s->tx_start + s->tx_len) % 8] = value; - s->tx_len++; - strongarm_uart_update_status(s); - strongarm_uart_update_int_status(s); - if (s->tx_len == 1) { - strongarm_uart_tx(s); - } - } - break; - - case UTSR0: - s->utsr0 = s->utsr0 & ~(value & - (UTSR0_REB | UTSR0_RBB | UTSR0_RID)); - strongarm_uart_update_int_status(s); - break; - - default: - printf("%s: Bad register 0x" TARGET_FMT_plx "\n", __func__, addr); - } -} - -static const MemoryRegionOps strongarm_uart_ops = { - .read = strongarm_uart_read, - .write = strongarm_uart_write, - .endianness = DEVICE_NATIVE_ENDIAN, -}; - -static int strongarm_uart_init(SysBusDevice *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 = 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, - strongarm_uart_can_receive, - strongarm_uart_receive, - strongarm_uart_event, - s); - } - - return 0; -} - -static void strongarm_uart_reset(DeviceState *dev) -{ - StrongARMUARTState *s = STRONGARM_UART(dev); - - s->utcr0 = UTCR0_DSS; /* 8 data, no parity */ - s->brd = 23; /* 9600 */ - /* enable send & recv - this actually violates spec */ - s->utcr3 = UTCR3_TXE | UTCR3_RXE; - - s->rx_len = s->tx_len = 0; - - strongarm_uart_update_parameters(s); - strongarm_uart_update_status(s); - strongarm_uart_update_int_status(s); -} - -static int strongarm_uart_post_load(void *opaque, int version_id) -{ - StrongARMUARTState *s = opaque; - - strongarm_uart_update_parameters(s); - strongarm_uart_update_status(s); - strongarm_uart_update_int_status(s); - - /* tx and restart timer */ - if (s->tx_len) { - strongarm_uart_tx(s); - } - - /* restart rx timeout timer */ - if (s->rx_len) { - timer_mod(s->rx_timeout_timer, - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + s->char_transmit_time * 3); - } - - return 0; -} - -static const VMStateDescription vmstate_strongarm_uart_regs = { - .name = "strongarm-uart", - .version_id = 0, - .minimum_version_id = 0, - .post_load = strongarm_uart_post_load, - .fields = (VMStateField[]) { - VMSTATE_UINT8(utcr0, StrongARMUARTState), - VMSTATE_UINT16(brd, StrongARMUARTState), - VMSTATE_UINT8(utcr3, StrongARMUARTState), - VMSTATE_UINT8(utsr0, StrongARMUARTState), - VMSTATE_UINT8_ARRAY(tx_fifo, StrongARMUARTState, 8), - VMSTATE_UINT8(tx_start, StrongARMUARTState), - VMSTATE_UINT8(tx_len, StrongARMUARTState), - VMSTATE_UINT16_ARRAY(rx_fifo, StrongARMUARTState, 12), - VMSTATE_UINT8(rx_start, StrongARMUARTState), - VMSTATE_UINT8(rx_len, StrongARMUARTState), - VMSTATE_BOOL(wait_break_end, StrongARMUARTState), - VMSTATE_END_OF_LIST(), - }, -}; - -static Property strongarm_uart_properties[] = { - DEFINE_PROP_CHR("chardev", StrongARMUARTState, chr), - DEFINE_PROP_END_OF_LIST(), -}; - -static void strongarm_uart_class_init(ObjectClass *klass, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(klass); - SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); - - k->init = strongarm_uart_init; - dc->desc = "StrongARM UART controller"; - dc->reset = strongarm_uart_reset; - dc->vmsd = &vmstate_strongarm_uart_regs; - dc->props = strongarm_uart_properties; -} - -static const TypeInfo strongarm_uart_info = { - .name = TYPE_STRONGARM_UART, - .parent = TYPE_SYS_BUS_DEVICE, - .instance_size = sizeof(StrongARMUARTState), - .class_init = strongarm_uart_class_init, -}; - -/* Synchronous Serial Ports */ - -#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; - - uint16_t sscr[2]; - uint16_t sssr; - - uint16_t rx_fifo[8]; - uint8_t rx_level; - uint8_t rx_start; -} StrongARMSSPState; - -#define SSCR0 0x60 /* SSP Control register 0 */ -#define SSCR1 0x64 /* SSP Control register 1 */ -#define SSDR 0x6c /* SSP Data register */ -#define SSSR 0x74 /* SSP Status register */ - -/* Bitfields for above registers */ -#define SSCR0_SPI(x) (((x) & 0x30) == 0x00) -#define SSCR0_SSP(x) (((x) & 0x30) == 0x10) -#define SSCR0_UWIRE(x) (((x) & 0x30) == 0x20) -#define SSCR0_PSP(x) (((x) & 0x30) == 0x30) -#define SSCR0_SSE (1 << 7) -#define SSCR0_DSS(x) (((x) & 0xf) + 1) -#define SSCR1_RIE (1 << 0) -#define SSCR1_TIE (1 << 1) -#define SSCR1_LBM (1 << 2) -#define SSSR_TNF (1 << 2) -#define SSSR_RNE (1 << 3) -#define SSSR_TFS (1 << 5) -#define SSSR_RFS (1 << 6) -#define SSSR_ROR (1 << 7) -#define SSSR_RW 0x0080 - -static void strongarm_ssp_int_update(StrongARMSSPState *s) -{ - int level = 0; - - level |= (s->sssr & SSSR_ROR); - level |= (s->sssr & SSSR_RFS) && (s->sscr[1] & SSCR1_RIE); - level |= (s->sssr & SSSR_TFS) && (s->sscr[1] & SSCR1_TIE); - qemu_set_irq(s->irq, level); -} - -static void strongarm_ssp_fifo_update(StrongARMSSPState *s) -{ - s->sssr &= ~SSSR_TFS; - s->sssr &= ~SSSR_TNF; - if (s->sscr[0] & SSCR0_SSE) { - if (s->rx_level >= 4) { - s->sssr |= SSSR_RFS; - } else { - s->sssr &= ~SSSR_RFS; - } - if (s->rx_level) { - s->sssr |= SSSR_RNE; - } else { - s->sssr &= ~SSSR_RNE; - } - /* TX FIFO is never filled, so it is always in underrun - condition if SSP is enabled */ - s->sssr |= SSSR_TFS; - s->sssr |= SSSR_TNF; - } - - strongarm_ssp_int_update(s); -} - -static uint64_t strongarm_ssp_read(void *opaque, hwaddr addr, - unsigned size) -{ - StrongARMSSPState *s = opaque; - uint32_t retval; - - switch (addr) { - case SSCR0: - return s->sscr[0]; - case SSCR1: - return s->sscr[1]; - case SSSR: - return s->sssr; - case SSDR: - if (~s->sscr[0] & SSCR0_SSE) { - return 0xffffffff; - } - if (s->rx_level < 1) { - printf("%s: SSP Rx Underrun\n", __func__); - return 0xffffffff; - } - s->rx_level--; - retval = s->rx_fifo[s->rx_start++]; - s->rx_start &= 0x7; - strongarm_ssp_fifo_update(s); - return retval; - default: - printf("%s: Bad register 0x" TARGET_FMT_plx "\n", __func__, addr); - break; - } - return 0; -} - -static void strongarm_ssp_write(void *opaque, hwaddr addr, - uint64_t value, unsigned size) -{ - StrongARMSSPState *s = opaque; - - switch (addr) { - case SSCR0: - s->sscr[0] = value & 0xffbf; - if ((s->sscr[0] & SSCR0_SSE) && SSCR0_DSS(value) < 4) { - printf("%s: Wrong data size: %i bits\n", __func__, - (int)SSCR0_DSS(value)); - } - if (!(value & SSCR0_SSE)) { - s->sssr = 0; - s->rx_level = 0; - } - strongarm_ssp_fifo_update(s); - break; - - case SSCR1: - s->sscr[1] = value & 0x2f; - if (value & SSCR1_LBM) { - printf("%s: Attempt to use SSP LBM mode\n", __func__); - } - strongarm_ssp_fifo_update(s); - break; - - case SSSR: - s->sssr &= ~(value & SSSR_RW); - strongarm_ssp_int_update(s); - break; - - case SSDR: - if (SSCR0_UWIRE(s->sscr[0])) { - value &= 0xff; - } else - /* Note how 32bits overflow does no harm here */ - value &= (1 << SSCR0_DSS(s->sscr[0])) - 1; - - /* Data goes from here to the Tx FIFO and is shifted out from - * there directly to the slave, no need to buffer it. - */ - if (s->sscr[0] & SSCR0_SSE) { - uint32_t readval; - if (s->sscr[1] & SSCR1_LBM) { - readval = value; - } else { - readval = ssi_transfer(s->bus, value); - } - - if (s->rx_level < 0x08) { - s->rx_fifo[(s->rx_start + s->rx_level++) & 0x7] = readval; - } else { - s->sssr |= SSSR_ROR; - } - } - strongarm_ssp_fifo_update(s); - break; - - default: - printf("%s: Bad register 0x" TARGET_FMT_plx "\n", __func__, addr); - break; - } -} - -static const MemoryRegionOps strongarm_ssp_ops = { - .read = strongarm_ssp_read, - .write = strongarm_ssp_write, - .endianness = DEVICE_NATIVE_ENDIAN, -}; - -static int strongarm_ssp_post_load(void *opaque, int version_id) -{ - StrongARMSSPState *s = opaque; - - strongarm_ssp_fifo_update(s); - - return 0; -} - -static int strongarm_ssp_init(SysBusDevice *sbd) -{ - DeviceState *dev = DEVICE(sbd); - StrongARMSSPState *s = STRONGARM_SSP(dev); - - sysbus_init_irq(sbd, &s->irq); - - memory_region_init_io(&s->iomem, OBJECT(s), &strongarm_ssp_ops, s, - "ssp", 0x1000); - sysbus_init_mmio(sbd, &s->iomem); - - s->bus = ssi_create_bus(dev, "ssi"); - return 0; -} - -static void strongarm_ssp_reset(DeviceState *dev) -{ - StrongARMSSPState *s = STRONGARM_SSP(dev); - - s->sssr = 0x03; /* 3 bit data, SPI, disabled */ - s->rx_start = 0; - s->rx_level = 0; -} - -static const VMStateDescription vmstate_strongarm_ssp_regs = { - .name = "strongarm-ssp", - .version_id = 0, - .minimum_version_id = 0, - .post_load = strongarm_ssp_post_load, - .fields = (VMStateField[]) { - VMSTATE_UINT16_ARRAY(sscr, StrongARMSSPState, 2), - VMSTATE_UINT16(sssr, StrongARMSSPState), - VMSTATE_UINT16_ARRAY(rx_fifo, StrongARMSSPState, 8), - VMSTATE_UINT8(rx_start, StrongARMSSPState), - VMSTATE_UINT8(rx_level, StrongARMSSPState), - VMSTATE_END_OF_LIST(), - }, -}; - -static void strongarm_ssp_class_init(ObjectClass *klass, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(klass); - SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); - - k->init = strongarm_ssp_init; - dc->desc = "StrongARM SSP controller"; - dc->reset = strongarm_ssp_reset; - dc->vmsd = &vmstate_strongarm_ssp_regs; -} - -static const TypeInfo strongarm_ssp_info = { - .name = TYPE_STRONGARM_SSP, - .parent = TYPE_SYS_BUS_DEVICE, - .instance_size = sizeof(StrongARMSSPState), - .class_init = strongarm_ssp_class_init, -}; - -/* Main CPU functions */ -StrongARMState *sa1110_init(MemoryRegion *sysmem, - unsigned int sdram_size, const char *rev) -{ - StrongARMState *s; - int i; - - s = g_new0(StrongARMState, 1); - - if (!rev) { - rev = "sa1110-b5"; - } - - if (strncmp(rev, "sa1110", 6)) { - error_report("Machine requires a SA1110 processor."); - exit(1); - } - - s->cpu = cpu_arm_init(rev); - - if (!s->cpu) { - error_report("Unable to find CPU definition"); - exit(1); - } - - memory_region_allocate_system_memory(&s->sdram, NULL, "strongarm.sdram", - sdram_size); - memory_region_add_subregion(sysmem, SA_SDCS0, &s->sdram); - - s->pic = sysbus_create_varargs("strongarm_pic", 0x90050000, - 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_OSTC1), - qdev_get_gpio_in(s->pic, SA_PIC_OSTC2), - qdev_get_gpio_in(s->pic, SA_PIC_OSTC3), - NULL); - - 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(TYPE_STRONGARM_PPC, 0x90060000, NULL); - - for (i = 0; sa_serial[i].io_base; i++) { - 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, - sa_serial[i].io_base); - sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, - qdev_get_gpio_in(s->pic, sa_serial[i].irq)); - } - - 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"); - - return s; -} - -static void strongarm_register_types(void) -{ - type_register_static(&strongarm_pic_info); - type_register_static(&strongarm_rtc_sysbus_info); - type_register_static(&strongarm_gpio_info); - type_register_static(&strongarm_ppc_info); - type_register_static(&strongarm_uart_info); - type_register_static(&strongarm_ssp_info); -} - -type_init(strongarm_register_types) |