diff options
Diffstat (limited to 'hw/arm')
-rw-r--r-- | hw/arm/Makefile.objs | 31 | ||||
-rw-r--r-- | hw/arm/armv7m.c | 2 | ||||
-rw-r--r-- | hw/arm/boot.c | 2 | ||||
-rw-r--r-- | hw/arm/collie.c | 8 | ||||
-rw-r--r-- | hw/arm/exynos4210.c | 4 | ||||
-rw-r--r-- | hw/arm/exynos4_boards.c | 4 | ||||
-rw-r--r-- | hw/arm/gumstix.c | 6 | ||||
-rw-r--r-- | hw/arm/highbank.c | 4 | ||||
-rw-r--r-- | hw/arm/integratorcp.c | 4 | ||||
-rw-r--r-- | hw/arm/kzm.c | 8 | ||||
-rw-r--r-- | hw/arm/mainstone.c | 8 | ||||
-rw-r--r-- | hw/arm/musicpal.c | 10 | ||||
-rw-r--r-- | hw/arm/nseries.c | 10 | ||||
-rw-r--r-- | hw/arm/omap1.c | 6 | ||||
-rw-r--r-- | hw/arm/omap2.c | 8 | ||||
-rw-r--r-- | hw/arm/omap_sx1.c | 6 | ||||
-rw-r--r-- | hw/arm/palm.c | 6 | ||||
-rw-r--r-- | hw/arm/pic_cpu.c | 2 | ||||
-rw-r--r-- | hw/arm/pxa2xx.c | 6 | ||||
-rw-r--r-- | hw/arm/pxa2xx_gpio.c | 2 | ||||
-rw-r--r-- | hw/arm/pxa2xx_pic.c | 2 | ||||
-rw-r--r-- | hw/arm/realview.c | 8 | ||||
-rw-r--r-- | hw/arm/spitz.c | 12 | ||||
-rw-r--r-- | hw/arm/stellaris.c | 6 | ||||
-rw-r--r-- | hw/arm/strongarm.c | 1623 | ||||
-rw-r--r-- | hw/arm/strongarm.h | 68 | ||||
-rw-r--r-- | hw/arm/tosa.c | 10 | ||||
-rw-r--r-- | hw/arm/versatilepb.c | 8 | ||||
-rw-r--r-- | hw/arm/vexpress.c | 8 | ||||
-rw-r--r-- | hw/arm/xilinx_zynq.c | 4 | ||||
-rw-r--r-- | hw/arm/z2.c | 10 |
31 files changed, 1779 insertions, 117 deletions
diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs index f5f7d0e539..9e3a06fc18 100644 --- a/hw/arm/Makefile.objs +++ b/hw/arm/Makefile.objs @@ -1,36 +1,7 @@ -obj-y += zynq_slcr.o -obj-y += xilinx_spips.o -obj-y += arm_gic.o arm_gic_common.o -obj-y += a9scu.o -obj-y += realview_gic.o arm_sysctl.o arm11mpcore.o a9mpcore.o -obj-y += exynos4210_gic.o exynos4210_combiner.o -obj-y += exynos4210_uart.o exynos4210_pwm.o -obj-y += exynos4210_pmu.o exynos4210_mct.o exynos4210_fimd.o -obj-y += exynos4210_rtc.o exynos4210_i2c.o -obj-y += arm_mptimer.o a15mpcore.o -obj-y += armv7m_nvic.o stellaris_enet.o -obj-y += pxa2xx_timer.o pxa2xx_dma.o -obj-y += pxa2xx_lcd.o pxa2xx_mmci.o pxa2xx_pcmcia.o pxa2xx_keypad.o -obj-y += zaurus.o ide/microdrive.o tc6393xb.o -obj-y += omap_lcdc.o omap_dma.o omap_clk.o omap_mmc.o omap_i2c.o \ - omap_gpio.o omap_intc.o omap_uart.o -obj-y += omap_dss.o soc_dma.o omap_gptimer.o omap_synctimer.o \ - omap_gpmc.o omap_sdrc.o omap_spi.o omap_tap.o omap_l4.o -obj-y += tsc210x.o -obj-y += blizzard.o onenand.o cbus.o tusb6010.o usb/hcd-musb.o -obj-y += mst_fpga.o -obj-y += bitbang_i2c.o marvell_88w8618_audio.o -obj-y += framebuffer.o -obj-y += strongarm.o -obj-y += imx_serial.o imx_ccm.o imx_timer.o imx_avic.o -obj-$(CONFIG_KVM) += kvm/arm_gic.o - -obj-y := $(addprefix ../,$(obj-y)) - obj-y += boot.o collie.o exynos4_boards.o gumstix.o highbank.o obj-y += integratorcp.o kzm.o mainstone.o musicpal.o nseries.o obj-y += omap_sx1.o palm.o pic_cpu.o realview.o spitz.o stellaris.o obj-y += tosa.o versatilepb.o vexpress.o xilinx_zynq.o z2.o obj-y += armv7m.o exynos4210.o pxa2xx.o pxa2xx_gpio.o pxa2xx_pic.o -obj-y += omap1.o omap2.o +obj-y += omap1.o omap2.o strongarm.o diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c index 1d5bb592c4..a4bdd5f30f 100644 --- a/hw/arm/armv7m.c +++ b/hw/arm/armv7m.c @@ -8,7 +8,7 @@ */ #include "hw/sysbus.h" -#include "hw/arm-misc.h" +#include "hw/arm.h" #include "hw/loader.h" #include "elf.h" diff --git a/hw/arm/boot.c b/hw/arm/boot.c index 43253fd34a..c79c590171 100644 --- a/hw/arm/boot.c +++ b/hw/arm/boot.c @@ -9,7 +9,7 @@ #include "config.h" #include "hw/hw.h" -#include "hw/arm-misc.h" +#include "hw/arm.h" #include "sysemu/sysemu.h" #include "hw/boards.h" #include "hw/loader.h" diff --git a/hw/arm/collie.c b/hw/arm/collie.c index 17fddc8d5b..5420bb4ba8 100644 --- a/hw/arm/collie.c +++ b/hw/arm/collie.c @@ -11,10 +11,10 @@ #include "hw/hw.h" #include "hw/sysbus.h" #include "hw/boards.h" -#include "hw/devices.h" -#include "hw/strongarm.h" -#include "hw/arm-misc.h" -#include "hw/flash.h" +#include "hw/arm/devices.h" +#include "strongarm.h" +#include "hw/arm.h" +#include "hw/block/flash.h" #include "sysemu/blockdev.h" #include "exec/address-spaces.h" diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c index 4592514bb2..78b8b7407a 100644 --- a/hw/arm/exynos4210.c +++ b/hw/arm/exynos4210.c @@ -24,9 +24,9 @@ #include "hw/boards.h" #include "sysemu/sysemu.h" #include "hw/sysbus.h" -#include "hw/arm-misc.h" +#include "hw/arm.h" #include "hw/loader.h" -#include "hw/exynos4210.h" +#include "hw/arm/exynos4210.h" #include "hw/usb/hcd-ehci.h" #define EXYNOS4210_CHIPID_ADDR 0x10000000 diff --git a/hw/arm/exynos4_boards.c b/hw/arm/exynos4_boards.c index 473da349bd..ba14a1fd09 100644 --- a/hw/arm/exynos4_boards.c +++ b/hw/arm/exynos4_boards.c @@ -24,9 +24,9 @@ #include "sysemu/sysemu.h" #include "hw/sysbus.h" #include "net/net.h" -#include "hw/arm-misc.h" +#include "hw/arm.h" #include "exec/address-spaces.h" -#include "hw/exynos4210.h" +#include "hw/arm/exynos4210.h" #include "hw/boards.h" #undef DEBUG diff --git a/hw/arm/gumstix.c b/hw/arm/gumstix.c index 8859b7392f..4d800c9547 100644 --- a/hw/arm/gumstix.c +++ b/hw/arm/gumstix.c @@ -35,10 +35,10 @@ */ #include "hw/hw.h" -#include "hw/pxa.h" +#include "hw/arm/pxa.h" #include "net/net.h" -#include "hw/flash.h" -#include "hw/devices.h" +#include "hw/block/flash.h" +#include "hw/arm/devices.h" #include "hw/boards.h" #include "sysemu/blockdev.h" #include "exec/address-spaces.h" diff --git a/hw/arm/highbank.c b/hw/arm/highbank.c index a622224dcc..58f73c1bd3 100644 --- a/hw/arm/highbank.c +++ b/hw/arm/highbank.c @@ -18,8 +18,8 @@ */ #include "hw/sysbus.h" -#include "hw/arm-misc.h" -#include "hw/devices.h" +#include "hw/arm.h" +#include "hw/arm/devices.h" #include "hw/loader.h" #include "net/net.h" #include "sysemu/sysemu.h" diff --git a/hw/arm/integratorcp.c b/hw/arm/integratorcp.c index e0ba327a55..8d0fb7584a 100644 --- a/hw/arm/integratorcp.c +++ b/hw/arm/integratorcp.c @@ -8,9 +8,9 @@ */ #include "hw/sysbus.h" -#include "hw/devices.h" +#include "hw/arm/devices.h" #include "hw/boards.h" -#include "hw/arm-misc.h" +#include "hw/arm.h" #include "net/net.h" #include "exec/address-spaces.h" #include "sysemu/sysemu.h" diff --git a/hw/arm/kzm.c b/hw/arm/kzm.c index ec50a319ac..46264cdeac 100644 --- a/hw/arm/kzm.c +++ b/hw/arm/kzm.c @@ -16,13 +16,13 @@ #include "hw/sysbus.h" #include "exec/address-spaces.h" #include "hw/hw.h" -#include "hw/arm-misc.h" -#include "hw/devices.h" +#include "hw/arm.h" +#include "hw/arm/devices.h" #include "net/net.h" #include "sysemu/sysemu.h" #include "hw/boards.h" -#include "hw/serial.h" -#include "hw/imx.h" +#include "hw/char/serial.h" +#include "hw/arm/imx.h" /* Memory map for Kzm Emulation Baseboard: * 0x00000000-0x00003fff 16k secure ROM IGNORED diff --git a/hw/arm/mainstone.c b/hw/arm/mainstone.c index aea908f036..b78e6f00d3 100644 --- a/hw/arm/mainstone.c +++ b/hw/arm/mainstone.c @@ -12,12 +12,12 @@ * GNU GPL, version 2 or (at your option) any later version. */ #include "hw/hw.h" -#include "hw/pxa.h" -#include "hw/arm-misc.h" +#include "hw/arm/pxa.h" +#include "hw/arm.h" #include "net/net.h" -#include "hw/devices.h" +#include "hw/arm/devices.h" #include "hw/boards.h" -#include "hw/flash.h" +#include "hw/block/flash.h" #include "sysemu/blockdev.h" #include "hw/sysbus.h" #include "exec/address-spaces.h" diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c index ea8473db3e..97b13405e6 100644 --- a/hw/arm/musicpal.c +++ b/hw/arm/musicpal.c @@ -10,18 +10,18 @@ */ #include "hw/sysbus.h" -#include "hw/arm-misc.h" -#include "hw/devices.h" +#include "hw/arm.h" +#include "hw/arm/devices.h" #include "net/net.h" #include "sysemu/sysemu.h" #include "hw/boards.h" -#include "hw/serial.h" +#include "hw/char/serial.h" #include "qemu/timer.h" #include "hw/ptimer.h" #include "block/block.h" -#include "hw/flash.h" +#include "hw/block/flash.h" #include "ui/console.h" -#include "hw/i2c.h" +#include "hw/i2c/i2c.h" #include "sysemu/blockdev.h" #include "exec/address-spaces.h" #include "ui/pixel_ops.h" diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c index b28e7d372f..ba8dc3e01a 100644 --- a/hw/arm/nseries.c +++ b/hw/arm/nseries.c @@ -20,14 +20,14 @@ #include "qemu-common.h" #include "sysemu/sysemu.h" -#include "hw/omap.h" -#include "hw/arm-misc.h" +#include "hw/arm/omap.h" +#include "hw/arm.h" #include "hw/irq.h" #include "ui/console.h" #include "hw/boards.h" -#include "hw/i2c.h" -#include "hw/devices.h" -#include "hw/flash.h" +#include "hw/i2c/i2c.h" +#include "hw/arm/devices.h" +#include "hw/block/flash.h" #include "hw/hw.h" #include "hw/bt.h" #include "hw/loader.h" diff --git a/hw/arm/omap1.c b/hw/arm/omap1.c index 3245c62e68..17caa61822 100644 --- a/hw/arm/omap1.c +++ b/hw/arm/omap1.c @@ -17,10 +17,10 @@ * with this program; if not, see <http://www.gnu.org/licenses/>. */ #include "hw/hw.h" -#include "hw/arm-misc.h" -#include "hw/omap.h" +#include "hw/arm.h" +#include "hw/arm/omap.h" #include "sysemu/sysemu.h" -#include "hw/soc_dma.h" +#include "hw/arm/soc_dma.h" #include "sysemu/blockdev.h" #include "qemu/range.h" #include "hw/sysbus.h" diff --git a/hw/arm/omap2.c b/hw/arm/omap2.c index 0a2cd7bab6..010c483e8c 100644 --- a/hw/arm/omap2.c +++ b/hw/arm/omap2.c @@ -20,13 +20,13 @@ #include "sysemu/blockdev.h" #include "hw/hw.h" -#include "hw/arm-misc.h" -#include "hw/omap.h" +#include "hw/arm.h" +#include "hw/arm/omap.h" #include "sysemu/sysemu.h" #include "qemu/timer.h" #include "char/char.h" -#include "hw/flash.h" -#include "hw/soc_dma.h" +#include "hw/block/flash.h" +#include "hw/arm/soc_dma.h" #include "hw/sysbus.h" #include "audio/audio.h" diff --git a/hw/arm/omap_sx1.c b/hw/arm/omap_sx1.c index 85982334bd..aa85602aa6 100644 --- a/hw/arm/omap_sx1.c +++ b/hw/arm/omap_sx1.c @@ -27,10 +27,10 @@ */ #include "hw/hw.h" #include "ui/console.h" -#include "hw/omap.h" +#include "hw/arm/omap.h" #include "hw/boards.h" -#include "hw/arm-misc.h" -#include "hw/flash.h" +#include "hw/arm.h" +#include "hw/block/flash.h" #include "sysemu/blockdev.h" #include "exec/address-spaces.h" diff --git a/hw/arm/palm.c b/hw/arm/palm.c index baeb585067..0bc11aed2b 100644 --- a/hw/arm/palm.c +++ b/hw/arm/palm.c @@ -20,10 +20,10 @@ #include "audio/audio.h" #include "sysemu/sysemu.h" #include "ui/console.h" -#include "hw/omap.h" +#include "hw/arm/omap.h" #include "hw/boards.h" -#include "hw/arm-misc.h" -#include "hw/devices.h" +#include "hw/arm.h" +#include "hw/arm/devices.h" #include "hw/loader.h" #include "exec/address-spaces.h" diff --git a/hw/arm/pic_cpu.c b/hw/arm/pic_cpu.c index 3a3f06566b..787767f51f 100644 --- a/hw/arm/pic_cpu.c +++ b/hw/arm/pic_cpu.c @@ -8,7 +8,7 @@ */ #include "hw/hw.h" -#include "hw/arm-misc.h" +#include "hw/arm.h" #include "sysemu/kvm.h" /* Input 0 is IRQ and input 1 is FIQ. */ diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c index b7ca511d45..bbecc770ed 100644 --- a/hw/arm/pxa2xx.c +++ b/hw/arm/pxa2xx.c @@ -8,10 +8,10 @@ */ #include "hw/sysbus.h" -#include "hw/pxa.h" +#include "hw/arm/pxa.h" #include "sysemu/sysemu.h" -#include "hw/serial.h" -#include "hw/i2c.h" +#include "hw/char/serial.h" +#include "hw/i2c/i2c.h" #include "hw/ssi.h" #include "char/char.h" #include "sysemu/blockdev.h" diff --git a/hw/arm/pxa2xx_gpio.c b/hw/arm/pxa2xx_gpio.c index 55ebcd724a..fa31575edd 100644 --- a/hw/arm/pxa2xx_gpio.c +++ b/hw/arm/pxa2xx_gpio.c @@ -9,7 +9,7 @@ #include "hw/hw.h" #include "hw/sysbus.h" -#include "hw/pxa.h" +#include "hw/arm/pxa.h" #define PXA2XX_GPIO_BANKS 4 diff --git a/hw/arm/pxa2xx_pic.c b/hw/arm/pxa2xx_pic.c index 25e90895e1..835d07c341 100644 --- a/hw/arm/pxa2xx_pic.c +++ b/hw/arm/pxa2xx_pic.c @@ -9,7 +9,7 @@ */ #include "hw/hw.h" -#include "hw/pxa.h" +#include "hw/arm/pxa.h" #include "hw/sysbus.h" #define ICIP 0x00 /* Interrupt Controller IRQ Pending register */ diff --git a/hw/arm/realview.c b/hw/arm/realview.c index 5fb490c832..afd52d31be 100644 --- a/hw/arm/realview.c +++ b/hw/arm/realview.c @@ -8,14 +8,14 @@ */ #include "hw/sysbus.h" -#include "hw/arm-misc.h" -#include "hw/primecell.h" -#include "hw/devices.h" +#include "hw/arm.h" +#include "hw/arm/primecell.h" +#include "hw/arm/devices.h" #include "hw/pci/pci.h" #include "net/net.h" #include "sysemu/sysemu.h" #include "hw/boards.h" -#include "hw/i2c.h" +#include "hw/i2c/i2c.h" #include "sysemu/blockdev.h" #include "exec/address-spaces.h" diff --git a/hw/arm/spitz.c b/hw/arm/spitz.c index f5832bea93..fa434dc68e 100644 --- a/hw/arm/spitz.c +++ b/hw/arm/spitz.c @@ -11,16 +11,16 @@ */ #include "hw/hw.h" -#include "hw/pxa.h" -#include "hw/arm-misc.h" +#include "hw/arm/pxa.h" +#include "hw/arm.h" #include "sysemu/sysemu.h" #include "hw/pcmcia.h" -#include "hw/i2c.h" +#include "hw/i2c/i2c.h" #include "hw/ssi.h" -#include "hw/flash.h" +#include "hw/block/flash.h" #include "qemu/timer.h" -#include "hw/devices.h" -#include "hw/sharpsl.h" +#include "hw/arm/devices.h" +#include "hw/arm/sharpsl.h" #include "ui/console.h" #include "block/block.h" #include "audio/audio.h" diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c index f4ce7945f3..952087ce2d 100644 --- a/hw/arm/stellaris.c +++ b/hw/arm/stellaris.c @@ -9,10 +9,10 @@ #include "hw/sysbus.h" #include "hw/ssi.h" -#include "hw/arm-misc.h" -#include "hw/devices.h" +#include "hw/arm.h" +#include "hw/arm/devices.h" #include "qemu/timer.h" -#include "hw/i2c.h" +#include "hw/i2c/i2c.h" #include "net/net.h" #include "hw/boards.h" #include "exec/address-spaces.h" diff --git a/hw/arm/strongarm.c b/hw/arm/strongarm.c new file mode 100644 index 0000000000..5873a3c956 --- /dev/null +++ b/hw/arm/strongarm.c @@ -0,0 +1,1623 @@ +/* + * 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/sysbus.h" +#include "strongarm.h" +#include "qemu/error-report.h" +#include "hw/arm.h" +#include "char/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 */ +typedef struct { + SysBusDevice busdev; + 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 *dev) +{ + StrongARMPICState *s = FROM_SYSBUS(StrongARMPICState, dev); + + qdev_init_gpio_in(&dev->qdev, strongarm_pic_set_irq, SA_PIC_SRCS); + memory_region_init_io(&s->iomem, &strongarm_pic_ops, s, "pic", 0x1000); + sysbus_init_mmio(dev, &s->iomem); + sysbus_init_irq(dev, &s->irq); + sysbus_init_irq(dev, &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, + .minimum_version_id_old = 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 = "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) */ + +typedef struct { + SysBusDevice busdev; + 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_get_clock_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); + } else { + qemu_del_timer(s->rtc_hz); + } + + if ((s->rtsr & RTSR_ALE) && !(s->rtsr & RTSR_AL)) { + qemu_mod_timer(s->rtc_alarm, s->last_hz + + (((s->rtar - s->last_rcnr) * 1000 * + ((s->rttr & 0xffff) + 1)) >> 15)); + } else { + qemu_del_timer(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_get_clock_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 = FROM_SYSBUS(StrongARMRTCState, 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_get_clock_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); + + sysbus_init_irq(dev, &s->rtc_irq); + sysbus_init_irq(dev, &s->rtc_hz_irq); + + memory_region_init_io(&s->iomem, &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, + .minimum_version_id_old = 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 = "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 + +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 gpsr; + 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 = ffs(diff) - 1; + 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 */ + DPRINTF("%s: Read from a write-only register 0x" TARGET_FMT_plx "\n", + __func__, offset); + return s->gpsr; /* Return last written value. */ + + 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. */ + + 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); + s->gpsr = value; + 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, "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 *dev) +{ + StrongARMGPIOInfo *s; + 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); + + memory_region_init_io(&s->iomem, &strongarm_gpio_ops, s, "gpio", 0x1000); + + sysbus_init_mmio(dev, &s->iomem); + for (i = 0; i < 11; i++) { + sysbus_init_irq(dev, &s->irqs[i]); + } + sysbus_init_irq(dev, &s->irqX); + + return 0; +} + +static const VMStateDescription vmstate_strongarm_gpio_regs = { + .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(dir, StrongARMGPIOInfo), + VMSTATE_UINT32(rising, StrongARMGPIOInfo), + VMSTATE_UINT32(falling, StrongARMGPIOInfo), + VMSTATE_UINT32(status, StrongARMGPIOInfo), + VMSTATE_UINT32(gafr, 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"; +} + +static const TypeInfo strongarm_gpio_info = { + .name = "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 + +typedef struct StrongARMPPCInfo StrongARMPPCInfo; +struct StrongARMPPCInfo { + SysBusDevice busdev; + 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 = ffs(diff) - 1; + 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 *dev) +{ + StrongARMPPCInfo *s; + + s = FROM_SYSBUS(StrongARMPPCInfo, dev); + + qdev_init_gpio_in(&dev->qdev, strongarm_ppc_set, 22); + qdev_init_gpio_out(&dev->qdev, s->handler, 22); + + memory_region_init_io(&s->iomem, &strongarm_ppc_ops, s, "ppc", 0x1000); + + sysbus_init_mmio(dev, &s->iomem); + + return 0; +} + +static const VMStateDescription vmstate_strongarm_ppc_regs = { + .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(dir, StrongARMPPCInfo), + VMSTATE_UINT32(ppar, StrongARMPPCInfo), + VMSTATE_UINT32(psdr, StrongARMPPCInfo), + VMSTATE_UINT32(ppfr, 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"; +} + +static const TypeInfo strongarm_ppc_info = { + .name = "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) + +typedef struct { + SysBusDevice busdev; + 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 */ + qemu_mod_timer(s->rx_timeout_timer, + qemu_get_clock_ns(vm_clock) + 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_get_clock_ns(vm_clock); + + 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) { + qemu_mod_timer(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 = FROM_SYSBUS(StrongARMUARTState, dev); + + memory_region_init_io(&s->iomem, &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); + + 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 = DO_UPCAST(StrongARMUARTState, busdev.qdev, 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) { + qemu_mod_timer(s->rx_timeout_timer, + qemu_get_clock_ns(vm_clock) + s->char_transmit_time * 3); + } + + return 0; +} + +static const VMStateDescription vmstate_strongarm_uart_regs = { + .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), + 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 = "strongarm-uart", + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(StrongARMUARTState), + .class_init = strongarm_uart_class_init, +}; + +/* Synchronous Serial Ports */ +typedef struct { + SysBusDevice busdev; + 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 *dev) +{ + StrongARMSSPState *s = FROM_SYSBUS(StrongARMSSPState, dev); + + sysbus_init_irq(dev, &s->irq); + + memory_region_init_io(&s->iomem, &strongarm_ssp_ops, s, "ssp", 0x1000); + sysbus_init_mmio(dev, &s->iomem); + + s->bus = ssi_create_bus(&dev->qdev, "ssi"); + return 0; +} + +static void strongarm_ssp_reset(DeviceState *dev) +{ + StrongARMSSPState *s = DO_UPCAST(StrongARMSSPState, busdev.qdev, 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, + .minimum_version_id_old = 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 = "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; + qemu_irq *pic; + int i; + + s = g_malloc0(sizeof(StrongARMState)); + + 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_init_ram(&s->sdram, "strongarm.sdram", sdram_size); + vmstate_register_ram_global(&s->sdram); + 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); + + 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("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); + + for (i = 0; sa_serial[i].io_base; i++) { + DeviceState *dev = qdev_create(NULL, "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("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) diff --git a/hw/arm/strongarm.h b/hw/arm/strongarm.h new file mode 100644 index 0000000000..2893f94445 --- /dev/null +++ b/hw/arm/strongarm.h @@ -0,0 +1,68 @@ +#ifndef _STRONGARM_H +#define _STRONGARM_H + +#include "exec/memory.h" + +#define SA_CS0 0x00000000 +#define SA_CS1 0x08000000 +#define SA_CS2 0x10000000 +#define SA_CS3 0x18000000 +#define SA_PCMCIA_CS0 0x20000000 +#define SA_PCMCIA_CS1 0x30000000 +#define SA_CS4 0x40000000 +#define SA_CS5 0x48000000 +/* system registers here */ +#define SA_SDCS0 0xc0000000 +#define SA_SDCS1 0xc8000000 +#define SA_SDCS2 0xd0000000 +#define SA_SDCS3 0xd8000000 + +enum { + SA_PIC_GPIO0_EDGE = 0, + SA_PIC_GPIO1_EDGE, + SA_PIC_GPIO2_EDGE, + SA_PIC_GPIO3_EDGE, + SA_PIC_GPIO4_EDGE, + SA_PIC_GPIO5_EDGE, + SA_PIC_GPIO6_EDGE, + SA_PIC_GPIO7_EDGE, + SA_PIC_GPIO8_EDGE, + SA_PIC_GPIO9_EDGE, + SA_PIC_GPIO10_EDGE, + SA_PIC_GPIOX_EDGE, + SA_PIC_LCD, + SA_PIC_UDC, + SA_PIC_RSVD1, + SA_PIC_UART1, + SA_PIC_UART2, + SA_PIC_UART3, + SA_PIC_MCP, + SA_PIC_SSP, + SA_PIC_DMA_CH0, + SA_PIC_DMA_CH1, + SA_PIC_DMA_CH2, + SA_PIC_DMA_CH3, + SA_PIC_DMA_CH4, + SA_PIC_DMA_CH5, + SA_PIC_OSTC0, + SA_PIC_OSTC1, + SA_PIC_OSTC2, + SA_PIC_OSTC3, + SA_PIC_RTC_HZ, + SA_PIC_RTC_ALARM, +}; + +typedef struct { + ARMCPU *cpu; + MemoryRegion sdram; + DeviceState *pic; + DeviceState *gpio; + DeviceState *ppc; + DeviceState *ssp; + SSIBus *ssp_bus; +} StrongARMState; + +StrongARMState *sa1110_init(MemoryRegion *sysmem, + unsigned int sdram_size, const char *rev); + +#endif diff --git a/hw/arm/tosa.c b/hw/arm/tosa.c index 747888c64e..c4362d4313 100644 --- a/hw/arm/tosa.c +++ b/hw/arm/tosa.c @@ -12,14 +12,14 @@ */ #include "hw/hw.h" -#include "hw/pxa.h" -#include "hw/arm-misc.h" -#include "hw/devices.h" -#include "hw/sharpsl.h" +#include "hw/arm/pxa.h" +#include "hw/arm.h" +#include "hw/arm/devices.h" +#include "hw/arm/sharpsl.h" #include "hw/pcmcia.h" #include "block/block.h" #include "hw/boards.h" -#include "hw/i2c.h" +#include "hw/i2c/i2c.h" #include "hw/ssi.h" #include "sysemu/blockdev.h" #include "hw/sysbus.h" diff --git a/hw/arm/versatilepb.c b/hw/arm/versatilepb.c index baaa265888..d9be604481 100644 --- a/hw/arm/versatilepb.c +++ b/hw/arm/versatilepb.c @@ -8,16 +8,16 @@ */ #include "hw/sysbus.h" -#include "hw/arm-misc.h" -#include "hw/devices.h" +#include "hw/arm.h" +#include "hw/arm/devices.h" #include "net/net.h" #include "sysemu/sysemu.h" #include "hw/pci/pci.h" -#include "hw/i2c.h" +#include "hw/i2c/i2c.h" #include "hw/boards.h" #include "sysemu/blockdev.h" #include "exec/address-spaces.h" -#include "hw/flash.h" +#include "hw/block/flash.h" #define VERSATILE_FLASH_ADDR 0x34000000 #define VERSATILE_FLASH_SIZE (64 * 1024 * 1024) diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c index 2e1a5d0e5b..96e098579f 100644 --- a/hw/arm/vexpress.c +++ b/hw/arm/vexpress.c @@ -22,15 +22,15 @@ */ #include "hw/sysbus.h" -#include "hw/arm-misc.h" -#include "hw/primecell.h" -#include "hw/devices.h" +#include "hw/arm.h" +#include "hw/arm/primecell.h" +#include "hw/arm/devices.h" #include "net/net.h" #include "sysemu/sysemu.h" #include "hw/boards.h" #include "exec/address-spaces.h" #include "sysemu/blockdev.h" -#include "hw/flash.h" +#include "hw/block/flash.h" #define VEXPRESS_BOARD_ID 0x8e0 #define VEXPRESS_FLASH_SIZE (64 * 1024 * 1024) diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c index 5b9257a9de..8d65f796f9 100644 --- a/hw/arm/xilinx_zynq.c +++ b/hw/arm/xilinx_zynq.c @@ -16,12 +16,12 @@ */ #include "hw/sysbus.h" -#include "hw/arm-misc.h" +#include "hw/arm.h" #include "net/net.h" #include "exec/address-spaces.h" #include "sysemu/sysemu.h" #include "hw/boards.h" -#include "hw/flash.h" +#include "hw/block/flash.h" #include "sysemu/blockdev.h" #include "hw/loader.h" #include "hw/ssi.h" diff --git a/hw/arm/z2.c b/hw/arm/z2.c index cbb6d8085e..3e272088f5 100644 --- a/hw/arm/z2.c +++ b/hw/arm/z2.c @@ -12,14 +12,14 @@ */ #include "hw/hw.h" -#include "hw/pxa.h" -#include "hw/arm-misc.h" -#include "hw/devices.h" -#include "hw/i2c.h" +#include "hw/arm/pxa.h" +#include "hw/arm.h" +#include "hw/arm/devices.h" +#include "hw/i2c/i2c.h" #include "hw/ssi.h" #include "hw/boards.h" #include "sysemu/sysemu.h" -#include "hw/flash.h" +#include "hw/block/flash.h" #include "sysemu/blockdev.h" #include "ui/console.h" #include "audio/audio.h" |