/*
 * 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 "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"

//#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 =  (get_ticks_per_sec() / 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)
