summaryrefslogtreecommitdiffstats
path: root/qemu/hw/arm
diff options
context:
space:
mode:
Diffstat (limited to 'qemu/hw/arm')
-rw-r--r--qemu/hw/arm/Makefile.objs19
-rw-r--r--qemu/hw/arm/allwinner-a10.c142
-rw-r--r--qemu/hw/arm/armv7m.c265
-rw-r--r--qemu/hw/arm/ast2400.c140
-rw-r--r--qemu/hw/arm/bcm2835_peripherals.c312
-rw-r--r--qemu/hw/arm/bcm2836.c184
-rw-r--r--qemu/hw/arm/boot.c994
-rw-r--r--qemu/hw/arm/collie.c68
-rw-r--r--qemu/hw/arm/cubieboard.c86
-rw-r--r--qemu/hw/arm/digic.c123
-rw-r--r--qemu/hw/arm/digic_boards.c160
-rw-r--r--qemu/hw/arm/exynos4210.c378
-rw-r--r--qemu/hw/arm/exynos4_boards.c186
-rw-r--r--qemu/hw/arm/fsl-imx25.c313
-rw-r--r--qemu/hw/arm/fsl-imx31.c287
-rw-r--r--qemu/hw/arm/gumstix.c159
-rw-r--r--qemu/hw/arm/highbank.c441
-rw-r--r--qemu/hw/arm/imx25_pdk.c153
-rw-r--r--qemu/hw/arm/integratorcp.c674
-rw-r--r--qemu/hw/arm/kzm.c147
-rw-r--r--qemu/hw/arm/mainstone.c199
-rw-r--r--qemu/hw/arm/musicpal.c1751
-rw-r--r--qemu/hw/arm/netduino2.c49
-rw-r--r--qemu/hw/arm/nseries.c1454
-rw-r--r--qemu/hw/arm/omap1.c4086
-rw-r--r--qemu/hw/arm/omap2.c2691
-rw-r--r--qemu/hw/arm/omap_sx1.c256
-rw-r--r--qemu/hw/arm/palm.c280
-rw-r--r--qemu/hw/arm/palmetto-bmc.c68
-rw-r--r--qemu/hw/arm/pxa2xx.c2358
-rw-r--r--qemu/hw/arm/pxa2xx_gpio.c357
-rw-r--r--qemu/hw/arm/pxa2xx_pic.c340
-rw-r--r--qemu/hw/arm/raspi.c172
-rw-r--r--qemu/hw/arm/realview.c463
-rw-r--r--qemu/hw/arm/spitz.c1178
-rw-r--r--qemu/hw/arm/stellaris.c1475
-rw-r--r--qemu/hw/arm/stm32f205_soc.c165
-rw-r--r--qemu/hw/arm/strongarm.c1662
-rw-r--r--qemu/hw/arm/strongarm.h68
-rw-r--r--qemu/hw/arm/sysbus-fdt.c542
-rw-r--r--qemu/hw/arm/tosa.c303
-rw-r--r--qemu/hw/arm/versatilepb.c448
-rw-r--r--qemu/hw/arm/vexpress.c806
-rw-r--r--qemu/hw/arm/virt-acpi-build.c755
-rw-r--r--qemu/hw/arm/virt.c1435
-rw-r--r--qemu/hw/arm/xilinx_zynq.c318
-rw-r--r--qemu/hw/arm/xlnx-ep108.c115
-rw-r--r--qemu/hw/arm/xlnx-zynqmp.c403
-rw-r--r--qemu/hw/arm/z2.c382
49 files changed, 0 insertions, 29810 deletions
diff --git a/qemu/hw/arm/Makefile.objs b/qemu/hw/arm/Makefile.objs
deleted file mode 100644
index 954c9fe15..000000000
--- a/qemu/hw/arm/Makefile.objs
+++ /dev/null
@@ -1,19 +0,0 @@
-obj-y += boot.o collie.o exynos4_boards.o gumstix.o highbank.o
-obj-$(CONFIG_DIGIC) += digic_boards.o
-obj-y += integratorcp.o mainstone.o musicpal.o nseries.o
-obj-y += omap_sx1.o palm.o realview.o spitz.o stellaris.o
-obj-y += tosa.o versatilepb.o vexpress.o virt.o xilinx_zynq.o z2.o
-obj-$(CONFIG_ACPI) += virt-acpi-build.o
-obj-y += netduino2.o
-obj-y += sysbus-fdt.o
-
-obj-y += armv7m.o exynos4210.o pxa2xx.o pxa2xx_gpio.o pxa2xx_pic.o
-obj-$(CONFIG_DIGIC) += digic.o
-obj-y += omap1.o omap2.o strongarm.o
-obj-$(CONFIG_ALLWINNER_A10) += allwinner-a10.o cubieboard.o
-obj-$(CONFIG_RASPI) += bcm2835_peripherals.o bcm2836.o raspi.o
-obj-$(CONFIG_STM32F205_SOC) += stm32f205_soc.o
-obj-$(CONFIG_XLNX_ZYNQMP) += xlnx-zynqmp.o xlnx-ep108.o
-obj-$(CONFIG_FSL_IMX25) += fsl-imx25.o imx25_pdk.o
-obj-$(CONFIG_FSL_IMX31) += fsl-imx31.o kzm.o
-obj-$(CONFIG_ASPEED_SOC) += ast2400.o palmetto-bmc.o
diff --git a/qemu/hw/arm/allwinner-a10.c b/qemu/hw/arm/allwinner-a10.c
deleted file mode 100644
index ca15d1c8c..000000000
--- a/qemu/hw/arm/allwinner-a10.c
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Allwinner A10 SoC emulation
- *
- * Copyright (C) 2013 Li Guang
- * Written by Li Guang <lig.fnst@cn.fujitsu.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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.
- */
-
-#include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "qemu-common.h"
-#include "cpu.h"
-#include "hw/sysbus.h"
-#include "hw/devices.h"
-#include "hw/arm/allwinner-a10.h"
-
-static void aw_a10_init(Object *obj)
-{
- AwA10State *s = AW_A10(obj);
-
- object_initialize(&s->cpu, sizeof(s->cpu), "cortex-a8-" TYPE_ARM_CPU);
- object_property_add_child(obj, "cpu", OBJECT(&s->cpu), NULL);
-
- object_initialize(&s->intc, sizeof(s->intc), TYPE_AW_A10_PIC);
- qdev_set_parent_bus(DEVICE(&s->intc), sysbus_get_default());
-
- object_initialize(&s->timer, sizeof(s->timer), TYPE_AW_A10_PIT);
- qdev_set_parent_bus(DEVICE(&s->timer), sysbus_get_default());
-
- object_initialize(&s->emac, sizeof(s->emac), TYPE_AW_EMAC);
- qdev_set_parent_bus(DEVICE(&s->emac), sysbus_get_default());
- /* FIXME use qdev NIC properties instead of nd_table[] */
- if (nd_table[0].used) {
- qemu_check_nic_model(&nd_table[0], TYPE_AW_EMAC);
- qdev_set_nic_properties(DEVICE(&s->emac), &nd_table[0]);
- }
-
- object_initialize(&s->sata, sizeof(s->sata), TYPE_ALLWINNER_AHCI);
- qdev_set_parent_bus(DEVICE(&s->sata), sysbus_get_default());
-}
-
-static void aw_a10_realize(DeviceState *dev, Error **errp)
-{
- AwA10State *s = AW_A10(dev);
- SysBusDevice *sysbusdev;
- uint8_t i;
- qemu_irq fiq, irq;
- Error *err = NULL;
-
- object_property_set_bool(OBJECT(&s->cpu), true, "realized", &err);
- if (err != NULL) {
- error_propagate(errp, err);
- return;
- }
- irq = qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_IRQ);
- fiq = qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_FIQ);
-
- object_property_set_bool(OBJECT(&s->intc), true, "realized", &err);
- if (err != NULL) {
- error_propagate(errp, err);
- return;
- }
- sysbusdev = SYS_BUS_DEVICE(&s->intc);
- sysbus_mmio_map(sysbusdev, 0, AW_A10_PIC_REG_BASE);
- sysbus_connect_irq(sysbusdev, 0, irq);
- sysbus_connect_irq(sysbusdev, 1, fiq);
- for (i = 0; i < AW_A10_PIC_INT_NR; i++) {
- s->irq[i] = qdev_get_gpio_in(DEVICE(&s->intc), i);
- }
-
- object_property_set_bool(OBJECT(&s->timer), true, "realized", &err);
- if (err != NULL) {
- error_propagate(errp, err);
- return;
- }
- sysbusdev = SYS_BUS_DEVICE(&s->timer);
- sysbus_mmio_map(sysbusdev, 0, AW_A10_PIT_REG_BASE);
- sysbus_connect_irq(sysbusdev, 0, s->irq[22]);
- sysbus_connect_irq(sysbusdev, 1, s->irq[23]);
- sysbus_connect_irq(sysbusdev, 2, s->irq[24]);
- sysbus_connect_irq(sysbusdev, 3, s->irq[25]);
- sysbus_connect_irq(sysbusdev, 4, s->irq[67]);
- sysbus_connect_irq(sysbusdev, 5, s->irq[68]);
-
- object_property_set_bool(OBJECT(&s->emac), true, "realized", &err);
- if (err != NULL) {
- error_propagate(errp, err);
- return;
- }
- sysbusdev = SYS_BUS_DEVICE(&s->emac);
- sysbus_mmio_map(sysbusdev, 0, AW_A10_EMAC_BASE);
- sysbus_connect_irq(sysbusdev, 0, s->irq[55]);
-
- object_property_set_bool(OBJECT(&s->sata), true, "realized", &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->sata), 0, AW_A10_SATA_BASE);
- sysbus_connect_irq(SYS_BUS_DEVICE(&s->sata), 0, s->irq[56]);
-
- /* FIXME use a qdev chardev prop instead of serial_hds[] */
- serial_mm_init(get_system_memory(), AW_A10_UART0_REG_BASE, 2, s->irq[1],
- 115200, serial_hds[0], DEVICE_NATIVE_ENDIAN);
-}
-
-static void aw_a10_class_init(ObjectClass *oc, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
-
- dc->realize = aw_a10_realize;
-
- /*
- * Reason: creates an ARM CPU, thus use after free(), see
- * arm_cpu_class_init()
- */
- dc->cannot_destroy_with_object_finalize_yet = true;
-}
-
-static const TypeInfo aw_a10_type_info = {
- .name = TYPE_AW_A10,
- .parent = TYPE_DEVICE,
- .instance_size = sizeof(AwA10State),
- .instance_init = aw_a10_init,
- .class_init = aw_a10_class_init,
-};
-
-static void aw_a10_register_types(void)
-{
- type_register_static(&aw_a10_type_info);
-}
-
-type_init(aw_a10_register_types)
diff --git a/qemu/hw/arm/armv7m.c b/qemu/hw/arm/armv7m.c
deleted file mode 100644
index bb2a22d96..000000000
--- a/qemu/hw/arm/armv7m.c
+++ /dev/null
@@ -1,265 +0,0 @@
-/*
- * ARMV7M System emulation.
- *
- * Copyright (c) 2006-2007 CodeSourcery.
- * Written by Paul Brook
- *
- * This code is licensed under the GPL.
- */
-
-#include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "qemu-common.h"
-#include "cpu.h"
-#include "hw/sysbus.h"
-#include "hw/arm/arm.h"
-#include "hw/loader.h"
-#include "elf.h"
-#include "sysemu/qtest.h"
-#include "qemu/error-report.h"
-
-/* Bitbanded IO. Each word corresponds to a single bit. */
-
-/* Get the byte address of the real memory for a bitband access. */
-static inline uint32_t bitband_addr(void * opaque, uint32_t addr)
-{
- uint32_t res;
-
- res = *(uint32_t *)opaque;
- res |= (addr & 0x1ffffff) >> 5;
- return res;
-
-}
-
-static uint32_t bitband_readb(void *opaque, hwaddr offset)
-{
- uint8_t v;
- cpu_physical_memory_read(bitband_addr(opaque, offset), &v, 1);
- return (v & (1 << ((offset >> 2) & 7))) != 0;
-}
-
-static void bitband_writeb(void *opaque, hwaddr offset,
- uint32_t value)
-{
- uint32_t addr;
- uint8_t mask;
- uint8_t v;
- addr = bitband_addr(opaque, offset);
- mask = (1 << ((offset >> 2) & 7));
- cpu_physical_memory_read(addr, &v, 1);
- if (value & 1)
- v |= mask;
- else
- v &= ~mask;
- cpu_physical_memory_write(addr, &v, 1);
-}
-
-static uint32_t bitband_readw(void *opaque, hwaddr offset)
-{
- uint32_t addr;
- uint16_t mask;
- uint16_t v;
- addr = bitband_addr(opaque, offset) & ~1;
- mask = (1 << ((offset >> 2) & 15));
- mask = tswap16(mask);
- cpu_physical_memory_read(addr, &v, 2);
- return (v & mask) != 0;
-}
-
-static void bitband_writew(void *opaque, hwaddr offset,
- uint32_t value)
-{
- uint32_t addr;
- uint16_t mask;
- uint16_t v;
- addr = bitband_addr(opaque, offset) & ~1;
- mask = (1 << ((offset >> 2) & 15));
- mask = tswap16(mask);
- cpu_physical_memory_read(addr, &v, 2);
- if (value & 1)
- v |= mask;
- else
- v &= ~mask;
- cpu_physical_memory_write(addr, &v, 2);
-}
-
-static uint32_t bitband_readl(void *opaque, hwaddr offset)
-{
- uint32_t addr;
- uint32_t mask;
- uint32_t v;
- addr = bitband_addr(opaque, offset) & ~3;
- mask = (1 << ((offset >> 2) & 31));
- mask = tswap32(mask);
- cpu_physical_memory_read(addr, &v, 4);
- return (v & mask) != 0;
-}
-
-static void bitband_writel(void *opaque, hwaddr offset,
- uint32_t value)
-{
- uint32_t addr;
- uint32_t mask;
- uint32_t v;
- addr = bitband_addr(opaque, offset) & ~3;
- mask = (1 << ((offset >> 2) & 31));
- mask = tswap32(mask);
- cpu_physical_memory_read(addr, &v, 4);
- if (value & 1)
- v |= mask;
- else
- v &= ~mask;
- cpu_physical_memory_write(addr, &v, 4);
-}
-
-static const MemoryRegionOps bitband_ops = {
- .old_mmio = {
- .read = { bitband_readb, bitband_readw, bitband_readl, },
- .write = { bitband_writeb, bitband_writew, bitband_writel, },
- },
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-#define TYPE_BITBAND "ARM,bitband-memory"
-#define BITBAND(obj) OBJECT_CHECK(BitBandState, (obj), TYPE_BITBAND)
-
-typedef struct {
- /*< private >*/
- SysBusDevice parent_obj;
- /*< public >*/
-
- MemoryRegion iomem;
- uint32_t base;
-} BitBandState;
-
-static int bitband_init(SysBusDevice *dev)
-{
- BitBandState *s = BITBAND(dev);
-
- memory_region_init_io(&s->iomem, OBJECT(s), &bitband_ops, &s->base,
- "bitband", 0x02000000);
- sysbus_init_mmio(dev, &s->iomem);
- return 0;
-}
-
-static void armv7m_bitband_init(void)
-{
- DeviceState *dev;
-
- dev = qdev_create(NULL, TYPE_BITBAND);
- qdev_prop_set_uint32(dev, "base", 0x20000000);
- qdev_init_nofail(dev);
- sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, 0x22000000);
-
- dev = qdev_create(NULL, TYPE_BITBAND);
- qdev_prop_set_uint32(dev, "base", 0x40000000);
- qdev_init_nofail(dev);
- sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, 0x42000000);
-}
-
-/* Board init. */
-
-static void armv7m_reset(void *opaque)
-{
- ARMCPU *cpu = opaque;
-
- cpu_reset(CPU(cpu));
-}
-
-/* Init CPU and memory for a v7-M based board.
- mem_size is in bytes.
- Returns the NVIC array. */
-
-DeviceState *armv7m_init(MemoryRegion *system_memory, int mem_size, int num_irq,
- const char *kernel_filename, const char *cpu_model)
-{
- ARMCPU *cpu;
- CPUARMState *env;
- DeviceState *nvic;
- int image_size;
- uint64_t entry;
- uint64_t lowaddr;
- int big_endian;
- MemoryRegion *hack = g_new(MemoryRegion, 1);
-
- if (cpu_model == NULL) {
- cpu_model = "cortex-m3";
- }
- cpu = cpu_arm_init(cpu_model);
- if (cpu == NULL) {
- fprintf(stderr, "Unable to find CPU definition\n");
- exit(1);
- }
- env = &cpu->env;
-
- armv7m_bitband_init();
-
- nvic = qdev_create(NULL, "armv7m_nvic");
- qdev_prop_set_uint32(nvic, "num-irq", num_irq);
- env->nvic = nvic;
- qdev_init_nofail(nvic);
- sysbus_connect_irq(SYS_BUS_DEVICE(nvic), 0,
- qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ));
-
-#ifdef TARGET_WORDS_BIGENDIAN
- big_endian = 1;
-#else
- big_endian = 0;
-#endif
-
- if (!kernel_filename && !qtest_enabled()) {
- fprintf(stderr, "Guest image must be specified (using -kernel)\n");
- exit(1);
- }
-
- if (kernel_filename) {
- image_size = load_elf(kernel_filename, NULL, NULL, &entry, &lowaddr,
- NULL, big_endian, EM_ARM, 1, 0);
- if (image_size < 0) {
- image_size = load_image_targphys(kernel_filename, 0, mem_size);
- lowaddr = 0;
- }
- if (image_size < 0) {
- error_report("Could not load kernel '%s'", kernel_filename);
- exit(1);
- }
- }
-
- /* Hack to map an additional page of ram at the top of the address
- space. This stops qemu complaining about executing code outside RAM
- when returning from an exception. */
- memory_region_init_ram(hack, NULL, "armv7m.hack", 0x1000, &error_fatal);
- vmstate_register_ram_global(hack);
- memory_region_add_subregion(system_memory, 0xfffff000, hack);
-
- qemu_register_reset(armv7m_reset, cpu);
- return nvic;
-}
-
-static Property bitband_properties[] = {
- DEFINE_PROP_UINT32("base", BitBandState, base, 0),
- DEFINE_PROP_END_OF_LIST(),
-};
-
-static void bitband_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
-
- k->init = bitband_init;
- dc->props = bitband_properties;
-}
-
-static const TypeInfo bitband_info = {
- .name = TYPE_BITBAND,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(BitBandState),
- .class_init = bitband_class_init,
-};
-
-static void armv7m_register_types(void)
-{
- type_register_static(&bitband_info);
-}
-
-type_init(armv7m_register_types)
diff --git a/qemu/hw/arm/ast2400.c b/qemu/hw/arm/ast2400.c
deleted file mode 100644
index 03f993863..000000000
--- a/qemu/hw/arm/ast2400.c
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * AST2400 SoC
- *
- * Andrew Jeffery <andrew@aj.id.au>
- * Jeremy Kerr <jk@ozlabs.org>
- *
- * Copyright 2016 IBM Corp.
- *
- * This code is licensed under the GPL version 2 or later. See
- * the COPYING file in the top-level directory.
- */
-
-#include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "qemu-common.h"
-#include "cpu.h"
-#include "exec/address-spaces.h"
-#include "hw/arm/ast2400.h"
-#include "hw/char/serial.h"
-
-#define AST2400_UART_5_BASE 0x00184000
-#define AST2400_IOMEM_SIZE 0x00200000
-#define AST2400_IOMEM_BASE 0x1E600000
-#define AST2400_VIC_BASE 0x1E6C0000
-#define AST2400_TIMER_BASE 0x1E782000
-
-static const int uart_irqs[] = { 9, 32, 33, 34, 10 };
-static const int timer_irqs[] = { 16, 17, 18, 35, 36, 37, 38, 39, };
-
-/*
- * IO handlers: simply catch any reads/writes to IO addresses that aren't
- * handled by a device mapping.
- */
-
-static uint64_t ast2400_io_read(void *p, hwaddr offset, unsigned size)
-{
- qemu_log_mask(LOG_UNIMP, "%s: 0x%" HWADDR_PRIx " [%u]\n",
- __func__, offset, size);
- return 0;
-}
-
-static void ast2400_io_write(void *opaque, hwaddr offset, uint64_t value,
- unsigned size)
-{
- qemu_log_mask(LOG_UNIMP, "%s: 0x%" HWADDR_PRIx " <- 0x%" PRIx64 " [%u]\n",
- __func__, offset, value, size);
-}
-
-static const MemoryRegionOps ast2400_io_ops = {
- .read = ast2400_io_read,
- .write = ast2400_io_write,
- .endianness = DEVICE_LITTLE_ENDIAN,
-};
-
-static void ast2400_init(Object *obj)
-{
- AST2400State *s = AST2400(obj);
-
- s->cpu = cpu_arm_init("arm926");
-
- object_initialize(&s->vic, sizeof(s->vic), TYPE_ASPEED_VIC);
- object_property_add_child(obj, "vic", OBJECT(&s->vic), NULL);
- qdev_set_parent_bus(DEVICE(&s->vic), sysbus_get_default());
-
- object_initialize(&s->timerctrl, sizeof(s->timerctrl), TYPE_ASPEED_TIMER);
- object_property_add_child(obj, "timerctrl", OBJECT(&s->timerctrl), NULL);
- qdev_set_parent_bus(DEVICE(&s->timerctrl), sysbus_get_default());
-}
-
-static void ast2400_realize(DeviceState *dev, Error **errp)
-{
- int i;
- AST2400State *s = AST2400(dev);
- Error *err = NULL;
-
- /* IO space */
- memory_region_init_io(&s->iomem, NULL, &ast2400_io_ops, NULL,
- "ast2400.io", AST2400_IOMEM_SIZE);
- memory_region_add_subregion_overlap(get_system_memory(), AST2400_IOMEM_BASE,
- &s->iomem, -1);
-
- /* VIC */
- object_property_set_bool(OBJECT(&s->vic), true, "realized", &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->vic), 0, AST2400_VIC_BASE);
- sysbus_connect_irq(SYS_BUS_DEVICE(&s->vic), 0,
- qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_IRQ));
- sysbus_connect_irq(SYS_BUS_DEVICE(&s->vic), 1,
- qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_FIQ));
-
- /* Timer */
- object_property_set_bool(OBJECT(&s->timerctrl), true, "realized", &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->timerctrl), 0, AST2400_TIMER_BASE);
- for (i = 0; i < ARRAY_SIZE(timer_irqs); i++) {
- qemu_irq irq = qdev_get_gpio_in(DEVICE(&s->vic), timer_irqs[i]);
- sysbus_connect_irq(SYS_BUS_DEVICE(&s->timerctrl), i, irq);
- }
-
- /* UART - attach an 8250 to the IO space as our UART5 */
- if (serial_hds[0]) {
- qemu_irq uart5 = qdev_get_gpio_in(DEVICE(&s->vic), uart_irqs[4]);
- serial_mm_init(&s->iomem, AST2400_UART_5_BASE, 2,
- uart5, 38400, serial_hds[0], DEVICE_LITTLE_ENDIAN);
- }
-}
-
-static void ast2400_class_init(ObjectClass *oc, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
-
- dc->realize = ast2400_realize;
-
- /*
- * Reason: creates an ARM CPU, thus use after free(), see
- * arm_cpu_class_init()
- */
- dc->cannot_destroy_with_object_finalize_yet = true;
-}
-
-static const TypeInfo ast2400_type_info = {
- .name = TYPE_AST2400,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(AST2400State),
- .instance_init = ast2400_init,
- .class_init = ast2400_class_init,
-};
-
-static void ast2400_register_types(void)
-{
- type_register_static(&ast2400_type_info);
-}
-
-type_init(ast2400_register_types)
diff --git a/qemu/hw/arm/bcm2835_peripherals.c b/qemu/hw/arm/bcm2835_peripherals.c
deleted file mode 100644
index 234d51843..000000000
--- a/qemu/hw/arm/bcm2835_peripherals.c
+++ /dev/null
@@ -1,312 +0,0 @@
-/*
- * Raspberry Pi emulation (c) 2012 Gregory Estrade
- * Upstreaming code cleanup [including bcm2835_*] (c) 2013 Jan Petrous
- *
- * Rasperry Pi 2 emulation and refactoring Copyright (c) 2015, Microsoft
- * Written by Andrew Baumann
- *
- * This code is licensed under the GNU GPLv2 and later.
- */
-
-#include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "hw/arm/bcm2835_peripherals.h"
-#include "hw/misc/bcm2835_mbox_defs.h"
-#include "hw/arm/raspi_platform.h"
-#include "sysemu/char.h"
-
-/* Peripheral base address on the VC (GPU) system bus */
-#define BCM2835_VC_PERI_BASE 0x7e000000
-
-/* Capabilities for SD controller: no DMA, high-speed, default clocks etc. */
-#define BCM2835_SDHC_CAPAREG 0x52034b4
-
-static void bcm2835_peripherals_init(Object *obj)
-{
- BCM2835PeripheralState *s = BCM2835_PERIPHERALS(obj);
-
- /* Memory region for peripheral devices, which we export to our parent */
- memory_region_init(&s->peri_mr, obj,"bcm2835-peripherals", 0x1000000);
- object_property_add_child(obj, "peripheral-io", OBJECT(&s->peri_mr), NULL);
- sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->peri_mr);
-
- /* Internal memory region for peripheral bus addresses (not exported) */
- memory_region_init(&s->gpu_bus_mr, obj, "bcm2835-gpu", (uint64_t)1 << 32);
- object_property_add_child(obj, "gpu-bus", OBJECT(&s->gpu_bus_mr), NULL);
-
- /* Internal memory region for request/response communication with
- * mailbox-addressable peripherals (not exported)
- */
- memory_region_init(&s->mbox_mr, obj, "bcm2835-mbox",
- MBOX_CHAN_COUNT << MBOX_AS_CHAN_SHIFT);
-
- /* Interrupt Controller */
- object_initialize(&s->ic, sizeof(s->ic), TYPE_BCM2835_IC);
- object_property_add_child(obj, "ic", OBJECT(&s->ic), NULL);
- qdev_set_parent_bus(DEVICE(&s->ic), sysbus_get_default());
-
- /* UART0 */
- s->uart0 = SYS_BUS_DEVICE(object_new("pl011"));
- object_property_add_child(obj, "uart0", OBJECT(s->uart0), NULL);
- qdev_set_parent_bus(DEVICE(s->uart0), sysbus_get_default());
-
- /* AUX / UART1 */
- object_initialize(&s->aux, sizeof(s->aux), TYPE_BCM2835_AUX);
- object_property_add_child(obj, "aux", OBJECT(&s->aux), NULL);
- qdev_set_parent_bus(DEVICE(&s->aux), sysbus_get_default());
-
- /* Mailboxes */
- object_initialize(&s->mboxes, sizeof(s->mboxes), TYPE_BCM2835_MBOX);
- object_property_add_child(obj, "mbox", OBJECT(&s->mboxes), NULL);
- qdev_set_parent_bus(DEVICE(&s->mboxes), sysbus_get_default());
-
- object_property_add_const_link(OBJECT(&s->mboxes), "mbox-mr",
- OBJECT(&s->mbox_mr), &error_abort);
-
- /* Framebuffer */
- object_initialize(&s->fb, sizeof(s->fb), TYPE_BCM2835_FB);
- object_property_add_child(obj, "fb", OBJECT(&s->fb), NULL);
- object_property_add_alias(obj, "vcram-size", OBJECT(&s->fb), "vcram-size",
- &error_abort);
- qdev_set_parent_bus(DEVICE(&s->fb), sysbus_get_default());
-
- object_property_add_const_link(OBJECT(&s->fb), "dma-mr",
- OBJECT(&s->gpu_bus_mr), &error_abort);
-
- /* Property channel */
- object_initialize(&s->property, sizeof(s->property), TYPE_BCM2835_PROPERTY);
- object_property_add_child(obj, "property", OBJECT(&s->property), NULL);
- object_property_add_alias(obj, "board-rev", OBJECT(&s->property),
- "board-rev", &error_abort);
- qdev_set_parent_bus(DEVICE(&s->property), sysbus_get_default());
-
- object_property_add_const_link(OBJECT(&s->property), "fb",
- OBJECT(&s->fb), &error_abort);
- object_property_add_const_link(OBJECT(&s->property), "dma-mr",
- OBJECT(&s->gpu_bus_mr), &error_abort);
-
- /* Extended Mass Media Controller */
- object_initialize(&s->sdhci, sizeof(s->sdhci), TYPE_SYSBUS_SDHCI);
- object_property_add_child(obj, "sdhci", OBJECT(&s->sdhci), NULL);
- qdev_set_parent_bus(DEVICE(&s->sdhci), sysbus_get_default());
-
- /* DMA Channels */
- object_initialize(&s->dma, sizeof(s->dma), TYPE_BCM2835_DMA);
- object_property_add_child(obj, "dma", OBJECT(&s->dma), NULL);
- qdev_set_parent_bus(DEVICE(&s->dma), sysbus_get_default());
-
- object_property_add_const_link(OBJECT(&s->dma), "dma-mr",
- OBJECT(&s->gpu_bus_mr), &error_abort);
-}
-
-static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
-{
- BCM2835PeripheralState *s = BCM2835_PERIPHERALS(dev);
- Object *obj;
- MemoryRegion *ram;
- Error *err = NULL;
- uint32_t ram_size, vcram_size;
- CharDriverState *chr;
- int n;
-
- obj = object_property_get_link(OBJECT(dev), "ram", &err);
- if (obj == NULL) {
- error_setg(errp, "%s: required ram link not found: %s",
- __func__, error_get_pretty(err));
- return;
- }
-
- ram = MEMORY_REGION(obj);
- ram_size = memory_region_size(ram);
-
- /* Map peripherals and RAM into the GPU address space. */
- memory_region_init_alias(&s->peri_mr_alias, OBJECT(s),
- "bcm2835-peripherals", &s->peri_mr, 0,
- memory_region_size(&s->peri_mr));
-
- memory_region_add_subregion_overlap(&s->gpu_bus_mr, BCM2835_VC_PERI_BASE,
- &s->peri_mr_alias, 1);
-
- /* RAM is aliased four times (different cache configurations) on the GPU */
- for (n = 0; n < 4; n++) {
- memory_region_init_alias(&s->ram_alias[n], OBJECT(s),
- "bcm2835-gpu-ram-alias[*]", ram, 0, ram_size);
- memory_region_add_subregion_overlap(&s->gpu_bus_mr, (hwaddr)n << 30,
- &s->ram_alias[n], 0);
- }
-
- /* Interrupt Controller */
- object_property_set_bool(OBJECT(&s->ic), true, "realized", &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
-
- memory_region_add_subregion(&s->peri_mr, ARMCTRL_IC_OFFSET,
- sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->ic), 0));
- sysbus_pass_irq(SYS_BUS_DEVICE(s), SYS_BUS_DEVICE(&s->ic));
-
- /* UART0 */
- object_property_set_bool(OBJECT(s->uart0), true, "realized", &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
-
- memory_region_add_subregion(&s->peri_mr, UART0_OFFSET,
- sysbus_mmio_get_region(s->uart0, 0));
- sysbus_connect_irq(s->uart0, 0,
- qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ,
- INTERRUPT_UART));
-
- /* AUX / UART1 */
- /* TODO: don't call qemu_char_get_next_serial() here, instead set
- * chardev properties for each uart at the board level, once pl011
- * (uart0) has been updated to avoid qemu_char_get_next_serial()
- */
- chr = qemu_char_get_next_serial();
- if (chr == NULL) {
- chr = qemu_chr_new("bcm2835.uart1", "null", NULL);
- }
- qdev_prop_set_chr(DEVICE(&s->aux), "chardev", chr);
-
- object_property_set_bool(OBJECT(&s->aux), true, "realized", &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
-
- memory_region_add_subregion(&s->peri_mr, UART1_OFFSET,
- sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->aux), 0));
- sysbus_connect_irq(SYS_BUS_DEVICE(&s->aux), 0,
- qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ,
- INTERRUPT_AUX));
-
- /* Mailboxes */
- object_property_set_bool(OBJECT(&s->mboxes), true, "realized", &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
-
- memory_region_add_subregion(&s->peri_mr, ARMCTRL_0_SBM_OFFSET,
- sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->mboxes), 0));
- sysbus_connect_irq(SYS_BUS_DEVICE(&s->mboxes), 0,
- qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_ARM_IRQ,
- INTERRUPT_ARM_MAILBOX));
-
- /* Framebuffer */
- vcram_size = (uint32_t)object_property_get_int(OBJECT(s), "vcram-size",
- &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
-
- object_property_set_int(OBJECT(&s->fb), ram_size - vcram_size,
- "vcram-base", &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
-
- object_property_set_bool(OBJECT(&s->fb), true, "realized", &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
-
- memory_region_add_subregion(&s->mbox_mr, MBOX_CHAN_FB << MBOX_AS_CHAN_SHIFT,
- sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->fb), 0));
- sysbus_connect_irq(SYS_BUS_DEVICE(&s->fb), 0,
- qdev_get_gpio_in(DEVICE(&s->mboxes), MBOX_CHAN_FB));
-
- /* Property channel */
- object_property_set_bool(OBJECT(&s->property), true, "realized", &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
-
- memory_region_add_subregion(&s->mbox_mr,
- MBOX_CHAN_PROPERTY << MBOX_AS_CHAN_SHIFT,
- sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->property), 0));
- sysbus_connect_irq(SYS_BUS_DEVICE(&s->property), 0,
- qdev_get_gpio_in(DEVICE(&s->mboxes), MBOX_CHAN_PROPERTY));
-
- /* Extended Mass Media Controller */
- object_property_set_int(OBJECT(&s->sdhci), BCM2835_SDHC_CAPAREG, "capareg",
- &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
-
- object_property_set_bool(OBJECT(&s->sdhci), true, "pending-insert-quirk",
- &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
-
- object_property_set_bool(OBJECT(&s->sdhci), true, "realized", &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
-
- memory_region_add_subregion(&s->peri_mr, EMMC_OFFSET,
- sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->sdhci), 0));
- sysbus_connect_irq(SYS_BUS_DEVICE(&s->sdhci), 0,
- qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ,
- INTERRUPT_ARASANSDIO));
- object_property_add_alias(OBJECT(s), "sd-bus", OBJECT(&s->sdhci), "sd-bus",
- &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
-
- /* DMA Channels */
- object_property_set_bool(OBJECT(&s->dma), true, "realized", &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
-
- memory_region_add_subregion(&s->peri_mr, DMA_OFFSET,
- sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->dma), 0));
- memory_region_add_subregion(&s->peri_mr, DMA15_OFFSET,
- sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->dma), 1));
-
- for (n = 0; n <= 12; n++) {
- sysbus_connect_irq(SYS_BUS_DEVICE(&s->dma), n,
- qdev_get_gpio_in_named(DEVICE(&s->ic),
- BCM2835_IC_GPU_IRQ,
- INTERRUPT_DMA0 + n));
- }
-}
-
-static void bcm2835_peripherals_class_init(ObjectClass *oc, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
-
- dc->realize = bcm2835_peripherals_realize;
- /* Reason: realize() method uses qemu_char_get_next_serial() */
- dc->cannot_instantiate_with_device_add_yet = true;
-}
-
-static const TypeInfo bcm2835_peripherals_type_info = {
- .name = TYPE_BCM2835_PERIPHERALS,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(BCM2835PeripheralState),
- .instance_init = bcm2835_peripherals_init,
- .class_init = bcm2835_peripherals_class_init,
-};
-
-static void bcm2835_peripherals_register_types(void)
-{
- type_register_static(&bcm2835_peripherals_type_info);
-}
-
-type_init(bcm2835_peripherals_register_types)
diff --git a/qemu/hw/arm/bcm2836.c b/qemu/hw/arm/bcm2836.c
deleted file mode 100644
index 8451190a1..000000000
--- a/qemu/hw/arm/bcm2836.c
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * Raspberry Pi emulation (c) 2012 Gregory Estrade
- * Upstreaming code cleanup [including bcm2835_*] (c) 2013 Jan Petrous
- *
- * Rasperry Pi 2 emulation and refactoring Copyright (c) 2015, Microsoft
- * Written by Andrew Baumann
- *
- * This code is licensed under the GNU GPLv2 and later.
- */
-
-#include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "qemu-common.h"
-#include "cpu.h"
-#include "hw/arm/bcm2836.h"
-#include "hw/arm/raspi_platform.h"
-#include "hw/sysbus.h"
-#include "exec/address-spaces.h"
-
-/* Peripheral base address seen by the CPU */
-#define BCM2836_PERI_BASE 0x3F000000
-
-/* "QA7" (Pi2) interrupt controller and mailboxes etc. */
-#define BCM2836_CONTROL_BASE 0x40000000
-
-static void bcm2836_init(Object *obj)
-{
- BCM2836State *s = BCM2836(obj);
- int n;
-
- for (n = 0; n < BCM2836_NCPUS; n++) {
- object_initialize(&s->cpus[n], sizeof(s->cpus[n]),
- "cortex-a15-" TYPE_ARM_CPU);
- object_property_add_child(obj, "cpu[*]", OBJECT(&s->cpus[n]),
- &error_abort);
- }
-
- object_initialize(&s->control, sizeof(s->control), TYPE_BCM2836_CONTROL);
- object_property_add_child(obj, "control", OBJECT(&s->control), NULL);
- qdev_set_parent_bus(DEVICE(&s->control), sysbus_get_default());
-
- object_initialize(&s->peripherals, sizeof(s->peripherals),
- TYPE_BCM2835_PERIPHERALS);
- object_property_add_child(obj, "peripherals", OBJECT(&s->peripherals),
- &error_abort);
- object_property_add_alias(obj, "board-rev", OBJECT(&s->peripherals),
- "board-rev", &error_abort);
- object_property_add_alias(obj, "vcram-size", OBJECT(&s->peripherals),
- "vcram-size", &error_abort);
- qdev_set_parent_bus(DEVICE(&s->peripherals), sysbus_get_default());
-}
-
-static void bcm2836_realize(DeviceState *dev, Error **errp)
-{
- BCM2836State *s = BCM2836(dev);
- Object *obj;
- Error *err = NULL;
- int n;
-
- /* common peripherals from bcm2835 */
-
- obj = object_property_get_link(OBJECT(dev), "ram", &err);
- if (obj == NULL) {
- error_setg(errp, "%s: required ram link not found: %s",
- __func__, error_get_pretty(err));
- return;
- }
-
- object_property_add_const_link(OBJECT(&s->peripherals), "ram", obj, &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
-
- object_property_set_bool(OBJECT(&s->peripherals), true, "realized", &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
-
- object_property_add_alias(OBJECT(s), "sd-bus", OBJECT(&s->peripherals),
- "sd-bus", &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
-
- sysbus_mmio_map_overlap(SYS_BUS_DEVICE(&s->peripherals), 0,
- BCM2836_PERI_BASE, 1);
-
- /* bcm2836 interrupt controller (and mailboxes, etc.) */
- object_property_set_bool(OBJECT(&s->control), true, "realized", &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
-
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->control), 0, BCM2836_CONTROL_BASE);
-
- sysbus_connect_irq(SYS_BUS_DEVICE(&s->peripherals), 0,
- qdev_get_gpio_in_named(DEVICE(&s->control), "gpu-irq", 0));
- sysbus_connect_irq(SYS_BUS_DEVICE(&s->peripherals), 1,
- qdev_get_gpio_in_named(DEVICE(&s->control), "gpu-fiq", 0));
-
- for (n = 0; n < BCM2836_NCPUS; n++) {
- /* Mirror bcm2836, which has clusterid set to 0xf
- * TODO: this should be converted to a property of ARM_CPU
- */
- s->cpus[n].mp_affinity = 0xF00 | n;
-
- /* set periphbase/CBAR value for CPU-local registers */
- object_property_set_int(OBJECT(&s->cpus[n]),
- BCM2836_PERI_BASE + MCORE_OFFSET,
- "reset-cbar", &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
-
- /* start powered off if not enabled */
- object_property_set_bool(OBJECT(&s->cpus[n]), n >= s->enabled_cpus,
- "start-powered-off", &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
-
- object_property_set_bool(OBJECT(&s->cpus[n]), true, "realized", &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
-
- /* Connect irq/fiq outputs from the interrupt controller. */
- qdev_connect_gpio_out_named(DEVICE(&s->control), "irq", n,
- qdev_get_gpio_in(DEVICE(&s->cpus[n]), ARM_CPU_IRQ));
- qdev_connect_gpio_out_named(DEVICE(&s->control), "fiq", n,
- qdev_get_gpio_in(DEVICE(&s->cpus[n]), ARM_CPU_FIQ));
-
- /* Connect timers from the CPU to the interrupt controller */
- qdev_connect_gpio_out(DEVICE(&s->cpus[n]), GTIMER_PHYS,
- qdev_get_gpio_in_named(DEVICE(&s->control), "cntpnsirq", n));
- qdev_connect_gpio_out(DEVICE(&s->cpus[n]), GTIMER_VIRT,
- qdev_get_gpio_in_named(DEVICE(&s->control), "cntvirq", n));
- qdev_connect_gpio_out(DEVICE(&s->cpus[n]), GTIMER_HYP,
- qdev_get_gpio_in_named(DEVICE(&s->control), "cnthpirq", n));
- qdev_connect_gpio_out(DEVICE(&s->cpus[n]), GTIMER_SEC,
- qdev_get_gpio_in_named(DEVICE(&s->control), "cntpsirq", n));
- }
-}
-
-static Property bcm2836_props[] = {
- DEFINE_PROP_UINT32("enabled-cpus", BCM2836State, enabled_cpus, BCM2836_NCPUS),
- DEFINE_PROP_END_OF_LIST()
-};
-
-static void bcm2836_class_init(ObjectClass *oc, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
-
- dc->props = bcm2836_props;
- dc->realize = bcm2836_realize;
-
- /*
- * Reason: creates an ARM CPU, thus use after free(), see
- * arm_cpu_class_init()
- */
- dc->cannot_destroy_with_object_finalize_yet = true;
-}
-
-static const TypeInfo bcm2836_type_info = {
- .name = TYPE_BCM2836,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(BCM2836State),
- .instance_init = bcm2836_init,
- .class_init = bcm2836_class_init,
-};
-
-static void bcm2836_register_types(void)
-{
- type_register_static(&bcm2836_type_info);
-}
-
-type_init(bcm2836_register_types)
diff --git a/qemu/hw/arm/boot.c b/qemu/hw/arm/boot.c
deleted file mode 100644
index 587694557..000000000
--- a/qemu/hw/arm/boot.c
+++ /dev/null
@@ -1,994 +0,0 @@
-/*
- * ARM kernel loader.
- *
- * Copyright (c) 2006-2007 CodeSourcery.
- * Written by Paul Brook
- *
- * This code is licensed under the GPL.
- */
-
-#include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "hw/hw.h"
-#include "hw/arm/arm.h"
-#include "hw/arm/linux-boot-if.h"
-#include "sysemu/kvm.h"
-#include "sysemu/sysemu.h"
-#include "hw/boards.h"
-#include "hw/loader.h"
-#include "elf.h"
-#include "sysemu/device_tree.h"
-#include "qemu/config-file.h"
-#include "exec/address-spaces.h"
-
-/* Kernel boot protocol is specified in the kernel docs
- * Documentation/arm/Booting and Documentation/arm64/booting.txt
- * They have different preferred image load offsets from system RAM base.
- */
-#define KERNEL_ARGS_ADDR 0x100
-#define KERNEL_LOAD_ADDR 0x00010000
-#define KERNEL64_LOAD_ADDR 0x00080000
-
-typedef enum {
- FIXUP_NONE = 0, /* do nothing */
- FIXUP_TERMINATOR, /* end of insns */
- FIXUP_BOARDID, /* overwrite with board ID number */
- FIXUP_BOARD_SETUP, /* overwrite with board specific setup code address */
- FIXUP_ARGPTR, /* overwrite with pointer to kernel args */
- FIXUP_ENTRYPOINT, /* overwrite with kernel entry point */
- FIXUP_GIC_CPU_IF, /* overwrite with GIC CPU interface address */
- FIXUP_BOOTREG, /* overwrite with boot register address */
- FIXUP_DSB, /* overwrite with correct DSB insn for cpu */
- FIXUP_MAX,
-} FixupType;
-
-typedef struct ARMInsnFixup {
- uint32_t insn;
- FixupType fixup;
-} ARMInsnFixup;
-
-static const ARMInsnFixup bootloader_aarch64[] = {
- { 0x580000c0 }, /* ldr x0, arg ; Load the lower 32-bits of DTB */
- { 0xaa1f03e1 }, /* mov x1, xzr */
- { 0xaa1f03e2 }, /* mov x2, xzr */
- { 0xaa1f03e3 }, /* mov x3, xzr */
- { 0x58000084 }, /* ldr x4, entry ; Load the lower 32-bits of kernel entry */
- { 0xd61f0080 }, /* br x4 ; Jump to the kernel entry point */
- { 0, FIXUP_ARGPTR }, /* arg: .word @DTB Lower 32-bits */
- { 0 }, /* .word @DTB Higher 32-bits */
- { 0, FIXUP_ENTRYPOINT }, /* entry: .word @Kernel Entry Lower 32-bits */
- { 0 }, /* .word @Kernel Entry Higher 32-bits */
- { 0, FIXUP_TERMINATOR }
-};
-
-/* A very small bootloader: call the board-setup code (if needed),
- * set r0-r2, then jump to the kernel.
- * If we're not calling boot setup code then we don't copy across
- * the first BOOTLOADER_NO_BOARD_SETUP_OFFSET insns in this array.
- */
-
-static const ARMInsnFixup bootloader[] = {
- { 0xe28fe004 }, /* add lr, pc, #4 */
- { 0xe51ff004 }, /* ldr pc, [pc, #-4] */
- { 0, FIXUP_BOARD_SETUP },
-#define BOOTLOADER_NO_BOARD_SETUP_OFFSET 3
- { 0xe3a00000 }, /* mov r0, #0 */
- { 0xe59f1004 }, /* ldr r1, [pc, #4] */
- { 0xe59f2004 }, /* ldr r2, [pc, #4] */
- { 0xe59ff004 }, /* ldr pc, [pc, #4] */
- { 0, FIXUP_BOARDID },
- { 0, FIXUP_ARGPTR },
- { 0, FIXUP_ENTRYPOINT },
- { 0, FIXUP_TERMINATOR }
-};
-
-/* Handling for secondary CPU boot in a multicore system.
- * Unlike the uniprocessor/primary CPU boot, this is platform
- * dependent. The default code here is based on the secondary
- * CPU boot protocol used on realview/vexpress boards, with
- * some parameterisation to increase its flexibility.
- * QEMU platform models for which this code is not appropriate
- * should override write_secondary_boot and secondary_cpu_reset_hook
- * instead.
- *
- * This code enables the interrupt controllers for the secondary
- * CPUs and then puts all the secondary CPUs into a loop waiting
- * for an interprocessor interrupt and polling a configurable
- * location for the kernel secondary CPU entry point.
- */
-#define DSB_INSN 0xf57ff04f
-#define CP15_DSB_INSN 0xee070f9a /* mcr cp15, 0, r0, c7, c10, 4 */
-
-static const ARMInsnFixup smpboot[] = {
- { 0xe59f2028 }, /* ldr r2, gic_cpu_if */
- { 0xe59f0028 }, /* ldr r0, bootreg_addr */
- { 0xe3a01001 }, /* mov r1, #1 */
- { 0xe5821000 }, /* str r1, [r2] - set GICC_CTLR.Enable */
- { 0xe3a010ff }, /* mov r1, #0xff */
- { 0xe5821004 }, /* str r1, [r2, 4] - set GIC_PMR.Priority to 0xff */
- { 0, FIXUP_DSB }, /* dsb */
- { 0xe320f003 }, /* wfi */
- { 0xe5901000 }, /* ldr r1, [r0] */
- { 0xe1110001 }, /* tst r1, r1 */
- { 0x0afffffb }, /* beq <wfi> */
- { 0xe12fff11 }, /* bx r1 */
- { 0, FIXUP_GIC_CPU_IF }, /* gic_cpu_if: .word 0x.... */
- { 0, FIXUP_BOOTREG }, /* bootreg_addr: .word 0x.... */
- { 0, FIXUP_TERMINATOR }
-};
-
-static void write_bootloader(const char *name, hwaddr addr,
- const ARMInsnFixup *insns, uint32_t *fixupcontext)
-{
- /* Fix up the specified bootloader fragment and write it into
- * guest memory using rom_add_blob_fixed(). fixupcontext is
- * an array giving the values to write in for the fixup types
- * which write a value into the code array.
- */
- int i, len;
- uint32_t *code;
-
- len = 0;
- while (insns[len].fixup != FIXUP_TERMINATOR) {
- len++;
- }
-
- code = g_new0(uint32_t, len);
-
- for (i = 0; i < len; i++) {
- uint32_t insn = insns[i].insn;
- FixupType fixup = insns[i].fixup;
-
- switch (fixup) {
- case FIXUP_NONE:
- break;
- case FIXUP_BOARDID:
- case FIXUP_BOARD_SETUP:
- case FIXUP_ARGPTR:
- case FIXUP_ENTRYPOINT:
- case FIXUP_GIC_CPU_IF:
- case FIXUP_BOOTREG:
- case FIXUP_DSB:
- insn = fixupcontext[fixup];
- break;
- default:
- abort();
- }
- code[i] = tswap32(insn);
- }
-
- rom_add_blob_fixed(name, code, len * sizeof(uint32_t), addr);
-
- g_free(code);
-}
-
-static void default_write_secondary(ARMCPU *cpu,
- const struct arm_boot_info *info)
-{
- uint32_t fixupcontext[FIXUP_MAX];
-
- fixupcontext[FIXUP_GIC_CPU_IF] = info->gic_cpu_if_addr;
- fixupcontext[FIXUP_BOOTREG] = info->smp_bootreg_addr;
- if (arm_feature(&cpu->env, ARM_FEATURE_V7)) {
- fixupcontext[FIXUP_DSB] = DSB_INSN;
- } else {
- fixupcontext[FIXUP_DSB] = CP15_DSB_INSN;
- }
-
- write_bootloader("smpboot", info->smp_loader_start,
- smpboot, fixupcontext);
-}
-
-void arm_write_secure_board_setup_dummy_smc(ARMCPU *cpu,
- const struct arm_boot_info *info,
- hwaddr mvbar_addr)
-{
- int n;
- uint32_t mvbar_blob[] = {
- /* mvbar_addr: secure monitor vectors
- * Default unimplemented and unused vectors to spin. Makes it
- * easier to debug (as opposed to the CPU running away).
- */
- 0xeafffffe, /* (spin) */
- 0xeafffffe, /* (spin) */
- 0xe1b0f00e, /* movs pc, lr ;SMC exception return */
- 0xeafffffe, /* (spin) */
- 0xeafffffe, /* (spin) */
- 0xeafffffe, /* (spin) */
- 0xeafffffe, /* (spin) */
- 0xeafffffe, /* (spin) */
- };
- uint32_t board_setup_blob[] = {
- /* board setup addr */
- 0xe3a00e00 + (mvbar_addr >> 4), /* mov r0, #mvbar_addr */
- 0xee0c0f30, /* mcr p15, 0, r0, c12, c0, 1 ;set MVBAR */
- 0xee110f11, /* mrc p15, 0, r0, c1 , c1, 0 ;read SCR */
- 0xe3800031, /* orr r0, #0x31 ;enable AW, FW, NS */
- 0xee010f11, /* mcr p15, 0, r0, c1, c1, 0 ;write SCR */
- 0xe1a0100e, /* mov r1, lr ;save LR across SMC */
- 0xe1600070, /* smc #0 ;call monitor to flush SCR */
- 0xe1a0f001, /* mov pc, r1 ;return */
- };
-
- /* check that mvbar_addr is correctly aligned and relocatable (using MOV) */
- assert((mvbar_addr & 0x1f) == 0 && (mvbar_addr >> 4) < 0x100);
-
- /* check that these blobs don't overlap */
- assert((mvbar_addr + sizeof(mvbar_blob) <= info->board_setup_addr)
- || (info->board_setup_addr + sizeof(board_setup_blob) <= mvbar_addr));
-
- for (n = 0; n < ARRAY_SIZE(mvbar_blob); n++) {
- mvbar_blob[n] = tswap32(mvbar_blob[n]);
- }
- rom_add_blob_fixed("board-setup-mvbar", mvbar_blob, sizeof(mvbar_blob),
- mvbar_addr);
-
- for (n = 0; n < ARRAY_SIZE(board_setup_blob); n++) {
- board_setup_blob[n] = tswap32(board_setup_blob[n]);
- }
- rom_add_blob_fixed("board-setup", board_setup_blob,
- sizeof(board_setup_blob), info->board_setup_addr);
-}
-
-static void default_reset_secondary(ARMCPU *cpu,
- const struct arm_boot_info *info)
-{
- CPUState *cs = CPU(cpu);
-
- address_space_stl_notdirty(&address_space_memory, info->smp_bootreg_addr,
- 0, MEMTXATTRS_UNSPECIFIED, NULL);
- cpu_set_pc(cs, info->smp_loader_start);
-}
-
-static inline bool have_dtb(const struct arm_boot_info *info)
-{
- return info->dtb_filename || info->get_dtb;
-}
-
-#define WRITE_WORD(p, value) do { \
- address_space_stl_notdirty(&address_space_memory, p, value, \
- MEMTXATTRS_UNSPECIFIED, NULL); \
- p += 4; \
-} while (0)
-
-static void set_kernel_args(const struct arm_boot_info *info)
-{
- int initrd_size = info->initrd_size;
- hwaddr base = info->loader_start;
- hwaddr p;
-
- p = base + KERNEL_ARGS_ADDR;
- /* ATAG_CORE */
- WRITE_WORD(p, 5);
- WRITE_WORD(p, 0x54410001);
- WRITE_WORD(p, 1);
- WRITE_WORD(p, 0x1000);
- WRITE_WORD(p, 0);
- /* ATAG_MEM */
- /* TODO: handle multiple chips on one ATAG list */
- WRITE_WORD(p, 4);
- WRITE_WORD(p, 0x54410002);
- WRITE_WORD(p, info->ram_size);
- WRITE_WORD(p, info->loader_start);
- if (initrd_size) {
- /* ATAG_INITRD2 */
- WRITE_WORD(p, 4);
- WRITE_WORD(p, 0x54420005);
- WRITE_WORD(p, info->initrd_start);
- WRITE_WORD(p, initrd_size);
- }
- if (info->kernel_cmdline && *info->kernel_cmdline) {
- /* ATAG_CMDLINE */
- int cmdline_size;
-
- cmdline_size = strlen(info->kernel_cmdline);
- cpu_physical_memory_write(p + 8, info->kernel_cmdline,
- cmdline_size + 1);
- cmdline_size = (cmdline_size >> 2) + 1;
- WRITE_WORD(p, cmdline_size + 2);
- WRITE_WORD(p, 0x54410009);
- p += cmdline_size * 4;
- }
- if (info->atag_board) {
- /* ATAG_BOARD */
- int atag_board_len;
- uint8_t atag_board_buf[0x1000];
-
- atag_board_len = (info->atag_board(info, atag_board_buf) + 3) & ~3;
- WRITE_WORD(p, (atag_board_len + 8) >> 2);
- WRITE_WORD(p, 0x414f4d50);
- cpu_physical_memory_write(p, atag_board_buf, atag_board_len);
- p += atag_board_len;
- }
- /* ATAG_END */
- WRITE_WORD(p, 0);
- WRITE_WORD(p, 0);
-}
-
-static void set_kernel_args_old(const struct arm_boot_info *info)
-{
- hwaddr p;
- const char *s;
- int initrd_size = info->initrd_size;
- hwaddr base = info->loader_start;
-
- /* see linux/include/asm-arm/setup.h */
- p = base + KERNEL_ARGS_ADDR;
- /* page_size */
- WRITE_WORD(p, 4096);
- /* nr_pages */
- WRITE_WORD(p, info->ram_size / 4096);
- /* ramdisk_size */
- WRITE_WORD(p, 0);
-#define FLAG_READONLY 1
-#define FLAG_RDLOAD 4
-#define FLAG_RDPROMPT 8
- /* flags */
- WRITE_WORD(p, FLAG_READONLY | FLAG_RDLOAD | FLAG_RDPROMPT);
- /* rootdev */
- WRITE_WORD(p, (31 << 8) | 0); /* /dev/mtdblock0 */
- /* video_num_cols */
- WRITE_WORD(p, 0);
- /* video_num_rows */
- WRITE_WORD(p, 0);
- /* video_x */
- WRITE_WORD(p, 0);
- /* video_y */
- WRITE_WORD(p, 0);
- /* memc_control_reg */
- WRITE_WORD(p, 0);
- /* unsigned char sounddefault */
- /* unsigned char adfsdrives */
- /* unsigned char bytes_per_char_h */
- /* unsigned char bytes_per_char_v */
- WRITE_WORD(p, 0);
- /* pages_in_bank[4] */
- WRITE_WORD(p, 0);
- WRITE_WORD(p, 0);
- WRITE_WORD(p, 0);
- WRITE_WORD(p, 0);
- /* pages_in_vram */
- WRITE_WORD(p, 0);
- /* initrd_start */
- if (initrd_size) {
- WRITE_WORD(p, info->initrd_start);
- } else {
- WRITE_WORD(p, 0);
- }
- /* initrd_size */
- WRITE_WORD(p, initrd_size);
- /* rd_start */
- WRITE_WORD(p, 0);
- /* system_rev */
- WRITE_WORD(p, 0);
- /* system_serial_low */
- WRITE_WORD(p, 0);
- /* system_serial_high */
- WRITE_WORD(p, 0);
- /* mem_fclk_21285 */
- WRITE_WORD(p, 0);
- /* zero unused fields */
- while (p < base + KERNEL_ARGS_ADDR + 256 + 1024) {
- WRITE_WORD(p, 0);
- }
- s = info->kernel_cmdline;
- if (s) {
- cpu_physical_memory_write(p, s, strlen(s) + 1);
- } else {
- WRITE_WORD(p, 0);
- }
-}
-
-/**
- * load_dtb() - load a device tree binary image into memory
- * @addr: the address to load the image at
- * @binfo: struct describing the boot environment
- * @addr_limit: upper limit of the available memory area at @addr
- *
- * Load a device tree supplied by the machine or by the user with the
- * '-dtb' command line option, and put it at offset @addr in target
- * memory.
- *
- * If @addr_limit contains a meaningful value (i.e., it is strictly greater
- * than @addr), the device tree is only loaded if its size does not exceed
- * the limit.
- *
- * Returns: the size of the device tree image on success,
- * 0 if the image size exceeds the limit,
- * -1 on errors.
- *
- * Note: Must not be called unless have_dtb(binfo) is true.
- */
-static int load_dtb(hwaddr addr, const struct arm_boot_info *binfo,
- hwaddr addr_limit)
-{
- void *fdt = NULL;
- int size, rc;
- uint32_t acells, scells;
-
- if (binfo->dtb_filename) {
- char *filename;
- filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, binfo->dtb_filename);
- if (!filename) {
- fprintf(stderr, "Couldn't open dtb file %s\n", binfo->dtb_filename);
- goto fail;
- }
-
- fdt = load_device_tree(filename, &size);
- if (!fdt) {
- fprintf(stderr, "Couldn't open dtb file %s\n", filename);
- g_free(filename);
- goto fail;
- }
- g_free(filename);
- } else {
- fdt = binfo->get_dtb(binfo, &size);
- if (!fdt) {
- fprintf(stderr, "Board was unable to create a dtb blob\n");
- goto fail;
- }
- }
-
- if (addr_limit > addr && size > (addr_limit - addr)) {
- /* Installing the device tree blob at addr would exceed addr_limit.
- * Whether this constitutes failure is up to the caller to decide,
- * so just return 0 as size, i.e., no error.
- */
- g_free(fdt);
- return 0;
- }
-
- acells = qemu_fdt_getprop_cell(fdt, "/", "#address-cells",
- NULL, &error_fatal);
- scells = qemu_fdt_getprop_cell(fdt, "/", "#size-cells",
- NULL, &error_fatal);
- if (acells == 0 || scells == 0) {
- fprintf(stderr, "dtb file invalid (#address-cells or #size-cells 0)\n");
- goto fail;
- }
-
- if (scells < 2 && binfo->ram_size >= (1ULL << 32)) {
- /* This is user error so deserves a friendlier error message
- * than the failure of setprop_sized_cells would provide
- */
- fprintf(stderr, "qemu: dtb file not compatible with "
- "RAM size > 4GB\n");
- goto fail;
- }
-
- rc = qemu_fdt_setprop_sized_cells(fdt, "/memory", "reg",
- acells, binfo->loader_start,
- scells, binfo->ram_size);
- if (rc < 0) {
- fprintf(stderr, "couldn't set /memory/reg\n");
- goto fail;
- }
-
- if (binfo->kernel_cmdline && *binfo->kernel_cmdline) {
- rc = qemu_fdt_setprop_string(fdt, "/chosen", "bootargs",
- binfo->kernel_cmdline);
- if (rc < 0) {
- fprintf(stderr, "couldn't set /chosen/bootargs\n");
- goto fail;
- }
- }
-
- if (binfo->initrd_size) {
- rc = qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-start",
- binfo->initrd_start);
- if (rc < 0) {
- fprintf(stderr, "couldn't set /chosen/linux,initrd-start\n");
- goto fail;
- }
-
- rc = qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-end",
- binfo->initrd_start + binfo->initrd_size);
- if (rc < 0) {
- fprintf(stderr, "couldn't set /chosen/linux,initrd-end\n");
- goto fail;
- }
- }
-
- if (binfo->modify_dtb) {
- binfo->modify_dtb(binfo, fdt);
- }
-
- qemu_fdt_dumpdtb(fdt, size);
-
- /* Put the DTB into the memory map as a ROM image: this will ensure
- * the DTB is copied again upon reset, even if addr points into RAM.
- */
- rom_add_blob_fixed("dtb", fdt, size, addr);
-
- g_free(fdt);
-
- return size;
-
-fail:
- g_free(fdt);
- return -1;
-}
-
-static void do_cpu_reset(void *opaque)
-{
- ARMCPU *cpu = opaque;
- CPUState *cs = CPU(cpu);
- CPUARMState *env = &cpu->env;
- const struct arm_boot_info *info = env->boot_info;
-
- cpu_reset(cs);
- if (info) {
- if (!info->is_linux) {
- int i;
- /* Jump to the entry point. */
- uint64_t entry = info->entry;
-
- switch (info->endianness) {
- case ARM_ENDIANNESS_LE:
- env->cp15.sctlr_el[1] &= ~SCTLR_E0E;
- for (i = 1; i < 4; ++i) {
- env->cp15.sctlr_el[i] &= ~SCTLR_EE;
- }
- env->uncached_cpsr &= ~CPSR_E;
- break;
- case ARM_ENDIANNESS_BE8:
- env->cp15.sctlr_el[1] |= SCTLR_E0E;
- for (i = 1; i < 4; ++i) {
- env->cp15.sctlr_el[i] |= SCTLR_EE;
- }
- env->uncached_cpsr |= CPSR_E;
- break;
- case ARM_ENDIANNESS_BE32:
- env->cp15.sctlr_el[1] |= SCTLR_B;
- break;
- case ARM_ENDIANNESS_UNKNOWN:
- break; /* Board's decision */
- default:
- g_assert_not_reached();
- }
-
- if (!env->aarch64) {
- env->thumb = info->entry & 1;
- entry &= 0xfffffffe;
- }
- cpu_set_pc(cs, entry);
- } else {
- /* If we are booting Linux then we need to check whether we are
- * booting into secure or non-secure state and adjust the state
- * accordingly. Out of reset, ARM is defined to be in secure state
- * (SCR.NS = 0), we change that here if non-secure boot has been
- * requested.
- */
- if (arm_feature(env, ARM_FEATURE_EL3)) {
- /* AArch64 is defined to come out of reset into EL3 if enabled.
- * If we are booting Linux then we need to adjust our EL as
- * Linux expects us to be in EL2 or EL1. AArch32 resets into
- * SVC, which Linux expects, so no privilege/exception level to
- * adjust.
- */
- if (env->aarch64) {
- env->cp15.scr_el3 |= SCR_RW;
- if (arm_feature(env, ARM_FEATURE_EL2)) {
- env->cp15.hcr_el2 |= HCR_RW;
- env->pstate = PSTATE_MODE_EL2h;
- } else {
- env->pstate = PSTATE_MODE_EL1h;
- }
- }
-
- /* Set to non-secure if not a secure boot */
- if (!info->secure_boot &&
- (cs != first_cpu || !info->secure_board_setup)) {
- /* Linux expects non-secure state */
- env->cp15.scr_el3 |= SCR_NS;
- }
- }
-
- if (cs == first_cpu) {
- cpu_set_pc(cs, info->loader_start);
-
- if (!have_dtb(info)) {
- if (old_param) {
- set_kernel_args_old(info);
- } else {
- set_kernel_args(info);
- }
- }
- } else {
- info->secondary_cpu_reset_hook(cpu, info);
- }
- }
- }
-}
-
-/**
- * load_image_to_fw_cfg() - Load an image file into an fw_cfg entry identified
- * by key.
- * @fw_cfg: The firmware config instance to store the data in.
- * @size_key: The firmware config key to store the size of the loaded
- * data under, with fw_cfg_add_i32().
- * @data_key: The firmware config key to store the loaded data under,
- * with fw_cfg_add_bytes().
- * @image_name: The name of the image file to load. If it is NULL, the
- * function returns without doing anything.
- * @try_decompress: Whether the image should be decompressed (gunzipped) before
- * adding it to fw_cfg. If decompression fails, the image is
- * loaded as-is.
- *
- * In case of failure, the function prints an error message to stderr and the
- * process exits with status 1.
- */
-static void load_image_to_fw_cfg(FWCfgState *fw_cfg, uint16_t size_key,
- uint16_t data_key, const char *image_name,
- bool try_decompress)
-{
- size_t size = -1;
- uint8_t *data;
-
- if (image_name == NULL) {
- return;
- }
-
- if (try_decompress) {
- size = load_image_gzipped_buffer(image_name,
- LOAD_IMAGE_MAX_GUNZIP_BYTES, &data);
- }
-
- if (size == (size_t)-1) {
- gchar *contents;
- gsize length;
-
- if (!g_file_get_contents(image_name, &contents, &length, NULL)) {
- fprintf(stderr, "failed to load \"%s\"\n", image_name);
- exit(1);
- }
- size = length;
- data = (uint8_t *)contents;
- }
-
- fw_cfg_add_i32(fw_cfg, size_key, size);
- fw_cfg_add_bytes(fw_cfg, data_key, data, size);
-}
-
-static int do_arm_linux_init(Object *obj, void *opaque)
-{
- if (object_dynamic_cast(obj, TYPE_ARM_LINUX_BOOT_IF)) {
- ARMLinuxBootIf *albif = ARM_LINUX_BOOT_IF(obj);
- ARMLinuxBootIfClass *albifc = ARM_LINUX_BOOT_IF_GET_CLASS(obj);
- struct arm_boot_info *info = opaque;
-
- if (albifc->arm_linux_init) {
- albifc->arm_linux_init(albif, info->secure_boot);
- }
- }
- return 0;
-}
-
-static uint64_t arm_load_elf(struct arm_boot_info *info, uint64_t *pentry,
- uint64_t *lowaddr, uint64_t *highaddr,
- int elf_machine)
-{
- bool elf_is64;
- union {
- Elf32_Ehdr h32;
- Elf64_Ehdr h64;
- } elf_header;
- int data_swab = 0;
- bool big_endian;
- uint64_t ret = -1;
- Error *err = NULL;
-
-
- load_elf_hdr(info->kernel_filename, &elf_header, &elf_is64, &err);
- if (err) {
- return ret;
- }
-
- if (elf_is64) {
- big_endian = elf_header.h64.e_ident[EI_DATA] == ELFDATA2MSB;
- info->endianness = big_endian ? ARM_ENDIANNESS_BE8
- : ARM_ENDIANNESS_LE;
- } else {
- big_endian = elf_header.h32.e_ident[EI_DATA] == ELFDATA2MSB;
- if (big_endian) {
- if (bswap32(elf_header.h32.e_flags) & EF_ARM_BE8) {
- info->endianness = ARM_ENDIANNESS_BE8;
- } else {
- info->endianness = ARM_ENDIANNESS_BE32;
- /* In BE32, the CPU has a different view of the per-byte
- * address map than the rest of the system. BE32 ELF files
- * are organised such that they can be programmed through
- * the CPU's per-word byte-reversed view of the world. QEMU
- * however loads ELF files independently of the CPU. So
- * tell the ELF loader to byte reverse the data for us.
- */
- data_swab = 2;
- }
- } else {
- info->endianness = ARM_ENDIANNESS_LE;
- }
- }
-
- ret = load_elf(info->kernel_filename, NULL, NULL,
- pentry, lowaddr, highaddr, big_endian, elf_machine,
- 1, data_swab);
- if (ret <= 0) {
- /* The header loaded but the image didn't */
- exit(1);
- }
-
- return ret;
-}
-
-static void arm_load_kernel_notify(Notifier *notifier, void *data)
-{
- CPUState *cs;
- int kernel_size;
- int initrd_size;
- int is_linux = 0;
- uint64_t elf_entry, elf_low_addr, elf_high_addr;
- int elf_machine;
- hwaddr entry, kernel_load_offset;
- static const ARMInsnFixup *primary_loader;
- ArmLoadKernelNotifier *n = DO_UPCAST(ArmLoadKernelNotifier,
- notifier, notifier);
- ARMCPU *cpu = n->cpu;
- struct arm_boot_info *info =
- container_of(n, struct arm_boot_info, load_kernel_notifier);
-
- /* The board code is not supposed to set secure_board_setup unless
- * running its code in secure mode is actually possible, and KVM
- * doesn't support secure.
- */
- assert(!(info->secure_board_setup && kvm_enabled()));
-
- /* Load the kernel. */
- if (!info->kernel_filename || info->firmware_loaded) {
-
- if (have_dtb(info)) {
- /* If we have a device tree blob, but no kernel to supply it to (or
- * the kernel is supposed to be loaded by the bootloader), copy the
- * DTB to the base of RAM for the bootloader to pick up.
- */
- if (load_dtb(info->loader_start, info, 0) < 0) {
- exit(1);
- }
- }
-
- if (info->kernel_filename) {
- FWCfgState *fw_cfg;
- bool try_decompressing_kernel;
-
- fw_cfg = fw_cfg_find();
- try_decompressing_kernel = arm_feature(&cpu->env,
- ARM_FEATURE_AARCH64);
-
- /* Expose the kernel, the command line, and the initrd in fw_cfg.
- * We don't process them here at all, it's all left to the
- * firmware.
- */
- load_image_to_fw_cfg(fw_cfg,
- FW_CFG_KERNEL_SIZE, FW_CFG_KERNEL_DATA,
- info->kernel_filename,
- try_decompressing_kernel);
- load_image_to_fw_cfg(fw_cfg,
- FW_CFG_INITRD_SIZE, FW_CFG_INITRD_DATA,
- info->initrd_filename, false);
-
- if (info->kernel_cmdline) {
- fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE,
- strlen(info->kernel_cmdline) + 1);
- fw_cfg_add_string(fw_cfg, FW_CFG_CMDLINE_DATA,
- info->kernel_cmdline);
- }
- }
-
- /* We will start from address 0 (typically a boot ROM image) in the
- * same way as hardware.
- */
- return;
- }
-
- if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
- primary_loader = bootloader_aarch64;
- kernel_load_offset = KERNEL64_LOAD_ADDR;
- elf_machine = EM_AARCH64;
- } else {
- primary_loader = bootloader;
- if (!info->write_board_setup) {
- primary_loader += BOOTLOADER_NO_BOARD_SETUP_OFFSET;
- }
- kernel_load_offset = KERNEL_LOAD_ADDR;
- elf_machine = EM_ARM;
- }
-
- info->dtb_filename = qemu_opt_get(qemu_get_machine_opts(), "dtb");
-
- if (!info->secondary_cpu_reset_hook) {
- info->secondary_cpu_reset_hook = default_reset_secondary;
- }
- if (!info->write_secondary_boot) {
- info->write_secondary_boot = default_write_secondary;
- }
-
- if (info->nb_cpus == 0)
- info->nb_cpus = 1;
-
- /* We want to put the initrd far enough into RAM that when the
- * kernel is uncompressed it will not clobber the initrd. However
- * on boards without much RAM we must ensure that we still leave
- * enough room for a decent sized initrd, and on boards with large
- * amounts of RAM we must avoid the initrd being so far up in RAM
- * that it is outside lowmem and inaccessible to the kernel.
- * So for boards with less than 256MB of RAM we put the initrd
- * halfway into RAM, and for boards with 256MB of RAM or more we put
- * the initrd at 128MB.
- */
- info->initrd_start = info->loader_start +
- MIN(info->ram_size / 2, 128 * 1024 * 1024);
-
- /* Assume that raw images are linux kernels, and ELF images are not. */
- kernel_size = arm_load_elf(info, &elf_entry, &elf_low_addr,
- &elf_high_addr, elf_machine);
- if (kernel_size > 0 && have_dtb(info)) {
- /* If there is still some room left at the base of RAM, try and put
- * the DTB there like we do for images loaded with -bios or -pflash.
- */
- if (elf_low_addr > info->loader_start
- || elf_high_addr < info->loader_start) {
- /* Pass elf_low_addr as address limit to load_dtb if it may be
- * pointing into RAM, otherwise pass '0' (no limit)
- */
- if (elf_low_addr < info->loader_start) {
- elf_low_addr = 0;
- }
- if (load_dtb(info->loader_start, info, elf_low_addr) < 0) {
- exit(1);
- }
- }
- }
- entry = elf_entry;
- if (kernel_size < 0) {
- kernel_size = load_uimage(info->kernel_filename, &entry, NULL,
- &is_linux, NULL, NULL);
- }
- /* On aarch64, it's the bootloader's job to uncompress the kernel. */
- if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64) && kernel_size < 0) {
- entry = info->loader_start + kernel_load_offset;
- kernel_size = load_image_gzipped(info->kernel_filename, entry,
- info->ram_size - kernel_load_offset);
- is_linux = 1;
- }
- if (kernel_size < 0) {
- entry = info->loader_start + kernel_load_offset;
- kernel_size = load_image_targphys(info->kernel_filename, entry,
- info->ram_size - kernel_load_offset);
- is_linux = 1;
- }
- if (kernel_size < 0) {
- fprintf(stderr, "qemu: could not load kernel '%s'\n",
- info->kernel_filename);
- exit(1);
- }
- info->entry = entry;
- if (is_linux) {
- uint32_t fixupcontext[FIXUP_MAX];
-
- if (info->initrd_filename) {
- initrd_size = load_ramdisk(info->initrd_filename,
- info->initrd_start,
- info->ram_size -
- info->initrd_start);
- if (initrd_size < 0) {
- initrd_size = load_image_targphys(info->initrd_filename,
- info->initrd_start,
- info->ram_size -
- info->initrd_start);
- }
- if (initrd_size < 0) {
- fprintf(stderr, "qemu: could not load initrd '%s'\n",
- info->initrd_filename);
- exit(1);
- }
- } else {
- initrd_size = 0;
- }
- info->initrd_size = initrd_size;
-
- fixupcontext[FIXUP_BOARDID] = info->board_id;
- fixupcontext[FIXUP_BOARD_SETUP] = info->board_setup_addr;
-
- /* for device tree boot, we pass the DTB directly in r2. Otherwise
- * we point to the kernel args.
- */
- if (have_dtb(info)) {
- hwaddr align;
- hwaddr dtb_start;
-
- if (elf_machine == EM_AARCH64) {
- /*
- * Some AArch64 kernels on early bootup map the fdt region as
- *
- * [ ALIGN_DOWN(fdt, 2MB) ... ALIGN_DOWN(fdt, 2MB) + 2MB ]
- *
- * Let's play safe and prealign it to 2MB to give us some space.
- */
- align = 2 * 1024 * 1024;
- } else {
- /*
- * Some 32bit kernels will trash anything in the 4K page the
- * initrd ends in, so make sure the DTB isn't caught up in that.
- */
- align = 4096;
- }
-
- /* Place the DTB after the initrd in memory with alignment. */
- dtb_start = QEMU_ALIGN_UP(info->initrd_start + initrd_size, align);
- if (load_dtb(dtb_start, info, 0) < 0) {
- exit(1);
- }
- fixupcontext[FIXUP_ARGPTR] = dtb_start;
- } else {
- fixupcontext[FIXUP_ARGPTR] = info->loader_start + KERNEL_ARGS_ADDR;
- if (info->ram_size >= (1ULL << 32)) {
- fprintf(stderr, "qemu: RAM size must be less than 4GB to boot"
- " Linux kernel using ATAGS (try passing a device tree"
- " using -dtb)\n");
- exit(1);
- }
- }
- fixupcontext[FIXUP_ENTRYPOINT] = entry;
-
- write_bootloader("bootloader", info->loader_start,
- primary_loader, fixupcontext);
-
- if (info->nb_cpus > 1) {
- info->write_secondary_boot(cpu, info);
- }
- if (info->write_board_setup) {
- info->write_board_setup(cpu, info);
- }
-
- /* Notify devices which need to fake up firmware initialization
- * that we're doing a direct kernel boot.
- */
- object_child_foreach_recursive(object_get_root(),
- do_arm_linux_init, info);
- }
- info->is_linux = is_linux;
-
- for (cs = CPU(cpu); cs; cs = CPU_NEXT(cs)) {
- ARM_CPU(cs)->env.boot_info = info;
- }
-}
-
-void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
-{
- CPUState *cs;
-
- info->load_kernel_notifier.cpu = cpu;
- info->load_kernel_notifier.notifier.notify = arm_load_kernel_notify;
- qemu_add_machine_init_done_notifier(&info->load_kernel_notifier.notifier);
-
- /* CPU objects (unlike devices) are not automatically reset on system
- * reset, so we must always register a handler to do so. If we're
- * actually loading a kernel, the handler is also responsible for
- * arranging that we start it correctly.
- */
- for (cs = CPU(cpu); cs; cs = CPU_NEXT(cs)) {
- qemu_register_reset(do_cpu_reset, ARM_CPU(cs));
- }
-}
-
-static const TypeInfo arm_linux_boot_if_info = {
- .name = TYPE_ARM_LINUX_BOOT_IF,
- .parent = TYPE_INTERFACE,
- .class_size = sizeof(ARMLinuxBootIfClass),
-};
-
-static void arm_linux_boot_register_types(void)
-{
- type_register_static(&arm_linux_boot_if_info);
-}
-
-type_init(arm_linux_boot_register_types)
diff --git a/qemu/hw/arm/collie.c b/qemu/hw/arm/collie.c
deleted file mode 100644
index 8bb308a42..000000000
--- a/qemu/hw/arm/collie.c
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * SA-1110-based Sharp Zaurus SL-5500 platform.
- *
- * Copyright (C) 2011 Dmitry Eremin-Solenikov
- *
- * This code is licensed under GNU GPL v2.
- *
- * Contributions after 2012-01-13 are licensed under the terms of the
- * GNU GPL, version 2 or (at your option) any later version.
- */
-#include "qemu/osdep.h"
-#include "hw/hw.h"
-#include "hw/sysbus.h"
-#include "hw/boards.h"
-#include "hw/devices.h"
-#include "strongarm.h"
-#include "hw/arm/arm.h"
-#include "hw/block/flash.h"
-#include "sysemu/block-backend.h"
-#include "exec/address-spaces.h"
-
-static struct arm_boot_info collie_binfo = {
- .loader_start = SA_SDCS0,
- .ram_size = 0x20000000,
-};
-
-static void collie_init(MachineState *machine)
-{
- const char *cpu_model = machine->cpu_model;
- const char *kernel_filename = machine->kernel_filename;
- const char *kernel_cmdline = machine->kernel_cmdline;
- const char *initrd_filename = machine->initrd_filename;
- StrongARMState *s;
- DriveInfo *dinfo;
- MemoryRegion *sysmem = get_system_memory();
-
- if (!cpu_model) {
- cpu_model = "sa1110";
- }
-
- s = sa1110_init(sysmem, collie_binfo.ram_size, cpu_model);
-
- dinfo = drive_get(IF_PFLASH, 0, 0);
- pflash_cfi01_register(SA_CS0, NULL, "collie.fl1", 0x02000000,
- dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
- (64 * 1024), 512, 4, 0x00, 0x00, 0x00, 0x00, 0);
-
- dinfo = drive_get(IF_PFLASH, 0, 1);
- pflash_cfi01_register(SA_CS1, NULL, "collie.fl2", 0x02000000,
- dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
- (64 * 1024), 512, 4, 0x00, 0x00, 0x00, 0x00, 0);
-
- sysbus_create_simple("scoop", 0x40800000, NULL);
-
- collie_binfo.kernel_filename = kernel_filename;
- collie_binfo.kernel_cmdline = kernel_cmdline;
- collie_binfo.initrd_filename = initrd_filename;
- collie_binfo.board_id = 0x208;
- arm_load_kernel(s->cpu, &collie_binfo);
-}
-
-static void collie_machine_init(MachineClass *mc)
-{
- mc->desc = "Sharp SL-5500 (Collie) PDA (SA-1110)";
- mc->init = collie_init;
-}
-
-DEFINE_MACHINE("collie", collie_machine_init)
diff --git a/qemu/hw/arm/cubieboard.c b/qemu/hw/arm/cubieboard.c
deleted file mode 100644
index fbd78ed01..000000000
--- a/qemu/hw/arm/cubieboard.c
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * cubieboard emulation
- *
- * Copyright (C) 2013 Li Guang
- * Written by Li Guang <lig.fnst@cn.fujitsu.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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.
- */
-
-#include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "qemu-common.h"
-#include "cpu.h"
-#include "hw/sysbus.h"
-#include "hw/devices.h"
-#include "hw/boards.h"
-#include "hw/arm/allwinner-a10.h"
-
-static struct arm_boot_info cubieboard_binfo = {
- .loader_start = AW_A10_SDRAM_BASE,
- .board_id = 0x1008,
-};
-
-typedef struct CubieBoardState {
- AwA10State *a10;
- MemoryRegion sdram;
-} CubieBoardState;
-
-static void cubieboard_init(MachineState *machine)
-{
- CubieBoardState *s = g_new(CubieBoardState, 1);
- Error *err = NULL;
-
- s->a10 = AW_A10(object_new(TYPE_AW_A10));
-
- object_property_set_int(OBJECT(&s->a10->emac), 1, "phy-addr", &err);
- if (err != NULL) {
- error_reportf_err(err, "Couldn't set phy address: ");
- exit(1);
- }
-
- object_property_set_int(OBJECT(&s->a10->timer), 32768, "clk0-freq", &err);
- if (err != NULL) {
- error_reportf_err(err, "Couldn't set clk0 frequency: ");
- exit(1);
- }
-
- object_property_set_int(OBJECT(&s->a10->timer), 24000000, "clk1-freq",
- &err);
- if (err != NULL) {
- error_reportf_err(err, "Couldn't set clk1 frequency: ");
- exit(1);
- }
-
- object_property_set_bool(OBJECT(s->a10), true, "realized", &err);
- if (err != NULL) {
- error_reportf_err(err, "Couldn't realize Allwinner A10: ");
- exit(1);
- }
-
- memory_region_allocate_system_memory(&s->sdram, NULL, "cubieboard.ram",
- machine->ram_size);
- memory_region_add_subregion(get_system_memory(), AW_A10_SDRAM_BASE,
- &s->sdram);
-
- cubieboard_binfo.ram_size = machine->ram_size;
- cubieboard_binfo.kernel_filename = machine->kernel_filename;
- cubieboard_binfo.kernel_cmdline = machine->kernel_cmdline;
- arm_load_kernel(&s->a10->cpu, &cubieboard_binfo);
-}
-
-static void cubieboard_machine_init(MachineClass *mc)
-{
- mc->desc = "cubietech cubieboard";
- mc->init = cubieboard_init;
-}
-
-DEFINE_MACHINE("cubieboard", cubieboard_machine_init)
diff --git a/qemu/hw/arm/digic.c b/qemu/hw/arm/digic.c
deleted file mode 100644
index e0f973032..000000000
--- a/qemu/hw/arm/digic.c
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * QEMU model of the Canon DIGIC SoC.
- *
- * Copyright (C) 2013 Antony Pavlov <antonynpavlov@gmail.com>
- *
- * This model is based on reverse engineering efforts
- * made by CHDK (http://chdk.wikia.com) and
- * Magic Lantern (http://www.magiclantern.fm) projects
- * contributors.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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.
- *
- */
-
-#include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "hw/arm/digic.h"
-
-#define DIGIC4_TIMER_BASE(n) (0xc0210000 + (n) * 0x100)
-
-#define DIGIC_UART_BASE 0xc0800000
-
-static void digic_init(Object *obj)
-{
- DigicState *s = DIGIC(obj);
- DeviceState *dev;
- int i;
-
- object_initialize(&s->cpu, sizeof(s->cpu), "arm946-" TYPE_ARM_CPU);
- object_property_add_child(obj, "cpu", OBJECT(&s->cpu), NULL);
-
- for (i = 0; i < DIGIC4_NB_TIMERS; i++) {
-#define DIGIC_TIMER_NAME_MLEN 11
- char name[DIGIC_TIMER_NAME_MLEN];
-
- object_initialize(&s->timer[i], sizeof(s->timer[i]), TYPE_DIGIC_TIMER);
- dev = DEVICE(&s->timer[i]);
- qdev_set_parent_bus(dev, sysbus_get_default());
- snprintf(name, DIGIC_TIMER_NAME_MLEN, "timer[%d]", i);
- object_property_add_child(obj, name, OBJECT(&s->timer[i]), NULL);
- }
-
- object_initialize(&s->uart, sizeof(s->uart), TYPE_DIGIC_UART);
- dev = DEVICE(&s->uart);
- qdev_set_parent_bus(dev, sysbus_get_default());
- object_property_add_child(obj, "uart", OBJECT(&s->uart), NULL);
-}
-
-static void digic_realize(DeviceState *dev, Error **errp)
-{
- DigicState *s = DIGIC(dev);
- Error *err = NULL;
- SysBusDevice *sbd;
- int i;
-
- object_property_set_bool(OBJECT(&s->cpu), true, "reset-hivecs", &err);
- if (err != NULL) {
- error_propagate(errp, err);
- return;
- }
-
- object_property_set_bool(OBJECT(&s->cpu), true, "realized", &err);
- if (err != NULL) {
- error_propagate(errp, err);
- return;
- }
-
- for (i = 0; i < DIGIC4_NB_TIMERS; i++) {
- object_property_set_bool(OBJECT(&s->timer[i]), true, "realized", &err);
- if (err != NULL) {
- error_propagate(errp, err);
- return;
- }
-
- sbd = SYS_BUS_DEVICE(&s->timer[i]);
- sysbus_mmio_map(sbd, 0, DIGIC4_TIMER_BASE(i));
- }
-
- object_property_set_bool(OBJECT(&s->uart), true, "realized", &err);
- if (err != NULL) {
- error_propagate(errp, err);
- return;
- }
-
- sbd = SYS_BUS_DEVICE(&s->uart);
- sysbus_mmio_map(sbd, 0, DIGIC_UART_BASE);
-}
-
-static void digic_class_init(ObjectClass *oc, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
-
- dc->realize = digic_realize;
-
- /*
- * Reason: creates an ARM CPU, thus use after free(), see
- * arm_cpu_class_init()
- */
- dc->cannot_destroy_with_object_finalize_yet = true;
-}
-
-static const TypeInfo digic_type_info = {
- .name = TYPE_DIGIC,
- .parent = TYPE_DEVICE,
- .instance_size = sizeof(DigicState),
- .instance_init = digic_init,
- .class_init = digic_class_init,
-};
-
-static void digic_register_types(void)
-{
- type_register_static(&digic_type_info);
-}
-
-type_init(digic_register_types)
diff --git a/qemu/hw/arm/digic_boards.c b/qemu/hw/arm/digic_boards.c
deleted file mode 100644
index 520c8e9ff..000000000
--- a/qemu/hw/arm/digic_boards.c
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * QEMU model of the Canon DIGIC boards (cameras indeed :).
- *
- * Copyright (C) 2013 Antony Pavlov <antonynpavlov@gmail.com>
- *
- * This model is based on reverse engineering efforts
- * made by CHDK (http://chdk.wikia.com) and
- * Magic Lantern (http://www.magiclantern.fm) projects
- * contributors.
- *
- * See docs here:
- * http://magiclantern.wikia.com/wiki/Register_Map
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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.
- *
- */
-
-#include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "qemu-common.h"
-#include "cpu.h"
-#include "hw/boards.h"
-#include "exec/address-spaces.h"
-#include "qemu/error-report.h"
-#include "hw/arm/digic.h"
-#include "hw/block/flash.h"
-#include "hw/loader.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/qtest.h"
-
-#define DIGIC4_ROM0_BASE 0xf0000000
-#define DIGIC4_ROM1_BASE 0xf8000000
-#define DIGIC4_ROM_MAX_SIZE 0x08000000
-
-typedef struct DigicBoardState {
- DigicState *digic;
- MemoryRegion ram;
-} DigicBoardState;
-
-typedef struct DigicBoard {
- hwaddr ram_size;
- void (*add_rom0)(DigicBoardState *, hwaddr, const char *);
- const char *rom0_def_filename;
- void (*add_rom1)(DigicBoardState *, hwaddr, const char *);
- const char *rom1_def_filename;
-} DigicBoard;
-
-static void digic4_board_setup_ram(DigicBoardState *s, hwaddr ram_size)
-{
- memory_region_allocate_system_memory(&s->ram, NULL, "ram", ram_size);
- memory_region_add_subregion(get_system_memory(), 0, &s->ram);
-}
-
-static void digic4_board_init(DigicBoard *board)
-{
- Error *err = NULL;
-
- DigicBoardState *s = g_new(DigicBoardState, 1);
-
- s->digic = DIGIC(object_new(TYPE_DIGIC));
- object_property_set_bool(OBJECT(s->digic), true, "realized", &err);
- if (err != NULL) {
- error_reportf_err(err, "Couldn't realize DIGIC SoC: ");
- exit(1);
- }
-
- digic4_board_setup_ram(s, board->ram_size);
-
- if (board->add_rom0) {
- board->add_rom0(s, DIGIC4_ROM0_BASE, board->rom0_def_filename);
- }
-
- if (board->add_rom1) {
- board->add_rom1(s, DIGIC4_ROM1_BASE, board->rom1_def_filename);
- }
-}
-
-static void digic_load_rom(DigicBoardState *s, hwaddr addr,
- hwaddr max_size, const char *def_filename)
-{
- target_long rom_size;
- const char *filename;
-
- if (qtest_enabled()) {
- /* qtest runs no code so don't attempt a ROM load which
- * could fail and result in a spurious test failure.
- */
- return;
- }
-
- if (bios_name) {
- filename = bios_name;
- } else {
- filename = def_filename;
- }
-
- if (filename) {
- char *fn = qemu_find_file(QEMU_FILE_TYPE_BIOS, filename);
-
- if (!fn) {
- error_report("Couldn't find rom image '%s'.", filename);
- exit(1);
- }
-
- rom_size = load_image_targphys(fn, addr, max_size);
- if (rom_size < 0 || rom_size > max_size) {
- error_report("Couldn't load rom image '%s'.", filename);
- exit(1);
- }
- g_free(fn);
- }
-}
-
-/*
- * Samsung K8P3215UQB
- * 64M Bit (4Mx16) Page Mode / Multi-Bank NOR Flash Memory
- */
-static void digic4_add_k8p3215uqb_rom(DigicBoardState *s, hwaddr addr,
- const char *def_filename)
-{
-#define FLASH_K8P3215UQB_SIZE (4 * 1024 * 1024)
-#define FLASH_K8P3215UQB_SECTOR_SIZE (64 * 1024)
-
- pflash_cfi02_register(addr, NULL, "pflash", FLASH_K8P3215UQB_SIZE,
- NULL, FLASH_K8P3215UQB_SECTOR_SIZE,
- FLASH_K8P3215UQB_SIZE / FLASH_K8P3215UQB_SECTOR_SIZE,
- DIGIC4_ROM_MAX_SIZE / FLASH_K8P3215UQB_SIZE,
- 4,
- 0x00EC, 0x007E, 0x0003, 0x0001,
- 0x0555, 0x2aa, 0);
-
- digic_load_rom(s, addr, FLASH_K8P3215UQB_SIZE, def_filename);
-}
-
-static DigicBoard digic4_board_canon_a1100 = {
- .ram_size = 64 * 1024 * 1024,
- .add_rom1 = digic4_add_k8p3215uqb_rom,
- .rom1_def_filename = "canon-a1100-rom1.bin",
-};
-
-static void canon_a1100_init(MachineState *machine)
-{
- digic4_board_init(&digic4_board_canon_a1100);
-}
-
-static void canon_a1100_machine_init(MachineClass *mc)
-{
- mc->desc = "Canon PowerShot A1100 IS";
- mc->init = &canon_a1100_init;
-}
-
-DEFINE_MACHINE("canon-a1100", canon_a1100_machine_init)
diff --git a/qemu/hw/arm/exynos4210.c b/qemu/hw/arm/exynos4210.c
deleted file mode 100644
index be3c96d21..000000000
--- a/qemu/hw/arm/exynos4210.c
+++ /dev/null
@@ -1,378 +0,0 @@
-/*
- * Samsung exynos4210 SoC emulation
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd. All rights reserved.
- * Maksim Kozlov <m.kozlov@samsung.com>
- * Evgeny Voevodin <e.voevodin@samsung.com>
- * Igor Mitsyanko <i.mitsyanko@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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/>.
- *
- */
-
-#include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "qemu-common.h"
-#include "cpu.h"
-#include "hw/boards.h"
-#include "sysemu/sysemu.h"
-#include "hw/sysbus.h"
-#include "hw/arm/arm.h"
-#include "hw/loader.h"
-#include "hw/arm/exynos4210.h"
-#include "hw/usb/hcd-ehci.h"
-
-#define EXYNOS4210_CHIPID_ADDR 0x10000000
-
-/* PWM */
-#define EXYNOS4210_PWM_BASE_ADDR 0x139D0000
-
-/* RTC */
-#define EXYNOS4210_RTC_BASE_ADDR 0x10070000
-
-/* MCT */
-#define EXYNOS4210_MCT_BASE_ADDR 0x10050000
-
-/* I2C */
-#define EXYNOS4210_I2C_SHIFT 0x00010000
-#define EXYNOS4210_I2C_BASE_ADDR 0x13860000
-/* Interrupt Group of External Interrupt Combiner for I2C */
-#define EXYNOS4210_I2C_INTG 27
-#define EXYNOS4210_HDMI_INTG 16
-
-/* UART's definitions */
-#define EXYNOS4210_UART0_BASE_ADDR 0x13800000
-#define EXYNOS4210_UART1_BASE_ADDR 0x13810000
-#define EXYNOS4210_UART2_BASE_ADDR 0x13820000
-#define EXYNOS4210_UART3_BASE_ADDR 0x13830000
-#define EXYNOS4210_UART0_FIFO_SIZE 256
-#define EXYNOS4210_UART1_FIFO_SIZE 64
-#define EXYNOS4210_UART2_FIFO_SIZE 16
-#define EXYNOS4210_UART3_FIFO_SIZE 16
-/* Interrupt Group of External Interrupt Combiner for UART */
-#define EXYNOS4210_UART_INT_GRP 26
-
-/* External GIC */
-#define EXYNOS4210_EXT_GIC_CPU_BASE_ADDR 0x10480000
-#define EXYNOS4210_EXT_GIC_DIST_BASE_ADDR 0x10490000
-
-/* Combiner */
-#define EXYNOS4210_EXT_COMBINER_BASE_ADDR 0x10440000
-#define EXYNOS4210_INT_COMBINER_BASE_ADDR 0x10448000
-
-/* PMU SFR base address */
-#define EXYNOS4210_PMU_BASE_ADDR 0x10020000
-
-/* Display controllers (FIMD) */
-#define EXYNOS4210_FIMD0_BASE_ADDR 0x11C00000
-
-/* EHCI */
-#define EXYNOS4210_EHCI_BASE_ADDR 0x12580000
-
-static uint8_t chipid_and_omr[] = { 0x11, 0x02, 0x21, 0x43,
- 0x09, 0x00, 0x00, 0x00 };
-
-static uint64_t exynos4210_chipid_and_omr_read(void *opaque, hwaddr offset,
- unsigned size)
-{
- assert(offset < sizeof(chipid_and_omr));
- return chipid_and_omr[offset];
-}
-
-static void exynos4210_chipid_and_omr_write(void *opaque, hwaddr offset,
- uint64_t value, unsigned size)
-{
- return;
-}
-
-static const MemoryRegionOps exynos4210_chipid_and_omr_ops = {
- .read = exynos4210_chipid_and_omr_read,
- .write = exynos4210_chipid_and_omr_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
- .impl = {
- .max_access_size = 1,
- }
-};
-
-void exynos4210_write_secondary(ARMCPU *cpu,
- const struct arm_boot_info *info)
-{
- int n;
- uint32_t smpboot[] = {
- 0xe59f3034, /* ldr r3, External gic_cpu_if */
- 0xe59f2034, /* ldr r2, Internal gic_cpu_if */
- 0xe59f0034, /* ldr r0, startaddr */
- 0xe3a01001, /* mov r1, #1 */
- 0xe5821000, /* str r1, [r2] */
- 0xe5831000, /* str r1, [r3] */
- 0xe3a010ff, /* mov r1, #0xff */
- 0xe5821004, /* str r1, [r2, #4] */
- 0xe5831004, /* str r1, [r3, #4] */
- 0xf57ff04f, /* dsb */
- 0xe320f003, /* wfi */
- 0xe5901000, /* ldr r1, [r0] */
- 0xe1110001, /* tst r1, r1 */
- 0x0afffffb, /* beq <wfi> */
- 0xe12fff11, /* bx r1 */
- EXYNOS4210_EXT_GIC_CPU_BASE_ADDR,
- 0, /* gic_cpu_if: base address of Internal GIC CPU interface */
- 0 /* bootreg: Boot register address is held here */
- };
- smpboot[ARRAY_SIZE(smpboot) - 1] = info->smp_bootreg_addr;
- smpboot[ARRAY_SIZE(smpboot) - 2] = info->gic_cpu_if_addr;
- for (n = 0; n < ARRAY_SIZE(smpboot); n++) {
- smpboot[n] = tswap32(smpboot[n]);
- }
- rom_add_blob_fixed("smpboot", smpboot, sizeof(smpboot),
- info->smp_loader_start);
-}
-
-Exynos4210State *exynos4210_init(MemoryRegion *system_mem,
- unsigned long ram_size)
-{
- int i, n;
- Exynos4210State *s = g_new(Exynos4210State, 1);
- qemu_irq gate_irq[EXYNOS4210_NCPUS][EXYNOS4210_IRQ_GATE_NINPUTS];
- unsigned long mem_size;
- DeviceState *dev;
- SysBusDevice *busdev;
- ObjectClass *cpu_oc;
-
- cpu_oc = cpu_class_by_name(TYPE_ARM_CPU, "cortex-a9");
- assert(cpu_oc);
-
- for (n = 0; n < EXYNOS4210_NCPUS; n++) {
- Object *cpuobj = object_new(object_class_get_name(cpu_oc));
-
- /* By default A9 CPUs have EL3 enabled. This board does not currently
- * support EL3 so the CPU EL3 property is disabled before realization.
- */
- if (object_property_find(cpuobj, "has_el3", NULL)) {
- object_property_set_bool(cpuobj, false, "has_el3", &error_fatal);
- }
-
- s->cpu[n] = ARM_CPU(cpuobj);
- object_property_set_int(cpuobj, EXYNOS4210_SMP_PRIVATE_BASE_ADDR,
- "reset-cbar", &error_abort);
- object_property_set_bool(cpuobj, true, "realized", &error_fatal);
- }
-
- /*** IRQs ***/
-
- s->irq_table = exynos4210_init_irq(&s->irqs);
-
- /* IRQ Gate */
- for (i = 0; i < EXYNOS4210_NCPUS; i++) {
- dev = qdev_create(NULL, "exynos4210.irq_gate");
- qdev_prop_set_uint32(dev, "n_in", EXYNOS4210_IRQ_GATE_NINPUTS);
- qdev_init_nofail(dev);
- /* Get IRQ Gate input in gate_irq */
- for (n = 0; n < EXYNOS4210_IRQ_GATE_NINPUTS; n++) {
- gate_irq[i][n] = qdev_get_gpio_in(dev, n);
- }
- busdev = SYS_BUS_DEVICE(dev);
-
- /* Connect IRQ Gate output to CPU's IRQ line */
- sysbus_connect_irq(busdev, 0,
- qdev_get_gpio_in(DEVICE(s->cpu[i]), ARM_CPU_IRQ));
- }
-
- /* Private memory region and Internal GIC */
- dev = qdev_create(NULL, "a9mpcore_priv");
- qdev_prop_set_uint32(dev, "num-cpu", EXYNOS4210_NCPUS);
- qdev_init_nofail(dev);
- busdev = SYS_BUS_DEVICE(dev);
- sysbus_mmio_map(busdev, 0, EXYNOS4210_SMP_PRIVATE_BASE_ADDR);
- for (n = 0; n < EXYNOS4210_NCPUS; n++) {
- sysbus_connect_irq(busdev, n, gate_irq[n][0]);
- }
- for (n = 0; n < EXYNOS4210_INT_GIC_NIRQ; n++) {
- s->irqs.int_gic_irq[n] = qdev_get_gpio_in(dev, n);
- }
-
- /* Cache controller */
- sysbus_create_simple("l2x0", EXYNOS4210_L2X0_BASE_ADDR, NULL);
-
- /* External GIC */
- dev = qdev_create(NULL, "exynos4210.gic");
- qdev_prop_set_uint32(dev, "num-cpu", EXYNOS4210_NCPUS);
- qdev_init_nofail(dev);
- busdev = SYS_BUS_DEVICE(dev);
- /* Map CPU interface */
- sysbus_mmio_map(busdev, 0, EXYNOS4210_EXT_GIC_CPU_BASE_ADDR);
- /* Map Distributer interface */
- sysbus_mmio_map(busdev, 1, EXYNOS4210_EXT_GIC_DIST_BASE_ADDR);
- for (n = 0; n < EXYNOS4210_NCPUS; n++) {
- sysbus_connect_irq(busdev, n, gate_irq[n][1]);
- }
- for (n = 0; n < EXYNOS4210_EXT_GIC_NIRQ; n++) {
- s->irqs.ext_gic_irq[n] = qdev_get_gpio_in(dev, n);
- }
-
- /* Internal Interrupt Combiner */
- dev = qdev_create(NULL, "exynos4210.combiner");
- qdev_init_nofail(dev);
- busdev = SYS_BUS_DEVICE(dev);
- for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) {
- sysbus_connect_irq(busdev, n, s->irqs.int_gic_irq[n]);
- }
- exynos4210_combiner_get_gpioin(&s->irqs, dev, 0);
- sysbus_mmio_map(busdev, 0, EXYNOS4210_INT_COMBINER_BASE_ADDR);
-
- /* External Interrupt Combiner */
- dev = qdev_create(NULL, "exynos4210.combiner");
- qdev_prop_set_uint32(dev, "external", 1);
- qdev_init_nofail(dev);
- busdev = SYS_BUS_DEVICE(dev);
- for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) {
- sysbus_connect_irq(busdev, n, s->irqs.ext_gic_irq[n]);
- }
- exynos4210_combiner_get_gpioin(&s->irqs, dev, 1);
- sysbus_mmio_map(busdev, 0, EXYNOS4210_EXT_COMBINER_BASE_ADDR);
-
- /* Initialize board IRQs. */
- exynos4210_init_board_irqs(&s->irqs);
-
- /*** Memory ***/
-
- /* Chip-ID and OMR */
- memory_region_init_io(&s->chipid_mem, NULL, &exynos4210_chipid_and_omr_ops,
- NULL, "exynos4210.chipid", sizeof(chipid_and_omr));
- memory_region_add_subregion(system_mem, EXYNOS4210_CHIPID_ADDR,
- &s->chipid_mem);
-
- /* Internal ROM */
- memory_region_init_ram(&s->irom_mem, NULL, "exynos4210.irom",
- EXYNOS4210_IROM_SIZE, &error_fatal);
- vmstate_register_ram_global(&s->irom_mem);
- memory_region_set_readonly(&s->irom_mem, true);
- memory_region_add_subregion(system_mem, EXYNOS4210_IROM_BASE_ADDR,
- &s->irom_mem);
- /* mirror of iROM */
- memory_region_init_alias(&s->irom_alias_mem, NULL, "exynos4210.irom_alias",
- &s->irom_mem,
- 0,
- EXYNOS4210_IROM_SIZE);
- memory_region_set_readonly(&s->irom_alias_mem, true);
- memory_region_add_subregion(system_mem, EXYNOS4210_IROM_MIRROR_BASE_ADDR,
- &s->irom_alias_mem);
-
- /* Internal RAM */
- memory_region_init_ram(&s->iram_mem, NULL, "exynos4210.iram",
- EXYNOS4210_IRAM_SIZE, &error_fatal);
- vmstate_register_ram_global(&s->iram_mem);
- memory_region_add_subregion(system_mem, EXYNOS4210_IRAM_BASE_ADDR,
- &s->iram_mem);
-
- /* DRAM */
- mem_size = ram_size;
- if (mem_size > EXYNOS4210_DRAM_MAX_SIZE) {
- memory_region_init_ram(&s->dram1_mem, NULL, "exynos4210.dram1",
- mem_size - EXYNOS4210_DRAM_MAX_SIZE, &error_fatal);
- vmstate_register_ram_global(&s->dram1_mem);
- memory_region_add_subregion(system_mem, EXYNOS4210_DRAM1_BASE_ADDR,
- &s->dram1_mem);
- mem_size = EXYNOS4210_DRAM_MAX_SIZE;
- }
- memory_region_init_ram(&s->dram0_mem, NULL, "exynos4210.dram0", mem_size,
- &error_fatal);
- vmstate_register_ram_global(&s->dram0_mem);
- memory_region_add_subregion(system_mem, EXYNOS4210_DRAM0_BASE_ADDR,
- &s->dram0_mem);
-
- /* PMU.
- * The only reason of existence at the moment is that secondary CPU boot
- * loader uses PMU INFORM5 register as a holding pen.
- */
- sysbus_create_simple("exynos4210.pmu", EXYNOS4210_PMU_BASE_ADDR, NULL);
-
- /* PWM */
- sysbus_create_varargs("exynos4210.pwm", EXYNOS4210_PWM_BASE_ADDR,
- s->irq_table[exynos4210_get_irq(22, 0)],
- s->irq_table[exynos4210_get_irq(22, 1)],
- s->irq_table[exynos4210_get_irq(22, 2)],
- s->irq_table[exynos4210_get_irq(22, 3)],
- s->irq_table[exynos4210_get_irq(22, 4)],
- NULL);
- /* RTC */
- sysbus_create_varargs("exynos4210.rtc", EXYNOS4210_RTC_BASE_ADDR,
- s->irq_table[exynos4210_get_irq(23, 0)],
- s->irq_table[exynos4210_get_irq(23, 1)],
- NULL);
-
- /* Multi Core Timer */
- dev = qdev_create(NULL, "exynos4210.mct");
- qdev_init_nofail(dev);
- busdev = SYS_BUS_DEVICE(dev);
- for (n = 0; n < 4; n++) {
- /* Connect global timer interrupts to Combiner gpio_in */
- sysbus_connect_irq(busdev, n,
- s->irq_table[exynos4210_get_irq(1, 4 + n)]);
- }
- /* Connect local timer interrupts to Combiner gpio_in */
- sysbus_connect_irq(busdev, 4,
- s->irq_table[exynos4210_get_irq(51, 0)]);
- sysbus_connect_irq(busdev, 5,
- s->irq_table[exynos4210_get_irq(35, 3)]);
- sysbus_mmio_map(busdev, 0, EXYNOS4210_MCT_BASE_ADDR);
-
- /*** I2C ***/
- for (n = 0; n < EXYNOS4210_I2C_NUMBER; n++) {
- uint32_t addr = EXYNOS4210_I2C_BASE_ADDR + EXYNOS4210_I2C_SHIFT * n;
- qemu_irq i2c_irq;
-
- if (n < 8) {
- i2c_irq = s->irq_table[exynos4210_get_irq(EXYNOS4210_I2C_INTG, n)];
- } else {
- i2c_irq = s->irq_table[exynos4210_get_irq(EXYNOS4210_HDMI_INTG, 1)];
- }
-
- dev = qdev_create(NULL, "exynos4210.i2c");
- qdev_init_nofail(dev);
- busdev = SYS_BUS_DEVICE(dev);
- sysbus_connect_irq(busdev, 0, i2c_irq);
- sysbus_mmio_map(busdev, 0, addr);
- s->i2c_if[n] = (I2CBus *)qdev_get_child_bus(dev, "i2c");
- }
-
-
- /*** UARTs ***/
- exynos4210_uart_create(EXYNOS4210_UART0_BASE_ADDR,
- EXYNOS4210_UART0_FIFO_SIZE, 0, NULL,
- s->irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP, 0)]);
-
- exynos4210_uart_create(EXYNOS4210_UART1_BASE_ADDR,
- EXYNOS4210_UART1_FIFO_SIZE, 1, NULL,
- s->irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP, 1)]);
-
- exynos4210_uart_create(EXYNOS4210_UART2_BASE_ADDR,
- EXYNOS4210_UART2_FIFO_SIZE, 2, NULL,
- s->irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP, 2)]);
-
- exynos4210_uart_create(EXYNOS4210_UART3_BASE_ADDR,
- EXYNOS4210_UART3_FIFO_SIZE, 3, NULL,
- s->irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP, 3)]);
-
- /*** Display controller (FIMD) ***/
- sysbus_create_varargs("exynos4210.fimd", EXYNOS4210_FIMD0_BASE_ADDR,
- s->irq_table[exynos4210_get_irq(11, 0)],
- s->irq_table[exynos4210_get_irq(11, 1)],
- s->irq_table[exynos4210_get_irq(11, 2)],
- NULL);
-
- sysbus_create_simple(TYPE_EXYNOS4210_EHCI, EXYNOS4210_EHCI_BASE_ADDR,
- s->irq_table[exynos4210_get_irq(28, 3)]);
-
- return s;
-}
diff --git a/qemu/hw/arm/exynos4_boards.c b/qemu/hw/arm/exynos4_boards.c
deleted file mode 100644
index 0efa19405..000000000
--- a/qemu/hw/arm/exynos4_boards.c
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * Samsung exynos4 SoC based boards emulation
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd. All rights reserved.
- * Maksim Kozlov <m.kozlov@samsung.com>
- * Evgeny Voevodin <e.voevodin@samsung.com>
- * Igor Mitsyanko <i.mitsyanko@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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/>.
- *
- */
-
-#include "qemu/osdep.h"
-#include "qemu-common.h"
-#include "cpu.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/qtest.h"
-#include "hw/sysbus.h"
-#include "net/net.h"
-#include "hw/arm/arm.h"
-#include "exec/address-spaces.h"
-#include "hw/arm/exynos4210.h"
-#include "hw/boards.h"
-
-#undef DEBUG
-
-//#define DEBUG
-
-#ifdef DEBUG
- #undef PRINT_DEBUG
- #define PRINT_DEBUG(fmt, args...) \
- do { \
- fprintf(stderr, " [%s:%d] "fmt, __func__, __LINE__, ##args); \
- } while (0)
-#else
- #define PRINT_DEBUG(fmt, args...) do {} while (0)
-#endif
-
-#define SMDK_LAN9118_BASE_ADDR 0x05000000
-
-typedef enum Exynos4BoardType {
- EXYNOS4_BOARD_NURI,
- EXYNOS4_BOARD_SMDKC210,
- EXYNOS4_NUM_OF_BOARDS
-} Exynos4BoardType;
-
-static int exynos4_board_id[EXYNOS4_NUM_OF_BOARDS] = {
- [EXYNOS4_BOARD_NURI] = 0xD33,
- [EXYNOS4_BOARD_SMDKC210] = 0xB16,
-};
-
-static int exynos4_board_smp_bootreg_addr[EXYNOS4_NUM_OF_BOARDS] = {
- [EXYNOS4_BOARD_NURI] = EXYNOS4210_SECOND_CPU_BOOTREG,
- [EXYNOS4_BOARD_SMDKC210] = EXYNOS4210_SECOND_CPU_BOOTREG,
-};
-
-static unsigned long exynos4_board_ram_size[EXYNOS4_NUM_OF_BOARDS] = {
- [EXYNOS4_BOARD_NURI] = 0x40000000,
- [EXYNOS4_BOARD_SMDKC210] = 0x40000000,
-};
-
-static struct arm_boot_info exynos4_board_binfo = {
- .loader_start = EXYNOS4210_BASE_BOOT_ADDR,
- .smp_loader_start = EXYNOS4210_SMP_BOOT_ADDR,
- .nb_cpus = EXYNOS4210_NCPUS,
- .write_secondary_boot = exynos4210_write_secondary,
-};
-
-static void lan9215_init(uint32_t base, qemu_irq irq)
-{
- DeviceState *dev;
- SysBusDevice *s;
-
- /* This should be a 9215 but the 9118 is close enough */
- if (nd_table[0].used) {
- qemu_check_nic_model(&nd_table[0], "lan9118");
- dev = qdev_create(NULL, "lan9118");
- qdev_set_nic_properties(dev, &nd_table[0]);
- qdev_prop_set_uint32(dev, "mode_16bit", 1);
- qdev_init_nofail(dev);
- s = SYS_BUS_DEVICE(dev);
- sysbus_mmio_map(s, 0, base);
- sysbus_connect_irq(s, 0, irq);
- }
-}
-
-static Exynos4210State *exynos4_boards_init_common(MachineState *machine,
- Exynos4BoardType board_type)
-{
- MachineClass *mc = MACHINE_GET_CLASS(machine);
-
- if (smp_cpus != EXYNOS4210_NCPUS && !qtest_enabled()) {
- fprintf(stderr, "%s board supports only %d CPU cores. Ignoring smp_cpus"
- " value.\n",
- mc->name, EXYNOS4210_NCPUS);
- }
-
- exynos4_board_binfo.ram_size = exynos4_board_ram_size[board_type];
- exynos4_board_binfo.board_id = exynos4_board_id[board_type];
- exynos4_board_binfo.smp_bootreg_addr =
- exynos4_board_smp_bootreg_addr[board_type];
- exynos4_board_binfo.kernel_filename = machine->kernel_filename;
- exynos4_board_binfo.initrd_filename = machine->initrd_filename;
- exynos4_board_binfo.kernel_cmdline = machine->kernel_cmdline;
- exynos4_board_binfo.gic_cpu_if_addr =
- EXYNOS4210_SMP_PRIVATE_BASE_ADDR + 0x100;
-
- PRINT_DEBUG("\n ram_size: %luMiB [0x%08lx]\n"
- " kernel_filename: %s\n"
- " kernel_cmdline: %s\n"
- " initrd_filename: %s\n",
- exynos4_board_ram_size[board_type] / 1048576,
- exynos4_board_ram_size[board_type],
- machine->kernel_filename,
- machine->kernel_cmdline,
- machine->initrd_filename);
-
- return exynos4210_init(get_system_memory(),
- exynos4_board_ram_size[board_type]);
-}
-
-static void nuri_init(MachineState *machine)
-{
- exynos4_boards_init_common(machine, EXYNOS4_BOARD_NURI);
-
- arm_load_kernel(ARM_CPU(first_cpu), &exynos4_board_binfo);
-}
-
-static void smdkc210_init(MachineState *machine)
-{
- Exynos4210State *s = exynos4_boards_init_common(machine,
- EXYNOS4_BOARD_SMDKC210);
-
- lan9215_init(SMDK_LAN9118_BASE_ADDR,
- qemu_irq_invert(s->irq_table[exynos4210_get_irq(37, 1)]));
- arm_load_kernel(ARM_CPU(first_cpu), &exynos4_board_binfo);
-}
-
-static void nuri_class_init(ObjectClass *oc, void *data)
-{
- MachineClass *mc = MACHINE_CLASS(oc);
-
- mc->desc = "Samsung NURI board (Exynos4210)";
- mc->init = nuri_init;
- mc->max_cpus = EXYNOS4210_NCPUS;
-}
-
-static const TypeInfo nuri_type = {
- .name = MACHINE_TYPE_NAME("nuri"),
- .parent = TYPE_MACHINE,
- .class_init = nuri_class_init,
-};
-
-static void smdkc210_class_init(ObjectClass *oc, void *data)
-{
- MachineClass *mc = MACHINE_CLASS(oc);
-
- mc->desc = "Samsung SMDKC210 board (Exynos4210)";
- mc->init = smdkc210_init;
- mc->max_cpus = EXYNOS4210_NCPUS;
-}
-
-static const TypeInfo smdkc210_type = {
- .name = MACHINE_TYPE_NAME("smdkc210"),
- .parent = TYPE_MACHINE,
- .class_init = smdkc210_class_init,
-};
-
-static void exynos4_machines_init(void)
-{
- type_register_static(&nuri_type);
- type_register_static(&smdkc210_type);
-}
-
-type_init(exynos4_machines_init)
diff --git a/qemu/hw/arm/fsl-imx25.c b/qemu/hw/arm/fsl-imx25.c
deleted file mode 100644
index 2f878b935..000000000
--- a/qemu/hw/arm/fsl-imx25.c
+++ /dev/null
@@ -1,313 +0,0 @@
-/*
- * Copyright (c) 2013 Jean-Christophe Dubois <jcd@tribudubois.net>
- *
- * i.MX25 SOC emulation.
- *
- * Based on hw/arm/xlnx-zynqmp.c
- *
- * Copyright (C) 2015 Xilinx Inc
- * Written by Peter Crosthwaite <peter.crosthwaite@xilinx.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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/>.
- */
-
-#include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "qemu-common.h"
-#include "cpu.h"
-#include "hw/arm/fsl-imx25.h"
-#include "sysemu/sysemu.h"
-#include "exec/address-spaces.h"
-#include "hw/boards.h"
-#include "sysemu/char.h"
-
-static void fsl_imx25_init(Object *obj)
-{
- FslIMX25State *s = FSL_IMX25(obj);
- int i;
-
- object_initialize(&s->cpu, sizeof(s->cpu), "arm926-" TYPE_ARM_CPU);
-
- object_initialize(&s->avic, sizeof(s->avic), TYPE_IMX_AVIC);
- qdev_set_parent_bus(DEVICE(&s->avic), sysbus_get_default());
-
- object_initialize(&s->ccm, sizeof(s->ccm), TYPE_IMX25_CCM);
- qdev_set_parent_bus(DEVICE(&s->ccm), sysbus_get_default());
-
- for (i = 0; i < FSL_IMX25_NUM_UARTS; i++) {
- object_initialize(&s->uart[i], sizeof(s->uart[i]), TYPE_IMX_SERIAL);
- qdev_set_parent_bus(DEVICE(&s->uart[i]), sysbus_get_default());
- }
-
- for (i = 0; i < FSL_IMX25_NUM_GPTS; i++) {
- object_initialize(&s->gpt[i], sizeof(s->gpt[i]), TYPE_IMX_GPT);
- qdev_set_parent_bus(DEVICE(&s->gpt[i]), sysbus_get_default());
- }
-
- for (i = 0; i < FSL_IMX25_NUM_EPITS; i++) {
- object_initialize(&s->epit[i], sizeof(s->epit[i]), TYPE_IMX_EPIT);
- qdev_set_parent_bus(DEVICE(&s->epit[i]), sysbus_get_default());
- }
-
- object_initialize(&s->fec, sizeof(s->fec), TYPE_IMX_FEC);
- qdev_set_parent_bus(DEVICE(&s->fec), sysbus_get_default());
-
- for (i = 0; i < FSL_IMX25_NUM_I2CS; i++) {
- object_initialize(&s->i2c[i], sizeof(s->i2c[i]), TYPE_IMX_I2C);
- qdev_set_parent_bus(DEVICE(&s->i2c[i]), sysbus_get_default());
- }
-
- for (i = 0; i < FSL_IMX25_NUM_GPIOS; i++) {
- object_initialize(&s->gpio[i], sizeof(s->gpio[i]), TYPE_IMX_GPIO);
- qdev_set_parent_bus(DEVICE(&s->gpio[i]), sysbus_get_default());
- }
-}
-
-static void fsl_imx25_realize(DeviceState *dev, Error **errp)
-{
- FslIMX25State *s = FSL_IMX25(dev);
- uint8_t i;
- Error *err = NULL;
-
- object_property_set_bool(OBJECT(&s->cpu), true, "realized", &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
-
- object_property_set_bool(OBJECT(&s->avic), true, "realized", &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->avic), 0, FSL_IMX25_AVIC_ADDR);
- sysbus_connect_irq(SYS_BUS_DEVICE(&s->avic), 0,
- qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_IRQ));
- sysbus_connect_irq(SYS_BUS_DEVICE(&s->avic), 1,
- qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_FIQ));
-
- object_property_set_bool(OBJECT(&s->ccm), true, "realized", &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->ccm), 0, FSL_IMX25_CCM_ADDR);
-
- /* Initialize all UARTs */
- for (i = 0; i < FSL_IMX25_NUM_UARTS; i++) {
- static const struct {
- hwaddr addr;
- unsigned int irq;
- } serial_table[FSL_IMX25_NUM_UARTS] = {
- { FSL_IMX25_UART1_ADDR, FSL_IMX25_UART1_IRQ },
- { FSL_IMX25_UART2_ADDR, FSL_IMX25_UART2_IRQ },
- { FSL_IMX25_UART3_ADDR, FSL_IMX25_UART3_IRQ },
- { FSL_IMX25_UART4_ADDR, FSL_IMX25_UART4_IRQ },
- { FSL_IMX25_UART5_ADDR, FSL_IMX25_UART5_IRQ }
- };
-
- if (i < MAX_SERIAL_PORTS) {
- CharDriverState *chr;
-
- chr = serial_hds[i];
-
- if (!chr) {
- char label[20];
- snprintf(label, sizeof(label), "imx31.uart%d", i);
- chr = qemu_chr_new(label, "null", NULL);
- }
-
- qdev_prop_set_chr(DEVICE(&s->uart[i]), "chardev", chr);
- }
-
- object_property_set_bool(OBJECT(&s->uart[i]), true, "realized", &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->uart[i]), 0, serial_table[i].addr);
- sysbus_connect_irq(SYS_BUS_DEVICE(&s->uart[i]), 0,
- qdev_get_gpio_in(DEVICE(&s->avic),
- serial_table[i].irq));
- }
-
- /* Initialize all GPT timers */
- for (i = 0; i < FSL_IMX25_NUM_GPTS; i++) {
- static const struct {
- hwaddr addr;
- unsigned int irq;
- } gpt_table[FSL_IMX25_NUM_GPTS] = {
- { FSL_IMX25_GPT1_ADDR, FSL_IMX25_GPT1_IRQ },
- { FSL_IMX25_GPT2_ADDR, FSL_IMX25_GPT2_IRQ },
- { FSL_IMX25_GPT3_ADDR, FSL_IMX25_GPT3_IRQ },
- { FSL_IMX25_GPT4_ADDR, FSL_IMX25_GPT4_IRQ }
- };
-
- s->gpt[i].ccm = IMX_CCM(&s->ccm);
-
- object_property_set_bool(OBJECT(&s->gpt[i]), true, "realized", &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpt[i]), 0, gpt_table[i].addr);
- sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpt[i]), 0,
- qdev_get_gpio_in(DEVICE(&s->avic),
- gpt_table[i].irq));
- }
-
- /* Initialize all EPIT timers */
- for (i = 0; i < FSL_IMX25_NUM_EPITS; i++) {
- static const struct {
- hwaddr addr;
- unsigned int irq;
- } epit_table[FSL_IMX25_NUM_EPITS] = {
- { FSL_IMX25_EPIT1_ADDR, FSL_IMX25_EPIT1_IRQ },
- { FSL_IMX25_EPIT2_ADDR, FSL_IMX25_EPIT2_IRQ }
- };
-
- s->epit[i].ccm = IMX_CCM(&s->ccm);
-
- object_property_set_bool(OBJECT(&s->epit[i]), true, "realized", &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->epit[i]), 0, epit_table[i].addr);
- sysbus_connect_irq(SYS_BUS_DEVICE(&s->epit[i]), 0,
- qdev_get_gpio_in(DEVICE(&s->avic),
- epit_table[i].irq));
- }
-
- qdev_set_nic_properties(DEVICE(&s->fec), &nd_table[0]);
- object_property_set_bool(OBJECT(&s->fec), true, "realized", &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->fec), 0, FSL_IMX25_FEC_ADDR);
- sysbus_connect_irq(SYS_BUS_DEVICE(&s->fec), 0,
- qdev_get_gpio_in(DEVICE(&s->avic), FSL_IMX25_FEC_IRQ));
-
-
- /* Initialize all I2C */
- for (i = 0; i < FSL_IMX25_NUM_I2CS; i++) {
- static const struct {
- hwaddr addr;
- unsigned int irq;
- } i2c_table[FSL_IMX25_NUM_I2CS] = {
- { FSL_IMX25_I2C1_ADDR, FSL_IMX25_I2C1_IRQ },
- { FSL_IMX25_I2C2_ADDR, FSL_IMX25_I2C2_IRQ },
- { FSL_IMX25_I2C3_ADDR, FSL_IMX25_I2C3_IRQ }
- };
-
- object_property_set_bool(OBJECT(&s->i2c[i]), true, "realized", &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c[i]), 0, i2c_table[i].addr);
- sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c[i]), 0,
- qdev_get_gpio_in(DEVICE(&s->avic),
- i2c_table[i].irq));
- }
-
- /* Initialize all GPIOs */
- for (i = 0; i < FSL_IMX25_NUM_GPIOS; i++) {
- static const struct {
- hwaddr addr;
- unsigned int irq;
- } gpio_table[FSL_IMX25_NUM_GPIOS] = {
- { FSL_IMX25_GPIO1_ADDR, FSL_IMX25_GPIO1_IRQ },
- { FSL_IMX25_GPIO2_ADDR, FSL_IMX25_GPIO2_IRQ },
- { FSL_IMX25_GPIO3_ADDR, FSL_IMX25_GPIO3_IRQ },
- { FSL_IMX25_GPIO4_ADDR, FSL_IMX25_GPIO4_IRQ }
- };
-
- object_property_set_bool(OBJECT(&s->gpio[i]), true, "realized", &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpio[i]), 0, gpio_table[i].addr);
- /* Connect GPIO IRQ to PIC */
- sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio[i]), 0,
- qdev_get_gpio_in(DEVICE(&s->avic),
- gpio_table[i].irq));
- }
-
- /* initialize 2 x 16 KB ROM */
- memory_region_init_rom_device(&s->rom[0], NULL, NULL, NULL,
- "imx25.rom0", FSL_IMX25_ROM0_SIZE, &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
- memory_region_add_subregion(get_system_memory(), FSL_IMX25_ROM0_ADDR,
- &s->rom[0]);
- memory_region_init_rom_device(&s->rom[1], NULL, NULL, NULL,
- "imx25.rom1", FSL_IMX25_ROM1_SIZE, &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
- memory_region_add_subregion(get_system_memory(), FSL_IMX25_ROM1_ADDR,
- &s->rom[1]);
-
- /* initialize internal RAM (128 KB) */
- memory_region_init_ram(&s->iram, NULL, "imx25.iram", FSL_IMX25_IRAM_SIZE,
- &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
- memory_region_add_subregion(get_system_memory(), FSL_IMX25_IRAM_ADDR,
- &s->iram);
- vmstate_register_ram_global(&s->iram);
-
- /* internal RAM (128 KB) is aliased over 128 MB - 128 KB */
- memory_region_init_alias(&s->iram_alias, NULL, "imx25.iram_alias",
- &s->iram, 0, FSL_IMX25_IRAM_ALIAS_SIZE);
- memory_region_add_subregion(get_system_memory(), FSL_IMX25_IRAM_ALIAS_ADDR,
- &s->iram_alias);
-}
-
-static void fsl_imx25_class_init(ObjectClass *oc, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
-
- dc->realize = fsl_imx25_realize;
-
- /*
- * Reason: creates an ARM CPU, thus use after free(), see
- * arm_cpu_class_init()
- */
- dc->cannot_destroy_with_object_finalize_yet = true;
- dc->desc = "i.MX25 SOC";
-}
-
-static const TypeInfo fsl_imx25_type_info = {
- .name = TYPE_FSL_IMX25,
- .parent = TYPE_DEVICE,
- .instance_size = sizeof(FslIMX25State),
- .instance_init = fsl_imx25_init,
- .class_init = fsl_imx25_class_init,
-};
-
-static void fsl_imx25_register_types(void)
-{
- type_register_static(&fsl_imx25_type_info);
-}
-
-type_init(fsl_imx25_register_types)
diff --git a/qemu/hw/arm/fsl-imx31.c b/qemu/hw/arm/fsl-imx31.c
deleted file mode 100644
index 31a3a8791..000000000
--- a/qemu/hw/arm/fsl-imx31.c
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * Copyright (c) 2013 Jean-Christophe Dubois <jcd@tribudubois.net>
- *
- * i.MX31 SOC emulation.
- *
- * Based on hw/arm/fsl-imx31.c
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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/>.
- */
-
-#include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "qemu-common.h"
-#include "cpu.h"
-#include "hw/arm/fsl-imx31.h"
-#include "sysemu/sysemu.h"
-#include "exec/address-spaces.h"
-#include "hw/boards.h"
-#include "sysemu/char.h"
-
-static void fsl_imx31_init(Object *obj)
-{
- FslIMX31State *s = FSL_IMX31(obj);
- int i;
-
- object_initialize(&s->cpu, sizeof(s->cpu), "arm1136-" TYPE_ARM_CPU);
-
- object_initialize(&s->avic, sizeof(s->avic), TYPE_IMX_AVIC);
- qdev_set_parent_bus(DEVICE(&s->avic), sysbus_get_default());
-
- object_initialize(&s->ccm, sizeof(s->ccm), TYPE_IMX31_CCM);
- qdev_set_parent_bus(DEVICE(&s->ccm), sysbus_get_default());
-
- for (i = 0; i < FSL_IMX31_NUM_UARTS; i++) {
- object_initialize(&s->uart[i], sizeof(s->uart[i]), TYPE_IMX_SERIAL);
- qdev_set_parent_bus(DEVICE(&s->uart[i]), sysbus_get_default());
- }
-
- object_initialize(&s->gpt, sizeof(s->gpt), TYPE_IMX_GPT);
- qdev_set_parent_bus(DEVICE(&s->gpt), sysbus_get_default());
-
- for (i = 0; i < FSL_IMX31_NUM_EPITS; i++) {
- object_initialize(&s->epit[i], sizeof(s->epit[i]), TYPE_IMX_EPIT);
- qdev_set_parent_bus(DEVICE(&s->epit[i]), sysbus_get_default());
- }
-
- for (i = 0; i < FSL_IMX31_NUM_I2CS; i++) {
- object_initialize(&s->i2c[i], sizeof(s->i2c[i]), TYPE_IMX_I2C);
- qdev_set_parent_bus(DEVICE(&s->i2c[i]), sysbus_get_default());
- }
-
- for (i = 0; i < FSL_IMX31_NUM_GPIOS; i++) {
- object_initialize(&s->gpio[i], sizeof(s->gpio[i]), TYPE_IMX_GPIO);
- qdev_set_parent_bus(DEVICE(&s->gpio[i]), sysbus_get_default());
- }
-}
-
-static void fsl_imx31_realize(DeviceState *dev, Error **errp)
-{
- FslIMX31State *s = FSL_IMX31(dev);
- uint16_t i;
- Error *err = NULL;
-
- object_property_set_bool(OBJECT(&s->cpu), true, "realized", &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
-
- object_property_set_bool(OBJECT(&s->avic), true, "realized", &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->avic), 0, FSL_IMX31_AVIC_ADDR);
- sysbus_connect_irq(SYS_BUS_DEVICE(&s->avic), 0,
- qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_IRQ));
- sysbus_connect_irq(SYS_BUS_DEVICE(&s->avic), 1,
- qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_FIQ));
-
- object_property_set_bool(OBJECT(&s->ccm), true, "realized", &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->ccm), 0, FSL_IMX31_CCM_ADDR);
-
- /* Initialize all UARTS */
- for (i = 0; i < FSL_IMX31_NUM_UARTS; i++) {
- static const struct {
- hwaddr addr;
- unsigned int irq;
- } serial_table[FSL_IMX31_NUM_UARTS] = {
- { FSL_IMX31_UART1_ADDR, FSL_IMX31_UART1_IRQ },
- { FSL_IMX31_UART2_ADDR, FSL_IMX31_UART2_IRQ },
- };
-
- if (i < MAX_SERIAL_PORTS) {
- CharDriverState *chr;
-
- chr = serial_hds[i];
-
- if (!chr) {
- char label[20];
- snprintf(label, sizeof(label), "imx31.uart%d", i);
- chr = qemu_chr_new(label, "null", NULL);
- }
-
- qdev_prop_set_chr(DEVICE(&s->uart[i]), "chardev", chr);
- }
-
- object_property_set_bool(OBJECT(&s->uart[i]), true, "realized", &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
-
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->uart[i]), 0, serial_table[i].addr);
- sysbus_connect_irq(SYS_BUS_DEVICE(&s->uart[i]), 0,
- qdev_get_gpio_in(DEVICE(&s->avic),
- serial_table[i].irq));
- }
-
- s->gpt.ccm = IMX_CCM(&s->ccm);
-
- object_property_set_bool(OBJECT(&s->gpt), true, "realized", &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
-
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpt), 0, FSL_IMX31_GPT_ADDR);
- sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpt), 0,
- qdev_get_gpio_in(DEVICE(&s->avic), FSL_IMX31_GPT_IRQ));
-
- /* Initialize all EPIT timers */
- for (i = 0; i < FSL_IMX31_NUM_EPITS; i++) {
- static const struct {
- hwaddr addr;
- unsigned int irq;
- } epit_table[FSL_IMX31_NUM_EPITS] = {
- { FSL_IMX31_EPIT1_ADDR, FSL_IMX31_EPIT1_IRQ },
- { FSL_IMX31_EPIT2_ADDR, FSL_IMX31_EPIT2_IRQ },
- };
-
- s->epit[i].ccm = IMX_CCM(&s->ccm);
-
- object_property_set_bool(OBJECT(&s->epit[i]), true, "realized", &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
-
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->epit[i]), 0, epit_table[i].addr);
- sysbus_connect_irq(SYS_BUS_DEVICE(&s->epit[i]), 0,
- qdev_get_gpio_in(DEVICE(&s->avic),
- epit_table[i].irq));
- }
-
- /* Initialize all I2C */
- for (i = 0; i < FSL_IMX31_NUM_I2CS; i++) {
- static const struct {
- hwaddr addr;
- unsigned int irq;
- } i2c_table[FSL_IMX31_NUM_I2CS] = {
- { FSL_IMX31_I2C1_ADDR, FSL_IMX31_I2C1_IRQ },
- { FSL_IMX31_I2C2_ADDR, FSL_IMX31_I2C2_IRQ },
- { FSL_IMX31_I2C3_ADDR, FSL_IMX31_I2C3_IRQ }
- };
-
- /* Initialize the I2C */
- object_property_set_bool(OBJECT(&s->i2c[i]), true, "realized", &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
- /* Map I2C memory */
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c[i]), 0, i2c_table[i].addr);
- /* Connect I2C IRQ to PIC */
- sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c[i]), 0,
- qdev_get_gpio_in(DEVICE(&s->avic),
- i2c_table[i].irq));
- }
-
- /* Initialize all GPIOs */
- for (i = 0; i < FSL_IMX31_NUM_GPIOS; i++) {
- static const struct {
- hwaddr addr;
- unsigned int irq;
- } gpio_table[FSL_IMX31_NUM_GPIOS] = {
- { FSL_IMX31_GPIO1_ADDR, FSL_IMX31_GPIO1_IRQ },
- { FSL_IMX31_GPIO2_ADDR, FSL_IMX31_GPIO2_IRQ },
- { FSL_IMX31_GPIO3_ADDR, FSL_IMX31_GPIO3_IRQ }
- };
-
- object_property_set_bool(OBJECT(&s->gpio[i]), false, "has-edge-sel",
- &error_abort);
- object_property_set_bool(OBJECT(&s->gpio[i]), true, "realized", &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpio[i]), 0, gpio_table[i].addr);
- /* Connect GPIO IRQ to PIC */
- sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio[i]), 0,
- qdev_get_gpio_in(DEVICE(&s->avic),
- gpio_table[i].irq));
- }
-
- /* On a real system, the first 16k is a `secure boot rom' */
- memory_region_init_rom_device(&s->secure_rom, NULL, NULL, NULL,
- "imx31.secure_rom",
- FSL_IMX31_SECURE_ROM_SIZE, &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
- memory_region_add_subregion(get_system_memory(), FSL_IMX31_SECURE_ROM_ADDR,
- &s->secure_rom);
-
- /* There is also a 16k ROM */
- memory_region_init_rom_device(&s->rom, NULL, NULL, NULL, "imx31.rom",
- FSL_IMX31_ROM_SIZE, &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
- memory_region_add_subregion(get_system_memory(), FSL_IMX31_ROM_ADDR,
- &s->rom);
-
- /* initialize internal RAM (16 KB) */
- memory_region_init_ram(&s->iram, NULL, "imx31.iram", FSL_IMX31_IRAM_SIZE,
- &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
- memory_region_add_subregion(get_system_memory(), FSL_IMX31_IRAM_ADDR,
- &s->iram);
- vmstate_register_ram_global(&s->iram);
-
- /* internal RAM (16 KB) is aliased over 256 MB - 16 KB */
- memory_region_init_alias(&s->iram_alias, NULL, "imx31.iram_alias",
- &s->iram, 0, FSL_IMX31_IRAM_ALIAS_SIZE);
- memory_region_add_subregion(get_system_memory(), FSL_IMX31_IRAM_ALIAS_ADDR,
- &s->iram_alias);
-}
-
-static void fsl_imx31_class_init(ObjectClass *oc, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
-
- dc->realize = fsl_imx31_realize;
-
- /*
- * Reason: creates an ARM CPU, thus use after free(), see
- * arm_cpu_class_init()
- */
- dc->cannot_destroy_with_object_finalize_yet = true;
- dc->desc = "i.MX31 SOC";
-}
-
-static const TypeInfo fsl_imx31_type_info = {
- .name = TYPE_FSL_IMX31,
- .parent = TYPE_DEVICE,
- .instance_size = sizeof(FslIMX31State),
- .instance_init = fsl_imx31_init,
- .class_init = fsl_imx31_class_init,
-};
-
-static void fsl_imx31_register_types(void)
-{
- type_register_static(&fsl_imx31_type_info);
-}
-
-type_init(fsl_imx31_register_types)
diff --git a/qemu/hw/arm/gumstix.c b/qemu/hw/arm/gumstix.c
deleted file mode 100644
index d59d9ba4e..000000000
--- a/qemu/hw/arm/gumstix.c
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Gumstix Platforms
- *
- * Copyright (c) 2007 by Thorsten Zitterell <info@bitmux.org>
- *
- * Code based on spitz platform by Andrzej Zaborowski <balrog@zabor.org>
- *
- * This code is licensed under the GNU GPL v2.
- *
- * Contributions after 2012-01-13 are licensed under the terms of the
- * GNU GPL, version 2 or (at your option) any later version.
- */
-
-/*
- * Example usage:
- *
- * connex:
- * =======
- * create image:
- * # dd of=flash bs=1k count=16k if=/dev/zero
- * # dd of=flash bs=1k conv=notrunc if=u-boot.bin
- * # dd of=flash bs=1k conv=notrunc seek=256 if=rootfs.arm_nofpu.jffs2
- * start it:
- * # qemu-system-arm -M connex -pflash flash -monitor null -nographic
- *
- * verdex:
- * =======
- * create image:
- * # dd of=flash bs=1k count=32k if=/dev/zero
- * # dd of=flash bs=1k conv=notrunc if=u-boot.bin
- * # dd of=flash bs=1k conv=notrunc seek=256 if=rootfs.arm_nofpu.jffs2
- * # dd of=flash bs=1k conv=notrunc seek=31744 if=uImage
- * start it:
- * # qemu-system-arm -M verdex -pflash flash -monitor null -nographic -m 289
- */
-
-#include "qemu/osdep.h"
-#include "hw/hw.h"
-#include "hw/arm/pxa.h"
-#include "net/net.h"
-#include "hw/block/flash.h"
-#include "hw/devices.h"
-#include "hw/boards.h"
-#include "sysemu/block-backend.h"
-#include "exec/address-spaces.h"
-#include "sysemu/qtest.h"
-
-static const int sector_len = 128 * 1024;
-
-static void connex_init(MachineState *machine)
-{
- PXA2xxState *cpu;
- DriveInfo *dinfo;
- int be;
- MemoryRegion *address_space_mem = get_system_memory();
-
- uint32_t connex_rom = 0x01000000;
- uint32_t connex_ram = 0x04000000;
-
- cpu = pxa255_init(address_space_mem, connex_ram);
-
- dinfo = drive_get(IF_PFLASH, 0, 0);
- if (!dinfo && !qtest_enabled()) {
- fprintf(stderr, "A flash image must be given with the "
- "'pflash' parameter\n");
- exit(1);
- }
-
-#ifdef TARGET_WORDS_BIGENDIAN
- be = 1;
-#else
- be = 0;
-#endif
- if (!pflash_cfi01_register(0x00000000, NULL, "connext.rom", connex_rom,
- dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
- sector_len, connex_rom / sector_len,
- 2, 0, 0, 0, 0, be)) {
- fprintf(stderr, "qemu: Error registering flash memory.\n");
- exit(1);
- }
-
- /* Interrupt line of NIC is connected to GPIO line 36 */
- smc91c111_init(&nd_table[0], 0x04000300,
- qdev_get_gpio_in(cpu->gpio, 36));
-}
-
-static void verdex_init(MachineState *machine)
-{
- const char *cpu_model = machine->cpu_model;
- PXA2xxState *cpu;
- DriveInfo *dinfo;
- int be;
- MemoryRegion *address_space_mem = get_system_memory();
-
- uint32_t verdex_rom = 0x02000000;
- uint32_t verdex_ram = 0x10000000;
-
- cpu = pxa270_init(address_space_mem, verdex_ram, cpu_model ?: "pxa270-c0");
-
- dinfo = drive_get(IF_PFLASH, 0, 0);
- if (!dinfo && !qtest_enabled()) {
- fprintf(stderr, "A flash image must be given with the "
- "'pflash' parameter\n");
- exit(1);
- }
-
-#ifdef TARGET_WORDS_BIGENDIAN
- be = 1;
-#else
- be = 0;
-#endif
- if (!pflash_cfi01_register(0x00000000, NULL, "verdex.rom", verdex_rom,
- dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
- sector_len, verdex_rom / sector_len,
- 2, 0, 0, 0, 0, be)) {
- fprintf(stderr, "qemu: Error registering flash memory.\n");
- exit(1);
- }
-
- /* Interrupt line of NIC is connected to GPIO line 99 */
- smc91c111_init(&nd_table[0], 0x04000300,
- qdev_get_gpio_in(cpu->gpio, 99));
-}
-
-static void connex_class_init(ObjectClass *oc, void *data)
-{
- MachineClass *mc = MACHINE_CLASS(oc);
-
- mc->desc = "Gumstix Connex (PXA255)";
- mc->init = connex_init;
-}
-
-static const TypeInfo connex_type = {
- .name = MACHINE_TYPE_NAME("connex"),
- .parent = TYPE_MACHINE,
- .class_init = connex_class_init,
-};
-
-static void verdex_class_init(ObjectClass *oc, void *data)
-{
- MachineClass *mc = MACHINE_CLASS(oc);
-
- mc->desc = "Gumstix Verdex (PXA270)";
- mc->init = verdex_init;
-}
-
-static const TypeInfo verdex_type = {
- .name = MACHINE_TYPE_NAME("verdex"),
- .parent = TYPE_MACHINE,
- .class_init = verdex_class_init,
-};
-
-static void gumstix_machine_init(void)
-{
- type_register_static(&connex_type);
- type_register_static(&verdex_type);
-}
-
-type_init(gumstix_machine_init)
diff --git a/qemu/hw/arm/highbank.c b/qemu/hw/arm/highbank.c
deleted file mode 100644
index d9930c0d3..000000000
--- a/qemu/hw/arm/highbank.c
+++ /dev/null
@@ -1,441 +0,0 @@
-/*
- * Calxeda Highbank SoC emulation
- *
- * Copyright (c) 2010-2012 Calxeda
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2 or later, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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/>.
- *
- */
-
-#include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "hw/sysbus.h"
-#include "hw/arm/arm.h"
-#include "hw/devices.h"
-#include "hw/loader.h"
-#include "net/net.h"
-#include "sysemu/kvm.h"
-#include "sysemu/sysemu.h"
-#include "hw/boards.h"
-#include "sysemu/block-backend.h"
-#include "exec/address-spaces.h"
-#include "qemu/error-report.h"
-
-#define SMP_BOOT_ADDR 0x100
-#define SMP_BOOT_REG 0x40
-#define MPCORE_PERIPHBASE 0xfff10000
-
-#define MVBAR_ADDR 0x200
-#define BOARD_SETUP_ADDR (MVBAR_ADDR + 8 * sizeof(uint32_t))
-
-#define NIRQ_GIC 160
-
-/* Board init. */
-
-static void hb_write_board_setup(ARMCPU *cpu,
- const struct arm_boot_info *info)
-{
- arm_write_secure_board_setup_dummy_smc(cpu, info, MVBAR_ADDR);
-}
-
-static void hb_write_secondary(ARMCPU *cpu, const struct arm_boot_info *info)
-{
- int n;
- uint32_t smpboot[] = {
- 0xee100fb0, /* mrc p15, 0, r0, c0, c0, 5 - read current core id */
- 0xe210000f, /* ands r0, r0, #0x0f */
- 0xe3a03040, /* mov r3, #0x40 - jump address is 0x40 + 0x10 * core id */
- 0xe0830200, /* add r0, r3, r0, lsl #4 */
- 0xe59f2024, /* ldr r2, privbase */
- 0xe3a01001, /* mov r1, #1 */
- 0xe5821100, /* str r1, [r2, #256] - set GICC_CTLR.Enable */
- 0xe3a010ff, /* mov r1, #0xff */
- 0xe5821104, /* str r1, [r2, #260] - set GICC_PMR.Priority to 0xff */
- 0xf57ff04f, /* dsb */
- 0xe320f003, /* wfi */
- 0xe5901000, /* ldr r1, [r0] */
- 0xe1110001, /* tst r1, r1 */
- 0x0afffffb, /* beq <wfi> */
- 0xe12fff11, /* bx r1 */
- MPCORE_PERIPHBASE /* privbase: MPCore peripheral base address. */
- };
- for (n = 0; n < ARRAY_SIZE(smpboot); n++) {
- smpboot[n] = tswap32(smpboot[n]);
- }
- rom_add_blob_fixed("smpboot", smpboot, sizeof(smpboot), SMP_BOOT_ADDR);
-}
-
-static void hb_reset_secondary(ARMCPU *cpu, const struct arm_boot_info *info)
-{
- CPUARMState *env = &cpu->env;
-
- switch (info->nb_cpus) {
- case 4:
- address_space_stl_notdirty(&address_space_memory,
- SMP_BOOT_REG + 0x30, 0,
- MEMTXATTRS_UNSPECIFIED, NULL);
- case 3:
- address_space_stl_notdirty(&address_space_memory,
- SMP_BOOT_REG + 0x20, 0,
- MEMTXATTRS_UNSPECIFIED, NULL);
- case 2:
- address_space_stl_notdirty(&address_space_memory,
- SMP_BOOT_REG + 0x10, 0,
- MEMTXATTRS_UNSPECIFIED, NULL);
- env->regs[15] = SMP_BOOT_ADDR;
- break;
- default:
- break;
- }
-}
-
-#define NUM_REGS 0x200
-static void hb_regs_write(void *opaque, hwaddr offset,
- uint64_t value, unsigned size)
-{
- uint32_t *regs = opaque;
-
- if (offset == 0xf00) {
- if (value == 1 || value == 2) {
- qemu_system_reset_request();
- } else if (value == 3) {
- qemu_system_shutdown_request();
- }
- }
-
- regs[offset/4] = value;
-}
-
-static uint64_t hb_regs_read(void *opaque, hwaddr offset,
- unsigned size)
-{
- uint32_t *regs = opaque;
- uint32_t value = regs[offset/4];
-
- if ((offset == 0x100) || (offset == 0x108) || (offset == 0x10C)) {
- value |= 0x30000000;
- }
-
- return value;
-}
-
-static const MemoryRegionOps hb_mem_ops = {
- .read = hb_regs_read,
- .write = hb_regs_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-#define TYPE_HIGHBANK_REGISTERS "highbank-regs"
-#define HIGHBANK_REGISTERS(obj) \
- OBJECT_CHECK(HighbankRegsState, (obj), TYPE_HIGHBANK_REGISTERS)
-
-typedef struct {
- /*< private >*/
- SysBusDevice parent_obj;
- /*< public >*/
-
- MemoryRegion iomem;
- uint32_t regs[NUM_REGS];
-} HighbankRegsState;
-
-static VMStateDescription vmstate_highbank_regs = {
- .name = "highbank-regs",
- .version_id = 0,
- .minimum_version_id = 0,
- .fields = (VMStateField[]) {
- VMSTATE_UINT32_ARRAY(regs, HighbankRegsState, NUM_REGS),
- VMSTATE_END_OF_LIST(),
- },
-};
-
-static void highbank_regs_reset(DeviceState *dev)
-{
- HighbankRegsState *s = HIGHBANK_REGISTERS(dev);
-
- s->regs[0x40] = 0x05F20121;
- s->regs[0x41] = 0x2;
- s->regs[0x42] = 0x05F30121;
- s->regs[0x43] = 0x05F40121;
-}
-
-static int highbank_regs_init(SysBusDevice *dev)
-{
- HighbankRegsState *s = HIGHBANK_REGISTERS(dev);
-
- memory_region_init_io(&s->iomem, OBJECT(s), &hb_mem_ops, s->regs,
- "highbank_regs", 0x1000);
- sysbus_init_mmio(dev, &s->iomem);
-
- return 0;
-}
-
-static void highbank_regs_class_init(ObjectClass *klass, void *data)
-{
- SysBusDeviceClass *sbc = SYS_BUS_DEVICE_CLASS(klass);
- DeviceClass *dc = DEVICE_CLASS(klass);
-
- sbc->init = highbank_regs_init;
- dc->desc = "Calxeda Highbank registers";
- dc->vmsd = &vmstate_highbank_regs;
- dc->reset = highbank_regs_reset;
-}
-
-static const TypeInfo highbank_regs_info = {
- .name = TYPE_HIGHBANK_REGISTERS,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(HighbankRegsState),
- .class_init = highbank_regs_class_init,
-};
-
-static void highbank_regs_register_types(void)
-{
- type_register_static(&highbank_regs_info);
-}
-
-type_init(highbank_regs_register_types)
-
-static struct arm_boot_info highbank_binfo;
-
-enum cxmachines {
- CALXEDA_HIGHBANK,
- CALXEDA_MIDWAY,
-};
-
-/* ram_size must be set to match the upper bound of memory in the
- * device tree (linux/arch/arm/boot/dts/highbank.dts), which is
- * normally 0xff900000 or -m 4089. When running this board on a
- * 32-bit host, set the reg value of memory to 0xf7ff00000 in the
- * device tree and pass -m 2047 to QEMU.
- */
-static void calxeda_init(MachineState *machine, enum cxmachines machine_id)
-{
- ram_addr_t ram_size = machine->ram_size;
- const char *cpu_model = machine->cpu_model;
- const char *kernel_filename = machine->kernel_filename;
- const char *kernel_cmdline = machine->kernel_cmdline;
- const char *initrd_filename = machine->initrd_filename;
- DeviceState *dev = NULL;
- SysBusDevice *busdev;
- qemu_irq pic[128];
- int n;
- qemu_irq cpu_irq[4];
- qemu_irq cpu_fiq[4];
- MemoryRegion *sysram;
- MemoryRegion *dram;
- MemoryRegion *sysmem;
- char *sysboot_filename;
-
- switch (machine_id) {
- case CALXEDA_HIGHBANK:
- cpu_model = "cortex-a9";
- break;
- case CALXEDA_MIDWAY:
- cpu_model = "cortex-a15";
- break;
- }
-
- for (n = 0; n < smp_cpus; n++) {
- ObjectClass *oc = cpu_class_by_name(TYPE_ARM_CPU, cpu_model);
- Object *cpuobj;
- ARMCPU *cpu;
-
- cpuobj = object_new(object_class_get_name(oc));
- cpu = ARM_CPU(cpuobj);
-
- object_property_set_int(cpuobj, QEMU_PSCI_CONDUIT_SMC,
- "psci-conduit", &error_abort);
-
- if (n) {
- /* Secondary CPUs start in PSCI powered-down state */
- object_property_set_bool(cpuobj, true,
- "start-powered-off", &error_abort);
- }
-
- if (object_property_find(cpuobj, "reset-cbar", NULL)) {
- object_property_set_int(cpuobj, MPCORE_PERIPHBASE,
- "reset-cbar", &error_abort);
- }
- object_property_set_bool(cpuobj, true, "realized", &error_fatal);
- cpu_irq[n] = qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ);
- cpu_fiq[n] = qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_FIQ);
- }
-
- sysmem = get_system_memory();
- dram = g_new(MemoryRegion, 1);
- memory_region_allocate_system_memory(dram, NULL, "highbank.dram", ram_size);
- /* SDRAM at address zero. */
- memory_region_add_subregion(sysmem, 0, dram);
-
- sysram = g_new(MemoryRegion, 1);
- memory_region_init_ram(sysram, NULL, "highbank.sysram", 0x8000,
- &error_fatal);
- memory_region_add_subregion(sysmem, 0xfff88000, sysram);
- if (bios_name != NULL) {
- sysboot_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
- if (sysboot_filename != NULL) {
- if (load_image_targphys(sysboot_filename, 0xfff88000, 0x8000) < 0) {
- error_report("Unable to load %s", bios_name);
- exit(1);
- }
- g_free(sysboot_filename);
- } else {
- error_report("Unable to find %s", bios_name);
- exit(1);
- }
- }
-
- switch (machine_id) {
- case CALXEDA_HIGHBANK:
- dev = qdev_create(NULL, "l2x0");
- qdev_init_nofail(dev);
- busdev = SYS_BUS_DEVICE(dev);
- sysbus_mmio_map(busdev, 0, 0xfff12000);
-
- dev = qdev_create(NULL, "a9mpcore_priv");
- break;
- case CALXEDA_MIDWAY:
- dev = qdev_create(NULL, "a15mpcore_priv");
- break;
- }
- qdev_prop_set_uint32(dev, "num-cpu", smp_cpus);
- qdev_prop_set_uint32(dev, "num-irq", NIRQ_GIC);
- qdev_init_nofail(dev);
- busdev = SYS_BUS_DEVICE(dev);
- sysbus_mmio_map(busdev, 0, MPCORE_PERIPHBASE);
- for (n = 0; n < smp_cpus; n++) {
- sysbus_connect_irq(busdev, n, cpu_irq[n]);
- sysbus_connect_irq(busdev, n + smp_cpus, cpu_fiq[n]);
- }
-
- for (n = 0; n < 128; n++) {
- pic[n] = qdev_get_gpio_in(dev, n);
- }
-
- dev = qdev_create(NULL, "sp804");
- qdev_prop_set_uint32(dev, "freq0", 150000000);
- qdev_prop_set_uint32(dev, "freq1", 150000000);
- qdev_init_nofail(dev);
- busdev = SYS_BUS_DEVICE(dev);
- sysbus_mmio_map(busdev, 0, 0xfff34000);
- sysbus_connect_irq(busdev, 0, pic[18]);
- sysbus_create_simple("pl011", 0xfff36000, pic[20]);
-
- dev = qdev_create(NULL, "highbank-regs");
- qdev_init_nofail(dev);
- busdev = SYS_BUS_DEVICE(dev);
- sysbus_mmio_map(busdev, 0, 0xfff3c000);
-
- sysbus_create_simple("pl061", 0xfff30000, pic[14]);
- sysbus_create_simple("pl061", 0xfff31000, pic[15]);
- sysbus_create_simple("pl061", 0xfff32000, pic[16]);
- sysbus_create_simple("pl061", 0xfff33000, pic[17]);
- sysbus_create_simple("pl031", 0xfff35000, pic[19]);
- sysbus_create_simple("pl022", 0xfff39000, pic[23]);
-
- sysbus_create_simple("sysbus-ahci", 0xffe08000, pic[83]);
-
- if (nd_table[0].used) {
- qemu_check_nic_model(&nd_table[0], "xgmac");
- dev = qdev_create(NULL, "xgmac");
- qdev_set_nic_properties(dev, &nd_table[0]);
- qdev_init_nofail(dev);
- sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, 0xfff50000);
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[77]);
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), 1, pic[78]);
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), 2, pic[79]);
-
- qemu_check_nic_model(&nd_table[1], "xgmac");
- dev = qdev_create(NULL, "xgmac");
- qdev_set_nic_properties(dev, &nd_table[1]);
- qdev_init_nofail(dev);
- sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, 0xfff51000);
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[80]);
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), 1, pic[81]);
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), 2, pic[82]);
- }
-
- highbank_binfo.ram_size = ram_size;
- highbank_binfo.kernel_filename = kernel_filename;
- highbank_binfo.kernel_cmdline = kernel_cmdline;
- highbank_binfo.initrd_filename = initrd_filename;
- /* highbank requires a dtb in order to boot, and the dtb will override
- * the board ID. The following value is ignored, so set it to -1 to be
- * clear that the value is meaningless.
- */
- highbank_binfo.board_id = -1;
- highbank_binfo.nb_cpus = smp_cpus;
- highbank_binfo.loader_start = 0;
- highbank_binfo.write_secondary_boot = hb_write_secondary;
- highbank_binfo.secondary_cpu_reset_hook = hb_reset_secondary;
- if (!kvm_enabled()) {
- highbank_binfo.board_setup_addr = BOARD_SETUP_ADDR;
- highbank_binfo.write_board_setup = hb_write_board_setup;
- highbank_binfo.secure_board_setup = true;
- } else {
- error_report("WARNING: cannot load built-in Monitor support "
- "if KVM is enabled. Some guests (such as Linux) "
- "may not boot.");
- }
-
- arm_load_kernel(ARM_CPU(first_cpu), &highbank_binfo);
-}
-
-static void highbank_init(MachineState *machine)
-{
- calxeda_init(machine, CALXEDA_HIGHBANK);
-}
-
-static void midway_init(MachineState *machine)
-{
- calxeda_init(machine, CALXEDA_MIDWAY);
-}
-
-static void highbank_class_init(ObjectClass *oc, void *data)
-{
- MachineClass *mc = MACHINE_CLASS(oc);
-
- mc->desc = "Calxeda Highbank (ECX-1000)";
- mc->init = highbank_init;
- mc->block_default_type = IF_SCSI;
- mc->max_cpus = 4;
-}
-
-static const TypeInfo highbank_type = {
- .name = MACHINE_TYPE_NAME("highbank"),
- .parent = TYPE_MACHINE,
- .class_init = highbank_class_init,
-};
-
-static void midway_class_init(ObjectClass *oc, void *data)
-{
- MachineClass *mc = MACHINE_CLASS(oc);
-
- mc->desc = "Calxeda Midway (ECX-2000)";
- mc->init = midway_init;
- mc->block_default_type = IF_SCSI;
- mc->max_cpus = 4;
-}
-
-static const TypeInfo midway_type = {
- .name = MACHINE_TYPE_NAME("midway"),
- .parent = TYPE_MACHINE,
- .class_init = midway_class_init,
-};
-
-static void calxeda_machines_init(void)
-{
- type_register_static(&highbank_type);
- type_register_static(&midway_type);
-}
-
-type_init(calxeda_machines_init)
diff --git a/qemu/hw/arm/imx25_pdk.c b/qemu/hw/arm/imx25_pdk.c
deleted file mode 100644
index 025b60843..000000000
--- a/qemu/hw/arm/imx25_pdk.c
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Copyright (c) 2013 Jean-Christophe Dubois <jcd@tribudubois.net>
- *
- * PDK Board System emulation.
- *
- * Based on hw/arm/kzm.c
- *
- * Copyright (c) 2008 OKL and 2011 NICTA
- * Written by Hans at OK-Labs
- * Updated by Peter Chubb.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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/>.
- */
-
-#include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "qemu-common.h"
-#include "cpu.h"
-#include "hw/arm/fsl-imx25.h"
-#include "hw/boards.h"
-#include "qemu/error-report.h"
-#include "exec/address-spaces.h"
-#include "sysemu/qtest.h"
-#include "hw/i2c/i2c.h"
-
-/* Memory map for PDK Emulation Baseboard:
- * 0x00000000-0x7fffffff See i.MX25 SOC fr support
- * 0x80000000-0x87ffffff RAM + Alias EMULATED
- * 0x90000000-0x9fffffff RAM + Alias EMULATED
- * 0xa0000000-0xa7ffffff Flash IGNORED
- * 0xa8000000-0xafffffff Flash IGNORED
- * 0xb0000000-0xb1ffffff SRAM IGNORED
- * 0xb2000000-0xb3ffffff SRAM IGNORED
- * 0xb4000000-0xb5ffffff CS4 IGNORED
- * 0xb6000000-0xb8000fff Reserved IGNORED
- * 0xb8001000-0xb8001fff SDRAM CTRL reg IGNORED
- * 0xb8002000-0xb8002fff WEIM CTRL reg IGNORED
- * 0xb8003000-0xb8003fff M3IF CTRL reg IGNORED
- * 0xb8004000-0xb8004fff EMI CTRL reg IGNORED
- * 0xb8005000-0xbaffffff Reserved IGNORED
- * 0xbb000000-0xbb000fff NAND flash area buf IGNORED
- * 0xbb001000-0xbb0011ff NAND flash reserved IGNORED
- * 0xbb001200-0xbb001dff Reserved IGNORED
- * 0xbb001e00-0xbb001fff NAN flash CTRL reg IGNORED
- * 0xbb012000-0xbfffffff Reserved IGNORED
- * 0xc0000000-0xffffffff Reserved IGNORED
- */
-
-typedef struct IMX25PDK {
- FslIMX25State soc;
- MemoryRegion ram;
- MemoryRegion ram_alias;
-} IMX25PDK;
-
-static struct arm_boot_info imx25_pdk_binfo;
-
-static void imx25_pdk_init(MachineState *machine)
-{
- IMX25PDK *s = g_new0(IMX25PDK, 1);
- unsigned int ram_size;
- unsigned int alias_offset;
- int i;
-
- object_initialize(&s->soc, sizeof(s->soc), TYPE_FSL_IMX25);
- object_property_add_child(OBJECT(machine), "soc", OBJECT(&s->soc),
- &error_abort);
-
- object_property_set_bool(OBJECT(&s->soc), true, "realized", &error_fatal);
-
- /* We need to initialize our memory */
- if (machine->ram_size > (FSL_IMX25_SDRAM0_SIZE + FSL_IMX25_SDRAM1_SIZE)) {
- error_report("WARNING: RAM size " RAM_ADDR_FMT " above max supported, "
- "reduced to %x", machine->ram_size,
- FSL_IMX25_SDRAM0_SIZE + FSL_IMX25_SDRAM1_SIZE);
- machine->ram_size = FSL_IMX25_SDRAM0_SIZE + FSL_IMX25_SDRAM1_SIZE;
- }
-
- memory_region_allocate_system_memory(&s->ram, NULL, "imx25.ram",
- machine->ram_size);
- memory_region_add_subregion(get_system_memory(), FSL_IMX25_SDRAM0_ADDR,
- &s->ram);
-
- /* initialize the alias memory if any */
- for (i = 0, ram_size = machine->ram_size, alias_offset = 0;
- (i < 2) && ram_size; i++) {
- unsigned int size;
- static const struct {
- hwaddr addr;
- unsigned int size;
- } ram[2] = {
- { FSL_IMX25_SDRAM0_ADDR, FSL_IMX25_SDRAM0_SIZE },
- { FSL_IMX25_SDRAM1_ADDR, FSL_IMX25_SDRAM1_SIZE },
- };
-
- size = MIN(ram_size, ram[i].size);
-
- ram_size -= size;
-
- if (size < ram[i].size) {
- memory_region_init_alias(&s->ram_alias, NULL, "ram.alias",
- &s->ram, alias_offset, ram[i].size - size);
- memory_region_add_subregion(get_system_memory(),
- ram[i].addr + size, &s->ram_alias);
- }
-
- alias_offset += ram[i].size;
- }
-
- imx25_pdk_binfo.ram_size = machine->ram_size;
- imx25_pdk_binfo.kernel_filename = machine->kernel_filename;
- imx25_pdk_binfo.kernel_cmdline = machine->kernel_cmdline;
- imx25_pdk_binfo.initrd_filename = machine->initrd_filename;
- imx25_pdk_binfo.loader_start = FSL_IMX25_SDRAM0_ADDR;
- imx25_pdk_binfo.board_id = 1771,
- imx25_pdk_binfo.nb_cpus = 1;
-
- /*
- * We test explicitly for qtest here as it is not done (yet?) in
- * arm_load_kernel(). Without this the "make check" command would
- * fail.
- */
- if (!qtest_enabled()) {
- arm_load_kernel(&s->soc.cpu, &imx25_pdk_binfo);
- } else {
- /*
- * This I2C device doesn't exist on the real board.
- * We add it here (only on qtest usage) to be able to do a bit
- * of simple qtest. See "make check" for details.
- */
- i2c_create_slave((I2CBus *)qdev_get_child_bus(DEVICE(&s->soc.i2c[0]),
- "i2c"),
- "ds1338", 0x68);
- }
-}
-
-static void imx25_pdk_machine_init(MachineClass *mc)
-{
- mc->desc = "ARM i.MX25 PDK board (ARM926)";
- mc->init = imx25_pdk_init;
-}
-
-DEFINE_MACHINE("imx25-pdk", imx25_pdk_machine_init)
diff --git a/qemu/hw/arm/integratorcp.c b/qemu/hw/arm/integratorcp.c
deleted file mode 100644
index e31bca6e7..000000000
--- a/qemu/hw/arm/integratorcp.c
+++ /dev/null
@@ -1,674 +0,0 @@
-/*
- * ARM Integrator CP System emulation.
- *
- * Copyright (c) 2005-2007 CodeSourcery.
- * Written by Paul Brook
- *
- * This code is licensed under the GPL
- */
-
-#include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "qemu-common.h"
-#include "cpu.h"
-#include "hw/sysbus.h"
-#include "hw/devices.h"
-#include "hw/boards.h"
-#include "hw/arm/arm.h"
-#include "hw/misc/arm_integrator_debug.h"
-#include "net/net.h"
-#include "exec/address-spaces.h"
-#include "sysemu/sysemu.h"
-#include "qemu/error-report.h"
-
-#define TYPE_INTEGRATOR_CM "integrator_core"
-#define INTEGRATOR_CM(obj) \
- OBJECT_CHECK(IntegratorCMState, (obj), TYPE_INTEGRATOR_CM)
-
-typedef struct IntegratorCMState {
- /*< private >*/
- SysBusDevice parent_obj;
- /*< public >*/
-
- MemoryRegion iomem;
- uint32_t memsz;
- MemoryRegion flash;
- uint32_t cm_osc;
- uint32_t cm_ctrl;
- uint32_t cm_lock;
- uint32_t cm_auxosc;
- uint32_t cm_sdram;
- uint32_t cm_init;
- uint32_t cm_flags;
- uint32_t cm_nvflags;
- uint32_t cm_refcnt_offset;
- uint32_t int_level;
- uint32_t irq_enabled;
- uint32_t fiq_enabled;
-} IntegratorCMState;
-
-static uint8_t integrator_spd[128] = {
- 128, 8, 4, 11, 9, 1, 64, 0, 2, 0xa0, 0xa0, 0, 0, 8, 0, 1,
- 0xe, 4, 0x1c, 1, 2, 0x20, 0xc0, 0, 0, 0, 0, 0x30, 0x28, 0x30, 0x28, 0x40
-};
-
-static uint64_t integratorcm_read(void *opaque, hwaddr offset,
- unsigned size)
-{
- IntegratorCMState *s = opaque;
- if (offset >= 0x100 && offset < 0x200) {
- /* CM_SPD */
- if (offset >= 0x180)
- return 0;
- return integrator_spd[offset >> 2];
- }
- switch (offset >> 2) {
- case 0: /* CM_ID */
- return 0x411a3001;
- case 1: /* CM_PROC */
- return 0;
- case 2: /* CM_OSC */
- return s->cm_osc;
- case 3: /* CM_CTRL */
- return s->cm_ctrl;
- case 4: /* CM_STAT */
- return 0x00100000;
- case 5: /* CM_LOCK */
- if (s->cm_lock == 0xa05f) {
- return 0x1a05f;
- } else {
- return s->cm_lock;
- }
- case 6: /* CM_LMBUSCNT */
- /* ??? High frequency timer. */
- hw_error("integratorcm_read: CM_LMBUSCNT");
- case 7: /* CM_AUXOSC */
- return s->cm_auxosc;
- case 8: /* CM_SDRAM */
- return s->cm_sdram;
- case 9: /* CM_INIT */
- return s->cm_init;
- case 10: /* CM_REFCNT */
- /* This register, CM_REFCNT, provides a 32-bit count value.
- * The count increments at the fixed reference clock frequency of 24MHz
- * and can be used as a real-time counter.
- */
- return (uint32_t)muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), 24,
- 1000) - s->cm_refcnt_offset;
- case 12: /* CM_FLAGS */
- return s->cm_flags;
- case 14: /* CM_NVFLAGS */
- return s->cm_nvflags;
- case 16: /* CM_IRQ_STAT */
- return s->int_level & s->irq_enabled;
- case 17: /* CM_IRQ_RSTAT */
- return s->int_level;
- case 18: /* CM_IRQ_ENSET */
- return s->irq_enabled;
- case 20: /* CM_SOFT_INTSET */
- return s->int_level & 1;
- case 24: /* CM_FIQ_STAT */
- return s->int_level & s->fiq_enabled;
- case 25: /* CM_FIQ_RSTAT */
- return s->int_level;
- case 26: /* CM_FIQ_ENSET */
- return s->fiq_enabled;
- case 32: /* CM_VOLTAGE_CTL0 */
- case 33: /* CM_VOLTAGE_CTL1 */
- case 34: /* CM_VOLTAGE_CTL2 */
- case 35: /* CM_VOLTAGE_CTL3 */
- /* ??? Voltage control unimplemented. */
- return 0;
- default:
- hw_error("integratorcm_read: Unimplemented offset 0x%x\n",
- (int)offset);
- return 0;
- }
-}
-
-static void integratorcm_do_remap(IntegratorCMState *s)
-{
- /* Sync memory region state with CM_CTRL REMAP bit:
- * bit 0 => flash at address 0; bit 1 => RAM
- */
- memory_region_set_enabled(&s->flash, !(s->cm_ctrl & 4));
-}
-
-static void integratorcm_set_ctrl(IntegratorCMState *s, uint32_t value)
-{
- if (value & 8) {
- qemu_system_reset_request();
- }
- if ((s->cm_ctrl ^ value) & 1) {
- /* (value & 1) != 0 means the green "MISC LED" is lit.
- * We don't have any nice place to display LEDs. printf is a bad
- * idea because Linux uses the LED as a heartbeat and the output
- * will swamp anything else on the terminal.
- */
- }
- /* Note that the RESET bit [3] always reads as zero */
- s->cm_ctrl = (s->cm_ctrl & ~5) | (value & 5);
- integratorcm_do_remap(s);
-}
-
-static void integratorcm_update(IntegratorCMState *s)
-{
- /* ??? The CPU irq/fiq is raised when either the core module or base PIC
- are active. */
- if (s->int_level & (s->irq_enabled | s->fiq_enabled))
- hw_error("Core module interrupt\n");
-}
-
-static void integratorcm_write(void *opaque, hwaddr offset,
- uint64_t value, unsigned size)
-{
- IntegratorCMState *s = opaque;
- switch (offset >> 2) {
- case 2: /* CM_OSC */
- if (s->cm_lock == 0xa05f)
- s->cm_osc = value;
- break;
- case 3: /* CM_CTRL */
- integratorcm_set_ctrl(s, value);
- break;
- case 5: /* CM_LOCK */
- s->cm_lock = value & 0xffff;
- break;
- case 7: /* CM_AUXOSC */
- if (s->cm_lock == 0xa05f)
- s->cm_auxosc = value;
- break;
- case 8: /* CM_SDRAM */
- s->cm_sdram = value;
- break;
- case 9: /* CM_INIT */
- /* ??? This can change the memory bus frequency. */
- s->cm_init = value;
- break;
- case 12: /* CM_FLAGSS */
- s->cm_flags |= value;
- break;
- case 13: /* CM_FLAGSC */
- s->cm_flags &= ~value;
- break;
- case 14: /* CM_NVFLAGSS */
- s->cm_nvflags |= value;
- break;
- case 15: /* CM_NVFLAGSS */
- s->cm_nvflags &= ~value;
- break;
- case 18: /* CM_IRQ_ENSET */
- s->irq_enabled |= value;
- integratorcm_update(s);
- break;
- case 19: /* CM_IRQ_ENCLR */
- s->irq_enabled &= ~value;
- integratorcm_update(s);
- break;
- case 20: /* CM_SOFT_INTSET */
- s->int_level |= (value & 1);
- integratorcm_update(s);
- break;
- case 21: /* CM_SOFT_INTCLR */
- s->int_level &= ~(value & 1);
- integratorcm_update(s);
- break;
- case 26: /* CM_FIQ_ENSET */
- s->fiq_enabled |= value;
- integratorcm_update(s);
- break;
- case 27: /* CM_FIQ_ENCLR */
- s->fiq_enabled &= ~value;
- integratorcm_update(s);
- break;
- case 32: /* CM_VOLTAGE_CTL0 */
- case 33: /* CM_VOLTAGE_CTL1 */
- case 34: /* CM_VOLTAGE_CTL2 */
- case 35: /* CM_VOLTAGE_CTL3 */
- /* ??? Voltage control unimplemented. */
- break;
- default:
- hw_error("integratorcm_write: Unimplemented offset 0x%x\n",
- (int)offset);
- break;
- }
-}
-
-/* Integrator/CM control registers. */
-
-static const MemoryRegionOps integratorcm_ops = {
- .read = integratorcm_read,
- .write = integratorcm_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static int integratorcm_init(SysBusDevice *dev)
-{
- IntegratorCMState *s = INTEGRATOR_CM(dev);
-
- s->cm_osc = 0x01000048;
- /* ??? What should the high bits of this value be? */
- s->cm_auxosc = 0x0007feff;
- s->cm_sdram = 0x00011122;
- if (s->memsz >= 256) {
- integrator_spd[31] = 64;
- s->cm_sdram |= 0x10;
- } else if (s->memsz >= 128) {
- integrator_spd[31] = 32;
- s->cm_sdram |= 0x0c;
- } else if (s->memsz >= 64) {
- integrator_spd[31] = 16;
- s->cm_sdram |= 0x08;
- } else if (s->memsz >= 32) {
- integrator_spd[31] = 4;
- s->cm_sdram |= 0x04;
- } else {
- integrator_spd[31] = 2;
- }
- memcpy(integrator_spd + 73, "QEMU-MEMORY", 11);
- s->cm_init = 0x00000112;
- s->cm_refcnt_offset = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), 24,
- 1000);
- memory_region_init_ram(&s->flash, OBJECT(s), "integrator.flash", 0x100000,
- &error_fatal);
- vmstate_register_ram_global(&s->flash);
-
- memory_region_init_io(&s->iomem, OBJECT(s), &integratorcm_ops, s,
- "integratorcm", 0x00800000);
- sysbus_init_mmio(dev, &s->iomem);
-
- integratorcm_do_remap(s);
- /* ??? Save/restore. */
- return 0;
-}
-
-/* Integrator/CP hardware emulation. */
-/* Primary interrupt controller. */
-
-#define TYPE_INTEGRATOR_PIC "integrator_pic"
-#define INTEGRATOR_PIC(obj) \
- OBJECT_CHECK(icp_pic_state, (obj), TYPE_INTEGRATOR_PIC)
-
-typedef struct icp_pic_state {
- /*< private >*/
- SysBusDevice parent_obj;
- /*< public >*/
-
- MemoryRegion iomem;
- uint32_t level;
- uint32_t irq_enabled;
- uint32_t fiq_enabled;
- qemu_irq parent_irq;
- qemu_irq parent_fiq;
-} icp_pic_state;
-
-static void icp_pic_update(icp_pic_state *s)
-{
- uint32_t flags;
-
- flags = (s->level & s->irq_enabled);
- qemu_set_irq(s->parent_irq, flags != 0);
- flags = (s->level & s->fiq_enabled);
- qemu_set_irq(s->parent_fiq, flags != 0);
-}
-
-static void icp_pic_set_irq(void *opaque, int irq, int level)
-{
- icp_pic_state *s = (icp_pic_state *)opaque;
- if (level)
- s->level |= 1 << irq;
- else
- s->level &= ~(1 << irq);
- icp_pic_update(s);
-}
-
-static uint64_t icp_pic_read(void *opaque, hwaddr offset,
- unsigned size)
-{
- icp_pic_state *s = (icp_pic_state *)opaque;
-
- switch (offset >> 2) {
- case 0: /* IRQ_STATUS */
- return s->level & s->irq_enabled;
- case 1: /* IRQ_RAWSTAT */
- return s->level;
- case 2: /* IRQ_ENABLESET */
- return s->irq_enabled;
- case 4: /* INT_SOFTSET */
- return s->level & 1;
- case 8: /* FRQ_STATUS */
- return s->level & s->fiq_enabled;
- case 9: /* FRQ_RAWSTAT */
- return s->level;
- case 10: /* FRQ_ENABLESET */
- return s->fiq_enabled;
- case 3: /* IRQ_ENABLECLR */
- case 5: /* INT_SOFTCLR */
- case 11: /* FRQ_ENABLECLR */
- default:
- printf ("icp_pic_read: Bad register offset 0x%x\n", (int)offset);
- return 0;
- }
-}
-
-static void icp_pic_write(void *opaque, hwaddr offset,
- uint64_t value, unsigned size)
-{
- icp_pic_state *s = (icp_pic_state *)opaque;
-
- switch (offset >> 2) {
- case 2: /* IRQ_ENABLESET */
- s->irq_enabled |= value;
- break;
- case 3: /* IRQ_ENABLECLR */
- s->irq_enabled &= ~value;
- break;
- case 4: /* INT_SOFTSET */
- if (value & 1)
- icp_pic_set_irq(s, 0, 1);
- break;
- case 5: /* INT_SOFTCLR */
- if (value & 1)
- icp_pic_set_irq(s, 0, 0);
- break;
- case 10: /* FRQ_ENABLESET */
- s->fiq_enabled |= value;
- break;
- case 11: /* FRQ_ENABLECLR */
- s->fiq_enabled &= ~value;
- break;
- case 0: /* IRQ_STATUS */
- case 1: /* IRQ_RAWSTAT */
- case 8: /* FRQ_STATUS */
- case 9: /* FRQ_RAWSTAT */
- default:
- printf ("icp_pic_write: Bad register offset 0x%x\n", (int)offset);
- return;
- }
- icp_pic_update(s);
-}
-
-static const MemoryRegionOps icp_pic_ops = {
- .read = icp_pic_read,
- .write = icp_pic_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static int icp_pic_init(SysBusDevice *sbd)
-{
- DeviceState *dev = DEVICE(sbd);
- icp_pic_state *s = INTEGRATOR_PIC(dev);
-
- qdev_init_gpio_in(dev, icp_pic_set_irq, 32);
- sysbus_init_irq(sbd, &s->parent_irq);
- sysbus_init_irq(sbd, &s->parent_fiq);
- memory_region_init_io(&s->iomem, OBJECT(s), &icp_pic_ops, s,
- "icp-pic", 0x00800000);
- sysbus_init_mmio(sbd, &s->iomem);
- return 0;
-}
-
-/* CP control registers. */
-
-#define TYPE_ICP_CONTROL_REGS "icp-ctrl-regs"
-#define ICP_CONTROL_REGS(obj) \
- OBJECT_CHECK(ICPCtrlRegsState, (obj), TYPE_ICP_CONTROL_REGS)
-
-typedef struct ICPCtrlRegsState {
- /*< private >*/
- SysBusDevice parent_obj;
- /*< public >*/
-
- MemoryRegion iomem;
-
- qemu_irq mmc_irq;
- uint32_t intreg_state;
-} ICPCtrlRegsState;
-
-#define ICP_GPIO_MMC_WPROT "mmc-wprot"
-#define ICP_GPIO_MMC_CARDIN "mmc-cardin"
-
-#define ICP_INTREG_WPROT (1 << 0)
-#define ICP_INTREG_CARDIN (1 << 3)
-
-static uint64_t icp_control_read(void *opaque, hwaddr offset,
- unsigned size)
-{
- ICPCtrlRegsState *s = opaque;
-
- switch (offset >> 2) {
- case 0: /* CP_IDFIELD */
- return 0x41034003;
- case 1: /* CP_FLASHPROG */
- return 0;
- case 2: /* CP_INTREG */
- return s->intreg_state;
- case 3: /* CP_DECODE */
- return 0x11;
- default:
- hw_error("icp_control_read: Bad offset %x\n", (int)offset);
- return 0;
- }
-}
-
-static void icp_control_write(void *opaque, hwaddr offset,
- uint64_t value, unsigned size)
-{
- ICPCtrlRegsState *s = opaque;
-
- switch (offset >> 2) {
- case 2: /* CP_INTREG */
- s->intreg_state &= ~(value & ICP_INTREG_CARDIN);
- qemu_set_irq(s->mmc_irq, !!(s->intreg_state & ICP_INTREG_CARDIN));
- break;
- case 1: /* CP_FLASHPROG */
- case 3: /* CP_DECODE */
- /* Nothing interesting implemented yet. */
- break;
- default:
- hw_error("icp_control_write: Bad offset %x\n", (int)offset);
- }
-}
-
-static const MemoryRegionOps icp_control_ops = {
- .read = icp_control_read,
- .write = icp_control_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static void icp_control_mmc_wprot(void *opaque, int line, int level)
-{
- ICPCtrlRegsState *s = opaque;
-
- s->intreg_state &= ~ICP_INTREG_WPROT;
- if (level) {
- s->intreg_state |= ICP_INTREG_WPROT;
- }
-}
-
-static void icp_control_mmc_cardin(void *opaque, int line, int level)
-{
- ICPCtrlRegsState *s = opaque;
-
- /* line is released by writing to CP_INTREG */
- if (level) {
- s->intreg_state |= ICP_INTREG_CARDIN;
- qemu_set_irq(s->mmc_irq, 1);
- }
-}
-
-static void icp_control_init(Object *obj)
-{
- SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
- ICPCtrlRegsState *s = ICP_CONTROL_REGS(obj);
- DeviceState *dev = DEVICE(obj);
-
- memory_region_init_io(&s->iomem, OBJECT(s), &icp_control_ops, s,
- "icp_ctrl_regs", 0x00800000);
- sysbus_init_mmio(sbd, &s->iomem);
-
- qdev_init_gpio_in_named(dev, icp_control_mmc_wprot, ICP_GPIO_MMC_WPROT, 1);
- qdev_init_gpio_in_named(dev, icp_control_mmc_cardin,
- ICP_GPIO_MMC_CARDIN, 1);
- sysbus_init_irq(sbd, &s->mmc_irq);
-}
-
-
-/* Board init. */
-
-static struct arm_boot_info integrator_binfo = {
- .loader_start = 0x0,
- .board_id = 0x113,
-};
-
-static void integratorcp_init(MachineState *machine)
-{
- ram_addr_t ram_size = machine->ram_size;
- const char *cpu_model = machine->cpu_model;
- const char *kernel_filename = machine->kernel_filename;
- const char *kernel_cmdline = machine->kernel_cmdline;
- const char *initrd_filename = machine->initrd_filename;
- ObjectClass *cpu_oc;
- Object *cpuobj;
- ARMCPU *cpu;
- MemoryRegion *address_space_mem = get_system_memory();
- MemoryRegion *ram = g_new(MemoryRegion, 1);
- MemoryRegion *ram_alias = g_new(MemoryRegion, 1);
- qemu_irq pic[32];
- DeviceState *dev, *sic, *icp;
- int i;
-
- if (!cpu_model) {
- cpu_model = "arm926";
- }
-
- cpu_oc = cpu_class_by_name(TYPE_ARM_CPU, cpu_model);
- if (!cpu_oc) {
- fprintf(stderr, "Unable to find CPU definition\n");
- exit(1);
- }
-
- cpuobj = object_new(object_class_get_name(cpu_oc));
-
- /* By default ARM1176 CPUs have EL3 enabled. This board does not
- * currently support EL3 so the CPU EL3 property is disabled before
- * realization.
- */
- if (object_property_find(cpuobj, "has_el3", NULL)) {
- object_property_set_bool(cpuobj, false, "has_el3", &error_fatal);
- }
-
- object_property_set_bool(cpuobj, true, "realized", &error_fatal);
-
- cpu = ARM_CPU(cpuobj);
-
- memory_region_allocate_system_memory(ram, NULL, "integrator.ram",
- ram_size);
- /* ??? On a real system the first 1Mb is mapped as SSRAM or boot flash. */
- /* ??? RAM should repeat to fill physical memory space. */
- /* SDRAM at address zero*/
- memory_region_add_subregion(address_space_mem, 0, ram);
- /* And again at address 0x80000000 */
- memory_region_init_alias(ram_alias, NULL, "ram.alias", ram, 0, ram_size);
- memory_region_add_subregion(address_space_mem, 0x80000000, ram_alias);
-
- dev = qdev_create(NULL, TYPE_INTEGRATOR_CM);
- qdev_prop_set_uint32(dev, "memsz", ram_size >> 20);
- qdev_init_nofail(dev);
- sysbus_mmio_map((SysBusDevice *)dev, 0, 0x10000000);
-
- dev = sysbus_create_varargs(TYPE_INTEGRATOR_PIC, 0x14000000,
- qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ),
- qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_FIQ),
- NULL);
- for (i = 0; i < 32; i++) {
- pic[i] = qdev_get_gpio_in(dev, i);
- }
- sic = sysbus_create_simple(TYPE_INTEGRATOR_PIC, 0xca000000, pic[26]);
- sysbus_create_varargs("integrator_pit", 0x13000000,
- pic[5], pic[6], pic[7], NULL);
- sysbus_create_simple("pl031", 0x15000000, pic[8]);
- sysbus_create_simple("pl011", 0x16000000, pic[1]);
- sysbus_create_simple("pl011", 0x17000000, pic[2]);
- icp = sysbus_create_simple(TYPE_ICP_CONTROL_REGS, 0xcb000000,
- qdev_get_gpio_in(sic, 3));
- sysbus_create_simple("pl050_keyboard", 0x18000000, pic[3]);
- sysbus_create_simple("pl050_mouse", 0x19000000, pic[4]);
- sysbus_create_simple(TYPE_INTEGRATOR_DEBUG, 0x1a000000, 0);
-
- dev = sysbus_create_varargs("pl181", 0x1c000000, pic[23], pic[24], NULL);
- qdev_connect_gpio_out(dev, 0,
- qdev_get_gpio_in_named(icp, ICP_GPIO_MMC_WPROT, 0));
- qdev_connect_gpio_out(dev, 1,
- qdev_get_gpio_in_named(icp, ICP_GPIO_MMC_CARDIN, 0));
-
- if (nd_table[0].used)
- smc91c111_init(&nd_table[0], 0xc8000000, pic[27]);
-
- sysbus_create_simple("pl110", 0xc0000000, pic[22]);
-
- integrator_binfo.ram_size = ram_size;
- integrator_binfo.kernel_filename = kernel_filename;
- integrator_binfo.kernel_cmdline = kernel_cmdline;
- integrator_binfo.initrd_filename = initrd_filename;
- arm_load_kernel(cpu, &integrator_binfo);
-}
-
-static void integratorcp_machine_init(MachineClass *mc)
-{
- mc->desc = "ARM Integrator/CP (ARM926EJ-S)";
- mc->init = integratorcp_init;
-}
-
-DEFINE_MACHINE("integratorcp", integratorcp_machine_init)
-
-static Property core_properties[] = {
- DEFINE_PROP_UINT32("memsz", IntegratorCMState, memsz, 0),
- DEFINE_PROP_END_OF_LIST(),
-};
-
-static void core_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
-
- k->init = integratorcm_init;
- dc->props = core_properties;
-}
-
-static const TypeInfo core_info = {
- .name = TYPE_INTEGRATOR_CM,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(IntegratorCMState),
- .class_init = core_class_init,
-};
-
-static void icp_pic_class_init(ObjectClass *klass, void *data)
-{
- SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
-
- sdc->init = icp_pic_init;
-}
-
-static const TypeInfo icp_pic_info = {
- .name = TYPE_INTEGRATOR_PIC,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(icp_pic_state),
- .class_init = icp_pic_class_init,
-};
-
-static const TypeInfo icp_ctrl_regs_info = {
- .name = TYPE_ICP_CONTROL_REGS,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(ICPCtrlRegsState),
- .instance_init = icp_control_init,
-};
-
-static void integratorcp_register_types(void)
-{
- type_register_static(&icp_pic_info);
- type_register_static(&core_info);
- type_register_static(&icp_ctrl_regs_info);
-}
-
-type_init(integratorcp_register_types)
diff --git a/qemu/hw/arm/kzm.c b/qemu/hw/arm/kzm.c
deleted file mode 100644
index 2c96ee33b..000000000
--- a/qemu/hw/arm/kzm.c
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * KZM Board System emulation.
- *
- * Copyright (c) 2008 OKL and 2011 NICTA
- * Written by Hans at OK-Labs
- * Updated by Peter Chubb.
- *
- * This code is licensed under the GPL, version 2 or later.
- * See the file `COPYING' in the top level directory.
- *
- * It (partially) emulates a Kyoto Microcomputer
- * KZM-ARM11-01 evaluation board, with a Freescale
- * i.MX31 SoC
- */
-
-#include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "qemu-common.h"
-#include "cpu.h"
-#include "hw/arm/fsl-imx31.h"
-#include "hw/boards.h"
-#include "qemu/error-report.h"
-#include "exec/address-spaces.h"
-#include "net/net.h"
-#include "hw/devices.h"
-#include "hw/char/serial.h"
-#include "sysemu/qtest.h"
-
-/* Memory map for Kzm Emulation Baseboard:
- * 0x00000000-0x7fffffff See i.MX31 SOC for support
- * 0x80000000-0x8fffffff RAM EMULATED
- * 0x90000000-0x9fffffff RAM EMULATED
- * 0xa0000000-0xafffffff Flash IGNORED
- * 0xb0000000-0xb3ffffff Unavailable IGNORED
- * 0xb4000000-0xb4000fff 8-bit free space IGNORED
- * 0xb4001000-0xb400100f Board control IGNORED
- * 0xb4001003 DIP switch
- * 0xb4001010-0xb400101f 7-segment LED IGNORED
- * 0xb4001020-0xb400102f LED IGNORED
- * 0xb4001030-0xb400103f LED IGNORED
- * 0xb4001040-0xb400104f FPGA, UART EMULATED
- * 0xb4001050-0xb400105f FPGA, UART EMULATED
- * 0xb4001060-0xb40fffff FPGA IGNORED
- * 0xb6000000-0xb61fffff LAN controller EMULATED
- * 0xb6200000-0xb62fffff FPGA NAND Controller IGNORED
- * 0xb6300000-0xb7ffffff Free IGNORED
- * 0xb8000000-0xb8004fff Memory control registers IGNORED
- * 0xc0000000-0xc3ffffff PCMCIA/CF IGNORED
- * 0xc4000000-0xffffffff Reserved IGNORED
- */
-
-typedef struct IMX31KZM {
- FslIMX31State soc;
- MemoryRegion ram;
- MemoryRegion ram_alias;
-} IMX31KZM;
-
-#define KZM_RAM_ADDR (FSL_IMX31_SDRAM0_ADDR)
-#define KZM_FPGA_ADDR (FSL_IMX31_CS4_ADDR + 0x1040)
-#define KZM_LAN9118_ADDR (FSL_IMX31_CS5_ADDR)
-
-static struct arm_boot_info kzm_binfo = {
- .loader_start = KZM_RAM_ADDR,
- .board_id = 1722,
-};
-
-static void kzm_init(MachineState *machine)
-{
- IMX31KZM *s = g_new0(IMX31KZM, 1);
- unsigned int ram_size;
- unsigned int alias_offset;
- unsigned int i;
-
- object_initialize(&s->soc, sizeof(s->soc), TYPE_FSL_IMX31);
- object_property_add_child(OBJECT(machine), "soc", OBJECT(&s->soc),
- &error_abort);
-
- object_property_set_bool(OBJECT(&s->soc), true, "realized", &error_fatal);
-
- /* Check the amount of memory is compatible with the SOC */
- if (machine->ram_size > (FSL_IMX31_SDRAM0_SIZE + FSL_IMX31_SDRAM1_SIZE)) {
- error_report("WARNING: RAM size " RAM_ADDR_FMT " above max supported, "
- "reduced to %x", machine->ram_size,
- FSL_IMX31_SDRAM0_SIZE + FSL_IMX31_SDRAM1_SIZE);
- machine->ram_size = FSL_IMX31_SDRAM0_SIZE + FSL_IMX31_SDRAM1_SIZE;
- }
-
- memory_region_allocate_system_memory(&s->ram, NULL, "kzm.ram",
- machine->ram_size);
- memory_region_add_subregion(get_system_memory(), FSL_IMX31_SDRAM0_ADDR,
- &s->ram);
-
- /* initialize the alias memory if any */
- for (i = 0, ram_size = machine->ram_size, alias_offset = 0;
- (i < 2) && ram_size; i++) {
- unsigned int size;
- static const struct {
- hwaddr addr;
- unsigned int size;
- } ram[2] = {
- { FSL_IMX31_SDRAM0_ADDR, FSL_IMX31_SDRAM0_SIZE },
- { FSL_IMX31_SDRAM1_ADDR, FSL_IMX31_SDRAM1_SIZE },
- };
-
- size = MIN(ram_size, ram[i].size);
-
- ram_size -= size;
-
- if (size < ram[i].size) {
- memory_region_init_alias(&s->ram_alias, NULL, "ram.alias",
- &s->ram, alias_offset, ram[i].size - size);
- memory_region_add_subregion(get_system_memory(),
- ram[i].addr + size, &s->ram_alias);
- }
-
- alias_offset += ram[i].size;
- }
-
- if (nd_table[0].used) {
- lan9118_init(&nd_table[0], KZM_LAN9118_ADDR,
- qdev_get_gpio_in(DEVICE(&s->soc.avic), 52));
- }
-
- if (serial_hds[2]) { /* touchscreen */
- serial_mm_init(get_system_memory(), KZM_FPGA_ADDR+0x10, 0,
- qdev_get_gpio_in(DEVICE(&s->soc.avic), 52),
- 14745600, serial_hds[2], DEVICE_NATIVE_ENDIAN);
- }
-
- kzm_binfo.ram_size = machine->ram_size;
- kzm_binfo.kernel_filename = machine->kernel_filename;
- kzm_binfo.kernel_cmdline = machine->kernel_cmdline;
- kzm_binfo.initrd_filename = machine->initrd_filename;
- kzm_binfo.nb_cpus = 1;
-
- if (!qtest_enabled()) {
- arm_load_kernel(&s->soc.cpu, &kzm_binfo);
- }
-}
-
-static void kzm_machine_init(MachineClass *mc)
-{
- mc->desc = "ARM KZM Emulation Baseboard (ARM1136)";
- mc->init = kzm_init;
-}
-
-DEFINE_MACHINE("kzm", kzm_machine_init)
diff --git a/qemu/hw/arm/mainstone.c b/qemu/hw/arm/mainstone.c
deleted file mode 100644
index 454acc5d2..000000000
--- a/qemu/hw/arm/mainstone.c
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * PXA270-based Intel Mainstone platforms.
- *
- * Copyright (c) 2007 by Armin Kuster <akuster@kama-aina.net> or
- * <akuster@mvista.com>
- *
- * Code based on spitz platform by Andrzej Zaborowski <balrog@zabor.org>
- *
- * This code is licensed under the GNU GPL v2.
- *
- * Contributions after 2012-01-13 are licensed under the terms of the
- * GNU GPL, version 2 or (at your option) any later version.
- */
-#include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "hw/hw.h"
-#include "hw/arm/pxa.h"
-#include "hw/arm/arm.h"
-#include "net/net.h"
-#include "hw/devices.h"
-#include "hw/boards.h"
-#include "hw/block/flash.h"
-#include "sysemu/block-backend.h"
-#include "hw/sysbus.h"
-#include "exec/address-spaces.h"
-#include "sysemu/qtest.h"
-
-/* Device addresses */
-#define MST_FPGA_PHYS 0x08000000
-#define MST_ETH_PHYS 0x10000300
-#define MST_FLASH_0 0x00000000
-#define MST_FLASH_1 0x04000000
-
-/* IRQ definitions */
-#define MMC_IRQ 0
-#define USIM_IRQ 1
-#define USBC_IRQ 2
-#define ETHERNET_IRQ 3
-#define AC97_IRQ 4
-#define PEN_IRQ 5
-#define MSINS_IRQ 6
-#define EXBRD_IRQ 7
-#define S0_CD_IRQ 9
-#define S0_STSCHG_IRQ 10
-#define S0_IRQ 11
-#define S1_CD_IRQ 13
-#define S1_STSCHG_IRQ 14
-#define S1_IRQ 15
-
-static const struct keymap map[0xE0] = {
- [0 ... 0xDF] = { -1, -1 },
- [0x1e] = {0,0}, /* a */
- [0x30] = {0,1}, /* b */
- [0x2e] = {0,2}, /* c */
- [0x20] = {0,3}, /* d */
- [0x12] = {0,4}, /* e */
- [0x21] = {0,5}, /* f */
- [0x22] = {1,0}, /* g */
- [0x23] = {1,1}, /* h */
- [0x17] = {1,2}, /* i */
- [0x24] = {1,3}, /* j */
- [0x25] = {1,4}, /* k */
- [0x26] = {1,5}, /* l */
- [0x32] = {2,0}, /* m */
- [0x31] = {2,1}, /* n */
- [0x18] = {2,2}, /* o */
- [0x19] = {2,3}, /* p */
- [0x10] = {2,4}, /* q */
- [0x13] = {2,5}, /* r */
- [0x1f] = {3,0}, /* s */
- [0x14] = {3,1}, /* t */
- [0x16] = {3,2}, /* u */
- [0x2f] = {3,3}, /* v */
- [0x11] = {3,4}, /* w */
- [0x2d] = {3,5}, /* x */
- [0x15] = {4,2}, /* y */
- [0x2c] = {4,3}, /* z */
- [0xc7] = {5,0}, /* Home */
- [0x2a] = {5,1}, /* shift */
- /*
- * There are two matrix positions which map to space,
- * but QEMU can only use one of them for the reverse
- * mapping, so simply use the second one.
- */
- /* [0x39] = {5,2}, space */
- [0x39] = {5,3}, /* space */
- /*
- * Matrix position {5,4} and other keys are missing here.
- * TODO: Compare with Linux code and test real hardware.
- */
- [0x1c] = {5,5}, /* enter (TODO: might be wrong) */
- [0xc8] = {6,0}, /* up */
- [0xd0] = {6,1}, /* down */
- [0xcb] = {6,2}, /* left */
- [0xcd] = {6,3}, /* right */
-};
-
-enum mainstone_model_e { mainstone };
-
-#define MAINSTONE_RAM 0x04000000
-#define MAINSTONE_ROM 0x00800000
-#define MAINSTONE_FLASH 0x02000000
-
-static struct arm_boot_info mainstone_binfo = {
- .loader_start = PXA2XX_SDRAM_BASE,
- .ram_size = 0x04000000,
-};
-
-static void mainstone_common_init(MemoryRegion *address_space_mem,
- MachineState *machine,
- enum mainstone_model_e model, int arm_id)
-{
- uint32_t sector_len = 256 * 1024;
- hwaddr mainstone_flash_base[] = { MST_FLASH_0, MST_FLASH_1 };
- PXA2xxState *mpu;
- DeviceState *mst_irq;
- DriveInfo *dinfo;
- int i;
- int be;
- MemoryRegion *rom = g_new(MemoryRegion, 1);
- const char *cpu_model = machine->cpu_model;
-
- if (!cpu_model)
- cpu_model = "pxa270-c5";
-
- /* Setup CPU & memory */
- mpu = pxa270_init(address_space_mem, mainstone_binfo.ram_size, cpu_model);
- memory_region_init_ram(rom, NULL, "mainstone.rom", MAINSTONE_ROM,
- &error_fatal);
- vmstate_register_ram_global(rom);
- memory_region_set_readonly(rom, true);
- memory_region_add_subregion(address_space_mem, 0, rom);
-
-#ifdef TARGET_WORDS_BIGENDIAN
- be = 1;
-#else
- be = 0;
-#endif
- /* There are two 32MiB flash devices on the board */
- for (i = 0; i < 2; i ++) {
- dinfo = drive_get(IF_PFLASH, 0, i);
- if (!dinfo) {
- if (qtest_enabled()) {
- break;
- }
- fprintf(stderr, "Two flash images must be given with the "
- "'pflash' parameter\n");
- exit(1);
- }
-
- if (!pflash_cfi01_register(mainstone_flash_base[i], NULL,
- i ? "mainstone.flash1" : "mainstone.flash0",
- MAINSTONE_FLASH,
- blk_by_legacy_dinfo(dinfo),
- sector_len, MAINSTONE_FLASH / sector_len,
- 4, 0, 0, 0, 0, be)) {
- fprintf(stderr, "qemu: Error registering flash memory.\n");
- exit(1);
- }
- }
-
- mst_irq = sysbus_create_simple("mainstone-fpga", MST_FPGA_PHYS,
- qdev_get_gpio_in(mpu->gpio, 0));
-
- /* setup keypad */
- pxa27x_register_keypad(mpu->kp, map, 0xe0);
-
- /* MMC/SD host */
- pxa2xx_mmci_handlers(mpu->mmc, NULL, qdev_get_gpio_in(mst_irq, MMC_IRQ));
-
- pxa2xx_pcmcia_set_irq_cb(mpu->pcmcia[0],
- qdev_get_gpio_in(mst_irq, S0_IRQ),
- qdev_get_gpio_in(mst_irq, S0_CD_IRQ));
- pxa2xx_pcmcia_set_irq_cb(mpu->pcmcia[1],
- qdev_get_gpio_in(mst_irq, S1_IRQ),
- qdev_get_gpio_in(mst_irq, S1_CD_IRQ));
-
- smc91c111_init(&nd_table[0], MST_ETH_PHYS,
- qdev_get_gpio_in(mst_irq, ETHERNET_IRQ));
-
- mainstone_binfo.kernel_filename = machine->kernel_filename;
- mainstone_binfo.kernel_cmdline = machine->kernel_cmdline;
- mainstone_binfo.initrd_filename = machine->initrd_filename;
- mainstone_binfo.board_id = arm_id;
- arm_load_kernel(mpu->cpu, &mainstone_binfo);
-}
-
-static void mainstone_init(MachineState *machine)
-{
- mainstone_common_init(get_system_memory(), machine, mainstone, 0x196);
-}
-
-static void mainstone2_machine_init(MachineClass *mc)
-{
- mc->desc = "Mainstone II (PXA27x)";
- mc->init = mainstone_init;
-}
-
-DEFINE_MACHINE("mainstone", mainstone2_machine_init)
diff --git a/qemu/hw/arm/musicpal.c b/qemu/hw/arm/musicpal.c
deleted file mode 100644
index 7a4cc07dd..000000000
--- a/qemu/hw/arm/musicpal.c
+++ /dev/null
@@ -1,1751 +0,0 @@
-/*
- * Marvell MV88W8618 / Freecom MusicPal emulation.
- *
- * Copyright (c) 2008 Jan Kiszka
- *
- * This code is licensed under the GNU GPL v2.
- *
- * Contributions after 2012-01-13 are licensed under the terms of the
- * GNU GPL, version 2 or (at your option) any later version.
- */
-
-#include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "qemu-common.h"
-#include "cpu.h"
-#include "hw/sysbus.h"
-#include "hw/arm/arm.h"
-#include "hw/devices.h"
-#include "net/net.h"
-#include "sysemu/sysemu.h"
-#include "hw/boards.h"
-#include "hw/char/serial.h"
-#include "qemu/timer.h"
-#include "hw/ptimer.h"
-#include "hw/block/flash.h"
-#include "ui/console.h"
-#include "hw/i2c/i2c.h"
-#include "sysemu/block-backend.h"
-#include "exec/address-spaces.h"
-#include "ui/pixel_ops.h"
-
-#define MP_MISC_BASE 0x80002000
-#define MP_MISC_SIZE 0x00001000
-
-#define MP_ETH_BASE 0x80008000
-#define MP_ETH_SIZE 0x00001000
-
-#define MP_WLAN_BASE 0x8000C000
-#define MP_WLAN_SIZE 0x00000800
-
-#define MP_UART1_BASE 0x8000C840
-#define MP_UART2_BASE 0x8000C940
-
-#define MP_GPIO_BASE 0x8000D000
-#define MP_GPIO_SIZE 0x00001000
-
-#define MP_FLASHCFG_BASE 0x90006000
-#define MP_FLASHCFG_SIZE 0x00001000
-
-#define MP_AUDIO_BASE 0x90007000
-
-#define MP_PIC_BASE 0x90008000
-#define MP_PIC_SIZE 0x00001000
-
-#define MP_PIT_BASE 0x90009000
-#define MP_PIT_SIZE 0x00001000
-
-#define MP_LCD_BASE 0x9000c000
-#define MP_LCD_SIZE 0x00001000
-
-#define MP_SRAM_BASE 0xC0000000
-#define MP_SRAM_SIZE 0x00020000
-
-#define MP_RAM_DEFAULT_SIZE 32*1024*1024
-#define MP_FLASH_SIZE_MAX 32*1024*1024
-
-#define MP_TIMER1_IRQ 4
-#define MP_TIMER2_IRQ 5
-#define MP_TIMER3_IRQ 6
-#define MP_TIMER4_IRQ 7
-#define MP_EHCI_IRQ 8
-#define MP_ETH_IRQ 9
-#define MP_UART1_IRQ 11
-#define MP_UART2_IRQ 11
-#define MP_GPIO_IRQ 12
-#define MP_RTC_IRQ 28
-#define MP_AUDIO_IRQ 30
-
-/* Wolfson 8750 I2C address */
-#define MP_WM_ADDR 0x1A
-
-/* Ethernet register offsets */
-#define MP_ETH_SMIR 0x010
-#define MP_ETH_PCXR 0x408
-#define MP_ETH_SDCMR 0x448
-#define MP_ETH_ICR 0x450
-#define MP_ETH_IMR 0x458
-#define MP_ETH_FRDP0 0x480
-#define MP_ETH_FRDP1 0x484
-#define MP_ETH_FRDP2 0x488
-#define MP_ETH_FRDP3 0x48C
-#define MP_ETH_CRDP0 0x4A0
-#define MP_ETH_CRDP1 0x4A4
-#define MP_ETH_CRDP2 0x4A8
-#define MP_ETH_CRDP3 0x4AC
-#define MP_ETH_CTDP0 0x4E0
-#define MP_ETH_CTDP1 0x4E4
-
-/* MII PHY access */
-#define MP_ETH_SMIR_DATA 0x0000FFFF
-#define MP_ETH_SMIR_ADDR 0x03FF0000
-#define MP_ETH_SMIR_OPCODE (1 << 26) /* Read value */
-#define MP_ETH_SMIR_RDVALID (1 << 27)
-
-/* PHY registers */
-#define MP_ETH_PHY1_BMSR 0x00210000
-#define MP_ETH_PHY1_PHYSID1 0x00410000
-#define MP_ETH_PHY1_PHYSID2 0x00610000
-
-#define MP_PHY_BMSR_LINK 0x0004
-#define MP_PHY_BMSR_AUTONEG 0x0008
-
-#define MP_PHY_88E3015 0x01410E20
-
-/* TX descriptor status */
-#define MP_ETH_TX_OWN (1U << 31)
-
-/* RX descriptor status */
-#define MP_ETH_RX_OWN (1U << 31)
-
-/* Interrupt cause/mask bits */
-#define MP_ETH_IRQ_RX_BIT 0
-#define MP_ETH_IRQ_RX (1 << MP_ETH_IRQ_RX_BIT)
-#define MP_ETH_IRQ_TXHI_BIT 2
-#define MP_ETH_IRQ_TXLO_BIT 3
-
-/* Port config bits */
-#define MP_ETH_PCXR_2BSM_BIT 28 /* 2-byte incoming suffix */
-
-/* SDMA command bits */
-#define MP_ETH_CMD_TXHI (1 << 23)
-#define MP_ETH_CMD_TXLO (1 << 22)
-
-typedef struct mv88w8618_tx_desc {
- uint32_t cmdstat;
- uint16_t res;
- uint16_t bytes;
- uint32_t buffer;
- uint32_t next;
-} mv88w8618_tx_desc;
-
-typedef struct mv88w8618_rx_desc {
- uint32_t cmdstat;
- uint16_t bytes;
- uint16_t buffer_size;
- uint32_t buffer;
- uint32_t next;
-} mv88w8618_rx_desc;
-
-#define TYPE_MV88W8618_ETH "mv88w8618_eth"
-#define MV88W8618_ETH(obj) \
- OBJECT_CHECK(mv88w8618_eth_state, (obj), TYPE_MV88W8618_ETH)
-
-typedef struct mv88w8618_eth_state {
- /*< private >*/
- SysBusDevice parent_obj;
- /*< public >*/
-
- MemoryRegion iomem;
- qemu_irq irq;
- uint32_t smir;
- uint32_t icr;
- uint32_t imr;
- int mmio_index;
- uint32_t vlan_header;
- uint32_t tx_queue[2];
- uint32_t rx_queue[4];
- uint32_t frx_queue[4];
- uint32_t cur_rx[4];
- NICState *nic;
- NICConf conf;
-} mv88w8618_eth_state;
-
-static void eth_rx_desc_put(uint32_t addr, mv88w8618_rx_desc *desc)
-{
- cpu_to_le32s(&desc->cmdstat);
- cpu_to_le16s(&desc->bytes);
- cpu_to_le16s(&desc->buffer_size);
- cpu_to_le32s(&desc->buffer);
- cpu_to_le32s(&desc->next);
- cpu_physical_memory_write(addr, desc, sizeof(*desc));
-}
-
-static void eth_rx_desc_get(uint32_t addr, mv88w8618_rx_desc *desc)
-{
- cpu_physical_memory_read(addr, desc, sizeof(*desc));
- le32_to_cpus(&desc->cmdstat);
- le16_to_cpus(&desc->bytes);
- le16_to_cpus(&desc->buffer_size);
- le32_to_cpus(&desc->buffer);
- le32_to_cpus(&desc->next);
-}
-
-static ssize_t eth_receive(NetClientState *nc, const uint8_t *buf, size_t size)
-{
- mv88w8618_eth_state *s = qemu_get_nic_opaque(nc);
- uint32_t desc_addr;
- mv88w8618_rx_desc desc;
- int i;
-
- for (i = 0; i < 4; i++) {
- desc_addr = s->cur_rx[i];
- if (!desc_addr) {
- continue;
- }
- do {
- eth_rx_desc_get(desc_addr, &desc);
- if ((desc.cmdstat & MP_ETH_RX_OWN) && desc.buffer_size >= size) {
- cpu_physical_memory_write(desc.buffer + s->vlan_header,
- buf, size);
- desc.bytes = size + s->vlan_header;
- desc.cmdstat &= ~MP_ETH_RX_OWN;
- s->cur_rx[i] = desc.next;
-
- s->icr |= MP_ETH_IRQ_RX;
- if (s->icr & s->imr) {
- qemu_irq_raise(s->irq);
- }
- eth_rx_desc_put(desc_addr, &desc);
- return size;
- }
- desc_addr = desc.next;
- } while (desc_addr != s->rx_queue[i]);
- }
- return size;
-}
-
-static void eth_tx_desc_put(uint32_t addr, mv88w8618_tx_desc *desc)
-{
- cpu_to_le32s(&desc->cmdstat);
- cpu_to_le16s(&desc->res);
- cpu_to_le16s(&desc->bytes);
- cpu_to_le32s(&desc->buffer);
- cpu_to_le32s(&desc->next);
- cpu_physical_memory_write(addr, desc, sizeof(*desc));
-}
-
-static void eth_tx_desc_get(uint32_t addr, mv88w8618_tx_desc *desc)
-{
- cpu_physical_memory_read(addr, desc, sizeof(*desc));
- le32_to_cpus(&desc->cmdstat);
- le16_to_cpus(&desc->res);
- le16_to_cpus(&desc->bytes);
- le32_to_cpus(&desc->buffer);
- le32_to_cpus(&desc->next);
-}
-
-static void eth_send(mv88w8618_eth_state *s, int queue_index)
-{
- uint32_t desc_addr = s->tx_queue[queue_index];
- mv88w8618_tx_desc desc;
- uint32_t next_desc;
- uint8_t buf[2048];
- int len;
-
- do {
- eth_tx_desc_get(desc_addr, &desc);
- next_desc = desc.next;
- if (desc.cmdstat & MP_ETH_TX_OWN) {
- len = desc.bytes;
- if (len < 2048) {
- cpu_physical_memory_read(desc.buffer, buf, len);
- qemu_send_packet(qemu_get_queue(s->nic), buf, len);
- }
- desc.cmdstat &= ~MP_ETH_TX_OWN;
- s->icr |= 1 << (MP_ETH_IRQ_TXLO_BIT - queue_index);
- eth_tx_desc_put(desc_addr, &desc);
- }
- desc_addr = next_desc;
- } while (desc_addr != s->tx_queue[queue_index]);
-}
-
-static uint64_t mv88w8618_eth_read(void *opaque, hwaddr offset,
- unsigned size)
-{
- mv88w8618_eth_state *s = opaque;
-
- switch (offset) {
- case MP_ETH_SMIR:
- if (s->smir & MP_ETH_SMIR_OPCODE) {
- switch (s->smir & MP_ETH_SMIR_ADDR) {
- case MP_ETH_PHY1_BMSR:
- return MP_PHY_BMSR_LINK | MP_PHY_BMSR_AUTONEG |
- MP_ETH_SMIR_RDVALID;
- case MP_ETH_PHY1_PHYSID1:
- return (MP_PHY_88E3015 >> 16) | MP_ETH_SMIR_RDVALID;
- case MP_ETH_PHY1_PHYSID2:
- return (MP_PHY_88E3015 & 0xFFFF) | MP_ETH_SMIR_RDVALID;
- default:
- return MP_ETH_SMIR_RDVALID;
- }
- }
- return 0;
-
- case MP_ETH_ICR:
- return s->icr;
-
- case MP_ETH_IMR:
- return s->imr;
-
- case MP_ETH_FRDP0 ... MP_ETH_FRDP3:
- return s->frx_queue[(offset - MP_ETH_FRDP0)/4];
-
- case MP_ETH_CRDP0 ... MP_ETH_CRDP3:
- return s->rx_queue[(offset - MP_ETH_CRDP0)/4];
-
- case MP_ETH_CTDP0 ... MP_ETH_CTDP1:
- return s->tx_queue[(offset - MP_ETH_CTDP0)/4];
-
- default:
- return 0;
- }
-}
-
-static void mv88w8618_eth_write(void *opaque, hwaddr offset,
- uint64_t value, unsigned size)
-{
- mv88w8618_eth_state *s = opaque;
-
- switch (offset) {
- case MP_ETH_SMIR:
- s->smir = value;
- break;
-
- case MP_ETH_PCXR:
- s->vlan_header = ((value >> MP_ETH_PCXR_2BSM_BIT) & 1) * 2;
- break;
-
- case MP_ETH_SDCMR:
- if (value & MP_ETH_CMD_TXHI) {
- eth_send(s, 1);
- }
- if (value & MP_ETH_CMD_TXLO) {
- eth_send(s, 0);
- }
- if (value & (MP_ETH_CMD_TXHI | MP_ETH_CMD_TXLO) && s->icr & s->imr) {
- qemu_irq_raise(s->irq);
- }
- break;
-
- case MP_ETH_ICR:
- s->icr &= value;
- break;
-
- case MP_ETH_IMR:
- s->imr = value;
- if (s->icr & s->imr) {
- qemu_irq_raise(s->irq);
- }
- break;
-
- case MP_ETH_FRDP0 ... MP_ETH_FRDP3:
- s->frx_queue[(offset - MP_ETH_FRDP0)/4] = value;
- break;
-
- case MP_ETH_CRDP0 ... MP_ETH_CRDP3:
- s->rx_queue[(offset - MP_ETH_CRDP0)/4] =
- s->cur_rx[(offset - MP_ETH_CRDP0)/4] = value;
- break;
-
- case MP_ETH_CTDP0 ... MP_ETH_CTDP1:
- s->tx_queue[(offset - MP_ETH_CTDP0)/4] = value;
- break;
- }
-}
-
-static const MemoryRegionOps mv88w8618_eth_ops = {
- .read = mv88w8618_eth_read,
- .write = mv88w8618_eth_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static void eth_cleanup(NetClientState *nc)
-{
- mv88w8618_eth_state *s = qemu_get_nic_opaque(nc);
-
- s->nic = NULL;
-}
-
-static NetClientInfo net_mv88w8618_info = {
- .type = NET_CLIENT_OPTIONS_KIND_NIC,
- .size = sizeof(NICState),
- .receive = eth_receive,
- .cleanup = eth_cleanup,
-};
-
-static int mv88w8618_eth_init(SysBusDevice *sbd)
-{
- DeviceState *dev = DEVICE(sbd);
- mv88w8618_eth_state *s = MV88W8618_ETH(dev);
-
- sysbus_init_irq(sbd, &s->irq);
- s->nic = qemu_new_nic(&net_mv88w8618_info, &s->conf,
- object_get_typename(OBJECT(dev)), dev->id, s);
- memory_region_init_io(&s->iomem, OBJECT(s), &mv88w8618_eth_ops, s,
- "mv88w8618-eth", MP_ETH_SIZE);
- sysbus_init_mmio(sbd, &s->iomem);
- return 0;
-}
-
-static const VMStateDescription mv88w8618_eth_vmsd = {
- .name = "mv88w8618_eth",
- .version_id = 1,
- .minimum_version_id = 1,
- .fields = (VMStateField[]) {
- VMSTATE_UINT32(smir, mv88w8618_eth_state),
- VMSTATE_UINT32(icr, mv88w8618_eth_state),
- VMSTATE_UINT32(imr, mv88w8618_eth_state),
- VMSTATE_UINT32(vlan_header, mv88w8618_eth_state),
- VMSTATE_UINT32_ARRAY(tx_queue, mv88w8618_eth_state, 2),
- VMSTATE_UINT32_ARRAY(rx_queue, mv88w8618_eth_state, 4),
- VMSTATE_UINT32_ARRAY(frx_queue, mv88w8618_eth_state, 4),
- VMSTATE_UINT32_ARRAY(cur_rx, mv88w8618_eth_state, 4),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static Property mv88w8618_eth_properties[] = {
- DEFINE_NIC_PROPERTIES(mv88w8618_eth_state, conf),
- DEFINE_PROP_END_OF_LIST(),
-};
-
-static void mv88w8618_eth_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
-
- k->init = mv88w8618_eth_init;
- dc->vmsd = &mv88w8618_eth_vmsd;
- dc->props = mv88w8618_eth_properties;
-}
-
-static const TypeInfo mv88w8618_eth_info = {
- .name = TYPE_MV88W8618_ETH,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(mv88w8618_eth_state),
- .class_init = mv88w8618_eth_class_init,
-};
-
-/* LCD register offsets */
-#define MP_LCD_IRQCTRL 0x180
-#define MP_LCD_IRQSTAT 0x184
-#define MP_LCD_SPICTRL 0x1ac
-#define MP_LCD_INST 0x1bc
-#define MP_LCD_DATA 0x1c0
-
-/* Mode magics */
-#define MP_LCD_SPI_DATA 0x00100011
-#define MP_LCD_SPI_CMD 0x00104011
-#define MP_LCD_SPI_INVALID 0x00000000
-
-/* Commmands */
-#define MP_LCD_INST_SETPAGE0 0xB0
-/* ... */
-#define MP_LCD_INST_SETPAGE7 0xB7
-
-#define MP_LCD_TEXTCOLOR 0xe0e0ff /* RRGGBB */
-
-#define TYPE_MUSICPAL_LCD "musicpal_lcd"
-#define MUSICPAL_LCD(obj) \
- OBJECT_CHECK(musicpal_lcd_state, (obj), TYPE_MUSICPAL_LCD)
-
-typedef struct musicpal_lcd_state {
- /*< private >*/
- SysBusDevice parent_obj;
- /*< public >*/
-
- MemoryRegion iomem;
- uint32_t brightness;
- uint32_t mode;
- uint32_t irqctrl;
- uint32_t page;
- uint32_t page_off;
- QemuConsole *con;
- uint8_t video_ram[128*64/8];
-} musicpal_lcd_state;
-
-static uint8_t scale_lcd_color(musicpal_lcd_state *s, uint8_t col)
-{
- switch (s->brightness) {
- case 7:
- return col;
- case 0:
- return 0;
- default:
- return (col * s->brightness) / 7;
- }
-}
-
-#define SET_LCD_PIXEL(depth, type) \
-static inline void glue(set_lcd_pixel, depth) \
- (musicpal_lcd_state *s, int x, int y, type col) \
-{ \
- int dx, dy; \
- DisplaySurface *surface = qemu_console_surface(s->con); \
- type *pixel = &((type *) surface_data(surface))[(y * 128 * 3 + x) * 3]; \
-\
- for (dy = 0; dy < 3; dy++, pixel += 127 * 3) \
- for (dx = 0; dx < 3; dx++, pixel++) \
- *pixel = col; \
-}
-SET_LCD_PIXEL(8, uint8_t)
-SET_LCD_PIXEL(16, uint16_t)
-SET_LCD_PIXEL(32, uint32_t)
-
-static void lcd_refresh(void *opaque)
-{
- musicpal_lcd_state *s = opaque;
- DisplaySurface *surface = qemu_console_surface(s->con);
- int x, y, col;
-
- switch (surface_bits_per_pixel(surface)) {
- case 0:
- return;
-#define LCD_REFRESH(depth, func) \
- case depth: \
- col = func(scale_lcd_color(s, (MP_LCD_TEXTCOLOR >> 16) & 0xff), \
- scale_lcd_color(s, (MP_LCD_TEXTCOLOR >> 8) & 0xff), \
- scale_lcd_color(s, MP_LCD_TEXTCOLOR & 0xff)); \
- for (x = 0; x < 128; x++) { \
- for (y = 0; y < 64; y++) { \
- if (s->video_ram[x + (y/8)*128] & (1 << (y % 8))) { \
- glue(set_lcd_pixel, depth)(s, x, y, col); \
- } else { \
- glue(set_lcd_pixel, depth)(s, x, y, 0); \
- } \
- } \
- } \
- break;
- LCD_REFRESH(8, rgb_to_pixel8)
- LCD_REFRESH(16, rgb_to_pixel16)
- LCD_REFRESH(32, (is_surface_bgr(surface) ?
- rgb_to_pixel32bgr : rgb_to_pixel32))
- default:
- hw_error("unsupported colour depth %i\n",
- surface_bits_per_pixel(surface));
- }
-
- dpy_gfx_update(s->con, 0, 0, 128*3, 64*3);
-}
-
-static void lcd_invalidate(void *opaque)
-{
-}
-
-static void musicpal_lcd_gpio_brightness_in(void *opaque, int irq, int level)
-{
- musicpal_lcd_state *s = opaque;
- s->brightness &= ~(1 << irq);
- s->brightness |= level << irq;
-}
-
-static uint64_t musicpal_lcd_read(void *opaque, hwaddr offset,
- unsigned size)
-{
- musicpal_lcd_state *s = opaque;
-
- switch (offset) {
- case MP_LCD_IRQCTRL:
- return s->irqctrl;
-
- default:
- return 0;
- }
-}
-
-static void musicpal_lcd_write(void *opaque, hwaddr offset,
- uint64_t value, unsigned size)
-{
- musicpal_lcd_state *s = opaque;
-
- switch (offset) {
- case MP_LCD_IRQCTRL:
- s->irqctrl = value;
- break;
-
- case MP_LCD_SPICTRL:
- if (value == MP_LCD_SPI_DATA || value == MP_LCD_SPI_CMD) {
- s->mode = value;
- } else {
- s->mode = MP_LCD_SPI_INVALID;
- }
- break;
-
- case MP_LCD_INST:
- if (value >= MP_LCD_INST_SETPAGE0 && value <= MP_LCD_INST_SETPAGE7) {
- s->page = value - MP_LCD_INST_SETPAGE0;
- s->page_off = 0;
- }
- break;
-
- case MP_LCD_DATA:
- if (s->mode == MP_LCD_SPI_CMD) {
- if (value >= MP_LCD_INST_SETPAGE0 &&
- value <= MP_LCD_INST_SETPAGE7) {
- s->page = value - MP_LCD_INST_SETPAGE0;
- s->page_off = 0;
- }
- } else if (s->mode == MP_LCD_SPI_DATA) {
- s->video_ram[s->page*128 + s->page_off] = value;
- s->page_off = (s->page_off + 1) & 127;
- }
- break;
- }
-}
-
-static const MemoryRegionOps musicpal_lcd_ops = {
- .read = musicpal_lcd_read,
- .write = musicpal_lcd_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static const GraphicHwOps musicpal_gfx_ops = {
- .invalidate = lcd_invalidate,
- .gfx_update = lcd_refresh,
-};
-
-static int musicpal_lcd_init(SysBusDevice *sbd)
-{
- DeviceState *dev = DEVICE(sbd);
- musicpal_lcd_state *s = MUSICPAL_LCD(dev);
-
- s->brightness = 7;
-
- memory_region_init_io(&s->iomem, OBJECT(s), &musicpal_lcd_ops, s,
- "musicpal-lcd", MP_LCD_SIZE);
- sysbus_init_mmio(sbd, &s->iomem);
-
- s->con = graphic_console_init(dev, 0, &musicpal_gfx_ops, s);
- qemu_console_resize(s->con, 128*3, 64*3);
-
- qdev_init_gpio_in(dev, musicpal_lcd_gpio_brightness_in, 3);
-
- return 0;
-}
-
-static const VMStateDescription musicpal_lcd_vmsd = {
- .name = "musicpal_lcd",
- .version_id = 1,
- .minimum_version_id = 1,
- .fields = (VMStateField[]) {
- VMSTATE_UINT32(brightness, musicpal_lcd_state),
- VMSTATE_UINT32(mode, musicpal_lcd_state),
- VMSTATE_UINT32(irqctrl, musicpal_lcd_state),
- VMSTATE_UINT32(page, musicpal_lcd_state),
- VMSTATE_UINT32(page_off, musicpal_lcd_state),
- VMSTATE_BUFFER(video_ram, musicpal_lcd_state),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static void musicpal_lcd_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
-
- k->init = musicpal_lcd_init;
- dc->vmsd = &musicpal_lcd_vmsd;
-}
-
-static const TypeInfo musicpal_lcd_info = {
- .name = TYPE_MUSICPAL_LCD,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(musicpal_lcd_state),
- .class_init = musicpal_lcd_class_init,
-};
-
-/* PIC register offsets */
-#define MP_PIC_STATUS 0x00
-#define MP_PIC_ENABLE_SET 0x08
-#define MP_PIC_ENABLE_CLR 0x0C
-
-#define TYPE_MV88W8618_PIC "mv88w8618_pic"
-#define MV88W8618_PIC(obj) \
- OBJECT_CHECK(mv88w8618_pic_state, (obj), TYPE_MV88W8618_PIC)
-
-typedef struct mv88w8618_pic_state {
- /*< private >*/
- SysBusDevice parent_obj;
- /*< public >*/
-
- MemoryRegion iomem;
- uint32_t level;
- uint32_t enabled;
- qemu_irq parent_irq;
-} mv88w8618_pic_state;
-
-static void mv88w8618_pic_update(mv88w8618_pic_state *s)
-{
- qemu_set_irq(s->parent_irq, (s->level & s->enabled));
-}
-
-static void mv88w8618_pic_set_irq(void *opaque, int irq, int level)
-{
- mv88w8618_pic_state *s = opaque;
-
- if (level) {
- s->level |= 1 << irq;
- } else {
- s->level &= ~(1 << irq);
- }
- mv88w8618_pic_update(s);
-}
-
-static uint64_t mv88w8618_pic_read(void *opaque, hwaddr offset,
- unsigned size)
-{
- mv88w8618_pic_state *s = opaque;
-
- switch (offset) {
- case MP_PIC_STATUS:
- return s->level & s->enabled;
-
- default:
- return 0;
- }
-}
-
-static void mv88w8618_pic_write(void *opaque, hwaddr offset,
- uint64_t value, unsigned size)
-{
- mv88w8618_pic_state *s = opaque;
-
- switch (offset) {
- case MP_PIC_ENABLE_SET:
- s->enabled |= value;
- break;
-
- case MP_PIC_ENABLE_CLR:
- s->enabled &= ~value;
- s->level &= ~value;
- break;
- }
- mv88w8618_pic_update(s);
-}
-
-static void mv88w8618_pic_reset(DeviceState *d)
-{
- mv88w8618_pic_state *s = MV88W8618_PIC(d);
-
- s->level = 0;
- s->enabled = 0;
-}
-
-static const MemoryRegionOps mv88w8618_pic_ops = {
- .read = mv88w8618_pic_read,
- .write = mv88w8618_pic_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static int mv88w8618_pic_init(SysBusDevice *dev)
-{
- mv88w8618_pic_state *s = MV88W8618_PIC(dev);
-
- qdev_init_gpio_in(DEVICE(dev), mv88w8618_pic_set_irq, 32);
- sysbus_init_irq(dev, &s->parent_irq);
- memory_region_init_io(&s->iomem, OBJECT(s), &mv88w8618_pic_ops, s,
- "musicpal-pic", MP_PIC_SIZE);
- sysbus_init_mmio(dev, &s->iomem);
- return 0;
-}
-
-static const VMStateDescription mv88w8618_pic_vmsd = {
- .name = "mv88w8618_pic",
- .version_id = 1,
- .minimum_version_id = 1,
- .fields = (VMStateField[]) {
- VMSTATE_UINT32(level, mv88w8618_pic_state),
- VMSTATE_UINT32(enabled, mv88w8618_pic_state),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static void mv88w8618_pic_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
-
- k->init = mv88w8618_pic_init;
- dc->reset = mv88w8618_pic_reset;
- dc->vmsd = &mv88w8618_pic_vmsd;
-}
-
-static const TypeInfo mv88w8618_pic_info = {
- .name = TYPE_MV88W8618_PIC,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(mv88w8618_pic_state),
- .class_init = mv88w8618_pic_class_init,
-};
-
-/* PIT register offsets */
-#define MP_PIT_TIMER1_LENGTH 0x00
-/* ... */
-#define MP_PIT_TIMER4_LENGTH 0x0C
-#define MP_PIT_CONTROL 0x10
-#define MP_PIT_TIMER1_VALUE 0x14
-/* ... */
-#define MP_PIT_TIMER4_VALUE 0x20
-#define MP_BOARD_RESET 0x34
-
-/* Magic board reset value (probably some watchdog behind it) */
-#define MP_BOARD_RESET_MAGIC 0x10000
-
-typedef struct mv88w8618_timer_state {
- ptimer_state *ptimer;
- uint32_t limit;
- int freq;
- qemu_irq irq;
-} mv88w8618_timer_state;
-
-#define TYPE_MV88W8618_PIT "mv88w8618_pit"
-#define MV88W8618_PIT(obj) \
- OBJECT_CHECK(mv88w8618_pit_state, (obj), TYPE_MV88W8618_PIT)
-
-typedef struct mv88w8618_pit_state {
- /*< private >*/
- SysBusDevice parent_obj;
- /*< public >*/
-
- MemoryRegion iomem;
- mv88w8618_timer_state timer[4];
-} mv88w8618_pit_state;
-
-static void mv88w8618_timer_tick(void *opaque)
-{
- mv88w8618_timer_state *s = opaque;
-
- qemu_irq_raise(s->irq);
-}
-
-static void mv88w8618_timer_init(SysBusDevice *dev, mv88w8618_timer_state *s,
- uint32_t freq)
-{
- QEMUBH *bh;
-
- sysbus_init_irq(dev, &s->irq);
- s->freq = freq;
-
- bh = qemu_bh_new(mv88w8618_timer_tick, s);
- s->ptimer = ptimer_init(bh);
-}
-
-static uint64_t mv88w8618_pit_read(void *opaque, hwaddr offset,
- unsigned size)
-{
- mv88w8618_pit_state *s = opaque;
- mv88w8618_timer_state *t;
-
- switch (offset) {
- case MP_PIT_TIMER1_VALUE ... MP_PIT_TIMER4_VALUE:
- t = &s->timer[(offset-MP_PIT_TIMER1_VALUE) >> 2];
- return ptimer_get_count(t->ptimer);
-
- default:
- return 0;
- }
-}
-
-static void mv88w8618_pit_write(void *opaque, hwaddr offset,
- uint64_t value, unsigned size)
-{
- mv88w8618_pit_state *s = opaque;
- mv88w8618_timer_state *t;
- int i;
-
- switch (offset) {
- case MP_PIT_TIMER1_LENGTH ... MP_PIT_TIMER4_LENGTH:
- t = &s->timer[offset >> 2];
- t->limit = value;
- if (t->limit > 0) {
- ptimer_set_limit(t->ptimer, t->limit, 1);
- } else {
- ptimer_stop(t->ptimer);
- }
- break;
-
- case MP_PIT_CONTROL:
- for (i = 0; i < 4; i++) {
- t = &s->timer[i];
- if (value & 0xf && t->limit > 0) {
- ptimer_set_limit(t->ptimer, t->limit, 0);
- ptimer_set_freq(t->ptimer, t->freq);
- ptimer_run(t->ptimer, 0);
- } else {
- ptimer_stop(t->ptimer);
- }
- value >>= 4;
- }
- break;
-
- case MP_BOARD_RESET:
- if (value == MP_BOARD_RESET_MAGIC) {
- qemu_system_reset_request();
- }
- break;
- }
-}
-
-static void mv88w8618_pit_reset(DeviceState *d)
-{
- mv88w8618_pit_state *s = MV88W8618_PIT(d);
- int i;
-
- for (i = 0; i < 4; i++) {
- ptimer_stop(s->timer[i].ptimer);
- s->timer[i].limit = 0;
- }
-}
-
-static const MemoryRegionOps mv88w8618_pit_ops = {
- .read = mv88w8618_pit_read,
- .write = mv88w8618_pit_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static int mv88w8618_pit_init(SysBusDevice *dev)
-{
- mv88w8618_pit_state *s = MV88W8618_PIT(dev);
- int i;
-
- /* Letting them all run at 1 MHz is likely just a pragmatic
- * simplification. */
- for (i = 0; i < 4; i++) {
- mv88w8618_timer_init(dev, &s->timer[i], 1000000);
- }
-
- memory_region_init_io(&s->iomem, OBJECT(s), &mv88w8618_pit_ops, s,
- "musicpal-pit", MP_PIT_SIZE);
- sysbus_init_mmio(dev, &s->iomem);
- return 0;
-}
-
-static const VMStateDescription mv88w8618_timer_vmsd = {
- .name = "timer",
- .version_id = 1,
- .minimum_version_id = 1,
- .fields = (VMStateField[]) {
- VMSTATE_PTIMER(ptimer, mv88w8618_timer_state),
- VMSTATE_UINT32(limit, mv88w8618_timer_state),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static const VMStateDescription mv88w8618_pit_vmsd = {
- .name = "mv88w8618_pit",
- .version_id = 1,
- .minimum_version_id = 1,
- .fields = (VMStateField[]) {
- VMSTATE_STRUCT_ARRAY(timer, mv88w8618_pit_state, 4, 1,
- mv88w8618_timer_vmsd, mv88w8618_timer_state),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static void mv88w8618_pit_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
-
- k->init = mv88w8618_pit_init;
- dc->reset = mv88w8618_pit_reset;
- dc->vmsd = &mv88w8618_pit_vmsd;
-}
-
-static const TypeInfo mv88w8618_pit_info = {
- .name = TYPE_MV88W8618_PIT,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(mv88w8618_pit_state),
- .class_init = mv88w8618_pit_class_init,
-};
-
-/* Flash config register offsets */
-#define MP_FLASHCFG_CFGR0 0x04
-
-#define TYPE_MV88W8618_FLASHCFG "mv88w8618_flashcfg"
-#define MV88W8618_FLASHCFG(obj) \
- OBJECT_CHECK(mv88w8618_flashcfg_state, (obj), TYPE_MV88W8618_FLASHCFG)
-
-typedef struct mv88w8618_flashcfg_state {
- /*< private >*/
- SysBusDevice parent_obj;
- /*< public >*/
-
- MemoryRegion iomem;
- uint32_t cfgr0;
-} mv88w8618_flashcfg_state;
-
-static uint64_t mv88w8618_flashcfg_read(void *opaque,
- hwaddr offset,
- unsigned size)
-{
- mv88w8618_flashcfg_state *s = opaque;
-
- switch (offset) {
- case MP_FLASHCFG_CFGR0:
- return s->cfgr0;
-
- default:
- return 0;
- }
-}
-
-static void mv88w8618_flashcfg_write(void *opaque, hwaddr offset,
- uint64_t value, unsigned size)
-{
- mv88w8618_flashcfg_state *s = opaque;
-
- switch (offset) {
- case MP_FLASHCFG_CFGR0:
- s->cfgr0 = value;
- break;
- }
-}
-
-static const MemoryRegionOps mv88w8618_flashcfg_ops = {
- .read = mv88w8618_flashcfg_read,
- .write = mv88w8618_flashcfg_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static int mv88w8618_flashcfg_init(SysBusDevice *dev)
-{
- mv88w8618_flashcfg_state *s = MV88W8618_FLASHCFG(dev);
-
- s->cfgr0 = 0xfffe4285; /* Default as set by U-Boot for 8 MB flash */
- memory_region_init_io(&s->iomem, OBJECT(s), &mv88w8618_flashcfg_ops, s,
- "musicpal-flashcfg", MP_FLASHCFG_SIZE);
- sysbus_init_mmio(dev, &s->iomem);
- return 0;
-}
-
-static const VMStateDescription mv88w8618_flashcfg_vmsd = {
- .name = "mv88w8618_flashcfg",
- .version_id = 1,
- .minimum_version_id = 1,
- .fields = (VMStateField[]) {
- VMSTATE_UINT32(cfgr0, mv88w8618_flashcfg_state),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static void mv88w8618_flashcfg_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
-
- k->init = mv88w8618_flashcfg_init;
- dc->vmsd = &mv88w8618_flashcfg_vmsd;
-}
-
-static const TypeInfo mv88w8618_flashcfg_info = {
- .name = TYPE_MV88W8618_FLASHCFG,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(mv88w8618_flashcfg_state),
- .class_init = mv88w8618_flashcfg_class_init,
-};
-
-/* Misc register offsets */
-#define MP_MISC_BOARD_REVISION 0x18
-
-#define MP_BOARD_REVISION 0x31
-
-typedef struct {
- SysBusDevice parent_obj;
- MemoryRegion iomem;
-} MusicPalMiscState;
-
-#define TYPE_MUSICPAL_MISC "musicpal-misc"
-#define MUSICPAL_MISC(obj) \
- OBJECT_CHECK(MusicPalMiscState, (obj), TYPE_MUSICPAL_MISC)
-
-static uint64_t musicpal_misc_read(void *opaque, hwaddr offset,
- unsigned size)
-{
- switch (offset) {
- case MP_MISC_BOARD_REVISION:
- return MP_BOARD_REVISION;
-
- default:
- return 0;
- }
-}
-
-static void musicpal_misc_write(void *opaque, hwaddr offset,
- uint64_t value, unsigned size)
-{
-}
-
-static const MemoryRegionOps musicpal_misc_ops = {
- .read = musicpal_misc_read,
- .write = musicpal_misc_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static void musicpal_misc_init(Object *obj)
-{
- SysBusDevice *sd = SYS_BUS_DEVICE(obj);
- MusicPalMiscState *s = MUSICPAL_MISC(obj);
-
- memory_region_init_io(&s->iomem, OBJECT(s), &musicpal_misc_ops, NULL,
- "musicpal-misc", MP_MISC_SIZE);
- sysbus_init_mmio(sd, &s->iomem);
-}
-
-static const TypeInfo musicpal_misc_info = {
- .name = TYPE_MUSICPAL_MISC,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_init = musicpal_misc_init,
- .instance_size = sizeof(MusicPalMiscState),
-};
-
-/* WLAN register offsets */
-#define MP_WLAN_MAGIC1 0x11c
-#define MP_WLAN_MAGIC2 0x124
-
-static uint64_t mv88w8618_wlan_read(void *opaque, hwaddr offset,
- unsigned size)
-{
- switch (offset) {
- /* Workaround to allow loading the binary-only wlandrv.ko crap
- * from the original Freecom firmware. */
- case MP_WLAN_MAGIC1:
- return ~3;
- case MP_WLAN_MAGIC2:
- return -1;
-
- default:
- return 0;
- }
-}
-
-static void mv88w8618_wlan_write(void *opaque, hwaddr offset,
- uint64_t value, unsigned size)
-{
-}
-
-static const MemoryRegionOps mv88w8618_wlan_ops = {
- .read = mv88w8618_wlan_read,
- .write =mv88w8618_wlan_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static int mv88w8618_wlan_init(SysBusDevice *dev)
-{
- MemoryRegion *iomem = g_new(MemoryRegion, 1);
-
- memory_region_init_io(iomem, OBJECT(dev), &mv88w8618_wlan_ops, NULL,
- "musicpal-wlan", MP_WLAN_SIZE);
- sysbus_init_mmio(dev, iomem);
- return 0;
-}
-
-/* GPIO register offsets */
-#define MP_GPIO_OE_LO 0x008
-#define MP_GPIO_OUT_LO 0x00c
-#define MP_GPIO_IN_LO 0x010
-#define MP_GPIO_IER_LO 0x014
-#define MP_GPIO_IMR_LO 0x018
-#define MP_GPIO_ISR_LO 0x020
-#define MP_GPIO_OE_HI 0x508
-#define MP_GPIO_OUT_HI 0x50c
-#define MP_GPIO_IN_HI 0x510
-#define MP_GPIO_IER_HI 0x514
-#define MP_GPIO_IMR_HI 0x518
-#define MP_GPIO_ISR_HI 0x520
-
-/* GPIO bits & masks */
-#define MP_GPIO_LCD_BRIGHTNESS 0x00070000
-#define MP_GPIO_I2C_DATA_BIT 29
-#define MP_GPIO_I2C_CLOCK_BIT 30
-
-/* LCD brightness bits in GPIO_OE_HI */
-#define MP_OE_LCD_BRIGHTNESS 0x0007
-
-#define TYPE_MUSICPAL_GPIO "musicpal_gpio"
-#define MUSICPAL_GPIO(obj) \
- OBJECT_CHECK(musicpal_gpio_state, (obj), TYPE_MUSICPAL_GPIO)
-
-typedef struct musicpal_gpio_state {
- /*< private >*/
- SysBusDevice parent_obj;
- /*< public >*/
-
- MemoryRegion iomem;
- uint32_t lcd_brightness;
- uint32_t out_state;
- uint32_t in_state;
- uint32_t ier;
- uint32_t imr;
- uint32_t isr;
- qemu_irq irq;
- qemu_irq out[5]; /* 3 brightness out + 2 lcd (data and clock ) */
-} musicpal_gpio_state;
-
-static void musicpal_gpio_brightness_update(musicpal_gpio_state *s) {
- int i;
- uint32_t brightness;
-
- /* compute brightness ratio */
- switch (s->lcd_brightness) {
- case 0x00000007:
- brightness = 0;
- break;
-
- case 0x00020000:
- brightness = 1;
- break;
-
- case 0x00020001:
- brightness = 2;
- break;
-
- case 0x00040000:
- brightness = 3;
- break;
-
- case 0x00010006:
- brightness = 4;
- break;
-
- case 0x00020005:
- brightness = 5;
- break;
-
- case 0x00040003:
- brightness = 6;
- break;
-
- case 0x00030004:
- default:
- brightness = 7;
- }
-
- /* set lcd brightness GPIOs */
- for (i = 0; i <= 2; i++) {
- qemu_set_irq(s->out[i], (brightness >> i) & 1);
- }
-}
-
-static void musicpal_gpio_pin_event(void *opaque, int pin, int level)
-{
- musicpal_gpio_state *s = opaque;
- uint32_t mask = 1 << pin;
- uint32_t delta = level << pin;
- uint32_t old = s->in_state & mask;
-
- s->in_state &= ~mask;
- s->in_state |= delta;
-
- if ((old ^ delta) &&
- ((level && (s->imr & mask)) || (!level && (s->ier & mask)))) {
- s->isr = mask;
- qemu_irq_raise(s->irq);
- }
-}
-
-static uint64_t musicpal_gpio_read(void *opaque, hwaddr offset,
- unsigned size)
-{
- musicpal_gpio_state *s = opaque;
-
- switch (offset) {
- case MP_GPIO_OE_HI: /* used for LCD brightness control */
- return s->lcd_brightness & MP_OE_LCD_BRIGHTNESS;
-
- case MP_GPIO_OUT_LO:
- return s->out_state & 0xFFFF;
- case MP_GPIO_OUT_HI:
- return s->out_state >> 16;
-
- case MP_GPIO_IN_LO:
- return s->in_state & 0xFFFF;
- case MP_GPIO_IN_HI:
- return s->in_state >> 16;
-
- case MP_GPIO_IER_LO:
- return s->ier & 0xFFFF;
- case MP_GPIO_IER_HI:
- return s->ier >> 16;
-
- case MP_GPIO_IMR_LO:
- return s->imr & 0xFFFF;
- case MP_GPIO_IMR_HI:
- return s->imr >> 16;
-
- case MP_GPIO_ISR_LO:
- return s->isr & 0xFFFF;
- case MP_GPIO_ISR_HI:
- return s->isr >> 16;
-
- default:
- return 0;
- }
-}
-
-static void musicpal_gpio_write(void *opaque, hwaddr offset,
- uint64_t value, unsigned size)
-{
- musicpal_gpio_state *s = opaque;
- switch (offset) {
- case MP_GPIO_OE_HI: /* used for LCD brightness control */
- s->lcd_brightness = (s->lcd_brightness & MP_GPIO_LCD_BRIGHTNESS) |
- (value & MP_OE_LCD_BRIGHTNESS);
- musicpal_gpio_brightness_update(s);
- break;
-
- case MP_GPIO_OUT_LO:
- s->out_state = (s->out_state & 0xFFFF0000) | (value & 0xFFFF);
- break;
- case MP_GPIO_OUT_HI:
- s->out_state = (s->out_state & 0xFFFF) | (value << 16);
- s->lcd_brightness = (s->lcd_brightness & 0xFFFF) |
- (s->out_state & MP_GPIO_LCD_BRIGHTNESS);
- musicpal_gpio_brightness_update(s);
- qemu_set_irq(s->out[3], (s->out_state >> MP_GPIO_I2C_DATA_BIT) & 1);
- qemu_set_irq(s->out[4], (s->out_state >> MP_GPIO_I2C_CLOCK_BIT) & 1);
- break;
-
- case MP_GPIO_IER_LO:
- s->ier = (s->ier & 0xFFFF0000) | (value & 0xFFFF);
- break;
- case MP_GPIO_IER_HI:
- s->ier = (s->ier & 0xFFFF) | (value << 16);
- break;
-
- case MP_GPIO_IMR_LO:
- s->imr = (s->imr & 0xFFFF0000) | (value & 0xFFFF);
- break;
- case MP_GPIO_IMR_HI:
- s->imr = (s->imr & 0xFFFF) | (value << 16);
- break;
- }
-}
-
-static const MemoryRegionOps musicpal_gpio_ops = {
- .read = musicpal_gpio_read,
- .write = musicpal_gpio_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static void musicpal_gpio_reset(DeviceState *d)
-{
- musicpal_gpio_state *s = MUSICPAL_GPIO(d);
-
- s->lcd_brightness = 0;
- s->out_state = 0;
- s->in_state = 0xffffffff;
- s->ier = 0;
- s->imr = 0;
- s->isr = 0;
-}
-
-static int musicpal_gpio_init(SysBusDevice *sbd)
-{
- DeviceState *dev = DEVICE(sbd);
- musicpal_gpio_state *s = MUSICPAL_GPIO(dev);
-
- sysbus_init_irq(sbd, &s->irq);
-
- memory_region_init_io(&s->iomem, OBJECT(s), &musicpal_gpio_ops, s,
- "musicpal-gpio", MP_GPIO_SIZE);
- sysbus_init_mmio(sbd, &s->iomem);
-
- qdev_init_gpio_out(dev, s->out, ARRAY_SIZE(s->out));
-
- qdev_init_gpio_in(dev, musicpal_gpio_pin_event, 32);
-
- return 0;
-}
-
-static const VMStateDescription musicpal_gpio_vmsd = {
- .name = "musicpal_gpio",
- .version_id = 1,
- .minimum_version_id = 1,
- .fields = (VMStateField[]) {
- VMSTATE_UINT32(lcd_brightness, musicpal_gpio_state),
- VMSTATE_UINT32(out_state, musicpal_gpio_state),
- VMSTATE_UINT32(in_state, musicpal_gpio_state),
- VMSTATE_UINT32(ier, musicpal_gpio_state),
- VMSTATE_UINT32(imr, musicpal_gpio_state),
- VMSTATE_UINT32(isr, musicpal_gpio_state),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static void musicpal_gpio_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
-
- k->init = musicpal_gpio_init;
- dc->reset = musicpal_gpio_reset;
- dc->vmsd = &musicpal_gpio_vmsd;
-}
-
-static const TypeInfo musicpal_gpio_info = {
- .name = TYPE_MUSICPAL_GPIO,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(musicpal_gpio_state),
- .class_init = musicpal_gpio_class_init,
-};
-
-/* Keyboard codes & masks */
-#define KEY_RELEASED 0x80
-#define KEY_CODE 0x7f
-
-#define KEYCODE_TAB 0x0f
-#define KEYCODE_ENTER 0x1c
-#define KEYCODE_F 0x21
-#define KEYCODE_M 0x32
-
-#define KEYCODE_EXTENDED 0xe0
-#define KEYCODE_UP 0x48
-#define KEYCODE_DOWN 0x50
-#define KEYCODE_LEFT 0x4b
-#define KEYCODE_RIGHT 0x4d
-
-#define MP_KEY_WHEEL_VOL (1 << 0)
-#define MP_KEY_WHEEL_VOL_INV (1 << 1)
-#define MP_KEY_WHEEL_NAV (1 << 2)
-#define MP_KEY_WHEEL_NAV_INV (1 << 3)
-#define MP_KEY_BTN_FAVORITS (1 << 4)
-#define MP_KEY_BTN_MENU (1 << 5)
-#define MP_KEY_BTN_VOLUME (1 << 6)
-#define MP_KEY_BTN_NAVIGATION (1 << 7)
-
-#define TYPE_MUSICPAL_KEY "musicpal_key"
-#define MUSICPAL_KEY(obj) \
- OBJECT_CHECK(musicpal_key_state, (obj), TYPE_MUSICPAL_KEY)
-
-typedef struct musicpal_key_state {
- /*< private >*/
- SysBusDevice parent_obj;
- /*< public >*/
-
- MemoryRegion iomem;
- uint32_t kbd_extended;
- uint32_t pressed_keys;
- qemu_irq out[8];
-} musicpal_key_state;
-
-static void musicpal_key_event(void *opaque, int keycode)
-{
- musicpal_key_state *s = opaque;
- uint32_t event = 0;
- int i;
-
- if (keycode == KEYCODE_EXTENDED) {
- s->kbd_extended = 1;
- return;
- }
-
- if (s->kbd_extended) {
- switch (keycode & KEY_CODE) {
- case KEYCODE_UP:
- event = MP_KEY_WHEEL_NAV | MP_KEY_WHEEL_NAV_INV;
- break;
-
- case KEYCODE_DOWN:
- event = MP_KEY_WHEEL_NAV;
- break;
-
- case KEYCODE_LEFT:
- event = MP_KEY_WHEEL_VOL | MP_KEY_WHEEL_VOL_INV;
- break;
-
- case KEYCODE_RIGHT:
- event = MP_KEY_WHEEL_VOL;
- break;
- }
- } else {
- switch (keycode & KEY_CODE) {
- case KEYCODE_F:
- event = MP_KEY_BTN_FAVORITS;
- break;
-
- case KEYCODE_TAB:
- event = MP_KEY_BTN_VOLUME;
- break;
-
- case KEYCODE_ENTER:
- event = MP_KEY_BTN_NAVIGATION;
- break;
-
- case KEYCODE_M:
- event = MP_KEY_BTN_MENU;
- break;
- }
- /* Do not repeat already pressed buttons */
- if (!(keycode & KEY_RELEASED) && (s->pressed_keys & event)) {
- event = 0;
- }
- }
-
- if (event) {
- /* Raise GPIO pin first if repeating a key */
- if (!(keycode & KEY_RELEASED) && (s->pressed_keys & event)) {
- for (i = 0; i <= 7; i++) {
- if (event & (1 << i)) {
- qemu_set_irq(s->out[i], 1);
- }
- }
- }
- for (i = 0; i <= 7; i++) {
- if (event & (1 << i)) {
- qemu_set_irq(s->out[i], !!(keycode & KEY_RELEASED));
- }
- }
- if (keycode & KEY_RELEASED) {
- s->pressed_keys &= ~event;
- } else {
- s->pressed_keys |= event;
- }
- }
-
- s->kbd_extended = 0;
-}
-
-static int musicpal_key_init(SysBusDevice *sbd)
-{
- DeviceState *dev = DEVICE(sbd);
- musicpal_key_state *s = MUSICPAL_KEY(dev);
-
- memory_region_init(&s->iomem, OBJECT(s), "dummy", 0);
- sysbus_init_mmio(sbd, &s->iomem);
-
- s->kbd_extended = 0;
- s->pressed_keys = 0;
-
- qdev_init_gpio_out(dev, s->out, ARRAY_SIZE(s->out));
-
- qemu_add_kbd_event_handler(musicpal_key_event, s);
-
- return 0;
-}
-
-static const VMStateDescription musicpal_key_vmsd = {
- .name = "musicpal_key",
- .version_id = 1,
- .minimum_version_id = 1,
- .fields = (VMStateField[]) {
- VMSTATE_UINT32(kbd_extended, musicpal_key_state),
- VMSTATE_UINT32(pressed_keys, musicpal_key_state),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static void musicpal_key_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
-
- k->init = musicpal_key_init;
- dc->vmsd = &musicpal_key_vmsd;
-}
-
-static const TypeInfo musicpal_key_info = {
- .name = TYPE_MUSICPAL_KEY,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(musicpal_key_state),
- .class_init = musicpal_key_class_init,
-};
-
-static struct arm_boot_info musicpal_binfo = {
- .loader_start = 0x0,
- .board_id = 0x20e,
-};
-
-static void musicpal_init(MachineState *machine)
-{
- const char *cpu_model = machine->cpu_model;
- const char *kernel_filename = machine->kernel_filename;
- const char *kernel_cmdline = machine->kernel_cmdline;
- const char *initrd_filename = machine->initrd_filename;
- ARMCPU *cpu;
- qemu_irq pic[32];
- DeviceState *dev;
- DeviceState *i2c_dev;
- DeviceState *lcd_dev;
- DeviceState *key_dev;
- DeviceState *wm8750_dev;
- SysBusDevice *s;
- I2CBus *i2c;
- int i;
- unsigned long flash_size;
- DriveInfo *dinfo;
- MemoryRegion *address_space_mem = get_system_memory();
- MemoryRegion *ram = g_new(MemoryRegion, 1);
- MemoryRegion *sram = g_new(MemoryRegion, 1);
-
- if (!cpu_model) {
- cpu_model = "arm926";
- }
- cpu = cpu_arm_init(cpu_model);
- if (!cpu) {
- fprintf(stderr, "Unable to find CPU definition\n");
- exit(1);
- }
-
- /* For now we use a fixed - the original - RAM size */
- memory_region_allocate_system_memory(ram, NULL, "musicpal.ram",
- MP_RAM_DEFAULT_SIZE);
- memory_region_add_subregion(address_space_mem, 0, ram);
-
- memory_region_init_ram(sram, NULL, "musicpal.sram", MP_SRAM_SIZE,
- &error_fatal);
- vmstate_register_ram_global(sram);
- memory_region_add_subregion(address_space_mem, MP_SRAM_BASE, sram);
-
- dev = sysbus_create_simple(TYPE_MV88W8618_PIC, MP_PIC_BASE,
- qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ));
- for (i = 0; i < 32; i++) {
- pic[i] = qdev_get_gpio_in(dev, i);
- }
- sysbus_create_varargs(TYPE_MV88W8618_PIT, MP_PIT_BASE, pic[MP_TIMER1_IRQ],
- pic[MP_TIMER2_IRQ], pic[MP_TIMER3_IRQ],
- pic[MP_TIMER4_IRQ], NULL);
-
- if (serial_hds[0]) {
- serial_mm_init(address_space_mem, MP_UART1_BASE, 2, pic[MP_UART1_IRQ],
- 1825000, serial_hds[0], DEVICE_NATIVE_ENDIAN);
- }
- if (serial_hds[1]) {
- serial_mm_init(address_space_mem, MP_UART2_BASE, 2, pic[MP_UART2_IRQ],
- 1825000, serial_hds[1], DEVICE_NATIVE_ENDIAN);
- }
-
- /* Register flash */
- dinfo = drive_get(IF_PFLASH, 0, 0);
- if (dinfo) {
- BlockBackend *blk = blk_by_legacy_dinfo(dinfo);
-
- flash_size = blk_getlength(blk);
- if (flash_size != 8*1024*1024 && flash_size != 16*1024*1024 &&
- flash_size != 32*1024*1024) {
- fprintf(stderr, "Invalid flash image size\n");
- exit(1);
- }
-
- /*
- * The original U-Boot accesses the flash at 0xFE000000 instead of
- * 0xFF800000 (if there is 8 MB flash). So remap flash access if the
- * image is smaller than 32 MB.
- */
-#ifdef TARGET_WORDS_BIGENDIAN
- pflash_cfi02_register(0x100000000ULL-MP_FLASH_SIZE_MAX, NULL,
- "musicpal.flash", flash_size,
- blk, 0x10000, (flash_size + 0xffff) >> 16,
- MP_FLASH_SIZE_MAX / flash_size,
- 2, 0x00BF, 0x236D, 0x0000, 0x0000,
- 0x5555, 0x2AAA, 1);
-#else
- pflash_cfi02_register(0x100000000ULL-MP_FLASH_SIZE_MAX, NULL,
- "musicpal.flash", flash_size,
- blk, 0x10000, (flash_size + 0xffff) >> 16,
- MP_FLASH_SIZE_MAX / flash_size,
- 2, 0x00BF, 0x236D, 0x0000, 0x0000,
- 0x5555, 0x2AAA, 0);
-#endif
-
- }
- sysbus_create_simple(TYPE_MV88W8618_FLASHCFG, MP_FLASHCFG_BASE, NULL);
-
- qemu_check_nic_model(&nd_table[0], "mv88w8618");
- dev = qdev_create(NULL, TYPE_MV88W8618_ETH);
- qdev_set_nic_properties(dev, &nd_table[0]);
- qdev_init_nofail(dev);
- sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, MP_ETH_BASE);
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[MP_ETH_IRQ]);
-
- sysbus_create_simple("mv88w8618_wlan", MP_WLAN_BASE, NULL);
-
- sysbus_create_simple(TYPE_MUSICPAL_MISC, MP_MISC_BASE, NULL);
-
- dev = sysbus_create_simple(TYPE_MUSICPAL_GPIO, MP_GPIO_BASE,
- pic[MP_GPIO_IRQ]);
- i2c_dev = sysbus_create_simple("gpio_i2c", -1, NULL);
- i2c = (I2CBus *)qdev_get_child_bus(i2c_dev, "i2c");
-
- lcd_dev = sysbus_create_simple(TYPE_MUSICPAL_LCD, MP_LCD_BASE, NULL);
- key_dev = sysbus_create_simple(TYPE_MUSICPAL_KEY, -1, NULL);
-
- /* I2C read data */
- qdev_connect_gpio_out(i2c_dev, 0,
- qdev_get_gpio_in(dev, MP_GPIO_I2C_DATA_BIT));
- /* I2C data */
- qdev_connect_gpio_out(dev, 3, qdev_get_gpio_in(i2c_dev, 0));
- /* I2C clock */
- qdev_connect_gpio_out(dev, 4, qdev_get_gpio_in(i2c_dev, 1));
-
- for (i = 0; i < 3; i++) {
- qdev_connect_gpio_out(dev, i, qdev_get_gpio_in(lcd_dev, i));
- }
- for (i = 0; i < 4; i++) {
- qdev_connect_gpio_out(key_dev, i, qdev_get_gpio_in(dev, i + 8));
- }
- for (i = 4; i < 8; i++) {
- qdev_connect_gpio_out(key_dev, i, qdev_get_gpio_in(dev, i + 15));
- }
-
- wm8750_dev = i2c_create_slave(i2c, "wm8750", MP_WM_ADDR);
- dev = qdev_create(NULL, "mv88w8618_audio");
- s = SYS_BUS_DEVICE(dev);
- qdev_prop_set_ptr(dev, "wm8750", wm8750_dev);
- qdev_init_nofail(dev);
- sysbus_mmio_map(s, 0, MP_AUDIO_BASE);
- sysbus_connect_irq(s, 0, pic[MP_AUDIO_IRQ]);
-
- musicpal_binfo.ram_size = MP_RAM_DEFAULT_SIZE;
- musicpal_binfo.kernel_filename = kernel_filename;
- musicpal_binfo.kernel_cmdline = kernel_cmdline;
- musicpal_binfo.initrd_filename = initrd_filename;
- arm_load_kernel(cpu, &musicpal_binfo);
-}
-
-static void musicpal_machine_init(MachineClass *mc)
-{
- mc->desc = "Marvell 88w8618 / MusicPal (ARM926EJ-S)";
- mc->init = musicpal_init;
-}
-
-DEFINE_MACHINE("musicpal", musicpal_machine_init)
-
-static void mv88w8618_wlan_class_init(ObjectClass *klass, void *data)
-{
- SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
-
- sdc->init = mv88w8618_wlan_init;
-}
-
-static const TypeInfo mv88w8618_wlan_info = {
- .name = "mv88w8618_wlan",
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(SysBusDevice),
- .class_init = mv88w8618_wlan_class_init,
-};
-
-static void musicpal_register_types(void)
-{
- type_register_static(&mv88w8618_pic_info);
- type_register_static(&mv88w8618_pit_info);
- type_register_static(&mv88w8618_flashcfg_info);
- type_register_static(&mv88w8618_eth_info);
- type_register_static(&mv88w8618_wlan_info);
- type_register_static(&musicpal_lcd_info);
- type_register_static(&musicpal_gpio_info);
- type_register_static(&musicpal_key_info);
- type_register_static(&musicpal_misc_info);
-}
-
-type_init(musicpal_register_types)
diff --git a/qemu/hw/arm/netduino2.c b/qemu/hw/arm/netduino2.c
deleted file mode 100644
index 23d792837..000000000
--- a/qemu/hw/arm/netduino2.c
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Netduino 2 Machine Model
- *
- * Copyright (c) 2014 Alistair Francis <alistair@alistair23.me>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "hw/boards.h"
-#include "qemu/error-report.h"
-#include "hw/arm/stm32f205_soc.h"
-
-static void netduino2_init(MachineState *machine)
-{
- DeviceState *dev;
-
- dev = qdev_create(NULL, TYPE_STM32F205_SOC);
- if (machine->kernel_filename) {
- qdev_prop_set_string(dev, "kernel-filename", machine->kernel_filename);
- }
- qdev_prop_set_string(dev, "cpu-model", "cortex-m3");
- object_property_set_bool(OBJECT(dev), true, "realized", &error_fatal);
-}
-
-static void netduino2_machine_init(MachineClass *mc)
-{
- mc->desc = "Netduino 2 Machine";
- mc->init = netduino2_init;
-}
-
-DEFINE_MACHINE("netduino2", netduino2_machine_init)
diff --git a/qemu/hw/arm/nseries.c b/qemu/hw/arm/nseries.c
deleted file mode 100644
index 538250555..000000000
--- a/qemu/hw/arm/nseries.c
+++ /dev/null
@@ -1,1454 +0,0 @@
-/*
- * Nokia N-series internet tablets.
- *
- * Copyright (C) 2007 Nokia Corporation
- * Written by Andrzej Zaborowski <andrew@openedhand.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 or
- * (at your option) version 3 of the License.
- *
- * 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/>.
- */
-
-#include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "qemu/cutils.h"
-#include "sysemu/sysemu.h"
-#include "hw/arm/omap.h"
-#include "hw/arm/arm.h"
-#include "hw/irq.h"
-#include "ui/console.h"
-#include "hw/boards.h"
-#include "hw/i2c/i2c.h"
-#include "hw/devices.h"
-#include "hw/block/flash.h"
-#include "hw/hw.h"
-#include "hw/bt.h"
-#include "hw/loader.h"
-#include "sysemu/block-backend.h"
-#include "hw/sysbus.h"
-#include "exec/address-spaces.h"
-
-/* Nokia N8x0 support */
-struct n800_s {
- struct omap_mpu_state_s *mpu;
-
- struct rfbi_chip_s blizzard;
- struct {
- void *opaque;
- uint32_t (*txrx)(void *opaque, uint32_t value, int len);
- uWireSlave *chip;
- } ts;
-
- int keymap[0x80];
- DeviceState *kbd;
-
- DeviceState *usb;
- void *retu;
- void *tahvo;
- DeviceState *nand;
-};
-
-/* GPIO pins */
-#define N8X0_TUSB_ENABLE_GPIO 0
-#define N800_MMC2_WP_GPIO 8
-#define N800_UNKNOWN_GPIO0 9 /* out */
-#define N810_MMC2_VIOSD_GPIO 9
-#define N810_HEADSET_AMP_GPIO 10
-#define N800_CAM_TURN_GPIO 12
-#define N810_GPS_RESET_GPIO 12
-#define N800_BLIZZARD_POWERDOWN_GPIO 15
-#define N800_MMC1_WP_GPIO 23
-#define N810_MMC2_VSD_GPIO 23
-#define N8X0_ONENAND_GPIO 26
-#define N810_BLIZZARD_RESET_GPIO 30
-#define N800_UNKNOWN_GPIO2 53 /* out */
-#define N8X0_TUSB_INT_GPIO 58
-#define N8X0_BT_WKUP_GPIO 61
-#define N8X0_STI_GPIO 62
-#define N8X0_CBUS_SEL_GPIO 64
-#define N8X0_CBUS_DAT_GPIO 65
-#define N8X0_CBUS_CLK_GPIO 66
-#define N8X0_WLAN_IRQ_GPIO 87
-#define N8X0_BT_RESET_GPIO 92
-#define N8X0_TEA5761_CS_GPIO 93
-#define N800_UNKNOWN_GPIO 94
-#define N810_TSC_RESET_GPIO 94
-#define N800_CAM_ACT_GPIO 95
-#define N810_GPS_WAKEUP_GPIO 95
-#define N8X0_MMC_CS_GPIO 96
-#define N8X0_WLAN_PWR_GPIO 97
-#define N8X0_BT_HOST_WKUP_GPIO 98
-#define N810_SPEAKER_AMP_GPIO 101
-#define N810_KB_LOCK_GPIO 102
-#define N800_TSC_TS_GPIO 103
-#define N810_TSC_TS_GPIO 106
-#define N8X0_HEADPHONE_GPIO 107
-#define N8X0_RETU_GPIO 108
-#define N800_TSC_KP_IRQ_GPIO 109
-#define N810_KEYBOARD_GPIO 109
-#define N800_BAT_COVER_GPIO 110
-#define N810_SLIDE_GPIO 110
-#define N8X0_TAHVO_GPIO 111
-#define N800_UNKNOWN_GPIO4 112 /* out */
-#define N810_SLEEPX_LED_GPIO 112
-#define N800_TSC_RESET_GPIO 118 /* ? */
-#define N810_AIC33_RESET_GPIO 118
-#define N800_TSC_UNKNOWN_GPIO 119 /* out */
-#define N8X0_TMP105_GPIO 125
-
-/* Config */
-#define BT_UART 0
-#define XLDR_LL_UART 1
-
-/* Addresses on the I2C bus 0 */
-#define N810_TLV320AIC33_ADDR 0x18 /* Audio CODEC */
-#define N8X0_TCM825x_ADDR 0x29 /* Camera */
-#define N810_LP5521_ADDR 0x32 /* LEDs */
-#define N810_TSL2563_ADDR 0x3d /* Light sensor */
-#define N810_LM8323_ADDR 0x45 /* Keyboard */
-/* Addresses on the I2C bus 1 */
-#define N8X0_TMP105_ADDR 0x48 /* Temperature sensor */
-#define N8X0_MENELAUS_ADDR 0x72 /* Power management */
-
-/* Chipselects on GPMC NOR interface */
-#define N8X0_ONENAND_CS 0
-#define N8X0_USB_ASYNC_CS 1
-#define N8X0_USB_SYNC_CS 4
-
-#define N8X0_BD_ADDR 0x00, 0x1a, 0x89, 0x9e, 0x3e, 0x81
-
-static void n800_mmc_cs_cb(void *opaque, int line, int level)
-{
- /* TODO: this seems to actually be connected to the menelaus, to
- * which also both MMC slots connect. */
- omap_mmc_enable((struct omap_mmc_s *) opaque, !level);
-}
-
-static void n8x0_gpio_setup(struct n800_s *s)
-{
- qdev_connect_gpio_out(s->mpu->gpio, N8X0_MMC_CS_GPIO,
- qemu_allocate_irq(n800_mmc_cs_cb, s->mpu->mmc, 0));
- qemu_irq_lower(qdev_get_gpio_in(s->mpu->gpio, N800_BAT_COVER_GPIO));
-}
-
-#define MAEMO_CAL_HEADER(...) \
- 'C', 'o', 'n', 'F', 0x02, 0x00, 0x04, 0x00, \
- __VA_ARGS__, \
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
-static const uint8_t n8x0_cal_wlan_mac[] = {
- MAEMO_CAL_HEADER('w', 'l', 'a', 'n', '-', 'm', 'a', 'c')
- 0x1c, 0x00, 0x00, 0x00, 0x47, 0xd6, 0x69, 0xb3,
- 0x30, 0x08, 0xa0, 0x83, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00,
- 0x89, 0x00, 0x00, 0x00, 0x9e, 0x00, 0x00, 0x00,
- 0x5d, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00,
-};
-
-static const uint8_t n8x0_cal_bt_id[] = {
- MAEMO_CAL_HEADER('b', 't', '-', 'i', 'd', 0, 0, 0)
- 0x0a, 0x00, 0x00, 0x00, 0xa3, 0x4b, 0xf6, 0x96,
- 0xa8, 0xeb, 0xb2, 0x41, 0x00, 0x00, 0x00, 0x00,
- N8X0_BD_ADDR,
-};
-
-static void n8x0_nand_setup(struct n800_s *s)
-{
- char *otp_region;
- DriveInfo *dinfo;
-
- s->nand = qdev_create(NULL, "onenand");
- qdev_prop_set_uint16(s->nand, "manufacturer_id", NAND_MFR_SAMSUNG);
- /* Either 0x40 or 0x48 are OK for the device ID */
- qdev_prop_set_uint16(s->nand, "device_id", 0x48);
- qdev_prop_set_uint16(s->nand, "version_id", 0);
- qdev_prop_set_int32(s->nand, "shift", 1);
- dinfo = drive_get(IF_MTD, 0, 0);
- if (dinfo) {
- qdev_prop_set_drive(s->nand, "drive", blk_by_legacy_dinfo(dinfo),
- &error_fatal);
- }
- qdev_init_nofail(s->nand);
- sysbus_connect_irq(SYS_BUS_DEVICE(s->nand), 0,
- qdev_get_gpio_in(s->mpu->gpio, N8X0_ONENAND_GPIO));
- omap_gpmc_attach(s->mpu->gpmc, N8X0_ONENAND_CS,
- sysbus_mmio_get_region(SYS_BUS_DEVICE(s->nand), 0));
- otp_region = onenand_raw_otp(s->nand);
-
- memcpy(otp_region + 0x000, n8x0_cal_wlan_mac, sizeof(n8x0_cal_wlan_mac));
- memcpy(otp_region + 0x800, n8x0_cal_bt_id, sizeof(n8x0_cal_bt_id));
- /* XXX: in theory should also update the OOB for both pages */
-}
-
-static qemu_irq n8x0_system_powerdown;
-
-static void n8x0_powerdown_req(Notifier *n, void *opaque)
-{
- qemu_irq_raise(n8x0_system_powerdown);
-}
-
-static Notifier n8x0_system_powerdown_notifier = {
- .notify = n8x0_powerdown_req
-};
-
-static void n8x0_i2c_setup(struct n800_s *s)
-{
- DeviceState *dev;
- qemu_irq tmp_irq = qdev_get_gpio_in(s->mpu->gpio, N8X0_TMP105_GPIO);
- I2CBus *i2c = omap_i2c_bus(s->mpu->i2c[0]);
-
- /* Attach a menelaus PM chip */
- dev = i2c_create_slave(i2c, "twl92230", N8X0_MENELAUS_ADDR);
- qdev_connect_gpio_out(dev, 3,
- qdev_get_gpio_in(s->mpu->ih[0],
- OMAP_INT_24XX_SYS_NIRQ));
-
- n8x0_system_powerdown = qdev_get_gpio_in(dev, 3);
- qemu_register_powerdown_notifier(&n8x0_system_powerdown_notifier);
-
- /* Attach a TMP105 PM chip (A0 wired to ground) */
- dev = i2c_create_slave(i2c, "tmp105", N8X0_TMP105_ADDR);
- qdev_connect_gpio_out(dev, 0, tmp_irq);
-}
-
-/* Touchscreen and keypad controller */
-static MouseTransformInfo n800_pointercal = {
- .x = 800,
- .y = 480,
- .a = { 14560, -68, -3455208, -39, -9621, 35152972, 65536 },
-};
-
-static MouseTransformInfo n810_pointercal = {
- .x = 800,
- .y = 480,
- .a = { 15041, 148, -4731056, 171, -10238, 35933380, 65536 },
-};
-
-#define RETU_KEYCODE 61 /* F3 */
-
-static void n800_key_event(void *opaque, int keycode)
-{
- struct n800_s *s = (struct n800_s *) opaque;
- int code = s->keymap[keycode & 0x7f];
-
- if (code == -1) {
- if ((keycode & 0x7f) == RETU_KEYCODE) {
- retu_key_event(s->retu, !(keycode & 0x80));
- }
- return;
- }
-
- tsc210x_key_event(s->ts.chip, code, !(keycode & 0x80));
-}
-
-static const int n800_keys[16] = {
- -1,
- 72, /* Up */
- 63, /* Home (F5) */
- -1,
- 75, /* Left */
- 28, /* Enter */
- 77, /* Right */
- -1,
- 1, /* Cycle (ESC) */
- 80, /* Down */
- 62, /* Menu (F4) */
- -1,
- 66, /* Zoom- (F8) */
- 64, /* FullScreen (F6) */
- 65, /* Zoom+ (F7) */
- -1,
-};
-
-static void n800_tsc_kbd_setup(struct n800_s *s)
-{
- int i;
-
- /* XXX: are the three pins inverted inside the chip between the
- * tsc and the cpu (N4111)? */
- qemu_irq penirq = NULL; /* NC */
- qemu_irq kbirq = qdev_get_gpio_in(s->mpu->gpio, N800_TSC_KP_IRQ_GPIO);
- qemu_irq dav = qdev_get_gpio_in(s->mpu->gpio, N800_TSC_TS_GPIO);
-
- s->ts.chip = tsc2301_init(penirq, kbirq, dav);
- s->ts.opaque = s->ts.chip->opaque;
- s->ts.txrx = tsc210x_txrx;
-
- for (i = 0; i < 0x80; i++) {
- s->keymap[i] = -1;
- }
- for (i = 0; i < 0x10; i++) {
- if (n800_keys[i] >= 0) {
- s->keymap[n800_keys[i]] = i;
- }
- }
-
- qemu_add_kbd_event_handler(n800_key_event, s);
-
- tsc210x_set_transform(s->ts.chip, &n800_pointercal);
-}
-
-static void n810_tsc_setup(struct n800_s *s)
-{
- qemu_irq pintdav = qdev_get_gpio_in(s->mpu->gpio, N810_TSC_TS_GPIO);
-
- s->ts.opaque = tsc2005_init(pintdav);
- s->ts.txrx = tsc2005_txrx;
-
- tsc2005_set_transform(s->ts.opaque, &n810_pointercal);
-}
-
-/* N810 Keyboard controller */
-static void n810_key_event(void *opaque, int keycode)
-{
- struct n800_s *s = (struct n800_s *) opaque;
- int code = s->keymap[keycode & 0x7f];
-
- if (code == -1) {
- if ((keycode & 0x7f) == RETU_KEYCODE) {
- retu_key_event(s->retu, !(keycode & 0x80));
- }
- return;
- }
-
- lm832x_key_event(s->kbd, code, !(keycode & 0x80));
-}
-
-#define M 0
-
-static int n810_keys[0x80] = {
- [0x01] = 16, /* Q */
- [0x02] = 37, /* K */
- [0x03] = 24, /* O */
- [0x04] = 25, /* P */
- [0x05] = 14, /* Backspace */
- [0x06] = 30, /* A */
- [0x07] = 31, /* S */
- [0x08] = 32, /* D */
- [0x09] = 33, /* F */
- [0x0a] = 34, /* G */
- [0x0b] = 35, /* H */
- [0x0c] = 36, /* J */
-
- [0x11] = 17, /* W */
- [0x12] = 62, /* Menu (F4) */
- [0x13] = 38, /* L */
- [0x14] = 40, /* ' (Apostrophe) */
- [0x16] = 44, /* Z */
- [0x17] = 45, /* X */
- [0x18] = 46, /* C */
- [0x19] = 47, /* V */
- [0x1a] = 48, /* B */
- [0x1b] = 49, /* N */
- [0x1c] = 42, /* Shift (Left shift) */
- [0x1f] = 65, /* Zoom+ (F7) */
-
- [0x21] = 18, /* E */
- [0x22] = 39, /* ; (Semicolon) */
- [0x23] = 12, /* - (Minus) */
- [0x24] = 13, /* = (Equal) */
- [0x2b] = 56, /* Fn (Left Alt) */
- [0x2c] = 50, /* M */
- [0x2f] = 66, /* Zoom- (F8) */
-
- [0x31] = 19, /* R */
- [0x32] = 29 | M, /* Right Ctrl */
- [0x34] = 57, /* Space */
- [0x35] = 51, /* , (Comma) */
- [0x37] = 72 | M, /* Up */
- [0x3c] = 82 | M, /* Compose (Insert) */
- [0x3f] = 64, /* FullScreen (F6) */
-
- [0x41] = 20, /* T */
- [0x44] = 52, /* . (Dot) */
- [0x46] = 77 | M, /* Right */
- [0x4f] = 63, /* Home (F5) */
- [0x51] = 21, /* Y */
- [0x53] = 80 | M, /* Down */
- [0x55] = 28, /* Enter */
- [0x5f] = 1, /* Cycle (ESC) */
-
- [0x61] = 22, /* U */
- [0x64] = 75 | M, /* Left */
-
- [0x71] = 23, /* I */
-#if 0
- [0x75] = 28 | M, /* KP Enter (KP Enter) */
-#else
- [0x75] = 15, /* KP Enter (Tab) */
-#endif
-};
-
-#undef M
-
-static void n810_kbd_setup(struct n800_s *s)
-{
- qemu_irq kbd_irq = qdev_get_gpio_in(s->mpu->gpio, N810_KEYBOARD_GPIO);
- int i;
-
- for (i = 0; i < 0x80; i++) {
- s->keymap[i] = -1;
- }
- for (i = 0; i < 0x80; i++) {
- if (n810_keys[i] > 0) {
- s->keymap[n810_keys[i]] = i;
- }
- }
-
- qemu_add_kbd_event_handler(n810_key_event, s);
-
- /* Attach the LM8322 keyboard to the I2C bus,
- * should happen in n8x0_i2c_setup and s->kbd be initialised here. */
- s->kbd = i2c_create_slave(omap_i2c_bus(s->mpu->i2c[0]),
- "lm8323", N810_LM8323_ADDR);
- qdev_connect_gpio_out(s->kbd, 0, kbd_irq);
-}
-
-/* LCD MIPI DBI-C controller (URAL) */
-struct mipid_s {
- int resp[4];
- int param[4];
- int p;
- int pm;
- int cmd;
-
- int sleep;
- int booster;
- int te;
- int selfcheck;
- int partial;
- int normal;
- int vscr;
- int invert;
- int onoff;
- int gamma;
- uint32_t id;
-};
-
-static void mipid_reset(struct mipid_s *s)
-{
- s->pm = 0;
- s->cmd = 0;
-
- s->sleep = 1;
- s->booster = 0;
- s->selfcheck =
- (1 << 7) | /* Register loading OK. */
- (1 << 5) | /* The chip is attached. */
- (1 << 4); /* Display glass still in one piece. */
- s->te = 0;
- s->partial = 0;
- s->normal = 1;
- s->vscr = 0;
- s->invert = 0;
- s->onoff = 1;
- s->gamma = 0;
-}
-
-static uint32_t mipid_txrx(void *opaque, uint32_t cmd, int len)
-{
- struct mipid_s *s = (struct mipid_s *) opaque;
- uint8_t ret;
-
- if (len > 9) {
- hw_error("%s: FIXME: bad SPI word width %i\n", __FUNCTION__, len);
- }
-
- if (s->p >= ARRAY_SIZE(s->resp)) {
- ret = 0;
- } else {
- ret = s->resp[s->p++];
- }
- if (s->pm-- > 0) {
- s->param[s->pm] = cmd;
- } else {
- s->cmd = cmd;
- }
-
- switch (s->cmd) {
- case 0x00: /* NOP */
- break;
-
- case 0x01: /* SWRESET */
- mipid_reset(s);
- break;
-
- case 0x02: /* BSTROFF */
- s->booster = 0;
- break;
- case 0x03: /* BSTRON */
- s->booster = 1;
- break;
-
- case 0x04: /* RDDID */
- s->p = 0;
- s->resp[0] = (s->id >> 16) & 0xff;
- s->resp[1] = (s->id >> 8) & 0xff;
- s->resp[2] = (s->id >> 0) & 0xff;
- break;
-
- case 0x06: /* RD_RED */
- case 0x07: /* RD_GREEN */
- /* XXX the bootloader sometimes issues RD_BLUE meaning RDDID so
- * for the bootloader one needs to change this. */
- case 0x08: /* RD_BLUE */
- s->p = 0;
- /* TODO: return first pixel components */
- s->resp[0] = 0x01;
- break;
-
- case 0x09: /* RDDST */
- s->p = 0;
- s->resp[0] = s->booster << 7;
- s->resp[1] = (5 << 4) | (s->partial << 2) |
- (s->sleep << 1) | s->normal;
- s->resp[2] = (s->vscr << 7) | (s->invert << 5) |
- (s->onoff << 2) | (s->te << 1) | (s->gamma >> 2);
- s->resp[3] = s->gamma << 6;
- break;
-
- case 0x0a: /* RDDPM */
- s->p = 0;
- s->resp[0] = (s->onoff << 2) | (s->normal << 3) | (s->sleep << 4) |
- (s->partial << 5) | (s->sleep << 6) | (s->booster << 7);
- break;
- case 0x0b: /* RDDMADCTR */
- s->p = 0;
- s->resp[0] = 0;
- break;
- case 0x0c: /* RDDCOLMOD */
- s->p = 0;
- s->resp[0] = 5; /* 65K colours */
- break;
- case 0x0d: /* RDDIM */
- s->p = 0;
- s->resp[0] = (s->invert << 5) | (s->vscr << 7) | s->gamma;
- break;
- case 0x0e: /* RDDSM */
- s->p = 0;
- s->resp[0] = s->te << 7;
- break;
- case 0x0f: /* RDDSDR */
- s->p = 0;
- s->resp[0] = s->selfcheck;
- break;
-
- case 0x10: /* SLPIN */
- s->sleep = 1;
- break;
- case 0x11: /* SLPOUT */
- s->sleep = 0;
- s->selfcheck ^= 1 << 6; /* POFF self-diagnosis Ok */
- break;
-
- case 0x12: /* PTLON */
- s->partial = 1;
- s->normal = 0;
- s->vscr = 0;
- break;
- case 0x13: /* NORON */
- s->partial = 0;
- s->normal = 1;
- s->vscr = 0;
- break;
-
- case 0x20: /* INVOFF */
- s->invert = 0;
- break;
- case 0x21: /* INVON */
- s->invert = 1;
- break;
-
- case 0x22: /* APOFF */
- case 0x23: /* APON */
- goto bad_cmd;
-
- case 0x25: /* WRCNTR */
- if (s->pm < 0) {
- s->pm = 1;
- }
- goto bad_cmd;
-
- case 0x26: /* GAMSET */
- if (!s->pm) {
- s->gamma = ctz32(s->param[0] & 0xf);
- if (s->gamma == 32) {
- s->gamma = -1; /* XXX: should this be 0? */
- }
- } else if (s->pm < 0) {
- s->pm = 1;
- }
- break;
-
- case 0x28: /* DISPOFF */
- s->onoff = 0;
- break;
- case 0x29: /* DISPON */
- s->onoff = 1;
- break;
-
- case 0x2a: /* CASET */
- case 0x2b: /* RASET */
- case 0x2c: /* RAMWR */
- case 0x2d: /* RGBSET */
- case 0x2e: /* RAMRD */
- case 0x30: /* PTLAR */
- case 0x33: /* SCRLAR */
- goto bad_cmd;
-
- case 0x34: /* TEOFF */
- s->te = 0;
- break;
- case 0x35: /* TEON */
- if (!s->pm) {
- s->te = 1;
- } else if (s->pm < 0) {
- s->pm = 1;
- }
- break;
-
- case 0x36: /* MADCTR */
- goto bad_cmd;
-
- case 0x37: /* VSCSAD */
- s->partial = 0;
- s->normal = 0;
- s->vscr = 1;
- break;
-
- case 0x38: /* IDMOFF */
- case 0x39: /* IDMON */
- case 0x3a: /* COLMOD */
- goto bad_cmd;
-
- case 0xb0: /* CLKINT / DISCTL */
- case 0xb1: /* CLKEXT */
- if (s->pm < 0) {
- s->pm = 2;
- }
- break;
-
- case 0xb4: /* FRMSEL */
- break;
-
- case 0xb5: /* FRM8SEL */
- case 0xb6: /* TMPRNG / INIESC */
- case 0xb7: /* TMPHIS / NOP2 */
- case 0xb8: /* TMPREAD / MADCTL */
- case 0xba: /* DISTCTR */
- case 0xbb: /* EPVOL */
- goto bad_cmd;
-
- case 0xbd: /* Unknown */
- s->p = 0;
- s->resp[0] = 0;
- s->resp[1] = 1;
- break;
-
- case 0xc2: /* IFMOD */
- if (s->pm < 0) {
- s->pm = 2;
- }
- break;
-
- case 0xc6: /* PWRCTL */
- case 0xc7: /* PPWRCTL */
- case 0xd0: /* EPWROUT */
- case 0xd1: /* EPWRIN */
- case 0xd4: /* RDEV */
- case 0xd5: /* RDRR */
- goto bad_cmd;
-
- case 0xda: /* RDID1 */
- s->p = 0;
- s->resp[0] = (s->id >> 16) & 0xff;
- break;
- case 0xdb: /* RDID2 */
- s->p = 0;
- s->resp[0] = (s->id >> 8) & 0xff;
- break;
- case 0xdc: /* RDID3 */
- s->p = 0;
- s->resp[0] = (s->id >> 0) & 0xff;
- break;
-
- default:
- bad_cmd:
- qemu_log_mask(LOG_GUEST_ERROR,
- "%s: unknown command %02x\n", __func__, s->cmd);
- break;
- }
-
- return ret;
-}
-
-static void *mipid_init(void)
-{
- struct mipid_s *s = (struct mipid_s *) g_malloc0(sizeof(*s));
-
- s->id = 0x838f03;
- mipid_reset(s);
-
- return s;
-}
-
-static void n8x0_spi_setup(struct n800_s *s)
-{
- void *tsc = s->ts.opaque;
- void *mipid = mipid_init();
-
- omap_mcspi_attach(s->mpu->mcspi[0], s->ts.txrx, tsc, 0);
- omap_mcspi_attach(s->mpu->mcspi[0], mipid_txrx, mipid, 1);
-}
-
-/* This task is normally performed by the bootloader. If we're loading
- * a kernel directly, we need to enable the Blizzard ourselves. */
-static void n800_dss_init(struct rfbi_chip_s *chip)
-{
- uint8_t *fb_blank;
-
- chip->write(chip->opaque, 0, 0x2a); /* LCD Width register */
- chip->write(chip->opaque, 1, 0x64);
- chip->write(chip->opaque, 0, 0x2c); /* LCD HNDP register */
- chip->write(chip->opaque, 1, 0x1e);
- chip->write(chip->opaque, 0, 0x2e); /* LCD Height 0 register */
- chip->write(chip->opaque, 1, 0xe0);
- chip->write(chip->opaque, 0, 0x30); /* LCD Height 1 register */
- chip->write(chip->opaque, 1, 0x01);
- chip->write(chip->opaque, 0, 0x32); /* LCD VNDP register */
- chip->write(chip->opaque, 1, 0x06);
- chip->write(chip->opaque, 0, 0x68); /* Display Mode register */
- chip->write(chip->opaque, 1, 1); /* Enable bit */
-
- chip->write(chip->opaque, 0, 0x6c);
- chip->write(chip->opaque, 1, 0x00); /* Input X Start Position */
- chip->write(chip->opaque, 1, 0x00); /* Input X Start Position */
- chip->write(chip->opaque, 1, 0x00); /* Input Y Start Position */
- chip->write(chip->opaque, 1, 0x00); /* Input Y Start Position */
- chip->write(chip->opaque, 1, 0x1f); /* Input X End Position */
- chip->write(chip->opaque, 1, 0x03); /* Input X End Position */
- chip->write(chip->opaque, 1, 0xdf); /* Input Y End Position */
- chip->write(chip->opaque, 1, 0x01); /* Input Y End Position */
- chip->write(chip->opaque, 1, 0x00); /* Output X Start Position */
- chip->write(chip->opaque, 1, 0x00); /* Output X Start Position */
- chip->write(chip->opaque, 1, 0x00); /* Output Y Start Position */
- chip->write(chip->opaque, 1, 0x00); /* Output Y Start Position */
- chip->write(chip->opaque, 1, 0x1f); /* Output X End Position */
- chip->write(chip->opaque, 1, 0x03); /* Output X End Position */
- chip->write(chip->opaque, 1, 0xdf); /* Output Y End Position */
- chip->write(chip->opaque, 1, 0x01); /* Output Y End Position */
- chip->write(chip->opaque, 1, 0x01); /* Input Data Format */
- chip->write(chip->opaque, 1, 0x01); /* Data Source Select */
-
- fb_blank = memset(g_malloc(800 * 480 * 2), 0xff, 800 * 480 * 2);
- /* Display Memory Data Port */
- chip->block(chip->opaque, 1, fb_blank, 800 * 480 * 2, 800);
- g_free(fb_blank);
-}
-
-static void n8x0_dss_setup(struct n800_s *s)
-{
- s->blizzard.opaque = s1d13745_init(NULL);
- s->blizzard.block = s1d13745_write_block;
- s->blizzard.write = s1d13745_write;
- s->blizzard.read = s1d13745_read;
-
- omap_rfbi_attach(s->mpu->dss, 0, &s->blizzard);
-}
-
-static void n8x0_cbus_setup(struct n800_s *s)
-{
- qemu_irq dat_out = qdev_get_gpio_in(s->mpu->gpio, N8X0_CBUS_DAT_GPIO);
- qemu_irq retu_irq = qdev_get_gpio_in(s->mpu->gpio, N8X0_RETU_GPIO);
- qemu_irq tahvo_irq = qdev_get_gpio_in(s->mpu->gpio, N8X0_TAHVO_GPIO);
-
- CBus *cbus = cbus_init(dat_out);
-
- qdev_connect_gpio_out(s->mpu->gpio, N8X0_CBUS_CLK_GPIO, cbus->clk);
- qdev_connect_gpio_out(s->mpu->gpio, N8X0_CBUS_DAT_GPIO, cbus->dat);
- qdev_connect_gpio_out(s->mpu->gpio, N8X0_CBUS_SEL_GPIO, cbus->sel);
-
- cbus_attach(cbus, s->retu = retu_init(retu_irq, 1));
- cbus_attach(cbus, s->tahvo = tahvo_init(tahvo_irq, 1));
-}
-
-static void n8x0_uart_setup(struct n800_s *s)
-{
- CharDriverState *radio = uart_hci_init(
- qdev_get_gpio_in(s->mpu->gpio, N8X0_BT_HOST_WKUP_GPIO));
-
- qdev_connect_gpio_out(s->mpu->gpio, N8X0_BT_RESET_GPIO,
- csrhci_pins_get(radio)[csrhci_pin_reset]);
- qdev_connect_gpio_out(s->mpu->gpio, N8X0_BT_WKUP_GPIO,
- csrhci_pins_get(radio)[csrhci_pin_wakeup]);
-
- omap_uart_attach(s->mpu->uart[BT_UART], radio);
-}
-
-static void n8x0_usb_setup(struct n800_s *s)
-{
- SysBusDevice *dev;
- s->usb = qdev_create(NULL, "tusb6010");
- dev = SYS_BUS_DEVICE(s->usb);
- qdev_init_nofail(s->usb);
- sysbus_connect_irq(dev, 0,
- qdev_get_gpio_in(s->mpu->gpio, N8X0_TUSB_INT_GPIO));
- /* Using the NOR interface */
- omap_gpmc_attach(s->mpu->gpmc, N8X0_USB_ASYNC_CS,
- sysbus_mmio_get_region(dev, 0));
- omap_gpmc_attach(s->mpu->gpmc, N8X0_USB_SYNC_CS,
- sysbus_mmio_get_region(dev, 1));
- qdev_connect_gpio_out(s->mpu->gpio, N8X0_TUSB_ENABLE_GPIO,
- qdev_get_gpio_in(s->usb, 0)); /* tusb_pwr */
-}
-
-/* Setup done before the main bootloader starts by some early setup code
- * - used when we want to run the main bootloader in emulation. This
- * isn't documented. */
-static uint32_t n800_pinout[104] = {
- 0x080f00d8, 0x00d40808, 0x03080808, 0x080800d0,
- 0x00dc0808, 0x0b0f0f00, 0x080800b4, 0x00c00808,
- 0x08080808, 0x180800c4, 0x00b80000, 0x08080808,
- 0x080800bc, 0x00cc0808, 0x08081818, 0x18180128,
- 0x01241800, 0x18181818, 0x000000f0, 0x01300000,
- 0x00001b0b, 0x1b0f0138, 0x00e0181b, 0x1b031b0b,
- 0x180f0078, 0x00740018, 0x0f0f0f1a, 0x00000080,
- 0x007c0000, 0x00000000, 0x00000088, 0x00840000,
- 0x00000000, 0x00000094, 0x00980300, 0x0f180003,
- 0x0000008c, 0x00900f0f, 0x0f0f1b00, 0x0f00009c,
- 0x01140000, 0x1b1b0f18, 0x0818013c, 0x01400008,
- 0x00001818, 0x000b0110, 0x010c1800, 0x0b030b0f,
- 0x181800f4, 0x00f81818, 0x00000018, 0x000000fc,
- 0x00401808, 0x00000000, 0x0f1b0030, 0x003c0008,
- 0x00000000, 0x00000038, 0x00340000, 0x00000000,
- 0x1a080070, 0x00641a1a, 0x08080808, 0x08080060,
- 0x005c0808, 0x08080808, 0x08080058, 0x00540808,
- 0x08080808, 0x0808006c, 0x00680808, 0x08080808,
- 0x000000a8, 0x00b00000, 0x08080808, 0x000000a0,
- 0x00a40000, 0x00000000, 0x08ff0050, 0x004c0808,
- 0xffffffff, 0xffff0048, 0x0044ffff, 0xffffffff,
- 0x000000ac, 0x01040800, 0x08080b0f, 0x18180100,
- 0x01081818, 0x0b0b1808, 0x1a0300e4, 0x012c0b1a,
- 0x02020018, 0x0b000134, 0x011c0800, 0x0b1b1b00,
- 0x0f0000c8, 0x00ec181b, 0x000f0f02, 0x00180118,
- 0x01200000, 0x0f0b1b1b, 0x0f0200e8, 0x0000020b,
-};
-
-static void n800_setup_nolo_tags(void *sram_base)
-{
- int i;
- uint32_t *p = sram_base + 0x8000;
- uint32_t *v = sram_base + 0xa000;
-
- memset(p, 0, 0x3000);
-
- strcpy((void *) (p + 0), "QEMU N800");
-
- strcpy((void *) (p + 8), "F5");
-
- stl_p(p + 10, 0x04f70000);
- strcpy((void *) (p + 9), "RX-34");
-
- /* RAM size in MB? */
- stl_p(p + 12, 0x80);
-
- /* Pointer to the list of tags */
- stl_p(p + 13, OMAP2_SRAM_BASE + 0x9000);
-
- /* The NOLO tags start here */
- p = sram_base + 0x9000;
-#define ADD_TAG(tag, len) \
- stw_p((uint16_t *) p + 0, tag); \
- stw_p((uint16_t *) p + 1, len); p++; \
- stl_p(p++, OMAP2_SRAM_BASE | (((void *) v - sram_base) & 0xffff));
-
- /* OMAP STI console? Pin out settings? */
- ADD_TAG(0x6e01, 414);
- for (i = 0; i < ARRAY_SIZE(n800_pinout); i++) {
- stl_p(v++, n800_pinout[i]);
- }
-
- /* Kernel memsize? */
- ADD_TAG(0x6e05, 1);
- stl_p(v++, 2);
-
- /* NOLO serial console */
- ADD_TAG(0x6e02, 4);
- stl_p(v++, XLDR_LL_UART); /* UART number (1 - 3) */
-
-#if 0
- /* CBUS settings (Retu/AVilma) */
- ADD_TAG(0x6e03, 6);
- stw_p((uint16_t *) v + 0, 65); /* CBUS GPIO0 */
- stw_p((uint16_t *) v + 1, 66); /* CBUS GPIO1 */
- stw_p((uint16_t *) v + 2, 64); /* CBUS GPIO2 */
- v += 2;
-#endif
-
- /* Nokia ASIC BB5 (Retu/Tahvo) */
- ADD_TAG(0x6e0a, 4);
- stw_p((uint16_t *) v + 0, 111); /* "Retu" interrupt GPIO */
- stw_p((uint16_t *) v + 1, 108); /* "Tahvo" interrupt GPIO */
- v++;
-
- /* LCD console? */
- ADD_TAG(0x6e04, 4);
- stw_p((uint16_t *) v + 0, 30); /* ??? */
- stw_p((uint16_t *) v + 1, 24); /* ??? */
- v++;
-
-#if 0
- /* LCD settings */
- ADD_TAG(0x6e06, 2);
- stw_p((uint16_t *) (v++), 15); /* ??? */
-#endif
-
- /* I^2C (Menelaus) */
- ADD_TAG(0x6e07, 4);
- stl_p(v++, 0x00720000); /* ??? */
-
- /* Unknown */
- ADD_TAG(0x6e0b, 6);
- stw_p((uint16_t *) v + 0, 94); /* ??? */
- stw_p((uint16_t *) v + 1, 23); /* ??? */
- stw_p((uint16_t *) v + 2, 0); /* ??? */
- v += 2;
-
- /* OMAP gpio switch info */
- ADD_TAG(0x6e0c, 80);
- strcpy((void *) v, "bat_cover"); v += 3;
- stw_p((uint16_t *) v + 0, 110); /* GPIO num ??? */
- stw_p((uint16_t *) v + 1, 1); /* GPIO num ??? */
- v += 2;
- strcpy((void *) v, "cam_act"); v += 3;
- stw_p((uint16_t *) v + 0, 95); /* GPIO num ??? */
- stw_p((uint16_t *) v + 1, 32); /* GPIO num ??? */
- v += 2;
- strcpy((void *) v, "cam_turn"); v += 3;
- stw_p((uint16_t *) v + 0, 12); /* GPIO num ??? */
- stw_p((uint16_t *) v + 1, 33); /* GPIO num ??? */
- v += 2;
- strcpy((void *) v, "headphone"); v += 3;
- stw_p((uint16_t *) v + 0, 107); /* GPIO num ??? */
- stw_p((uint16_t *) v + 1, 17); /* GPIO num ??? */
- v += 2;
-
- /* Bluetooth */
- ADD_TAG(0x6e0e, 12);
- stl_p(v++, 0x5c623d01); /* ??? */
- stl_p(v++, 0x00000201); /* ??? */
- stl_p(v++, 0x00000000); /* ??? */
-
- /* CX3110x WLAN settings */
- ADD_TAG(0x6e0f, 8);
- stl_p(v++, 0x00610025); /* ??? */
- stl_p(v++, 0xffff0057); /* ??? */
-
- /* MMC host settings */
- ADD_TAG(0x6e10, 12);
- stl_p(v++, 0xffff000f); /* ??? */
- stl_p(v++, 0xffffffff); /* ??? */
- stl_p(v++, 0x00000060); /* ??? */
-
- /* OneNAND chip select */
- ADD_TAG(0x6e11, 10);
- stl_p(v++, 0x00000401); /* ??? */
- stl_p(v++, 0x0002003a); /* ??? */
- stl_p(v++, 0x00000002); /* ??? */
-
- /* TEA5761 sensor settings */
- ADD_TAG(0x6e12, 2);
- stl_p(v++, 93); /* GPIO num ??? */
-
-#if 0
- /* Unknown tag */
- ADD_TAG(6e09, 0);
-
- /* Kernel UART / console */
- ADD_TAG(6e12, 0);
-#endif
-
- /* End of the list */
- stl_p(p++, 0x00000000);
- stl_p(p++, 0x00000000);
-}
-
-/* This task is normally performed by the bootloader. If we're loading
- * a kernel directly, we need to set up GPMC mappings ourselves. */
-static void n800_gpmc_init(struct n800_s *s)
-{
- uint32_t config7 =
- (0xf << 8) | /* MASKADDRESS */
- (1 << 6) | /* CSVALID */
- (4 << 0); /* BASEADDRESS */
-
- cpu_physical_memory_write(0x6800a078, /* GPMC_CONFIG7_0 */
- &config7, sizeof(config7));
-}
-
-/* Setup sequence done by the bootloader */
-static void n8x0_boot_init(void *opaque)
-{
- struct n800_s *s = (struct n800_s *) opaque;
- uint32_t buf;
-
- /* PRCM setup */
-#define omap_writel(addr, val) \
- buf = (val); \
- cpu_physical_memory_write(addr, &buf, sizeof(buf))
-
- omap_writel(0x48008060, 0x41); /* PRCM_CLKSRC_CTRL */
- omap_writel(0x48008070, 1); /* PRCM_CLKOUT_CTRL */
- omap_writel(0x48008078, 0); /* PRCM_CLKEMUL_CTRL */
- omap_writel(0x48008090, 0); /* PRCM_VOLTSETUP */
- omap_writel(0x48008094, 0); /* PRCM_CLKSSETUP */
- omap_writel(0x48008098, 0); /* PRCM_POLCTRL */
- omap_writel(0x48008140, 2); /* CM_CLKSEL_MPU */
- omap_writel(0x48008148, 0); /* CM_CLKSTCTRL_MPU */
- omap_writel(0x48008158, 1); /* RM_RSTST_MPU */
- omap_writel(0x480081c8, 0x15); /* PM_WKDEP_MPU */
- omap_writel(0x480081d4, 0x1d4); /* PM_EVGENCTRL_MPU */
- omap_writel(0x480081d8, 0); /* PM_EVEGENONTIM_MPU */
- omap_writel(0x480081dc, 0); /* PM_EVEGENOFFTIM_MPU */
- omap_writel(0x480081e0, 0xc); /* PM_PWSTCTRL_MPU */
- omap_writel(0x48008200, 0x047e7ff7); /* CM_FCLKEN1_CORE */
- omap_writel(0x48008204, 0x00000004); /* CM_FCLKEN2_CORE */
- omap_writel(0x48008210, 0x047e7ff1); /* CM_ICLKEN1_CORE */
- omap_writel(0x48008214, 0x00000004); /* CM_ICLKEN2_CORE */
- omap_writel(0x4800821c, 0x00000000); /* CM_ICLKEN4_CORE */
- omap_writel(0x48008230, 0); /* CM_AUTOIDLE1_CORE */
- omap_writel(0x48008234, 0); /* CM_AUTOIDLE2_CORE */
- omap_writel(0x48008238, 7); /* CM_AUTOIDLE3_CORE */
- omap_writel(0x4800823c, 0); /* CM_AUTOIDLE4_CORE */
- omap_writel(0x48008240, 0x04360626); /* CM_CLKSEL1_CORE */
- omap_writel(0x48008244, 0x00000014); /* CM_CLKSEL2_CORE */
- omap_writel(0x48008248, 0); /* CM_CLKSTCTRL_CORE */
- omap_writel(0x48008300, 0x00000000); /* CM_FCLKEN_GFX */
- omap_writel(0x48008310, 0x00000000); /* CM_ICLKEN_GFX */
- omap_writel(0x48008340, 0x00000001); /* CM_CLKSEL_GFX */
- omap_writel(0x48008400, 0x00000004); /* CM_FCLKEN_WKUP */
- omap_writel(0x48008410, 0x00000004); /* CM_ICLKEN_WKUP */
- omap_writel(0x48008440, 0x00000000); /* CM_CLKSEL_WKUP */
- omap_writel(0x48008500, 0x000000cf); /* CM_CLKEN_PLL */
- omap_writel(0x48008530, 0x0000000c); /* CM_AUTOIDLE_PLL */
- omap_writel(0x48008540, /* CM_CLKSEL1_PLL */
- (0x78 << 12) | (6 << 8));
- omap_writel(0x48008544, 2); /* CM_CLKSEL2_PLL */
-
- /* GPMC setup */
- n800_gpmc_init(s);
-
- /* Video setup */
- n800_dss_init(&s->blizzard);
-
- /* CPU setup */
- s->mpu->cpu->env.GE = 0x5;
-
- /* If the machine has a slided keyboard, open it */
- if (s->kbd) {
- qemu_irq_raise(qdev_get_gpio_in(s->mpu->gpio, N810_SLIDE_GPIO));
- }
-}
-
-#define OMAP_TAG_NOKIA_BT 0x4e01
-#define OMAP_TAG_WLAN_CX3110X 0x4e02
-#define OMAP_TAG_CBUS 0x4e03
-#define OMAP_TAG_EM_ASIC_BB5 0x4e04
-
-static struct omap_gpiosw_info_s {
- const char *name;
- int line;
- int type;
-} n800_gpiosw_info[] = {
- {
- "bat_cover", N800_BAT_COVER_GPIO,
- OMAP_GPIOSW_TYPE_COVER | OMAP_GPIOSW_INVERTED,
- }, {
- "cam_act", N800_CAM_ACT_GPIO,
- OMAP_GPIOSW_TYPE_ACTIVITY,
- }, {
- "cam_turn", N800_CAM_TURN_GPIO,
- OMAP_GPIOSW_TYPE_ACTIVITY | OMAP_GPIOSW_INVERTED,
- }, {
- "headphone", N8X0_HEADPHONE_GPIO,
- OMAP_GPIOSW_TYPE_CONNECTION | OMAP_GPIOSW_INVERTED,
- },
- { NULL }
-}, n810_gpiosw_info[] = {
- {
- "gps_reset", N810_GPS_RESET_GPIO,
- OMAP_GPIOSW_TYPE_ACTIVITY | OMAP_GPIOSW_OUTPUT,
- }, {
- "gps_wakeup", N810_GPS_WAKEUP_GPIO,
- OMAP_GPIOSW_TYPE_ACTIVITY | OMAP_GPIOSW_OUTPUT,
- }, {
- "headphone", N8X0_HEADPHONE_GPIO,
- OMAP_GPIOSW_TYPE_CONNECTION | OMAP_GPIOSW_INVERTED,
- }, {
- "kb_lock", N810_KB_LOCK_GPIO,
- OMAP_GPIOSW_TYPE_COVER | OMAP_GPIOSW_INVERTED,
- }, {
- "sleepx_led", N810_SLEEPX_LED_GPIO,
- OMAP_GPIOSW_TYPE_ACTIVITY | OMAP_GPIOSW_INVERTED | OMAP_GPIOSW_OUTPUT,
- }, {
- "slide", N810_SLIDE_GPIO,
- OMAP_GPIOSW_TYPE_COVER | OMAP_GPIOSW_INVERTED,
- },
- { NULL }
-};
-
-static struct omap_partition_info_s {
- uint32_t offset;
- uint32_t size;
- int mask;
- const char *name;
-} n800_part_info[] = {
- { 0x00000000, 0x00020000, 0x3, "bootloader" },
- { 0x00020000, 0x00060000, 0x0, "config" },
- { 0x00080000, 0x00200000, 0x0, "kernel" },
- { 0x00280000, 0x00200000, 0x3, "initfs" },
- { 0x00480000, 0x0fb80000, 0x3, "rootfs" },
-
- { 0, 0, 0, NULL }
-}, n810_part_info[] = {
- { 0x00000000, 0x00020000, 0x3, "bootloader" },
- { 0x00020000, 0x00060000, 0x0, "config" },
- { 0x00080000, 0x00220000, 0x0, "kernel" },
- { 0x002a0000, 0x00400000, 0x0, "initfs" },
- { 0x006a0000, 0x0f960000, 0x0, "rootfs" },
-
- { 0, 0, 0, NULL }
-};
-
-static bdaddr_t n8x0_bd_addr = {{ N8X0_BD_ADDR }};
-
-static int n8x0_atag_setup(void *p, int model)
-{
- uint8_t *b;
- uint16_t *w;
- uint32_t *l;
- struct omap_gpiosw_info_s *gpiosw;
- struct omap_partition_info_s *partition;
- const char *tag;
-
- w = p;
-
- stw_p(w++, OMAP_TAG_UART); /* u16 tag */
- stw_p(w++, 4); /* u16 len */
- stw_p(w++, (1 << 2) | (1 << 1) | (1 << 0)); /* uint enabled_uarts */
- w++;
-
-#if 0
- stw_p(w++, OMAP_TAG_SERIAL_CONSOLE); /* u16 tag */
- stw_p(w++, 4); /* u16 len */
- stw_p(w++, XLDR_LL_UART + 1); /* u8 console_uart */
- stw_p(w++, 115200); /* u32 console_speed */
-#endif
-
- stw_p(w++, OMAP_TAG_LCD); /* u16 tag */
- stw_p(w++, 36); /* u16 len */
- strcpy((void *) w, "QEMU LCD panel"); /* char panel_name[16] */
- w += 8;
- strcpy((void *) w, "blizzard"); /* char ctrl_name[16] */
- w += 8;
- stw_p(w++, N810_BLIZZARD_RESET_GPIO); /* TODO: n800 s16 nreset_gpio */
- stw_p(w++, 24); /* u8 data_lines */
-
- stw_p(w++, OMAP_TAG_CBUS); /* u16 tag */
- stw_p(w++, 8); /* u16 len */
- stw_p(w++, N8X0_CBUS_CLK_GPIO); /* s16 clk_gpio */
- stw_p(w++, N8X0_CBUS_DAT_GPIO); /* s16 dat_gpio */
- stw_p(w++, N8X0_CBUS_SEL_GPIO); /* s16 sel_gpio */
- w++;
-
- stw_p(w++, OMAP_TAG_EM_ASIC_BB5); /* u16 tag */
- stw_p(w++, 4); /* u16 len */
- stw_p(w++, N8X0_RETU_GPIO); /* s16 retu_irq_gpio */
- stw_p(w++, N8X0_TAHVO_GPIO); /* s16 tahvo_irq_gpio */
-
- gpiosw = (model == 810) ? n810_gpiosw_info : n800_gpiosw_info;
- for (; gpiosw->name; gpiosw++) {
- stw_p(w++, OMAP_TAG_GPIO_SWITCH); /* u16 tag */
- stw_p(w++, 20); /* u16 len */
- strcpy((void *) w, gpiosw->name); /* char name[12] */
- w += 6;
- stw_p(w++, gpiosw->line); /* u16 gpio */
- stw_p(w++, gpiosw->type);
- stw_p(w++, 0);
- stw_p(w++, 0);
- }
-
- stw_p(w++, OMAP_TAG_NOKIA_BT); /* u16 tag */
- stw_p(w++, 12); /* u16 len */
- b = (void *) w;
- stb_p(b++, 0x01); /* u8 chip_type (CSR) */
- stb_p(b++, N8X0_BT_WKUP_GPIO); /* u8 bt_wakeup_gpio */
- stb_p(b++, N8X0_BT_HOST_WKUP_GPIO); /* u8 host_wakeup_gpio */
- stb_p(b++, N8X0_BT_RESET_GPIO); /* u8 reset_gpio */
- stb_p(b++, BT_UART + 1); /* u8 bt_uart */
- memcpy(b, &n8x0_bd_addr, 6); /* u8 bd_addr[6] */
- b += 6;
- stb_p(b++, 0x02); /* u8 bt_sysclk (38.4) */
- w = (void *) b;
-
- stw_p(w++, OMAP_TAG_WLAN_CX3110X); /* u16 tag */
- stw_p(w++, 8); /* u16 len */
- stw_p(w++, 0x25); /* u8 chip_type */
- stw_p(w++, N8X0_WLAN_PWR_GPIO); /* s16 power_gpio */
- stw_p(w++, N8X0_WLAN_IRQ_GPIO); /* s16 irq_gpio */
- stw_p(w++, -1); /* s16 spi_cs_gpio */
-
- stw_p(w++, OMAP_TAG_MMC); /* u16 tag */
- stw_p(w++, 16); /* u16 len */
- if (model == 810) {
- stw_p(w++, 0x23f); /* unsigned flags */
- stw_p(w++, -1); /* s16 power_pin */
- stw_p(w++, -1); /* s16 switch_pin */
- stw_p(w++, -1); /* s16 wp_pin */
- stw_p(w++, 0x240); /* unsigned flags */
- stw_p(w++, 0xc000); /* s16 power_pin */
- stw_p(w++, 0x0248); /* s16 switch_pin */
- stw_p(w++, 0xc000); /* s16 wp_pin */
- } else {
- stw_p(w++, 0xf); /* unsigned flags */
- stw_p(w++, -1); /* s16 power_pin */
- stw_p(w++, -1); /* s16 switch_pin */
- stw_p(w++, -1); /* s16 wp_pin */
- stw_p(w++, 0); /* unsigned flags */
- stw_p(w++, 0); /* s16 power_pin */
- stw_p(w++, 0); /* s16 switch_pin */
- stw_p(w++, 0); /* s16 wp_pin */
- }
-
- stw_p(w++, OMAP_TAG_TEA5761); /* u16 tag */
- stw_p(w++, 4); /* u16 len */
- stw_p(w++, N8X0_TEA5761_CS_GPIO); /* u16 enable_gpio */
- w++;
-
- partition = (model == 810) ? n810_part_info : n800_part_info;
- for (; partition->name; partition++) {
- stw_p(w++, OMAP_TAG_PARTITION); /* u16 tag */
- stw_p(w++, 28); /* u16 len */
- strcpy((void *) w, partition->name); /* char name[16] */
- l = (void *) (w + 8);
- stl_p(l++, partition->size); /* unsigned int size */
- stl_p(l++, partition->offset); /* unsigned int offset */
- stl_p(l++, partition->mask); /* unsigned int mask_flags */
- w = (void *) l;
- }
-
- stw_p(w++, OMAP_TAG_BOOT_REASON); /* u16 tag */
- stw_p(w++, 12); /* u16 len */
-#if 0
- strcpy((void *) w, "por"); /* char reason_str[12] */
- strcpy((void *) w, "charger"); /* char reason_str[12] */
- strcpy((void *) w, "32wd_to"); /* char reason_str[12] */
- strcpy((void *) w, "sw_rst"); /* char reason_str[12] */
- strcpy((void *) w, "mbus"); /* char reason_str[12] */
- strcpy((void *) w, "unknown"); /* char reason_str[12] */
- strcpy((void *) w, "swdg_to"); /* char reason_str[12] */
- strcpy((void *) w, "sec_vio"); /* char reason_str[12] */
- strcpy((void *) w, "pwr_key"); /* char reason_str[12] */
- strcpy((void *) w, "rtc_alarm"); /* char reason_str[12] */
-#else
- strcpy((void *) w, "pwr_key"); /* char reason_str[12] */
-#endif
- w += 6;
-
- tag = (model == 810) ? "RX-44" : "RX-34";
- stw_p(w++, OMAP_TAG_VERSION_STR); /* u16 tag */
- stw_p(w++, 24); /* u16 len */
- strcpy((void *) w, "product"); /* char component[12] */
- w += 6;
- strcpy((void *) w, tag); /* char version[12] */
- w += 6;
-
- stw_p(w++, OMAP_TAG_VERSION_STR); /* u16 tag */
- stw_p(w++, 24); /* u16 len */
- strcpy((void *) w, "hw-build"); /* char component[12] */
- w += 6;
- strcpy((void *) w, "QEMU ");
- pstrcat((void *) w, 12, qemu_hw_version()); /* char version[12] */
- w += 6;
-
- tag = (model == 810) ? "1.1.10-qemu" : "1.1.6-qemu";
- stw_p(w++, OMAP_TAG_VERSION_STR); /* u16 tag */
- stw_p(w++, 24); /* u16 len */
- strcpy((void *) w, "nolo"); /* char component[12] */
- w += 6;
- strcpy((void *) w, tag); /* char version[12] */
- w += 6;
-
- return (void *) w - p;
-}
-
-static int n800_atag_setup(const struct arm_boot_info *info, void *p)
-{
- return n8x0_atag_setup(p, 800);
-}
-
-static int n810_atag_setup(const struct arm_boot_info *info, void *p)
-{
- return n8x0_atag_setup(p, 810);
-}
-
-static void n8x0_init(MachineState *machine,
- struct arm_boot_info *binfo, int model)
-{
- MemoryRegion *sysmem = get_system_memory();
- struct n800_s *s = (struct n800_s *) g_malloc0(sizeof(*s));
- int sdram_size = binfo->ram_size;
-
- s->mpu = omap2420_mpu_init(sysmem, sdram_size, machine->cpu_model);
-
- /* Setup peripherals
- *
- * Believed external peripherals layout in the N810:
- * (spi bus 1)
- * tsc2005
- * lcd_mipid
- * (spi bus 2)
- * Conexant cx3110x (WLAN)
- * optional: pc2400m (WiMAX)
- * (i2c bus 0)
- * TLV320AIC33 (audio codec)
- * TCM825x (camera by Toshiba)
- * lp5521 (clever LEDs)
- * tsl2563 (light sensor, hwmon, model 7, rev. 0)
- * lm8323 (keypad, manf 00, rev 04)
- * (i2c bus 1)
- * tmp105 (temperature sensor, hwmon)
- * menelaus (pm)
- * (somewhere on i2c - maybe N800-only)
- * tea5761 (FM tuner)
- * (serial 0)
- * GPS
- * (some serial port)
- * csr41814 (Bluetooth)
- */
- n8x0_gpio_setup(s);
- n8x0_nand_setup(s);
- n8x0_i2c_setup(s);
- if (model == 800) {
- n800_tsc_kbd_setup(s);
- } else if (model == 810) {
- n810_tsc_setup(s);
- n810_kbd_setup(s);
- }
- n8x0_spi_setup(s);
- n8x0_dss_setup(s);
- n8x0_cbus_setup(s);
- n8x0_uart_setup(s);
- if (usb_enabled()) {
- n8x0_usb_setup(s);
- }
-
- if (machine->kernel_filename) {
- /* Or at the linux loader. */
- binfo->kernel_filename = machine->kernel_filename;
- binfo->kernel_cmdline = machine->kernel_cmdline;
- binfo->initrd_filename = machine->initrd_filename;
- arm_load_kernel(s->mpu->cpu, binfo);
-
- qemu_register_reset(n8x0_boot_init, s);
- }
-
- if (option_rom[0].name &&
- (machine->boot_order[0] == 'n' || !machine->kernel_filename)) {
- uint8_t nolo_tags[0x10000];
- /* No, wait, better start at the ROM. */
- s->mpu->cpu->env.regs[15] = OMAP2_Q2_BASE + 0x400000;
-
- /* This is intended for loading the `secondary.bin' program from
- * Nokia images (the NOLO bootloader). The entry point seems
- * to be at OMAP2_Q2_BASE + 0x400000.
- *
- * The `2nd.bin' files contain some kind of earlier boot code and
- * for them the entry point needs to be set to OMAP2_SRAM_BASE.
- *
- * The code above is for loading the `zImage' file from Nokia
- * images. */
- load_image_targphys(option_rom[0].name,
- OMAP2_Q2_BASE + 0x400000,
- sdram_size - 0x400000);
-
- n800_setup_nolo_tags(nolo_tags);
- cpu_physical_memory_write(OMAP2_SRAM_BASE, nolo_tags, 0x10000);
- }
-}
-
-static struct arm_boot_info n800_binfo = {
- .loader_start = OMAP2_Q2_BASE,
- /* Actually two chips of 0x4000000 bytes each */
- .ram_size = 0x08000000,
- .board_id = 0x4f7,
- .atag_board = n800_atag_setup,
-};
-
-static struct arm_boot_info n810_binfo = {
- .loader_start = OMAP2_Q2_BASE,
- /* Actually two chips of 0x4000000 bytes each */
- .ram_size = 0x08000000,
- /* 0x60c and 0x6bf (WiMAX Edition) have been assigned but are not
- * used by some older versions of the bootloader and 5555 is used
- * instead (including versions that shipped with many devices). */
- .board_id = 0x60c,
- .atag_board = n810_atag_setup,
-};
-
-static void n800_init(MachineState *machine)
-{
- n8x0_init(machine, &n800_binfo, 800);
-}
-
-static void n810_init(MachineState *machine)
-{
- n8x0_init(machine, &n810_binfo, 810);
-}
-
-static void n800_class_init(ObjectClass *oc, void *data)
-{
- MachineClass *mc = MACHINE_CLASS(oc);
-
- mc->desc = "Nokia N800 tablet aka. RX-34 (OMAP2420)";
- mc->init = n800_init;
- mc->default_boot_order = "";
-}
-
-static const TypeInfo n800_type = {
- .name = MACHINE_TYPE_NAME("n800"),
- .parent = TYPE_MACHINE,
- .class_init = n800_class_init,
-};
-
-static void n810_class_init(ObjectClass *oc, void *data)
-{
- MachineClass *mc = MACHINE_CLASS(oc);
-
- mc->desc = "Nokia N810 tablet aka. RX-44 (OMAP2420)";
- mc->init = n810_init;
- mc->default_boot_order = "";
-}
-
-static const TypeInfo n810_type = {
- .name = MACHINE_TYPE_NAME("n810"),
- .parent = TYPE_MACHINE,
- .class_init = n810_class_init,
-};
-
-static void nseries_machine_init(void)
-{
- type_register_static(&n800_type);
- type_register_static(&n810_type);
-}
-
-type_init(nseries_machine_init)
diff --git a/qemu/hw/arm/omap1.c b/qemu/hw/arm/omap1.c
deleted file mode 100644
index b3cf0ec69..000000000
--- a/qemu/hw/arm/omap1.c
+++ /dev/null
@@ -1,4086 +0,0 @@
-/*
- * TI OMAP processors emulation.
- *
- * Copyright (C) 2006-2008 Andrzej Zaborowski <balrog@zabor.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 or
- * (at your option) version 3 of the License.
- *
- * 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/>.
- */
-
-#include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "qemu-common.h"
-#include "cpu.h"
-#include "hw/boards.h"
-#include "hw/hw.h"
-#include "hw/arm/arm.h"
-#include "hw/arm/omap.h"
-#include "sysemu/sysemu.h"
-#include "hw/arm/soc_dma.h"
-#include "sysemu/block-backend.h"
-#include "sysemu/blockdev.h"
-#include "qemu/range.h"
-#include "hw/sysbus.h"
-#include "qemu/cutils.h"
-#include "qemu/bcd.h"
-
-/* Should signal the TCMI/GPMC */
-uint32_t omap_badwidth_read8(void *opaque, hwaddr addr)
-{
- uint8_t ret;
-
- OMAP_8B_REG(addr);
- cpu_physical_memory_read(addr, &ret, 1);
- return ret;
-}
-
-void omap_badwidth_write8(void *opaque, hwaddr addr,
- uint32_t value)
-{
- uint8_t val8 = value;
-
- OMAP_8B_REG(addr);
- cpu_physical_memory_write(addr, &val8, 1);
-}
-
-uint32_t omap_badwidth_read16(void *opaque, hwaddr addr)
-{
- uint16_t ret;
-
- OMAP_16B_REG(addr);
- cpu_physical_memory_read(addr, &ret, 2);
- return ret;
-}
-
-void omap_badwidth_write16(void *opaque, hwaddr addr,
- uint32_t value)
-{
- uint16_t val16 = value;
-
- OMAP_16B_REG(addr);
- cpu_physical_memory_write(addr, &val16, 2);
-}
-
-uint32_t omap_badwidth_read32(void *opaque, hwaddr addr)
-{
- uint32_t ret;
-
- OMAP_32B_REG(addr);
- cpu_physical_memory_read(addr, &ret, 4);
- return ret;
-}
-
-void omap_badwidth_write32(void *opaque, hwaddr addr,
- uint32_t value)
-{
- OMAP_32B_REG(addr);
- cpu_physical_memory_write(addr, &value, 4);
-}
-
-/* MPU OS timers */
-struct omap_mpu_timer_s {
- MemoryRegion iomem;
- qemu_irq irq;
- omap_clk clk;
- uint32_t val;
- int64_t time;
- QEMUTimer *timer;
- QEMUBH *tick;
- int64_t rate;
- int it_ena;
-
- int enable;
- int ptv;
- int ar;
- int st;
- uint32_t reset_val;
-};
-
-static inline uint32_t omap_timer_read(struct omap_mpu_timer_s *timer)
-{
- uint64_t distance = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - timer->time;
-
- if (timer->st && timer->enable && timer->rate)
- return timer->val - muldiv64(distance >> (timer->ptv + 1),
- timer->rate, NANOSECONDS_PER_SECOND);
- else
- return timer->val;
-}
-
-static inline void omap_timer_sync(struct omap_mpu_timer_s *timer)
-{
- timer->val = omap_timer_read(timer);
- timer->time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
-}
-
-static inline void omap_timer_update(struct omap_mpu_timer_s *timer)
-{
- int64_t expires;
-
- if (timer->enable && timer->st && timer->rate) {
- timer->val = timer->reset_val; /* Should skip this on clk enable */
- expires = muldiv64((uint64_t) timer->val << (timer->ptv + 1),
- NANOSECONDS_PER_SECOND, timer->rate);
-
- /* If timer expiry would be sooner than in about 1 ms and
- * auto-reload isn't set, then fire immediately. This is a hack
- * to make systems like PalmOS run in acceptable time. PalmOS
- * sets the interval to a very low value and polls the status bit
- * in a busy loop when it wants to sleep just a couple of CPU
- * ticks. */
- if (expires > (NANOSECONDS_PER_SECOND >> 10) || timer->ar) {
- timer_mod(timer->timer, timer->time + expires);
- } else {
- qemu_bh_schedule(timer->tick);
- }
- } else
- timer_del(timer->timer);
-}
-
-static void omap_timer_fire(void *opaque)
-{
- struct omap_mpu_timer_s *timer = opaque;
-
- if (!timer->ar) {
- timer->val = 0;
- timer->st = 0;
- }
-
- if (timer->it_ena)
- /* Edge-triggered irq */
- qemu_irq_pulse(timer->irq);
-}
-
-static void omap_timer_tick(void *opaque)
-{
- struct omap_mpu_timer_s *timer = (struct omap_mpu_timer_s *) opaque;
-
- omap_timer_sync(timer);
- omap_timer_fire(timer);
- omap_timer_update(timer);
-}
-
-static void omap_timer_clk_update(void *opaque, int line, int on)
-{
- struct omap_mpu_timer_s *timer = (struct omap_mpu_timer_s *) opaque;
-
- omap_timer_sync(timer);
- timer->rate = on ? omap_clk_getrate(timer->clk) : 0;
- omap_timer_update(timer);
-}
-
-static void omap_timer_clk_setup(struct omap_mpu_timer_s *timer)
-{
- omap_clk_adduser(timer->clk,
- qemu_allocate_irq(omap_timer_clk_update, timer, 0));
- timer->rate = omap_clk_getrate(timer->clk);
-}
-
-static uint64_t omap_mpu_timer_read(void *opaque, hwaddr addr,
- unsigned size)
-{
- struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *) opaque;
-
- if (size != 4) {
- return omap_badwidth_read32(opaque, addr);
- }
-
- switch (addr) {
- case 0x00: /* CNTL_TIMER */
- return (s->enable << 5) | (s->ptv << 2) | (s->ar << 1) | s->st;
-
- case 0x04: /* LOAD_TIM */
- break;
-
- case 0x08: /* READ_TIM */
- return omap_timer_read(s);
- }
-
- OMAP_BAD_REG(addr);
- return 0;
-}
-
-static void omap_mpu_timer_write(void *opaque, hwaddr addr,
- uint64_t value, unsigned size)
-{
- struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *) opaque;
-
- if (size != 4) {
- omap_badwidth_write32(opaque, addr, value);
- return;
- }
-
- switch (addr) {
- case 0x00: /* CNTL_TIMER */
- omap_timer_sync(s);
- s->enable = (value >> 5) & 1;
- s->ptv = (value >> 2) & 7;
- s->ar = (value >> 1) & 1;
- s->st = value & 1;
- omap_timer_update(s);
- return;
-
- case 0x04: /* LOAD_TIM */
- s->reset_val = value;
- return;
-
- case 0x08: /* READ_TIM */
- OMAP_RO_REG(addr);
- break;
-
- default:
- OMAP_BAD_REG(addr);
- }
-}
-
-static const MemoryRegionOps omap_mpu_timer_ops = {
- .read = omap_mpu_timer_read,
- .write = omap_mpu_timer_write,
- .endianness = DEVICE_LITTLE_ENDIAN,
-};
-
-static void omap_mpu_timer_reset(struct omap_mpu_timer_s *s)
-{
- timer_del(s->timer);
- s->enable = 0;
- s->reset_val = 31337;
- s->val = 0;
- s->ptv = 0;
- s->ar = 0;
- s->st = 0;
- s->it_ena = 1;
-}
-
-static struct omap_mpu_timer_s *omap_mpu_timer_init(MemoryRegion *system_memory,
- hwaddr base,
- qemu_irq irq, omap_clk clk)
-{
- struct omap_mpu_timer_s *s = g_new0(struct omap_mpu_timer_s, 1);
-
- s->irq = irq;
- s->clk = clk;
- s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, omap_timer_tick, s);
- s->tick = qemu_bh_new(omap_timer_fire, s);
- omap_mpu_timer_reset(s);
- omap_timer_clk_setup(s);
-
- memory_region_init_io(&s->iomem, NULL, &omap_mpu_timer_ops, s,
- "omap-mpu-timer", 0x100);
-
- memory_region_add_subregion(system_memory, base, &s->iomem);
-
- return s;
-}
-
-/* Watchdog timer */
-struct omap_watchdog_timer_s {
- struct omap_mpu_timer_s timer;
- MemoryRegion iomem;
- uint8_t last_wr;
- int mode;
- int free;
- int reset;
-};
-
-static uint64_t omap_wd_timer_read(void *opaque, hwaddr addr,
- unsigned size)
-{
- struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *) opaque;
-
- if (size != 2) {
- return omap_badwidth_read16(opaque, addr);
- }
-
- switch (addr) {
- case 0x00: /* CNTL_TIMER */
- return (s->timer.ptv << 9) | (s->timer.ar << 8) |
- (s->timer.st << 7) | (s->free << 1);
-
- case 0x04: /* READ_TIMER */
- return omap_timer_read(&s->timer);
-
- case 0x08: /* TIMER_MODE */
- return s->mode << 15;
- }
-
- OMAP_BAD_REG(addr);
- return 0;
-}
-
-static void omap_wd_timer_write(void *opaque, hwaddr addr,
- uint64_t value, unsigned size)
-{
- struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *) opaque;
-
- if (size != 2) {
- omap_badwidth_write16(opaque, addr, value);
- return;
- }
-
- switch (addr) {
- case 0x00: /* CNTL_TIMER */
- omap_timer_sync(&s->timer);
- s->timer.ptv = (value >> 9) & 7;
- s->timer.ar = (value >> 8) & 1;
- s->timer.st = (value >> 7) & 1;
- s->free = (value >> 1) & 1;
- omap_timer_update(&s->timer);
- break;
-
- case 0x04: /* LOAD_TIMER */
- s->timer.reset_val = value & 0xffff;
- break;
-
- case 0x08: /* TIMER_MODE */
- if (!s->mode && ((value >> 15) & 1))
- omap_clk_get(s->timer.clk);
- s->mode |= (value >> 15) & 1;
- if (s->last_wr == 0xf5) {
- if ((value & 0xff) == 0xa0) {
- if (s->mode) {
- s->mode = 0;
- omap_clk_put(s->timer.clk);
- }
- } else {
- /* XXX: on T|E hardware somehow this has no effect,
- * on Zire 71 it works as specified. */
- s->reset = 1;
- qemu_system_reset_request();
- }
- }
- s->last_wr = value & 0xff;
- break;
-
- default:
- OMAP_BAD_REG(addr);
- }
-}
-
-static const MemoryRegionOps omap_wd_timer_ops = {
- .read = omap_wd_timer_read,
- .write = omap_wd_timer_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static void omap_wd_timer_reset(struct omap_watchdog_timer_s *s)
-{
- timer_del(s->timer.timer);
- if (!s->mode)
- omap_clk_get(s->timer.clk);
- s->mode = 1;
- s->free = 1;
- s->reset = 0;
- s->timer.enable = 1;
- s->timer.it_ena = 1;
- s->timer.reset_val = 0xffff;
- s->timer.val = 0;
- s->timer.st = 0;
- s->timer.ptv = 0;
- s->timer.ar = 0;
- omap_timer_update(&s->timer);
-}
-
-static struct omap_watchdog_timer_s *omap_wd_timer_init(MemoryRegion *memory,
- hwaddr base,
- qemu_irq irq, omap_clk clk)
-{
- struct omap_watchdog_timer_s *s = g_new0(struct omap_watchdog_timer_s, 1);
-
- s->timer.irq = irq;
- s->timer.clk = clk;
- s->timer.timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, omap_timer_tick, &s->timer);
- omap_wd_timer_reset(s);
- omap_timer_clk_setup(&s->timer);
-
- memory_region_init_io(&s->iomem, NULL, &omap_wd_timer_ops, s,
- "omap-wd-timer", 0x100);
- memory_region_add_subregion(memory, base, &s->iomem);
-
- return s;
-}
-
-/* 32-kHz timer */
-struct omap_32khz_timer_s {
- struct omap_mpu_timer_s timer;
- MemoryRegion iomem;
-};
-
-static uint64_t omap_os_timer_read(void *opaque, hwaddr addr,
- unsigned size)
-{
- struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *) opaque;
- int offset = addr & OMAP_MPUI_REG_MASK;
-
- if (size != 4) {
- return omap_badwidth_read32(opaque, addr);
- }
-
- switch (offset) {
- case 0x00: /* TVR */
- return s->timer.reset_val;
-
- case 0x04: /* TCR */
- return omap_timer_read(&s->timer);
-
- case 0x08: /* CR */
- return (s->timer.ar << 3) | (s->timer.it_ena << 2) | s->timer.st;
-
- default:
- break;
- }
- OMAP_BAD_REG(addr);
- return 0;
-}
-
-static void omap_os_timer_write(void *opaque, hwaddr addr,
- uint64_t value, unsigned size)
-{
- struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *) opaque;
- int offset = addr & OMAP_MPUI_REG_MASK;
-
- if (size != 4) {
- omap_badwidth_write32(opaque, addr, value);
- return;
- }
-
- switch (offset) {
- case 0x00: /* TVR */
- s->timer.reset_val = value & 0x00ffffff;
- break;
-
- case 0x04: /* TCR */
- OMAP_RO_REG(addr);
- break;
-
- case 0x08: /* CR */
- s->timer.ar = (value >> 3) & 1;
- s->timer.it_ena = (value >> 2) & 1;
- if (s->timer.st != (value & 1) || (value & 2)) {
- omap_timer_sync(&s->timer);
- s->timer.enable = value & 1;
- s->timer.st = value & 1;
- omap_timer_update(&s->timer);
- }
- break;
-
- default:
- OMAP_BAD_REG(addr);
- }
-}
-
-static const MemoryRegionOps omap_os_timer_ops = {
- .read = omap_os_timer_read,
- .write = omap_os_timer_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static void omap_os_timer_reset(struct omap_32khz_timer_s *s)
-{
- timer_del(s->timer.timer);
- s->timer.enable = 0;
- s->timer.it_ena = 0;
- s->timer.reset_val = 0x00ffffff;
- s->timer.val = 0;
- s->timer.st = 0;
- s->timer.ptv = 0;
- s->timer.ar = 1;
-}
-
-static struct omap_32khz_timer_s *omap_os_timer_init(MemoryRegion *memory,
- hwaddr base,
- qemu_irq irq, omap_clk clk)
-{
- struct omap_32khz_timer_s *s = g_new0(struct omap_32khz_timer_s, 1);
-
- s->timer.irq = irq;
- s->timer.clk = clk;
- s->timer.timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, omap_timer_tick, &s->timer);
- omap_os_timer_reset(s);
- omap_timer_clk_setup(&s->timer);
-
- memory_region_init_io(&s->iomem, NULL, &omap_os_timer_ops, s,
- "omap-os-timer", 0x800);
- memory_region_add_subregion(memory, base, &s->iomem);
-
- return s;
-}
-
-/* Ultra Low-Power Device Module */
-static uint64_t omap_ulpd_pm_read(void *opaque, hwaddr addr,
- unsigned size)
-{
- struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
- uint16_t ret;
-
- if (size != 2) {
- return omap_badwidth_read16(opaque, addr);
- }
-
- switch (addr) {
- case 0x14: /* IT_STATUS */
- ret = s->ulpd_pm_regs[addr >> 2];
- s->ulpd_pm_regs[addr >> 2] = 0;
- qemu_irq_lower(qdev_get_gpio_in(s->ih[1], OMAP_INT_GAUGE_32K));
- return ret;
-
- case 0x18: /* Reserved */
- case 0x1c: /* Reserved */
- case 0x20: /* Reserved */
- case 0x28: /* Reserved */
- case 0x2c: /* Reserved */
- OMAP_BAD_REG(addr);
- /* fall through */
- case 0x00: /* COUNTER_32_LSB */
- case 0x04: /* COUNTER_32_MSB */
- case 0x08: /* COUNTER_HIGH_FREQ_LSB */
- case 0x0c: /* COUNTER_HIGH_FREQ_MSB */
- case 0x10: /* GAUGING_CTRL */
- case 0x24: /* SETUP_ANALOG_CELL3_ULPD1 */
- case 0x30: /* CLOCK_CTRL */
- case 0x34: /* SOFT_REQ */
- case 0x38: /* COUNTER_32_FIQ */
- case 0x3c: /* DPLL_CTRL */
- case 0x40: /* STATUS_REQ */
- /* XXX: check clk::usecount state for every clock */
- case 0x48: /* LOCL_TIME */
- case 0x4c: /* APLL_CTRL */
- case 0x50: /* POWER_CTRL */
- return s->ulpd_pm_regs[addr >> 2];
- }
-
- OMAP_BAD_REG(addr);
- return 0;
-}
-
-static inline void omap_ulpd_clk_update(struct omap_mpu_state_s *s,
- uint16_t diff, uint16_t value)
-{
- if (diff & (1 << 4)) /* USB_MCLK_EN */
- omap_clk_onoff(omap_findclk(s, "usb_clk0"), (value >> 4) & 1);
- if (diff & (1 << 5)) /* DIS_USB_PVCI_CLK */
- omap_clk_onoff(omap_findclk(s, "usb_w2fc_ck"), (~value >> 5) & 1);
-}
-
-static inline void omap_ulpd_req_update(struct omap_mpu_state_s *s,
- uint16_t diff, uint16_t value)
-{
- if (diff & (1 << 0)) /* SOFT_DPLL_REQ */
- omap_clk_canidle(omap_findclk(s, "dpll4"), (~value >> 0) & 1);
- if (diff & (1 << 1)) /* SOFT_COM_REQ */
- omap_clk_canidle(omap_findclk(s, "com_mclk_out"), (~value >> 1) & 1);
- if (diff & (1 << 2)) /* SOFT_SDW_REQ */
- omap_clk_canidle(omap_findclk(s, "bt_mclk_out"), (~value >> 2) & 1);
- if (diff & (1 << 3)) /* SOFT_USB_REQ */
- omap_clk_canidle(omap_findclk(s, "usb_clk0"), (~value >> 3) & 1);
-}
-
-static void omap_ulpd_pm_write(void *opaque, hwaddr addr,
- uint64_t value, unsigned size)
-{
- struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
- int64_t now, ticks;
- int div, mult;
- static const int bypass_div[4] = { 1, 2, 4, 4 };
- uint16_t diff;
-
- if (size != 2) {
- omap_badwidth_write16(opaque, addr, value);
- return;
- }
-
- switch (addr) {
- case 0x00: /* COUNTER_32_LSB */
- case 0x04: /* COUNTER_32_MSB */
- case 0x08: /* COUNTER_HIGH_FREQ_LSB */
- case 0x0c: /* COUNTER_HIGH_FREQ_MSB */
- case 0x14: /* IT_STATUS */
- case 0x40: /* STATUS_REQ */
- OMAP_RO_REG(addr);
- break;
-
- case 0x10: /* GAUGING_CTRL */
- /* Bits 0 and 1 seem to be confused in the OMAP 310 TRM */
- if ((s->ulpd_pm_regs[addr >> 2] ^ value) & 1) {
- now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
-
- if (value & 1)
- s->ulpd_gauge_start = now;
- else {
- now -= s->ulpd_gauge_start;
-
- /* 32-kHz ticks */
- ticks = muldiv64(now, 32768, NANOSECONDS_PER_SECOND);
- s->ulpd_pm_regs[0x00 >> 2] = (ticks >> 0) & 0xffff;
- s->ulpd_pm_regs[0x04 >> 2] = (ticks >> 16) & 0xffff;
- if (ticks >> 32) /* OVERFLOW_32K */
- s->ulpd_pm_regs[0x14 >> 2] |= 1 << 2;
-
- /* High frequency ticks */
- ticks = muldiv64(now, 12000000, NANOSECONDS_PER_SECOND);
- s->ulpd_pm_regs[0x08 >> 2] = (ticks >> 0) & 0xffff;
- s->ulpd_pm_regs[0x0c >> 2] = (ticks >> 16) & 0xffff;
- if (ticks >> 32) /* OVERFLOW_HI_FREQ */
- s->ulpd_pm_regs[0x14 >> 2] |= 1 << 1;
-
- s->ulpd_pm_regs[0x14 >> 2] |= 1 << 0; /* IT_GAUGING */
- qemu_irq_raise(qdev_get_gpio_in(s->ih[1], OMAP_INT_GAUGE_32K));
- }
- }
- s->ulpd_pm_regs[addr >> 2] = value;
- break;
-
- case 0x18: /* Reserved */
- case 0x1c: /* Reserved */
- case 0x20: /* Reserved */
- case 0x28: /* Reserved */
- case 0x2c: /* Reserved */
- OMAP_BAD_REG(addr);
- /* fall through */
- case 0x24: /* SETUP_ANALOG_CELL3_ULPD1 */
- case 0x38: /* COUNTER_32_FIQ */
- case 0x48: /* LOCL_TIME */
- case 0x50: /* POWER_CTRL */
- s->ulpd_pm_regs[addr >> 2] = value;
- break;
-
- case 0x30: /* CLOCK_CTRL */
- diff = s->ulpd_pm_regs[addr >> 2] ^ value;
- s->ulpd_pm_regs[addr >> 2] = value & 0x3f;
- omap_ulpd_clk_update(s, diff, value);
- break;
-
- case 0x34: /* SOFT_REQ */
- diff = s->ulpd_pm_regs[addr >> 2] ^ value;
- s->ulpd_pm_regs[addr >> 2] = value & 0x1f;
- omap_ulpd_req_update(s, diff, value);
- break;
-
- case 0x3c: /* DPLL_CTRL */
- /* XXX: OMAP310 TRM claims bit 3 is PLL_ENABLE, and bit 4 is
- * omitted altogether, probably a typo. */
- /* This register has identical semantics with DPLL(1:3) control
- * registers, see omap_dpll_write() */
- diff = s->ulpd_pm_regs[addr >> 2] & value;
- s->ulpd_pm_regs[addr >> 2] = value & 0x2fff;
- if (diff & (0x3ff << 2)) {
- if (value & (1 << 4)) { /* PLL_ENABLE */
- div = ((value >> 5) & 3) + 1; /* PLL_DIV */
- mult = MIN((value >> 7) & 0x1f, 1); /* PLL_MULT */
- } else {
- div = bypass_div[((value >> 2) & 3)]; /* BYPASS_DIV */
- mult = 1;
- }
- omap_clk_setrate(omap_findclk(s, "dpll4"), div, mult);
- }
-
- /* Enter the desired mode. */
- s->ulpd_pm_regs[addr >> 2] =
- (s->ulpd_pm_regs[addr >> 2] & 0xfffe) |
- ((s->ulpd_pm_regs[addr >> 2] >> 4) & 1);
-
- /* Act as if the lock is restored. */
- s->ulpd_pm_regs[addr >> 2] |= 2;
- break;
-
- case 0x4c: /* APLL_CTRL */
- diff = s->ulpd_pm_regs[addr >> 2] & value;
- s->ulpd_pm_regs[addr >> 2] = value & 0xf;
- if (diff & (1 << 0)) /* APLL_NDPLL_SWITCH */
- omap_clk_reparent(omap_findclk(s, "ck_48m"), omap_findclk(s,
- (value & (1 << 0)) ? "apll" : "dpll4"));
- break;
-
- default:
- OMAP_BAD_REG(addr);
- }
-}
-
-static const MemoryRegionOps omap_ulpd_pm_ops = {
- .read = omap_ulpd_pm_read,
- .write = omap_ulpd_pm_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static void omap_ulpd_pm_reset(struct omap_mpu_state_s *mpu)
-{
- mpu->ulpd_pm_regs[0x00 >> 2] = 0x0001;
- mpu->ulpd_pm_regs[0x04 >> 2] = 0x0000;
- mpu->ulpd_pm_regs[0x08 >> 2] = 0x0001;
- mpu->ulpd_pm_regs[0x0c >> 2] = 0x0000;
- mpu->ulpd_pm_regs[0x10 >> 2] = 0x0000;
- mpu->ulpd_pm_regs[0x18 >> 2] = 0x01;
- mpu->ulpd_pm_regs[0x1c >> 2] = 0x01;
- mpu->ulpd_pm_regs[0x20 >> 2] = 0x01;
- mpu->ulpd_pm_regs[0x24 >> 2] = 0x03ff;
- mpu->ulpd_pm_regs[0x28 >> 2] = 0x01;
- mpu->ulpd_pm_regs[0x2c >> 2] = 0x01;
- omap_ulpd_clk_update(mpu, mpu->ulpd_pm_regs[0x30 >> 2], 0x0000);
- mpu->ulpd_pm_regs[0x30 >> 2] = 0x0000;
- omap_ulpd_req_update(mpu, mpu->ulpd_pm_regs[0x34 >> 2], 0x0000);
- mpu->ulpd_pm_regs[0x34 >> 2] = 0x0000;
- mpu->ulpd_pm_regs[0x38 >> 2] = 0x0001;
- mpu->ulpd_pm_regs[0x3c >> 2] = 0x2211;
- mpu->ulpd_pm_regs[0x40 >> 2] = 0x0000; /* FIXME: dump a real STATUS_REQ */
- mpu->ulpd_pm_regs[0x48 >> 2] = 0x960;
- mpu->ulpd_pm_regs[0x4c >> 2] = 0x08;
- mpu->ulpd_pm_regs[0x50 >> 2] = 0x08;
- omap_clk_setrate(omap_findclk(mpu, "dpll4"), 1, 4);
- omap_clk_reparent(omap_findclk(mpu, "ck_48m"), omap_findclk(mpu, "dpll4"));
-}
-
-static void omap_ulpd_pm_init(MemoryRegion *system_memory,
- hwaddr base,
- struct omap_mpu_state_s *mpu)
-{
- memory_region_init_io(&mpu->ulpd_pm_iomem, NULL, &omap_ulpd_pm_ops, mpu,
- "omap-ulpd-pm", 0x800);
- memory_region_add_subregion(system_memory, base, &mpu->ulpd_pm_iomem);
- omap_ulpd_pm_reset(mpu);
-}
-
-/* OMAP Pin Configuration */
-static uint64_t omap_pin_cfg_read(void *opaque, hwaddr addr,
- unsigned size)
-{
- struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
-
- if (size != 4) {
- return omap_badwidth_read32(opaque, addr);
- }
-
- switch (addr) {
- case 0x00: /* FUNC_MUX_CTRL_0 */
- case 0x04: /* FUNC_MUX_CTRL_1 */
- case 0x08: /* FUNC_MUX_CTRL_2 */
- return s->func_mux_ctrl[addr >> 2];
-
- case 0x0c: /* COMP_MODE_CTRL_0 */
- return s->comp_mode_ctrl[0];
-
- case 0x10: /* FUNC_MUX_CTRL_3 */
- case 0x14: /* FUNC_MUX_CTRL_4 */
- case 0x18: /* FUNC_MUX_CTRL_5 */
- case 0x1c: /* FUNC_MUX_CTRL_6 */
- case 0x20: /* FUNC_MUX_CTRL_7 */
- case 0x24: /* FUNC_MUX_CTRL_8 */
- case 0x28: /* FUNC_MUX_CTRL_9 */
- case 0x2c: /* FUNC_MUX_CTRL_A */
- case 0x30: /* FUNC_MUX_CTRL_B */
- case 0x34: /* FUNC_MUX_CTRL_C */
- case 0x38: /* FUNC_MUX_CTRL_D */
- return s->func_mux_ctrl[(addr >> 2) - 1];
-
- case 0x40: /* PULL_DWN_CTRL_0 */
- case 0x44: /* PULL_DWN_CTRL_1 */
- case 0x48: /* PULL_DWN_CTRL_2 */
- case 0x4c: /* PULL_DWN_CTRL_3 */
- return s->pull_dwn_ctrl[(addr & 0xf) >> 2];
-
- case 0x50: /* GATE_INH_CTRL_0 */
- return s->gate_inh_ctrl[0];
-
- case 0x60: /* VOLTAGE_CTRL_0 */
- return s->voltage_ctrl[0];
-
- case 0x70: /* TEST_DBG_CTRL_0 */
- return s->test_dbg_ctrl[0];
-
- case 0x80: /* MOD_CONF_CTRL_0 */
- return s->mod_conf_ctrl[0];
- }
-
- OMAP_BAD_REG(addr);
- return 0;
-}
-
-static inline void omap_pin_funcmux0_update(struct omap_mpu_state_s *s,
- uint32_t diff, uint32_t value)
-{
- if (s->compat1509) {
- if (diff & (1 << 9)) /* BLUETOOTH */
- omap_clk_onoff(omap_findclk(s, "bt_mclk_out"),
- (~value >> 9) & 1);
- if (diff & (1 << 7)) /* USB.CLKO */
- omap_clk_onoff(omap_findclk(s, "usb.clko"),
- (value >> 7) & 1);
- }
-}
-
-static inline void omap_pin_funcmux1_update(struct omap_mpu_state_s *s,
- uint32_t diff, uint32_t value)
-{
- if (s->compat1509) {
- if (diff & (1U << 31)) {
- /* MCBSP3_CLK_HIZ_DI */
- omap_clk_onoff(omap_findclk(s, "mcbsp3.clkx"), (value >> 31) & 1);
- }
- if (diff & (1 << 1)) {
- /* CLK32K */
- omap_clk_onoff(omap_findclk(s, "clk32k_out"), (~value >> 1) & 1);
- }
- }
-}
-
-static inline void omap_pin_modconf1_update(struct omap_mpu_state_s *s,
- uint32_t diff, uint32_t value)
-{
- if (diff & (1U << 31)) {
- /* CONF_MOD_UART3_CLK_MODE_R */
- omap_clk_reparent(omap_findclk(s, "uart3_ck"),
- omap_findclk(s, ((value >> 31) & 1) ?
- "ck_48m" : "armper_ck"));
- }
- if (diff & (1 << 30)) /* CONF_MOD_UART2_CLK_MODE_R */
- omap_clk_reparent(omap_findclk(s, "uart2_ck"),
- omap_findclk(s, ((value >> 30) & 1) ?
- "ck_48m" : "armper_ck"));
- if (diff & (1 << 29)) /* CONF_MOD_UART1_CLK_MODE_R */
- omap_clk_reparent(omap_findclk(s, "uart1_ck"),
- omap_findclk(s, ((value >> 29) & 1) ?
- "ck_48m" : "armper_ck"));
- if (diff & (1 << 23)) /* CONF_MOD_MMC_SD_CLK_REQ_R */
- omap_clk_reparent(omap_findclk(s, "mmc_ck"),
- omap_findclk(s, ((value >> 23) & 1) ?
- "ck_48m" : "armper_ck"));
- if (diff & (1 << 12)) /* CONF_MOD_COM_MCLK_12_48_S */
- omap_clk_reparent(omap_findclk(s, "com_mclk_out"),
- omap_findclk(s, ((value >> 12) & 1) ?
- "ck_48m" : "armper_ck"));
- if (diff & (1 << 9)) /* CONF_MOD_USB_HOST_HHC_UHO */
- omap_clk_onoff(omap_findclk(s, "usb_hhc_ck"), (value >> 9) & 1);
-}
-
-static void omap_pin_cfg_write(void *opaque, hwaddr addr,
- uint64_t value, unsigned size)
-{
- struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
- uint32_t diff;
-
- if (size != 4) {
- omap_badwidth_write32(opaque, addr, value);
- return;
- }
-
- switch (addr) {
- case 0x00: /* FUNC_MUX_CTRL_0 */
- diff = s->func_mux_ctrl[addr >> 2] ^ value;
- s->func_mux_ctrl[addr >> 2] = value;
- omap_pin_funcmux0_update(s, diff, value);
- return;
-
- case 0x04: /* FUNC_MUX_CTRL_1 */
- diff = s->func_mux_ctrl[addr >> 2] ^ value;
- s->func_mux_ctrl[addr >> 2] = value;
- omap_pin_funcmux1_update(s, diff, value);
- return;
-
- case 0x08: /* FUNC_MUX_CTRL_2 */
- s->func_mux_ctrl[addr >> 2] = value;
- return;
-
- case 0x0c: /* COMP_MODE_CTRL_0 */
- s->comp_mode_ctrl[0] = value;
- s->compat1509 = (value != 0x0000eaef);
- omap_pin_funcmux0_update(s, ~0, s->func_mux_ctrl[0]);
- omap_pin_funcmux1_update(s, ~0, s->func_mux_ctrl[1]);
- return;
-
- case 0x10: /* FUNC_MUX_CTRL_3 */
- case 0x14: /* FUNC_MUX_CTRL_4 */
- case 0x18: /* FUNC_MUX_CTRL_5 */
- case 0x1c: /* FUNC_MUX_CTRL_6 */
- case 0x20: /* FUNC_MUX_CTRL_7 */
- case 0x24: /* FUNC_MUX_CTRL_8 */
- case 0x28: /* FUNC_MUX_CTRL_9 */
- case 0x2c: /* FUNC_MUX_CTRL_A */
- case 0x30: /* FUNC_MUX_CTRL_B */
- case 0x34: /* FUNC_MUX_CTRL_C */
- case 0x38: /* FUNC_MUX_CTRL_D */
- s->func_mux_ctrl[(addr >> 2) - 1] = value;
- return;
-
- case 0x40: /* PULL_DWN_CTRL_0 */
- case 0x44: /* PULL_DWN_CTRL_1 */
- case 0x48: /* PULL_DWN_CTRL_2 */
- case 0x4c: /* PULL_DWN_CTRL_3 */
- s->pull_dwn_ctrl[(addr & 0xf) >> 2] = value;
- return;
-
- case 0x50: /* GATE_INH_CTRL_0 */
- s->gate_inh_ctrl[0] = value;
- return;
-
- case 0x60: /* VOLTAGE_CTRL_0 */
- s->voltage_ctrl[0] = value;
- return;
-
- case 0x70: /* TEST_DBG_CTRL_0 */
- s->test_dbg_ctrl[0] = value;
- return;
-
- case 0x80: /* MOD_CONF_CTRL_0 */
- diff = s->mod_conf_ctrl[0] ^ value;
- s->mod_conf_ctrl[0] = value;
- omap_pin_modconf1_update(s, diff, value);
- return;
-
- default:
- OMAP_BAD_REG(addr);
- }
-}
-
-static const MemoryRegionOps omap_pin_cfg_ops = {
- .read = omap_pin_cfg_read,
- .write = omap_pin_cfg_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static void omap_pin_cfg_reset(struct omap_mpu_state_s *mpu)
-{
- /* Start in Compatibility Mode. */
- mpu->compat1509 = 1;
- omap_pin_funcmux0_update(mpu, mpu->func_mux_ctrl[0], 0);
- omap_pin_funcmux1_update(mpu, mpu->func_mux_ctrl[1], 0);
- omap_pin_modconf1_update(mpu, mpu->mod_conf_ctrl[0], 0);
- memset(mpu->func_mux_ctrl, 0, sizeof(mpu->func_mux_ctrl));
- memset(mpu->comp_mode_ctrl, 0, sizeof(mpu->comp_mode_ctrl));
- memset(mpu->pull_dwn_ctrl, 0, sizeof(mpu->pull_dwn_ctrl));
- memset(mpu->gate_inh_ctrl, 0, sizeof(mpu->gate_inh_ctrl));
- memset(mpu->voltage_ctrl, 0, sizeof(mpu->voltage_ctrl));
- memset(mpu->test_dbg_ctrl, 0, sizeof(mpu->test_dbg_ctrl));
- memset(mpu->mod_conf_ctrl, 0, sizeof(mpu->mod_conf_ctrl));
-}
-
-static void omap_pin_cfg_init(MemoryRegion *system_memory,
- hwaddr base,
- struct omap_mpu_state_s *mpu)
-{
- memory_region_init_io(&mpu->pin_cfg_iomem, NULL, &omap_pin_cfg_ops, mpu,
- "omap-pin-cfg", 0x800);
- memory_region_add_subregion(system_memory, base, &mpu->pin_cfg_iomem);
- omap_pin_cfg_reset(mpu);
-}
-
-/* Device Identification, Die Identification */
-static uint64_t omap_id_read(void *opaque, hwaddr addr,
- unsigned size)
-{
- struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
-
- if (size != 4) {
- return omap_badwidth_read32(opaque, addr);
- }
-
- switch (addr) {
- case 0xfffe1800: /* DIE_ID_LSB */
- return 0xc9581f0e;
- case 0xfffe1804: /* DIE_ID_MSB */
- return 0xa8858bfa;
-
- case 0xfffe2000: /* PRODUCT_ID_LSB */
- return 0x00aaaafc;
- case 0xfffe2004: /* PRODUCT_ID_MSB */
- return 0xcafeb574;
-
- case 0xfffed400: /* JTAG_ID_LSB */
- switch (s->mpu_model) {
- case omap310:
- return 0x03310315;
- case omap1510:
- return 0x03310115;
- default:
- hw_error("%s: bad mpu model\n", __FUNCTION__);
- }
- break;
-
- case 0xfffed404: /* JTAG_ID_MSB */
- switch (s->mpu_model) {
- case omap310:
- return 0xfb57402f;
- case omap1510:
- return 0xfb47002f;
- default:
- hw_error("%s: bad mpu model\n", __FUNCTION__);
- }
- break;
- }
-
- OMAP_BAD_REG(addr);
- return 0;
-}
-
-static void omap_id_write(void *opaque, hwaddr addr,
- uint64_t value, unsigned size)
-{
- if (size != 4) {
- omap_badwidth_write32(opaque, addr, value);
- return;
- }
-
- OMAP_BAD_REG(addr);
-}
-
-static const MemoryRegionOps omap_id_ops = {
- .read = omap_id_read,
- .write = omap_id_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static void omap_id_init(MemoryRegion *memory, struct omap_mpu_state_s *mpu)
-{
- memory_region_init_io(&mpu->id_iomem, NULL, &omap_id_ops, mpu,
- "omap-id", 0x100000000ULL);
- memory_region_init_alias(&mpu->id_iomem_e18, NULL, "omap-id-e18", &mpu->id_iomem,
- 0xfffe1800, 0x800);
- memory_region_add_subregion(memory, 0xfffe1800, &mpu->id_iomem_e18);
- memory_region_init_alias(&mpu->id_iomem_ed4, NULL, "omap-id-ed4", &mpu->id_iomem,
- 0xfffed400, 0x100);
- memory_region_add_subregion(memory, 0xfffed400, &mpu->id_iomem_ed4);
- if (!cpu_is_omap15xx(mpu)) {
- memory_region_init_alias(&mpu->id_iomem_ed4, NULL, "omap-id-e20",
- &mpu->id_iomem, 0xfffe2000, 0x800);
- memory_region_add_subregion(memory, 0xfffe2000, &mpu->id_iomem_e20);
- }
-}
-
-/* MPUI Control (Dummy) */
-static uint64_t omap_mpui_read(void *opaque, hwaddr addr,
- unsigned size)
-{
- struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
-
- if (size != 4) {
- return omap_badwidth_read32(opaque, addr);
- }
-
- switch (addr) {
- case 0x00: /* CTRL */
- return s->mpui_ctrl;
- case 0x04: /* DEBUG_ADDR */
- return 0x01ffffff;
- case 0x08: /* DEBUG_DATA */
- return 0xffffffff;
- case 0x0c: /* DEBUG_FLAG */
- return 0x00000800;
- case 0x10: /* STATUS */
- return 0x00000000;
-
- /* Not in OMAP310 */
- case 0x14: /* DSP_STATUS */
- case 0x18: /* DSP_BOOT_CONFIG */
- return 0x00000000;
- case 0x1c: /* DSP_MPUI_CONFIG */
- return 0x0000ffff;
- }
-
- OMAP_BAD_REG(addr);
- return 0;
-}
-
-static void omap_mpui_write(void *opaque, hwaddr addr,
- uint64_t value, unsigned size)
-{
- struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
-
- if (size != 4) {
- omap_badwidth_write32(opaque, addr, value);
- return;
- }
-
- switch (addr) {
- case 0x00: /* CTRL */
- s->mpui_ctrl = value & 0x007fffff;
- break;
-
- case 0x04: /* DEBUG_ADDR */
- case 0x08: /* DEBUG_DATA */
- case 0x0c: /* DEBUG_FLAG */
- case 0x10: /* STATUS */
- /* Not in OMAP310 */
- case 0x14: /* DSP_STATUS */
- OMAP_RO_REG(addr);
- break;
- case 0x18: /* DSP_BOOT_CONFIG */
- case 0x1c: /* DSP_MPUI_CONFIG */
- break;
-
- default:
- OMAP_BAD_REG(addr);
- }
-}
-
-static const MemoryRegionOps omap_mpui_ops = {
- .read = omap_mpui_read,
- .write = omap_mpui_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static void omap_mpui_reset(struct omap_mpu_state_s *s)
-{
- s->mpui_ctrl = 0x0003ff1b;
-}
-
-static void omap_mpui_init(MemoryRegion *memory, hwaddr base,
- struct omap_mpu_state_s *mpu)
-{
- memory_region_init_io(&mpu->mpui_iomem, NULL, &omap_mpui_ops, mpu,
- "omap-mpui", 0x100);
- memory_region_add_subregion(memory, base, &mpu->mpui_iomem);
-
- omap_mpui_reset(mpu);
-}
-
-/* TIPB Bridges */
-struct omap_tipb_bridge_s {
- qemu_irq abort;
- MemoryRegion iomem;
-
- int width_intr;
- uint16_t control;
- uint16_t alloc;
- uint16_t buffer;
- uint16_t enh_control;
-};
-
-static uint64_t omap_tipb_bridge_read(void *opaque, hwaddr addr,
- unsigned size)
-{
- struct omap_tipb_bridge_s *s = (struct omap_tipb_bridge_s *) opaque;
-
- if (size < 2) {
- return omap_badwidth_read16(opaque, addr);
- }
-
- switch (addr) {
- case 0x00: /* TIPB_CNTL */
- return s->control;
- case 0x04: /* TIPB_BUS_ALLOC */
- return s->alloc;
- case 0x08: /* MPU_TIPB_CNTL */
- return s->buffer;
- case 0x0c: /* ENHANCED_TIPB_CNTL */
- return s->enh_control;
- case 0x10: /* ADDRESS_DBG */
- case 0x14: /* DATA_DEBUG_LOW */
- case 0x18: /* DATA_DEBUG_HIGH */
- return 0xffff;
- case 0x1c: /* DEBUG_CNTR_SIG */
- return 0x00f8;
- }
-
- OMAP_BAD_REG(addr);
- return 0;
-}
-
-static void omap_tipb_bridge_write(void *opaque, hwaddr addr,
- uint64_t value, unsigned size)
-{
- struct omap_tipb_bridge_s *s = (struct omap_tipb_bridge_s *) opaque;
-
- if (size < 2) {
- omap_badwidth_write16(opaque, addr, value);
- return;
- }
-
- switch (addr) {
- case 0x00: /* TIPB_CNTL */
- s->control = value & 0xffff;
- break;
-
- case 0x04: /* TIPB_BUS_ALLOC */
- s->alloc = value & 0x003f;
- break;
-
- case 0x08: /* MPU_TIPB_CNTL */
- s->buffer = value & 0x0003;
- break;
-
- case 0x0c: /* ENHANCED_TIPB_CNTL */
- s->width_intr = !(value & 2);
- s->enh_control = value & 0x000f;
- break;
-
- case 0x10: /* ADDRESS_DBG */
- case 0x14: /* DATA_DEBUG_LOW */
- case 0x18: /* DATA_DEBUG_HIGH */
- case 0x1c: /* DEBUG_CNTR_SIG */
- OMAP_RO_REG(addr);
- break;
-
- default:
- OMAP_BAD_REG(addr);
- }
-}
-
-static const MemoryRegionOps omap_tipb_bridge_ops = {
- .read = omap_tipb_bridge_read,
- .write = omap_tipb_bridge_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static void omap_tipb_bridge_reset(struct omap_tipb_bridge_s *s)
-{
- s->control = 0xffff;
- s->alloc = 0x0009;
- s->buffer = 0x0000;
- s->enh_control = 0x000f;
-}
-
-static struct omap_tipb_bridge_s *omap_tipb_bridge_init(
- MemoryRegion *memory, hwaddr base,
- qemu_irq abort_irq, omap_clk clk)
-{
- struct omap_tipb_bridge_s *s = g_new0(struct omap_tipb_bridge_s, 1);
-
- s->abort = abort_irq;
- omap_tipb_bridge_reset(s);
-
- memory_region_init_io(&s->iomem, NULL, &omap_tipb_bridge_ops, s,
- "omap-tipb-bridge", 0x100);
- memory_region_add_subregion(memory, base, &s->iomem);
-
- return s;
-}
-
-/* Dummy Traffic Controller's Memory Interface */
-static uint64_t omap_tcmi_read(void *opaque, hwaddr addr,
- unsigned size)
-{
- struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
- uint32_t ret;
-
- if (size != 4) {
- return omap_badwidth_read32(opaque, addr);
- }
-
- switch (addr) {
- case 0x00: /* IMIF_PRIO */
- case 0x04: /* EMIFS_PRIO */
- case 0x08: /* EMIFF_PRIO */
- case 0x0c: /* EMIFS_CONFIG */
- case 0x10: /* EMIFS_CS0_CONFIG */
- case 0x14: /* EMIFS_CS1_CONFIG */
- case 0x18: /* EMIFS_CS2_CONFIG */
- case 0x1c: /* EMIFS_CS3_CONFIG */
- case 0x24: /* EMIFF_MRS */
- case 0x28: /* TIMEOUT1 */
- case 0x2c: /* TIMEOUT2 */
- case 0x30: /* TIMEOUT3 */
- case 0x3c: /* EMIFF_SDRAM_CONFIG_2 */
- case 0x40: /* EMIFS_CFG_DYN_WAIT */
- return s->tcmi_regs[addr >> 2];
-
- case 0x20: /* EMIFF_SDRAM_CONFIG */
- ret = s->tcmi_regs[addr >> 2];
- s->tcmi_regs[addr >> 2] &= ~1; /* XXX: Clear SLRF on SDRAM access */
- /* XXX: We can try using the VGA_DIRTY flag for this */
- return ret;
- }
-
- OMAP_BAD_REG(addr);
- return 0;
-}
-
-static void omap_tcmi_write(void *opaque, hwaddr addr,
- uint64_t value, unsigned size)
-{
- struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
-
- if (size != 4) {
- omap_badwidth_write32(opaque, addr, value);
- return;
- }
-
- switch (addr) {
- case 0x00: /* IMIF_PRIO */
- case 0x04: /* EMIFS_PRIO */
- case 0x08: /* EMIFF_PRIO */
- case 0x10: /* EMIFS_CS0_CONFIG */
- case 0x14: /* EMIFS_CS1_CONFIG */
- case 0x18: /* EMIFS_CS2_CONFIG */
- case 0x1c: /* EMIFS_CS3_CONFIG */
- case 0x20: /* EMIFF_SDRAM_CONFIG */
- case 0x24: /* EMIFF_MRS */
- case 0x28: /* TIMEOUT1 */
- case 0x2c: /* TIMEOUT2 */
- case 0x30: /* TIMEOUT3 */
- case 0x3c: /* EMIFF_SDRAM_CONFIG_2 */
- case 0x40: /* EMIFS_CFG_DYN_WAIT */
- s->tcmi_regs[addr >> 2] = value;
- break;
- case 0x0c: /* EMIFS_CONFIG */
- s->tcmi_regs[addr >> 2] = (value & 0xf) | (1 << 4);
- break;
-
- default:
- OMAP_BAD_REG(addr);
- }
-}
-
-static const MemoryRegionOps omap_tcmi_ops = {
- .read = omap_tcmi_read,
- .write = omap_tcmi_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static void omap_tcmi_reset(struct omap_mpu_state_s *mpu)
-{
- mpu->tcmi_regs[0x00 >> 2] = 0x00000000;
- mpu->tcmi_regs[0x04 >> 2] = 0x00000000;
- mpu->tcmi_regs[0x08 >> 2] = 0x00000000;
- mpu->tcmi_regs[0x0c >> 2] = 0x00000010;
- mpu->tcmi_regs[0x10 >> 2] = 0x0010fffb;
- mpu->tcmi_regs[0x14 >> 2] = 0x0010fffb;
- mpu->tcmi_regs[0x18 >> 2] = 0x0010fffb;
- mpu->tcmi_regs[0x1c >> 2] = 0x0010fffb;
- mpu->tcmi_regs[0x20 >> 2] = 0x00618800;
- mpu->tcmi_regs[0x24 >> 2] = 0x00000037;
- mpu->tcmi_regs[0x28 >> 2] = 0x00000000;
- mpu->tcmi_regs[0x2c >> 2] = 0x00000000;
- mpu->tcmi_regs[0x30 >> 2] = 0x00000000;
- mpu->tcmi_regs[0x3c >> 2] = 0x00000003;
- mpu->tcmi_regs[0x40 >> 2] = 0x00000000;
-}
-
-static void omap_tcmi_init(MemoryRegion *memory, hwaddr base,
- struct omap_mpu_state_s *mpu)
-{
- memory_region_init_io(&mpu->tcmi_iomem, NULL, &omap_tcmi_ops, mpu,
- "omap-tcmi", 0x100);
- memory_region_add_subregion(memory, base, &mpu->tcmi_iomem);
- omap_tcmi_reset(mpu);
-}
-
-/* Digital phase-locked loops control */
-struct dpll_ctl_s {
- MemoryRegion iomem;
- uint16_t mode;
- omap_clk dpll;
-};
-
-static uint64_t omap_dpll_read(void *opaque, hwaddr addr,
- unsigned size)
-{
- struct dpll_ctl_s *s = (struct dpll_ctl_s *) opaque;
-
- if (size != 2) {
- return omap_badwidth_read16(opaque, addr);
- }
-
- if (addr == 0x00) /* CTL_REG */
- return s->mode;
-
- OMAP_BAD_REG(addr);
- return 0;
-}
-
-static void omap_dpll_write(void *opaque, hwaddr addr,
- uint64_t value, unsigned size)
-{
- struct dpll_ctl_s *s = (struct dpll_ctl_s *) opaque;
- uint16_t diff;
- static const int bypass_div[4] = { 1, 2, 4, 4 };
- int div, mult;
-
- if (size != 2) {
- omap_badwidth_write16(opaque, addr, value);
- return;
- }
-
- if (addr == 0x00) { /* CTL_REG */
- /* See omap_ulpd_pm_write() too */
- diff = s->mode & value;
- s->mode = value & 0x2fff;
- if (diff & (0x3ff << 2)) {
- if (value & (1 << 4)) { /* PLL_ENABLE */
- div = ((value >> 5) & 3) + 1; /* PLL_DIV */
- mult = MIN((value >> 7) & 0x1f, 1); /* PLL_MULT */
- } else {
- div = bypass_div[((value >> 2) & 3)]; /* BYPASS_DIV */
- mult = 1;
- }
- omap_clk_setrate(s->dpll, div, mult);
- }
-
- /* Enter the desired mode. */
- s->mode = (s->mode & 0xfffe) | ((s->mode >> 4) & 1);
-
- /* Act as if the lock is restored. */
- s->mode |= 2;
- } else {
- OMAP_BAD_REG(addr);
- }
-}
-
-static const MemoryRegionOps omap_dpll_ops = {
- .read = omap_dpll_read,
- .write = omap_dpll_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static void omap_dpll_reset(struct dpll_ctl_s *s)
-{
- s->mode = 0x2002;
- omap_clk_setrate(s->dpll, 1, 1);
-}
-
-static struct dpll_ctl_s *omap_dpll_init(MemoryRegion *memory,
- hwaddr base, omap_clk clk)
-{
- struct dpll_ctl_s *s = g_malloc0(sizeof(*s));
- memory_region_init_io(&s->iomem, NULL, &omap_dpll_ops, s, "omap-dpll", 0x100);
-
- s->dpll = clk;
- omap_dpll_reset(s);
-
- memory_region_add_subregion(memory, base, &s->iomem);
- return s;
-}
-
-/* MPU Clock/Reset/Power Mode Control */
-static uint64_t omap_clkm_read(void *opaque, hwaddr addr,
- unsigned size)
-{
- struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
-
- if (size != 2) {
- return omap_badwidth_read16(opaque, addr);
- }
-
- switch (addr) {
- case 0x00: /* ARM_CKCTL */
- return s->clkm.arm_ckctl;
-
- case 0x04: /* ARM_IDLECT1 */
- return s->clkm.arm_idlect1;
-
- case 0x08: /* ARM_IDLECT2 */
- return s->clkm.arm_idlect2;
-
- case 0x0c: /* ARM_EWUPCT */
- return s->clkm.arm_ewupct;
-
- case 0x10: /* ARM_RSTCT1 */
- return s->clkm.arm_rstct1;
-
- case 0x14: /* ARM_RSTCT2 */
- return s->clkm.arm_rstct2;
-
- case 0x18: /* ARM_SYSST */
- return (s->clkm.clocking_scheme << 11) | s->clkm.cold_start;
-
- case 0x1c: /* ARM_CKOUT1 */
- return s->clkm.arm_ckout1;
-
- case 0x20: /* ARM_CKOUT2 */
- break;
- }
-
- OMAP_BAD_REG(addr);
- return 0;
-}
-
-static inline void omap_clkm_ckctl_update(struct omap_mpu_state_s *s,
- uint16_t diff, uint16_t value)
-{
- omap_clk clk;
-
- if (diff & (1 << 14)) { /* ARM_INTHCK_SEL */
- if (value & (1 << 14))
- /* Reserved */;
- else {
- clk = omap_findclk(s, "arminth_ck");
- omap_clk_reparent(clk, omap_findclk(s, "tc_ck"));
- }
- }
- if (diff & (1 << 12)) { /* ARM_TIMXO */
- clk = omap_findclk(s, "armtim_ck");
- if (value & (1 << 12))
- omap_clk_reparent(clk, omap_findclk(s, "clkin"));
- else
- omap_clk_reparent(clk, omap_findclk(s, "ck_gen1"));
- }
- /* XXX: en_dspck */
- if (diff & (3 << 10)) { /* DSPMMUDIV */
- clk = omap_findclk(s, "dspmmu_ck");
- omap_clk_setrate(clk, 1 << ((value >> 10) & 3), 1);
- }
- if (diff & (3 << 8)) { /* TCDIV */
- clk = omap_findclk(s, "tc_ck");
- omap_clk_setrate(clk, 1 << ((value >> 8) & 3), 1);
- }
- if (diff & (3 << 6)) { /* DSPDIV */
- clk = omap_findclk(s, "dsp_ck");
- omap_clk_setrate(clk, 1 << ((value >> 6) & 3), 1);
- }
- if (diff & (3 << 4)) { /* ARMDIV */
- clk = omap_findclk(s, "arm_ck");
- omap_clk_setrate(clk, 1 << ((value >> 4) & 3), 1);
- }
- if (diff & (3 << 2)) { /* LCDDIV */
- clk = omap_findclk(s, "lcd_ck");
- omap_clk_setrate(clk, 1 << ((value >> 2) & 3), 1);
- }
- if (diff & (3 << 0)) { /* PERDIV */
- clk = omap_findclk(s, "armper_ck");
- omap_clk_setrate(clk, 1 << ((value >> 0) & 3), 1);
- }
-}
-
-static inline void omap_clkm_idlect1_update(struct omap_mpu_state_s *s,
- uint16_t diff, uint16_t value)
-{
- omap_clk clk;
-
- if (value & (1 << 11)) { /* SETARM_IDLE */
- cpu_interrupt(CPU(s->cpu), CPU_INTERRUPT_HALT);
- }
- if (!(value & (1 << 10))) /* WKUP_MODE */
- qemu_system_shutdown_request(); /* XXX: disable wakeup from IRQ */
-
-#define SET_CANIDLE(clock, bit) \
- if (diff & (1 << bit)) { \
- clk = omap_findclk(s, clock); \
- omap_clk_canidle(clk, (value >> bit) & 1); \
- }
- SET_CANIDLE("mpuwd_ck", 0) /* IDLWDT_ARM */
- SET_CANIDLE("armxor_ck", 1) /* IDLXORP_ARM */
- SET_CANIDLE("mpuper_ck", 2) /* IDLPER_ARM */
- SET_CANIDLE("lcd_ck", 3) /* IDLLCD_ARM */
- SET_CANIDLE("lb_ck", 4) /* IDLLB_ARM */
- SET_CANIDLE("hsab_ck", 5) /* IDLHSAB_ARM */
- SET_CANIDLE("tipb_ck", 6) /* IDLIF_ARM */
- SET_CANIDLE("dma_ck", 6) /* IDLIF_ARM */
- SET_CANIDLE("tc_ck", 6) /* IDLIF_ARM */
- SET_CANIDLE("dpll1", 7) /* IDLDPLL_ARM */
- SET_CANIDLE("dpll2", 7) /* IDLDPLL_ARM */
- SET_CANIDLE("dpll3", 7) /* IDLDPLL_ARM */
- SET_CANIDLE("mpui_ck", 8) /* IDLAPI_ARM */
- SET_CANIDLE("armtim_ck", 9) /* IDLTIM_ARM */
-}
-
-static inline void omap_clkm_idlect2_update(struct omap_mpu_state_s *s,
- uint16_t diff, uint16_t value)
-{
- omap_clk clk;
-
-#define SET_ONOFF(clock, bit) \
- if (diff & (1 << bit)) { \
- clk = omap_findclk(s, clock); \
- omap_clk_onoff(clk, (value >> bit) & 1); \
- }
- SET_ONOFF("mpuwd_ck", 0) /* EN_WDTCK */
- SET_ONOFF("armxor_ck", 1) /* EN_XORPCK */
- SET_ONOFF("mpuper_ck", 2) /* EN_PERCK */
- SET_ONOFF("lcd_ck", 3) /* EN_LCDCK */
- SET_ONOFF("lb_ck", 4) /* EN_LBCK */
- SET_ONOFF("hsab_ck", 5) /* EN_HSABCK */
- SET_ONOFF("mpui_ck", 6) /* EN_APICK */
- SET_ONOFF("armtim_ck", 7) /* EN_TIMCK */
- SET_CANIDLE("dma_ck", 8) /* DMACK_REQ */
- SET_ONOFF("arm_gpio_ck", 9) /* EN_GPIOCK */
- SET_ONOFF("lbfree_ck", 10) /* EN_LBFREECK */
-}
-
-static inline void omap_clkm_ckout1_update(struct omap_mpu_state_s *s,
- uint16_t diff, uint16_t value)
-{
- omap_clk clk;
-
- if (diff & (3 << 4)) { /* TCLKOUT */
- clk = omap_findclk(s, "tclk_out");
- switch ((value >> 4) & 3) {
- case 1:
- omap_clk_reparent(clk, omap_findclk(s, "ck_gen3"));
- omap_clk_onoff(clk, 1);
- break;
- case 2:
- omap_clk_reparent(clk, omap_findclk(s, "tc_ck"));
- omap_clk_onoff(clk, 1);
- break;
- default:
- omap_clk_onoff(clk, 0);
- }
- }
- if (diff & (3 << 2)) { /* DCLKOUT */
- clk = omap_findclk(s, "dclk_out");
- switch ((value >> 2) & 3) {
- case 0:
- omap_clk_reparent(clk, omap_findclk(s, "dspmmu_ck"));
- break;
- case 1:
- omap_clk_reparent(clk, omap_findclk(s, "ck_gen2"));
- break;
- case 2:
- omap_clk_reparent(clk, omap_findclk(s, "dsp_ck"));
- break;
- case 3:
- omap_clk_reparent(clk, omap_findclk(s, "ck_ref14"));
- break;
- }
- }
- if (diff & (3 << 0)) { /* ACLKOUT */
- clk = omap_findclk(s, "aclk_out");
- switch ((value >> 0) & 3) {
- case 1:
- omap_clk_reparent(clk, omap_findclk(s, "ck_gen1"));
- omap_clk_onoff(clk, 1);
- break;
- case 2:
- omap_clk_reparent(clk, omap_findclk(s, "arm_ck"));
- omap_clk_onoff(clk, 1);
- break;
- case 3:
- omap_clk_reparent(clk, omap_findclk(s, "ck_ref14"));
- omap_clk_onoff(clk, 1);
- break;
- default:
- omap_clk_onoff(clk, 0);
- }
- }
-}
-
-static void omap_clkm_write(void *opaque, hwaddr addr,
- uint64_t value, unsigned size)
-{
- struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
- uint16_t diff;
- omap_clk clk;
- static const char *clkschemename[8] = {
- "fully synchronous", "fully asynchronous", "synchronous scalable",
- "mix mode 1", "mix mode 2", "bypass mode", "mix mode 3", "mix mode 4",
- };
-
- if (size != 2) {
- omap_badwidth_write16(opaque, addr, value);
- return;
- }
-
- switch (addr) {
- case 0x00: /* ARM_CKCTL */
- diff = s->clkm.arm_ckctl ^ value;
- s->clkm.arm_ckctl = value & 0x7fff;
- omap_clkm_ckctl_update(s, diff, value);
- return;
-
- case 0x04: /* ARM_IDLECT1 */
- diff = s->clkm.arm_idlect1 ^ value;
- s->clkm.arm_idlect1 = value & 0x0fff;
- omap_clkm_idlect1_update(s, diff, value);
- return;
-
- case 0x08: /* ARM_IDLECT2 */
- diff = s->clkm.arm_idlect2 ^ value;
- s->clkm.arm_idlect2 = value & 0x07ff;
- omap_clkm_idlect2_update(s, diff, value);
- return;
-
- case 0x0c: /* ARM_EWUPCT */
- s->clkm.arm_ewupct = value & 0x003f;
- return;
-
- case 0x10: /* ARM_RSTCT1 */
- diff = s->clkm.arm_rstct1 ^ value;
- s->clkm.arm_rstct1 = value & 0x0007;
- if (value & 9) {
- qemu_system_reset_request();
- s->clkm.cold_start = 0xa;
- }
- if (diff & ~value & 4) { /* DSP_RST */
- omap_mpui_reset(s);
- omap_tipb_bridge_reset(s->private_tipb);
- omap_tipb_bridge_reset(s->public_tipb);
- }
- if (diff & 2) { /* DSP_EN */
- clk = omap_findclk(s, "dsp_ck");
- omap_clk_canidle(clk, (~value >> 1) & 1);
- }
- return;
-
- case 0x14: /* ARM_RSTCT2 */
- s->clkm.arm_rstct2 = value & 0x0001;
- return;
-
- case 0x18: /* ARM_SYSST */
- if ((s->clkm.clocking_scheme ^ (value >> 11)) & 7) {
- s->clkm.clocking_scheme = (value >> 11) & 7;
- printf("%s: clocking scheme set to %s\n", __FUNCTION__,
- clkschemename[s->clkm.clocking_scheme]);
- }
- s->clkm.cold_start &= value & 0x3f;
- return;
-
- case 0x1c: /* ARM_CKOUT1 */
- diff = s->clkm.arm_ckout1 ^ value;
- s->clkm.arm_ckout1 = value & 0x003f;
- omap_clkm_ckout1_update(s, diff, value);
- return;
-
- case 0x20: /* ARM_CKOUT2 */
- default:
- OMAP_BAD_REG(addr);
- }
-}
-
-static const MemoryRegionOps omap_clkm_ops = {
- .read = omap_clkm_read,
- .write = omap_clkm_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static uint64_t omap_clkdsp_read(void *opaque, hwaddr addr,
- unsigned size)
-{
- struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
- CPUState *cpu = CPU(s->cpu);
-
- if (size != 2) {
- return omap_badwidth_read16(opaque, addr);
- }
-
- switch (addr) {
- case 0x04: /* DSP_IDLECT1 */
- return s->clkm.dsp_idlect1;
-
- case 0x08: /* DSP_IDLECT2 */
- return s->clkm.dsp_idlect2;
-
- case 0x14: /* DSP_RSTCT2 */
- return s->clkm.dsp_rstct2;
-
- case 0x18: /* DSP_SYSST */
- cpu = CPU(s->cpu);
- return (s->clkm.clocking_scheme << 11) | s->clkm.cold_start |
- (cpu->halted << 6); /* Quite useless... */
- }
-
- OMAP_BAD_REG(addr);
- return 0;
-}
-
-static inline void omap_clkdsp_idlect1_update(struct omap_mpu_state_s *s,
- uint16_t diff, uint16_t value)
-{
- omap_clk clk;
-
- SET_CANIDLE("dspxor_ck", 1); /* IDLXORP_DSP */
-}
-
-static inline void omap_clkdsp_idlect2_update(struct omap_mpu_state_s *s,
- uint16_t diff, uint16_t value)
-{
- omap_clk clk;
-
- SET_ONOFF("dspxor_ck", 1); /* EN_XORPCK */
-}
-
-static void omap_clkdsp_write(void *opaque, hwaddr addr,
- uint64_t value, unsigned size)
-{
- struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
- uint16_t diff;
-
- if (size != 2) {
- omap_badwidth_write16(opaque, addr, value);
- return;
- }
-
- switch (addr) {
- case 0x04: /* DSP_IDLECT1 */
- diff = s->clkm.dsp_idlect1 ^ value;
- s->clkm.dsp_idlect1 = value & 0x01f7;
- omap_clkdsp_idlect1_update(s, diff, value);
- break;
-
- case 0x08: /* DSP_IDLECT2 */
- s->clkm.dsp_idlect2 = value & 0x0037;
- diff = s->clkm.dsp_idlect1 ^ value;
- omap_clkdsp_idlect2_update(s, diff, value);
- break;
-
- case 0x14: /* DSP_RSTCT2 */
- s->clkm.dsp_rstct2 = value & 0x0001;
- break;
-
- case 0x18: /* DSP_SYSST */
- s->clkm.cold_start &= value & 0x3f;
- break;
-
- default:
- OMAP_BAD_REG(addr);
- }
-}
-
-static const MemoryRegionOps omap_clkdsp_ops = {
- .read = omap_clkdsp_read,
- .write = omap_clkdsp_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static void omap_clkm_reset(struct omap_mpu_state_s *s)
-{
- if (s->wdt && s->wdt->reset)
- s->clkm.cold_start = 0x6;
- s->clkm.clocking_scheme = 0;
- omap_clkm_ckctl_update(s, ~0, 0x3000);
- s->clkm.arm_ckctl = 0x3000;
- omap_clkm_idlect1_update(s, s->clkm.arm_idlect1 ^ 0x0400, 0x0400);
- s->clkm.arm_idlect1 = 0x0400;
- omap_clkm_idlect2_update(s, s->clkm.arm_idlect2 ^ 0x0100, 0x0100);
- s->clkm.arm_idlect2 = 0x0100;
- s->clkm.arm_ewupct = 0x003f;
- s->clkm.arm_rstct1 = 0x0000;
- s->clkm.arm_rstct2 = 0x0000;
- s->clkm.arm_ckout1 = 0x0015;
- s->clkm.dpll1_mode = 0x2002;
- omap_clkdsp_idlect1_update(s, s->clkm.dsp_idlect1 ^ 0x0040, 0x0040);
- s->clkm.dsp_idlect1 = 0x0040;
- omap_clkdsp_idlect2_update(s, ~0, 0x0000);
- s->clkm.dsp_idlect2 = 0x0000;
- s->clkm.dsp_rstct2 = 0x0000;
-}
-
-static void omap_clkm_init(MemoryRegion *memory, hwaddr mpu_base,
- hwaddr dsp_base, struct omap_mpu_state_s *s)
-{
- memory_region_init_io(&s->clkm_iomem, NULL, &omap_clkm_ops, s,
- "omap-clkm", 0x100);
- memory_region_init_io(&s->clkdsp_iomem, NULL, &omap_clkdsp_ops, s,
- "omap-clkdsp", 0x1000);
-
- s->clkm.arm_idlect1 = 0x03ff;
- s->clkm.arm_idlect2 = 0x0100;
- s->clkm.dsp_idlect1 = 0x0002;
- omap_clkm_reset(s);
- s->clkm.cold_start = 0x3a;
-
- memory_region_add_subregion(memory, mpu_base, &s->clkm_iomem);
- memory_region_add_subregion(memory, dsp_base, &s->clkdsp_iomem);
-}
-
-/* MPU I/O */
-struct omap_mpuio_s {
- qemu_irq irq;
- qemu_irq kbd_irq;
- qemu_irq *in;
- qemu_irq handler[16];
- qemu_irq wakeup;
- MemoryRegion iomem;
-
- uint16_t inputs;
- uint16_t outputs;
- uint16_t dir;
- uint16_t edge;
- uint16_t mask;
- uint16_t ints;
-
- uint16_t debounce;
- uint16_t latch;
- uint8_t event;
-
- uint8_t buttons[5];
- uint8_t row_latch;
- uint8_t cols;
- int kbd_mask;
- int clk;
-};
-
-static void omap_mpuio_set(void *opaque, int line, int level)
-{
- struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
- uint16_t prev = s->inputs;
-
- if (level)
- s->inputs |= 1 << line;
- else
- s->inputs &= ~(1 << line);
-
- if (((1 << line) & s->dir & ~s->mask) && s->clk) {
- if ((s->edge & s->inputs & ~prev) | (~s->edge & ~s->inputs & prev)) {
- s->ints |= 1 << line;
- qemu_irq_raise(s->irq);
- /* TODO: wakeup */
- }
- if ((s->event & (1 << 0)) && /* SET_GPIO_EVENT_MODE */
- (s->event >> 1) == line) /* PIN_SELECT */
- s->latch = s->inputs;
- }
-}
-
-static void omap_mpuio_kbd_update(struct omap_mpuio_s *s)
-{
- int i;
- uint8_t *row, rows = 0, cols = ~s->cols;
-
- for (row = s->buttons + 4, i = 1 << 4; i; row --, i >>= 1)
- if (*row & cols)
- rows |= i;
-
- qemu_set_irq(s->kbd_irq, rows && !s->kbd_mask && s->clk);
- s->row_latch = ~rows;
-}
-
-static uint64_t omap_mpuio_read(void *opaque, hwaddr addr,
- unsigned size)
-{
- struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
- int offset = addr & OMAP_MPUI_REG_MASK;
- uint16_t ret;
-
- if (size != 2) {
- return omap_badwidth_read16(opaque, addr);
- }
-
- switch (offset) {
- case 0x00: /* INPUT_LATCH */
- return s->inputs;
-
- case 0x04: /* OUTPUT_REG */
- return s->outputs;
-
- case 0x08: /* IO_CNTL */
- return s->dir;
-
- case 0x10: /* KBR_LATCH */
- return s->row_latch;
-
- case 0x14: /* KBC_REG */
- return s->cols;
-
- case 0x18: /* GPIO_EVENT_MODE_REG */
- return s->event;
-
- case 0x1c: /* GPIO_INT_EDGE_REG */
- return s->edge;
-
- case 0x20: /* KBD_INT */
- return (~s->row_latch & 0x1f) && !s->kbd_mask;
-
- case 0x24: /* GPIO_INT */
- ret = s->ints;
- s->ints &= s->mask;
- if (ret)
- qemu_irq_lower(s->irq);
- return ret;
-
- case 0x28: /* KBD_MASKIT */
- return s->kbd_mask;
-
- case 0x2c: /* GPIO_MASKIT */
- return s->mask;
-
- case 0x30: /* GPIO_DEBOUNCING_REG */
- return s->debounce;
-
- case 0x34: /* GPIO_LATCH_REG */
- return s->latch;
- }
-
- OMAP_BAD_REG(addr);
- return 0;
-}
-
-static void omap_mpuio_write(void *opaque, hwaddr addr,
- uint64_t value, unsigned size)
-{
- struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
- int offset = addr & OMAP_MPUI_REG_MASK;
- uint16_t diff;
- int ln;
-
- if (size != 2) {
- omap_badwidth_write16(opaque, addr, value);
- return;
- }
-
- switch (offset) {
- case 0x04: /* OUTPUT_REG */
- diff = (s->outputs ^ value) & ~s->dir;
- s->outputs = value;
- while ((ln = ctz32(diff)) != 32) {
- if (s->handler[ln])
- qemu_set_irq(s->handler[ln], (value >> ln) & 1);
- diff &= ~(1 << ln);
- }
- break;
-
- case 0x08: /* IO_CNTL */
- diff = s->outputs & (s->dir ^ value);
- s->dir = value;
-
- value = s->outputs & ~s->dir;
- while ((ln = ctz32(diff)) != 32) {
- if (s->handler[ln])
- qemu_set_irq(s->handler[ln], (value >> ln) & 1);
- diff &= ~(1 << ln);
- }
- break;
-
- case 0x14: /* KBC_REG */
- s->cols = value;
- omap_mpuio_kbd_update(s);
- break;
-
- case 0x18: /* GPIO_EVENT_MODE_REG */
- s->event = value & 0x1f;
- break;
-
- case 0x1c: /* GPIO_INT_EDGE_REG */
- s->edge = value;
- break;
-
- case 0x28: /* KBD_MASKIT */
- s->kbd_mask = value & 1;
- omap_mpuio_kbd_update(s);
- break;
-
- case 0x2c: /* GPIO_MASKIT */
- s->mask = value;
- break;
-
- case 0x30: /* GPIO_DEBOUNCING_REG */
- s->debounce = value & 0x1ff;
- break;
-
- case 0x00: /* INPUT_LATCH */
- case 0x10: /* KBR_LATCH */
- case 0x20: /* KBD_INT */
- case 0x24: /* GPIO_INT */
- case 0x34: /* GPIO_LATCH_REG */
- OMAP_RO_REG(addr);
- return;
-
- default:
- OMAP_BAD_REG(addr);
- return;
- }
-}
-
-static const MemoryRegionOps omap_mpuio_ops = {
- .read = omap_mpuio_read,
- .write = omap_mpuio_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static void omap_mpuio_reset(struct omap_mpuio_s *s)
-{
- s->inputs = 0;
- s->outputs = 0;
- s->dir = ~0;
- s->event = 0;
- s->edge = 0;
- s->kbd_mask = 0;
- s->mask = 0;
- s->debounce = 0;
- s->latch = 0;
- s->ints = 0;
- s->row_latch = 0x1f;
- s->clk = 1;
-}
-
-static void omap_mpuio_onoff(void *opaque, int line, int on)
-{
- struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
-
- s->clk = on;
- if (on)
- omap_mpuio_kbd_update(s);
-}
-
-static struct omap_mpuio_s *omap_mpuio_init(MemoryRegion *memory,
- hwaddr base,
- qemu_irq kbd_int, qemu_irq gpio_int, qemu_irq wakeup,
- omap_clk clk)
-{
- struct omap_mpuio_s *s = g_new0(struct omap_mpuio_s, 1);
-
- s->irq = gpio_int;
- s->kbd_irq = kbd_int;
- s->wakeup = wakeup;
- s->in = qemu_allocate_irqs(omap_mpuio_set, s, 16);
- omap_mpuio_reset(s);
-
- memory_region_init_io(&s->iomem, NULL, &omap_mpuio_ops, s,
- "omap-mpuio", 0x800);
- memory_region_add_subregion(memory, base, &s->iomem);
-
- omap_clk_adduser(clk, qemu_allocate_irq(omap_mpuio_onoff, s, 0));
-
- return s;
-}
-
-qemu_irq *omap_mpuio_in_get(struct omap_mpuio_s *s)
-{
- return s->in;
-}
-
-void omap_mpuio_out_set(struct omap_mpuio_s *s, int line, qemu_irq handler)
-{
- if (line >= 16 || line < 0)
- hw_error("%s: No GPIO line %i\n", __FUNCTION__, line);
- s->handler[line] = handler;
-}
-
-void omap_mpuio_key(struct omap_mpuio_s *s, int row, int col, int down)
-{
- if (row >= 5 || row < 0)
- hw_error("%s: No key %i-%i\n", __FUNCTION__, col, row);
-
- if (down)
- s->buttons[row] |= 1 << col;
- else
- s->buttons[row] &= ~(1 << col);
-
- omap_mpuio_kbd_update(s);
-}
-
-/* MicroWire Interface */
-struct omap_uwire_s {
- MemoryRegion iomem;
- qemu_irq txirq;
- qemu_irq rxirq;
- qemu_irq txdrq;
-
- uint16_t txbuf;
- uint16_t rxbuf;
- uint16_t control;
- uint16_t setup[5];
-
- uWireSlave *chip[4];
-};
-
-static void omap_uwire_transfer_start(struct omap_uwire_s *s)
-{
- int chipselect = (s->control >> 10) & 3; /* INDEX */
- uWireSlave *slave = s->chip[chipselect];
-
- if ((s->control >> 5) & 0x1f) { /* NB_BITS_WR */
- if (s->control & (1 << 12)) /* CS_CMD */
- if (slave && slave->send)
- slave->send(slave->opaque,
- s->txbuf >> (16 - ((s->control >> 5) & 0x1f)));
- s->control &= ~(1 << 14); /* CSRB */
- /* TODO: depending on s->setup[4] bits [1:0] assert an IRQ or
- * a DRQ. When is the level IRQ supposed to be reset? */
- }
-
- if ((s->control >> 0) & 0x1f) { /* NB_BITS_RD */
- if (s->control & (1 << 12)) /* CS_CMD */
- if (slave && slave->receive)
- s->rxbuf = slave->receive(slave->opaque);
- s->control |= 1 << 15; /* RDRB */
- /* TODO: depending on s->setup[4] bits [1:0] assert an IRQ or
- * a DRQ. When is the level IRQ supposed to be reset? */
- }
-}
-
-static uint64_t omap_uwire_read(void *opaque, hwaddr addr,
- unsigned size)
-{
- struct omap_uwire_s *s = (struct omap_uwire_s *) opaque;
- int offset = addr & OMAP_MPUI_REG_MASK;
-
- if (size != 2) {
- return omap_badwidth_read16(opaque, addr);
- }
-
- switch (offset) {
- case 0x00: /* RDR */
- s->control &= ~(1 << 15); /* RDRB */
- return s->rxbuf;
-
- case 0x04: /* CSR */
- return s->control;
-
- case 0x08: /* SR1 */
- return s->setup[0];
- case 0x0c: /* SR2 */
- return s->setup[1];
- case 0x10: /* SR3 */
- return s->setup[2];
- case 0x14: /* SR4 */
- return s->setup[3];
- case 0x18: /* SR5 */
- return s->setup[4];
- }
-
- OMAP_BAD_REG(addr);
- return 0;
-}
-
-static void omap_uwire_write(void *opaque, hwaddr addr,
- uint64_t value, unsigned size)
-{
- struct omap_uwire_s *s = (struct omap_uwire_s *) opaque;
- int offset = addr & OMAP_MPUI_REG_MASK;
-
- if (size != 2) {
- omap_badwidth_write16(opaque, addr, value);
- return;
- }
-
- switch (offset) {
- case 0x00: /* TDR */
- s->txbuf = value; /* TD */
- if ((s->setup[4] & (1 << 2)) && /* AUTO_TX_EN */
- ((s->setup[4] & (1 << 3)) || /* CS_TOGGLE_TX_EN */
- (s->control & (1 << 12)))) { /* CS_CMD */
- s->control |= 1 << 14; /* CSRB */
- omap_uwire_transfer_start(s);
- }
- break;
-
- case 0x04: /* CSR */
- s->control = value & 0x1fff;
- if (value & (1 << 13)) /* START */
- omap_uwire_transfer_start(s);
- break;
-
- case 0x08: /* SR1 */
- s->setup[0] = value & 0x003f;
- break;
-
- case 0x0c: /* SR2 */
- s->setup[1] = value & 0x0fc0;
- break;
-
- case 0x10: /* SR3 */
- s->setup[2] = value & 0x0003;
- break;
-
- case 0x14: /* SR4 */
- s->setup[3] = value & 0x0001;
- break;
-
- case 0x18: /* SR5 */
- s->setup[4] = value & 0x000f;
- break;
-
- default:
- OMAP_BAD_REG(addr);
- return;
- }
-}
-
-static const MemoryRegionOps omap_uwire_ops = {
- .read = omap_uwire_read,
- .write = omap_uwire_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static void omap_uwire_reset(struct omap_uwire_s *s)
-{
- s->control = 0;
- s->setup[0] = 0;
- s->setup[1] = 0;
- s->setup[2] = 0;
- s->setup[3] = 0;
- s->setup[4] = 0;
-}
-
-static struct omap_uwire_s *omap_uwire_init(MemoryRegion *system_memory,
- hwaddr base,
- qemu_irq txirq, qemu_irq rxirq,
- qemu_irq dma,
- omap_clk clk)
-{
- struct omap_uwire_s *s = g_new0(struct omap_uwire_s, 1);
-
- s->txirq = txirq;
- s->rxirq = rxirq;
- s->txdrq = dma;
- omap_uwire_reset(s);
-
- memory_region_init_io(&s->iomem, NULL, &omap_uwire_ops, s, "omap-uwire", 0x800);
- memory_region_add_subregion(system_memory, base, &s->iomem);
-
- return s;
-}
-
-void omap_uwire_attach(struct omap_uwire_s *s,
- uWireSlave *slave, int chipselect)
-{
- if (chipselect < 0 || chipselect > 3) {
- fprintf(stderr, "%s: Bad chipselect %i\n", __FUNCTION__, chipselect);
- exit(-1);
- }
-
- s->chip[chipselect] = slave;
-}
-
-/* Pseudonoise Pulse-Width Light Modulator */
-struct omap_pwl_s {
- MemoryRegion iomem;
- uint8_t output;
- uint8_t level;
- uint8_t enable;
- int clk;
-};
-
-static void omap_pwl_update(struct omap_pwl_s *s)
-{
- int output = (s->clk && s->enable) ? s->level : 0;
-
- if (output != s->output) {
- s->output = output;
- printf("%s: Backlight now at %i/256\n", __FUNCTION__, output);
- }
-}
-
-static uint64_t omap_pwl_read(void *opaque, hwaddr addr,
- unsigned size)
-{
- struct omap_pwl_s *s = (struct omap_pwl_s *) opaque;
- int offset = addr & OMAP_MPUI_REG_MASK;
-
- if (size != 1) {
- return omap_badwidth_read8(opaque, addr);
- }
-
- switch (offset) {
- case 0x00: /* PWL_LEVEL */
- return s->level;
- case 0x04: /* PWL_CTRL */
- return s->enable;
- }
- OMAP_BAD_REG(addr);
- return 0;
-}
-
-static void omap_pwl_write(void *opaque, hwaddr addr,
- uint64_t value, unsigned size)
-{
- struct omap_pwl_s *s = (struct omap_pwl_s *) opaque;
- int offset = addr & OMAP_MPUI_REG_MASK;
-
- if (size != 1) {
- omap_badwidth_write8(opaque, addr, value);
- return;
- }
-
- switch (offset) {
- case 0x00: /* PWL_LEVEL */
- s->level = value;
- omap_pwl_update(s);
- break;
- case 0x04: /* PWL_CTRL */
- s->enable = value & 1;
- omap_pwl_update(s);
- break;
- default:
- OMAP_BAD_REG(addr);
- return;
- }
-}
-
-static const MemoryRegionOps omap_pwl_ops = {
- .read = omap_pwl_read,
- .write = omap_pwl_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static void omap_pwl_reset(struct omap_pwl_s *s)
-{
- s->output = 0;
- s->level = 0;
- s->enable = 0;
- s->clk = 1;
- omap_pwl_update(s);
-}
-
-static void omap_pwl_clk_update(void *opaque, int line, int on)
-{
- struct omap_pwl_s *s = (struct omap_pwl_s *) opaque;
-
- s->clk = on;
- omap_pwl_update(s);
-}
-
-static struct omap_pwl_s *omap_pwl_init(MemoryRegion *system_memory,
- hwaddr base,
- omap_clk clk)
-{
- struct omap_pwl_s *s = g_malloc0(sizeof(*s));
-
- omap_pwl_reset(s);
-
- memory_region_init_io(&s->iomem, NULL, &omap_pwl_ops, s,
- "omap-pwl", 0x800);
- memory_region_add_subregion(system_memory, base, &s->iomem);
-
- omap_clk_adduser(clk, qemu_allocate_irq(omap_pwl_clk_update, s, 0));
- return s;
-}
-
-/* Pulse-Width Tone module */
-struct omap_pwt_s {
- MemoryRegion iomem;
- uint8_t frc;
- uint8_t vrc;
- uint8_t gcr;
- omap_clk clk;
-};
-
-static uint64_t omap_pwt_read(void *opaque, hwaddr addr,
- unsigned size)
-{
- struct omap_pwt_s *s = (struct omap_pwt_s *) opaque;
- int offset = addr & OMAP_MPUI_REG_MASK;
-
- if (size != 1) {
- return omap_badwidth_read8(opaque, addr);
- }
-
- switch (offset) {
- case 0x00: /* FRC */
- return s->frc;
- case 0x04: /* VCR */
- return s->vrc;
- case 0x08: /* GCR */
- return s->gcr;
- }
- OMAP_BAD_REG(addr);
- return 0;
-}
-
-static void omap_pwt_write(void *opaque, hwaddr addr,
- uint64_t value, unsigned size)
-{
- struct omap_pwt_s *s = (struct omap_pwt_s *) opaque;
- int offset = addr & OMAP_MPUI_REG_MASK;
-
- if (size != 1) {
- omap_badwidth_write8(opaque, addr, value);
- return;
- }
-
- switch (offset) {
- case 0x00: /* FRC */
- s->frc = value & 0x3f;
- break;
- case 0x04: /* VRC */
- if ((value ^ s->vrc) & 1) {
- if (value & 1)
- printf("%s: %iHz buzz on\n", __FUNCTION__, (int)
- /* 1.5 MHz from a 12-MHz or 13-MHz PWT_CLK */
- ((omap_clk_getrate(s->clk) >> 3) /
- /* Pre-multiplexer divider */
- ((s->gcr & 2) ? 1 : 154) /
- /* Octave multiplexer */
- (2 << (value & 3)) *
- /* 101/107 divider */
- ((value & (1 << 2)) ? 101 : 107) *
- /* 49/55 divider */
- ((value & (1 << 3)) ? 49 : 55) *
- /* 50/63 divider */
- ((value & (1 << 4)) ? 50 : 63) *
- /* 80/127 divider */
- ((value & (1 << 5)) ? 80 : 127) /
- (107 * 55 * 63 * 127)));
- else
- printf("%s: silence!\n", __FUNCTION__);
- }
- s->vrc = value & 0x7f;
- break;
- case 0x08: /* GCR */
- s->gcr = value & 3;
- break;
- default:
- OMAP_BAD_REG(addr);
- return;
- }
-}
-
-static const MemoryRegionOps omap_pwt_ops = {
- .read =omap_pwt_read,
- .write = omap_pwt_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static void omap_pwt_reset(struct omap_pwt_s *s)
-{
- s->frc = 0;
- s->vrc = 0;
- s->gcr = 0;
-}
-
-static struct omap_pwt_s *omap_pwt_init(MemoryRegion *system_memory,
- hwaddr base,
- omap_clk clk)
-{
- struct omap_pwt_s *s = g_malloc0(sizeof(*s));
- s->clk = clk;
- omap_pwt_reset(s);
-
- memory_region_init_io(&s->iomem, NULL, &omap_pwt_ops, s,
- "omap-pwt", 0x800);
- memory_region_add_subregion(system_memory, base, &s->iomem);
- return s;
-}
-
-/* Real-time Clock module */
-struct omap_rtc_s {
- MemoryRegion iomem;
- qemu_irq irq;
- qemu_irq alarm;
- QEMUTimer *clk;
-
- uint8_t interrupts;
- uint8_t status;
- int16_t comp_reg;
- int running;
- int pm_am;
- int auto_comp;
- int round;
- struct tm alarm_tm;
- time_t alarm_ti;
-
- struct tm current_tm;
- time_t ti;
- uint64_t tick;
-};
-
-static void omap_rtc_interrupts_update(struct omap_rtc_s *s)
-{
- /* s->alarm is level-triggered */
- qemu_set_irq(s->alarm, (s->status >> 6) & 1);
-}
-
-static void omap_rtc_alarm_update(struct omap_rtc_s *s)
-{
- s->alarm_ti = mktimegm(&s->alarm_tm);
- if (s->alarm_ti == -1)
- printf("%s: conversion failed\n", __FUNCTION__);
-}
-
-static uint64_t omap_rtc_read(void *opaque, hwaddr addr,
- unsigned size)
-{
- struct omap_rtc_s *s = (struct omap_rtc_s *) opaque;
- int offset = addr & OMAP_MPUI_REG_MASK;
- uint8_t i;
-
- if (size != 1) {
- return omap_badwidth_read8(opaque, addr);
- }
-
- switch (offset) {
- case 0x00: /* SECONDS_REG */
- return to_bcd(s->current_tm.tm_sec);
-
- case 0x04: /* MINUTES_REG */
- return to_bcd(s->current_tm.tm_min);
-
- case 0x08: /* HOURS_REG */
- if (s->pm_am)
- return ((s->current_tm.tm_hour > 11) << 7) |
- to_bcd(((s->current_tm.tm_hour - 1) % 12) + 1);
- else
- return to_bcd(s->current_tm.tm_hour);
-
- case 0x0c: /* DAYS_REG */
- return to_bcd(s->current_tm.tm_mday);
-
- case 0x10: /* MONTHS_REG */
- return to_bcd(s->current_tm.tm_mon + 1);
-
- case 0x14: /* YEARS_REG */
- return to_bcd(s->current_tm.tm_year % 100);
-
- case 0x18: /* WEEK_REG */
- return s->current_tm.tm_wday;
-
- case 0x20: /* ALARM_SECONDS_REG */
- return to_bcd(s->alarm_tm.tm_sec);
-
- case 0x24: /* ALARM_MINUTES_REG */
- return to_bcd(s->alarm_tm.tm_min);
-
- case 0x28: /* ALARM_HOURS_REG */
- if (s->pm_am)
- return ((s->alarm_tm.tm_hour > 11) << 7) |
- to_bcd(((s->alarm_tm.tm_hour - 1) % 12) + 1);
- else
- return to_bcd(s->alarm_tm.tm_hour);
-
- case 0x2c: /* ALARM_DAYS_REG */
- return to_bcd(s->alarm_tm.tm_mday);
-
- case 0x30: /* ALARM_MONTHS_REG */
- return to_bcd(s->alarm_tm.tm_mon + 1);
-
- case 0x34: /* ALARM_YEARS_REG */
- return to_bcd(s->alarm_tm.tm_year % 100);
-
- case 0x40: /* RTC_CTRL_REG */
- return (s->pm_am << 3) | (s->auto_comp << 2) |
- (s->round << 1) | s->running;
-
- case 0x44: /* RTC_STATUS_REG */
- i = s->status;
- s->status &= ~0x3d;
- return i;
-
- case 0x48: /* RTC_INTERRUPTS_REG */
- return s->interrupts;
-
- case 0x4c: /* RTC_COMP_LSB_REG */
- return ((uint16_t) s->comp_reg) & 0xff;
-
- case 0x50: /* RTC_COMP_MSB_REG */
- return ((uint16_t) s->comp_reg) >> 8;
- }
-
- OMAP_BAD_REG(addr);
- return 0;
-}
-
-static void omap_rtc_write(void *opaque, hwaddr addr,
- uint64_t value, unsigned size)
-{
- struct omap_rtc_s *s = (struct omap_rtc_s *) opaque;
- int offset = addr & OMAP_MPUI_REG_MASK;
- struct tm new_tm;
- time_t ti[2];
-
- if (size != 1) {
- omap_badwidth_write8(opaque, addr, value);
- return;
- }
-
- switch (offset) {
- case 0x00: /* SECONDS_REG */
-#ifdef ALMDEBUG
- printf("RTC SEC_REG <-- %02x\n", value);
-#endif
- s->ti -= s->current_tm.tm_sec;
- s->ti += from_bcd(value);
- return;
-
- case 0x04: /* MINUTES_REG */
-#ifdef ALMDEBUG
- printf("RTC MIN_REG <-- %02x\n", value);
-#endif
- s->ti -= s->current_tm.tm_min * 60;
- s->ti += from_bcd(value) * 60;
- return;
-
- case 0x08: /* HOURS_REG */
-#ifdef ALMDEBUG
- printf("RTC HRS_REG <-- %02x\n", value);
-#endif
- s->ti -= s->current_tm.tm_hour * 3600;
- if (s->pm_am) {
- s->ti += (from_bcd(value & 0x3f) & 12) * 3600;
- s->ti += ((value >> 7) & 1) * 43200;
- } else
- s->ti += from_bcd(value & 0x3f) * 3600;
- return;
-
- case 0x0c: /* DAYS_REG */
-#ifdef ALMDEBUG
- printf("RTC DAY_REG <-- %02x\n", value);
-#endif
- s->ti -= s->current_tm.tm_mday * 86400;
- s->ti += from_bcd(value) * 86400;
- return;
-
- case 0x10: /* MONTHS_REG */
-#ifdef ALMDEBUG
- printf("RTC MTH_REG <-- %02x\n", value);
-#endif
- memcpy(&new_tm, &s->current_tm, sizeof(new_tm));
- new_tm.tm_mon = from_bcd(value);
- ti[0] = mktimegm(&s->current_tm);
- ti[1] = mktimegm(&new_tm);
-
- if (ti[0] != -1 && ti[1] != -1) {
- s->ti -= ti[0];
- s->ti += ti[1];
- } else {
- /* A less accurate version */
- s->ti -= s->current_tm.tm_mon * 2592000;
- s->ti += from_bcd(value) * 2592000;
- }
- return;
-
- case 0x14: /* YEARS_REG */
-#ifdef ALMDEBUG
- printf("RTC YRS_REG <-- %02x\n", value);
-#endif
- memcpy(&new_tm, &s->current_tm, sizeof(new_tm));
- new_tm.tm_year += from_bcd(value) - (new_tm.tm_year % 100);
- ti[0] = mktimegm(&s->current_tm);
- ti[1] = mktimegm(&new_tm);
-
- if (ti[0] != -1 && ti[1] != -1) {
- s->ti -= ti[0];
- s->ti += ti[1];
- } else {
- /* A less accurate version */
- s->ti -= (time_t)(s->current_tm.tm_year % 100) * 31536000;
- s->ti += (time_t)from_bcd(value) * 31536000;
- }
- return;
-
- case 0x18: /* WEEK_REG */
- return; /* Ignored */
-
- case 0x20: /* ALARM_SECONDS_REG */
-#ifdef ALMDEBUG
- printf("ALM SEC_REG <-- %02x\n", value);
-#endif
- s->alarm_tm.tm_sec = from_bcd(value);
- omap_rtc_alarm_update(s);
- return;
-
- case 0x24: /* ALARM_MINUTES_REG */
-#ifdef ALMDEBUG
- printf("ALM MIN_REG <-- %02x\n", value);
-#endif
- s->alarm_tm.tm_min = from_bcd(value);
- omap_rtc_alarm_update(s);
- return;
-
- case 0x28: /* ALARM_HOURS_REG */
-#ifdef ALMDEBUG
- printf("ALM HRS_REG <-- %02x\n", value);
-#endif
- if (s->pm_am)
- s->alarm_tm.tm_hour =
- ((from_bcd(value & 0x3f)) % 12) +
- ((value >> 7) & 1) * 12;
- else
- s->alarm_tm.tm_hour = from_bcd(value);
- omap_rtc_alarm_update(s);
- return;
-
- case 0x2c: /* ALARM_DAYS_REG */
-#ifdef ALMDEBUG
- printf("ALM DAY_REG <-- %02x\n", value);
-#endif
- s->alarm_tm.tm_mday = from_bcd(value);
- omap_rtc_alarm_update(s);
- return;
-
- case 0x30: /* ALARM_MONTHS_REG */
-#ifdef ALMDEBUG
- printf("ALM MON_REG <-- %02x\n", value);
-#endif
- s->alarm_tm.tm_mon = from_bcd(value);
- omap_rtc_alarm_update(s);
- return;
-
- case 0x34: /* ALARM_YEARS_REG */
-#ifdef ALMDEBUG
- printf("ALM YRS_REG <-- %02x\n", value);
-#endif
- s->alarm_tm.tm_year = from_bcd(value);
- omap_rtc_alarm_update(s);
- return;
-
- case 0x40: /* RTC_CTRL_REG */
-#ifdef ALMDEBUG
- printf("RTC CONTROL <-- %02x\n", value);
-#endif
- s->pm_am = (value >> 3) & 1;
- s->auto_comp = (value >> 2) & 1;
- s->round = (value >> 1) & 1;
- s->running = value & 1;
- s->status &= 0xfd;
- s->status |= s->running << 1;
- return;
-
- case 0x44: /* RTC_STATUS_REG */
-#ifdef ALMDEBUG
- printf("RTC STATUSL <-- %02x\n", value);
-#endif
- s->status &= ~((value & 0xc0) ^ 0x80);
- omap_rtc_interrupts_update(s);
- return;
-
- case 0x48: /* RTC_INTERRUPTS_REG */
-#ifdef ALMDEBUG
- printf("RTC INTRS <-- %02x\n", value);
-#endif
- s->interrupts = value;
- return;
-
- case 0x4c: /* RTC_COMP_LSB_REG */
-#ifdef ALMDEBUG
- printf("RTC COMPLSB <-- %02x\n", value);
-#endif
- s->comp_reg &= 0xff00;
- s->comp_reg |= 0x00ff & value;
- return;
-
- case 0x50: /* RTC_COMP_MSB_REG */
-#ifdef ALMDEBUG
- printf("RTC COMPMSB <-- %02x\n", value);
-#endif
- s->comp_reg &= 0x00ff;
- s->comp_reg |= 0xff00 & (value << 8);
- return;
-
- default:
- OMAP_BAD_REG(addr);
- return;
- }
-}
-
-static const MemoryRegionOps omap_rtc_ops = {
- .read = omap_rtc_read,
- .write = omap_rtc_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static void omap_rtc_tick(void *opaque)
-{
- struct omap_rtc_s *s = opaque;
-
- if (s->round) {
- /* Round to nearest full minute. */
- if (s->current_tm.tm_sec < 30)
- s->ti -= s->current_tm.tm_sec;
- else
- s->ti += 60 - s->current_tm.tm_sec;
-
- s->round = 0;
- }
-
- localtime_r(&s->ti, &s->current_tm);
-
- if ((s->interrupts & 0x08) && s->ti == s->alarm_ti) {
- s->status |= 0x40;
- omap_rtc_interrupts_update(s);
- }
-
- if (s->interrupts & 0x04)
- switch (s->interrupts & 3) {
- case 0:
- s->status |= 0x04;
- qemu_irq_pulse(s->irq);
- break;
- case 1:
- if (s->current_tm.tm_sec)
- break;
- s->status |= 0x08;
- qemu_irq_pulse(s->irq);
- break;
- case 2:
- if (s->current_tm.tm_sec || s->current_tm.tm_min)
- break;
- s->status |= 0x10;
- qemu_irq_pulse(s->irq);
- break;
- case 3:
- if (s->current_tm.tm_sec ||
- s->current_tm.tm_min || s->current_tm.tm_hour)
- break;
- s->status |= 0x20;
- qemu_irq_pulse(s->irq);
- break;
- }
-
- /* Move on */
- if (s->running)
- s->ti ++;
- s->tick += 1000;
-
- /*
- * Every full hour add a rough approximation of the compensation
- * register to the 32kHz Timer (which drives the RTC) value.
- */
- if (s->auto_comp && !s->current_tm.tm_sec && !s->current_tm.tm_min)
- s->tick += s->comp_reg * 1000 / 32768;
-
- timer_mod(s->clk, s->tick);
-}
-
-static void omap_rtc_reset(struct omap_rtc_s *s)
-{
- struct tm tm;
-
- s->interrupts = 0;
- s->comp_reg = 0;
- s->running = 0;
- s->pm_am = 0;
- s->auto_comp = 0;
- s->round = 0;
- s->tick = qemu_clock_get_ms(rtc_clock);
- memset(&s->alarm_tm, 0, sizeof(s->alarm_tm));
- s->alarm_tm.tm_mday = 0x01;
- s->status = 1 << 7;
- qemu_get_timedate(&tm, 0);
- s->ti = mktimegm(&tm);
-
- omap_rtc_alarm_update(s);
- omap_rtc_tick(s);
-}
-
-static struct omap_rtc_s *omap_rtc_init(MemoryRegion *system_memory,
- hwaddr base,
- qemu_irq timerirq, qemu_irq alarmirq,
- omap_clk clk)
-{
- struct omap_rtc_s *s = g_new0(struct omap_rtc_s, 1);
-
- s->irq = timerirq;
- s->alarm = alarmirq;
- s->clk = timer_new_ms(rtc_clock, omap_rtc_tick, s);
-
- omap_rtc_reset(s);
-
- memory_region_init_io(&s->iomem, NULL, &omap_rtc_ops, s,
- "omap-rtc", 0x800);
- memory_region_add_subregion(system_memory, base, &s->iomem);
-
- return s;
-}
-
-/* Multi-channel Buffered Serial Port interfaces */
-struct omap_mcbsp_s {
- MemoryRegion iomem;
- qemu_irq txirq;
- qemu_irq rxirq;
- qemu_irq txdrq;
- qemu_irq rxdrq;
-
- uint16_t spcr[2];
- uint16_t rcr[2];
- uint16_t xcr[2];
- uint16_t srgr[2];
- uint16_t mcr[2];
- uint16_t pcr;
- uint16_t rcer[8];
- uint16_t xcer[8];
- int tx_rate;
- int rx_rate;
- int tx_req;
- int rx_req;
-
- I2SCodec *codec;
- QEMUTimer *source_timer;
- QEMUTimer *sink_timer;
-};
-
-static void omap_mcbsp_intr_update(struct omap_mcbsp_s *s)
-{
- int irq;
-
- switch ((s->spcr[0] >> 4) & 3) { /* RINTM */
- case 0:
- irq = (s->spcr[0] >> 1) & 1; /* RRDY */
- break;
- case 3:
- irq = (s->spcr[0] >> 3) & 1; /* RSYNCERR */
- break;
- default:
- irq = 0;
- break;
- }
-
- if (irq)
- qemu_irq_pulse(s->rxirq);
-
- switch ((s->spcr[1] >> 4) & 3) { /* XINTM */
- case 0:
- irq = (s->spcr[1] >> 1) & 1; /* XRDY */
- break;
- case 3:
- irq = (s->spcr[1] >> 3) & 1; /* XSYNCERR */
- break;
- default:
- irq = 0;
- break;
- }
-
- if (irq)
- qemu_irq_pulse(s->txirq);
-}
-
-static void omap_mcbsp_rx_newdata(struct omap_mcbsp_s *s)
-{
- if ((s->spcr[0] >> 1) & 1) /* RRDY */
- s->spcr[0] |= 1 << 2; /* RFULL */
- s->spcr[0] |= 1 << 1; /* RRDY */
- qemu_irq_raise(s->rxdrq);
- omap_mcbsp_intr_update(s);
-}
-
-static void omap_mcbsp_source_tick(void *opaque)
-{
- struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
- static const int bps[8] = { 0, 1, 1, 2, 2, 2, -255, -255 };
-
- if (!s->rx_rate)
- return;
- if (s->rx_req)
- printf("%s: Rx FIFO overrun\n", __FUNCTION__);
-
- s->rx_req = s->rx_rate << bps[(s->rcr[0] >> 5) & 7];
-
- omap_mcbsp_rx_newdata(s);
- timer_mod(s->source_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
- NANOSECONDS_PER_SECOND);
-}
-
-static void omap_mcbsp_rx_start(struct omap_mcbsp_s *s)
-{
- if (!s->codec || !s->codec->rts)
- omap_mcbsp_source_tick(s);
- else if (s->codec->in.len) {
- s->rx_req = s->codec->in.len;
- omap_mcbsp_rx_newdata(s);
- }
-}
-
-static void omap_mcbsp_rx_stop(struct omap_mcbsp_s *s)
-{
- timer_del(s->source_timer);
-}
-
-static void omap_mcbsp_rx_done(struct omap_mcbsp_s *s)
-{
- s->spcr[0] &= ~(1 << 1); /* RRDY */
- qemu_irq_lower(s->rxdrq);
- omap_mcbsp_intr_update(s);
-}
-
-static void omap_mcbsp_tx_newdata(struct omap_mcbsp_s *s)
-{
- s->spcr[1] |= 1 << 1; /* XRDY */
- qemu_irq_raise(s->txdrq);
- omap_mcbsp_intr_update(s);
-}
-
-static void omap_mcbsp_sink_tick(void *opaque)
-{
- struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
- static const int bps[8] = { 0, 1, 1, 2, 2, 2, -255, -255 };
-
- if (!s->tx_rate)
- return;
- if (s->tx_req)
- printf("%s: Tx FIFO underrun\n", __FUNCTION__);
-
- s->tx_req = s->tx_rate << bps[(s->xcr[0] >> 5) & 7];
-
- omap_mcbsp_tx_newdata(s);
- timer_mod(s->sink_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
- NANOSECONDS_PER_SECOND);
-}
-
-static void omap_mcbsp_tx_start(struct omap_mcbsp_s *s)
-{
- if (!s->codec || !s->codec->cts)
- omap_mcbsp_sink_tick(s);
- else if (s->codec->out.size) {
- s->tx_req = s->codec->out.size;
- omap_mcbsp_tx_newdata(s);
- }
-}
-
-static void omap_mcbsp_tx_done(struct omap_mcbsp_s *s)
-{
- s->spcr[1] &= ~(1 << 1); /* XRDY */
- qemu_irq_lower(s->txdrq);
- omap_mcbsp_intr_update(s);
- if (s->codec && s->codec->cts)
- s->codec->tx_swallow(s->codec->opaque);
-}
-
-static void omap_mcbsp_tx_stop(struct omap_mcbsp_s *s)
-{
- s->tx_req = 0;
- omap_mcbsp_tx_done(s);
- timer_del(s->sink_timer);
-}
-
-static void omap_mcbsp_req_update(struct omap_mcbsp_s *s)
-{
- int prev_rx_rate, prev_tx_rate;
- int rx_rate = 0, tx_rate = 0;
- int cpu_rate = 1500000; /* XXX */
-
- /* TODO: check CLKSTP bit */
- if (s->spcr[1] & (1 << 6)) { /* GRST */
- if (s->spcr[0] & (1 << 0)) { /* RRST */
- if ((s->srgr[1] & (1 << 13)) && /* CLKSM */
- (s->pcr & (1 << 8))) { /* CLKRM */
- if (~s->pcr & (1 << 7)) /* SCLKME */
- rx_rate = cpu_rate /
- ((s->srgr[0] & 0xff) + 1); /* CLKGDV */
- } else
- if (s->codec)
- rx_rate = s->codec->rx_rate;
- }
-
- if (s->spcr[1] & (1 << 0)) { /* XRST */
- if ((s->srgr[1] & (1 << 13)) && /* CLKSM */
- (s->pcr & (1 << 9))) { /* CLKXM */
- if (~s->pcr & (1 << 7)) /* SCLKME */
- tx_rate = cpu_rate /
- ((s->srgr[0] & 0xff) + 1); /* CLKGDV */
- } else
- if (s->codec)
- tx_rate = s->codec->tx_rate;
- }
- }
- prev_tx_rate = s->tx_rate;
- prev_rx_rate = s->rx_rate;
- s->tx_rate = tx_rate;
- s->rx_rate = rx_rate;
-
- if (s->codec)
- s->codec->set_rate(s->codec->opaque, rx_rate, tx_rate);
-
- if (!prev_tx_rate && tx_rate)
- omap_mcbsp_tx_start(s);
- else if (s->tx_rate && !tx_rate)
- omap_mcbsp_tx_stop(s);
-
- if (!prev_rx_rate && rx_rate)
- omap_mcbsp_rx_start(s);
- else if (prev_tx_rate && !tx_rate)
- omap_mcbsp_rx_stop(s);
-}
-
-static uint64_t omap_mcbsp_read(void *opaque, hwaddr addr,
- unsigned size)
-{
- struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
- int offset = addr & OMAP_MPUI_REG_MASK;
- uint16_t ret;
-
- if (size != 2) {
- return omap_badwidth_read16(opaque, addr);
- }
-
- switch (offset) {
- case 0x00: /* DRR2 */
- if (((s->rcr[0] >> 5) & 7) < 3) /* RWDLEN1 */
- return 0x0000;
- /* Fall through. */
- case 0x02: /* DRR1 */
- if (s->rx_req < 2) {
- printf("%s: Rx FIFO underrun\n", __FUNCTION__);
- omap_mcbsp_rx_done(s);
- } else {
- s->tx_req -= 2;
- if (s->codec && s->codec->in.len >= 2) {
- ret = s->codec->in.fifo[s->codec->in.start ++] << 8;
- ret |= s->codec->in.fifo[s->codec->in.start ++];
- s->codec->in.len -= 2;
- } else
- ret = 0x0000;
- if (!s->tx_req)
- omap_mcbsp_rx_done(s);
- return ret;
- }
- return 0x0000;
-
- case 0x04: /* DXR2 */
- case 0x06: /* DXR1 */
- return 0x0000;
-
- case 0x08: /* SPCR2 */
- return s->spcr[1];
- case 0x0a: /* SPCR1 */
- return s->spcr[0];
- case 0x0c: /* RCR2 */
- return s->rcr[1];
- case 0x0e: /* RCR1 */
- return s->rcr[0];
- case 0x10: /* XCR2 */
- return s->xcr[1];
- case 0x12: /* XCR1 */
- return s->xcr[0];
- case 0x14: /* SRGR2 */
- return s->srgr[1];
- case 0x16: /* SRGR1 */
- return s->srgr[0];
- case 0x18: /* MCR2 */
- return s->mcr[1];
- case 0x1a: /* MCR1 */
- return s->mcr[0];
- case 0x1c: /* RCERA */
- return s->rcer[0];
- case 0x1e: /* RCERB */
- return s->rcer[1];
- case 0x20: /* XCERA */
- return s->xcer[0];
- case 0x22: /* XCERB */
- return s->xcer[1];
- case 0x24: /* PCR0 */
- return s->pcr;
- case 0x26: /* RCERC */
- return s->rcer[2];
- case 0x28: /* RCERD */
- return s->rcer[3];
- case 0x2a: /* XCERC */
- return s->xcer[2];
- case 0x2c: /* XCERD */
- return s->xcer[3];
- case 0x2e: /* RCERE */
- return s->rcer[4];
- case 0x30: /* RCERF */
- return s->rcer[5];
- case 0x32: /* XCERE */
- return s->xcer[4];
- case 0x34: /* XCERF */
- return s->xcer[5];
- case 0x36: /* RCERG */
- return s->rcer[6];
- case 0x38: /* RCERH */
- return s->rcer[7];
- case 0x3a: /* XCERG */
- return s->xcer[6];
- case 0x3c: /* XCERH */
- return s->xcer[7];
- }
-
- OMAP_BAD_REG(addr);
- return 0;
-}
-
-static void omap_mcbsp_writeh(void *opaque, hwaddr addr,
- uint32_t value)
-{
- struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
- int offset = addr & OMAP_MPUI_REG_MASK;
-
- switch (offset) {
- case 0x00: /* DRR2 */
- case 0x02: /* DRR1 */
- OMAP_RO_REG(addr);
- return;
-
- case 0x04: /* DXR2 */
- if (((s->xcr[0] >> 5) & 7) < 3) /* XWDLEN1 */
- return;
- /* Fall through. */
- case 0x06: /* DXR1 */
- if (s->tx_req > 1) {
- s->tx_req -= 2;
- if (s->codec && s->codec->cts) {
- s->codec->out.fifo[s->codec->out.len ++] = (value >> 8) & 0xff;
- s->codec->out.fifo[s->codec->out.len ++] = (value >> 0) & 0xff;
- }
- if (s->tx_req < 2)
- omap_mcbsp_tx_done(s);
- } else
- printf("%s: Tx FIFO overrun\n", __FUNCTION__);
- return;
-
- case 0x08: /* SPCR2 */
- s->spcr[1] &= 0x0002;
- s->spcr[1] |= 0x03f9 & value;
- s->spcr[1] |= 0x0004 & (value << 2); /* XEMPTY := XRST */
- if (~value & 1) /* XRST */
- s->spcr[1] &= ~6;
- omap_mcbsp_req_update(s);
- return;
- case 0x0a: /* SPCR1 */
- s->spcr[0] &= 0x0006;
- s->spcr[0] |= 0xf8f9 & value;
- if (value & (1 << 15)) /* DLB */
- printf("%s: Digital Loopback mode enable attempt\n", __FUNCTION__);
- if (~value & 1) { /* RRST */
- s->spcr[0] &= ~6;
- s->rx_req = 0;
- omap_mcbsp_rx_done(s);
- }
- omap_mcbsp_req_update(s);
- return;
-
- case 0x0c: /* RCR2 */
- s->rcr[1] = value & 0xffff;
- return;
- case 0x0e: /* RCR1 */
- s->rcr[0] = value & 0x7fe0;
- return;
- case 0x10: /* XCR2 */
- s->xcr[1] = value & 0xffff;
- return;
- case 0x12: /* XCR1 */
- s->xcr[0] = value & 0x7fe0;
- return;
- case 0x14: /* SRGR2 */
- s->srgr[1] = value & 0xffff;
- omap_mcbsp_req_update(s);
- return;
- case 0x16: /* SRGR1 */
- s->srgr[0] = value & 0xffff;
- omap_mcbsp_req_update(s);
- return;
- case 0x18: /* MCR2 */
- s->mcr[1] = value & 0x03e3;
- if (value & 3) /* XMCM */
- printf("%s: Tx channel selection mode enable attempt\n",
- __FUNCTION__);
- return;
- case 0x1a: /* MCR1 */
- s->mcr[0] = value & 0x03e1;
- if (value & 1) /* RMCM */
- printf("%s: Rx channel selection mode enable attempt\n",
- __FUNCTION__);
- return;
- case 0x1c: /* RCERA */
- s->rcer[0] = value & 0xffff;
- return;
- case 0x1e: /* RCERB */
- s->rcer[1] = value & 0xffff;
- return;
- case 0x20: /* XCERA */
- s->xcer[0] = value & 0xffff;
- return;
- case 0x22: /* XCERB */
- s->xcer[1] = value & 0xffff;
- return;
- case 0x24: /* PCR0 */
- s->pcr = value & 0x7faf;
- return;
- case 0x26: /* RCERC */
- s->rcer[2] = value & 0xffff;
- return;
- case 0x28: /* RCERD */
- s->rcer[3] = value & 0xffff;
- return;
- case 0x2a: /* XCERC */
- s->xcer[2] = value & 0xffff;
- return;
- case 0x2c: /* XCERD */
- s->xcer[3] = value & 0xffff;
- return;
- case 0x2e: /* RCERE */
- s->rcer[4] = value & 0xffff;
- return;
- case 0x30: /* RCERF */
- s->rcer[5] = value & 0xffff;
- return;
- case 0x32: /* XCERE */
- s->xcer[4] = value & 0xffff;
- return;
- case 0x34: /* XCERF */
- s->xcer[5] = value & 0xffff;
- return;
- case 0x36: /* RCERG */
- s->rcer[6] = value & 0xffff;
- return;
- case 0x38: /* RCERH */
- s->rcer[7] = value & 0xffff;
- return;
- case 0x3a: /* XCERG */
- s->xcer[6] = value & 0xffff;
- return;
- case 0x3c: /* XCERH */
- s->xcer[7] = value & 0xffff;
- return;
- }
-
- OMAP_BAD_REG(addr);
-}
-
-static void omap_mcbsp_writew(void *opaque, hwaddr addr,
- uint32_t value)
-{
- struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
- int offset = addr & OMAP_MPUI_REG_MASK;
-
- if (offset == 0x04) { /* DXR */
- if (((s->xcr[0] >> 5) & 7) < 3) /* XWDLEN1 */
- return;
- if (s->tx_req > 3) {
- s->tx_req -= 4;
- if (s->codec && s->codec->cts) {
- s->codec->out.fifo[s->codec->out.len ++] =
- (value >> 24) & 0xff;
- s->codec->out.fifo[s->codec->out.len ++] =
- (value >> 16) & 0xff;
- s->codec->out.fifo[s->codec->out.len ++] =
- (value >> 8) & 0xff;
- s->codec->out.fifo[s->codec->out.len ++] =
- (value >> 0) & 0xff;
- }
- if (s->tx_req < 4)
- omap_mcbsp_tx_done(s);
- } else
- printf("%s: Tx FIFO overrun\n", __FUNCTION__);
- return;
- }
-
- omap_badwidth_write16(opaque, addr, value);
-}
-
-static void omap_mcbsp_write(void *opaque, hwaddr addr,
- uint64_t value, unsigned size)
-{
- switch (size) {
- case 2:
- omap_mcbsp_writeh(opaque, addr, value);
- break;
- case 4:
- omap_mcbsp_writew(opaque, addr, value);
- break;
- default:
- omap_badwidth_write16(opaque, addr, value);
- }
-}
-
-static const MemoryRegionOps omap_mcbsp_ops = {
- .read = omap_mcbsp_read,
- .write = omap_mcbsp_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static void omap_mcbsp_reset(struct omap_mcbsp_s *s)
-{
- memset(&s->spcr, 0, sizeof(s->spcr));
- memset(&s->rcr, 0, sizeof(s->rcr));
- memset(&s->xcr, 0, sizeof(s->xcr));
- s->srgr[0] = 0x0001;
- s->srgr[1] = 0x2000;
- memset(&s->mcr, 0, sizeof(s->mcr));
- memset(&s->pcr, 0, sizeof(s->pcr));
- memset(&s->rcer, 0, sizeof(s->rcer));
- memset(&s->xcer, 0, sizeof(s->xcer));
- s->tx_req = 0;
- s->rx_req = 0;
- s->tx_rate = 0;
- s->rx_rate = 0;
- timer_del(s->source_timer);
- timer_del(s->sink_timer);
-}
-
-static struct omap_mcbsp_s *omap_mcbsp_init(MemoryRegion *system_memory,
- hwaddr base,
- qemu_irq txirq, qemu_irq rxirq,
- qemu_irq *dma, omap_clk clk)
-{
- struct omap_mcbsp_s *s = g_new0(struct omap_mcbsp_s, 1);
-
- s->txirq = txirq;
- s->rxirq = rxirq;
- s->txdrq = dma[0];
- s->rxdrq = dma[1];
- s->sink_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, omap_mcbsp_sink_tick, s);
- s->source_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, omap_mcbsp_source_tick, s);
- omap_mcbsp_reset(s);
-
- memory_region_init_io(&s->iomem, NULL, &omap_mcbsp_ops, s, "omap-mcbsp", 0x800);
- memory_region_add_subregion(system_memory, base, &s->iomem);
-
- return s;
-}
-
-static void omap_mcbsp_i2s_swallow(void *opaque, int line, int level)
-{
- struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
-
- if (s->rx_rate) {
- s->rx_req = s->codec->in.len;
- omap_mcbsp_rx_newdata(s);
- }
-}
-
-static void omap_mcbsp_i2s_start(void *opaque, int line, int level)
-{
- struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
-
- if (s->tx_rate) {
- s->tx_req = s->codec->out.size;
- omap_mcbsp_tx_newdata(s);
- }
-}
-
-void omap_mcbsp_i2s_attach(struct omap_mcbsp_s *s, I2SCodec *slave)
-{
- s->codec = slave;
- slave->rx_swallow = qemu_allocate_irq(omap_mcbsp_i2s_swallow, s, 0);
- slave->tx_start = qemu_allocate_irq(omap_mcbsp_i2s_start, s, 0);
-}
-
-/* LED Pulse Generators */
-struct omap_lpg_s {
- MemoryRegion iomem;
- QEMUTimer *tm;
-
- uint8_t control;
- uint8_t power;
- int64_t on;
- int64_t period;
- int clk;
- int cycle;
-};
-
-static void omap_lpg_tick(void *opaque)
-{
- struct omap_lpg_s *s = opaque;
-
- if (s->cycle)
- timer_mod(s->tm, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + s->period - s->on);
- else
- timer_mod(s->tm, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + s->on);
-
- s->cycle = !s->cycle;
- printf("%s: LED is %s\n", __FUNCTION__, s->cycle ? "on" : "off");
-}
-
-static void omap_lpg_update(struct omap_lpg_s *s)
-{
- int64_t on, period = 1, ticks = 1000;
- static const int per[8] = { 1, 2, 4, 8, 12, 16, 20, 24 };
-
- if (~s->control & (1 << 6)) /* LPGRES */
- on = 0;
- else if (s->control & (1 << 7)) /* PERM_ON */
- on = period;
- else {
- period = muldiv64(ticks, per[s->control & 7], /* PERCTRL */
- 256 / 32);
- on = (s->clk && s->power) ? muldiv64(ticks,
- per[(s->control >> 3) & 7], 256) : 0; /* ONCTRL */
- }
-
- timer_del(s->tm);
- if (on == period && s->on < s->period)
- printf("%s: LED is on\n", __FUNCTION__);
- else if (on == 0 && s->on)
- printf("%s: LED is off\n", __FUNCTION__);
- else if (on && (on != s->on || period != s->period)) {
- s->cycle = 0;
- s->on = on;
- s->period = period;
- omap_lpg_tick(s);
- return;
- }
-
- s->on = on;
- s->period = period;
-}
-
-static void omap_lpg_reset(struct omap_lpg_s *s)
-{
- s->control = 0x00;
- s->power = 0x00;
- s->clk = 1;
- omap_lpg_update(s);
-}
-
-static uint64_t omap_lpg_read(void *opaque, hwaddr addr,
- unsigned size)
-{
- struct omap_lpg_s *s = (struct omap_lpg_s *) opaque;
- int offset = addr & OMAP_MPUI_REG_MASK;
-
- if (size != 1) {
- return omap_badwidth_read8(opaque, addr);
- }
-
- switch (offset) {
- case 0x00: /* LCR */
- return s->control;
-
- case 0x04: /* PMR */
- return s->power;
- }
-
- OMAP_BAD_REG(addr);
- return 0;
-}
-
-static void omap_lpg_write(void *opaque, hwaddr addr,
- uint64_t value, unsigned size)
-{
- struct omap_lpg_s *s = (struct omap_lpg_s *) opaque;
- int offset = addr & OMAP_MPUI_REG_MASK;
-
- if (size != 1) {
- omap_badwidth_write8(opaque, addr, value);
- return;
- }
-
- switch (offset) {
- case 0x00: /* LCR */
- if (~value & (1 << 6)) /* LPGRES */
- omap_lpg_reset(s);
- s->control = value & 0xff;
- omap_lpg_update(s);
- return;
-
- case 0x04: /* PMR */
- s->power = value & 0x01;
- omap_lpg_update(s);
- return;
-
- default:
- OMAP_BAD_REG(addr);
- return;
- }
-}
-
-static const MemoryRegionOps omap_lpg_ops = {
- .read = omap_lpg_read,
- .write = omap_lpg_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static void omap_lpg_clk_update(void *opaque, int line, int on)
-{
- struct omap_lpg_s *s = (struct omap_lpg_s *) opaque;
-
- s->clk = on;
- omap_lpg_update(s);
-}
-
-static struct omap_lpg_s *omap_lpg_init(MemoryRegion *system_memory,
- hwaddr base, omap_clk clk)
-{
- struct omap_lpg_s *s = g_new0(struct omap_lpg_s, 1);
-
- s->tm = timer_new_ms(QEMU_CLOCK_VIRTUAL, omap_lpg_tick, s);
-
- omap_lpg_reset(s);
-
- memory_region_init_io(&s->iomem, NULL, &omap_lpg_ops, s, "omap-lpg", 0x800);
- memory_region_add_subregion(system_memory, base, &s->iomem);
-
- omap_clk_adduser(clk, qemu_allocate_irq(omap_lpg_clk_update, s, 0));
-
- return s;
-}
-
-/* MPUI Peripheral Bridge configuration */
-static uint64_t omap_mpui_io_read(void *opaque, hwaddr addr,
- unsigned size)
-{
- if (size != 2) {
- return omap_badwidth_read16(opaque, addr);
- }
-
- if (addr == OMAP_MPUI_BASE) /* CMR */
- return 0xfe4d;
-
- OMAP_BAD_REG(addr);
- return 0;
-}
-
-static void omap_mpui_io_write(void *opaque, hwaddr addr,
- uint64_t value, unsigned size)
-{
- /* FIXME: infinite loop */
- omap_badwidth_write16(opaque, addr, value);
-}
-
-static const MemoryRegionOps omap_mpui_io_ops = {
- .read = omap_mpui_io_read,
- .write = omap_mpui_io_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static void omap_setup_mpui_io(MemoryRegion *system_memory,
- struct omap_mpu_state_s *mpu)
-{
- memory_region_init_io(&mpu->mpui_io_iomem, NULL, &omap_mpui_io_ops, mpu,
- "omap-mpui-io", 0x7fff);
- memory_region_add_subregion(system_memory, OMAP_MPUI_BASE,
- &mpu->mpui_io_iomem);
-}
-
-/* General chip reset */
-static void omap1_mpu_reset(void *opaque)
-{
- struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
-
- omap_dma_reset(mpu->dma);
- omap_mpu_timer_reset(mpu->timer[0]);
- omap_mpu_timer_reset(mpu->timer[1]);
- omap_mpu_timer_reset(mpu->timer[2]);
- omap_wd_timer_reset(mpu->wdt);
- omap_os_timer_reset(mpu->os_timer);
- omap_lcdc_reset(mpu->lcd);
- omap_ulpd_pm_reset(mpu);
- omap_pin_cfg_reset(mpu);
- omap_mpui_reset(mpu);
- omap_tipb_bridge_reset(mpu->private_tipb);
- omap_tipb_bridge_reset(mpu->public_tipb);
- omap_dpll_reset(mpu->dpll[0]);
- omap_dpll_reset(mpu->dpll[1]);
- omap_dpll_reset(mpu->dpll[2]);
- omap_uart_reset(mpu->uart[0]);
- omap_uart_reset(mpu->uart[1]);
- omap_uart_reset(mpu->uart[2]);
- omap_mmc_reset(mpu->mmc);
- omap_mpuio_reset(mpu->mpuio);
- omap_uwire_reset(mpu->microwire);
- omap_pwl_reset(mpu->pwl);
- omap_pwt_reset(mpu->pwt);
- omap_rtc_reset(mpu->rtc);
- omap_mcbsp_reset(mpu->mcbsp1);
- omap_mcbsp_reset(mpu->mcbsp2);
- omap_mcbsp_reset(mpu->mcbsp3);
- omap_lpg_reset(mpu->led[0]);
- omap_lpg_reset(mpu->led[1]);
- omap_clkm_reset(mpu);
- cpu_reset(CPU(mpu->cpu));
-}
-
-static const struct omap_map_s {
- hwaddr phys_dsp;
- hwaddr phys_mpu;
- uint32_t size;
- const char *name;
-} omap15xx_dsp_mm[] = {
- /* Strobe 0 */
- { 0xe1010000, 0xfffb0000, 0x800, "UART1 BT" }, /* CS0 */
- { 0xe1010800, 0xfffb0800, 0x800, "UART2 COM" }, /* CS1 */
- { 0xe1011800, 0xfffb1800, 0x800, "McBSP1 audio" }, /* CS3 */
- { 0xe1012000, 0xfffb2000, 0x800, "MCSI2 communication" }, /* CS4 */
- { 0xe1012800, 0xfffb2800, 0x800, "MCSI1 BT u-Law" }, /* CS5 */
- { 0xe1013000, 0xfffb3000, 0x800, "uWire" }, /* CS6 */
- { 0xe1013800, 0xfffb3800, 0x800, "I^2C" }, /* CS7 */
- { 0xe1014000, 0xfffb4000, 0x800, "USB W2FC" }, /* CS8 */
- { 0xe1014800, 0xfffb4800, 0x800, "RTC" }, /* CS9 */
- { 0xe1015000, 0xfffb5000, 0x800, "MPUIO" }, /* CS10 */
- { 0xe1015800, 0xfffb5800, 0x800, "PWL" }, /* CS11 */
- { 0xe1016000, 0xfffb6000, 0x800, "PWT" }, /* CS12 */
- { 0xe1017000, 0xfffb7000, 0x800, "McBSP3" }, /* CS14 */
- { 0xe1017800, 0xfffb7800, 0x800, "MMC" }, /* CS15 */
- { 0xe1019000, 0xfffb9000, 0x800, "32-kHz timer" }, /* CS18 */
- { 0xe1019800, 0xfffb9800, 0x800, "UART3" }, /* CS19 */
- { 0xe101c800, 0xfffbc800, 0x800, "TIPB switches" }, /* CS25 */
- /* Strobe 1 */
- { 0xe101e000, 0xfffce000, 0x800, "GPIOs" }, /* CS28 */
-
- { 0 }
-};
-
-static void omap_setup_dsp_mapping(MemoryRegion *system_memory,
- const struct omap_map_s *map)
-{
- MemoryRegion *io;
-
- for (; map->phys_dsp; map ++) {
- io = g_new(MemoryRegion, 1);
- memory_region_init_alias(io, NULL, map->name,
- system_memory, map->phys_mpu, map->size);
- memory_region_add_subregion(system_memory, map->phys_dsp, io);
- }
-}
-
-void omap_mpu_wakeup(void *opaque, int irq, int req)
-{
- struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
- CPUState *cpu = CPU(mpu->cpu);
-
- if (cpu->halted) {
- cpu_interrupt(cpu, CPU_INTERRUPT_EXITTB);
- }
-}
-
-static const struct dma_irq_map omap1_dma_irq_map[] = {
- { 0, OMAP_INT_DMA_CH0_6 },
- { 0, OMAP_INT_DMA_CH1_7 },
- { 0, OMAP_INT_DMA_CH2_8 },
- { 0, OMAP_INT_DMA_CH3 },
- { 0, OMAP_INT_DMA_CH4 },
- { 0, OMAP_INT_DMA_CH5 },
- { 1, OMAP_INT_1610_DMA_CH6 },
- { 1, OMAP_INT_1610_DMA_CH7 },
- { 1, OMAP_INT_1610_DMA_CH8 },
- { 1, OMAP_INT_1610_DMA_CH9 },
- { 1, OMAP_INT_1610_DMA_CH10 },
- { 1, OMAP_INT_1610_DMA_CH11 },
- { 1, OMAP_INT_1610_DMA_CH12 },
- { 1, OMAP_INT_1610_DMA_CH13 },
- { 1, OMAP_INT_1610_DMA_CH14 },
- { 1, OMAP_INT_1610_DMA_CH15 }
-};
-
-/* DMA ports for OMAP1 */
-static int omap_validate_emiff_addr(struct omap_mpu_state_s *s,
- hwaddr addr)
-{
- return range_covers_byte(OMAP_EMIFF_BASE, s->sdram_size, addr);
-}
-
-static int omap_validate_emifs_addr(struct omap_mpu_state_s *s,
- hwaddr addr)
-{
- return range_covers_byte(OMAP_EMIFS_BASE, OMAP_EMIFF_BASE - OMAP_EMIFS_BASE,
- addr);
-}
-
-static int omap_validate_imif_addr(struct omap_mpu_state_s *s,
- hwaddr addr)
-{
- return range_covers_byte(OMAP_IMIF_BASE, s->sram_size, addr);
-}
-
-static int omap_validate_tipb_addr(struct omap_mpu_state_s *s,
- hwaddr addr)
-{
- return range_covers_byte(0xfffb0000, 0xffff0000 - 0xfffb0000, addr);
-}
-
-static int omap_validate_local_addr(struct omap_mpu_state_s *s,
- hwaddr addr)
-{
- return range_covers_byte(OMAP_LOCALBUS_BASE, 0x1000000, addr);
-}
-
-static int omap_validate_tipb_mpui_addr(struct omap_mpu_state_s *s,
- hwaddr addr)
-{
- return range_covers_byte(0xe1010000, 0xe1020004 - 0xe1010000, addr);
-}
-
-struct omap_mpu_state_s *omap310_mpu_init(MemoryRegion *system_memory,
- unsigned long sdram_size,
- const char *core)
-{
- int i;
- struct omap_mpu_state_s *s = g_new0(struct omap_mpu_state_s, 1);
- qemu_irq dma_irqs[6];
- DriveInfo *dinfo;
- SysBusDevice *busdev;
-
- if (!core)
- core = "ti925t";
-
- /* Core */
- s->mpu_model = omap310;
- s->cpu = cpu_arm_init(core);
- if (s->cpu == NULL) {
- fprintf(stderr, "Unable to find CPU definition\n");
- exit(1);
- }
- s->sdram_size = sdram_size;
- s->sram_size = OMAP15XX_SRAM_SIZE;
-
- s->wakeup = qemu_allocate_irq(omap_mpu_wakeup, s, 0);
-
- /* Clocks */
- omap_clk_init(s);
-
- /* Memory-mapped stuff */
- memory_region_allocate_system_memory(&s->emiff_ram, NULL, "omap1.dram",
- s->sdram_size);
- memory_region_add_subregion(system_memory, OMAP_EMIFF_BASE, &s->emiff_ram);
- memory_region_init_ram(&s->imif_ram, NULL, "omap1.sram", s->sram_size,
- &error_fatal);
- vmstate_register_ram_global(&s->imif_ram);
- memory_region_add_subregion(system_memory, OMAP_IMIF_BASE, &s->imif_ram);
-
- omap_clkm_init(system_memory, 0xfffece00, 0xe1008000, s);
-
- s->ih[0] = qdev_create(NULL, "omap-intc");
- qdev_prop_set_uint32(s->ih[0], "size", 0x100);
- qdev_prop_set_ptr(s->ih[0], "clk", omap_findclk(s, "arminth_ck"));
- qdev_init_nofail(s->ih[0]);
- busdev = SYS_BUS_DEVICE(s->ih[0]);
- sysbus_connect_irq(busdev, 0,
- qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_IRQ));
- sysbus_connect_irq(busdev, 1,
- qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_FIQ));
- sysbus_mmio_map(busdev, 0, 0xfffecb00);
- s->ih[1] = qdev_create(NULL, "omap-intc");
- qdev_prop_set_uint32(s->ih[1], "size", 0x800);
- qdev_prop_set_ptr(s->ih[1], "clk", omap_findclk(s, "arminth_ck"));
- qdev_init_nofail(s->ih[1]);
- busdev = SYS_BUS_DEVICE(s->ih[1]);
- sysbus_connect_irq(busdev, 0,
- qdev_get_gpio_in(s->ih[0], OMAP_INT_15XX_IH2_IRQ));
- /* The second interrupt controller's FIQ output is not wired up */
- sysbus_mmio_map(busdev, 0, 0xfffe0000);
-
- for (i = 0; i < 6; i++) {
- dma_irqs[i] = qdev_get_gpio_in(s->ih[omap1_dma_irq_map[i].ih],
- omap1_dma_irq_map[i].intr);
- }
- s->dma = omap_dma_init(0xfffed800, dma_irqs, system_memory,
- qdev_get_gpio_in(s->ih[0], OMAP_INT_DMA_LCD),
- s, omap_findclk(s, "dma_ck"), omap_dma_3_1);
-
- s->port[emiff ].addr_valid = omap_validate_emiff_addr;
- s->port[emifs ].addr_valid = omap_validate_emifs_addr;
- s->port[imif ].addr_valid = omap_validate_imif_addr;
- s->port[tipb ].addr_valid = omap_validate_tipb_addr;
- s->port[local ].addr_valid = omap_validate_local_addr;
- s->port[tipb_mpui].addr_valid = omap_validate_tipb_mpui_addr;
-
- /* Register SDRAM and SRAM DMA ports for fast transfers. */
- soc_dma_port_add_mem(s->dma, memory_region_get_ram_ptr(&s->emiff_ram),
- OMAP_EMIFF_BASE, s->sdram_size);
- soc_dma_port_add_mem(s->dma, memory_region_get_ram_ptr(&s->imif_ram),
- OMAP_IMIF_BASE, s->sram_size);
-
- s->timer[0] = omap_mpu_timer_init(system_memory, 0xfffec500,
- qdev_get_gpio_in(s->ih[0], OMAP_INT_TIMER1),
- omap_findclk(s, "mputim_ck"));
- s->timer[1] = omap_mpu_timer_init(system_memory, 0xfffec600,
- qdev_get_gpio_in(s->ih[0], OMAP_INT_TIMER2),
- omap_findclk(s, "mputim_ck"));
- s->timer[2] = omap_mpu_timer_init(system_memory, 0xfffec700,
- qdev_get_gpio_in(s->ih[0], OMAP_INT_TIMER3),
- omap_findclk(s, "mputim_ck"));
-
- s->wdt = omap_wd_timer_init(system_memory, 0xfffec800,
- qdev_get_gpio_in(s->ih[0], OMAP_INT_WD_TIMER),
- omap_findclk(s, "armwdt_ck"));
-
- s->os_timer = omap_os_timer_init(system_memory, 0xfffb9000,
- qdev_get_gpio_in(s->ih[1], OMAP_INT_OS_TIMER),
- omap_findclk(s, "clk32-kHz"));
-
- s->lcd = omap_lcdc_init(system_memory, 0xfffec000,
- qdev_get_gpio_in(s->ih[0], OMAP_INT_LCD_CTRL),
- omap_dma_get_lcdch(s->dma),
- omap_findclk(s, "lcd_ck"));
-
- omap_ulpd_pm_init(system_memory, 0xfffe0800, s);
- omap_pin_cfg_init(system_memory, 0xfffe1000, s);
- omap_id_init(system_memory, s);
-
- omap_mpui_init(system_memory, 0xfffec900, s);
-
- s->private_tipb = omap_tipb_bridge_init(system_memory, 0xfffeca00,
- qdev_get_gpio_in(s->ih[0], OMAP_INT_BRIDGE_PRIV),
- omap_findclk(s, "tipb_ck"));
- s->public_tipb = omap_tipb_bridge_init(system_memory, 0xfffed300,
- qdev_get_gpio_in(s->ih[0], OMAP_INT_BRIDGE_PUB),
- omap_findclk(s, "tipb_ck"));
-
- omap_tcmi_init(system_memory, 0xfffecc00, s);
-
- s->uart[0] = omap_uart_init(0xfffb0000,
- qdev_get_gpio_in(s->ih[1], OMAP_INT_UART1),
- omap_findclk(s, "uart1_ck"),
- omap_findclk(s, "uart1_ck"),
- s->drq[OMAP_DMA_UART1_TX], s->drq[OMAP_DMA_UART1_RX],
- "uart1",
- serial_hds[0]);
- s->uart[1] = omap_uart_init(0xfffb0800,
- qdev_get_gpio_in(s->ih[1], OMAP_INT_UART2),
- omap_findclk(s, "uart2_ck"),
- omap_findclk(s, "uart2_ck"),
- s->drq[OMAP_DMA_UART2_TX], s->drq[OMAP_DMA_UART2_RX],
- "uart2",
- serial_hds[0] ? serial_hds[1] : NULL);
- s->uart[2] = omap_uart_init(0xfffb9800,
- qdev_get_gpio_in(s->ih[0], OMAP_INT_UART3),
- omap_findclk(s, "uart3_ck"),
- omap_findclk(s, "uart3_ck"),
- s->drq[OMAP_DMA_UART3_TX], s->drq[OMAP_DMA_UART3_RX],
- "uart3",
- serial_hds[0] && serial_hds[1] ? serial_hds[2] : NULL);
-
- s->dpll[0] = omap_dpll_init(system_memory, 0xfffecf00,
- omap_findclk(s, "dpll1"));
- s->dpll[1] = omap_dpll_init(system_memory, 0xfffed000,
- omap_findclk(s, "dpll2"));
- s->dpll[2] = omap_dpll_init(system_memory, 0xfffed100,
- omap_findclk(s, "dpll3"));
-
- dinfo = drive_get(IF_SD, 0, 0);
- if (!dinfo) {
- fprintf(stderr, "qemu: missing SecureDigital device\n");
- exit(1);
- }
- s->mmc = omap_mmc_init(0xfffb7800, system_memory,
- blk_by_legacy_dinfo(dinfo),
- qdev_get_gpio_in(s->ih[1], OMAP_INT_OQN),
- &s->drq[OMAP_DMA_MMC_TX],
- omap_findclk(s, "mmc_ck"));
-
- s->mpuio = omap_mpuio_init(system_memory, 0xfffb5000,
- qdev_get_gpio_in(s->ih[1], OMAP_INT_KEYBOARD),
- qdev_get_gpio_in(s->ih[1], OMAP_INT_MPUIO),
- s->wakeup, omap_findclk(s, "clk32-kHz"));
-
- s->gpio = qdev_create(NULL, "omap-gpio");
- qdev_prop_set_int32(s->gpio, "mpu_model", s->mpu_model);
- qdev_prop_set_ptr(s->gpio, "clk", omap_findclk(s, "arm_gpio_ck"));
- qdev_init_nofail(s->gpio);
- sysbus_connect_irq(SYS_BUS_DEVICE(s->gpio), 0,
- qdev_get_gpio_in(s->ih[0], OMAP_INT_GPIO_BANK1));
- sysbus_mmio_map(SYS_BUS_DEVICE(s->gpio), 0, 0xfffce000);
-
- s->microwire = omap_uwire_init(system_memory, 0xfffb3000,
- qdev_get_gpio_in(s->ih[1], OMAP_INT_uWireTX),
- qdev_get_gpio_in(s->ih[1], OMAP_INT_uWireRX),
- s->drq[OMAP_DMA_UWIRE_TX], omap_findclk(s, "mpuper_ck"));
-
- s->pwl = omap_pwl_init(system_memory, 0xfffb5800,
- omap_findclk(s, "armxor_ck"));
- s->pwt = omap_pwt_init(system_memory, 0xfffb6000,
- omap_findclk(s, "armxor_ck"));
-
- s->i2c[0] = qdev_create(NULL, "omap_i2c");
- qdev_prop_set_uint8(s->i2c[0], "revision", 0x11);
- qdev_prop_set_ptr(s->i2c[0], "fclk", omap_findclk(s, "mpuper_ck"));
- qdev_init_nofail(s->i2c[0]);
- busdev = SYS_BUS_DEVICE(s->i2c[0]);
- sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(s->ih[1], OMAP_INT_I2C));
- sysbus_connect_irq(busdev, 1, s->drq[OMAP_DMA_I2C_TX]);
- sysbus_connect_irq(busdev, 2, s->drq[OMAP_DMA_I2C_RX]);
- sysbus_mmio_map(busdev, 0, 0xfffb3800);
-
- s->rtc = omap_rtc_init(system_memory, 0xfffb4800,
- qdev_get_gpio_in(s->ih[1], OMAP_INT_RTC_TIMER),
- qdev_get_gpio_in(s->ih[1], OMAP_INT_RTC_ALARM),
- omap_findclk(s, "clk32-kHz"));
-
- s->mcbsp1 = omap_mcbsp_init(system_memory, 0xfffb1800,
- qdev_get_gpio_in(s->ih[1], OMAP_INT_McBSP1TX),
- qdev_get_gpio_in(s->ih[1], OMAP_INT_McBSP1RX),
- &s->drq[OMAP_DMA_MCBSP1_TX], omap_findclk(s, "dspxor_ck"));
- s->mcbsp2 = omap_mcbsp_init(system_memory, 0xfffb1000,
- qdev_get_gpio_in(s->ih[0],
- OMAP_INT_310_McBSP2_TX),
- qdev_get_gpio_in(s->ih[0],
- OMAP_INT_310_McBSP2_RX),
- &s->drq[OMAP_DMA_MCBSP2_TX], omap_findclk(s, "mpuper_ck"));
- s->mcbsp3 = omap_mcbsp_init(system_memory, 0xfffb7000,
- qdev_get_gpio_in(s->ih[1], OMAP_INT_McBSP3TX),
- qdev_get_gpio_in(s->ih[1], OMAP_INT_McBSP3RX),
- &s->drq[OMAP_DMA_MCBSP3_TX], omap_findclk(s, "dspxor_ck"));
-
- s->led[0] = omap_lpg_init(system_memory,
- 0xfffbd000, omap_findclk(s, "clk32-kHz"));
- s->led[1] = omap_lpg_init(system_memory,
- 0xfffbd800, omap_findclk(s, "clk32-kHz"));
-
- /* Register mappings not currenlty implemented:
- * MCSI2 Comm fffb2000 - fffb27ff (not mapped on OMAP310)
- * MCSI1 Bluetooth fffb2800 - fffb2fff (not mapped on OMAP310)
- * USB W2FC fffb4000 - fffb47ff
- * Camera Interface fffb6800 - fffb6fff
- * USB Host fffba000 - fffba7ff
- * FAC fffba800 - fffbafff
- * HDQ/1-Wire fffbc000 - fffbc7ff
- * TIPB switches fffbc800 - fffbcfff
- * Mailbox fffcf000 - fffcf7ff
- * Local bus IF fffec100 - fffec1ff
- * Local bus MMU fffec200 - fffec2ff
- * DSP MMU fffed200 - fffed2ff
- */
-
- omap_setup_dsp_mapping(system_memory, omap15xx_dsp_mm);
- omap_setup_mpui_io(system_memory, s);
-
- qemu_register_reset(omap1_mpu_reset, s);
-
- return s;
-}
diff --git a/qemu/hw/arm/omap2.c b/qemu/hw/arm/omap2.c
deleted file mode 100644
index 3a0d77714..000000000
--- a/qemu/hw/arm/omap2.c
+++ /dev/null
@@ -1,2691 +0,0 @@
-/*
- * TI OMAP processors emulation.
- *
- * Copyright (C) 2007-2008 Nokia Corporation
- * Written by Andrzej Zaborowski <andrew@openedhand.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 or
- * (at your option) version 3 of the License.
- *
- * 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/>.
- */
-
-#include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "qemu-common.h"
-#include "cpu.h"
-#include "sysemu/block-backend.h"
-#include "sysemu/blockdev.h"
-#include "hw/boards.h"
-#include "hw/hw.h"
-#include "hw/arm/arm.h"
-#include "hw/arm/omap.h"
-#include "sysemu/sysemu.h"
-#include "qemu/timer.h"
-#include "sysemu/char.h"
-#include "hw/block/flash.h"
-#include "hw/arm/soc_dma.h"
-#include "hw/sysbus.h"
-#include "audio/audio.h"
-
-/* Enhanced Audio Controller (CODEC only) */
-struct omap_eac_s {
- qemu_irq irq;
- MemoryRegion iomem;
-
- uint16_t sysconfig;
- uint8_t config[4];
- uint8_t control;
- uint8_t address;
- uint16_t data;
- uint8_t vtol;
- uint8_t vtsl;
- uint16_t mixer;
- uint16_t gain[4];
- uint8_t att;
- uint16_t max[7];
-
- struct {
- qemu_irq txdrq;
- qemu_irq rxdrq;
- uint32_t (*txrx)(void *opaque, uint32_t, int);
- void *opaque;
-
-#define EAC_BUF_LEN 1024
- uint32_t rxbuf[EAC_BUF_LEN];
- int rxoff;
- int rxlen;
- int rxavail;
- uint32_t txbuf[EAC_BUF_LEN];
- int txlen;
- int txavail;
-
- int enable;
- int rate;
-
- uint16_t config[4];
-
- /* These need to be moved to the actual codec */
- QEMUSoundCard card;
- SWVoiceIn *in_voice;
- SWVoiceOut *out_voice;
- int hw_enable;
- } codec;
-
- struct {
- uint8_t control;
- uint16_t config;
- } modem, bt;
-};
-
-static inline void omap_eac_interrupt_update(struct omap_eac_s *s)
-{
- qemu_set_irq(s->irq, (s->codec.config[1] >> 14) & 1); /* AURDI */
-}
-
-static inline void omap_eac_in_dmarequest_update(struct omap_eac_s *s)
-{
- qemu_set_irq(s->codec.rxdrq, (s->codec.rxavail || s->codec.rxlen) &&
- ((s->codec.config[1] >> 12) & 1)); /* DMAREN */
-}
-
-static inline void omap_eac_out_dmarequest_update(struct omap_eac_s *s)
-{
- qemu_set_irq(s->codec.txdrq, s->codec.txlen < s->codec.txavail &&
- ((s->codec.config[1] >> 11) & 1)); /* DMAWEN */
-}
-
-static inline void omap_eac_in_refill(struct omap_eac_s *s)
-{
- int left = MIN(EAC_BUF_LEN - s->codec.rxlen, s->codec.rxavail) << 2;
- int start = ((s->codec.rxoff + s->codec.rxlen) & (EAC_BUF_LEN - 1)) << 2;
- int leftwrap = MIN(left, (EAC_BUF_LEN << 2) - start);
- int recv = 1;
- uint8_t *buf = (uint8_t *) s->codec.rxbuf + start;
-
- left -= leftwrap;
- start = 0;
- while (leftwrap && (recv = AUD_read(s->codec.in_voice, buf + start,
- leftwrap)) > 0) { /* Be defensive */
- start += recv;
- leftwrap -= recv;
- }
- if (recv <= 0)
- s->codec.rxavail = 0;
- else
- s->codec.rxavail -= start >> 2;
- s->codec.rxlen += start >> 2;
-
- if (recv > 0 && left > 0) {
- start = 0;
- while (left && (recv = AUD_read(s->codec.in_voice,
- (uint8_t *) s->codec.rxbuf + start,
- left)) > 0) { /* Be defensive */
- start += recv;
- left -= recv;
- }
- if (recv <= 0)
- s->codec.rxavail = 0;
- else
- s->codec.rxavail -= start >> 2;
- s->codec.rxlen += start >> 2;
- }
-}
-
-static inline void omap_eac_out_empty(struct omap_eac_s *s)
-{
- int left = s->codec.txlen << 2;
- int start = 0;
- int sent = 1;
-
- while (left && (sent = AUD_write(s->codec.out_voice,
- (uint8_t *) s->codec.txbuf + start,
- left)) > 0) { /* Be defensive */
- start += sent;
- left -= sent;
- }
-
- if (!sent) {
- s->codec.txavail = 0;
- omap_eac_out_dmarequest_update(s);
- }
-
- if (start)
- s->codec.txlen = 0;
-}
-
-static void omap_eac_in_cb(void *opaque, int avail_b)
-{
- struct omap_eac_s *s = (struct omap_eac_s *) opaque;
-
- s->codec.rxavail = avail_b >> 2;
- omap_eac_in_refill(s);
- /* TODO: possibly discard current buffer if overrun */
- omap_eac_in_dmarequest_update(s);
-}
-
-static void omap_eac_out_cb(void *opaque, int free_b)
-{
- struct omap_eac_s *s = (struct omap_eac_s *) opaque;
-
- s->codec.txavail = free_b >> 2;
- if (s->codec.txlen)
- omap_eac_out_empty(s);
- else
- omap_eac_out_dmarequest_update(s);
-}
-
-static void omap_eac_enable_update(struct omap_eac_s *s)
-{
- s->codec.enable = !(s->codec.config[1] & 1) && /* EACPWD */
- (s->codec.config[1] & 2) && /* AUDEN */
- s->codec.hw_enable;
-}
-
-static const int omap_eac_fsint[4] = {
- 8000,
- 11025,
- 22050,
- 44100,
-};
-
-static const int omap_eac_fsint2[8] = {
- 8000,
- 11025,
- 22050,
- 44100,
- 48000,
- 0, 0, 0,
-};
-
-static const int omap_eac_fsint3[16] = {
- 8000,
- 11025,
- 16000,
- 22050,
- 24000,
- 32000,
- 44100,
- 48000,
- 0, 0, 0, 0, 0, 0, 0, 0,
-};
-
-static void omap_eac_rate_update(struct omap_eac_s *s)
-{
- int fsint[3];
-
- fsint[2] = (s->codec.config[3] >> 9) & 0xf;
- fsint[1] = (s->codec.config[2] >> 0) & 0x7;
- fsint[0] = (s->codec.config[0] >> 6) & 0x3;
- if (fsint[2] < 0xf)
- s->codec.rate = omap_eac_fsint3[fsint[2]];
- else if (fsint[1] < 0x7)
- s->codec.rate = omap_eac_fsint2[fsint[1]];
- else
- s->codec.rate = omap_eac_fsint[fsint[0]];
-}
-
-static void omap_eac_volume_update(struct omap_eac_s *s)
-{
- /* TODO */
-}
-
-static void omap_eac_format_update(struct omap_eac_s *s)
-{
- struct audsettings fmt;
-
- /* The hardware buffers at most one sample */
- if (s->codec.rxlen)
- s->codec.rxlen = 1;
-
- if (s->codec.in_voice) {
- AUD_set_active_in(s->codec.in_voice, 0);
- AUD_close_in(&s->codec.card, s->codec.in_voice);
- s->codec.in_voice = NULL;
- }
- if (s->codec.out_voice) {
- omap_eac_out_empty(s);
- AUD_set_active_out(s->codec.out_voice, 0);
- AUD_close_out(&s->codec.card, s->codec.out_voice);
- s->codec.out_voice = NULL;
- s->codec.txavail = 0;
- }
- /* Discard what couldn't be written */
- s->codec.txlen = 0;
-
- omap_eac_enable_update(s);
- if (!s->codec.enable)
- return;
-
- omap_eac_rate_update(s);
- fmt.endianness = ((s->codec.config[0] >> 8) & 1); /* LI_BI */
- fmt.nchannels = ((s->codec.config[0] >> 10) & 1) ? 2 : 1; /* MN_ST */
- fmt.freq = s->codec.rate;
- /* TODO: signedness possibly depends on the CODEC hardware - or
- * does I2S specify it? */
- /* All register writes are 16 bits so we we store 16-bit samples
- * in the buffers regardless of AGCFR[B8_16] value. */
- fmt.fmt = AUD_FMT_U16;
-
- s->codec.in_voice = AUD_open_in(&s->codec.card, s->codec.in_voice,
- "eac.codec.in", s, omap_eac_in_cb, &fmt);
- s->codec.out_voice = AUD_open_out(&s->codec.card, s->codec.out_voice,
- "eac.codec.out", s, omap_eac_out_cb, &fmt);
-
- omap_eac_volume_update(s);
-
- AUD_set_active_in(s->codec.in_voice, 1);
- AUD_set_active_out(s->codec.out_voice, 1);
-}
-
-static void omap_eac_reset(struct omap_eac_s *s)
-{
- s->sysconfig = 0;
- s->config[0] = 0x0c;
- s->config[1] = 0x09;
- s->config[2] = 0xab;
- s->config[3] = 0x03;
- s->control = 0x00;
- s->address = 0x00;
- s->data = 0x0000;
- s->vtol = 0x00;
- s->vtsl = 0x00;
- s->mixer = 0x0000;
- s->gain[0] = 0xe7e7;
- s->gain[1] = 0x6767;
- s->gain[2] = 0x6767;
- s->gain[3] = 0x6767;
- s->att = 0xce;
- s->max[0] = 0;
- s->max[1] = 0;
- s->max[2] = 0;
- s->max[3] = 0;
- s->max[4] = 0;
- s->max[5] = 0;
- s->max[6] = 0;
-
- s->modem.control = 0x00;
- s->modem.config = 0x0000;
- s->bt.control = 0x00;
- s->bt.config = 0x0000;
- s->codec.config[0] = 0x0649;
- s->codec.config[1] = 0x0000;
- s->codec.config[2] = 0x0007;
- s->codec.config[3] = 0x1ffc;
- s->codec.rxoff = 0;
- s->codec.rxlen = 0;
- s->codec.txlen = 0;
- s->codec.rxavail = 0;
- s->codec.txavail = 0;
-
- omap_eac_format_update(s);
- omap_eac_interrupt_update(s);
-}
-
-static uint64_t omap_eac_read(void *opaque, hwaddr addr,
- unsigned size)
-{
- struct omap_eac_s *s = (struct omap_eac_s *) opaque;
- uint32_t ret;
-
- if (size != 2) {
- return omap_badwidth_read16(opaque, addr);
- }
-
- switch (addr) {
- case 0x000: /* CPCFR1 */
- return s->config[0];
- case 0x004: /* CPCFR2 */
- return s->config[1];
- case 0x008: /* CPCFR3 */
- return s->config[2];
- case 0x00c: /* CPCFR4 */
- return s->config[3];
-
- case 0x010: /* CPTCTL */
- return s->control | ((s->codec.rxavail + s->codec.rxlen > 0) << 7) |
- ((s->codec.txlen < s->codec.txavail) << 5);
-
- case 0x014: /* CPTTADR */
- return s->address;
- case 0x018: /* CPTDATL */
- return s->data & 0xff;
- case 0x01c: /* CPTDATH */
- return s->data >> 8;
- case 0x020: /* CPTVSLL */
- return s->vtol;
- case 0x024: /* CPTVSLH */
- return s->vtsl | (3 << 5); /* CRDY1 | CRDY2 */
- case 0x040: /* MPCTR */
- return s->modem.control;
- case 0x044: /* MPMCCFR */
- return s->modem.config;
- case 0x060: /* BPCTR */
- return s->bt.control;
- case 0x064: /* BPMCCFR */
- return s->bt.config;
- case 0x080: /* AMSCFR */
- return s->mixer;
- case 0x084: /* AMVCTR */
- return s->gain[0];
- case 0x088: /* AM1VCTR */
- return s->gain[1];
- case 0x08c: /* AM2VCTR */
- return s->gain[2];
- case 0x090: /* AM3VCTR */
- return s->gain[3];
- case 0x094: /* ASTCTR */
- return s->att;
- case 0x098: /* APD1LCR */
- return s->max[0];
- case 0x09c: /* APD1RCR */
- return s->max[1];
- case 0x0a0: /* APD2LCR */
- return s->max[2];
- case 0x0a4: /* APD2RCR */
- return s->max[3];
- case 0x0a8: /* APD3LCR */
- return s->max[4];
- case 0x0ac: /* APD3RCR */
- return s->max[5];
- case 0x0b0: /* APD4R */
- return s->max[6];
- case 0x0b4: /* ADWR */
- /* This should be write-only? Docs list it as read-only. */
- return 0x0000;
- case 0x0b8: /* ADRDR */
- if (likely(s->codec.rxlen > 1)) {
- ret = s->codec.rxbuf[s->codec.rxoff ++];
- s->codec.rxlen --;
- s->codec.rxoff &= EAC_BUF_LEN - 1;
- return ret;
- } else if (s->codec.rxlen) {
- ret = s->codec.rxbuf[s->codec.rxoff ++];
- s->codec.rxlen --;
- s->codec.rxoff &= EAC_BUF_LEN - 1;
- if (s->codec.rxavail)
- omap_eac_in_refill(s);
- omap_eac_in_dmarequest_update(s);
- return ret;
- }
- return 0x0000;
- case 0x0bc: /* AGCFR */
- return s->codec.config[0];
- case 0x0c0: /* AGCTR */
- return s->codec.config[1] | ((s->codec.config[1] & 2) << 14);
- case 0x0c4: /* AGCFR2 */
- return s->codec.config[2];
- case 0x0c8: /* AGCFR3 */
- return s->codec.config[3];
- case 0x0cc: /* MBPDMACTR */
- case 0x0d0: /* MPDDMARR */
- case 0x0d8: /* MPUDMARR */
- case 0x0e4: /* BPDDMARR */
- case 0x0ec: /* BPUDMARR */
- return 0x0000;
-
- case 0x100: /* VERSION_NUMBER */
- return 0x0010;
-
- case 0x104: /* SYSCONFIG */
- return s->sysconfig;
-
- case 0x108: /* SYSSTATUS */
- return 1 | 0xe; /* RESETDONE | stuff */
- }
-
- OMAP_BAD_REG(addr);
- return 0;
-}
-
-static void omap_eac_write(void *opaque, hwaddr addr,
- uint64_t value, unsigned size)
-{
- struct omap_eac_s *s = (struct omap_eac_s *) opaque;
-
- if (size != 2) {
- omap_badwidth_write16(opaque, addr, value);
- return;
- }
-
- switch (addr) {
- case 0x098: /* APD1LCR */
- case 0x09c: /* APD1RCR */
- case 0x0a0: /* APD2LCR */
- case 0x0a4: /* APD2RCR */
- case 0x0a8: /* APD3LCR */
- case 0x0ac: /* APD3RCR */
- case 0x0b0: /* APD4R */
- case 0x0b8: /* ADRDR */
- case 0x0d0: /* MPDDMARR */
- case 0x0d8: /* MPUDMARR */
- case 0x0e4: /* BPDDMARR */
- case 0x0ec: /* BPUDMARR */
- case 0x100: /* VERSION_NUMBER */
- case 0x108: /* SYSSTATUS */
- OMAP_RO_REG(addr);
- return;
-
- case 0x000: /* CPCFR1 */
- s->config[0] = value & 0xff;
- omap_eac_format_update(s);
- break;
- case 0x004: /* CPCFR2 */
- s->config[1] = value & 0xff;
- omap_eac_format_update(s);
- break;
- case 0x008: /* CPCFR3 */
- s->config[2] = value & 0xff;
- omap_eac_format_update(s);
- break;
- case 0x00c: /* CPCFR4 */
- s->config[3] = value & 0xff;
- omap_eac_format_update(s);
- break;
-
- case 0x010: /* CPTCTL */
- /* Assuming TXF and TXE bits are read-only... */
- s->control = value & 0x5f;
- omap_eac_interrupt_update(s);
- break;
-
- case 0x014: /* CPTTADR */
- s->address = value & 0xff;
- break;
- case 0x018: /* CPTDATL */
- s->data &= 0xff00;
- s->data |= value & 0xff;
- break;
- case 0x01c: /* CPTDATH */
- s->data &= 0x00ff;
- s->data |= value << 8;
- break;
- case 0x020: /* CPTVSLL */
- s->vtol = value & 0xf8;
- break;
- case 0x024: /* CPTVSLH */
- s->vtsl = value & 0x9f;
- break;
- case 0x040: /* MPCTR */
- s->modem.control = value & 0x8f;
- break;
- case 0x044: /* MPMCCFR */
- s->modem.config = value & 0x7fff;
- break;
- case 0x060: /* BPCTR */
- s->bt.control = value & 0x8f;
- break;
- case 0x064: /* BPMCCFR */
- s->bt.config = value & 0x7fff;
- break;
- case 0x080: /* AMSCFR */
- s->mixer = value & 0x0fff;
- break;
- case 0x084: /* AMVCTR */
- s->gain[0] = value & 0xffff;
- break;
- case 0x088: /* AM1VCTR */
- s->gain[1] = value & 0xff7f;
- break;
- case 0x08c: /* AM2VCTR */
- s->gain[2] = value & 0xff7f;
- break;
- case 0x090: /* AM3VCTR */
- s->gain[3] = value & 0xff7f;
- break;
- case 0x094: /* ASTCTR */
- s->att = value & 0xff;
- break;
-
- case 0x0b4: /* ADWR */
- s->codec.txbuf[s->codec.txlen ++] = value;
- if (unlikely(s->codec.txlen == EAC_BUF_LEN ||
- s->codec.txlen == s->codec.txavail)) {
- if (s->codec.txavail)
- omap_eac_out_empty(s);
- /* Discard what couldn't be written */
- s->codec.txlen = 0;
- }
- break;
-
- case 0x0bc: /* AGCFR */
- s->codec.config[0] = value & 0x07ff;
- omap_eac_format_update(s);
- break;
- case 0x0c0: /* AGCTR */
- s->codec.config[1] = value & 0x780f;
- omap_eac_format_update(s);
- break;
- case 0x0c4: /* AGCFR2 */
- s->codec.config[2] = value & 0x003f;
- omap_eac_format_update(s);
- break;
- case 0x0c8: /* AGCFR3 */
- s->codec.config[3] = value & 0xffff;
- omap_eac_format_update(s);
- break;
- case 0x0cc: /* MBPDMACTR */
- case 0x0d4: /* MPDDMAWR */
- case 0x0e0: /* MPUDMAWR */
- case 0x0e8: /* BPDDMAWR */
- case 0x0f0: /* BPUDMAWR */
- break;
-
- case 0x104: /* SYSCONFIG */
- if (value & (1 << 1)) /* SOFTRESET */
- omap_eac_reset(s);
- s->sysconfig = value & 0x31d;
- break;
-
- default:
- OMAP_BAD_REG(addr);
- return;
- }
-}
-
-static const MemoryRegionOps omap_eac_ops = {
- .read = omap_eac_read,
- .write = omap_eac_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static struct omap_eac_s *omap_eac_init(struct omap_target_agent_s *ta,
- qemu_irq irq, qemu_irq *drq, omap_clk fclk, omap_clk iclk)
-{
- struct omap_eac_s *s = g_new0(struct omap_eac_s, 1);
-
- s->irq = irq;
- s->codec.rxdrq = *drq ++;
- s->codec.txdrq = *drq;
- omap_eac_reset(s);
-
- AUD_register_card("OMAP EAC", &s->codec.card);
-
- memory_region_init_io(&s->iomem, NULL, &omap_eac_ops, s, "omap.eac",
- omap_l4_region_size(ta, 0));
- omap_l4_attach(ta, 0, &s->iomem);
-
- return s;
-}
-
-/* STI/XTI (emulation interface) console - reverse engineered only */
-struct omap_sti_s {
- qemu_irq irq;
- MemoryRegion iomem;
- MemoryRegion iomem_fifo;
- CharDriverState *chr;
-
- uint32_t sysconfig;
- uint32_t systest;
- uint32_t irqst;
- uint32_t irqen;
- uint32_t clkcontrol;
- uint32_t serial_config;
-};
-
-#define STI_TRACE_CONSOLE_CHANNEL 239
-#define STI_TRACE_CONTROL_CHANNEL 253
-
-static inline void omap_sti_interrupt_update(struct omap_sti_s *s)
-{
- qemu_set_irq(s->irq, s->irqst & s->irqen);
-}
-
-static void omap_sti_reset(struct omap_sti_s *s)
-{
- s->sysconfig = 0;
- s->irqst = 0;
- s->irqen = 0;
- s->clkcontrol = 0;
- s->serial_config = 0;
-
- omap_sti_interrupt_update(s);
-}
-
-static uint64_t omap_sti_read(void *opaque, hwaddr addr,
- unsigned size)
-{
- struct omap_sti_s *s = (struct omap_sti_s *) opaque;
-
- if (size != 4) {
- return omap_badwidth_read32(opaque, addr);
- }
-
- switch (addr) {
- case 0x00: /* STI_REVISION */
- return 0x10;
-
- case 0x10: /* STI_SYSCONFIG */
- return s->sysconfig;
-
- case 0x14: /* STI_SYSSTATUS / STI_RX_STATUS / XTI_SYSSTATUS */
- return 0x00;
-
- case 0x18: /* STI_IRQSTATUS */
- return s->irqst;
-
- case 0x1c: /* STI_IRQSETEN / STI_IRQCLREN */
- return s->irqen;
-
- case 0x24: /* STI_ER / STI_DR / XTI_TRACESELECT */
- case 0x28: /* STI_RX_DR / XTI_RXDATA */
- /* TODO */
- return 0;
-
- case 0x2c: /* STI_CLK_CTRL / XTI_SCLKCRTL */
- return s->clkcontrol;
-
- case 0x30: /* STI_SERIAL_CFG / XTI_SCONFIG */
- return s->serial_config;
- }
-
- OMAP_BAD_REG(addr);
- return 0;
-}
-
-static void omap_sti_write(void *opaque, hwaddr addr,
- uint64_t value, unsigned size)
-{
- struct omap_sti_s *s = (struct omap_sti_s *) opaque;
-
- if (size != 4) {
- omap_badwidth_write32(opaque, addr, value);
- return;
- }
-
- switch (addr) {
- case 0x00: /* STI_REVISION */
- case 0x14: /* STI_SYSSTATUS / STI_RX_STATUS / XTI_SYSSTATUS */
- OMAP_RO_REG(addr);
- return;
-
- case 0x10: /* STI_SYSCONFIG */
- if (value & (1 << 1)) /* SOFTRESET */
- omap_sti_reset(s);
- s->sysconfig = value & 0xfe;
- break;
-
- case 0x18: /* STI_IRQSTATUS */
- s->irqst &= ~value;
- omap_sti_interrupt_update(s);
- break;
-
- case 0x1c: /* STI_IRQSETEN / STI_IRQCLREN */
- s->irqen = value & 0xffff;
- omap_sti_interrupt_update(s);
- break;
-
- case 0x2c: /* STI_CLK_CTRL / XTI_SCLKCRTL */
- s->clkcontrol = value & 0xff;
- break;
-
- case 0x30: /* STI_SERIAL_CFG / XTI_SCONFIG */
- s->serial_config = value & 0xff;
- break;
-
- case 0x24: /* STI_ER / STI_DR / XTI_TRACESELECT */
- case 0x28: /* STI_RX_DR / XTI_RXDATA */
- /* TODO */
- return;
-
- default:
- OMAP_BAD_REG(addr);
- return;
- }
-}
-
-static const MemoryRegionOps omap_sti_ops = {
- .read = omap_sti_read,
- .write = omap_sti_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static uint64_t omap_sti_fifo_read(void *opaque, hwaddr addr,
- unsigned size)
-{
- OMAP_BAD_REG(addr);
- return 0;
-}
-
-static void omap_sti_fifo_write(void *opaque, hwaddr addr,
- uint64_t value, unsigned size)
-{
- struct omap_sti_s *s = (struct omap_sti_s *) opaque;
- int ch = addr >> 6;
- uint8_t byte = value;
-
- if (size != 1) {
- omap_badwidth_write8(opaque, addr, size);
- return;
- }
-
- if (ch == STI_TRACE_CONTROL_CHANNEL) {
- /* Flush channel <i>value</i>. */
- qemu_chr_fe_write(s->chr, (const uint8_t *) "\r", 1);
- } else if (ch == STI_TRACE_CONSOLE_CHANNEL || 1) {
- if (value == 0xc0 || value == 0xc3) {
- /* Open channel <i>ch</i>. */
- } else if (value == 0x00)
- qemu_chr_fe_write(s->chr, (const uint8_t *) "\n", 1);
- else
- qemu_chr_fe_write(s->chr, &byte, 1);
- }
-}
-
-static const MemoryRegionOps omap_sti_fifo_ops = {
- .read = omap_sti_fifo_read,
- .write = omap_sti_fifo_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static struct omap_sti_s *omap_sti_init(struct omap_target_agent_s *ta,
- MemoryRegion *sysmem,
- hwaddr channel_base, qemu_irq irq, omap_clk clk,
- CharDriverState *chr)
-{
- struct omap_sti_s *s = g_new0(struct omap_sti_s, 1);
-
- s->irq = irq;
- omap_sti_reset(s);
-
- s->chr = chr ?: qemu_chr_new("null", "null", NULL);
-
- memory_region_init_io(&s->iomem, NULL, &omap_sti_ops, s, "omap.sti",
- omap_l4_region_size(ta, 0));
- omap_l4_attach(ta, 0, &s->iomem);
-
- memory_region_init_io(&s->iomem_fifo, NULL, &omap_sti_fifo_ops, s,
- "omap.sti.fifo", 0x10000);
- memory_region_add_subregion(sysmem, channel_base, &s->iomem_fifo);
-
- return s;
-}
-
-/* L4 Interconnect */
-#define L4TA(n) (n)
-#define L4TAO(n) ((n) + 39)
-
-static const struct omap_l4_region_s omap_l4_region[125] = {
- [ 1] = { 0x40800, 0x800, 32 }, /* Initiator agent */
- [ 2] = { 0x41000, 0x1000, 32 }, /* Link agent */
- [ 0] = { 0x40000, 0x800, 32 }, /* Address and protection */
- [ 3] = { 0x00000, 0x1000, 32 | 16 | 8 }, /* System Control and Pinout */
- [ 4] = { 0x01000, 0x1000, 32 | 16 | 8 }, /* L4TAO1 */
- [ 5] = { 0x04000, 0x1000, 32 | 16 }, /* 32K Timer */
- [ 6] = { 0x05000, 0x1000, 32 | 16 | 8 }, /* L4TAO2 */
- [ 7] = { 0x08000, 0x800, 32 }, /* PRCM Region A */
- [ 8] = { 0x08800, 0x800, 32 }, /* PRCM Region B */
- [ 9] = { 0x09000, 0x1000, 32 | 16 | 8 }, /* L4TAO */
- [ 10] = { 0x12000, 0x1000, 32 | 16 | 8 }, /* Test (BCM) */
- [ 11] = { 0x13000, 0x1000, 32 | 16 | 8 }, /* L4TA1 */
- [ 12] = { 0x14000, 0x1000, 32 }, /* Test/emulation (TAP) */
- [ 13] = { 0x15000, 0x1000, 32 | 16 | 8 }, /* L4TA2 */
- [ 14] = { 0x18000, 0x1000, 32 | 16 | 8 }, /* GPIO1 */
- [ 16] = { 0x1a000, 0x1000, 32 | 16 | 8 }, /* GPIO2 */
- [ 18] = { 0x1c000, 0x1000, 32 | 16 | 8 }, /* GPIO3 */
- [ 19] = { 0x1e000, 0x1000, 32 | 16 | 8 }, /* GPIO4 */
- [ 15] = { 0x19000, 0x1000, 32 | 16 | 8 }, /* Quad GPIO TOP */
- [ 17] = { 0x1b000, 0x1000, 32 | 16 | 8 }, /* L4TA3 */
- [ 20] = { 0x20000, 0x1000, 32 | 16 | 8 }, /* WD Timer 1 (Secure) */
- [ 22] = { 0x22000, 0x1000, 32 | 16 | 8 }, /* WD Timer 2 (OMAP) */
- [ 21] = { 0x21000, 0x1000, 32 | 16 | 8 }, /* Dual WD timer TOP */
- [ 23] = { 0x23000, 0x1000, 32 | 16 | 8 }, /* L4TA4 */
- [ 24] = { 0x28000, 0x1000, 32 | 16 | 8 }, /* GP Timer 1 */
- [ 25] = { 0x29000, 0x1000, 32 | 16 | 8 }, /* L4TA7 */
- [ 26] = { 0x48000, 0x2000, 32 | 16 | 8 }, /* Emulation (ARM11ETB) */
- [ 27] = { 0x4a000, 0x1000, 32 | 16 | 8 }, /* L4TA9 */
- [ 28] = { 0x50000, 0x400, 32 | 16 | 8 }, /* Display top */
- [ 29] = { 0x50400, 0x400, 32 | 16 | 8 }, /* Display control */
- [ 30] = { 0x50800, 0x400, 32 | 16 | 8 }, /* Display RFBI */
- [ 31] = { 0x50c00, 0x400, 32 | 16 | 8 }, /* Display encoder */
- [ 32] = { 0x51000, 0x1000, 32 | 16 | 8 }, /* L4TA10 */
- [ 33] = { 0x52000, 0x400, 32 | 16 | 8 }, /* Camera top */
- [ 34] = { 0x52400, 0x400, 32 | 16 | 8 }, /* Camera core */
- [ 35] = { 0x52800, 0x400, 32 | 16 | 8 }, /* Camera DMA */
- [ 36] = { 0x52c00, 0x400, 32 | 16 | 8 }, /* Camera MMU */
- [ 37] = { 0x53000, 0x1000, 32 | 16 | 8 }, /* L4TA11 */
- [ 38] = { 0x56000, 0x1000, 32 | 16 | 8 }, /* sDMA */
- [ 39] = { 0x57000, 0x1000, 32 | 16 | 8 }, /* L4TA12 */
- [ 40] = { 0x58000, 0x1000, 32 | 16 | 8 }, /* SSI top */
- [ 41] = { 0x59000, 0x1000, 32 | 16 | 8 }, /* SSI GDD */
- [ 42] = { 0x5a000, 0x1000, 32 | 16 | 8 }, /* SSI Port1 */
- [ 43] = { 0x5b000, 0x1000, 32 | 16 | 8 }, /* SSI Port2 */
- [ 44] = { 0x5c000, 0x1000, 32 | 16 | 8 }, /* L4TA13 */
- [ 45] = { 0x5e000, 0x1000, 32 | 16 | 8 }, /* USB OTG */
- [ 46] = { 0x5f000, 0x1000, 32 | 16 | 8 }, /* L4TAO4 */
- [ 47] = { 0x60000, 0x1000, 32 | 16 | 8 }, /* Emulation (WIN_TRACER1SDRC) */
- [ 48] = { 0x61000, 0x1000, 32 | 16 | 8 }, /* L4TA14 */
- [ 49] = { 0x62000, 0x1000, 32 | 16 | 8 }, /* Emulation (WIN_TRACER2GPMC) */
- [ 50] = { 0x63000, 0x1000, 32 | 16 | 8 }, /* L4TA15 */
- [ 51] = { 0x64000, 0x1000, 32 | 16 | 8 }, /* Emulation (WIN_TRACER3OCM) */
- [ 52] = { 0x65000, 0x1000, 32 | 16 | 8 }, /* L4TA16 */
- [ 53] = { 0x66000, 0x300, 32 | 16 | 8 }, /* Emulation (WIN_TRACER4L4) */
- [ 54] = { 0x67000, 0x1000, 32 | 16 | 8 }, /* L4TA17 */
- [ 55] = { 0x68000, 0x1000, 32 | 16 | 8 }, /* Emulation (XTI) */
- [ 56] = { 0x69000, 0x1000, 32 | 16 | 8 }, /* L4TA18 */
- [ 57] = { 0x6a000, 0x1000, 16 | 8 }, /* UART1 */
- [ 58] = { 0x6b000, 0x1000, 32 | 16 | 8 }, /* L4TA19 */
- [ 59] = { 0x6c000, 0x1000, 16 | 8 }, /* UART2 */
- [ 60] = { 0x6d000, 0x1000, 32 | 16 | 8 }, /* L4TA20 */
- [ 61] = { 0x6e000, 0x1000, 16 | 8 }, /* UART3 */
- [ 62] = { 0x6f000, 0x1000, 32 | 16 | 8 }, /* L4TA21 */
- [ 63] = { 0x70000, 0x1000, 16 }, /* I2C1 */
- [ 64] = { 0x71000, 0x1000, 32 | 16 | 8 }, /* L4TAO5 */
- [ 65] = { 0x72000, 0x1000, 16 }, /* I2C2 */
- [ 66] = { 0x73000, 0x1000, 32 | 16 | 8 }, /* L4TAO6 */
- [ 67] = { 0x74000, 0x1000, 16 }, /* McBSP1 */
- [ 68] = { 0x75000, 0x1000, 32 | 16 | 8 }, /* L4TAO7 */
- [ 69] = { 0x76000, 0x1000, 16 }, /* McBSP2 */
- [ 70] = { 0x77000, 0x1000, 32 | 16 | 8 }, /* L4TAO8 */
- [ 71] = { 0x24000, 0x1000, 32 | 16 | 8 }, /* WD Timer 3 (DSP) */
- [ 72] = { 0x25000, 0x1000, 32 | 16 | 8 }, /* L4TA5 */
- [ 73] = { 0x26000, 0x1000, 32 | 16 | 8 }, /* WD Timer 4 (IVA) */
- [ 74] = { 0x27000, 0x1000, 32 | 16 | 8 }, /* L4TA6 */
- [ 75] = { 0x2a000, 0x1000, 32 | 16 | 8 }, /* GP Timer 2 */
- [ 76] = { 0x2b000, 0x1000, 32 | 16 | 8 }, /* L4TA8 */
- [ 77] = { 0x78000, 0x1000, 32 | 16 | 8 }, /* GP Timer 3 */
- [ 78] = { 0x79000, 0x1000, 32 | 16 | 8 }, /* L4TA22 */
- [ 79] = { 0x7a000, 0x1000, 32 | 16 | 8 }, /* GP Timer 4 */
- [ 80] = { 0x7b000, 0x1000, 32 | 16 | 8 }, /* L4TA23 */
- [ 81] = { 0x7c000, 0x1000, 32 | 16 | 8 }, /* GP Timer 5 */
- [ 82] = { 0x7d000, 0x1000, 32 | 16 | 8 }, /* L4TA24 */
- [ 83] = { 0x7e000, 0x1000, 32 | 16 | 8 }, /* GP Timer 6 */
- [ 84] = { 0x7f000, 0x1000, 32 | 16 | 8 }, /* L4TA25 */
- [ 85] = { 0x80000, 0x1000, 32 | 16 | 8 }, /* GP Timer 7 */
- [ 86] = { 0x81000, 0x1000, 32 | 16 | 8 }, /* L4TA26 */
- [ 87] = { 0x82000, 0x1000, 32 | 16 | 8 }, /* GP Timer 8 */
- [ 88] = { 0x83000, 0x1000, 32 | 16 | 8 }, /* L4TA27 */
- [ 89] = { 0x84000, 0x1000, 32 | 16 | 8 }, /* GP Timer 9 */
- [ 90] = { 0x85000, 0x1000, 32 | 16 | 8 }, /* L4TA28 */
- [ 91] = { 0x86000, 0x1000, 32 | 16 | 8 }, /* GP Timer 10 */
- [ 92] = { 0x87000, 0x1000, 32 | 16 | 8 }, /* L4TA29 */
- [ 93] = { 0x88000, 0x1000, 32 | 16 | 8 }, /* GP Timer 11 */
- [ 94] = { 0x89000, 0x1000, 32 | 16 | 8 }, /* L4TA30 */
- [ 95] = { 0x8a000, 0x1000, 32 | 16 | 8 }, /* GP Timer 12 */
- [ 96] = { 0x8b000, 0x1000, 32 | 16 | 8 }, /* L4TA31 */
- [ 97] = { 0x90000, 0x1000, 16 }, /* EAC */
- [ 98] = { 0x91000, 0x1000, 32 | 16 | 8 }, /* L4TA32 */
- [ 99] = { 0x92000, 0x1000, 16 }, /* FAC */
- [100] = { 0x93000, 0x1000, 32 | 16 | 8 }, /* L4TA33 */
- [101] = { 0x94000, 0x1000, 32 | 16 | 8 }, /* IPC (MAILBOX) */
- [102] = { 0x95000, 0x1000, 32 | 16 | 8 }, /* L4TA34 */
- [103] = { 0x98000, 0x1000, 32 | 16 | 8 }, /* SPI1 */
- [104] = { 0x99000, 0x1000, 32 | 16 | 8 }, /* L4TA35 */
- [105] = { 0x9a000, 0x1000, 32 | 16 | 8 }, /* SPI2 */
- [106] = { 0x9b000, 0x1000, 32 | 16 | 8 }, /* L4TA36 */
- [107] = { 0x9c000, 0x1000, 16 | 8 }, /* MMC SDIO */
- [108] = { 0x9d000, 0x1000, 32 | 16 | 8 }, /* L4TAO9 */
- [109] = { 0x9e000, 0x1000, 32 | 16 | 8 }, /* MS_PRO */
- [110] = { 0x9f000, 0x1000, 32 | 16 | 8 }, /* L4TAO10 */
- [111] = { 0xa0000, 0x1000, 32 }, /* RNG */
- [112] = { 0xa1000, 0x1000, 32 | 16 | 8 }, /* L4TAO11 */
- [113] = { 0xa2000, 0x1000, 32 }, /* DES3DES */
- [114] = { 0xa3000, 0x1000, 32 | 16 | 8 }, /* L4TAO12 */
- [115] = { 0xa4000, 0x1000, 32 }, /* SHA1MD5 */
- [116] = { 0xa5000, 0x1000, 32 | 16 | 8 }, /* L4TAO13 */
- [117] = { 0xa6000, 0x1000, 32 }, /* AES */
- [118] = { 0xa7000, 0x1000, 32 | 16 | 8 }, /* L4TA37 */
- [119] = { 0xa8000, 0x2000, 32 }, /* PKA */
- [120] = { 0xaa000, 0x1000, 32 | 16 | 8 }, /* L4TA38 */
- [121] = { 0xb0000, 0x1000, 32 }, /* MG */
- [122] = { 0xb1000, 0x1000, 32 | 16 | 8 },
- [123] = { 0xb2000, 0x1000, 32 }, /* HDQ/1-Wire */
- [124] = { 0xb3000, 0x1000, 32 | 16 | 8 }, /* L4TA39 */
-};
-
-static const struct omap_l4_agent_info_s omap_l4_agent_info[54] = {
- { 0, 0, 3, 2 }, /* L4IA initiatior agent */
- { L4TAO(1), 3, 2, 1 }, /* Control and pinout module */
- { L4TAO(2), 5, 2, 1 }, /* 32K timer */
- { L4TAO(3), 7, 3, 2 }, /* PRCM */
- { L4TA(1), 10, 2, 1 }, /* BCM */
- { L4TA(2), 12, 2, 1 }, /* Test JTAG */
- { L4TA(3), 14, 6, 3 }, /* Quad GPIO */
- { L4TA(4), 20, 4, 3 }, /* WD timer 1/2 */
- { L4TA(7), 24, 2, 1 }, /* GP timer 1 */
- { L4TA(9), 26, 2, 1 }, /* ATM11 ETB */
- { L4TA(10), 28, 5, 4 }, /* Display subsystem */
- { L4TA(11), 33, 5, 4 }, /* Camera subsystem */
- { L4TA(12), 38, 2, 1 }, /* sDMA */
- { L4TA(13), 40, 5, 4 }, /* SSI */
- { L4TAO(4), 45, 2, 1 }, /* USB */
- { L4TA(14), 47, 2, 1 }, /* Win Tracer1 */
- { L4TA(15), 49, 2, 1 }, /* Win Tracer2 */
- { L4TA(16), 51, 2, 1 }, /* Win Tracer3 */
- { L4TA(17), 53, 2, 1 }, /* Win Tracer4 */
- { L4TA(18), 55, 2, 1 }, /* XTI */
- { L4TA(19), 57, 2, 1 }, /* UART1 */
- { L4TA(20), 59, 2, 1 }, /* UART2 */
- { L4TA(21), 61, 2, 1 }, /* UART3 */
- { L4TAO(5), 63, 2, 1 }, /* I2C1 */
- { L4TAO(6), 65, 2, 1 }, /* I2C2 */
- { L4TAO(7), 67, 2, 1 }, /* McBSP1 */
- { L4TAO(8), 69, 2, 1 }, /* McBSP2 */
- { L4TA(5), 71, 2, 1 }, /* WD Timer 3 (DSP) */
- { L4TA(6), 73, 2, 1 }, /* WD Timer 4 (IVA) */
- { L4TA(8), 75, 2, 1 }, /* GP Timer 2 */
- { L4TA(22), 77, 2, 1 }, /* GP Timer 3 */
- { L4TA(23), 79, 2, 1 }, /* GP Timer 4 */
- { L4TA(24), 81, 2, 1 }, /* GP Timer 5 */
- { L4TA(25), 83, 2, 1 }, /* GP Timer 6 */
- { L4TA(26), 85, 2, 1 }, /* GP Timer 7 */
- { L4TA(27), 87, 2, 1 }, /* GP Timer 8 */
- { L4TA(28), 89, 2, 1 }, /* GP Timer 9 */
- { L4TA(29), 91, 2, 1 }, /* GP Timer 10 */
- { L4TA(30), 93, 2, 1 }, /* GP Timer 11 */
- { L4TA(31), 95, 2, 1 }, /* GP Timer 12 */
- { L4TA(32), 97, 2, 1 }, /* EAC */
- { L4TA(33), 99, 2, 1 }, /* FAC */
- { L4TA(34), 101, 2, 1 }, /* IPC */
- { L4TA(35), 103, 2, 1 }, /* SPI1 */
- { L4TA(36), 105, 2, 1 }, /* SPI2 */
- { L4TAO(9), 107, 2, 1 }, /* MMC SDIO */
- { L4TAO(10), 109, 2, 1 },
- { L4TAO(11), 111, 2, 1 }, /* RNG */
- { L4TAO(12), 113, 2, 1 }, /* DES3DES */
- { L4TAO(13), 115, 2, 1 }, /* SHA1MD5 */
- { L4TA(37), 117, 2, 1 }, /* AES */
- { L4TA(38), 119, 2, 1 }, /* PKA */
- { -1, 121, 2, 1 },
- { L4TA(39), 123, 2, 1 }, /* HDQ/1-Wire */
-};
-
-#define omap_l4ta(bus, cs) \
- omap_l4ta_get(bus, omap_l4_region, omap_l4_agent_info, L4TA(cs))
-#define omap_l4tao(bus, cs) \
- omap_l4ta_get(bus, omap_l4_region, omap_l4_agent_info, L4TAO(cs))
-
-/* Power, Reset, and Clock Management */
-struct omap_prcm_s {
- qemu_irq irq[3];
- struct omap_mpu_state_s *mpu;
- MemoryRegion iomem0;
- MemoryRegion iomem1;
-
- uint32_t irqst[3];
- uint32_t irqen[3];
-
- uint32_t sysconfig;
- uint32_t voltctrl;
- uint32_t scratch[20];
-
- uint32_t clksrc[1];
- uint32_t clkout[1];
- uint32_t clkemul[1];
- uint32_t clkpol[1];
- uint32_t clksel[8];
- uint32_t clken[12];
- uint32_t clkctrl[4];
- uint32_t clkidle[7];
- uint32_t setuptime[2];
-
- uint32_t wkup[3];
- uint32_t wken[3];
- uint32_t wkst[3];
- uint32_t rst[4];
- uint32_t rstctrl[1];
- uint32_t power[4];
- uint32_t rsttime_wkup;
-
- uint32_t ev;
- uint32_t evtime[2];
-
- int dpll_lock, apll_lock[2];
-};
-
-static void omap_prcm_int_update(struct omap_prcm_s *s, int dom)
-{
- qemu_set_irq(s->irq[dom], s->irqst[dom] & s->irqen[dom]);
- /* XXX or is the mask applied before PRCM_IRQSTATUS_* ? */
-}
-
-static uint64_t omap_prcm_read(void *opaque, hwaddr addr,
- unsigned size)
-{
- struct omap_prcm_s *s = (struct omap_prcm_s *) opaque;
- uint32_t ret;
-
- if (size != 4) {
- return omap_badwidth_read32(opaque, addr);
- }
-
- switch (addr) {
- case 0x000: /* PRCM_REVISION */
- return 0x10;
-
- case 0x010: /* PRCM_SYSCONFIG */
- return s->sysconfig;
-
- case 0x018: /* PRCM_IRQSTATUS_MPU */
- return s->irqst[0];
-
- case 0x01c: /* PRCM_IRQENABLE_MPU */
- return s->irqen[0];
-
- case 0x050: /* PRCM_VOLTCTRL */
- return s->voltctrl;
- case 0x054: /* PRCM_VOLTST */
- return s->voltctrl & 3;
-
- case 0x060: /* PRCM_CLKSRC_CTRL */
- return s->clksrc[0];
- case 0x070: /* PRCM_CLKOUT_CTRL */
- return s->clkout[0];
- case 0x078: /* PRCM_CLKEMUL_CTRL */
- return s->clkemul[0];
- case 0x080: /* PRCM_CLKCFG_CTRL */
- case 0x084: /* PRCM_CLKCFG_STATUS */
- return 0;
-
- case 0x090: /* PRCM_VOLTSETUP */
- return s->setuptime[0];
-
- case 0x094: /* PRCM_CLKSSETUP */
- return s->setuptime[1];
-
- case 0x098: /* PRCM_POLCTRL */
- return s->clkpol[0];
-
- case 0x0b0: /* GENERAL_PURPOSE1 */
- case 0x0b4: /* GENERAL_PURPOSE2 */
- case 0x0b8: /* GENERAL_PURPOSE3 */
- case 0x0bc: /* GENERAL_PURPOSE4 */
- case 0x0c0: /* GENERAL_PURPOSE5 */
- case 0x0c4: /* GENERAL_PURPOSE6 */
- case 0x0c8: /* GENERAL_PURPOSE7 */
- case 0x0cc: /* GENERAL_PURPOSE8 */
- case 0x0d0: /* GENERAL_PURPOSE9 */
- case 0x0d4: /* GENERAL_PURPOSE10 */
- case 0x0d8: /* GENERAL_PURPOSE11 */
- case 0x0dc: /* GENERAL_PURPOSE12 */
- case 0x0e0: /* GENERAL_PURPOSE13 */
- case 0x0e4: /* GENERAL_PURPOSE14 */
- case 0x0e8: /* GENERAL_PURPOSE15 */
- case 0x0ec: /* GENERAL_PURPOSE16 */
- case 0x0f0: /* GENERAL_PURPOSE17 */
- case 0x0f4: /* GENERAL_PURPOSE18 */
- case 0x0f8: /* GENERAL_PURPOSE19 */
- case 0x0fc: /* GENERAL_PURPOSE20 */
- return s->scratch[(addr - 0xb0) >> 2];
-
- case 0x140: /* CM_CLKSEL_MPU */
- return s->clksel[0];
- case 0x148: /* CM_CLKSTCTRL_MPU */
- return s->clkctrl[0];
-
- case 0x158: /* RM_RSTST_MPU */
- return s->rst[0];
- case 0x1c8: /* PM_WKDEP_MPU */
- return s->wkup[0];
- case 0x1d4: /* PM_EVGENCTRL_MPU */
- return s->ev;
- case 0x1d8: /* PM_EVEGENONTIM_MPU */
- return s->evtime[0];
- case 0x1dc: /* PM_EVEGENOFFTIM_MPU */
- return s->evtime[1];
- case 0x1e0: /* PM_PWSTCTRL_MPU */
- return s->power[0];
- case 0x1e4: /* PM_PWSTST_MPU */
- return 0;
-
- case 0x200: /* CM_FCLKEN1_CORE */
- return s->clken[0];
- case 0x204: /* CM_FCLKEN2_CORE */
- return s->clken[1];
- case 0x210: /* CM_ICLKEN1_CORE */
- return s->clken[2];
- case 0x214: /* CM_ICLKEN2_CORE */
- return s->clken[3];
- case 0x21c: /* CM_ICLKEN4_CORE */
- return s->clken[4];
-
- case 0x220: /* CM_IDLEST1_CORE */
- /* TODO: check the actual iclk status */
- return 0x7ffffff9;
- case 0x224: /* CM_IDLEST2_CORE */
- /* TODO: check the actual iclk status */
- return 0x00000007;
- case 0x22c: /* CM_IDLEST4_CORE */
- /* TODO: check the actual iclk status */
- return 0x0000001f;
-
- case 0x230: /* CM_AUTOIDLE1_CORE */
- return s->clkidle[0];
- case 0x234: /* CM_AUTOIDLE2_CORE */
- return s->clkidle[1];
- case 0x238: /* CM_AUTOIDLE3_CORE */
- return s->clkidle[2];
- case 0x23c: /* CM_AUTOIDLE4_CORE */
- return s->clkidle[3];
-
- case 0x240: /* CM_CLKSEL1_CORE */
- return s->clksel[1];
- case 0x244: /* CM_CLKSEL2_CORE */
- return s->clksel[2];
-
- case 0x248: /* CM_CLKSTCTRL_CORE */
- return s->clkctrl[1];
-
- case 0x2a0: /* PM_WKEN1_CORE */
- return s->wken[0];
- case 0x2a4: /* PM_WKEN2_CORE */
- return s->wken[1];
-
- case 0x2b0: /* PM_WKST1_CORE */
- return s->wkst[0];
- case 0x2b4: /* PM_WKST2_CORE */
- return s->wkst[1];
- case 0x2c8: /* PM_WKDEP_CORE */
- return 0x1e;
-
- case 0x2e0: /* PM_PWSTCTRL_CORE */
- return s->power[1];
- case 0x2e4: /* PM_PWSTST_CORE */
- return 0x000030 | (s->power[1] & 0xfc00);
-
- case 0x300: /* CM_FCLKEN_GFX */
- return s->clken[5];
- case 0x310: /* CM_ICLKEN_GFX */
- return s->clken[6];
- case 0x320: /* CM_IDLEST_GFX */
- /* TODO: check the actual iclk status */
- return 0x00000001;
- case 0x340: /* CM_CLKSEL_GFX */
- return s->clksel[3];
- case 0x348: /* CM_CLKSTCTRL_GFX */
- return s->clkctrl[2];
- case 0x350: /* RM_RSTCTRL_GFX */
- return s->rstctrl[0];
- case 0x358: /* RM_RSTST_GFX */
- return s->rst[1];
- case 0x3c8: /* PM_WKDEP_GFX */
- return s->wkup[1];
-
- case 0x3e0: /* PM_PWSTCTRL_GFX */
- return s->power[2];
- case 0x3e4: /* PM_PWSTST_GFX */
- return s->power[2] & 3;
-
- case 0x400: /* CM_FCLKEN_WKUP */
- return s->clken[7];
- case 0x410: /* CM_ICLKEN_WKUP */
- return s->clken[8];
- case 0x420: /* CM_IDLEST_WKUP */
- /* TODO: check the actual iclk status */
- return 0x0000003f;
- case 0x430: /* CM_AUTOIDLE_WKUP */
- return s->clkidle[4];
- case 0x440: /* CM_CLKSEL_WKUP */
- return s->clksel[4];
- case 0x450: /* RM_RSTCTRL_WKUP */
- return 0;
- case 0x454: /* RM_RSTTIME_WKUP */
- return s->rsttime_wkup;
- case 0x458: /* RM_RSTST_WKUP */
- return s->rst[2];
- case 0x4a0: /* PM_WKEN_WKUP */
- return s->wken[2];
- case 0x4b0: /* PM_WKST_WKUP */
- return s->wkst[2];
-
- case 0x500: /* CM_CLKEN_PLL */
- return s->clken[9];
- case 0x520: /* CM_IDLEST_CKGEN */
- ret = 0x0000070 | (s->apll_lock[0] << 9) | (s->apll_lock[1] << 8);
- if (!(s->clksel[6] & 3))
- /* Core uses 32-kHz clock */
- ret |= 3 << 0;
- else if (!s->dpll_lock)
- /* DPLL not locked, core uses ref_clk */
- ret |= 1 << 0;
- else
- /* Core uses DPLL */
- ret |= 2 << 0;
- return ret;
- case 0x530: /* CM_AUTOIDLE_PLL */
- return s->clkidle[5];
- case 0x540: /* CM_CLKSEL1_PLL */
- return s->clksel[5];
- case 0x544: /* CM_CLKSEL2_PLL */
- return s->clksel[6];
-
- case 0x800: /* CM_FCLKEN_DSP */
- return s->clken[10];
- case 0x810: /* CM_ICLKEN_DSP */
- return s->clken[11];
- case 0x820: /* CM_IDLEST_DSP */
- /* TODO: check the actual iclk status */
- return 0x00000103;
- case 0x830: /* CM_AUTOIDLE_DSP */
- return s->clkidle[6];
- case 0x840: /* CM_CLKSEL_DSP */
- return s->clksel[7];
- case 0x848: /* CM_CLKSTCTRL_DSP */
- return s->clkctrl[3];
- case 0x850: /* RM_RSTCTRL_DSP */
- return 0;
- case 0x858: /* RM_RSTST_DSP */
- return s->rst[3];
- case 0x8c8: /* PM_WKDEP_DSP */
- return s->wkup[2];
- case 0x8e0: /* PM_PWSTCTRL_DSP */
- return s->power[3];
- case 0x8e4: /* PM_PWSTST_DSP */
- return 0x008030 | (s->power[3] & 0x3003);
-
- case 0x8f0: /* PRCM_IRQSTATUS_DSP */
- return s->irqst[1];
- case 0x8f4: /* PRCM_IRQENABLE_DSP */
- return s->irqen[1];
-
- case 0x8f8: /* PRCM_IRQSTATUS_IVA */
- return s->irqst[2];
- case 0x8fc: /* PRCM_IRQENABLE_IVA */
- return s->irqen[2];
- }
-
- OMAP_BAD_REG(addr);
- return 0;
-}
-
-static void omap_prcm_apll_update(struct omap_prcm_s *s)
-{
- int mode[2];
-
- mode[0] = (s->clken[9] >> 6) & 3;
- s->apll_lock[0] = (mode[0] == 3);
- mode[1] = (s->clken[9] >> 2) & 3;
- s->apll_lock[1] = (mode[1] == 3);
- /* TODO: update clocks */
-
- if (mode[0] == 1 || mode[0] == 2 || mode[1] == 1 || mode[1] == 2)
- fprintf(stderr, "%s: bad EN_54M_PLL or bad EN_96M_PLL\n",
- __FUNCTION__);
-}
-
-static void omap_prcm_dpll_update(struct omap_prcm_s *s)
-{
- omap_clk dpll = omap_findclk(s->mpu, "dpll");
- omap_clk dpll_x2 = omap_findclk(s->mpu, "dpll");
- omap_clk core = omap_findclk(s->mpu, "core_clk");
- int mode = (s->clken[9] >> 0) & 3;
- int mult, div;
-
- mult = (s->clksel[5] >> 12) & 0x3ff;
- div = (s->clksel[5] >> 8) & 0xf;
- if (mult == 0 || mult == 1)
- mode = 1; /* Bypass */
-
- s->dpll_lock = 0;
- switch (mode) {
- case 0:
- fprintf(stderr, "%s: bad EN_DPLL\n", __FUNCTION__);
- break;
- case 1: /* Low-power bypass mode (Default) */
- case 2: /* Fast-relock bypass mode */
- omap_clk_setrate(dpll, 1, 1);
- omap_clk_setrate(dpll_x2, 1, 1);
- break;
- case 3: /* Lock mode */
- s->dpll_lock = 1; /* After 20 FINT cycles (ref_clk / (div + 1)). */
-
- omap_clk_setrate(dpll, div + 1, mult);
- omap_clk_setrate(dpll_x2, div + 1, mult * 2);
- break;
- }
-
- switch ((s->clksel[6] >> 0) & 3) {
- case 0:
- omap_clk_reparent(core, omap_findclk(s->mpu, "clk32-kHz"));
- break;
- case 1:
- omap_clk_reparent(core, dpll);
- break;
- case 2:
- /* Default */
- omap_clk_reparent(core, dpll_x2);
- break;
- case 3:
- fprintf(stderr, "%s: bad CORE_CLK_SRC\n", __FUNCTION__);
- break;
- }
-}
-
-static void omap_prcm_write(void *opaque, hwaddr addr,
- uint64_t value, unsigned size)
-{
- struct omap_prcm_s *s = (struct omap_prcm_s *) opaque;
-
- if (size != 4) {
- omap_badwidth_write32(opaque, addr, value);
- return;
- }
-
- switch (addr) {
- case 0x000: /* PRCM_REVISION */
- case 0x054: /* PRCM_VOLTST */
- case 0x084: /* PRCM_CLKCFG_STATUS */
- case 0x1e4: /* PM_PWSTST_MPU */
- case 0x220: /* CM_IDLEST1_CORE */
- case 0x224: /* CM_IDLEST2_CORE */
- case 0x22c: /* CM_IDLEST4_CORE */
- case 0x2c8: /* PM_WKDEP_CORE */
- case 0x2e4: /* PM_PWSTST_CORE */
- case 0x320: /* CM_IDLEST_GFX */
- case 0x3e4: /* PM_PWSTST_GFX */
- case 0x420: /* CM_IDLEST_WKUP */
- case 0x520: /* CM_IDLEST_CKGEN */
- case 0x820: /* CM_IDLEST_DSP */
- case 0x8e4: /* PM_PWSTST_DSP */
- OMAP_RO_REG(addr);
- return;
-
- case 0x010: /* PRCM_SYSCONFIG */
- s->sysconfig = value & 1;
- break;
-
- case 0x018: /* PRCM_IRQSTATUS_MPU */
- s->irqst[0] &= ~value;
- omap_prcm_int_update(s, 0);
- break;
- case 0x01c: /* PRCM_IRQENABLE_MPU */
- s->irqen[0] = value & 0x3f;
- omap_prcm_int_update(s, 0);
- break;
-
- case 0x050: /* PRCM_VOLTCTRL */
- s->voltctrl = value & 0xf1c3;
- break;
-
- case 0x060: /* PRCM_CLKSRC_CTRL */
- s->clksrc[0] = value & 0xdb;
- /* TODO update clocks */
- break;
-
- case 0x070: /* PRCM_CLKOUT_CTRL */
- s->clkout[0] = value & 0xbbbb;
- /* TODO update clocks */
- break;
-
- case 0x078: /* PRCM_CLKEMUL_CTRL */
- s->clkemul[0] = value & 1;
- /* TODO update clocks */
- break;
-
- case 0x080: /* PRCM_CLKCFG_CTRL */
- break;
-
- case 0x090: /* PRCM_VOLTSETUP */
- s->setuptime[0] = value & 0xffff;
- break;
- case 0x094: /* PRCM_CLKSSETUP */
- s->setuptime[1] = value & 0xffff;
- break;
-
- case 0x098: /* PRCM_POLCTRL */
- s->clkpol[0] = value & 0x701;
- break;
-
- case 0x0b0: /* GENERAL_PURPOSE1 */
- case 0x0b4: /* GENERAL_PURPOSE2 */
- case 0x0b8: /* GENERAL_PURPOSE3 */
- case 0x0bc: /* GENERAL_PURPOSE4 */
- case 0x0c0: /* GENERAL_PURPOSE5 */
- case 0x0c4: /* GENERAL_PURPOSE6 */
- case 0x0c8: /* GENERAL_PURPOSE7 */
- case 0x0cc: /* GENERAL_PURPOSE8 */
- case 0x0d0: /* GENERAL_PURPOSE9 */
- case 0x0d4: /* GENERAL_PURPOSE10 */
- case 0x0d8: /* GENERAL_PURPOSE11 */
- case 0x0dc: /* GENERAL_PURPOSE12 */
- case 0x0e0: /* GENERAL_PURPOSE13 */
- case 0x0e4: /* GENERAL_PURPOSE14 */
- case 0x0e8: /* GENERAL_PURPOSE15 */
- case 0x0ec: /* GENERAL_PURPOSE16 */
- case 0x0f0: /* GENERAL_PURPOSE17 */
- case 0x0f4: /* GENERAL_PURPOSE18 */
- case 0x0f8: /* GENERAL_PURPOSE19 */
- case 0x0fc: /* GENERAL_PURPOSE20 */
- s->scratch[(addr - 0xb0) >> 2] = value;
- break;
-
- case 0x140: /* CM_CLKSEL_MPU */
- s->clksel[0] = value & 0x1f;
- /* TODO update clocks */
- break;
- case 0x148: /* CM_CLKSTCTRL_MPU */
- s->clkctrl[0] = value & 0x1f;
- break;
-
- case 0x158: /* RM_RSTST_MPU */
- s->rst[0] &= ~value;
- break;
- case 0x1c8: /* PM_WKDEP_MPU */
- s->wkup[0] = value & 0x15;
- break;
-
- case 0x1d4: /* PM_EVGENCTRL_MPU */
- s->ev = value & 0x1f;
- break;
- case 0x1d8: /* PM_EVEGENONTIM_MPU */
- s->evtime[0] = value;
- break;
- case 0x1dc: /* PM_EVEGENOFFTIM_MPU */
- s->evtime[1] = value;
- break;
-
- case 0x1e0: /* PM_PWSTCTRL_MPU */
- s->power[0] = value & 0xc0f;
- break;
-
- case 0x200: /* CM_FCLKEN1_CORE */
- s->clken[0] = value & 0xbfffffff;
- /* TODO update clocks */
- /* The EN_EAC bit only gets/puts func_96m_clk. */
- break;
- case 0x204: /* CM_FCLKEN2_CORE */
- s->clken[1] = value & 0x00000007;
- /* TODO update clocks */
- break;
- case 0x210: /* CM_ICLKEN1_CORE */
- s->clken[2] = value & 0xfffffff9;
- /* TODO update clocks */
- /* The EN_EAC bit only gets/puts core_l4_iclk. */
- break;
- case 0x214: /* CM_ICLKEN2_CORE */
- s->clken[3] = value & 0x00000007;
- /* TODO update clocks */
- break;
- case 0x21c: /* CM_ICLKEN4_CORE */
- s->clken[4] = value & 0x0000001f;
- /* TODO update clocks */
- break;
-
- case 0x230: /* CM_AUTOIDLE1_CORE */
- s->clkidle[0] = value & 0xfffffff9;
- /* TODO update clocks */
- break;
- case 0x234: /* CM_AUTOIDLE2_CORE */
- s->clkidle[1] = value & 0x00000007;
- /* TODO update clocks */
- break;
- case 0x238: /* CM_AUTOIDLE3_CORE */
- s->clkidle[2] = value & 0x00000007;
- /* TODO update clocks */
- break;
- case 0x23c: /* CM_AUTOIDLE4_CORE */
- s->clkidle[3] = value & 0x0000001f;
- /* TODO update clocks */
- break;
-
- case 0x240: /* CM_CLKSEL1_CORE */
- s->clksel[1] = value & 0x0fffbf7f;
- /* TODO update clocks */
- break;
-
- case 0x244: /* CM_CLKSEL2_CORE */
- s->clksel[2] = value & 0x00fffffc;
- /* TODO update clocks */
- break;
-
- case 0x248: /* CM_CLKSTCTRL_CORE */
- s->clkctrl[1] = value & 0x7;
- break;
-
- case 0x2a0: /* PM_WKEN1_CORE */
- s->wken[0] = value & 0x04667ff8;
- break;
- case 0x2a4: /* PM_WKEN2_CORE */
- s->wken[1] = value & 0x00000005;
- break;
-
- case 0x2b0: /* PM_WKST1_CORE */
- s->wkst[0] &= ~value;
- break;
- case 0x2b4: /* PM_WKST2_CORE */
- s->wkst[1] &= ~value;
- break;
-
- case 0x2e0: /* PM_PWSTCTRL_CORE */
- s->power[1] = (value & 0x00fc3f) | (1 << 2);
- break;
-
- case 0x300: /* CM_FCLKEN_GFX */
- s->clken[5] = value & 6;
- /* TODO update clocks */
- break;
- case 0x310: /* CM_ICLKEN_GFX */
- s->clken[6] = value & 1;
- /* TODO update clocks */
- break;
- case 0x340: /* CM_CLKSEL_GFX */
- s->clksel[3] = value & 7;
- /* TODO update clocks */
- break;
- case 0x348: /* CM_CLKSTCTRL_GFX */
- s->clkctrl[2] = value & 1;
- break;
- case 0x350: /* RM_RSTCTRL_GFX */
- s->rstctrl[0] = value & 1;
- /* TODO: reset */
- break;
- case 0x358: /* RM_RSTST_GFX */
- s->rst[1] &= ~value;
- break;
- case 0x3c8: /* PM_WKDEP_GFX */
- s->wkup[1] = value & 0x13;
- break;
- case 0x3e0: /* PM_PWSTCTRL_GFX */
- s->power[2] = (value & 0x00c0f) | (3 << 2);
- break;
-
- case 0x400: /* CM_FCLKEN_WKUP */
- s->clken[7] = value & 0xd;
- /* TODO update clocks */
- break;
- case 0x410: /* CM_ICLKEN_WKUP */
- s->clken[8] = value & 0x3f;
- /* TODO update clocks */
- break;
- case 0x430: /* CM_AUTOIDLE_WKUP */
- s->clkidle[4] = value & 0x0000003f;
- /* TODO update clocks */
- break;
- case 0x440: /* CM_CLKSEL_WKUP */
- s->clksel[4] = value & 3;
- /* TODO update clocks */
- break;
- case 0x450: /* RM_RSTCTRL_WKUP */
- /* TODO: reset */
- if (value & 2)
- qemu_system_reset_request();
- break;
- case 0x454: /* RM_RSTTIME_WKUP */
- s->rsttime_wkup = value & 0x1fff;
- break;
- case 0x458: /* RM_RSTST_WKUP */
- s->rst[2] &= ~value;
- break;
- case 0x4a0: /* PM_WKEN_WKUP */
- s->wken[2] = value & 0x00000005;
- break;
- case 0x4b0: /* PM_WKST_WKUP */
- s->wkst[2] &= ~value;
- break;
-
- case 0x500: /* CM_CLKEN_PLL */
- if (value & 0xffffff30)
- fprintf(stderr, "%s: write 0s in CM_CLKEN_PLL for "
- "future compatibility\n", __FUNCTION__);
- if ((s->clken[9] ^ value) & 0xcc) {
- s->clken[9] &= ~0xcc;
- s->clken[9] |= value & 0xcc;
- omap_prcm_apll_update(s);
- }
- if ((s->clken[9] ^ value) & 3) {
- s->clken[9] &= ~3;
- s->clken[9] |= value & 3;
- omap_prcm_dpll_update(s);
- }
- break;
- case 0x530: /* CM_AUTOIDLE_PLL */
- s->clkidle[5] = value & 0x000000cf;
- /* TODO update clocks */
- break;
- case 0x540: /* CM_CLKSEL1_PLL */
- if (value & 0xfc4000d7)
- fprintf(stderr, "%s: write 0s in CM_CLKSEL1_PLL for "
- "future compatibility\n", __FUNCTION__);
- if ((s->clksel[5] ^ value) & 0x003fff00) {
- s->clksel[5] = value & 0x03bfff28;
- omap_prcm_dpll_update(s);
- }
- /* TODO update the other clocks */
-
- s->clksel[5] = value & 0x03bfff28;
- break;
- case 0x544: /* CM_CLKSEL2_PLL */
- if (value & ~3)
- fprintf(stderr, "%s: write 0s in CM_CLKSEL2_PLL[31:2] for "
- "future compatibility\n", __FUNCTION__);
- if (s->clksel[6] != (value & 3)) {
- s->clksel[6] = value & 3;
- omap_prcm_dpll_update(s);
- }
- break;
-
- case 0x800: /* CM_FCLKEN_DSP */
- s->clken[10] = value & 0x501;
- /* TODO update clocks */
- break;
- case 0x810: /* CM_ICLKEN_DSP */
- s->clken[11] = value & 0x2;
- /* TODO update clocks */
- break;
- case 0x830: /* CM_AUTOIDLE_DSP */
- s->clkidle[6] = value & 0x2;
- /* TODO update clocks */
- break;
- case 0x840: /* CM_CLKSEL_DSP */
- s->clksel[7] = value & 0x3fff;
- /* TODO update clocks */
- break;
- case 0x848: /* CM_CLKSTCTRL_DSP */
- s->clkctrl[3] = value & 0x101;
- break;
- case 0x850: /* RM_RSTCTRL_DSP */
- /* TODO: reset */
- break;
- case 0x858: /* RM_RSTST_DSP */
- s->rst[3] &= ~value;
- break;
- case 0x8c8: /* PM_WKDEP_DSP */
- s->wkup[2] = value & 0x13;
- break;
- case 0x8e0: /* PM_PWSTCTRL_DSP */
- s->power[3] = (value & 0x03017) | (3 << 2);
- break;
-
- case 0x8f0: /* PRCM_IRQSTATUS_DSP */
- s->irqst[1] &= ~value;
- omap_prcm_int_update(s, 1);
- break;
- case 0x8f4: /* PRCM_IRQENABLE_DSP */
- s->irqen[1] = value & 0x7;
- omap_prcm_int_update(s, 1);
- break;
-
- case 0x8f8: /* PRCM_IRQSTATUS_IVA */
- s->irqst[2] &= ~value;
- omap_prcm_int_update(s, 2);
- break;
- case 0x8fc: /* PRCM_IRQENABLE_IVA */
- s->irqen[2] = value & 0x7;
- omap_prcm_int_update(s, 2);
- break;
-
- default:
- OMAP_BAD_REG(addr);
- return;
- }
-}
-
-static const MemoryRegionOps omap_prcm_ops = {
- .read = omap_prcm_read,
- .write = omap_prcm_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static void omap_prcm_reset(struct omap_prcm_s *s)
-{
- s->sysconfig = 0;
- s->irqst[0] = 0;
- s->irqst[1] = 0;
- s->irqst[2] = 0;
- s->irqen[0] = 0;
- s->irqen[1] = 0;
- s->irqen[2] = 0;
- s->voltctrl = 0x1040;
- s->ev = 0x14;
- s->evtime[0] = 0;
- s->evtime[1] = 0;
- s->clkctrl[0] = 0;
- s->clkctrl[1] = 0;
- s->clkctrl[2] = 0;
- s->clkctrl[3] = 0;
- s->clken[1] = 7;
- s->clken[3] = 7;
- s->clken[4] = 0;
- s->clken[5] = 0;
- s->clken[6] = 0;
- s->clken[7] = 0xc;
- s->clken[8] = 0x3e;
- s->clken[9] = 0x0d;
- s->clken[10] = 0;
- s->clken[11] = 0;
- s->clkidle[0] = 0;
- s->clkidle[2] = 7;
- s->clkidle[3] = 0;
- s->clkidle[4] = 0;
- s->clkidle[5] = 0x0c;
- s->clkidle[6] = 0;
- s->clksel[0] = 0x01;
- s->clksel[1] = 0x02100121;
- s->clksel[2] = 0x00000000;
- s->clksel[3] = 0x01;
- s->clksel[4] = 0;
- s->clksel[7] = 0x0121;
- s->wkup[0] = 0x15;
- s->wkup[1] = 0x13;
- s->wkup[2] = 0x13;
- s->wken[0] = 0x04667ff8;
- s->wken[1] = 0x00000005;
- s->wken[2] = 5;
- s->wkst[0] = 0;
- s->wkst[1] = 0;
- s->wkst[2] = 0;
- s->power[0] = 0x00c;
- s->power[1] = 4;
- s->power[2] = 0x0000c;
- s->power[3] = 0x14;
- s->rstctrl[0] = 1;
- s->rst[3] = 1;
- omap_prcm_apll_update(s);
- omap_prcm_dpll_update(s);
-}
-
-static void omap_prcm_coldreset(struct omap_prcm_s *s)
-{
- s->setuptime[0] = 0;
- s->setuptime[1] = 0;
- memset(&s->scratch, 0, sizeof(s->scratch));
- s->rst[0] = 0x01;
- s->rst[1] = 0x00;
- s->rst[2] = 0x01;
- s->clken[0] = 0;
- s->clken[2] = 0;
- s->clkidle[1] = 0;
- s->clksel[5] = 0;
- s->clksel[6] = 2;
- s->clksrc[0] = 0x43;
- s->clkout[0] = 0x0303;
- s->clkemul[0] = 0;
- s->clkpol[0] = 0x100;
- s->rsttime_wkup = 0x1002;
-
- omap_prcm_reset(s);
-}
-
-static struct omap_prcm_s *omap_prcm_init(struct omap_target_agent_s *ta,
- qemu_irq mpu_int, qemu_irq dsp_int, qemu_irq iva_int,
- struct omap_mpu_state_s *mpu)
-{
- struct omap_prcm_s *s = g_new0(struct omap_prcm_s, 1);
-
- s->irq[0] = mpu_int;
- s->irq[1] = dsp_int;
- s->irq[2] = iva_int;
- s->mpu = mpu;
- omap_prcm_coldreset(s);
-
- memory_region_init_io(&s->iomem0, NULL, &omap_prcm_ops, s, "omap.pcrm0",
- omap_l4_region_size(ta, 0));
- memory_region_init_io(&s->iomem1, NULL, &omap_prcm_ops, s, "omap.pcrm1",
- omap_l4_region_size(ta, 1));
- omap_l4_attach(ta, 0, &s->iomem0);
- omap_l4_attach(ta, 1, &s->iomem1);
-
- return s;
-}
-
-/* System and Pinout control */
-struct omap_sysctl_s {
- struct omap_mpu_state_s *mpu;
- MemoryRegion iomem;
-
- uint32_t sysconfig;
- uint32_t devconfig;
- uint32_t psaconfig;
- uint32_t padconf[0x45];
- uint8_t obs;
- uint32_t msuspendmux[5];
-};
-
-static uint32_t omap_sysctl_read8(void *opaque, hwaddr addr)
-{
-
- struct omap_sysctl_s *s = (struct omap_sysctl_s *) opaque;
- int pad_offset, byte_offset;
- int value;
-
- switch (addr) {
- case 0x030 ... 0x140: /* CONTROL_PADCONF - only used in the POP */
- pad_offset = (addr - 0x30) >> 2;
- byte_offset = (addr - 0x30) & (4 - 1);
-
- value = s->padconf[pad_offset];
- value = (value >> (byte_offset * 8)) & 0xff;
-
- return value;
-
- default:
- break;
- }
-
- OMAP_BAD_REG(addr);
- return 0;
-}
-
-static uint32_t omap_sysctl_read(void *opaque, hwaddr addr)
-{
- struct omap_sysctl_s *s = (struct omap_sysctl_s *) opaque;
-
- switch (addr) {
- case 0x000: /* CONTROL_REVISION */
- return 0x20;
-
- case 0x010: /* CONTROL_SYSCONFIG */
- return s->sysconfig;
-
- case 0x030 ... 0x140: /* CONTROL_PADCONF - only used in the POP */
- return s->padconf[(addr - 0x30) >> 2];
-
- case 0x270: /* CONTROL_DEBOBS */
- return s->obs;
-
- case 0x274: /* CONTROL_DEVCONF */
- return s->devconfig;
-
- case 0x28c: /* CONTROL_EMU_SUPPORT */
- return 0;
-
- case 0x290: /* CONTROL_MSUSPENDMUX_0 */
- return s->msuspendmux[0];
- case 0x294: /* CONTROL_MSUSPENDMUX_1 */
- return s->msuspendmux[1];
- case 0x298: /* CONTROL_MSUSPENDMUX_2 */
- return s->msuspendmux[2];
- case 0x29c: /* CONTROL_MSUSPENDMUX_3 */
- return s->msuspendmux[3];
- case 0x2a0: /* CONTROL_MSUSPENDMUX_4 */
- return s->msuspendmux[4];
- case 0x2a4: /* CONTROL_MSUSPENDMUX_5 */
- return 0;
-
- case 0x2b8: /* CONTROL_PSA_CTRL */
- return s->psaconfig;
- case 0x2bc: /* CONTROL_PSA_CMD */
- case 0x2c0: /* CONTROL_PSA_VALUE */
- return 0;
-
- case 0x2b0: /* CONTROL_SEC_CTRL */
- return 0x800000f1;
- case 0x2d0: /* CONTROL_SEC_EMU */
- return 0x80000015;
- case 0x2d4: /* CONTROL_SEC_TAP */
- return 0x8000007f;
- case 0x2b4: /* CONTROL_SEC_TEST */
- case 0x2f0: /* CONTROL_SEC_STATUS */
- case 0x2f4: /* CONTROL_SEC_ERR_STATUS */
- /* Secure mode is not present on general-pusrpose device. Outside
- * secure mode these values cannot be read or written. */
- return 0;
-
- case 0x2d8: /* CONTROL_OCM_RAM_PERM */
- return 0xff;
- case 0x2dc: /* CONTROL_OCM_PUB_RAM_ADD */
- case 0x2e0: /* CONTROL_EXT_SEC_RAM_START_ADD */
- case 0x2e4: /* CONTROL_EXT_SEC_RAM_STOP_ADD */
- /* No secure mode so no Extended Secure RAM present. */
- return 0;
-
- case 0x2f8: /* CONTROL_STATUS */
- /* Device Type => General-purpose */
- return 0x0300;
- case 0x2fc: /* CONTROL_GENERAL_PURPOSE_STATUS */
-
- case 0x300: /* CONTROL_RPUB_KEY_H_0 */
- case 0x304: /* CONTROL_RPUB_KEY_H_1 */
- case 0x308: /* CONTROL_RPUB_KEY_H_2 */
- case 0x30c: /* CONTROL_RPUB_KEY_H_3 */
- return 0xdecafbad;
-
- case 0x310: /* CONTROL_RAND_KEY_0 */
- case 0x314: /* CONTROL_RAND_KEY_1 */
- case 0x318: /* CONTROL_RAND_KEY_2 */
- case 0x31c: /* CONTROL_RAND_KEY_3 */
- case 0x320: /* CONTROL_CUST_KEY_0 */
- case 0x324: /* CONTROL_CUST_KEY_1 */
- case 0x330: /* CONTROL_TEST_KEY_0 */
- case 0x334: /* CONTROL_TEST_KEY_1 */
- case 0x338: /* CONTROL_TEST_KEY_2 */
- case 0x33c: /* CONTROL_TEST_KEY_3 */
- case 0x340: /* CONTROL_TEST_KEY_4 */
- case 0x344: /* CONTROL_TEST_KEY_5 */
- case 0x348: /* CONTROL_TEST_KEY_6 */
- case 0x34c: /* CONTROL_TEST_KEY_7 */
- case 0x350: /* CONTROL_TEST_KEY_8 */
- case 0x354: /* CONTROL_TEST_KEY_9 */
- /* Can only be accessed in secure mode and when C_FieldAccEnable
- * bit is set in CONTROL_SEC_CTRL.
- * TODO: otherwise an interconnect access error is generated. */
- return 0;
- }
-
- OMAP_BAD_REG(addr);
- return 0;
-}
-
-static void omap_sysctl_write8(void *opaque, hwaddr addr,
- uint32_t value)
-{
- struct omap_sysctl_s *s = (struct omap_sysctl_s *) opaque;
- int pad_offset, byte_offset;
- int prev_value;
-
- switch (addr) {
- case 0x030 ... 0x140: /* CONTROL_PADCONF - only used in the POP */
- pad_offset = (addr - 0x30) >> 2;
- byte_offset = (addr - 0x30) & (4 - 1);
-
- prev_value = s->padconf[pad_offset];
- prev_value &= ~(0xff << (byte_offset * 8));
- prev_value |= ((value & 0x1f1f1f1f) << (byte_offset * 8)) & 0x1f1f1f1f;
- s->padconf[pad_offset] = prev_value;
- break;
-
- default:
- OMAP_BAD_REG(addr);
- break;
- }
-}
-
-static void omap_sysctl_write(void *opaque, hwaddr addr,
- uint32_t value)
-{
- struct omap_sysctl_s *s = (struct omap_sysctl_s *) opaque;
-
- switch (addr) {
- case 0x000: /* CONTROL_REVISION */
- case 0x2a4: /* CONTROL_MSUSPENDMUX_5 */
- case 0x2c0: /* CONTROL_PSA_VALUE */
- case 0x2f8: /* CONTROL_STATUS */
- case 0x2fc: /* CONTROL_GENERAL_PURPOSE_STATUS */
- case 0x300: /* CONTROL_RPUB_KEY_H_0 */
- case 0x304: /* CONTROL_RPUB_KEY_H_1 */
- case 0x308: /* CONTROL_RPUB_KEY_H_2 */
- case 0x30c: /* CONTROL_RPUB_KEY_H_3 */
- case 0x310: /* CONTROL_RAND_KEY_0 */
- case 0x314: /* CONTROL_RAND_KEY_1 */
- case 0x318: /* CONTROL_RAND_KEY_2 */
- case 0x31c: /* CONTROL_RAND_KEY_3 */
- case 0x320: /* CONTROL_CUST_KEY_0 */
- case 0x324: /* CONTROL_CUST_KEY_1 */
- case 0x330: /* CONTROL_TEST_KEY_0 */
- case 0x334: /* CONTROL_TEST_KEY_1 */
- case 0x338: /* CONTROL_TEST_KEY_2 */
- case 0x33c: /* CONTROL_TEST_KEY_3 */
- case 0x340: /* CONTROL_TEST_KEY_4 */
- case 0x344: /* CONTROL_TEST_KEY_5 */
- case 0x348: /* CONTROL_TEST_KEY_6 */
- case 0x34c: /* CONTROL_TEST_KEY_7 */
- case 0x350: /* CONTROL_TEST_KEY_8 */
- case 0x354: /* CONTROL_TEST_KEY_9 */
- OMAP_RO_REG(addr);
- return;
-
- case 0x010: /* CONTROL_SYSCONFIG */
- s->sysconfig = value & 0x1e;
- break;
-
- case 0x030 ... 0x140: /* CONTROL_PADCONF - only used in the POP */
- /* XXX: should check constant bits */
- s->padconf[(addr - 0x30) >> 2] = value & 0x1f1f1f1f;
- break;
-
- case 0x270: /* CONTROL_DEBOBS */
- s->obs = value & 0xff;
- break;
-
- case 0x274: /* CONTROL_DEVCONF */
- s->devconfig = value & 0xffffc7ff;
- break;
-
- case 0x28c: /* CONTROL_EMU_SUPPORT */
- break;
-
- case 0x290: /* CONTROL_MSUSPENDMUX_0 */
- s->msuspendmux[0] = value & 0x3fffffff;
- break;
- case 0x294: /* CONTROL_MSUSPENDMUX_1 */
- s->msuspendmux[1] = value & 0x3fffffff;
- break;
- case 0x298: /* CONTROL_MSUSPENDMUX_2 */
- s->msuspendmux[2] = value & 0x3fffffff;
- break;
- case 0x29c: /* CONTROL_MSUSPENDMUX_3 */
- s->msuspendmux[3] = value & 0x3fffffff;
- break;
- case 0x2a0: /* CONTROL_MSUSPENDMUX_4 */
- s->msuspendmux[4] = value & 0x3fffffff;
- break;
-
- case 0x2b8: /* CONTROL_PSA_CTRL */
- s->psaconfig = value & 0x1c;
- s->psaconfig |= (value & 0x20) ? 2 : 1;
- break;
- case 0x2bc: /* CONTROL_PSA_CMD */
- break;
-
- case 0x2b0: /* CONTROL_SEC_CTRL */
- case 0x2b4: /* CONTROL_SEC_TEST */
- case 0x2d0: /* CONTROL_SEC_EMU */
- case 0x2d4: /* CONTROL_SEC_TAP */
- case 0x2d8: /* CONTROL_OCM_RAM_PERM */
- case 0x2dc: /* CONTROL_OCM_PUB_RAM_ADD */
- case 0x2e0: /* CONTROL_EXT_SEC_RAM_START_ADD */
- case 0x2e4: /* CONTROL_EXT_SEC_RAM_STOP_ADD */
- case 0x2f0: /* CONTROL_SEC_STATUS */
- case 0x2f4: /* CONTROL_SEC_ERR_STATUS */
- break;
-
- default:
- OMAP_BAD_REG(addr);
- return;
- }
-}
-
-static const MemoryRegionOps omap_sysctl_ops = {
- .old_mmio = {
- .read = {
- omap_sysctl_read8,
- omap_badwidth_read32, /* TODO */
- omap_sysctl_read,
- },
- .write = {
- omap_sysctl_write8,
- omap_badwidth_write32, /* TODO */
- omap_sysctl_write,
- },
- },
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static void omap_sysctl_reset(struct omap_sysctl_s *s)
-{
- /* (power-on reset) */
- s->sysconfig = 0;
- s->obs = 0;
- s->devconfig = 0x0c000000;
- s->msuspendmux[0] = 0x00000000;
- s->msuspendmux[1] = 0x00000000;
- s->msuspendmux[2] = 0x00000000;
- s->msuspendmux[3] = 0x00000000;
- s->msuspendmux[4] = 0x00000000;
- s->psaconfig = 1;
-
- s->padconf[0x00] = 0x000f0f0f;
- s->padconf[0x01] = 0x00000000;
- s->padconf[0x02] = 0x00000000;
- s->padconf[0x03] = 0x00000000;
- s->padconf[0x04] = 0x00000000;
- s->padconf[0x05] = 0x00000000;
- s->padconf[0x06] = 0x00000000;
- s->padconf[0x07] = 0x00000000;
- s->padconf[0x08] = 0x08080800;
- s->padconf[0x09] = 0x08080808;
- s->padconf[0x0a] = 0x08080808;
- s->padconf[0x0b] = 0x08080808;
- s->padconf[0x0c] = 0x08080808;
- s->padconf[0x0d] = 0x08080800;
- s->padconf[0x0e] = 0x08080808;
- s->padconf[0x0f] = 0x08080808;
- s->padconf[0x10] = 0x18181808; /* | 0x07070700 if SBoot3 */
- s->padconf[0x11] = 0x18181818; /* | 0x07070707 if SBoot3 */
- s->padconf[0x12] = 0x18181818; /* | 0x07070707 if SBoot3 */
- s->padconf[0x13] = 0x18181818; /* | 0x07070707 if SBoot3 */
- s->padconf[0x14] = 0x18181818; /* | 0x00070707 if SBoot3 */
- s->padconf[0x15] = 0x18181818;
- s->padconf[0x16] = 0x18181818; /* | 0x07000000 if SBoot3 */
- s->padconf[0x17] = 0x1f001f00;
- s->padconf[0x18] = 0x1f1f1f1f;
- s->padconf[0x19] = 0x00000000;
- s->padconf[0x1a] = 0x1f180000;
- s->padconf[0x1b] = 0x00001f1f;
- s->padconf[0x1c] = 0x1f001f00;
- s->padconf[0x1d] = 0x00000000;
- s->padconf[0x1e] = 0x00000000;
- s->padconf[0x1f] = 0x08000000;
- s->padconf[0x20] = 0x08080808;
- s->padconf[0x21] = 0x08080808;
- s->padconf[0x22] = 0x0f080808;
- s->padconf[0x23] = 0x0f0f0f0f;
- s->padconf[0x24] = 0x000f0f0f;
- s->padconf[0x25] = 0x1f1f1f0f;
- s->padconf[0x26] = 0x080f0f1f;
- s->padconf[0x27] = 0x070f1808;
- s->padconf[0x28] = 0x0f070707;
- s->padconf[0x29] = 0x000f0f1f;
- s->padconf[0x2a] = 0x0f0f0f1f;
- s->padconf[0x2b] = 0x08000000;
- s->padconf[0x2c] = 0x0000001f;
- s->padconf[0x2d] = 0x0f0f1f00;
- s->padconf[0x2e] = 0x1f1f0f0f;
- s->padconf[0x2f] = 0x0f1f1f1f;
- s->padconf[0x30] = 0x0f0f0f0f;
- s->padconf[0x31] = 0x0f1f0f1f;
- s->padconf[0x32] = 0x0f0f0f0f;
- s->padconf[0x33] = 0x0f1f0f1f;
- s->padconf[0x34] = 0x1f1f0f0f;
- s->padconf[0x35] = 0x0f0f1f1f;
- s->padconf[0x36] = 0x0f0f1f0f;
- s->padconf[0x37] = 0x0f0f0f0f;
- s->padconf[0x38] = 0x1f18180f;
- s->padconf[0x39] = 0x1f1f1f1f;
- s->padconf[0x3a] = 0x00001f1f;
- s->padconf[0x3b] = 0x00000000;
- s->padconf[0x3c] = 0x00000000;
- s->padconf[0x3d] = 0x0f0f0f0f;
- s->padconf[0x3e] = 0x18000f0f;
- s->padconf[0x3f] = 0x00070000;
- s->padconf[0x40] = 0x00000707;
- s->padconf[0x41] = 0x0f1f0700;
- s->padconf[0x42] = 0x1f1f070f;
- s->padconf[0x43] = 0x0008081f;
- s->padconf[0x44] = 0x00000800;
-}
-
-static struct omap_sysctl_s *omap_sysctl_init(struct omap_target_agent_s *ta,
- omap_clk iclk, struct omap_mpu_state_s *mpu)
-{
- struct omap_sysctl_s *s = g_new0(struct omap_sysctl_s, 1);
-
- s->mpu = mpu;
- omap_sysctl_reset(s);
-
- memory_region_init_io(&s->iomem, NULL, &omap_sysctl_ops, s, "omap.sysctl",
- omap_l4_region_size(ta, 0));
- omap_l4_attach(ta, 0, &s->iomem);
-
- return s;
-}
-
-/* General chip reset */
-static void omap2_mpu_reset(void *opaque)
-{
- struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
-
- omap_dma_reset(mpu->dma);
- omap_prcm_reset(mpu->prcm);
- omap_sysctl_reset(mpu->sysc);
- omap_gp_timer_reset(mpu->gptimer[0]);
- omap_gp_timer_reset(mpu->gptimer[1]);
- omap_gp_timer_reset(mpu->gptimer[2]);
- omap_gp_timer_reset(mpu->gptimer[3]);
- omap_gp_timer_reset(mpu->gptimer[4]);
- omap_gp_timer_reset(mpu->gptimer[5]);
- omap_gp_timer_reset(mpu->gptimer[6]);
- omap_gp_timer_reset(mpu->gptimer[7]);
- omap_gp_timer_reset(mpu->gptimer[8]);
- omap_gp_timer_reset(mpu->gptimer[9]);
- omap_gp_timer_reset(mpu->gptimer[10]);
- omap_gp_timer_reset(mpu->gptimer[11]);
- omap_synctimer_reset(mpu->synctimer);
- omap_sdrc_reset(mpu->sdrc);
- omap_gpmc_reset(mpu->gpmc);
- omap_dss_reset(mpu->dss);
- omap_uart_reset(mpu->uart[0]);
- omap_uart_reset(mpu->uart[1]);
- omap_uart_reset(mpu->uart[2]);
- omap_mmc_reset(mpu->mmc);
- omap_mcspi_reset(mpu->mcspi[0]);
- omap_mcspi_reset(mpu->mcspi[1]);
- cpu_reset(CPU(mpu->cpu));
-}
-
-static int omap2_validate_addr(struct omap_mpu_state_s *s,
- hwaddr addr)
-{
- return 1;
-}
-
-static const struct dma_irq_map omap2_dma_irq_map[] = {
- { 0, OMAP_INT_24XX_SDMA_IRQ0 },
- { 0, OMAP_INT_24XX_SDMA_IRQ1 },
- { 0, OMAP_INT_24XX_SDMA_IRQ2 },
- { 0, OMAP_INT_24XX_SDMA_IRQ3 },
-};
-
-struct omap_mpu_state_s *omap2420_mpu_init(MemoryRegion *sysmem,
- unsigned long sdram_size,
- const char *core)
-{
- struct omap_mpu_state_s *s = g_new0(struct omap_mpu_state_s, 1);
- qemu_irq dma_irqs[4];
- DriveInfo *dinfo;
- int i;
- SysBusDevice *busdev;
- struct omap_target_agent_s *ta;
-
- /* Core */
- s->mpu_model = omap2420;
- s->cpu = cpu_arm_init(core ?: "arm1136-r2");
- if (s->cpu == NULL) {
- fprintf(stderr, "Unable to find CPU definition\n");
- exit(1);
- }
- s->sdram_size = sdram_size;
- s->sram_size = OMAP242X_SRAM_SIZE;
-
- s->wakeup = qemu_allocate_irq(omap_mpu_wakeup, s, 0);
-
- /* Clocks */
- omap_clk_init(s);
-
- /* Memory-mapped stuff */
- memory_region_allocate_system_memory(&s->sdram, NULL, "omap2.dram",
- s->sdram_size);
- memory_region_add_subregion(sysmem, OMAP2_Q2_BASE, &s->sdram);
- memory_region_init_ram(&s->sram, NULL, "omap2.sram", s->sram_size,
- &error_fatal);
- vmstate_register_ram_global(&s->sram);
- memory_region_add_subregion(sysmem, OMAP2_SRAM_BASE, &s->sram);
-
- s->l4 = omap_l4_init(sysmem, OMAP2_L4_BASE, 54);
-
- /* Actually mapped at any 2K boundary in the ARM11 private-peripheral if */
- s->ih[0] = qdev_create(NULL, "omap2-intc");
- qdev_prop_set_uint8(s->ih[0], "revision", 0x21);
- qdev_prop_set_ptr(s->ih[0], "fclk", omap_findclk(s, "mpu_intc_fclk"));
- qdev_prop_set_ptr(s->ih[0], "iclk", omap_findclk(s, "mpu_intc_iclk"));
- qdev_init_nofail(s->ih[0]);
- busdev = SYS_BUS_DEVICE(s->ih[0]);
- sysbus_connect_irq(busdev, 0,
- qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_IRQ));
- sysbus_connect_irq(busdev, 1,
- qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_FIQ));
- sysbus_mmio_map(busdev, 0, 0x480fe000);
- s->prcm = omap_prcm_init(omap_l4tao(s->l4, 3),
- qdev_get_gpio_in(s->ih[0],
- OMAP_INT_24XX_PRCM_MPU_IRQ),
- NULL, NULL, s);
-
- s->sysc = omap_sysctl_init(omap_l4tao(s->l4, 1),
- omap_findclk(s, "omapctrl_iclk"), s);
-
- for (i = 0; i < 4; i++) {
- dma_irqs[i] = qdev_get_gpio_in(s->ih[omap2_dma_irq_map[i].ih],
- omap2_dma_irq_map[i].intr);
- }
- s->dma = omap_dma4_init(0x48056000, dma_irqs, sysmem, s, 256, 32,
- omap_findclk(s, "sdma_iclk"),
- omap_findclk(s, "sdma_fclk"));
- s->port->addr_valid = omap2_validate_addr;
-
- /* Register SDRAM and SRAM ports for fast DMA transfers. */
- soc_dma_port_add_mem(s->dma, memory_region_get_ram_ptr(&s->sdram),
- OMAP2_Q2_BASE, s->sdram_size);
- soc_dma_port_add_mem(s->dma, memory_region_get_ram_ptr(&s->sram),
- OMAP2_SRAM_BASE, s->sram_size);
-
- s->uart[0] = omap2_uart_init(sysmem, omap_l4ta(s->l4, 19),
- qdev_get_gpio_in(s->ih[0],
- OMAP_INT_24XX_UART1_IRQ),
- omap_findclk(s, "uart1_fclk"),
- omap_findclk(s, "uart1_iclk"),
- s->drq[OMAP24XX_DMA_UART1_TX],
- s->drq[OMAP24XX_DMA_UART1_RX],
- "uart1",
- serial_hds[0]);
- s->uart[1] = omap2_uart_init(sysmem, omap_l4ta(s->l4, 20),
- qdev_get_gpio_in(s->ih[0],
- OMAP_INT_24XX_UART2_IRQ),
- omap_findclk(s, "uart2_fclk"),
- omap_findclk(s, "uart2_iclk"),
- s->drq[OMAP24XX_DMA_UART2_TX],
- s->drq[OMAP24XX_DMA_UART2_RX],
- "uart2",
- serial_hds[0] ? serial_hds[1] : NULL);
- s->uart[2] = omap2_uart_init(sysmem, omap_l4ta(s->l4, 21),
- qdev_get_gpio_in(s->ih[0],
- OMAP_INT_24XX_UART3_IRQ),
- omap_findclk(s, "uart3_fclk"),
- omap_findclk(s, "uart3_iclk"),
- s->drq[OMAP24XX_DMA_UART3_TX],
- s->drq[OMAP24XX_DMA_UART3_RX],
- "uart3",
- serial_hds[0] && serial_hds[1] ? serial_hds[2] : NULL);
-
- s->gptimer[0] = omap_gp_timer_init(omap_l4ta(s->l4, 7),
- qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPTIMER1),
- omap_findclk(s, "wu_gpt1_clk"),
- omap_findclk(s, "wu_l4_iclk"));
- s->gptimer[1] = omap_gp_timer_init(omap_l4ta(s->l4, 8),
- qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPTIMER2),
- omap_findclk(s, "core_gpt2_clk"),
- omap_findclk(s, "core_l4_iclk"));
- s->gptimer[2] = omap_gp_timer_init(omap_l4ta(s->l4, 22),
- qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPTIMER3),
- omap_findclk(s, "core_gpt3_clk"),
- omap_findclk(s, "core_l4_iclk"));
- s->gptimer[3] = omap_gp_timer_init(omap_l4ta(s->l4, 23),
- qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPTIMER4),
- omap_findclk(s, "core_gpt4_clk"),
- omap_findclk(s, "core_l4_iclk"));
- s->gptimer[4] = omap_gp_timer_init(omap_l4ta(s->l4, 24),
- qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPTIMER5),
- omap_findclk(s, "core_gpt5_clk"),
- omap_findclk(s, "core_l4_iclk"));
- s->gptimer[5] = omap_gp_timer_init(omap_l4ta(s->l4, 25),
- qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPTIMER6),
- omap_findclk(s, "core_gpt6_clk"),
- omap_findclk(s, "core_l4_iclk"));
- s->gptimer[6] = omap_gp_timer_init(omap_l4ta(s->l4, 26),
- qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPTIMER7),
- omap_findclk(s, "core_gpt7_clk"),
- omap_findclk(s, "core_l4_iclk"));
- s->gptimer[7] = omap_gp_timer_init(omap_l4ta(s->l4, 27),
- qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPTIMER8),
- omap_findclk(s, "core_gpt8_clk"),
- omap_findclk(s, "core_l4_iclk"));
- s->gptimer[8] = omap_gp_timer_init(omap_l4ta(s->l4, 28),
- qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPTIMER9),
- omap_findclk(s, "core_gpt9_clk"),
- omap_findclk(s, "core_l4_iclk"));
- s->gptimer[9] = omap_gp_timer_init(omap_l4ta(s->l4, 29),
- qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPTIMER10),
- omap_findclk(s, "core_gpt10_clk"),
- omap_findclk(s, "core_l4_iclk"));
- s->gptimer[10] = omap_gp_timer_init(omap_l4ta(s->l4, 30),
- qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPTIMER11),
- omap_findclk(s, "core_gpt11_clk"),
- omap_findclk(s, "core_l4_iclk"));
- s->gptimer[11] = omap_gp_timer_init(omap_l4ta(s->l4, 31),
- qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPTIMER12),
- omap_findclk(s, "core_gpt12_clk"),
- omap_findclk(s, "core_l4_iclk"));
-
- omap_tap_init(omap_l4ta(s->l4, 2), s);
-
- s->synctimer = omap_synctimer_init(omap_l4tao(s->l4, 2), s,
- omap_findclk(s, "clk32-kHz"),
- omap_findclk(s, "core_l4_iclk"));
-
- s->i2c[0] = qdev_create(NULL, "omap_i2c");
- qdev_prop_set_uint8(s->i2c[0], "revision", 0x34);
- qdev_prop_set_ptr(s->i2c[0], "iclk", omap_findclk(s, "i2c1.iclk"));
- qdev_prop_set_ptr(s->i2c[0], "fclk", omap_findclk(s, "i2c1.fclk"));
- qdev_init_nofail(s->i2c[0]);
- busdev = SYS_BUS_DEVICE(s->i2c[0]);
- sysbus_connect_irq(busdev, 0,
- qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_I2C1_IRQ));
- sysbus_connect_irq(busdev, 1, s->drq[OMAP24XX_DMA_I2C1_TX]);
- sysbus_connect_irq(busdev, 2, s->drq[OMAP24XX_DMA_I2C1_RX]);
- sysbus_mmio_map(busdev, 0, omap_l4_region_base(omap_l4tao(s->l4, 5), 0));
-
- s->i2c[1] = qdev_create(NULL, "omap_i2c");
- qdev_prop_set_uint8(s->i2c[1], "revision", 0x34);
- qdev_prop_set_ptr(s->i2c[1], "iclk", omap_findclk(s, "i2c2.iclk"));
- qdev_prop_set_ptr(s->i2c[1], "fclk", omap_findclk(s, "i2c2.fclk"));
- qdev_init_nofail(s->i2c[1]);
- busdev = SYS_BUS_DEVICE(s->i2c[1]);
- sysbus_connect_irq(busdev, 0,
- qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_I2C2_IRQ));
- sysbus_connect_irq(busdev, 1, s->drq[OMAP24XX_DMA_I2C2_TX]);
- sysbus_connect_irq(busdev, 2, s->drq[OMAP24XX_DMA_I2C2_RX]);
- sysbus_mmio_map(busdev, 0, omap_l4_region_base(omap_l4tao(s->l4, 6), 0));
-
- s->gpio = qdev_create(NULL, "omap2-gpio");
- qdev_prop_set_int32(s->gpio, "mpu_model", s->mpu_model);
- qdev_prop_set_ptr(s->gpio, "iclk", omap_findclk(s, "gpio_iclk"));
- qdev_prop_set_ptr(s->gpio, "fclk0", omap_findclk(s, "gpio1_dbclk"));
- qdev_prop_set_ptr(s->gpio, "fclk1", omap_findclk(s, "gpio2_dbclk"));
- qdev_prop_set_ptr(s->gpio, "fclk2", omap_findclk(s, "gpio3_dbclk"));
- qdev_prop_set_ptr(s->gpio, "fclk3", omap_findclk(s, "gpio4_dbclk"));
- if (s->mpu_model == omap2430) {
- qdev_prop_set_ptr(s->gpio, "fclk4", omap_findclk(s, "gpio5_dbclk"));
- }
- qdev_init_nofail(s->gpio);
- busdev = SYS_BUS_DEVICE(s->gpio);
- sysbus_connect_irq(busdev, 0,
- qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPIO_BANK1));
- sysbus_connect_irq(busdev, 3,
- qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPIO_BANK2));
- sysbus_connect_irq(busdev, 6,
- qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPIO_BANK3));
- sysbus_connect_irq(busdev, 9,
- qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPIO_BANK4));
- if (s->mpu_model == omap2430) {
- sysbus_connect_irq(busdev, 12,
- qdev_get_gpio_in(s->ih[0],
- OMAP_INT_243X_GPIO_BANK5));
- }
- ta = omap_l4ta(s->l4, 3);
- sysbus_mmio_map(busdev, 0, omap_l4_region_base(ta, 1));
- sysbus_mmio_map(busdev, 1, omap_l4_region_base(ta, 0));
- sysbus_mmio_map(busdev, 2, omap_l4_region_base(ta, 2));
- sysbus_mmio_map(busdev, 3, omap_l4_region_base(ta, 4));
- sysbus_mmio_map(busdev, 4, omap_l4_region_base(ta, 5));
-
- s->sdrc = omap_sdrc_init(sysmem, 0x68009000);
- s->gpmc = omap_gpmc_init(s, 0x6800a000,
- qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_GPMC_IRQ),
- s->drq[OMAP24XX_DMA_GPMC]);
-
- dinfo = drive_get(IF_SD, 0, 0);
- if (!dinfo) {
- fprintf(stderr, "qemu: missing SecureDigital device\n");
- exit(1);
- }
- s->mmc = omap2_mmc_init(omap_l4tao(s->l4, 9),
- blk_by_legacy_dinfo(dinfo),
- qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_MMC_IRQ),
- &s->drq[OMAP24XX_DMA_MMC1_TX],
- omap_findclk(s, "mmc_fclk"), omap_findclk(s, "mmc_iclk"));
-
- s->mcspi[0] = omap_mcspi_init(omap_l4ta(s->l4, 35), 4,
- qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_MCSPI1_IRQ),
- &s->drq[OMAP24XX_DMA_SPI1_TX0],
- omap_findclk(s, "spi1_fclk"),
- omap_findclk(s, "spi1_iclk"));
- s->mcspi[1] = omap_mcspi_init(omap_l4ta(s->l4, 36), 2,
- qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_MCSPI2_IRQ),
- &s->drq[OMAP24XX_DMA_SPI2_TX0],
- omap_findclk(s, "spi2_fclk"),
- omap_findclk(s, "spi2_iclk"));
-
- s->dss = omap_dss_init(omap_l4ta(s->l4, 10), sysmem, 0x68000800,
- /* XXX wire M_IRQ_25, D_L2_IRQ_30 and I_IRQ_13 together */
- qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_DSS_IRQ),
- s->drq[OMAP24XX_DMA_DSS],
- omap_findclk(s, "dss_clk1"), omap_findclk(s, "dss_clk2"),
- omap_findclk(s, "dss_54m_clk"),
- omap_findclk(s, "dss_l3_iclk"),
- omap_findclk(s, "dss_l4_iclk"));
-
- omap_sti_init(omap_l4ta(s->l4, 18), sysmem, 0x54000000,
- qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_STI),
- omap_findclk(s, "emul_ck"),
- serial_hds[0] && serial_hds[1] && serial_hds[2] ?
- serial_hds[3] : NULL);
-
- s->eac = omap_eac_init(omap_l4ta(s->l4, 32),
- qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_EAC_IRQ),
- /* Ten consecutive lines */
- &s->drq[OMAP24XX_DMA_EAC_AC_RD],
- omap_findclk(s, "func_96m_clk"),
- omap_findclk(s, "core_l4_iclk"));
-
- /* All register mappings (includin those not currenlty implemented):
- * SystemControlMod 48000000 - 48000fff
- * SystemControlL4 48001000 - 48001fff
- * 32kHz Timer Mod 48004000 - 48004fff
- * 32kHz Timer L4 48005000 - 48005fff
- * PRCM ModA 48008000 - 480087ff
- * PRCM ModB 48008800 - 48008fff
- * PRCM L4 48009000 - 48009fff
- * TEST-BCM Mod 48012000 - 48012fff
- * TEST-BCM L4 48013000 - 48013fff
- * TEST-TAP Mod 48014000 - 48014fff
- * TEST-TAP L4 48015000 - 48015fff
- * GPIO1 Mod 48018000 - 48018fff
- * GPIO Top 48019000 - 48019fff
- * GPIO2 Mod 4801a000 - 4801afff
- * GPIO L4 4801b000 - 4801bfff
- * GPIO3 Mod 4801c000 - 4801cfff
- * GPIO4 Mod 4801e000 - 4801efff
- * WDTIMER1 Mod 48020000 - 48010fff
- * WDTIMER Top 48021000 - 48011fff
- * WDTIMER2 Mod 48022000 - 48012fff
- * WDTIMER L4 48023000 - 48013fff
- * WDTIMER3 Mod 48024000 - 48014fff
- * WDTIMER3 L4 48025000 - 48015fff
- * WDTIMER4 Mod 48026000 - 48016fff
- * WDTIMER4 L4 48027000 - 48017fff
- * GPTIMER1 Mod 48028000 - 48018fff
- * GPTIMER1 L4 48029000 - 48019fff
- * GPTIMER2 Mod 4802a000 - 4801afff
- * GPTIMER2 L4 4802b000 - 4801bfff
- * L4-Config AP 48040000 - 480407ff
- * L4-Config IP 48040800 - 48040fff
- * L4-Config LA 48041000 - 48041fff
- * ARM11ETB Mod 48048000 - 48049fff
- * ARM11ETB L4 4804a000 - 4804afff
- * DISPLAY Top 48050000 - 480503ff
- * DISPLAY DISPC 48050400 - 480507ff
- * DISPLAY RFBI 48050800 - 48050bff
- * DISPLAY VENC 48050c00 - 48050fff
- * DISPLAY L4 48051000 - 48051fff
- * CAMERA Top 48052000 - 480523ff
- * CAMERA core 48052400 - 480527ff
- * CAMERA DMA 48052800 - 48052bff
- * CAMERA MMU 48052c00 - 48052fff
- * CAMERA L4 48053000 - 48053fff
- * SDMA Mod 48056000 - 48056fff
- * SDMA L4 48057000 - 48057fff
- * SSI Top 48058000 - 48058fff
- * SSI GDD 48059000 - 48059fff
- * SSI Port1 4805a000 - 4805afff
- * SSI Port2 4805b000 - 4805bfff
- * SSI L4 4805c000 - 4805cfff
- * USB Mod 4805e000 - 480fefff
- * USB L4 4805f000 - 480fffff
- * WIN_TRACER1 Mod 48060000 - 48060fff
- * WIN_TRACER1 L4 48061000 - 48061fff
- * WIN_TRACER2 Mod 48062000 - 48062fff
- * WIN_TRACER2 L4 48063000 - 48063fff
- * WIN_TRACER3 Mod 48064000 - 48064fff
- * WIN_TRACER3 L4 48065000 - 48065fff
- * WIN_TRACER4 Top 48066000 - 480660ff
- * WIN_TRACER4 ETT 48066100 - 480661ff
- * WIN_TRACER4 WT 48066200 - 480662ff
- * WIN_TRACER4 L4 48067000 - 48067fff
- * XTI Mod 48068000 - 48068fff
- * XTI L4 48069000 - 48069fff
- * UART1 Mod 4806a000 - 4806afff
- * UART1 L4 4806b000 - 4806bfff
- * UART2 Mod 4806c000 - 4806cfff
- * UART2 L4 4806d000 - 4806dfff
- * UART3 Mod 4806e000 - 4806efff
- * UART3 L4 4806f000 - 4806ffff
- * I2C1 Mod 48070000 - 48070fff
- * I2C1 L4 48071000 - 48071fff
- * I2C2 Mod 48072000 - 48072fff
- * I2C2 L4 48073000 - 48073fff
- * McBSP1 Mod 48074000 - 48074fff
- * McBSP1 L4 48075000 - 48075fff
- * McBSP2 Mod 48076000 - 48076fff
- * McBSP2 L4 48077000 - 48077fff
- * GPTIMER3 Mod 48078000 - 48078fff
- * GPTIMER3 L4 48079000 - 48079fff
- * GPTIMER4 Mod 4807a000 - 4807afff
- * GPTIMER4 L4 4807b000 - 4807bfff
- * GPTIMER5 Mod 4807c000 - 4807cfff
- * GPTIMER5 L4 4807d000 - 4807dfff
- * GPTIMER6 Mod 4807e000 - 4807efff
- * GPTIMER6 L4 4807f000 - 4807ffff
- * GPTIMER7 Mod 48080000 - 48080fff
- * GPTIMER7 L4 48081000 - 48081fff
- * GPTIMER8 Mod 48082000 - 48082fff
- * GPTIMER8 L4 48083000 - 48083fff
- * GPTIMER9 Mod 48084000 - 48084fff
- * GPTIMER9 L4 48085000 - 48085fff
- * GPTIMER10 Mod 48086000 - 48086fff
- * GPTIMER10 L4 48087000 - 48087fff
- * GPTIMER11 Mod 48088000 - 48088fff
- * GPTIMER11 L4 48089000 - 48089fff
- * GPTIMER12 Mod 4808a000 - 4808afff
- * GPTIMER12 L4 4808b000 - 4808bfff
- * EAC Mod 48090000 - 48090fff
- * EAC L4 48091000 - 48091fff
- * FAC Mod 48092000 - 48092fff
- * FAC L4 48093000 - 48093fff
- * MAILBOX Mod 48094000 - 48094fff
- * MAILBOX L4 48095000 - 48095fff
- * SPI1 Mod 48098000 - 48098fff
- * SPI1 L4 48099000 - 48099fff
- * SPI2 Mod 4809a000 - 4809afff
- * SPI2 L4 4809b000 - 4809bfff
- * MMC/SDIO Mod 4809c000 - 4809cfff
- * MMC/SDIO L4 4809d000 - 4809dfff
- * MS_PRO Mod 4809e000 - 4809efff
- * MS_PRO L4 4809f000 - 4809ffff
- * RNG Mod 480a0000 - 480a0fff
- * RNG L4 480a1000 - 480a1fff
- * DES3DES Mod 480a2000 - 480a2fff
- * DES3DES L4 480a3000 - 480a3fff
- * SHA1MD5 Mod 480a4000 - 480a4fff
- * SHA1MD5 L4 480a5000 - 480a5fff
- * AES Mod 480a6000 - 480a6fff
- * AES L4 480a7000 - 480a7fff
- * PKA Mod 480a8000 - 480a9fff
- * PKA L4 480aa000 - 480aafff
- * MG Mod 480b0000 - 480b0fff
- * MG L4 480b1000 - 480b1fff
- * HDQ/1-wire Mod 480b2000 - 480b2fff
- * HDQ/1-wire L4 480b3000 - 480b3fff
- * MPU interrupt 480fe000 - 480fefff
- * STI channel base 54000000 - 5400ffff
- * IVA RAM 5c000000 - 5c01ffff
- * IVA ROM 5c020000 - 5c027fff
- * IMG_BUF_A 5c040000 - 5c040fff
- * IMG_BUF_B 5c042000 - 5c042fff
- * VLCDS 5c048000 - 5c0487ff
- * IMX_COEF 5c049000 - 5c04afff
- * IMX_CMD 5c051000 - 5c051fff
- * VLCDQ 5c053000 - 5c0533ff
- * VLCDH 5c054000 - 5c054fff
- * SEQ_CMD 5c055000 - 5c055fff
- * IMX_REG 5c056000 - 5c0560ff
- * VLCD_REG 5c056100 - 5c0561ff
- * SEQ_REG 5c056200 - 5c0562ff
- * IMG_BUF_REG 5c056300 - 5c0563ff
- * SEQIRQ_REG 5c056400 - 5c0564ff
- * OCP_REG 5c060000 - 5c060fff
- * SYSC_REG 5c070000 - 5c070fff
- * MMU_REG 5d000000 - 5d000fff
- * sDMA R 68000400 - 680005ff
- * sDMA W 68000600 - 680007ff
- * Display Control 68000800 - 680009ff
- * DSP subsystem 68000a00 - 68000bff
- * MPU subsystem 68000c00 - 68000dff
- * IVA subsystem 68001000 - 680011ff
- * USB 68001200 - 680013ff
- * Camera 68001400 - 680015ff
- * VLYNQ (firewall) 68001800 - 68001bff
- * VLYNQ 68001e00 - 68001fff
- * SSI 68002000 - 680021ff
- * L4 68002400 - 680025ff
- * DSP (firewall) 68002800 - 68002bff
- * DSP subsystem 68002e00 - 68002fff
- * IVA (firewall) 68003000 - 680033ff
- * IVA 68003600 - 680037ff
- * GFX 68003a00 - 68003bff
- * CMDWR emulation 68003c00 - 68003dff
- * SMS 68004000 - 680041ff
- * OCM 68004200 - 680043ff
- * GPMC 68004400 - 680045ff
- * RAM (firewall) 68005000 - 680053ff
- * RAM (err login) 68005400 - 680057ff
- * ROM (firewall) 68005800 - 68005bff
- * ROM (err login) 68005c00 - 68005fff
- * GPMC (firewall) 68006000 - 680063ff
- * GPMC (err login) 68006400 - 680067ff
- * SMS (err login) 68006c00 - 68006fff
- * SMS registers 68008000 - 68008fff
- * SDRC registers 68009000 - 68009fff
- * GPMC registers 6800a000 6800afff
- */
-
- qemu_register_reset(omap2_mpu_reset, s);
-
- return s;
-}
diff --git a/qemu/hw/arm/omap_sx1.c b/qemu/hw/arm/omap_sx1.c
deleted file mode 100644
index 5d74026cb..000000000
--- a/qemu/hw/arm/omap_sx1.c
+++ /dev/null
@@ -1,256 +0,0 @@
-/* omap_sx1.c Support for the Siemens SX1 smartphone emulation.
- *
- * Copyright (C) 2008
- * Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
- * Copyright (C) 2007 Vladimir Ananiev <vovan888@gmail.com>
- *
- * based on PalmOne's (TM) PDAs support (palm.c)
- */
-
-/*
- * PalmOne's (TM) PDAs.
- *
- * Copyright (C) 2006-2007 Andrzej Zaborowski <balrog@zabor.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * 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/>.
- */
-#include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "hw/hw.h"
-#include "ui/console.h"
-#include "hw/arm/omap.h"
-#include "hw/boards.h"
-#include "hw/arm/arm.h"
-#include "hw/block/flash.h"
-#include "sysemu/block-backend.h"
-#include "sysemu/qtest.h"
-#include "exec/address-spaces.h"
-
-/*****************************************************************************/
-/* Siemens SX1 Cellphone V1 */
-/* - ARM OMAP310 processor
- * - SRAM 192 kB
- * - SDRAM 32 MB at 0x10000000
- * - Boot flash 16 MB at 0x00000000
- * - Application flash 8 MB at 0x04000000
- * - 3 serial ports
- * - 1 SecureDigital
- * - 1 LCD display
- * - 1 RTC
- */
-
-/*****************************************************************************/
-/* Siemens SX1 Cellphone V2 */
-/* - ARM OMAP310 processor
- * - SRAM 192 kB
- * - SDRAM 32 MB at 0x10000000
- * - Boot flash 32 MB at 0x00000000
- * - 3 serial ports
- * - 1 SecureDigital
- * - 1 LCD display
- * - 1 RTC
- */
-
-static uint64_t static_read(void *opaque, hwaddr offset,
- unsigned size)
-{
- uint32_t *val = (uint32_t *) opaque;
- uint32_t mask = (4 / size) - 1;
-
- return *val >> ((offset & mask) << 3);
-}
-
-static void static_write(void *opaque, hwaddr offset,
- uint64_t value, unsigned size)
-{
-#ifdef SPY
- printf("%s: value %" PRIx64 " %u bytes written at 0x%x\n",
- __func__, value, size, (int)offset);
-#endif
-}
-
-static const MemoryRegionOps static_ops = {
- .read = static_read,
- .write = static_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-#define sdram_size 0x02000000
-#define sector_size (128 * 1024)
-#define flash0_size (16 * 1024 * 1024)
-#define flash1_size ( 8 * 1024 * 1024)
-#define flash2_size (32 * 1024 * 1024)
-#define total_ram_v1 (sdram_size + flash0_size + flash1_size + OMAP15XX_SRAM_SIZE)
-#define total_ram_v2 (sdram_size + flash2_size + OMAP15XX_SRAM_SIZE)
-
-static struct arm_boot_info sx1_binfo = {
- .loader_start = OMAP_EMIFF_BASE,
- .ram_size = sdram_size,
- .board_id = 0x265,
-};
-
-static void sx1_init(MachineState *machine, const int version)
-{
- struct omap_mpu_state_s *mpu;
- MemoryRegion *address_space = get_system_memory();
- MemoryRegion *flash = g_new(MemoryRegion, 1);
- MemoryRegion *cs = g_new(MemoryRegion, 4);
- static uint32_t cs0val = 0x00213090;
- static uint32_t cs1val = 0x00215070;
- static uint32_t cs2val = 0x00001139;
- static uint32_t cs3val = 0x00001139;
- DriveInfo *dinfo;
- int fl_idx;
- uint32_t flash_size = flash0_size;
- int be;
-
- if (version == 2) {
- flash_size = flash2_size;
- }
-
- mpu = omap310_mpu_init(address_space, sx1_binfo.ram_size,
- machine->cpu_model);
-
- /* External Flash (EMIFS) */
- memory_region_init_ram(flash, NULL, "omap_sx1.flash0-0", flash_size,
- &error_fatal);
- vmstate_register_ram_global(flash);
- memory_region_set_readonly(flash, true);
- memory_region_add_subregion(address_space, OMAP_CS0_BASE, flash);
-
- memory_region_init_io(&cs[0], NULL, &static_ops, &cs0val,
- "sx1.cs0", OMAP_CS0_SIZE - flash_size);
- memory_region_add_subregion(address_space,
- OMAP_CS0_BASE + flash_size, &cs[0]);
-
-
- memory_region_init_io(&cs[2], NULL, &static_ops, &cs2val,
- "sx1.cs2", OMAP_CS2_SIZE);
- memory_region_add_subregion(address_space,
- OMAP_CS2_BASE, &cs[2]);
-
- memory_region_init_io(&cs[3], NULL, &static_ops, &cs3val,
- "sx1.cs3", OMAP_CS3_SIZE);
- memory_region_add_subregion(address_space,
- OMAP_CS2_BASE, &cs[3]);
-
- fl_idx = 0;
-#ifdef TARGET_WORDS_BIGENDIAN
- be = 1;
-#else
- be = 0;
-#endif
-
- if ((dinfo = drive_get(IF_PFLASH, 0, fl_idx)) != NULL) {
- if (!pflash_cfi01_register(OMAP_CS0_BASE, NULL,
- "omap_sx1.flash0-1", flash_size,
- blk_by_legacy_dinfo(dinfo),
- sector_size, flash_size / sector_size,
- 4, 0, 0, 0, 0, be)) {
- fprintf(stderr, "qemu: Error registering flash memory %d.\n",
- fl_idx);
- }
- fl_idx++;
- }
-
- if ((version == 1) &&
- (dinfo = drive_get(IF_PFLASH, 0, fl_idx)) != NULL) {
- MemoryRegion *flash_1 = g_new(MemoryRegion, 1);
- memory_region_init_ram(flash_1, NULL, "omap_sx1.flash1-0", flash1_size,
- &error_fatal);
- vmstate_register_ram_global(flash_1);
- memory_region_set_readonly(flash_1, true);
- memory_region_add_subregion(address_space, OMAP_CS1_BASE, flash_1);
-
- memory_region_init_io(&cs[1], NULL, &static_ops, &cs1val,
- "sx1.cs1", OMAP_CS1_SIZE - flash1_size);
- memory_region_add_subregion(address_space,
- OMAP_CS1_BASE + flash1_size, &cs[1]);
-
- if (!pflash_cfi01_register(OMAP_CS1_BASE, NULL,
- "omap_sx1.flash1-1", flash1_size,
- blk_by_legacy_dinfo(dinfo),
- sector_size, flash1_size / sector_size,
- 4, 0, 0, 0, 0, be)) {
- fprintf(stderr, "qemu: Error registering flash memory %d.\n",
- fl_idx);
- }
- fl_idx++;
- } else {
- memory_region_init_io(&cs[1], NULL, &static_ops, &cs1val,
- "sx1.cs1", OMAP_CS1_SIZE);
- memory_region_add_subregion(address_space,
- OMAP_CS1_BASE, &cs[1]);
- }
-
- if (!machine->kernel_filename && !fl_idx && !qtest_enabled()) {
- fprintf(stderr, "Kernel or Flash image must be specified\n");
- exit(1);
- }
-
- /* Load the kernel. */
- sx1_binfo.kernel_filename = machine->kernel_filename;
- sx1_binfo.kernel_cmdline = machine->kernel_cmdline;
- sx1_binfo.initrd_filename = machine->initrd_filename;
- arm_load_kernel(mpu->cpu, &sx1_binfo);
-
- /* TODO: fix next line */
- //~ qemu_console_resize(ds, 640, 480);
-}
-
-static void sx1_init_v1(MachineState *machine)
-{
- sx1_init(machine, 1);
-}
-
-static void sx1_init_v2(MachineState *machine)
-{
- sx1_init(machine, 2);
-}
-
-static void sx1_machine_v2_class_init(ObjectClass *oc, void *data)
-{
- MachineClass *mc = MACHINE_CLASS(oc);
-
- mc->desc = "Siemens SX1 (OMAP310) V2";
- mc->init = sx1_init_v2;
-}
-
-static const TypeInfo sx1_machine_v2_type = {
- .name = MACHINE_TYPE_NAME("sx1"),
- .parent = TYPE_MACHINE,
- .class_init = sx1_machine_v2_class_init,
-};
-
-static void sx1_machine_v1_class_init(ObjectClass *oc, void *data)
-{
- MachineClass *mc = MACHINE_CLASS(oc);
-
- mc->desc = "Siemens SX1 (OMAP310) V1";
- mc->init = sx1_init_v1;
-}
-
-static const TypeInfo sx1_machine_v1_type = {
- .name = MACHINE_TYPE_NAME("sx1-v1"),
- .parent = TYPE_MACHINE,
- .class_init = sx1_machine_v1_class_init,
-};
-
-static void sx1_machine_init(void)
-{
- type_register_static(&sx1_machine_v1_type);
- type_register_static(&sx1_machine_v2_type);
-}
-
-type_init(sx1_machine_init)
diff --git a/qemu/hw/arm/palm.c b/qemu/hw/arm/palm.c
deleted file mode 100644
index 7f460732e..000000000
--- a/qemu/hw/arm/palm.c
+++ /dev/null
@@ -1,280 +0,0 @@
-/*
- * PalmOne's (TM) PDAs.
- *
- * Copyright (C) 2006-2007 Andrzej Zaborowski <balrog@zabor.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 or
- * (at your option) version 3 of the License.
- *
- * 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/>.
- */
-#include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "hw/hw.h"
-#include "audio/audio.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/qtest.h"
-#include "ui/console.h"
-#include "hw/arm/omap.h"
-#include "hw/boards.h"
-#include "hw/arm/arm.h"
-#include "hw/devices.h"
-#include "hw/loader.h"
-#include "exec/address-spaces.h"
-
-static uint32_t static_readb(void *opaque, hwaddr offset)
-{
- uint32_t *val = (uint32_t *) opaque;
- return *val >> ((offset & 3) << 3);
-}
-
-static uint32_t static_readh(void *opaque, hwaddr offset)
-{
- uint32_t *val = (uint32_t *) opaque;
- return *val >> ((offset & 1) << 3);
-}
-
-static uint32_t static_readw(void *opaque, hwaddr offset)
-{
- uint32_t *val = (uint32_t *) opaque;
- return *val >> ((offset & 0) << 3);
-}
-
-static void static_write(void *opaque, hwaddr offset,
- uint32_t value)
-{
-#ifdef SPY
- printf("%s: value %08lx written at " PA_FMT "\n",
- __FUNCTION__, value, offset);
-#endif
-}
-
-static const MemoryRegionOps static_ops = {
- .old_mmio = {
- .read = { static_readb, static_readh, static_readw, },
- .write = { static_write, static_write, static_write, },
- },
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-/* Palm Tunsgten|E support */
-
-/* Shared GPIOs */
-#define PALMTE_USBDETECT_GPIO 0
-#define PALMTE_USB_OR_DC_GPIO 1
-#define PALMTE_TSC_GPIO 4
-#define PALMTE_PINTDAV_GPIO 6
-#define PALMTE_MMC_WP_GPIO 8
-#define PALMTE_MMC_POWER_GPIO 9
-#define PALMTE_HDQ_GPIO 11
-#define PALMTE_HEADPHONES_GPIO 14
-#define PALMTE_SPEAKER_GPIO 15
-/* MPU private GPIOs */
-#define PALMTE_DC_GPIO 2
-#define PALMTE_MMC_SWITCH_GPIO 4
-#define PALMTE_MMC1_GPIO 6
-#define PALMTE_MMC2_GPIO 7
-#define PALMTE_MMC3_GPIO 11
-
-static MouseTransformInfo palmte_pointercal = {
- .x = 320,
- .y = 320,
- .a = { -5909, 8, 22465308, 104, 7644, -1219972, 65536 },
-};
-
-static void palmte_microwire_setup(struct omap_mpu_state_s *cpu)
-{
- uWireSlave *tsc;
-
- tsc = tsc2102_init(qdev_get_gpio_in(cpu->gpio, PALMTE_PINTDAV_GPIO));
-
- omap_uwire_attach(cpu->microwire, tsc, 0);
- omap_mcbsp_i2s_attach(cpu->mcbsp1, tsc210x_codec(tsc));
-
- tsc210x_set_transform(tsc, &palmte_pointercal);
-}
-
-static struct {
- int row;
- int column;
-} palmte_keymap[0x80] = {
- [0 ... 0x7f] = { -1, -1 },
- [0x3b] = { 0, 0 }, /* F1 -> Calendar */
- [0x3c] = { 1, 0 }, /* F2 -> Contacts */
- [0x3d] = { 2, 0 }, /* F3 -> Tasks List */
- [0x3e] = { 3, 0 }, /* F4 -> Note Pad */
- [0x01] = { 4, 0 }, /* Esc -> Power */
- [0x4b] = { 0, 1 }, /* Left */
- [0x50] = { 1, 1 }, /* Down */
- [0x48] = { 2, 1 }, /* Up */
- [0x4d] = { 3, 1 }, /* Right */
- [0x4c] = { 4, 1 }, /* Centre */
- [0x39] = { 4, 1 }, /* Spc -> Centre */
-};
-
-static void palmte_button_event(void *opaque, int keycode)
-{
- struct omap_mpu_state_s *cpu = (struct omap_mpu_state_s *) opaque;
-
- if (palmte_keymap[keycode & 0x7f].row != -1)
- omap_mpuio_key(cpu->mpuio,
- palmte_keymap[keycode & 0x7f].row,
- palmte_keymap[keycode & 0x7f].column,
- !(keycode & 0x80));
-}
-
-static void palmte_onoff_gpios(void *opaque, int line, int level)
-{
- switch (line) {
- case 0:
- printf("%s: current to MMC/SD card %sabled.\n",
- __FUNCTION__, level ? "dis" : "en");
- break;
- case 1:
- printf("%s: internal speaker amplifier %s.\n",
- __FUNCTION__, level ? "down" : "on");
- break;
-
- /* These LCD & Audio output signals have not been identified yet. */
- case 2:
- case 3:
- case 4:
- printf("%s: LCD GPIO%i %s.\n",
- __FUNCTION__, line - 1, level ? "high" : "low");
- break;
- case 5:
- case 6:
- printf("%s: Audio GPIO%i %s.\n",
- __FUNCTION__, line - 4, level ? "high" : "low");
- break;
- }
-}
-
-static void palmte_gpio_setup(struct omap_mpu_state_s *cpu)
-{
- qemu_irq *misc_gpio;
-
- omap_mmc_handlers(cpu->mmc,
- qdev_get_gpio_in(cpu->gpio, PALMTE_MMC_WP_GPIO),
- qemu_irq_invert(omap_mpuio_in_get(cpu->mpuio)
- [PALMTE_MMC_SWITCH_GPIO]));
-
- misc_gpio = qemu_allocate_irqs(palmte_onoff_gpios, cpu, 7);
- qdev_connect_gpio_out(cpu->gpio, PALMTE_MMC_POWER_GPIO, misc_gpio[0]);
- qdev_connect_gpio_out(cpu->gpio, PALMTE_SPEAKER_GPIO, misc_gpio[1]);
- qdev_connect_gpio_out(cpu->gpio, 11, misc_gpio[2]);
- qdev_connect_gpio_out(cpu->gpio, 12, misc_gpio[3]);
- qdev_connect_gpio_out(cpu->gpio, 13, misc_gpio[4]);
- omap_mpuio_out_set(cpu->mpuio, 1, misc_gpio[5]);
- omap_mpuio_out_set(cpu->mpuio, 3, misc_gpio[6]);
-
- /* Reset some inputs to initial state. */
- qemu_irq_lower(qdev_get_gpio_in(cpu->gpio, PALMTE_USBDETECT_GPIO));
- qemu_irq_lower(qdev_get_gpio_in(cpu->gpio, PALMTE_USB_OR_DC_GPIO));
- qemu_irq_lower(qdev_get_gpio_in(cpu->gpio, 4));
- qemu_irq_lower(qdev_get_gpio_in(cpu->gpio, PALMTE_HEADPHONES_GPIO));
- qemu_irq_lower(omap_mpuio_in_get(cpu->mpuio)[PALMTE_DC_GPIO]);
- qemu_irq_raise(omap_mpuio_in_get(cpu->mpuio)[6]);
- qemu_irq_raise(omap_mpuio_in_get(cpu->mpuio)[7]);
- qemu_irq_raise(omap_mpuio_in_get(cpu->mpuio)[11]);
-}
-
-static struct arm_boot_info palmte_binfo = {
- .loader_start = OMAP_EMIFF_BASE,
- .ram_size = 0x02000000,
- .board_id = 0x331,
-};
-
-static void palmte_init(MachineState *machine)
-{
- const char *cpu_model = machine->cpu_model;
- const char *kernel_filename = machine->kernel_filename;
- const char *kernel_cmdline = machine->kernel_cmdline;
- const char *initrd_filename = machine->initrd_filename;
- MemoryRegion *address_space_mem = get_system_memory();
- struct omap_mpu_state_s *mpu;
- int flash_size = 0x00800000;
- int sdram_size = palmte_binfo.ram_size;
- static uint32_t cs0val = 0xffffffff;
- static uint32_t cs1val = 0x0000e1a0;
- static uint32_t cs2val = 0x0000e1a0;
- static uint32_t cs3val = 0xe1a0e1a0;
- int rom_size, rom_loaded = 0;
- MemoryRegion *flash = g_new(MemoryRegion, 1);
- MemoryRegion *cs = g_new(MemoryRegion, 4);
-
- mpu = omap310_mpu_init(address_space_mem, sdram_size, cpu_model);
-
- /* External Flash (EMIFS) */
- memory_region_init_ram(flash, NULL, "palmte.flash", flash_size,
- &error_fatal);
- vmstate_register_ram_global(flash);
- memory_region_set_readonly(flash, true);
- memory_region_add_subregion(address_space_mem, OMAP_CS0_BASE, flash);
-
- memory_region_init_io(&cs[0], NULL, &static_ops, &cs0val, "palmte-cs0",
- OMAP_CS0_SIZE - flash_size);
- memory_region_add_subregion(address_space_mem, OMAP_CS0_BASE + flash_size,
- &cs[0]);
- memory_region_init_io(&cs[1], NULL, &static_ops, &cs1val, "palmte-cs1",
- OMAP_CS1_SIZE);
- memory_region_add_subregion(address_space_mem, OMAP_CS1_BASE, &cs[1]);
- memory_region_init_io(&cs[2], NULL, &static_ops, &cs2val, "palmte-cs2",
- OMAP_CS2_SIZE);
- memory_region_add_subregion(address_space_mem, OMAP_CS2_BASE, &cs[2]);
- memory_region_init_io(&cs[3], NULL, &static_ops, &cs3val, "palmte-cs3",
- OMAP_CS3_SIZE);
- memory_region_add_subregion(address_space_mem, OMAP_CS3_BASE, &cs[3]);
-
- palmte_microwire_setup(mpu);
-
- qemu_add_kbd_event_handler(palmte_button_event, mpu);
-
- palmte_gpio_setup(mpu);
-
- /* Setup initial (reset) machine state */
- if (nb_option_roms) {
- rom_size = get_image_size(option_rom[0].name);
- if (rom_size > flash_size) {
- fprintf(stderr, "%s: ROM image too big (%x > %x)\n",
- __FUNCTION__, rom_size, flash_size);
- rom_size = 0;
- }
- if (rom_size > 0) {
- rom_size = load_image_targphys(option_rom[0].name, OMAP_CS0_BASE,
- flash_size);
- rom_loaded = 1;
- }
- if (rom_size < 0) {
- fprintf(stderr, "%s: error loading '%s'\n",
- __FUNCTION__, option_rom[0].name);
- }
- }
-
- if (!rom_loaded && !kernel_filename && !qtest_enabled()) {
- fprintf(stderr, "Kernel or ROM image must be specified\n");
- exit(1);
- }
-
- /* Load the kernel. */
- palmte_binfo.kernel_filename = kernel_filename;
- palmte_binfo.kernel_cmdline = kernel_cmdline;
- palmte_binfo.initrd_filename = initrd_filename;
- arm_load_kernel(mpu->cpu, &palmte_binfo);
-}
-
-static void palmte_machine_init(MachineClass *mc)
-{
- mc->desc = "Palm Tungsten|E aka. Cheetah PDA (OMAP310)";
- mc->init = palmte_init;
-}
-
-DEFINE_MACHINE("cheetah", palmte_machine_init)
diff --git a/qemu/hw/arm/palmetto-bmc.c b/qemu/hw/arm/palmetto-bmc.c
deleted file mode 100644
index 89ebd92b9..000000000
--- a/qemu/hw/arm/palmetto-bmc.c
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * OpenPOWER Palmetto BMC
- *
- * Andrew Jeffery <andrew@aj.id.au>
- *
- * Copyright 2016 IBM Corp.
- *
- * This code is licensed under the GPL version 2 or later. See
- * the COPYING file in the top-level directory.
- */
-
-#include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "qemu-common.h"
-#include "cpu.h"
-#include "exec/address-spaces.h"
-#include "hw/arm/arm.h"
-#include "hw/arm/ast2400.h"
-#include "hw/boards.h"
-
-static struct arm_boot_info palmetto_bmc_binfo = {
- .loader_start = AST2400_SDRAM_BASE,
- .board_id = 0,
- .nb_cpus = 1,
-};
-
-typedef struct PalmettoBMCState {
- AST2400State soc;
- MemoryRegion ram;
-} PalmettoBMCState;
-
-static void palmetto_bmc_init(MachineState *machine)
-{
- PalmettoBMCState *bmc;
-
- bmc = g_new0(PalmettoBMCState, 1);
- object_initialize(&bmc->soc, (sizeof(bmc->soc)), TYPE_AST2400);
- object_property_add_child(OBJECT(machine), "soc", OBJECT(&bmc->soc),
- &error_abort);
-
- memory_region_allocate_system_memory(&bmc->ram, NULL, "ram", ram_size);
- memory_region_add_subregion(get_system_memory(), AST2400_SDRAM_BASE,
- &bmc->ram);
- object_property_add_const_link(OBJECT(&bmc->soc), "ram", OBJECT(&bmc->ram),
- &error_abort);
- object_property_set_bool(OBJECT(&bmc->soc), true, "realized",
- &error_abort);
-
- palmetto_bmc_binfo.kernel_filename = machine->kernel_filename;
- palmetto_bmc_binfo.initrd_filename = machine->initrd_filename;
- palmetto_bmc_binfo.kernel_cmdline = machine->kernel_cmdline;
- palmetto_bmc_binfo.ram_size = ram_size;
- arm_load_kernel(ARM_CPU(first_cpu), &palmetto_bmc_binfo);
-}
-
-static void palmetto_bmc_machine_init(MachineClass *mc)
-{
- mc->desc = "OpenPOWER Palmetto BMC";
- mc->init = palmetto_bmc_init;
- mc->max_cpus = 1;
- mc->no_sdcard = 1;
- mc->no_floppy = 1;
- mc->no_cdrom = 1;
- mc->no_sdcard = 1;
- mc->no_parallel = 1;
-}
-
-DEFINE_MACHINE("palmetto-bmc", palmetto_bmc_machine_init);
diff --git a/qemu/hw/arm/pxa2xx.c b/qemu/hw/arm/pxa2xx.c
deleted file mode 100644
index 1a8c36033..000000000
--- a/qemu/hw/arm/pxa2xx.c
+++ /dev/null
@@ -1,2358 +0,0 @@
-/*
- * Intel XScale PXA255/270 processor support.
- *
- * Copyright (c) 2006 Openedhand Ltd.
- * Written by Andrzej Zaborowski <balrog@zabor.org>
- *
- * This code is licensed under the GPL.
- */
-
-#include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "qemu-common.h"
-#include "cpu.h"
-#include "hw/sysbus.h"
-#include "hw/arm/pxa.h"
-#include "sysemu/sysemu.h"
-#include "hw/char/serial.h"
-#include "hw/i2c/i2c.h"
-#include "hw/ssi/ssi.h"
-#include "sysemu/char.h"
-#include "sysemu/block-backend.h"
-#include "sysemu/blockdev.h"
-#include "qemu/cutils.h"
-
-static struct {
- hwaddr io_base;
- int irqn;
-} pxa255_serial[] = {
- { 0x40100000, PXA2XX_PIC_FFUART },
- { 0x40200000, PXA2XX_PIC_BTUART },
- { 0x40700000, PXA2XX_PIC_STUART },
- { 0x41600000, PXA25X_PIC_HWUART },
- { 0, 0 }
-}, pxa270_serial[] = {
- { 0x40100000, PXA2XX_PIC_FFUART },
- { 0x40200000, PXA2XX_PIC_BTUART },
- { 0x40700000, PXA2XX_PIC_STUART },
- { 0, 0 }
-};
-
-typedef struct PXASSPDef {
- hwaddr io_base;
- int irqn;
-} PXASSPDef;
-
-#if 0
-static PXASSPDef pxa250_ssp[] = {
- { 0x41000000, PXA2XX_PIC_SSP },
- { 0, 0 }
-};
-#endif
-
-static PXASSPDef pxa255_ssp[] = {
- { 0x41000000, PXA2XX_PIC_SSP },
- { 0x41400000, PXA25X_PIC_NSSP },
- { 0, 0 }
-};
-
-#if 0
-static PXASSPDef pxa26x_ssp[] = {
- { 0x41000000, PXA2XX_PIC_SSP },
- { 0x41400000, PXA25X_PIC_NSSP },
- { 0x41500000, PXA26X_PIC_ASSP },
- { 0, 0 }
-};
-#endif
-
-static PXASSPDef pxa27x_ssp[] = {
- { 0x41000000, PXA2XX_PIC_SSP },
- { 0x41700000, PXA27X_PIC_SSP2 },
- { 0x41900000, PXA2XX_PIC_SSP3 },
- { 0, 0 }
-};
-
-#define PMCR 0x00 /* Power Manager Control register */
-#define PSSR 0x04 /* Power Manager Sleep Status register */
-#define PSPR 0x08 /* Power Manager Scratch-Pad register */
-#define PWER 0x0c /* Power Manager Wake-Up Enable register */
-#define PRER 0x10 /* Power Manager Rising-Edge Detect Enable register */
-#define PFER 0x14 /* Power Manager Falling-Edge Detect Enable register */
-#define PEDR 0x18 /* Power Manager Edge-Detect Status register */
-#define PCFR 0x1c /* Power Manager General Configuration register */
-#define PGSR0 0x20 /* Power Manager GPIO Sleep-State register 0 */
-#define PGSR1 0x24 /* Power Manager GPIO Sleep-State register 1 */
-#define PGSR2 0x28 /* Power Manager GPIO Sleep-State register 2 */
-#define PGSR3 0x2c /* Power Manager GPIO Sleep-State register 3 */
-#define RCSR 0x30 /* Reset Controller Status register */
-#define PSLR 0x34 /* Power Manager Sleep Configuration register */
-#define PTSR 0x38 /* Power Manager Standby Configuration register */
-#define PVCR 0x40 /* Power Manager Voltage Change Control register */
-#define PUCR 0x4c /* Power Manager USIM Card Control/Status register */
-#define PKWR 0x50 /* Power Manager Keyboard Wake-Up Enable register */
-#define PKSR 0x54 /* Power Manager Keyboard Level-Detect Status */
-#define PCMD0 0x80 /* Power Manager I2C Command register File 0 */
-#define PCMD31 0xfc /* Power Manager I2C Command register File 31 */
-
-static uint64_t pxa2xx_pm_read(void *opaque, hwaddr addr,
- unsigned size)
-{
- PXA2xxState *s = (PXA2xxState *) opaque;
-
- switch (addr) {
- case PMCR ... PCMD31:
- if (addr & 3)
- goto fail;
-
- return s->pm_regs[addr >> 2];
- default:
- fail:
- printf("%s: Bad register " REG_FMT "\n", __FUNCTION__, addr);
- break;
- }
- return 0;
-}
-
-static void pxa2xx_pm_write(void *opaque, hwaddr addr,
- uint64_t value, unsigned size)
-{
- PXA2xxState *s = (PXA2xxState *) opaque;
-
- switch (addr) {
- case PMCR:
- /* Clear the write-one-to-clear bits... */
- s->pm_regs[addr >> 2] &= ~(value & 0x2a);
- /* ...and set the plain r/w bits */
- s->pm_regs[addr >> 2] &= ~0x15;
- s->pm_regs[addr >> 2] |= value & 0x15;
- break;
-
- case PSSR: /* Read-clean registers */
- case RCSR:
- case PKSR:
- s->pm_regs[addr >> 2] &= ~value;
- break;
-
- default: /* Read-write registers */
- if (!(addr & 3)) {
- s->pm_regs[addr >> 2] = value;
- break;
- }
-
- printf("%s: Bad register " REG_FMT "\n", __FUNCTION__, addr);
- break;
- }
-}
-
-static const MemoryRegionOps pxa2xx_pm_ops = {
- .read = pxa2xx_pm_read,
- .write = pxa2xx_pm_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static const VMStateDescription vmstate_pxa2xx_pm = {
- .name = "pxa2xx_pm",
- .version_id = 0,
- .minimum_version_id = 0,
- .fields = (VMStateField[]) {
- VMSTATE_UINT32_ARRAY(pm_regs, PXA2xxState, 0x40),
- VMSTATE_END_OF_LIST()
- }
-};
-
-#define CCCR 0x00 /* Core Clock Configuration register */
-#define CKEN 0x04 /* Clock Enable register */
-#define OSCC 0x08 /* Oscillator Configuration register */
-#define CCSR 0x0c /* Core Clock Status register */
-
-static uint64_t pxa2xx_cm_read(void *opaque, hwaddr addr,
- unsigned size)
-{
- PXA2xxState *s = (PXA2xxState *) opaque;
-
- switch (addr) {
- case CCCR:
- case CKEN:
- case OSCC:
- return s->cm_regs[addr >> 2];
-
- case CCSR:
- return s->cm_regs[CCCR >> 2] | (3 << 28);
-
- default:
- printf("%s: Bad register " REG_FMT "\n", __FUNCTION__, addr);
- break;
- }
- return 0;
-}
-
-static void pxa2xx_cm_write(void *opaque, hwaddr addr,
- uint64_t value, unsigned size)
-{
- PXA2xxState *s = (PXA2xxState *) opaque;
-
- switch (addr) {
- case CCCR:
- case CKEN:
- s->cm_regs[addr >> 2] = value;
- break;
-
- case OSCC:
- s->cm_regs[addr >> 2] &= ~0x6c;
- s->cm_regs[addr >> 2] |= value & 0x6e;
- if ((value >> 1) & 1) /* OON */
- s->cm_regs[addr >> 2] |= 1 << 0; /* Oscillator is now stable */
- break;
-
- default:
- printf("%s: Bad register " REG_FMT "\n", __FUNCTION__, addr);
- break;
- }
-}
-
-static const MemoryRegionOps pxa2xx_cm_ops = {
- .read = pxa2xx_cm_read,
- .write = pxa2xx_cm_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static const VMStateDescription vmstate_pxa2xx_cm = {
- .name = "pxa2xx_cm",
- .version_id = 0,
- .minimum_version_id = 0,
- .fields = (VMStateField[]) {
- VMSTATE_UINT32_ARRAY(cm_regs, PXA2xxState, 4),
- VMSTATE_UINT32(clkcfg, PXA2xxState),
- VMSTATE_UINT32(pmnc, PXA2xxState),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static uint64_t pxa2xx_clkcfg_read(CPUARMState *env, const ARMCPRegInfo *ri)
-{
- PXA2xxState *s = (PXA2xxState *)ri->opaque;
- return s->clkcfg;
-}
-
-static void pxa2xx_clkcfg_write(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t value)
-{
- PXA2xxState *s = (PXA2xxState *)ri->opaque;
- s->clkcfg = value & 0xf;
- if (value & 2) {
- printf("%s: CPU frequency change attempt\n", __func__);
- }
-}
-
-static void pxa2xx_pwrmode_write(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t value)
-{
- PXA2xxState *s = (PXA2xxState *)ri->opaque;
- static const char *pwrmode[8] = {
- "Normal", "Idle", "Deep-idle", "Standby",
- "Sleep", "reserved (!)", "reserved (!)", "Deep-sleep",
- };
-
- if (value & 8) {
- printf("%s: CPU voltage change attempt\n", __func__);
- }
- switch (value & 7) {
- case 0:
- /* Do nothing */
- break;
-
- case 1:
- /* Idle */
- if (!(s->cm_regs[CCCR >> 2] & (1U << 31))) { /* CPDIS */
- cpu_interrupt(CPU(s->cpu), CPU_INTERRUPT_HALT);
- break;
- }
- /* Fall through. */
-
- case 2:
- /* Deep-Idle */
- cpu_interrupt(CPU(s->cpu), CPU_INTERRUPT_HALT);
- s->pm_regs[RCSR >> 2] |= 0x8; /* Set GPR */
- goto message;
-
- case 3:
- s->cpu->env.uncached_cpsr = ARM_CPU_MODE_SVC;
- s->cpu->env.daif = PSTATE_A | PSTATE_F | PSTATE_I;
- s->cpu->env.cp15.sctlr_ns = 0;
- s->cpu->env.cp15.cpacr_el1 = 0;
- s->cpu->env.cp15.ttbr0_el[1] = 0;
- s->cpu->env.cp15.dacr_ns = 0;
- s->pm_regs[PSSR >> 2] |= 0x8; /* Set STS */
- s->pm_regs[RCSR >> 2] |= 0x8; /* Set GPR */
-
- /*
- * The scratch-pad register is almost universally used
- * for storing the return address on suspend. For the
- * lack of a resuming bootloader, perform a jump
- * directly to that address.
- */
- memset(s->cpu->env.regs, 0, 4 * 15);
- s->cpu->env.regs[15] = s->pm_regs[PSPR >> 2];
-
-#if 0
- buffer = 0xe59ff000; /* ldr pc, [pc, #0] */
- cpu_physical_memory_write(0, &buffer, 4);
- buffer = s->pm_regs[PSPR >> 2];
- cpu_physical_memory_write(8, &buffer, 4);
-#endif
-
- /* Suspend */
- cpu_interrupt(current_cpu, CPU_INTERRUPT_HALT);
-
- goto message;
-
- default:
- message:
- printf("%s: machine entered %s mode\n", __func__,
- pwrmode[value & 7]);
- }
-}
-
-static uint64_t pxa2xx_cppmnc_read(CPUARMState *env, const ARMCPRegInfo *ri)
-{
- PXA2xxState *s = (PXA2xxState *)ri->opaque;
- return s->pmnc;
-}
-
-static void pxa2xx_cppmnc_write(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t value)
-{
- PXA2xxState *s = (PXA2xxState *)ri->opaque;
- s->pmnc = value;
-}
-
-static uint64_t pxa2xx_cpccnt_read(CPUARMState *env, const ARMCPRegInfo *ri)
-{
- PXA2xxState *s = (PXA2xxState *)ri->opaque;
- if (s->pmnc & 1) {
- return qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
- } else {
- return 0;
- }
-}
-
-static const ARMCPRegInfo pxa_cp_reginfo[] = {
- /* cp14 crm==1: perf registers */
- { .name = "CPPMNC", .cp = 14, .crn = 0, .crm = 1, .opc1 = 0, .opc2 = 0,
- .access = PL1_RW, .type = ARM_CP_IO,
- .readfn = pxa2xx_cppmnc_read, .writefn = pxa2xx_cppmnc_write },
- { .name = "CPCCNT", .cp = 14, .crn = 1, .crm = 1, .opc1 = 0, .opc2 = 0,
- .access = PL1_RW, .type = ARM_CP_IO,
- .readfn = pxa2xx_cpccnt_read, .writefn = arm_cp_write_ignore },
- { .name = "CPINTEN", .cp = 14, .crn = 4, .crm = 1, .opc1 = 0, .opc2 = 0,
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
- { .name = "CPFLAG", .cp = 14, .crn = 5, .crm = 1, .opc1 = 0, .opc2 = 0,
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
- { .name = "CPEVTSEL", .cp = 14, .crn = 8, .crm = 1, .opc1 = 0, .opc2 = 0,
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
- /* cp14 crm==2: performance count registers */
- { .name = "CPPMN0", .cp = 14, .crn = 0, .crm = 2, .opc1 = 0, .opc2 = 0,
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
- { .name = "CPPMN1", .cp = 14, .crn = 1, .crm = 2, .opc1 = 0, .opc2 = 0,
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
- { .name = "CPPMN2", .cp = 14, .crn = 2, .crm = 2, .opc1 = 0, .opc2 = 0,
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
- { .name = "CPPMN3", .cp = 14, .crn = 2, .crm = 3, .opc1 = 0, .opc2 = 0,
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
- /* cp14 crn==6: CLKCFG */
- { .name = "CLKCFG", .cp = 14, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 0,
- .access = PL1_RW, .type = ARM_CP_IO,
- .readfn = pxa2xx_clkcfg_read, .writefn = pxa2xx_clkcfg_write },
- /* cp14 crn==7: PWRMODE */
- { .name = "PWRMODE", .cp = 14, .crn = 7, .crm = 0, .opc1 = 0, .opc2 = 0,
- .access = PL1_RW, .type = ARM_CP_IO,
- .readfn = arm_cp_read_zero, .writefn = pxa2xx_pwrmode_write },
- REGINFO_SENTINEL
-};
-
-static void pxa2xx_setup_cp14(PXA2xxState *s)
-{
- define_arm_cp_regs_with_opaque(s->cpu, pxa_cp_reginfo, s);
-}
-
-#define MDCNFG 0x00 /* SDRAM Configuration register */
-#define MDREFR 0x04 /* SDRAM Refresh Control register */
-#define MSC0 0x08 /* Static Memory Control register 0 */
-#define MSC1 0x0c /* Static Memory Control register 1 */
-#define MSC2 0x10 /* Static Memory Control register 2 */
-#define MECR 0x14 /* Expansion Memory Bus Config register */
-#define SXCNFG 0x1c /* Synchronous Static Memory Config register */
-#define MCMEM0 0x28 /* PC Card Memory Socket 0 Timing register */
-#define MCMEM1 0x2c /* PC Card Memory Socket 1 Timing register */
-#define MCATT0 0x30 /* PC Card Attribute Socket 0 register */
-#define MCATT1 0x34 /* PC Card Attribute Socket 1 register */
-#define MCIO0 0x38 /* PC Card I/O Socket 0 Timing register */
-#define MCIO1 0x3c /* PC Card I/O Socket 1 Timing register */
-#define MDMRS 0x40 /* SDRAM Mode Register Set Config register */
-#define BOOT_DEF 0x44 /* Boot-time Default Configuration register */
-#define ARB_CNTL 0x48 /* Arbiter Control register */
-#define BSCNTR0 0x4c /* Memory Buffer Strength Control register 0 */
-#define BSCNTR1 0x50 /* Memory Buffer Strength Control register 1 */
-#define LCDBSCNTR 0x54 /* LCD Buffer Strength Control register */
-#define MDMRSLP 0x58 /* Low Power SDRAM Mode Set Config register */
-#define BSCNTR2 0x5c /* Memory Buffer Strength Control register 2 */
-#define BSCNTR3 0x60 /* Memory Buffer Strength Control register 3 */
-#define SA1110 0x64 /* SA-1110 Memory Compatibility register */
-
-static uint64_t pxa2xx_mm_read(void *opaque, hwaddr addr,
- unsigned size)
-{
- PXA2xxState *s = (PXA2xxState *) opaque;
-
- switch (addr) {
- case MDCNFG ... SA1110:
- if ((addr & 3) == 0)
- return s->mm_regs[addr >> 2];
-
- default:
- printf("%s: Bad register " REG_FMT "\n", __FUNCTION__, addr);
- break;
- }
- return 0;
-}
-
-static void pxa2xx_mm_write(void *opaque, hwaddr addr,
- uint64_t value, unsigned size)
-{
- PXA2xxState *s = (PXA2xxState *) opaque;
-
- switch (addr) {
- case MDCNFG ... SA1110:
- if ((addr & 3) == 0) {
- s->mm_regs[addr >> 2] = value;
- break;
- }
-
- default:
- printf("%s: Bad register " REG_FMT "\n", __FUNCTION__, addr);
- break;
- }
-}
-
-static const MemoryRegionOps pxa2xx_mm_ops = {
- .read = pxa2xx_mm_read,
- .write = pxa2xx_mm_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static const VMStateDescription vmstate_pxa2xx_mm = {
- .name = "pxa2xx_mm",
- .version_id = 0,
- .minimum_version_id = 0,
- .fields = (VMStateField[]) {
- VMSTATE_UINT32_ARRAY(mm_regs, PXA2xxState, 0x1a),
- VMSTATE_END_OF_LIST()
- }
-};
-
-#define TYPE_PXA2XX_SSP "pxa2xx-ssp"
-#define PXA2XX_SSP(obj) \
- OBJECT_CHECK(PXA2xxSSPState, (obj), TYPE_PXA2XX_SSP)
-
-/* Synchronous Serial Ports */
-typedef struct {
- /*< private >*/
- SysBusDevice parent_obj;
- /*< public >*/
-
- MemoryRegion iomem;
- qemu_irq irq;
- uint32_t enable;
- SSIBus *bus;
-
- uint32_t sscr[2];
- uint32_t sspsp;
- uint32_t ssto;
- uint32_t ssitr;
- uint32_t sssr;
- uint8_t sstsa;
- uint8_t ssrsa;
- uint8_t ssacd;
-
- uint32_t rx_fifo[16];
- uint32_t rx_level;
- uint32_t rx_start;
-} PXA2xxSSPState;
-
-static bool pxa2xx_ssp_vmstate_validate(void *opaque, int version_id)
-{
- PXA2xxSSPState *s = opaque;
-
- return s->rx_start < sizeof(s->rx_fifo);
-}
-
-static const VMStateDescription vmstate_pxa2xx_ssp = {
- .name = "pxa2xx-ssp",
- .version_id = 1,
- .minimum_version_id = 1,
- .fields = (VMStateField[]) {
- VMSTATE_UINT32(enable, PXA2xxSSPState),
- VMSTATE_UINT32_ARRAY(sscr, PXA2xxSSPState, 2),
- VMSTATE_UINT32(sspsp, PXA2xxSSPState),
- VMSTATE_UINT32(ssto, PXA2xxSSPState),
- VMSTATE_UINT32(ssitr, PXA2xxSSPState),
- VMSTATE_UINT32(sssr, PXA2xxSSPState),
- VMSTATE_UINT8(sstsa, PXA2xxSSPState),
- VMSTATE_UINT8(ssrsa, PXA2xxSSPState),
- VMSTATE_UINT8(ssacd, PXA2xxSSPState),
- VMSTATE_UINT32(rx_level, PXA2xxSSPState),
- VMSTATE_UINT32(rx_start, PXA2xxSSPState),
- VMSTATE_VALIDATE("fifo is 16 bytes", pxa2xx_ssp_vmstate_validate),
- VMSTATE_UINT32_ARRAY(rx_fifo, PXA2xxSSPState, 16),
- VMSTATE_END_OF_LIST()
- }
-};
-
-#define SSCR0 0x00 /* SSP Control register 0 */
-#define SSCR1 0x04 /* SSP Control register 1 */
-#define SSSR 0x08 /* SSP Status register */
-#define SSITR 0x0c /* SSP Interrupt Test register */
-#define SSDR 0x10 /* SSP Data register */
-#define SSTO 0x28 /* SSP Time-Out register */
-#define SSPSP 0x2c /* SSP Programmable Serial Protocol register */
-#define SSTSA 0x30 /* SSP TX Time Slot Active register */
-#define SSRSA 0x34 /* SSP RX Time Slot Active register */
-#define SSTSS 0x38 /* SSP Time Slot Status register */
-#define SSACD 0x3c /* SSP Audio Clock Divider 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_RIM (1 << 22)
-#define SSCR0_TIM (1 << 23)
-#define SSCR0_MOD (1U << 31)
-#define SSCR0_DSS(x) (((((x) >> 16) & 0x10) | ((x) & 0xf)) + 1)
-#define SSCR1_RIE (1 << 0)
-#define SSCR1_TIE (1 << 1)
-#define SSCR1_LBM (1 << 2)
-#define SSCR1_MWDS (1 << 5)
-#define SSCR1_TFT(x) ((((x) >> 6) & 0xf) + 1)
-#define SSCR1_RFT(x) ((((x) >> 10) & 0xf) + 1)
-#define SSCR1_EFWR (1 << 14)
-#define SSCR1_PINTE (1 << 18)
-#define SSCR1_TINTE (1 << 19)
-#define SSCR1_RSRE (1 << 20)
-#define SSCR1_TSRE (1 << 21)
-#define SSCR1_EBCEI (1 << 29)
-#define SSITR_INT (7 << 5)
-#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_PINT (1 << 18)
-#define SSSR_TINT (1 << 19)
-#define SSSR_EOC (1 << 20)
-#define SSSR_TUR (1 << 21)
-#define SSSR_BCE (1 << 23)
-#define SSSR_RW 0x00bc0080
-
-static void pxa2xx_ssp_int_update(PXA2xxSSPState *s)
-{
- int level = 0;
-
- level |= s->ssitr & SSITR_INT;
- level |= (s->sssr & SSSR_BCE) && (s->sscr[1] & SSCR1_EBCEI);
- level |= (s->sssr & SSSR_TUR) && !(s->sscr[0] & SSCR0_TIM);
- level |= (s->sssr & SSSR_EOC) && (s->sssr & (SSSR_TINT | SSSR_PINT));
- level |= (s->sssr & SSSR_TINT) && (s->sscr[1] & SSCR1_TINTE);
- level |= (s->sssr & SSSR_PINT) && (s->sscr[1] & SSCR1_PINTE);
- level |= (s->sssr & SSSR_ROR) && !(s->sscr[0] & SSCR0_RIM);
- 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 pxa2xx_ssp_fifo_update(PXA2xxSSPState *s)
-{
- s->sssr &= ~(0xf << 12); /* Clear RFL */
- s->sssr &= ~(0xf << 8); /* Clear TFL */
- s->sssr &= ~SSSR_TFS;
- s->sssr &= ~SSSR_TNF;
- if (s->enable) {
- s->sssr |= ((s->rx_level - 1) & 0xf) << 12;
- if (s->rx_level >= SSCR1_RFT(s->sscr[1]))
- 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;
- }
-
- pxa2xx_ssp_int_update(s);
-}
-
-static uint64_t pxa2xx_ssp_read(void *opaque, hwaddr addr,
- unsigned size)
-{
- PXA2xxSSPState *s = (PXA2xxSSPState *) opaque;
- uint32_t retval;
-
- switch (addr) {
- case SSCR0:
- return s->sscr[0];
- case SSCR1:
- return s->sscr[1];
- case SSPSP:
- return s->sspsp;
- case SSTO:
- return s->ssto;
- case SSITR:
- return s->ssitr;
- case SSSR:
- return s->sssr | s->ssitr;
- case SSDR:
- if (!s->enable)
- return 0xffffffff;
- if (s->rx_level < 1) {
- printf("%s: SSP Rx Underrun\n", __FUNCTION__);
- return 0xffffffff;
- }
- s->rx_level --;
- retval = s->rx_fifo[s->rx_start ++];
- s->rx_start &= 0xf;
- pxa2xx_ssp_fifo_update(s);
- return retval;
- case SSTSA:
- return s->sstsa;
- case SSRSA:
- return s->ssrsa;
- case SSTSS:
- return 0;
- case SSACD:
- return s->ssacd;
- default:
- printf("%s: Bad register " REG_FMT "\n", __FUNCTION__, addr);
- break;
- }
- return 0;
-}
-
-static void pxa2xx_ssp_write(void *opaque, hwaddr addr,
- uint64_t value64, unsigned size)
-{
- PXA2xxSSPState *s = (PXA2xxSSPState *) opaque;
- uint32_t value = value64;
-
- switch (addr) {
- case SSCR0:
- s->sscr[0] = value & 0xc7ffffff;
- s->enable = value & SSCR0_SSE;
- if (value & SSCR0_MOD)
- printf("%s: Attempt to use network mode\n", __FUNCTION__);
- if (s->enable && SSCR0_DSS(value) < 4)
- printf("%s: Wrong data size: %i bits\n", __FUNCTION__,
- SSCR0_DSS(value));
- if (!(value & SSCR0_SSE)) {
- s->sssr = 0;
- s->ssitr = 0;
- s->rx_level = 0;
- }
- pxa2xx_ssp_fifo_update(s);
- break;
-
- case SSCR1:
- s->sscr[1] = value;
- if (value & (SSCR1_LBM | SSCR1_EFWR))
- printf("%s: Attempt to use SSP test mode\n", __FUNCTION__);
- pxa2xx_ssp_fifo_update(s);
- break;
-
- case SSPSP:
- s->sspsp = value;
- break;
-
- case SSTO:
- s->ssto = value;
- break;
-
- case SSITR:
- s->ssitr = value & SSITR_INT;
- pxa2xx_ssp_int_update(s);
- break;
-
- case SSSR:
- s->sssr &= ~(value & SSSR_RW);
- pxa2xx_ssp_int_update(s);
- break;
-
- case SSDR:
- if (SSCR0_UWIRE(s->sscr[0])) {
- if (s->sscr[1] & SSCR1_MWDS)
- value &= 0xffff;
- else
- 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->enable) {
- uint32_t readval;
- readval = ssi_transfer(s->bus, value);
- if (s->rx_level < 0x10) {
- s->rx_fifo[(s->rx_start + s->rx_level ++) & 0xf] = readval;
- } else {
- s->sssr |= SSSR_ROR;
- }
- }
- pxa2xx_ssp_fifo_update(s);
- break;
-
- case SSTSA:
- s->sstsa = value;
- break;
-
- case SSRSA:
- s->ssrsa = value;
- break;
-
- case SSACD:
- s->ssacd = value;
- break;
-
- default:
- printf("%s: Bad register " REG_FMT "\n", __FUNCTION__, addr);
- break;
- }
-}
-
-static const MemoryRegionOps pxa2xx_ssp_ops = {
- .read = pxa2xx_ssp_read,
- .write = pxa2xx_ssp_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static void pxa2xx_ssp_reset(DeviceState *d)
-{
- PXA2xxSSPState *s = PXA2XX_SSP(d);
-
- s->enable = 0;
- s->sscr[0] = s->sscr[1] = 0;
- s->sspsp = 0;
- s->ssto = 0;
- s->ssitr = 0;
- s->sssr = 0;
- s->sstsa = 0;
- s->ssrsa = 0;
- s->ssacd = 0;
- s->rx_start = s->rx_level = 0;
-}
-
-static int pxa2xx_ssp_init(SysBusDevice *sbd)
-{
- DeviceState *dev = DEVICE(sbd);
- PXA2xxSSPState *s = PXA2XX_SSP(dev);
-
- sysbus_init_irq(sbd, &s->irq);
-
- memory_region_init_io(&s->iomem, OBJECT(s), &pxa2xx_ssp_ops, s,
- "pxa2xx-ssp", 0x1000);
- sysbus_init_mmio(sbd, &s->iomem);
-
- s->bus = ssi_create_bus(dev, "ssi");
- return 0;
-}
-
-/* Real-Time Clock */
-#define RCNR 0x00 /* RTC Counter register */
-#define RTAR 0x04 /* RTC Alarm register */
-#define RTSR 0x08 /* RTC Status register */
-#define RTTR 0x0c /* RTC Timer Trim register */
-#define RDCR 0x10 /* RTC Day Counter register */
-#define RYCR 0x14 /* RTC Year Counter register */
-#define RDAR1 0x18 /* RTC Wristwatch Day Alarm register 1 */
-#define RYAR1 0x1c /* RTC Wristwatch Year Alarm register 1 */
-#define RDAR2 0x20 /* RTC Wristwatch Day Alarm register 2 */
-#define RYAR2 0x24 /* RTC Wristwatch Year Alarm register 2 */
-#define SWCR 0x28 /* RTC Stopwatch Counter register */
-#define SWAR1 0x2c /* RTC Stopwatch Alarm register 1 */
-#define SWAR2 0x30 /* RTC Stopwatch Alarm register 2 */
-#define RTCPICR 0x34 /* RTC Periodic Interrupt Counter register */
-#define PIAR 0x38 /* RTC Periodic Interrupt Alarm register */
-
-#define TYPE_PXA2XX_RTC "pxa2xx_rtc"
-#define PXA2XX_RTC(obj) \
- OBJECT_CHECK(PXA2xxRTCState, (obj), TYPE_PXA2XX_RTC)
-
-typedef struct {
- /*< private >*/
- SysBusDevice parent_obj;
- /*< public >*/
-
- MemoryRegion iomem;
- uint32_t rttr;
- uint32_t rtsr;
- uint32_t rtar;
- uint32_t rdar1;
- uint32_t rdar2;
- uint32_t ryar1;
- uint32_t ryar2;
- uint32_t swar1;
- uint32_t swar2;
- uint32_t piar;
- uint32_t last_rcnr;
- uint32_t last_rdcr;
- uint32_t last_rycr;
- uint32_t last_swcr;
- uint32_t last_rtcpicr;
- int64_t last_hz;
- int64_t last_sw;
- int64_t last_pi;
- QEMUTimer *rtc_hz;
- QEMUTimer *rtc_rdal1;
- QEMUTimer *rtc_rdal2;
- QEMUTimer *rtc_swal1;
- QEMUTimer *rtc_swal2;
- QEMUTimer *rtc_pi;
- qemu_irq rtc_irq;
-} PXA2xxRTCState;
-
-static inline void pxa2xx_rtc_int_update(PXA2xxRTCState *s)
-{
- qemu_set_irq(s->rtc_irq, !!(s->rtsr & 0x2553));
-}
-
-static void pxa2xx_rtc_hzupdate(PXA2xxRTCState *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_rdcr += ((rt - s->last_hz) << 15) /
- (1000 * ((s->rttr & 0xffff) + 1));
- s->last_hz = rt;
-}
-
-static void pxa2xx_rtc_swupdate(PXA2xxRTCState *s)
-{
- int64_t rt = qemu_clock_get_ms(rtc_clock);
- if (s->rtsr & (1 << 12))
- s->last_swcr += (rt - s->last_sw) / 10;
- s->last_sw = rt;
-}
-
-static void pxa2xx_rtc_piupdate(PXA2xxRTCState *s)
-{
- int64_t rt = qemu_clock_get_ms(rtc_clock);
- if (s->rtsr & (1 << 15))
- s->last_swcr += rt - s->last_pi;
- s->last_pi = rt;
-}
-
-static inline void pxa2xx_rtc_alarm_update(PXA2xxRTCState *s,
- uint32_t rtsr)
-{
- if ((rtsr & (1 << 2)) && !(rtsr & (1 << 0)))
- timer_mod(s->rtc_hz, s->last_hz +
- (((s->rtar - s->last_rcnr) * 1000 *
- ((s->rttr & 0xffff) + 1)) >> 15));
- else
- timer_del(s->rtc_hz);
-
- if ((rtsr & (1 << 5)) && !(rtsr & (1 << 4)))
- timer_mod(s->rtc_rdal1, s->last_hz +
- (((s->rdar1 - s->last_rdcr) * 1000 *
- ((s->rttr & 0xffff) + 1)) >> 15)); /* TODO: fixup */
- else
- timer_del(s->rtc_rdal1);
-
- if ((rtsr & (1 << 7)) && !(rtsr & (1 << 6)))
- timer_mod(s->rtc_rdal2, s->last_hz +
- (((s->rdar2 - s->last_rdcr) * 1000 *
- ((s->rttr & 0xffff) + 1)) >> 15)); /* TODO: fixup */
- else
- timer_del(s->rtc_rdal2);
-
- if ((rtsr & 0x1200) == 0x1200 && !(rtsr & (1 << 8)))
- timer_mod(s->rtc_swal1, s->last_sw +
- (s->swar1 - s->last_swcr) * 10); /* TODO: fixup */
- else
- timer_del(s->rtc_swal1);
-
- if ((rtsr & 0x1800) == 0x1800 && !(rtsr & (1 << 10)))
- timer_mod(s->rtc_swal2, s->last_sw +
- (s->swar2 - s->last_swcr) * 10); /* TODO: fixup */
- else
- timer_del(s->rtc_swal2);
-
- if ((rtsr & 0xc000) == 0xc000 && !(rtsr & (1 << 13)))
- timer_mod(s->rtc_pi, s->last_pi +
- (s->piar & 0xffff) - s->last_rtcpicr);
- else
- timer_del(s->rtc_pi);
-}
-
-static inline void pxa2xx_rtc_hz_tick(void *opaque)
-{
- PXA2xxRTCState *s = (PXA2xxRTCState *) opaque;
- s->rtsr |= (1 << 0);
- pxa2xx_rtc_alarm_update(s, s->rtsr);
- pxa2xx_rtc_int_update(s);
-}
-
-static inline void pxa2xx_rtc_rdal1_tick(void *opaque)
-{
- PXA2xxRTCState *s = (PXA2xxRTCState *) opaque;
- s->rtsr |= (1 << 4);
- pxa2xx_rtc_alarm_update(s, s->rtsr);
- pxa2xx_rtc_int_update(s);
-}
-
-static inline void pxa2xx_rtc_rdal2_tick(void *opaque)
-{
- PXA2xxRTCState *s = (PXA2xxRTCState *) opaque;
- s->rtsr |= (1 << 6);
- pxa2xx_rtc_alarm_update(s, s->rtsr);
- pxa2xx_rtc_int_update(s);
-}
-
-static inline void pxa2xx_rtc_swal1_tick(void *opaque)
-{
- PXA2xxRTCState *s = (PXA2xxRTCState *) opaque;
- s->rtsr |= (1 << 8);
- pxa2xx_rtc_alarm_update(s, s->rtsr);
- pxa2xx_rtc_int_update(s);
-}
-
-static inline void pxa2xx_rtc_swal2_tick(void *opaque)
-{
- PXA2xxRTCState *s = (PXA2xxRTCState *) opaque;
- s->rtsr |= (1 << 10);
- pxa2xx_rtc_alarm_update(s, s->rtsr);
- pxa2xx_rtc_int_update(s);
-}
-
-static inline void pxa2xx_rtc_pi_tick(void *opaque)
-{
- PXA2xxRTCState *s = (PXA2xxRTCState *) opaque;
- s->rtsr |= (1 << 13);
- pxa2xx_rtc_piupdate(s);
- s->last_rtcpicr = 0;
- pxa2xx_rtc_alarm_update(s, s->rtsr);
- pxa2xx_rtc_int_update(s);
-}
-
-static uint64_t pxa2xx_rtc_read(void *opaque, hwaddr addr,
- unsigned size)
-{
- PXA2xxRTCState *s = (PXA2xxRTCState *) opaque;
-
- switch (addr) {
- case RTTR:
- return s->rttr;
- case RTSR:
- return s->rtsr;
- case RTAR:
- return s->rtar;
- case RDAR1:
- return s->rdar1;
- case RDAR2:
- return s->rdar2;
- case RYAR1:
- return s->ryar1;
- case RYAR2:
- return s->ryar2;
- case SWAR1:
- return s->swar1;
- case SWAR2:
- return s->swar2;
- case PIAR:
- return s->piar;
- case RCNR:
- return s->last_rcnr +
- ((qemu_clock_get_ms(rtc_clock) - s->last_hz) << 15) /
- (1000 * ((s->rttr & 0xffff) + 1));
- case RDCR:
- return s->last_rdcr +
- ((qemu_clock_get_ms(rtc_clock) - s->last_hz) << 15) /
- (1000 * ((s->rttr & 0xffff) + 1));
- case RYCR:
- return s->last_rycr;
- case SWCR:
- if (s->rtsr & (1 << 12))
- return s->last_swcr +
- (qemu_clock_get_ms(rtc_clock) - s->last_sw) / 10;
- else
- return s->last_swcr;
- default:
- printf("%s: Bad register " REG_FMT "\n", __FUNCTION__, addr);
- break;
- }
- return 0;
-}
-
-static void pxa2xx_rtc_write(void *opaque, hwaddr addr,
- uint64_t value64, unsigned size)
-{
- PXA2xxRTCState *s = (PXA2xxRTCState *) opaque;
- uint32_t value = value64;
-
- switch (addr) {
- case RTTR:
- if (!(s->rttr & (1U << 31))) {
- pxa2xx_rtc_hzupdate(s);
- s->rttr = value;
- pxa2xx_rtc_alarm_update(s, s->rtsr);
- }
- break;
-
- case RTSR:
- if ((s->rtsr ^ value) & (1 << 15))
- pxa2xx_rtc_piupdate(s);
-
- if ((s->rtsr ^ value) & (1 << 12))
- pxa2xx_rtc_swupdate(s);
-
- if (((s->rtsr ^ value) & 0x4aac) | (value & ~0xdaac))
- pxa2xx_rtc_alarm_update(s, value);
-
- s->rtsr = (value & 0xdaac) | (s->rtsr & ~(value & ~0xdaac));
- pxa2xx_rtc_int_update(s);
- break;
-
- case RTAR:
- s->rtar = value;
- pxa2xx_rtc_alarm_update(s, s->rtsr);
- break;
-
- case RDAR1:
- s->rdar1 = value;
- pxa2xx_rtc_alarm_update(s, s->rtsr);
- break;
-
- case RDAR2:
- s->rdar2 = value;
- pxa2xx_rtc_alarm_update(s, s->rtsr);
- break;
-
- case RYAR1:
- s->ryar1 = value;
- pxa2xx_rtc_alarm_update(s, s->rtsr);
- break;
-
- case RYAR2:
- s->ryar2 = value;
- pxa2xx_rtc_alarm_update(s, s->rtsr);
- break;
-
- case SWAR1:
- pxa2xx_rtc_swupdate(s);
- s->swar1 = value;
- s->last_swcr = 0;
- pxa2xx_rtc_alarm_update(s, s->rtsr);
- break;
-
- case SWAR2:
- s->swar2 = value;
- pxa2xx_rtc_alarm_update(s, s->rtsr);
- break;
-
- case PIAR:
- s->piar = value;
- pxa2xx_rtc_alarm_update(s, s->rtsr);
- break;
-
- case RCNR:
- pxa2xx_rtc_hzupdate(s);
- s->last_rcnr = value;
- pxa2xx_rtc_alarm_update(s, s->rtsr);
- break;
-
- case RDCR:
- pxa2xx_rtc_hzupdate(s);
- s->last_rdcr = value;
- pxa2xx_rtc_alarm_update(s, s->rtsr);
- break;
-
- case RYCR:
- s->last_rycr = value;
- break;
-
- case SWCR:
- pxa2xx_rtc_swupdate(s);
- s->last_swcr = value;
- pxa2xx_rtc_alarm_update(s, s->rtsr);
- break;
-
- case RTCPICR:
- pxa2xx_rtc_piupdate(s);
- s->last_rtcpicr = value & 0xffff;
- pxa2xx_rtc_alarm_update(s, s->rtsr);
- break;
-
- default:
- printf("%s: Bad register " REG_FMT "\n", __FUNCTION__, addr);
- }
-}
-
-static const MemoryRegionOps pxa2xx_rtc_ops = {
- .read = pxa2xx_rtc_read,
- .write = pxa2xx_rtc_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static int pxa2xx_rtc_init(SysBusDevice *dev)
-{
- PXA2xxRTCState *s = PXA2XX_RTC(dev);
- struct tm tm;
- int wom;
-
- s->rttr = 0x7fff;
- s->rtsr = 0;
-
- qemu_get_timedate(&tm, 0);
- wom = ((tm.tm_mday - 1) / 7) + 1;
-
- s->last_rcnr = (uint32_t) mktimegm(&tm);
- s->last_rdcr = (wom << 20) | ((tm.tm_wday + 1) << 17) |
- (tm.tm_hour << 12) | (tm.tm_min << 6) | tm.tm_sec;
- s->last_rycr = ((tm.tm_year + 1900) << 9) |
- ((tm.tm_mon + 1) << 5) | tm.tm_mday;
- s->last_swcr = (tm.tm_hour << 19) |
- (tm.tm_min << 13) | (tm.tm_sec << 7);
- s->last_rtcpicr = 0;
- s->last_hz = s->last_sw = s->last_pi = qemu_clock_get_ms(rtc_clock);
-
- s->rtc_hz = timer_new_ms(rtc_clock, pxa2xx_rtc_hz_tick, s);
- s->rtc_rdal1 = timer_new_ms(rtc_clock, pxa2xx_rtc_rdal1_tick, s);
- s->rtc_rdal2 = timer_new_ms(rtc_clock, pxa2xx_rtc_rdal2_tick, s);
- s->rtc_swal1 = timer_new_ms(rtc_clock, pxa2xx_rtc_swal1_tick, s);
- s->rtc_swal2 = timer_new_ms(rtc_clock, pxa2xx_rtc_swal2_tick, s);
- s->rtc_pi = timer_new_ms(rtc_clock, pxa2xx_rtc_pi_tick, s);
-
- sysbus_init_irq(dev, &s->rtc_irq);
-
- memory_region_init_io(&s->iomem, OBJECT(s), &pxa2xx_rtc_ops, s,
- "pxa2xx-rtc", 0x10000);
- sysbus_init_mmio(dev, &s->iomem);
-
- return 0;
-}
-
-static void pxa2xx_rtc_pre_save(void *opaque)
-{
- PXA2xxRTCState *s = (PXA2xxRTCState *) opaque;
-
- pxa2xx_rtc_hzupdate(s);
- pxa2xx_rtc_piupdate(s);
- pxa2xx_rtc_swupdate(s);
-}
-
-static int pxa2xx_rtc_post_load(void *opaque, int version_id)
-{
- PXA2xxRTCState *s = (PXA2xxRTCState *) opaque;
-
- pxa2xx_rtc_alarm_update(s, s->rtsr);
-
- return 0;
-}
-
-static const VMStateDescription vmstate_pxa2xx_rtc_regs = {
- .name = "pxa2xx_rtc",
- .version_id = 0,
- .minimum_version_id = 0,
- .pre_save = pxa2xx_rtc_pre_save,
- .post_load = pxa2xx_rtc_post_load,
- .fields = (VMStateField[]) {
- VMSTATE_UINT32(rttr, PXA2xxRTCState),
- VMSTATE_UINT32(rtsr, PXA2xxRTCState),
- VMSTATE_UINT32(rtar, PXA2xxRTCState),
- VMSTATE_UINT32(rdar1, PXA2xxRTCState),
- VMSTATE_UINT32(rdar2, PXA2xxRTCState),
- VMSTATE_UINT32(ryar1, PXA2xxRTCState),
- VMSTATE_UINT32(ryar2, PXA2xxRTCState),
- VMSTATE_UINT32(swar1, PXA2xxRTCState),
- VMSTATE_UINT32(swar2, PXA2xxRTCState),
- VMSTATE_UINT32(piar, PXA2xxRTCState),
- VMSTATE_UINT32(last_rcnr, PXA2xxRTCState),
- VMSTATE_UINT32(last_rdcr, PXA2xxRTCState),
- VMSTATE_UINT32(last_rycr, PXA2xxRTCState),
- VMSTATE_UINT32(last_swcr, PXA2xxRTCState),
- VMSTATE_UINT32(last_rtcpicr, PXA2xxRTCState),
- VMSTATE_INT64(last_hz, PXA2xxRTCState),
- VMSTATE_INT64(last_sw, PXA2xxRTCState),
- VMSTATE_INT64(last_pi, PXA2xxRTCState),
- VMSTATE_END_OF_LIST(),
- },
-};
-
-static void pxa2xx_rtc_sysbus_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
-
- k->init = pxa2xx_rtc_init;
- dc->desc = "PXA2xx RTC Controller";
- dc->vmsd = &vmstate_pxa2xx_rtc_regs;
-}
-
-static const TypeInfo pxa2xx_rtc_sysbus_info = {
- .name = TYPE_PXA2XX_RTC,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(PXA2xxRTCState),
- .class_init = pxa2xx_rtc_sysbus_class_init,
-};
-
-/* I2C Interface */
-
-#define TYPE_PXA2XX_I2C_SLAVE "pxa2xx-i2c-slave"
-#define PXA2XX_I2C_SLAVE(obj) \
- OBJECT_CHECK(PXA2xxI2CSlaveState, (obj), TYPE_PXA2XX_I2C_SLAVE)
-
-typedef struct PXA2xxI2CSlaveState {
- I2CSlave parent_obj;
-
- PXA2xxI2CState *host;
-} PXA2xxI2CSlaveState;
-
-#define TYPE_PXA2XX_I2C "pxa2xx_i2c"
-#define PXA2XX_I2C(obj) \
- OBJECT_CHECK(PXA2xxI2CState, (obj), TYPE_PXA2XX_I2C)
-
-struct PXA2xxI2CState {
- /*< private >*/
- SysBusDevice parent_obj;
- /*< public >*/
-
- MemoryRegion iomem;
- PXA2xxI2CSlaveState *slave;
- I2CBus *bus;
- qemu_irq irq;
- uint32_t offset;
- uint32_t region_size;
-
- uint16_t control;
- uint16_t status;
- uint8_t ibmr;
- uint8_t data;
-};
-
-#define IBMR 0x80 /* I2C Bus Monitor register */
-#define IDBR 0x88 /* I2C Data Buffer register */
-#define ICR 0x90 /* I2C Control register */
-#define ISR 0x98 /* I2C Status register */
-#define ISAR 0xa0 /* I2C Slave Address register */
-
-static void pxa2xx_i2c_update(PXA2xxI2CState *s)
-{
- uint16_t level = 0;
- level |= s->status & s->control & (1 << 10); /* BED */
- level |= (s->status & (1 << 7)) && (s->control & (1 << 9)); /* IRF */
- level |= (s->status & (1 << 6)) && (s->control & (1 << 8)); /* ITE */
- level |= s->status & (1 << 9); /* SAD */
- qemu_set_irq(s->irq, !!level);
-}
-
-/* These are only stubs now. */
-static void pxa2xx_i2c_event(I2CSlave *i2c, enum i2c_event event)
-{
- PXA2xxI2CSlaveState *slave = PXA2XX_I2C_SLAVE(i2c);
- PXA2xxI2CState *s = slave->host;
-
- switch (event) {
- case I2C_START_SEND:
- s->status |= (1 << 9); /* set SAD */
- s->status &= ~(1 << 0); /* clear RWM */
- break;
- case I2C_START_RECV:
- s->status |= (1 << 9); /* set SAD */
- s->status |= 1 << 0; /* set RWM */
- break;
- case I2C_FINISH:
- s->status |= (1 << 4); /* set SSD */
- break;
- case I2C_NACK:
- s->status |= 1 << 1; /* set ACKNAK */
- break;
- }
- pxa2xx_i2c_update(s);
-}
-
-static int pxa2xx_i2c_rx(I2CSlave *i2c)
-{
- PXA2xxI2CSlaveState *slave = PXA2XX_I2C_SLAVE(i2c);
- PXA2xxI2CState *s = slave->host;
-
- if ((s->control & (1 << 14)) || !(s->control & (1 << 6))) {
- return 0;
- }
-
- if (s->status & (1 << 0)) { /* RWM */
- s->status |= 1 << 6; /* set ITE */
- }
- pxa2xx_i2c_update(s);
-
- return s->data;
-}
-
-static int pxa2xx_i2c_tx(I2CSlave *i2c, uint8_t data)
-{
- PXA2xxI2CSlaveState *slave = PXA2XX_I2C_SLAVE(i2c);
- PXA2xxI2CState *s = slave->host;
-
- if ((s->control & (1 << 14)) || !(s->control & (1 << 6))) {
- return 1;
- }
-
- if (!(s->status & (1 << 0))) { /* RWM */
- s->status |= 1 << 7; /* set IRF */
- s->data = data;
- }
- pxa2xx_i2c_update(s);
-
- return 1;
-}
-
-static uint64_t pxa2xx_i2c_read(void *opaque, hwaddr addr,
- unsigned size)
-{
- PXA2xxI2CState *s = (PXA2xxI2CState *) opaque;
- I2CSlave *slave;
-
- addr -= s->offset;
- switch (addr) {
- case ICR:
- return s->control;
- case ISR:
- return s->status | (i2c_bus_busy(s->bus) << 2);
- case ISAR:
- slave = I2C_SLAVE(s->slave);
- return slave->address;
- case IDBR:
- return s->data;
- case IBMR:
- if (s->status & (1 << 2))
- s->ibmr ^= 3; /* Fake SCL and SDA pin changes */
- else
- s->ibmr = 0;
- return s->ibmr;
- default:
- printf("%s: Bad register " REG_FMT "\n", __FUNCTION__, addr);
- break;
- }
- return 0;
-}
-
-static void pxa2xx_i2c_write(void *opaque, hwaddr addr,
- uint64_t value64, unsigned size)
-{
- PXA2xxI2CState *s = (PXA2xxI2CState *) opaque;
- uint32_t value = value64;
- int ack;
-
- addr -= s->offset;
- switch (addr) {
- case ICR:
- s->control = value & 0xfff7;
- if ((value & (1 << 3)) && (value & (1 << 6))) { /* TB and IUE */
- /* TODO: slave mode */
- if (value & (1 << 0)) { /* START condition */
- if (s->data & 1)
- s->status |= 1 << 0; /* set RWM */
- else
- s->status &= ~(1 << 0); /* clear RWM */
- ack = !i2c_start_transfer(s->bus, s->data >> 1, s->data & 1);
- } else {
- if (s->status & (1 << 0)) { /* RWM */
- s->data = i2c_recv(s->bus);
- if (value & (1 << 2)) /* ACKNAK */
- i2c_nack(s->bus);
- ack = 1;
- } else
- ack = !i2c_send(s->bus, s->data);
- }
-
- if (value & (1 << 1)) /* STOP condition */
- i2c_end_transfer(s->bus);
-
- if (ack) {
- if (value & (1 << 0)) /* START condition */
- s->status |= 1 << 6; /* set ITE */
- else
- if (s->status & (1 << 0)) /* RWM */
- s->status |= 1 << 7; /* set IRF */
- else
- s->status |= 1 << 6; /* set ITE */
- s->status &= ~(1 << 1); /* clear ACKNAK */
- } else {
- s->status |= 1 << 6; /* set ITE */
- s->status |= 1 << 10; /* set BED */
- s->status |= 1 << 1; /* set ACKNAK */
- }
- }
- if (!(value & (1 << 3)) && (value & (1 << 6))) /* !TB and IUE */
- if (value & (1 << 4)) /* MA */
- i2c_end_transfer(s->bus);
- pxa2xx_i2c_update(s);
- break;
-
- case ISR:
- s->status &= ~(value & 0x07f0);
- pxa2xx_i2c_update(s);
- break;
-
- case ISAR:
- i2c_set_slave_address(I2C_SLAVE(s->slave), value & 0x7f);
- break;
-
- case IDBR:
- s->data = value & 0xff;
- break;
-
- default:
- printf("%s: Bad register " REG_FMT "\n", __FUNCTION__, addr);
- }
-}
-
-static const MemoryRegionOps pxa2xx_i2c_ops = {
- .read = pxa2xx_i2c_read,
- .write = pxa2xx_i2c_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static const VMStateDescription vmstate_pxa2xx_i2c_slave = {
- .name = "pxa2xx_i2c_slave",
- .version_id = 1,
- .minimum_version_id = 1,
- .fields = (VMStateField[]) {
- VMSTATE_I2C_SLAVE(parent_obj, PXA2xxI2CSlaveState),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static const VMStateDescription vmstate_pxa2xx_i2c = {
- .name = "pxa2xx_i2c",
- .version_id = 1,
- .minimum_version_id = 1,
- .fields = (VMStateField[]) {
- VMSTATE_UINT16(control, PXA2xxI2CState),
- VMSTATE_UINT16(status, PXA2xxI2CState),
- VMSTATE_UINT8(ibmr, PXA2xxI2CState),
- VMSTATE_UINT8(data, PXA2xxI2CState),
- VMSTATE_STRUCT_POINTER(slave, PXA2xxI2CState,
- vmstate_pxa2xx_i2c_slave, PXA2xxI2CSlaveState),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static int pxa2xx_i2c_slave_init(I2CSlave *i2c)
-{
- /* Nothing to do. */
- return 0;
-}
-
-static void pxa2xx_i2c_slave_class_init(ObjectClass *klass, void *data)
-{
- I2CSlaveClass *k = I2C_SLAVE_CLASS(klass);
-
- k->init = pxa2xx_i2c_slave_init;
- k->event = pxa2xx_i2c_event;
- k->recv = pxa2xx_i2c_rx;
- k->send = pxa2xx_i2c_tx;
-}
-
-static const TypeInfo pxa2xx_i2c_slave_info = {
- .name = TYPE_PXA2XX_I2C_SLAVE,
- .parent = TYPE_I2C_SLAVE,
- .instance_size = sizeof(PXA2xxI2CSlaveState),
- .class_init = pxa2xx_i2c_slave_class_init,
-};
-
-PXA2xxI2CState *pxa2xx_i2c_init(hwaddr base,
- qemu_irq irq, uint32_t region_size)
-{
- DeviceState *dev;
- SysBusDevice *i2c_dev;
- PXA2xxI2CState *s;
- I2CBus *i2cbus;
-
- dev = qdev_create(NULL, TYPE_PXA2XX_I2C);
- qdev_prop_set_uint32(dev, "size", region_size + 1);
- qdev_prop_set_uint32(dev, "offset", base & region_size);
- qdev_init_nofail(dev);
-
- i2c_dev = SYS_BUS_DEVICE(dev);
- sysbus_mmio_map(i2c_dev, 0, base & ~region_size);
- sysbus_connect_irq(i2c_dev, 0, irq);
-
- s = PXA2XX_I2C(i2c_dev);
- /* FIXME: Should the slave device really be on a separate bus? */
- i2cbus = i2c_init_bus(dev, "dummy");
- dev = i2c_create_slave(i2cbus, TYPE_PXA2XX_I2C_SLAVE, 0);
- s->slave = PXA2XX_I2C_SLAVE(dev);
- s->slave->host = s;
-
- return s;
-}
-
-static int pxa2xx_i2c_initfn(SysBusDevice *sbd)
-{
- DeviceState *dev = DEVICE(sbd);
- PXA2xxI2CState *s = PXA2XX_I2C(dev);
-
- s->bus = i2c_init_bus(dev, "i2c");
-
- memory_region_init_io(&s->iomem, OBJECT(s), &pxa2xx_i2c_ops, s,
- "pxa2xx-i2c", s->region_size);
- sysbus_init_mmio(sbd, &s->iomem);
- sysbus_init_irq(sbd, &s->irq);
-
- return 0;
-}
-
-I2CBus *pxa2xx_i2c_bus(PXA2xxI2CState *s)
-{
- return s->bus;
-}
-
-static Property pxa2xx_i2c_properties[] = {
- DEFINE_PROP_UINT32("size", PXA2xxI2CState, region_size, 0x10000),
- DEFINE_PROP_UINT32("offset", PXA2xxI2CState, offset, 0),
- DEFINE_PROP_END_OF_LIST(),
-};
-
-static void pxa2xx_i2c_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
-
- k->init = pxa2xx_i2c_initfn;
- dc->desc = "PXA2xx I2C Bus Controller";
- dc->vmsd = &vmstate_pxa2xx_i2c;
- dc->props = pxa2xx_i2c_properties;
-}
-
-static const TypeInfo pxa2xx_i2c_info = {
- .name = TYPE_PXA2XX_I2C,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(PXA2xxI2CState),
- .class_init = pxa2xx_i2c_class_init,
-};
-
-/* PXA Inter-IC Sound Controller */
-static void pxa2xx_i2s_reset(PXA2xxI2SState *i2s)
-{
- i2s->rx_len = 0;
- i2s->tx_len = 0;
- i2s->fifo_len = 0;
- i2s->clk = 0x1a;
- i2s->control[0] = 0x00;
- i2s->control[1] = 0x00;
- i2s->status = 0x00;
- i2s->mask = 0x00;
-}
-
-#define SACR_TFTH(val) ((val >> 8) & 0xf)
-#define SACR_RFTH(val) ((val >> 12) & 0xf)
-#define SACR_DREC(val) (val & (1 << 3))
-#define SACR_DPRL(val) (val & (1 << 4))
-
-static inline void pxa2xx_i2s_update(PXA2xxI2SState *i2s)
-{
- int rfs, tfs;
- rfs = SACR_RFTH(i2s->control[0]) < i2s->rx_len &&
- !SACR_DREC(i2s->control[1]);
- tfs = (i2s->tx_len || i2s->fifo_len < SACR_TFTH(i2s->control[0])) &&
- i2s->enable && !SACR_DPRL(i2s->control[1]);
-
- qemu_set_irq(i2s->rx_dma, rfs);
- qemu_set_irq(i2s->tx_dma, tfs);
-
- i2s->status &= 0xe0;
- if (i2s->fifo_len < 16 || !i2s->enable)
- i2s->status |= 1 << 0; /* TNF */
- if (i2s->rx_len)
- i2s->status |= 1 << 1; /* RNE */
- if (i2s->enable)
- i2s->status |= 1 << 2; /* BSY */
- if (tfs)
- i2s->status |= 1 << 3; /* TFS */
- if (rfs)
- i2s->status |= 1 << 4; /* RFS */
- if (!(i2s->tx_len && i2s->enable))
- i2s->status |= i2s->fifo_len << 8; /* TFL */
- i2s->status |= MAX(i2s->rx_len, 0xf) << 12; /* RFL */
-
- qemu_set_irq(i2s->irq, i2s->status & i2s->mask);
-}
-
-#define SACR0 0x00 /* Serial Audio Global Control register */
-#define SACR1 0x04 /* Serial Audio I2S/MSB-Justified Control register */
-#define SASR0 0x0c /* Serial Audio Interface and FIFO Status register */
-#define SAIMR 0x14 /* Serial Audio Interrupt Mask register */
-#define SAICR 0x18 /* Serial Audio Interrupt Clear register */
-#define SADIV 0x60 /* Serial Audio Clock Divider register */
-#define SADR 0x80 /* Serial Audio Data register */
-
-static uint64_t pxa2xx_i2s_read(void *opaque, hwaddr addr,
- unsigned size)
-{
- PXA2xxI2SState *s = (PXA2xxI2SState *) opaque;
-
- switch (addr) {
- case SACR0:
- return s->control[0];
- case SACR1:
- return s->control[1];
- case SASR0:
- return s->status;
- case SAIMR:
- return s->mask;
- case SAICR:
- return 0;
- case SADIV:
- return s->clk;
- case SADR:
- if (s->rx_len > 0) {
- s->rx_len --;
- pxa2xx_i2s_update(s);
- return s->codec_in(s->opaque);
- }
- return 0;
- default:
- printf("%s: Bad register " REG_FMT "\n", __FUNCTION__, addr);
- break;
- }
- return 0;
-}
-
-static void pxa2xx_i2s_write(void *opaque, hwaddr addr,
- uint64_t value, unsigned size)
-{
- PXA2xxI2SState *s = (PXA2xxI2SState *) opaque;
- uint32_t *sample;
-
- switch (addr) {
- case SACR0:
- if (value & (1 << 3)) /* RST */
- pxa2xx_i2s_reset(s);
- s->control[0] = value & 0xff3d;
- if (!s->enable && (value & 1) && s->tx_len) { /* ENB */
- for (sample = s->fifo; s->fifo_len > 0; s->fifo_len --, sample ++)
- s->codec_out(s->opaque, *sample);
- s->status &= ~(1 << 7); /* I2SOFF */
- }
- if (value & (1 << 4)) /* EFWR */
- printf("%s: Attempt to use special function\n", __FUNCTION__);
- s->enable = (value & 9) == 1; /* ENB && !RST*/
- pxa2xx_i2s_update(s);
- break;
- case SACR1:
- s->control[1] = value & 0x0039;
- if (value & (1 << 5)) /* ENLBF */
- printf("%s: Attempt to use loopback function\n", __FUNCTION__);
- if (value & (1 << 4)) /* DPRL */
- s->fifo_len = 0;
- pxa2xx_i2s_update(s);
- break;
- case SAIMR:
- s->mask = value & 0x0078;
- pxa2xx_i2s_update(s);
- break;
- case SAICR:
- s->status &= ~(value & (3 << 5));
- pxa2xx_i2s_update(s);
- break;
- case SADIV:
- s->clk = value & 0x007f;
- break;
- case SADR:
- if (s->tx_len && s->enable) {
- s->tx_len --;
- pxa2xx_i2s_update(s);
- s->codec_out(s->opaque, value);
- } else if (s->fifo_len < 16) {
- s->fifo[s->fifo_len ++] = value;
- pxa2xx_i2s_update(s);
- }
- break;
- default:
- printf("%s: Bad register " REG_FMT "\n", __FUNCTION__, addr);
- }
-}
-
-static const MemoryRegionOps pxa2xx_i2s_ops = {
- .read = pxa2xx_i2s_read,
- .write = pxa2xx_i2s_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static const VMStateDescription vmstate_pxa2xx_i2s = {
- .name = "pxa2xx_i2s",
- .version_id = 0,
- .minimum_version_id = 0,
- .fields = (VMStateField[]) {
- VMSTATE_UINT32_ARRAY(control, PXA2xxI2SState, 2),
- VMSTATE_UINT32(status, PXA2xxI2SState),
- VMSTATE_UINT32(mask, PXA2xxI2SState),
- VMSTATE_UINT32(clk, PXA2xxI2SState),
- VMSTATE_INT32(enable, PXA2xxI2SState),
- VMSTATE_INT32(rx_len, PXA2xxI2SState),
- VMSTATE_INT32(tx_len, PXA2xxI2SState),
- VMSTATE_INT32(fifo_len, PXA2xxI2SState),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static void pxa2xx_i2s_data_req(void *opaque, int tx, int rx)
-{
- PXA2xxI2SState *s = (PXA2xxI2SState *) opaque;
- uint32_t *sample;
-
- /* Signal FIFO errors */
- if (s->enable && s->tx_len)
- s->status |= 1 << 5; /* TUR */
- if (s->enable && s->rx_len)
- s->status |= 1 << 6; /* ROR */
-
- /* Should be tx - MIN(tx, s->fifo_len) but we don't really need to
- * handle the cases where it makes a difference. */
- s->tx_len = tx - s->fifo_len;
- s->rx_len = rx;
- /* Note that is s->codec_out wasn't set, we wouldn't get called. */
- if (s->enable)
- for (sample = s->fifo; s->fifo_len; s->fifo_len --, sample ++)
- s->codec_out(s->opaque, *sample);
- pxa2xx_i2s_update(s);
-}
-
-static PXA2xxI2SState *pxa2xx_i2s_init(MemoryRegion *sysmem,
- hwaddr base,
- qemu_irq irq, qemu_irq rx_dma, qemu_irq tx_dma)
-{
- PXA2xxI2SState *s = g_new0(PXA2xxI2SState, 1);
-
- s->irq = irq;
- s->rx_dma = rx_dma;
- s->tx_dma = tx_dma;
- s->data_req = pxa2xx_i2s_data_req;
-
- pxa2xx_i2s_reset(s);
-
- memory_region_init_io(&s->iomem, NULL, &pxa2xx_i2s_ops, s,
- "pxa2xx-i2s", 0x100000);
- memory_region_add_subregion(sysmem, base, &s->iomem);
-
- vmstate_register(NULL, base, &vmstate_pxa2xx_i2s, s);
-
- return s;
-}
-
-/* PXA Fast Infra-red Communications Port */
-#define TYPE_PXA2XX_FIR "pxa2xx-fir"
-#define PXA2XX_FIR(obj) OBJECT_CHECK(PXA2xxFIrState, (obj), TYPE_PXA2XX_FIR)
-
-struct PXA2xxFIrState {
- /*< private >*/
- SysBusDevice parent_obj;
- /*< public >*/
-
- MemoryRegion iomem;
- qemu_irq irq;
- qemu_irq rx_dma;
- qemu_irq tx_dma;
- uint32_t enable;
- CharDriverState *chr;
-
- uint8_t control[3];
- uint8_t status[2];
-
- uint32_t rx_len;
- uint32_t rx_start;
- uint8_t rx_fifo[64];
-};
-
-static void pxa2xx_fir_reset(DeviceState *d)
-{
- PXA2xxFIrState *s = PXA2XX_FIR(d);
-
- s->control[0] = 0x00;
- s->control[1] = 0x00;
- s->control[2] = 0x00;
- s->status[0] = 0x00;
- s->status[1] = 0x00;
- s->enable = 0;
-}
-
-static inline void pxa2xx_fir_update(PXA2xxFIrState *s)
-{
- static const int tresh[4] = { 8, 16, 32, 0 };
- int intr = 0;
- if ((s->control[0] & (1 << 4)) && /* RXE */
- s->rx_len >= tresh[s->control[2] & 3]) /* TRIG */
- s->status[0] |= 1 << 4; /* RFS */
- else
- s->status[0] &= ~(1 << 4); /* RFS */
- if (s->control[0] & (1 << 3)) /* TXE */
- s->status[0] |= 1 << 3; /* TFS */
- else
- s->status[0] &= ~(1 << 3); /* TFS */
- if (s->rx_len)
- s->status[1] |= 1 << 2; /* RNE */
- else
- s->status[1] &= ~(1 << 2); /* RNE */
- if (s->control[0] & (1 << 4)) /* RXE */
- s->status[1] |= 1 << 0; /* RSY */
- else
- s->status[1] &= ~(1 << 0); /* RSY */
-
- intr |= (s->control[0] & (1 << 5)) && /* RIE */
- (s->status[0] & (1 << 4)); /* RFS */
- intr |= (s->control[0] & (1 << 6)) && /* TIE */
- (s->status[0] & (1 << 3)); /* TFS */
- intr |= (s->control[2] & (1 << 4)) && /* TRAIL */
- (s->status[0] & (1 << 6)); /* EOC */
- intr |= (s->control[0] & (1 << 2)) && /* TUS */
- (s->status[0] & (1 << 1)); /* TUR */
- intr |= s->status[0] & 0x25; /* FRE, RAB, EIF */
-
- qemu_set_irq(s->rx_dma, (s->status[0] >> 4) & 1);
- qemu_set_irq(s->tx_dma, (s->status[0] >> 3) & 1);
-
- qemu_set_irq(s->irq, intr && s->enable);
-}
-
-#define ICCR0 0x00 /* FICP Control register 0 */
-#define ICCR1 0x04 /* FICP Control register 1 */
-#define ICCR2 0x08 /* FICP Control register 2 */
-#define ICDR 0x0c /* FICP Data register */
-#define ICSR0 0x14 /* FICP Status register 0 */
-#define ICSR1 0x18 /* FICP Status register 1 */
-#define ICFOR 0x1c /* FICP FIFO Occupancy Status register */
-
-static uint64_t pxa2xx_fir_read(void *opaque, hwaddr addr,
- unsigned size)
-{
- PXA2xxFIrState *s = (PXA2xxFIrState *) opaque;
- uint8_t ret;
-
- switch (addr) {
- case ICCR0:
- return s->control[0];
- case ICCR1:
- return s->control[1];
- case ICCR2:
- return s->control[2];
- case ICDR:
- s->status[0] &= ~0x01;
- s->status[1] &= ~0x72;
- if (s->rx_len) {
- s->rx_len --;
- ret = s->rx_fifo[s->rx_start ++];
- s->rx_start &= 63;
- pxa2xx_fir_update(s);
- return ret;
- }
- printf("%s: Rx FIFO underrun.\n", __FUNCTION__);
- break;
- case ICSR0:
- return s->status[0];
- case ICSR1:
- return s->status[1] | (1 << 3); /* TNF */
- case ICFOR:
- return s->rx_len;
- default:
- printf("%s: Bad register " REG_FMT "\n", __FUNCTION__, addr);
- break;
- }
- return 0;
-}
-
-static void pxa2xx_fir_write(void *opaque, hwaddr addr,
- uint64_t value64, unsigned size)
-{
- PXA2xxFIrState *s = (PXA2xxFIrState *) opaque;
- uint32_t value = value64;
- uint8_t ch;
-
- switch (addr) {
- case ICCR0:
- s->control[0] = value;
- if (!(value & (1 << 4))) /* RXE */
- s->rx_len = s->rx_start = 0;
- if (!(value & (1 << 3))) { /* TXE */
- /* Nop */
- }
- s->enable = value & 1; /* ITR */
- if (!s->enable)
- s->status[0] = 0;
- pxa2xx_fir_update(s);
- break;
- case ICCR1:
- s->control[1] = value;
- break;
- case ICCR2:
- s->control[2] = value & 0x3f;
- pxa2xx_fir_update(s);
- break;
- case ICDR:
- if (s->control[2] & (1 << 2)) /* TXP */
- ch = value;
- else
- ch = ~value;
- if (s->chr && s->enable && (s->control[0] & (1 << 3))) /* TXE */
- qemu_chr_fe_write(s->chr, &ch, 1);
- break;
- case ICSR0:
- s->status[0] &= ~(value & 0x66);
- pxa2xx_fir_update(s);
- break;
- case ICFOR:
- break;
- default:
- printf("%s: Bad register " REG_FMT "\n", __FUNCTION__, addr);
- }
-}
-
-static const MemoryRegionOps pxa2xx_fir_ops = {
- .read = pxa2xx_fir_read,
- .write = pxa2xx_fir_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static int pxa2xx_fir_is_empty(void *opaque)
-{
- PXA2xxFIrState *s = (PXA2xxFIrState *) opaque;
- return (s->rx_len < 64);
-}
-
-static void pxa2xx_fir_rx(void *opaque, const uint8_t *buf, int size)
-{
- PXA2xxFIrState *s = (PXA2xxFIrState *) opaque;
- if (!(s->control[0] & (1 << 4))) /* RXE */
- return;
-
- while (size --) {
- s->status[1] |= 1 << 4; /* EOF */
- if (s->rx_len >= 64) {
- s->status[1] |= 1 << 6; /* ROR */
- break;
- }
-
- if (s->control[2] & (1 << 3)) /* RXP */
- s->rx_fifo[(s->rx_start + s->rx_len ++) & 63] = *(buf ++);
- else
- s->rx_fifo[(s->rx_start + s->rx_len ++) & 63] = ~*(buf ++);
- }
-
- pxa2xx_fir_update(s);
-}
-
-static void pxa2xx_fir_event(void *opaque, int event)
-{
-}
-
-static void pxa2xx_fir_instance_init(Object *obj)
-{
- PXA2xxFIrState *s = PXA2XX_FIR(obj);
- SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
-
- memory_region_init_io(&s->iomem, obj, &pxa2xx_fir_ops, s,
- "pxa2xx-fir", 0x1000);
- sysbus_init_mmio(sbd, &s->iomem);
- sysbus_init_irq(sbd, &s->irq);
- sysbus_init_irq(sbd, &s->rx_dma);
- sysbus_init_irq(sbd, &s->tx_dma);
-}
-
-static void pxa2xx_fir_realize(DeviceState *dev, Error **errp)
-{
- PXA2xxFIrState *s = PXA2XX_FIR(dev);
-
- if (s->chr) {
- qemu_chr_fe_claim_no_fail(s->chr);
- qemu_chr_add_handlers(s->chr, pxa2xx_fir_is_empty,
- pxa2xx_fir_rx, pxa2xx_fir_event, s);
- }
-}
-
-static bool pxa2xx_fir_vmstate_validate(void *opaque, int version_id)
-{
- PXA2xxFIrState *s = opaque;
-
- return s->rx_start < ARRAY_SIZE(s->rx_fifo);
-}
-
-static const VMStateDescription pxa2xx_fir_vmsd = {
- .name = "pxa2xx-fir",
- .version_id = 1,
- .minimum_version_id = 1,
- .fields = (VMStateField[]) {
- VMSTATE_UINT32(enable, PXA2xxFIrState),
- VMSTATE_UINT8_ARRAY(control, PXA2xxFIrState, 3),
- VMSTATE_UINT8_ARRAY(status, PXA2xxFIrState, 2),
- VMSTATE_UINT32(rx_len, PXA2xxFIrState),
- VMSTATE_UINT32(rx_start, PXA2xxFIrState),
- VMSTATE_VALIDATE("fifo is 64 bytes", pxa2xx_fir_vmstate_validate),
- VMSTATE_UINT8_ARRAY(rx_fifo, PXA2xxFIrState, 64),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static Property pxa2xx_fir_properties[] = {
- DEFINE_PROP_CHR("chardev", PXA2xxFIrState, chr),
- DEFINE_PROP_END_OF_LIST(),
-};
-
-static void pxa2xx_fir_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
-
- dc->realize = pxa2xx_fir_realize;
- dc->vmsd = &pxa2xx_fir_vmsd;
- dc->props = pxa2xx_fir_properties;
- dc->reset = pxa2xx_fir_reset;
-}
-
-static const TypeInfo pxa2xx_fir_info = {
- .name = TYPE_PXA2XX_FIR,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(PXA2xxFIrState),
- .class_init = pxa2xx_fir_class_init,
- .instance_init = pxa2xx_fir_instance_init,
-};
-
-static PXA2xxFIrState *pxa2xx_fir_init(MemoryRegion *sysmem,
- hwaddr base,
- qemu_irq irq, qemu_irq rx_dma,
- qemu_irq tx_dma,
- CharDriverState *chr)
-{
- DeviceState *dev;
- SysBusDevice *sbd;
-
- dev = qdev_create(NULL, TYPE_PXA2XX_FIR);
- qdev_prop_set_chr(dev, "chardev", chr);
- qdev_init_nofail(dev);
- sbd = SYS_BUS_DEVICE(dev);
- sysbus_mmio_map(sbd, 0, base);
- sysbus_connect_irq(sbd, 0, irq);
- sysbus_connect_irq(sbd, 1, rx_dma);
- sysbus_connect_irq(sbd, 2, tx_dma);
- return PXA2XX_FIR(dev);
-}
-
-static void pxa2xx_reset(void *opaque, int line, int level)
-{
- PXA2xxState *s = (PXA2xxState *) opaque;
-
- if (level && (s->pm_regs[PCFR >> 2] & 0x10)) { /* GPR_EN */
- cpu_reset(CPU(s->cpu));
- /* TODO: reset peripherals */
- }
-}
-
-/* Initialise a PXA270 integrated chip (ARM based core). */
-PXA2xxState *pxa270_init(MemoryRegion *address_space,
- unsigned int sdram_size, const char *revision)
-{
- PXA2xxState *s;
- int i;
- DriveInfo *dinfo;
- s = g_new0(PXA2xxState, 1);
-
- if (revision && strncmp(revision, "pxa27", 5)) {
- fprintf(stderr, "Machine requires a PXA27x processor.\n");
- exit(1);
- }
- if (!revision)
- revision = "pxa270";
-
- s->cpu = cpu_arm_init(revision);
- if (s->cpu == NULL) {
- fprintf(stderr, "Unable to find CPU definition\n");
- exit(1);
- }
- s->reset = qemu_allocate_irq(pxa2xx_reset, s, 0);
-
- /* SDRAM & Internal Memory Storage */
- memory_region_init_ram(&s->sdram, NULL, "pxa270.sdram", sdram_size,
- &error_fatal);
- vmstate_register_ram_global(&s->sdram);
- memory_region_add_subregion(address_space, PXA2XX_SDRAM_BASE, &s->sdram);
- memory_region_init_ram(&s->internal, NULL, "pxa270.internal", 0x40000,
- &error_fatal);
- vmstate_register_ram_global(&s->internal);
- memory_region_add_subregion(address_space, PXA2XX_INTERNAL_BASE,
- &s->internal);
-
- s->pic = pxa2xx_pic_init(0x40d00000, s->cpu);
-
- s->dma = pxa27x_dma_init(0x40000000,
- qdev_get_gpio_in(s->pic, PXA2XX_PIC_DMA));
-
- sysbus_create_varargs("pxa27x-timer", 0x40a00000,
- qdev_get_gpio_in(s->pic, PXA2XX_PIC_OST_0 + 0),
- qdev_get_gpio_in(s->pic, PXA2XX_PIC_OST_0 + 1),
- qdev_get_gpio_in(s->pic, PXA2XX_PIC_OST_0 + 2),
- qdev_get_gpio_in(s->pic, PXA2XX_PIC_OST_0 + 3),
- qdev_get_gpio_in(s->pic, PXA27X_PIC_OST_4_11),
- NULL);
-
- s->gpio = pxa2xx_gpio_init(0x40e00000, s->cpu, s->pic, 121);
-
- dinfo = drive_get(IF_SD, 0, 0);
- if (!dinfo) {
- fprintf(stderr, "qemu: missing SecureDigital device\n");
- exit(1);
- }
- s->mmc = pxa2xx_mmci_init(address_space, 0x41100000,
- blk_by_legacy_dinfo(dinfo),
- qdev_get_gpio_in(s->pic, PXA2XX_PIC_MMC),
- qdev_get_gpio_in(s->dma, PXA2XX_RX_RQ_MMCI),
- qdev_get_gpio_in(s->dma, PXA2XX_TX_RQ_MMCI));
-
- for (i = 0; pxa270_serial[i].io_base; i++) {
- if (serial_hds[i]) {
- serial_mm_init(address_space, pxa270_serial[i].io_base, 2,
- qdev_get_gpio_in(s->pic, pxa270_serial[i].irqn),
- 14857000 / 16, serial_hds[i],
- DEVICE_NATIVE_ENDIAN);
- } else {
- break;
- }
- }
- if (serial_hds[i])
- s->fir = pxa2xx_fir_init(address_space, 0x40800000,
- qdev_get_gpio_in(s->pic, PXA2XX_PIC_ICP),
- qdev_get_gpio_in(s->dma, PXA2XX_RX_RQ_ICP),
- qdev_get_gpio_in(s->dma, PXA2XX_TX_RQ_ICP),
- serial_hds[i]);
-
- s->lcd = pxa2xx_lcdc_init(address_space, 0x44000000,
- qdev_get_gpio_in(s->pic, PXA2XX_PIC_LCD));
-
- s->cm_base = 0x41300000;
- s->cm_regs[CCCR >> 2] = 0x02000210; /* 416.0 MHz */
- s->clkcfg = 0x00000009; /* Turbo mode active */
- memory_region_init_io(&s->cm_iomem, NULL, &pxa2xx_cm_ops, s, "pxa2xx-cm", 0x1000);
- memory_region_add_subregion(address_space, s->cm_base, &s->cm_iomem);
- vmstate_register(NULL, 0, &vmstate_pxa2xx_cm, s);
-
- pxa2xx_setup_cp14(s);
-
- s->mm_base = 0x48000000;
- s->mm_regs[MDMRS >> 2] = 0x00020002;
- s->mm_regs[MDREFR >> 2] = 0x03ca4000;
- s->mm_regs[MECR >> 2] = 0x00000001; /* Two PC Card sockets */
- memory_region_init_io(&s->mm_iomem, NULL, &pxa2xx_mm_ops, s, "pxa2xx-mm", 0x1000);
- memory_region_add_subregion(address_space, s->mm_base, &s->mm_iomem);
- vmstate_register(NULL, 0, &vmstate_pxa2xx_mm, s);
-
- s->pm_base = 0x40f00000;
- memory_region_init_io(&s->pm_iomem, NULL, &pxa2xx_pm_ops, s, "pxa2xx-pm", 0x100);
- memory_region_add_subregion(address_space, s->pm_base, &s->pm_iomem);
- vmstate_register(NULL, 0, &vmstate_pxa2xx_pm, s);
-
- for (i = 0; pxa27x_ssp[i].io_base; i ++);
- s->ssp = g_new0(SSIBus *, i);
- for (i = 0; pxa27x_ssp[i].io_base; i ++) {
- DeviceState *dev;
- dev = sysbus_create_simple(TYPE_PXA2XX_SSP, pxa27x_ssp[i].io_base,
- qdev_get_gpio_in(s->pic, pxa27x_ssp[i].irqn));
- s->ssp[i] = (SSIBus *)qdev_get_child_bus(dev, "ssi");
- }
-
- if (usb_enabled()) {
- sysbus_create_simple("sysbus-ohci", 0x4c000000,
- qdev_get_gpio_in(s->pic, PXA2XX_PIC_USBH1));
- }
-
- s->pcmcia[0] = pxa2xx_pcmcia_init(address_space, 0x20000000);
- s->pcmcia[1] = pxa2xx_pcmcia_init(address_space, 0x30000000);
-
- sysbus_create_simple(TYPE_PXA2XX_RTC, 0x40900000,
- qdev_get_gpio_in(s->pic, PXA2XX_PIC_RTCALARM));
-
- s->i2c[0] = pxa2xx_i2c_init(0x40301600,
- qdev_get_gpio_in(s->pic, PXA2XX_PIC_I2C), 0xffff);
- s->i2c[1] = pxa2xx_i2c_init(0x40f00100,
- qdev_get_gpio_in(s->pic, PXA2XX_PIC_PWRI2C), 0xff);
-
- s->i2s = pxa2xx_i2s_init(address_space, 0x40400000,
- qdev_get_gpio_in(s->pic, PXA2XX_PIC_I2S),
- qdev_get_gpio_in(s->dma, PXA2XX_RX_RQ_I2S),
- qdev_get_gpio_in(s->dma, PXA2XX_TX_RQ_I2S));
-
- s->kp = pxa27x_keypad_init(address_space, 0x41500000,
- qdev_get_gpio_in(s->pic, PXA2XX_PIC_KEYPAD));
-
- /* GPIO1 resets the processor */
- /* The handler can be overridden by board-specific code */
- qdev_connect_gpio_out(s->gpio, 1, s->reset);
- return s;
-}
-
-/* Initialise a PXA255 integrated chip (ARM based core). */
-PXA2xxState *pxa255_init(MemoryRegion *address_space, unsigned int sdram_size)
-{
- PXA2xxState *s;
- int i;
- DriveInfo *dinfo;
-
- s = g_new0(PXA2xxState, 1);
-
- s->cpu = cpu_arm_init("pxa255");
- if (s->cpu == NULL) {
- fprintf(stderr, "Unable to find CPU definition\n");
- exit(1);
- }
- s->reset = qemu_allocate_irq(pxa2xx_reset, s, 0);
-
- /* SDRAM & Internal Memory Storage */
- memory_region_init_ram(&s->sdram, NULL, "pxa255.sdram", sdram_size,
- &error_fatal);
- vmstate_register_ram_global(&s->sdram);
- memory_region_add_subregion(address_space, PXA2XX_SDRAM_BASE, &s->sdram);
- memory_region_init_ram(&s->internal, NULL, "pxa255.internal",
- PXA2XX_INTERNAL_SIZE, &error_fatal);
- vmstate_register_ram_global(&s->internal);
- memory_region_add_subregion(address_space, PXA2XX_INTERNAL_BASE,
- &s->internal);
-
- s->pic = pxa2xx_pic_init(0x40d00000, s->cpu);
-
- s->dma = pxa255_dma_init(0x40000000,
- qdev_get_gpio_in(s->pic, PXA2XX_PIC_DMA));
-
- sysbus_create_varargs("pxa25x-timer", 0x40a00000,
- qdev_get_gpio_in(s->pic, PXA2XX_PIC_OST_0 + 0),
- qdev_get_gpio_in(s->pic, PXA2XX_PIC_OST_0 + 1),
- qdev_get_gpio_in(s->pic, PXA2XX_PIC_OST_0 + 2),
- qdev_get_gpio_in(s->pic, PXA2XX_PIC_OST_0 + 3),
- NULL);
-
- s->gpio = pxa2xx_gpio_init(0x40e00000, s->cpu, s->pic, 85);
-
- dinfo = drive_get(IF_SD, 0, 0);
- if (!dinfo) {
- fprintf(stderr, "qemu: missing SecureDigital device\n");
- exit(1);
- }
- s->mmc = pxa2xx_mmci_init(address_space, 0x41100000,
- blk_by_legacy_dinfo(dinfo),
- qdev_get_gpio_in(s->pic, PXA2XX_PIC_MMC),
- qdev_get_gpio_in(s->dma, PXA2XX_RX_RQ_MMCI),
- qdev_get_gpio_in(s->dma, PXA2XX_TX_RQ_MMCI));
-
- for (i = 0; pxa255_serial[i].io_base; i++) {
- if (serial_hds[i]) {
- serial_mm_init(address_space, pxa255_serial[i].io_base, 2,
- qdev_get_gpio_in(s->pic, pxa255_serial[i].irqn),
- 14745600 / 16, serial_hds[i],
- DEVICE_NATIVE_ENDIAN);
- } else {
- break;
- }
- }
- if (serial_hds[i])
- s->fir = pxa2xx_fir_init(address_space, 0x40800000,
- qdev_get_gpio_in(s->pic, PXA2XX_PIC_ICP),
- qdev_get_gpio_in(s->dma, PXA2XX_RX_RQ_ICP),
- qdev_get_gpio_in(s->dma, PXA2XX_TX_RQ_ICP),
- serial_hds[i]);
-
- s->lcd = pxa2xx_lcdc_init(address_space, 0x44000000,
- qdev_get_gpio_in(s->pic, PXA2XX_PIC_LCD));
-
- s->cm_base = 0x41300000;
- s->cm_regs[CCCR >> 2] = 0x02000210; /* 416.0 MHz */
- s->clkcfg = 0x00000009; /* Turbo mode active */
- memory_region_init_io(&s->cm_iomem, NULL, &pxa2xx_cm_ops, s, "pxa2xx-cm", 0x1000);
- memory_region_add_subregion(address_space, s->cm_base, &s->cm_iomem);
- vmstate_register(NULL, 0, &vmstate_pxa2xx_cm, s);
-
- pxa2xx_setup_cp14(s);
-
- s->mm_base = 0x48000000;
- s->mm_regs[MDMRS >> 2] = 0x00020002;
- s->mm_regs[MDREFR >> 2] = 0x03ca4000;
- s->mm_regs[MECR >> 2] = 0x00000001; /* Two PC Card sockets */
- memory_region_init_io(&s->mm_iomem, NULL, &pxa2xx_mm_ops, s, "pxa2xx-mm", 0x1000);
- memory_region_add_subregion(address_space, s->mm_base, &s->mm_iomem);
- vmstate_register(NULL, 0, &vmstate_pxa2xx_mm, s);
-
- s->pm_base = 0x40f00000;
- memory_region_init_io(&s->pm_iomem, NULL, &pxa2xx_pm_ops, s, "pxa2xx-pm", 0x100);
- memory_region_add_subregion(address_space, s->pm_base, &s->pm_iomem);
- vmstate_register(NULL, 0, &vmstate_pxa2xx_pm, s);
-
- for (i = 0; pxa255_ssp[i].io_base; i ++);
- s->ssp = g_new0(SSIBus *, i);
- for (i = 0; pxa255_ssp[i].io_base; i ++) {
- DeviceState *dev;
- dev = sysbus_create_simple(TYPE_PXA2XX_SSP, pxa255_ssp[i].io_base,
- qdev_get_gpio_in(s->pic, pxa255_ssp[i].irqn));
- s->ssp[i] = (SSIBus *)qdev_get_child_bus(dev, "ssi");
- }
-
- if (usb_enabled()) {
- sysbus_create_simple("sysbus-ohci", 0x4c000000,
- qdev_get_gpio_in(s->pic, PXA2XX_PIC_USBH1));
- }
-
- s->pcmcia[0] = pxa2xx_pcmcia_init(address_space, 0x20000000);
- s->pcmcia[1] = pxa2xx_pcmcia_init(address_space, 0x30000000);
-
- sysbus_create_simple(TYPE_PXA2XX_RTC, 0x40900000,
- qdev_get_gpio_in(s->pic, PXA2XX_PIC_RTCALARM));
-
- s->i2c[0] = pxa2xx_i2c_init(0x40301600,
- qdev_get_gpio_in(s->pic, PXA2XX_PIC_I2C), 0xffff);
- s->i2c[1] = pxa2xx_i2c_init(0x40f00100,
- qdev_get_gpio_in(s->pic, PXA2XX_PIC_PWRI2C), 0xff);
-
- s->i2s = pxa2xx_i2s_init(address_space, 0x40400000,
- qdev_get_gpio_in(s->pic, PXA2XX_PIC_I2S),
- qdev_get_gpio_in(s->dma, PXA2XX_RX_RQ_I2S),
- qdev_get_gpio_in(s->dma, PXA2XX_TX_RQ_I2S));
-
- /* GPIO1 resets the processor */
- /* The handler can be overridden by board-specific code */
- qdev_connect_gpio_out(s->gpio, 1, s->reset);
- return s;
-}
-
-static void pxa2xx_ssp_class_init(ObjectClass *klass, void *data)
-{
- SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
- DeviceClass *dc = DEVICE_CLASS(klass);
-
- sdc->init = pxa2xx_ssp_init;
- dc->reset = pxa2xx_ssp_reset;
- dc->vmsd = &vmstate_pxa2xx_ssp;
-}
-
-static const TypeInfo pxa2xx_ssp_info = {
- .name = TYPE_PXA2XX_SSP,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(PXA2xxSSPState),
- .class_init = pxa2xx_ssp_class_init,
-};
-
-static void pxa2xx_register_types(void)
-{
- type_register_static(&pxa2xx_i2c_slave_info);
- type_register_static(&pxa2xx_ssp_info);
- type_register_static(&pxa2xx_i2c_info);
- type_register_static(&pxa2xx_rtc_sysbus_info);
- type_register_static(&pxa2xx_fir_info);
-}
-
-type_init(pxa2xx_register_types)
diff --git a/qemu/hw/arm/pxa2xx_gpio.c b/qemu/hw/arm/pxa2xx_gpio.c
deleted file mode 100644
index 67e7e7094..000000000
--- a/qemu/hw/arm/pxa2xx_gpio.c
+++ /dev/null
@@ -1,357 +0,0 @@
-/*
- * Intel XScale PXA255/270 GPIO controller emulation.
- *
- * Copyright (c) 2006 Openedhand Ltd.
- * Written by Andrzej Zaborowski <balrog@zabor.org>
- *
- * This code is licensed under the GPL.
- */
-
-#include "qemu/osdep.h"
-#include "hw/hw.h"
-#include "hw/sysbus.h"
-#include "hw/arm/pxa.h"
-
-#define PXA2XX_GPIO_BANKS 4
-
-#define TYPE_PXA2XX_GPIO "pxa2xx-gpio"
-#define PXA2XX_GPIO(obj) \
- OBJECT_CHECK(PXA2xxGPIOInfo, (obj), TYPE_PXA2XX_GPIO)
-
-typedef struct PXA2xxGPIOInfo PXA2xxGPIOInfo;
-struct PXA2xxGPIOInfo {
- /*< private >*/
- SysBusDevice parent_obj;
- /*< public >*/
-
- MemoryRegion iomem;
- qemu_irq irq0, irq1, irqX;
- int lines;
- int ncpu;
- ARMCPU *cpu;
-
- /* XXX: GNU C vectors are more suitable */
- uint32_t ilevel[PXA2XX_GPIO_BANKS];
- uint32_t olevel[PXA2XX_GPIO_BANKS];
- uint32_t dir[PXA2XX_GPIO_BANKS];
- uint32_t rising[PXA2XX_GPIO_BANKS];
- uint32_t falling[PXA2XX_GPIO_BANKS];
- uint32_t status[PXA2XX_GPIO_BANKS];
- uint32_t gafr[PXA2XX_GPIO_BANKS * 2];
-
- uint32_t prev_level[PXA2XX_GPIO_BANKS];
- qemu_irq handler[PXA2XX_GPIO_BANKS * 32];
- qemu_irq read_notify;
-};
-
-static struct {
- enum {
- GPIO_NONE,
- GPLR,
- GPSR,
- GPCR,
- GPDR,
- GRER,
- GFER,
- GEDR,
- GAFR_L,
- GAFR_U,
- } reg;
- int bank;
-} pxa2xx_gpio_regs[0x200] = {
- [0 ... 0x1ff] = { GPIO_NONE, 0 },
-#define PXA2XX_REG(reg, a0, a1, a2, a3) \
- [a0] = { reg, 0 }, [a1] = { reg, 1 }, [a2] = { reg, 2 }, [a3] = { reg, 3 },
-
- PXA2XX_REG(GPLR, 0x000, 0x004, 0x008, 0x100)
- PXA2XX_REG(GPSR, 0x018, 0x01c, 0x020, 0x118)
- PXA2XX_REG(GPCR, 0x024, 0x028, 0x02c, 0x124)
- PXA2XX_REG(GPDR, 0x00c, 0x010, 0x014, 0x10c)
- PXA2XX_REG(GRER, 0x030, 0x034, 0x038, 0x130)
- PXA2XX_REG(GFER, 0x03c, 0x040, 0x044, 0x13c)
- PXA2XX_REG(GEDR, 0x048, 0x04c, 0x050, 0x148)
- PXA2XX_REG(GAFR_L, 0x054, 0x05c, 0x064, 0x06c)
- PXA2XX_REG(GAFR_U, 0x058, 0x060, 0x068, 0x070)
-};
-
-static void pxa2xx_gpio_irq_update(PXA2xxGPIOInfo *s)
-{
- if (s->status[0] & (1 << 0))
- qemu_irq_raise(s->irq0);
- else
- qemu_irq_lower(s->irq0);
-
- if (s->status[0] & (1 << 1))
- qemu_irq_raise(s->irq1);
- else
- qemu_irq_lower(s->irq1);
-
- if ((s->status[0] & ~3) | s->status[1] | s->status[2] | s->status[3])
- qemu_irq_raise(s->irqX);
- else
- qemu_irq_lower(s->irqX);
-}
-
-/* Bitmap of pins used as standby and sleep wake-up sources. */
-static const int pxa2xx_gpio_wake[PXA2XX_GPIO_BANKS] = {
- 0x8003fe1b, 0x002001fc, 0xec080000, 0x0012007f,
-};
-
-static void pxa2xx_gpio_set(void *opaque, int line, int level)
-{
- PXA2xxGPIOInfo *s = (PXA2xxGPIOInfo *) opaque;
- CPUState *cpu = CPU(s->cpu);
- int bank;
- uint32_t mask;
-
- if (line >= s->lines) {
- printf("%s: No GPIO pin %i\n", __FUNCTION__, line);
- return;
- }
-
- bank = line >> 5;
- mask = 1U << (line & 31);
-
- if (level) {
- s->status[bank] |= s->rising[bank] & mask &
- ~s->ilevel[bank] & ~s->dir[bank];
- s->ilevel[bank] |= mask;
- } else {
- s->status[bank] |= s->falling[bank] & mask &
- s->ilevel[bank] & ~s->dir[bank];
- s->ilevel[bank] &= ~mask;
- }
-
- if (s->status[bank] & mask)
- pxa2xx_gpio_irq_update(s);
-
- /* Wake-up GPIOs */
- if (cpu->halted && (mask & ~s->dir[bank] & pxa2xx_gpio_wake[bank])) {
- cpu_interrupt(cpu, CPU_INTERRUPT_EXITTB);
- }
-}
-
-static void pxa2xx_gpio_handler_update(PXA2xxGPIOInfo *s) {
- uint32_t level, diff;
- int i, bit, line;
- for (i = 0; i < PXA2XX_GPIO_BANKS; i ++) {
- level = s->olevel[i] & s->dir[i];
-
- for (diff = s->prev_level[i] ^ level; diff; diff ^= 1 << bit) {
- bit = ctz32(diff);
- line = bit + 32 * i;
- qemu_set_irq(s->handler[line], (level >> bit) & 1);
- }
-
- s->prev_level[i] = level;
- }
-}
-
-static uint64_t pxa2xx_gpio_read(void *opaque, hwaddr offset,
- unsigned size)
-{
- PXA2xxGPIOInfo *s = (PXA2xxGPIOInfo *) opaque;
- uint32_t ret;
- int bank;
- if (offset >= 0x200)
- return 0;
-
- bank = pxa2xx_gpio_regs[offset].bank;
- switch (pxa2xx_gpio_regs[offset].reg) {
- case GPDR: /* GPIO Pin-Direction registers */
- return s->dir[bank];
-
- case GPSR: /* GPIO Pin-Output Set registers */
- qemu_log_mask(LOG_GUEST_ERROR,
- "pxa2xx GPIO: read from write only register GPSR\n");
- return 0;
-
- case GPCR: /* GPIO Pin-Output Clear registers */
- qemu_log_mask(LOG_GUEST_ERROR,
- "pxa2xx GPIO: read from write only register GPCR\n");
- return 0;
-
- case GRER: /* GPIO Rising-Edge Detect Enable registers */
- return s->rising[bank];
-
- case GFER: /* GPIO Falling-Edge Detect Enable registers */
- return s->falling[bank];
-
- case GAFR_L: /* GPIO Alternate Function registers */
- return s->gafr[bank * 2];
-
- case GAFR_U: /* GPIO Alternate Function registers */
- return s->gafr[bank * 2 + 1];
-
- case GPLR: /* GPIO Pin-Level registers */
- ret = (s->olevel[bank] & s->dir[bank]) |
- (s->ilevel[bank] & ~s->dir[bank]);
- qemu_irq_raise(s->read_notify);
- return ret;
-
- case GEDR: /* GPIO Edge Detect Status registers */
- return s->status[bank];
-
- default:
- hw_error("%s: Bad offset " REG_FMT "\n", __FUNCTION__, offset);
- }
-
- return 0;
-}
-
-static void pxa2xx_gpio_write(void *opaque, hwaddr offset,
- uint64_t value, unsigned size)
-{
- PXA2xxGPIOInfo *s = (PXA2xxGPIOInfo *) opaque;
- int bank;
- if (offset >= 0x200)
- return;
-
- bank = pxa2xx_gpio_regs[offset].bank;
- switch (pxa2xx_gpio_regs[offset].reg) {
- case GPDR: /* GPIO Pin-Direction registers */
- s->dir[bank] = value;
- pxa2xx_gpio_handler_update(s);
- break;
-
- case GPSR: /* GPIO Pin-Output Set registers */
- s->olevel[bank] |= value;
- pxa2xx_gpio_handler_update(s);
- break;
-
- case GPCR: /* GPIO Pin-Output Clear registers */
- s->olevel[bank] &= ~value;
- pxa2xx_gpio_handler_update(s);
- break;
-
- case GRER: /* GPIO Rising-Edge Detect Enable registers */
- s->rising[bank] = value;
- break;
-
- case GFER: /* GPIO Falling-Edge Detect Enable registers */
- s->falling[bank] = value;
- break;
-
- case GAFR_L: /* GPIO Alternate Function registers */
- s->gafr[bank * 2] = value;
- break;
-
- case GAFR_U: /* GPIO Alternate Function registers */
- s->gafr[bank * 2 + 1] = value;
- break;
-
- case GEDR: /* GPIO Edge Detect Status registers */
- s->status[bank] &= ~value;
- pxa2xx_gpio_irq_update(s);
- break;
-
- default:
- hw_error("%s: Bad offset " REG_FMT "\n", __FUNCTION__, offset);
- }
-}
-
-static const MemoryRegionOps pxa_gpio_ops = {
- .read = pxa2xx_gpio_read,
- .write = pxa2xx_gpio_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-DeviceState *pxa2xx_gpio_init(hwaddr base,
- ARMCPU *cpu, DeviceState *pic, int lines)
-{
- CPUState *cs = CPU(cpu);
- DeviceState *dev;
-
- dev = qdev_create(NULL, TYPE_PXA2XX_GPIO);
- qdev_prop_set_int32(dev, "lines", lines);
- qdev_prop_set_int32(dev, "ncpu", cs->cpu_index);
- qdev_init_nofail(dev);
-
- sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0,
- qdev_get_gpio_in(pic, PXA2XX_PIC_GPIO_0));
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), 1,
- qdev_get_gpio_in(pic, PXA2XX_PIC_GPIO_1));
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), 2,
- qdev_get_gpio_in(pic, PXA2XX_PIC_GPIO_X));
-
- return dev;
-}
-
-static int pxa2xx_gpio_initfn(SysBusDevice *sbd)
-{
- DeviceState *dev = DEVICE(sbd);
- PXA2xxGPIOInfo *s = PXA2XX_GPIO(dev);
-
- s->cpu = ARM_CPU(qemu_get_cpu(s->ncpu));
-
- qdev_init_gpio_in(dev, pxa2xx_gpio_set, s->lines);
- qdev_init_gpio_out(dev, s->handler, s->lines);
-
- memory_region_init_io(&s->iomem, OBJECT(s), &pxa_gpio_ops, s, "pxa2xx-gpio", 0x1000);
- sysbus_init_mmio(sbd, &s->iomem);
- sysbus_init_irq(sbd, &s->irq0);
- sysbus_init_irq(sbd, &s->irq1);
- sysbus_init_irq(sbd, &s->irqX);
-
- return 0;
-}
-
-/*
- * Registers a callback to notify on GPLR reads. This normally
- * shouldn't be needed but it is used for the hack on Spitz machines.
- */
-void pxa2xx_gpio_read_notifier(DeviceState *dev, qemu_irq handler)
-{
- PXA2xxGPIOInfo *s = PXA2XX_GPIO(dev);
-
- s->read_notify = handler;
-}
-
-static const VMStateDescription vmstate_pxa2xx_gpio_regs = {
- .name = "pxa2xx-gpio",
- .version_id = 1,
- .minimum_version_id = 1,
- .fields = (VMStateField[]) {
- VMSTATE_UINT32_ARRAY(ilevel, PXA2xxGPIOInfo, PXA2XX_GPIO_BANKS),
- VMSTATE_UINT32_ARRAY(olevel, PXA2xxGPIOInfo, PXA2XX_GPIO_BANKS),
- VMSTATE_UINT32_ARRAY(dir, PXA2xxGPIOInfo, PXA2XX_GPIO_BANKS),
- VMSTATE_UINT32_ARRAY(rising, PXA2xxGPIOInfo, PXA2XX_GPIO_BANKS),
- VMSTATE_UINT32_ARRAY(falling, PXA2xxGPIOInfo, PXA2XX_GPIO_BANKS),
- VMSTATE_UINT32_ARRAY(status, PXA2xxGPIOInfo, PXA2XX_GPIO_BANKS),
- VMSTATE_UINT32_ARRAY(gafr, PXA2xxGPIOInfo, PXA2XX_GPIO_BANKS * 2),
- VMSTATE_UINT32_ARRAY(prev_level, PXA2xxGPIOInfo, PXA2XX_GPIO_BANKS),
- VMSTATE_END_OF_LIST(),
- },
-};
-
-static Property pxa2xx_gpio_properties[] = {
- DEFINE_PROP_INT32("lines", PXA2xxGPIOInfo, lines, 0),
- DEFINE_PROP_INT32("ncpu", PXA2xxGPIOInfo, ncpu, 0),
- DEFINE_PROP_END_OF_LIST(),
-};
-
-static void pxa2xx_gpio_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
-
- k->init = pxa2xx_gpio_initfn;
- dc->desc = "PXA2xx GPIO controller";
- dc->props = pxa2xx_gpio_properties;
- dc->vmsd = &vmstate_pxa2xx_gpio_regs;
-}
-
-static const TypeInfo pxa2xx_gpio_info = {
- .name = TYPE_PXA2XX_GPIO,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(PXA2xxGPIOInfo),
- .class_init = pxa2xx_gpio_class_init,
-};
-
-static void pxa2xx_gpio_register_types(void)
-{
- type_register_static(&pxa2xx_gpio_info);
-}
-
-type_init(pxa2xx_gpio_register_types)
diff --git a/qemu/hw/arm/pxa2xx_pic.c b/qemu/hw/arm/pxa2xx_pic.c
deleted file mode 100644
index 7e51532cd..000000000
--- a/qemu/hw/arm/pxa2xx_pic.c
+++ /dev/null
@@ -1,340 +0,0 @@
-/*
- * Intel XScale PXA Programmable Interrupt Controller.
- *
- * Copyright (c) 2006 Openedhand Ltd.
- * Copyright (c) 2006 Thorsten Zitterell
- * Written by Andrzej Zaborowski <balrog@zabor.org>
- *
- * This code is licensed under the GPL.
- */
-
-#include "qemu/osdep.h"
-#include "qemu-common.h"
-#include "cpu.h"
-#include "hw/hw.h"
-#include "hw/arm/pxa.h"
-#include "hw/sysbus.h"
-
-#define ICIP 0x00 /* Interrupt Controller IRQ Pending register */
-#define ICMR 0x04 /* Interrupt Controller Mask register */
-#define ICLR 0x08 /* Interrupt Controller Level register */
-#define ICFP 0x0c /* Interrupt Controller FIQ Pending register */
-#define ICPR 0x10 /* Interrupt Controller Pending register */
-#define ICCR 0x14 /* Interrupt Controller Control register */
-#define ICHP 0x18 /* Interrupt Controller Highest Priority register */
-#define IPR0 0x1c /* Interrupt Controller Priority register 0 */
-#define IPR31 0x98 /* Interrupt Controller Priority register 31 */
-#define ICIP2 0x9c /* Interrupt Controller IRQ Pending register 2 */
-#define ICMR2 0xa0 /* Interrupt Controller Mask register 2 */
-#define ICLR2 0xa4 /* Interrupt Controller Level register 2 */
-#define ICFP2 0xa8 /* Interrupt Controller FIQ Pending register 2 */
-#define ICPR2 0xac /* Interrupt Controller Pending register 2 */
-#define IPR32 0xb0 /* Interrupt Controller Priority register 32 */
-#define IPR39 0xcc /* Interrupt Controller Priority register 39 */
-
-#define PXA2XX_PIC_SRCS 40
-
-#define TYPE_PXA2XX_PIC "pxa2xx_pic"
-#define PXA2XX_PIC(obj) \
- OBJECT_CHECK(PXA2xxPICState, (obj), TYPE_PXA2XX_PIC)
-
-typedef struct {
- /*< private >*/
- SysBusDevice parent_obj;
- /*< public >*/
-
- MemoryRegion iomem;
- ARMCPU *cpu;
- uint32_t int_enabled[2];
- uint32_t int_pending[2];
- uint32_t is_fiq[2];
- uint32_t int_idle;
- uint32_t priority[PXA2XX_PIC_SRCS];
-} PXA2xxPICState;
-
-static void pxa2xx_pic_update(void *opaque)
-{
- uint32_t mask[2];
- PXA2xxPICState *s = (PXA2xxPICState *) opaque;
- CPUState *cpu = CPU(s->cpu);
-
- if (cpu->halted) {
- mask[0] = s->int_pending[0] & (s->int_enabled[0] | s->int_idle);
- mask[1] = s->int_pending[1] & (s->int_enabled[1] | s->int_idle);
- if (mask[0] || mask[1]) {
- cpu_interrupt(cpu, CPU_INTERRUPT_EXITTB);
- }
- }
-
- mask[0] = s->int_pending[0] & s->int_enabled[0];
- mask[1] = s->int_pending[1] & s->int_enabled[1];
-
- if ((mask[0] & s->is_fiq[0]) || (mask[1] & s->is_fiq[1])) {
- cpu_interrupt(cpu, CPU_INTERRUPT_FIQ);
- } else {
- cpu_reset_interrupt(cpu, CPU_INTERRUPT_FIQ);
- }
-
- if ((mask[0] & ~s->is_fiq[0]) || (mask[1] & ~s->is_fiq[1])) {
- cpu_interrupt(cpu, CPU_INTERRUPT_HARD);
- } else {
- cpu_reset_interrupt(cpu, CPU_INTERRUPT_HARD);
- }
-}
-
-/* Note: Here level means state of the signal on a pin, not
- * IRQ/FIQ distinction as in PXA Developer Manual. */
-static void pxa2xx_pic_set_irq(void *opaque, int irq, int level)
-{
- PXA2xxPICState *s = (PXA2xxPICState *) opaque;
- int int_set = (irq >= 32);
- irq &= 31;
-
- if (level)
- s->int_pending[int_set] |= 1 << irq;
- else
- s->int_pending[int_set] &= ~(1 << irq);
-
- pxa2xx_pic_update(opaque);
-}
-
-static inline uint32_t pxa2xx_pic_highest(PXA2xxPICState *s) {
- int i, int_set, irq;
- uint32_t bit, mask[2];
- uint32_t ichp = 0x003f003f; /* Both IDs invalid */
-
- mask[0] = s->int_pending[0] & s->int_enabled[0];
- mask[1] = s->int_pending[1] & s->int_enabled[1];
-
- for (i = PXA2XX_PIC_SRCS - 1; i >= 0; i --) {
- irq = s->priority[i] & 0x3f;
- if ((s->priority[i] & (1U << 31)) && irq < PXA2XX_PIC_SRCS) {
- /* Source peripheral ID is valid. */
- bit = 1 << (irq & 31);
- int_set = (irq >= 32);
-
- if (mask[int_set] & bit & s->is_fiq[int_set]) {
- /* FIQ asserted */
- ichp &= 0xffff0000;
- ichp |= (1 << 15) | irq;
- }
-
- if (mask[int_set] & bit & ~s->is_fiq[int_set]) {
- /* IRQ asserted */
- ichp &= 0x0000ffff;
- ichp |= (1U << 31) | (irq << 16);
- }
- }
- }
-
- return ichp;
-}
-
-static uint64_t pxa2xx_pic_mem_read(void *opaque, hwaddr offset,
- unsigned size)
-{
- PXA2xxPICState *s = (PXA2xxPICState *) opaque;
-
- switch (offset) {
- case ICIP: /* IRQ Pending register */
- return s->int_pending[0] & ~s->is_fiq[0] & s->int_enabled[0];
- case ICIP2: /* IRQ Pending register 2 */
- return s->int_pending[1] & ~s->is_fiq[1] & s->int_enabled[1];
- case ICMR: /* Mask register */
- return s->int_enabled[0];
- case ICMR2: /* Mask register 2 */
- return s->int_enabled[1];
- case ICLR: /* Level register */
- return s->is_fiq[0];
- case ICLR2: /* Level register 2 */
- return s->is_fiq[1];
- case ICCR: /* Idle mask */
- return (s->int_idle == 0);
- case ICFP: /* FIQ Pending register */
- return s->int_pending[0] & s->is_fiq[0] & s->int_enabled[0];
- case ICFP2: /* FIQ Pending register 2 */
- return s->int_pending[1] & s->is_fiq[1] & s->int_enabled[1];
- case ICPR: /* Pending register */
- return s->int_pending[0];
- case ICPR2: /* Pending register 2 */
- return s->int_pending[1];
- case IPR0 ... IPR31:
- return s->priority[0 + ((offset - IPR0 ) >> 2)];
- case IPR32 ... IPR39:
- return s->priority[32 + ((offset - IPR32) >> 2)];
- case ICHP: /* Highest Priority register */
- return pxa2xx_pic_highest(s);
- default:
- printf("%s: Bad register offset " REG_FMT "\n", __FUNCTION__, offset);
- return 0;
- }
-}
-
-static void pxa2xx_pic_mem_write(void *opaque, hwaddr offset,
- uint64_t value, unsigned size)
-{
- PXA2xxPICState *s = (PXA2xxPICState *) opaque;
-
- switch (offset) {
- case ICMR: /* Mask register */
- s->int_enabled[0] = value;
- break;
- case ICMR2: /* Mask register 2 */
- s->int_enabled[1] = value;
- break;
- case ICLR: /* Level register */
- s->is_fiq[0] = value;
- break;
- case ICLR2: /* Level register 2 */
- s->is_fiq[1] = value;
- break;
- case ICCR: /* Idle mask */
- s->int_idle = (value & 1) ? 0 : ~0;
- break;
- case IPR0 ... IPR31:
- s->priority[0 + ((offset - IPR0 ) >> 2)] = value & 0x8000003f;
- break;
- case IPR32 ... IPR39:
- s->priority[32 + ((offset - IPR32) >> 2)] = value & 0x8000003f;
- break;
- default:
- printf("%s: Bad register offset " REG_FMT "\n", __FUNCTION__, offset);
- return;
- }
- pxa2xx_pic_update(opaque);
-}
-
-/* Interrupt Controller Coprocessor Space Register Mapping */
-static const int pxa2xx_cp_reg_map[0x10] = {
- [0x0 ... 0xf] = -1,
- [0x0] = ICIP,
- [0x1] = ICMR,
- [0x2] = ICLR,
- [0x3] = ICFP,
- [0x4] = ICPR,
- [0x5] = ICHP,
- [0x6] = ICIP2,
- [0x7] = ICMR2,
- [0x8] = ICLR2,
- [0x9] = ICFP2,
- [0xa] = ICPR2,
-};
-
-static uint64_t pxa2xx_pic_cp_read(CPUARMState *env, const ARMCPRegInfo *ri)
-{
- int offset = pxa2xx_cp_reg_map[ri->crn];
- return pxa2xx_pic_mem_read(ri->opaque, offset, 4);
-}
-
-static void pxa2xx_pic_cp_write(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t value)
-{
- int offset = pxa2xx_cp_reg_map[ri->crn];
- pxa2xx_pic_mem_write(ri->opaque, offset, value, 4);
-}
-
-#define REGINFO_FOR_PIC_CP(NAME, CRN) \
- { .name = NAME, .cp = 6, .crn = CRN, .crm = 0, .opc1 = 0, .opc2 = 0, \
- .access = PL1_RW, .type = ARM_CP_IO, \
- .readfn = pxa2xx_pic_cp_read, .writefn = pxa2xx_pic_cp_write }
-
-static const ARMCPRegInfo pxa_pic_cp_reginfo[] = {
- REGINFO_FOR_PIC_CP("ICIP", 0),
- REGINFO_FOR_PIC_CP("ICMR", 1),
- REGINFO_FOR_PIC_CP("ICLR", 2),
- REGINFO_FOR_PIC_CP("ICFP", 3),
- REGINFO_FOR_PIC_CP("ICPR", 4),
- REGINFO_FOR_PIC_CP("ICHP", 5),
- REGINFO_FOR_PIC_CP("ICIP2", 6),
- REGINFO_FOR_PIC_CP("ICMR2", 7),
- REGINFO_FOR_PIC_CP("ICLR2", 8),
- REGINFO_FOR_PIC_CP("ICFP2", 9),
- REGINFO_FOR_PIC_CP("ICPR2", 0xa),
- REGINFO_SENTINEL
-};
-
-static const MemoryRegionOps pxa2xx_pic_ops = {
- .read = pxa2xx_pic_mem_read,
- .write = pxa2xx_pic_mem_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static int pxa2xx_pic_post_load(void *opaque, int version_id)
-{
- pxa2xx_pic_update(opaque);
- return 0;
-}
-
-DeviceState *pxa2xx_pic_init(hwaddr base, ARMCPU *cpu)
-{
- DeviceState *dev = qdev_create(NULL, TYPE_PXA2XX_PIC);
- PXA2xxPICState *s = PXA2XX_PIC(dev);
-
- s->cpu = cpu;
-
- s->int_pending[0] = 0;
- s->int_pending[1] = 0;
- s->int_enabled[0] = 0;
- s->int_enabled[1] = 0;
- s->is_fiq[0] = 0;
- s->is_fiq[1] = 0;
-
- qdev_init_nofail(dev);
-
- qdev_init_gpio_in(dev, pxa2xx_pic_set_irq, PXA2XX_PIC_SRCS);
-
- /* Enable IC memory-mapped registers access. */
- memory_region_init_io(&s->iomem, OBJECT(s), &pxa2xx_pic_ops, s,
- "pxa2xx-pic", 0x00100000);
- sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
- sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
-
- /* Enable IC coprocessor access. */
- define_arm_cp_regs_with_opaque(cpu, pxa_pic_cp_reginfo, s);
-
- return dev;
-}
-
-static VMStateDescription vmstate_pxa2xx_pic_regs = {
- .name = "pxa2xx_pic",
- .version_id = 0,
- .minimum_version_id = 0,
- .post_load = pxa2xx_pic_post_load,
- .fields = (VMStateField[]) {
- VMSTATE_UINT32_ARRAY(int_enabled, PXA2xxPICState, 2),
- VMSTATE_UINT32_ARRAY(int_pending, PXA2xxPICState, 2),
- VMSTATE_UINT32_ARRAY(is_fiq, PXA2xxPICState, 2),
- VMSTATE_UINT32(int_idle, PXA2xxPICState),
- VMSTATE_UINT32_ARRAY(priority, PXA2xxPICState, PXA2XX_PIC_SRCS),
- VMSTATE_END_OF_LIST(),
- },
-};
-
-static int pxa2xx_pic_initfn(SysBusDevice *dev)
-{
- return 0;
-}
-
-static void pxa2xx_pic_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
-
- k->init = pxa2xx_pic_initfn;
- dc->desc = "PXA2xx PIC";
- dc->vmsd = &vmstate_pxa2xx_pic_regs;
-}
-
-static const TypeInfo pxa2xx_pic_info = {
- .name = TYPE_PXA2XX_PIC,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(PXA2xxPICState),
- .class_init = pxa2xx_pic_class_init,
-};
-
-static void pxa2xx_pic_register_types(void)
-{
- type_register_static(&pxa2xx_pic_info);
-}
-
-type_init(pxa2xx_pic_register_types)
diff --git a/qemu/hw/arm/raspi.c b/qemu/hw/arm/raspi.c
deleted file mode 100644
index 2b295f14c..000000000
--- a/qemu/hw/arm/raspi.c
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * Raspberry Pi emulation (c) 2012 Gregory Estrade
- * Upstreaming code cleanup [including bcm2835_*] (c) 2013 Jan Petrous
- *
- * Rasperry Pi 2 emulation Copyright (c) 2015, Microsoft
- * Written by Andrew Baumann
- *
- * This code is licensed under the GNU GPLv2 and later.
- */
-
-#include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "qemu-common.h"
-#include "cpu.h"
-#include "hw/arm/bcm2836.h"
-#include "qemu/error-report.h"
-#include "hw/boards.h"
-#include "hw/loader.h"
-#include "hw/arm/arm.h"
-#include "sysemu/sysemu.h"
-
-#define SMPBOOT_ADDR 0x300 /* this should leave enough space for ATAGS */
-#define MVBAR_ADDR 0x400 /* secure vectors */
-#define BOARDSETUP_ADDR (MVBAR_ADDR + 0x20) /* board setup code */
-#define FIRMWARE_ADDR 0x8000 /* Pi loads kernel.img here by default */
-
-/* Table of Linux board IDs for different Pi versions */
-static const int raspi_boardid[] = {[1] = 0xc42, [2] = 0xc43};
-
-typedef struct RasPiState {
- BCM2836State soc;
- MemoryRegion ram;
-} RasPiState;
-
-static void write_smpboot(ARMCPU *cpu, const struct arm_boot_info *info)
-{
- static const uint32_t smpboot[] = {
- 0xe1a0e00f, /* mov lr, pc */
- 0xe3a0fe00 + (BOARDSETUP_ADDR >> 4), /* mov pc, BOARDSETUP_ADDR */
- 0xee100fb0, /* mrc p15, 0, r0, c0, c0, 5;get core ID */
- 0xe7e10050, /* ubfx r0, r0, #0, #2 ;extract LSB */
- 0xe59f5014, /* ldr r5, =0x400000CC ;load mbox base */
- 0xe320f001, /* 1: yield */
- 0xe7953200, /* ldr r3, [r5, r0, lsl #4] ;read mbox for our core*/
- 0xe3530000, /* cmp r3, #0 ;spin while zero */
- 0x0afffffb, /* beq 1b */
- 0xe7853200, /* str r3, [r5, r0, lsl #4] ;clear mbox */
- 0xe12fff13, /* bx r3 ;jump to target */
- 0x400000cc, /* (constant: mailbox 3 read/clear base) */
- };
-
- /* check that we don't overrun board setup vectors */
- QEMU_BUILD_BUG_ON(SMPBOOT_ADDR + sizeof(smpboot) > MVBAR_ADDR);
- /* check that board setup address is correctly relocated */
- QEMU_BUILD_BUG_ON((BOARDSETUP_ADDR & 0xf) != 0
- || (BOARDSETUP_ADDR >> 4) >= 0x100);
-
- rom_add_blob_fixed("raspi_smpboot", smpboot, sizeof(smpboot),
- info->smp_loader_start);
-}
-
-static void write_board_setup(ARMCPU *cpu, const struct arm_boot_info *info)
-{
- arm_write_secure_board_setup_dummy_smc(cpu, info, MVBAR_ADDR);
-}
-
-static void reset_secondary(ARMCPU *cpu, const struct arm_boot_info *info)
-{
- CPUState *cs = CPU(cpu);
- cpu_set_pc(cs, info->smp_loader_start);
-}
-
-static void setup_boot(MachineState *machine, int version, size_t ram_size)
-{
- static struct arm_boot_info binfo;
- int r;
-
- binfo.board_id = raspi_boardid[version];
- binfo.ram_size = ram_size;
- binfo.nb_cpus = smp_cpus;
- binfo.board_setup_addr = BOARDSETUP_ADDR;
- binfo.write_board_setup = write_board_setup;
- binfo.secure_board_setup = true;
- binfo.secure_boot = true;
-
- /* Pi2 requires SMP setup */
- if (version == 2) {
- binfo.smp_loader_start = SMPBOOT_ADDR;
- binfo.write_secondary_boot = write_smpboot;
- binfo.secondary_cpu_reset_hook = reset_secondary;
- }
-
- /* If the user specified a "firmware" image (e.g. UEFI), we bypass
- * the normal Linux boot process
- */
- if (machine->firmware) {
- /* load the firmware image (typically kernel.img) */
- r = load_image_targphys(machine->firmware, FIRMWARE_ADDR,
- ram_size - FIRMWARE_ADDR);
- if (r < 0) {
- error_report("Failed to load firmware from %s", machine->firmware);
- exit(1);
- }
-
- binfo.entry = FIRMWARE_ADDR;
- binfo.firmware_loaded = true;
- } else {
- binfo.kernel_filename = machine->kernel_filename;
- binfo.kernel_cmdline = machine->kernel_cmdline;
- binfo.initrd_filename = machine->initrd_filename;
- }
-
- arm_load_kernel(ARM_CPU(first_cpu), &binfo);
-}
-
-static void raspi2_init(MachineState *machine)
-{
- RasPiState *s = g_new0(RasPiState, 1);
- uint32_t vcram_size;
- DriveInfo *di;
- BlockBackend *blk;
- BusState *bus;
- DeviceState *carddev;
-
- object_initialize(&s->soc, sizeof(s->soc), TYPE_BCM2836);
- object_property_add_child(OBJECT(machine), "soc", OBJECT(&s->soc),
- &error_abort);
-
- /* Allocate and map RAM */
- memory_region_allocate_system_memory(&s->ram, OBJECT(machine), "ram",
- machine->ram_size);
- /* FIXME: Remove when we have custom CPU address space support */
- memory_region_add_subregion_overlap(get_system_memory(), 0, &s->ram, 0);
-
- /* Setup the SOC */
- object_property_add_const_link(OBJECT(&s->soc), "ram", OBJECT(&s->ram),
- &error_abort);
- object_property_set_int(OBJECT(&s->soc), smp_cpus, "enabled-cpus",
- &error_abort);
- object_property_set_int(OBJECT(&s->soc), 0xa21041, "board-rev",
- &error_abort);
- object_property_set_bool(OBJECT(&s->soc), true, "realized", &error_abort);
-
- /* Create and plug in the SD cards */
- di = drive_get_next(IF_SD);
- blk = di ? blk_by_legacy_dinfo(di) : NULL;
- bus = qdev_get_child_bus(DEVICE(&s->soc), "sd-bus");
- if (bus == NULL) {
- error_report("No SD bus found in SOC object");
- exit(1);
- }
- carddev = qdev_create(bus, TYPE_SD_CARD);
- qdev_prop_set_drive(carddev, "drive", blk, &error_fatal);
- object_property_set_bool(OBJECT(carddev), true, "realized", &error_fatal);
-
- vcram_size = object_property_get_int(OBJECT(&s->soc), "vcram-size",
- &error_abort);
- setup_boot(machine, 2, machine->ram_size - vcram_size);
-}
-
-static void raspi2_machine_init(MachineClass *mc)
-{
- mc->desc = "Raspberry Pi 2";
- mc->init = raspi2_init;
- mc->block_default_type = IF_SD;
- mc->no_parallel = 1;
- mc->no_floppy = 1;
- mc->no_cdrom = 1;
- mc->max_cpus = BCM2836_NCPUS;
- mc->default_ram_size = 1024 * 1024 * 1024;
-};
-DEFINE_MACHINE("raspi2", raspi2_machine_init)
diff --git a/qemu/hw/arm/realview.c b/qemu/hw/arm/realview.c
deleted file mode 100644
index 3222b360e..000000000
--- a/qemu/hw/arm/realview.c
+++ /dev/null
@@ -1,463 +0,0 @@
-/*
- * ARM RealView Baseboard System emulation.
- *
- * Copyright (c) 2006-2007 CodeSourcery.
- * Written by Paul Brook
- *
- * This code is licensed under the GPL.
- */
-
-#include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "qemu-common.h"
-#include "cpu.h"
-#include "hw/sysbus.h"
-#include "hw/arm/arm.h"
-#include "hw/arm/primecell.h"
-#include "hw/devices.h"
-#include "hw/pci/pci.h"
-#include "net/net.h"
-#include "sysemu/sysemu.h"
-#include "hw/boards.h"
-#include "hw/i2c/i2c.h"
-#include "sysemu/block-backend.h"
-#include "exec/address-spaces.h"
-#include "qemu/error-report.h"
-
-#define SMP_BOOT_ADDR 0xe0000000
-#define SMP_BOOTREG_ADDR 0x10000030
-
-/* Board init. */
-
-static struct arm_boot_info realview_binfo = {
- .smp_loader_start = SMP_BOOT_ADDR,
- .smp_bootreg_addr = SMP_BOOTREG_ADDR,
-};
-
-/* The following two lists must be consistent. */
-enum realview_board_type {
- BOARD_EB,
- BOARD_EB_MPCORE,
- BOARD_PB_A8,
- BOARD_PBX_A9,
-};
-
-static const int realview_board_id[] = {
- 0x33b,
- 0x33b,
- 0x769,
- 0x76d
-};
-
-static void realview_init(MachineState *machine,
- enum realview_board_type board_type)
-{
- ARMCPU *cpu = NULL;
- CPUARMState *env;
- ObjectClass *cpu_oc;
- MemoryRegion *sysmem = get_system_memory();
- MemoryRegion *ram_lo;
- MemoryRegion *ram_hi = g_new(MemoryRegion, 1);
- MemoryRegion *ram_alias = g_new(MemoryRegion, 1);
- MemoryRegion *ram_hack = g_new(MemoryRegion, 1);
- DeviceState *dev, *sysctl, *gpio2, *pl041;
- SysBusDevice *busdev;
- qemu_irq pic[64];
- qemu_irq mmc_irq[2];
- PCIBus *pci_bus = NULL;
- NICInfo *nd;
- I2CBus *i2c;
- int n;
- int done_nic = 0;
- qemu_irq cpu_irq[4];
- int is_mpcore = 0;
- int is_pb = 0;
- uint32_t proc_id = 0;
- uint32_t sys_id;
- ram_addr_t low_ram_size;
- ram_addr_t ram_size = machine->ram_size;
- hwaddr periphbase = 0;
-
- switch (board_type) {
- case BOARD_EB:
- break;
- case BOARD_EB_MPCORE:
- is_mpcore = 1;
- periphbase = 0x10100000;
- break;
- case BOARD_PB_A8:
- is_pb = 1;
- break;
- case BOARD_PBX_A9:
- is_mpcore = 1;
- is_pb = 1;
- periphbase = 0x1f000000;
- break;
- }
-
- cpu_oc = cpu_class_by_name(TYPE_ARM_CPU, machine->cpu_model);
- if (!cpu_oc) {
- fprintf(stderr, "Unable to find CPU definition\n");
- exit(1);
- }
-
- for (n = 0; n < smp_cpus; n++) {
- Object *cpuobj = object_new(object_class_get_name(cpu_oc));
-
- /* By default A9,A15 and ARM1176 CPUs have EL3 enabled. This board
- * does not currently support EL3 so the CPU EL3 property is disabled
- * before realization.
- */
- if (object_property_find(cpuobj, "has_el3", NULL)) {
- object_property_set_bool(cpuobj, false, "has_el3", &error_fatal);
- }
-
- if (is_pb && is_mpcore) {
- object_property_set_int(cpuobj, periphbase, "reset-cbar",
- &error_fatal);
- }
-
- object_property_set_bool(cpuobj, true, "realized", &error_fatal);
-
- cpu_irq[n] = qdev_get_gpio_in(DEVICE(cpuobj), ARM_CPU_IRQ);
- }
- cpu = ARM_CPU(first_cpu);
- env = &cpu->env;
- if (arm_feature(env, ARM_FEATURE_V7)) {
- if (is_mpcore) {
- proc_id = 0x0c000000;
- } else {
- proc_id = 0x0e000000;
- }
- } else if (arm_feature(env, ARM_FEATURE_V6K)) {
- proc_id = 0x06000000;
- } else if (arm_feature(env, ARM_FEATURE_V6)) {
- proc_id = 0x04000000;
- } else {
- proc_id = 0x02000000;
- }
-
- if (is_pb && ram_size > 0x20000000) {
- /* Core tile RAM. */
- ram_lo = g_new(MemoryRegion, 1);
- low_ram_size = ram_size - 0x20000000;
- ram_size = 0x20000000;
- memory_region_init_ram(ram_lo, NULL, "realview.lowmem", low_ram_size,
- &error_fatal);
- vmstate_register_ram_global(ram_lo);
- memory_region_add_subregion(sysmem, 0x20000000, ram_lo);
- }
-
- memory_region_init_ram(ram_hi, NULL, "realview.highmem", ram_size,
- &error_fatal);
- vmstate_register_ram_global(ram_hi);
- low_ram_size = ram_size;
- if (low_ram_size > 0x10000000)
- low_ram_size = 0x10000000;
- /* SDRAM at address zero. */
- memory_region_init_alias(ram_alias, NULL, "realview.alias",
- ram_hi, 0, low_ram_size);
- memory_region_add_subregion(sysmem, 0, ram_alias);
- if (is_pb) {
- /* And again at a high address. */
- memory_region_add_subregion(sysmem, 0x70000000, ram_hi);
- } else {
- ram_size = low_ram_size;
- }
-
- sys_id = is_pb ? 0x01780500 : 0xc1400400;
- sysctl = qdev_create(NULL, "realview_sysctl");
- qdev_prop_set_uint32(sysctl, "sys_id", sys_id);
- qdev_prop_set_uint32(sysctl, "proc_id", proc_id);
- qdev_init_nofail(sysctl);
- sysbus_mmio_map(SYS_BUS_DEVICE(sysctl), 0, 0x10000000);
-
- if (is_mpcore) {
- dev = qdev_create(NULL, is_pb ? "a9mpcore_priv": "realview_mpcore");
- qdev_prop_set_uint32(dev, "num-cpu", smp_cpus);
- qdev_init_nofail(dev);
- busdev = SYS_BUS_DEVICE(dev);
- sysbus_mmio_map(busdev, 0, periphbase);
- for (n = 0; n < smp_cpus; n++) {
- sysbus_connect_irq(busdev, n, cpu_irq[n]);
- }
- sysbus_create_varargs("l2x0", periphbase + 0x2000, NULL);
- /* Both A9 and 11MPCore put the GIC CPU i/f at base + 0x100 */
- realview_binfo.gic_cpu_if_addr = periphbase + 0x100;
- } else {
- uint32_t gic_addr = is_pb ? 0x1e000000 : 0x10040000;
- /* For now just create the nIRQ GIC, and ignore the others. */
- dev = sysbus_create_simple("realview_gic", gic_addr, cpu_irq[0]);
- }
- for (n = 0; n < 64; n++) {
- pic[n] = qdev_get_gpio_in(dev, n);
- }
-
- pl041 = qdev_create(NULL, "pl041");
- qdev_prop_set_uint32(pl041, "nc_fifo_depth", 512);
- qdev_init_nofail(pl041);
- sysbus_mmio_map(SYS_BUS_DEVICE(pl041), 0, 0x10004000);
- sysbus_connect_irq(SYS_BUS_DEVICE(pl041), 0, pic[19]);
-
- sysbus_create_simple("pl050_keyboard", 0x10006000, pic[20]);
- sysbus_create_simple("pl050_mouse", 0x10007000, pic[21]);
-
- sysbus_create_simple("pl011", 0x10009000, pic[12]);
- sysbus_create_simple("pl011", 0x1000a000, pic[13]);
- sysbus_create_simple("pl011", 0x1000b000, pic[14]);
- sysbus_create_simple("pl011", 0x1000c000, pic[15]);
-
- /* DMA controller is optional, apparently. */
- sysbus_create_simple("pl081", 0x10030000, pic[24]);
-
- sysbus_create_simple("sp804", 0x10011000, pic[4]);
- sysbus_create_simple("sp804", 0x10012000, pic[5]);
-
- sysbus_create_simple("pl061", 0x10013000, pic[6]);
- sysbus_create_simple("pl061", 0x10014000, pic[7]);
- gpio2 = sysbus_create_simple("pl061", 0x10015000, pic[8]);
-
- sysbus_create_simple("pl111", 0x10020000, pic[23]);
-
- dev = sysbus_create_varargs("pl181", 0x10005000, pic[17], pic[18], NULL);
- /* Wire up MMC card detect and read-only signals. These have
- * to go to both the PL061 GPIO and the sysctl register.
- * Note that the PL181 orders these lines (readonly,inserted)
- * and the PL061 has them the other way about. Also the card
- * detect line is inverted.
- */
- mmc_irq[0] = qemu_irq_split(
- qdev_get_gpio_in(sysctl, ARM_SYSCTL_GPIO_MMC_WPROT),
- qdev_get_gpio_in(gpio2, 1));
- mmc_irq[1] = qemu_irq_split(
- qdev_get_gpio_in(sysctl, ARM_SYSCTL_GPIO_MMC_CARDIN),
- qemu_irq_invert(qdev_get_gpio_in(gpio2, 0)));
- qdev_connect_gpio_out(dev, 0, mmc_irq[0]);
- qdev_connect_gpio_out(dev, 1, mmc_irq[1]);
-
- sysbus_create_simple("pl031", 0x10017000, pic[10]);
-
- if (!is_pb) {
- dev = qdev_create(NULL, "realview_pci");
- busdev = SYS_BUS_DEVICE(dev);
- qdev_init_nofail(dev);
- sysbus_mmio_map(busdev, 0, 0x10019000); /* PCI controller registers */
- sysbus_mmio_map(busdev, 1, 0x60000000); /* PCI self-config */
- sysbus_mmio_map(busdev, 2, 0x61000000); /* PCI config */
- sysbus_mmio_map(busdev, 3, 0x62000000); /* PCI I/O */
- sysbus_mmio_map(busdev, 4, 0x63000000); /* PCI memory window 1 */
- sysbus_mmio_map(busdev, 5, 0x64000000); /* PCI memory window 2 */
- sysbus_mmio_map(busdev, 6, 0x68000000); /* PCI memory window 3 */
- sysbus_connect_irq(busdev, 0, pic[48]);
- sysbus_connect_irq(busdev, 1, pic[49]);
- sysbus_connect_irq(busdev, 2, pic[50]);
- sysbus_connect_irq(busdev, 3, pic[51]);
- pci_bus = (PCIBus *)qdev_get_child_bus(dev, "pci");
- if (usb_enabled()) {
- pci_create_simple(pci_bus, -1, "pci-ohci");
- }
- n = drive_get_max_bus(IF_SCSI);
- while (n >= 0) {
- pci_create_simple(pci_bus, -1, "lsi53c895a");
- n--;
- }
- }
- for(n = 0; n < nb_nics; n++) {
- nd = &nd_table[n];
-
- if (!done_nic && (!nd->model ||
- strcmp(nd->model, is_pb ? "lan9118" : "smc91c111") == 0)) {
- if (is_pb) {
- lan9118_init(nd, 0x4e000000, pic[28]);
- } else {
- smc91c111_init(nd, 0x4e000000, pic[28]);
- }
- done_nic = 1;
- } else {
- if (pci_bus) {
- pci_nic_init_nofail(nd, pci_bus, "rtl8139", NULL);
- }
- }
- }
-
- dev = sysbus_create_simple("versatile_i2c", 0x10002000, NULL);
- i2c = (I2CBus *)qdev_get_child_bus(dev, "i2c");
- i2c_create_slave(i2c, "ds1338", 0x68);
-
- /* Memory map for RealView Emulation Baseboard: */
- /* 0x10000000 System registers. */
- /* 0x10001000 System controller. */
- /* 0x10002000 Two-Wire Serial Bus. */
- /* 0x10003000 Reserved. */
- /* 0x10004000 AACI. */
- /* 0x10005000 MCI. */
- /* 0x10006000 KMI0. */
- /* 0x10007000 KMI1. */
- /* 0x10008000 Character LCD. (EB) */
- /* 0x10009000 UART0. */
- /* 0x1000a000 UART1. */
- /* 0x1000b000 UART2. */
- /* 0x1000c000 UART3. */
- /* 0x1000d000 SSPI. */
- /* 0x1000e000 SCI. */
- /* 0x1000f000 Reserved. */
- /* 0x10010000 Watchdog. */
- /* 0x10011000 Timer 0+1. */
- /* 0x10012000 Timer 2+3. */
- /* 0x10013000 GPIO 0. */
- /* 0x10014000 GPIO 1. */
- /* 0x10015000 GPIO 2. */
- /* 0x10002000 Two-Wire Serial Bus - DVI. (PB) */
- /* 0x10017000 RTC. */
- /* 0x10018000 DMC. */
- /* 0x10019000 PCI controller config. */
- /* 0x10020000 CLCD. */
- /* 0x10030000 DMA Controller. */
- /* 0x10040000 GIC1. (EB) */
- /* 0x10050000 GIC2. (EB) */
- /* 0x10060000 GIC3. (EB) */
- /* 0x10070000 GIC4. (EB) */
- /* 0x10080000 SMC. */
- /* 0x1e000000 GIC1. (PB) */
- /* 0x1e001000 GIC2. (PB) */
- /* 0x1e002000 GIC3. (PB) */
- /* 0x1e003000 GIC4. (PB) */
- /* 0x40000000 NOR flash. */
- /* 0x44000000 DoC flash. */
- /* 0x48000000 SRAM. */
- /* 0x4c000000 Configuration flash. */
- /* 0x4e000000 Ethernet. */
- /* 0x4f000000 USB. */
- /* 0x50000000 PISMO. */
- /* 0x54000000 PISMO. */
- /* 0x58000000 PISMO. */
- /* 0x5c000000 PISMO. */
- /* 0x60000000 PCI. */
- /* 0x60000000 PCI Self Config. */
- /* 0x61000000 PCI Config. */
- /* 0x62000000 PCI IO. */
- /* 0x63000000 PCI mem 0. */
- /* 0x64000000 PCI mem 1. */
- /* 0x68000000 PCI mem 2. */
-
- /* ??? Hack to map an additional page of ram for the secondary CPU
- startup code. I guess this works on real hardware because the
- BootROM happens to be in ROM/flash or in memory that isn't clobbered
- until after Linux boots the secondary CPUs. */
- memory_region_init_ram(ram_hack, NULL, "realview.hack", 0x1000,
- &error_fatal);
- vmstate_register_ram_global(ram_hack);
- memory_region_add_subregion(sysmem, SMP_BOOT_ADDR, ram_hack);
-
- realview_binfo.ram_size = ram_size;
- realview_binfo.kernel_filename = machine->kernel_filename;
- realview_binfo.kernel_cmdline = machine->kernel_cmdline;
- realview_binfo.initrd_filename = machine->initrd_filename;
- realview_binfo.nb_cpus = smp_cpus;
- realview_binfo.board_id = realview_board_id[board_type];
- realview_binfo.loader_start = (board_type == BOARD_PB_A8 ? 0x70000000 : 0);
- arm_load_kernel(ARM_CPU(first_cpu), &realview_binfo);
-}
-
-static void realview_eb_init(MachineState *machine)
-{
- if (!machine->cpu_model) {
- machine->cpu_model = "arm926";
- }
- realview_init(machine, BOARD_EB);
-}
-
-static void realview_eb_mpcore_init(MachineState *machine)
-{
- if (!machine->cpu_model) {
- machine->cpu_model = "arm11mpcore";
- }
- realview_init(machine, BOARD_EB_MPCORE);
-}
-
-static void realview_pb_a8_init(MachineState *machine)
-{
- if (!machine->cpu_model) {
- machine->cpu_model = "cortex-a8";
- }
- realview_init(machine, BOARD_PB_A8);
-}
-
-static void realview_pbx_a9_init(MachineState *machine)
-{
- if (!machine->cpu_model) {
- machine->cpu_model = "cortex-a9";
- }
- realview_init(machine, BOARD_PBX_A9);
-}
-
-static void realview_eb_class_init(ObjectClass *oc, void *data)
-{
- MachineClass *mc = MACHINE_CLASS(oc);
-
- mc->desc = "ARM RealView Emulation Baseboard (ARM926EJ-S)";
- mc->init = realview_eb_init;
- mc->block_default_type = IF_SCSI;
-}
-
-static const TypeInfo realview_eb_type = {
- .name = MACHINE_TYPE_NAME("realview-eb"),
- .parent = TYPE_MACHINE,
- .class_init = realview_eb_class_init,
-};
-
-static void realview_eb_mpcore_class_init(ObjectClass *oc, void *data)
-{
- MachineClass *mc = MACHINE_CLASS(oc);
-
- mc->desc = "ARM RealView Emulation Baseboard (ARM11MPCore)";
- mc->init = realview_eb_mpcore_init;
- mc->block_default_type = IF_SCSI;
- mc->max_cpus = 4;
-}
-
-static const TypeInfo realview_eb_mpcore_type = {
- .name = MACHINE_TYPE_NAME("realview-eb-mpcore"),
- .parent = TYPE_MACHINE,
- .class_init = realview_eb_mpcore_class_init,
-};
-
-static void realview_pb_a8_class_init(ObjectClass *oc, void *data)
-{
- MachineClass *mc = MACHINE_CLASS(oc);
-
- mc->desc = "ARM RealView Platform Baseboard for Cortex-A8";
- mc->init = realview_pb_a8_init;
-}
-
-static const TypeInfo realview_pb_a8_type = {
- .name = MACHINE_TYPE_NAME("realview-pb-a8"),
- .parent = TYPE_MACHINE,
- .class_init = realview_pb_a8_class_init,
-};
-
-static void realview_pbx_a9_class_init(ObjectClass *oc, void *data)
-{
- MachineClass *mc = MACHINE_CLASS(oc);
-
- mc->desc = "ARM RealView Platform Baseboard Explore for Cortex-A9";
- mc->init = realview_pbx_a9_init;
- mc->block_default_type = IF_SCSI;
- mc->max_cpus = 4;
-}
-
-static const TypeInfo realview_pbx_a9_type = {
- .name = MACHINE_TYPE_NAME("realview-pbx-a9"),
- .parent = TYPE_MACHINE,
- .class_init = realview_pbx_a9_class_init,
-};
-
-static void realview_machine_init(void)
-{
- type_register_static(&realview_eb_type);
- type_register_static(&realview_eb_mpcore_type);
- type_register_static(&realview_pb_a8_type);
- type_register_static(&realview_pbx_a9_type);
-}
-
-type_init(realview_machine_init)
diff --git a/qemu/hw/arm/spitz.c b/qemu/hw/arm/spitz.c
deleted file mode 100644
index bf61d63b5..000000000
--- a/qemu/hw/arm/spitz.c
+++ /dev/null
@@ -1,1178 +0,0 @@
-/*
- * PXA270-based Clamshell PDA platforms.
- *
- * Copyright (c) 2006 Openedhand Ltd.
- * Written by Andrzej Zaborowski <balrog@zabor.org>
- *
- * This code is licensed under the GNU GPL v2.
- *
- * Contributions after 2012-01-13 are licensed under the terms of the
- * GNU GPL, version 2 or (at your option) any later version.
- */
-
-#include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "hw/hw.h"
-#include "hw/arm/pxa.h"
-#include "hw/arm/arm.h"
-#include "sysemu/sysemu.h"
-#include "hw/pcmcia.h"
-#include "hw/i2c/i2c.h"
-#include "hw/ssi/ssi.h"
-#include "hw/block/flash.h"
-#include "qemu/timer.h"
-#include "hw/devices.h"
-#include "hw/arm/sharpsl.h"
-#include "ui/console.h"
-#include "audio/audio.h"
-#include "hw/boards.h"
-#include "sysemu/block-backend.h"
-#include "hw/sysbus.h"
-#include "exec/address-spaces.h"
-
-#undef REG_FMT
-#define REG_FMT "0x%02lx"
-
-/* Spitz Flash */
-#define FLASH_BASE 0x0c000000
-#define FLASH_ECCLPLB 0x00 /* Line parity 7 - 0 bit */
-#define FLASH_ECCLPUB 0x04 /* Line parity 15 - 8 bit */
-#define FLASH_ECCCP 0x08 /* Column parity 5 - 0 bit */
-#define FLASH_ECCCNTR 0x0c /* ECC byte counter */
-#define FLASH_ECCCLRR 0x10 /* Clear ECC */
-#define FLASH_FLASHIO 0x14 /* Flash I/O */
-#define FLASH_FLASHCTL 0x18 /* Flash Control */
-
-#define FLASHCTL_CE0 (1 << 0)
-#define FLASHCTL_CLE (1 << 1)
-#define FLASHCTL_ALE (1 << 2)
-#define FLASHCTL_WP (1 << 3)
-#define FLASHCTL_CE1 (1 << 4)
-#define FLASHCTL_RYBY (1 << 5)
-#define FLASHCTL_NCE (FLASHCTL_CE0 | FLASHCTL_CE1)
-
-#define TYPE_SL_NAND "sl-nand"
-#define SL_NAND(obj) OBJECT_CHECK(SLNANDState, (obj), TYPE_SL_NAND)
-
-typedef struct {
- SysBusDevice parent_obj;
-
- MemoryRegion iomem;
- DeviceState *nand;
- uint8_t ctl;
- uint8_t manf_id;
- uint8_t chip_id;
- ECCState ecc;
-} SLNANDState;
-
-static uint64_t sl_read(void *opaque, hwaddr addr, unsigned size)
-{
- SLNANDState *s = (SLNANDState *) opaque;
- int ryby;
-
- switch (addr) {
-#define BSHR(byte, from, to) ((s->ecc.lp[byte] >> (from - to)) & (1 << to))
- case FLASH_ECCLPLB:
- return BSHR(0, 4, 0) | BSHR(0, 5, 2) | BSHR(0, 6, 4) | BSHR(0, 7, 6) |
- BSHR(1, 4, 1) | BSHR(1, 5, 3) | BSHR(1, 6, 5) | BSHR(1, 7, 7);
-
-#define BSHL(byte, from, to) ((s->ecc.lp[byte] << (to - from)) & (1 << to))
- case FLASH_ECCLPUB:
- return BSHL(0, 0, 0) | BSHL(0, 1, 2) | BSHL(0, 2, 4) | BSHL(0, 3, 6) |
- BSHL(1, 0, 1) | BSHL(1, 1, 3) | BSHL(1, 2, 5) | BSHL(1, 3, 7);
-
- case FLASH_ECCCP:
- return s->ecc.cp;
-
- case FLASH_ECCCNTR:
- return s->ecc.count & 0xff;
-
- case FLASH_FLASHCTL:
- nand_getpins(s->nand, &ryby);
- if (ryby)
- return s->ctl | FLASHCTL_RYBY;
- else
- return s->ctl;
-
- case FLASH_FLASHIO:
- if (size == 4) {
- return ecc_digest(&s->ecc, nand_getio(s->nand)) |
- (ecc_digest(&s->ecc, nand_getio(s->nand)) << 16);
- }
- return ecc_digest(&s->ecc, nand_getio(s->nand));
-
- default:
- zaurus_printf("Bad register offset " REG_FMT "\n", (unsigned long)addr);
- }
- return 0;
-}
-
-static void sl_write(void *opaque, hwaddr addr,
- uint64_t value, unsigned size)
-{
- SLNANDState *s = (SLNANDState *) opaque;
-
- switch (addr) {
- case FLASH_ECCCLRR:
- /* Value is ignored. */
- ecc_reset(&s->ecc);
- break;
-
- case FLASH_FLASHCTL:
- s->ctl = value & 0xff & ~FLASHCTL_RYBY;
- nand_setpins(s->nand,
- s->ctl & FLASHCTL_CLE,
- s->ctl & FLASHCTL_ALE,
- s->ctl & FLASHCTL_NCE,
- s->ctl & FLASHCTL_WP,
- 0);
- break;
-
- case FLASH_FLASHIO:
- nand_setio(s->nand, ecc_digest(&s->ecc, value & 0xff));
- break;
-
- default:
- zaurus_printf("Bad register offset " REG_FMT "\n", (unsigned long)addr);
- }
-}
-
-enum {
- FLASH_128M,
- FLASH_1024M,
-};
-
-static const MemoryRegionOps sl_ops = {
- .read = sl_read,
- .write = sl_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static void sl_flash_register(PXA2xxState *cpu, int size)
-{
- DeviceState *dev;
-
- dev = qdev_create(NULL, TYPE_SL_NAND);
-
- qdev_prop_set_uint8(dev, "manf_id", NAND_MFR_SAMSUNG);
- if (size == FLASH_128M)
- qdev_prop_set_uint8(dev, "chip_id", 0x73);
- else if (size == FLASH_1024M)
- qdev_prop_set_uint8(dev, "chip_id", 0xf1);
-
- qdev_init_nofail(dev);
- sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, FLASH_BASE);
-}
-
-static int sl_nand_init(SysBusDevice *dev)
-{
- SLNANDState *s = SL_NAND(dev);
- DriveInfo *nand;
-
- s->ctl = 0;
- /* FIXME use a qdev drive property instead of drive_get() */
- nand = drive_get(IF_MTD, 0, 0);
- s->nand = nand_init(nand ? blk_by_legacy_dinfo(nand) : NULL,
- s->manf_id, s->chip_id);
-
- memory_region_init_io(&s->iomem, OBJECT(s), &sl_ops, s, "sl", 0x40);
- sysbus_init_mmio(dev, &s->iomem);
-
- return 0;
-}
-
-/* Spitz Keyboard */
-
-#define SPITZ_KEY_STROBE_NUM 11
-#define SPITZ_KEY_SENSE_NUM 7
-
-static const int spitz_gpio_key_sense[SPITZ_KEY_SENSE_NUM] = {
- 12, 17, 91, 34, 36, 38, 39
-};
-
-static const int spitz_gpio_key_strobe[SPITZ_KEY_STROBE_NUM] = {
- 88, 23, 24, 25, 26, 27, 52, 103, 107, 108, 114
-};
-
-/* Eighth additional row maps the special keys */
-static int spitz_keymap[SPITZ_KEY_SENSE_NUM + 1][SPITZ_KEY_STROBE_NUM] = {
- { 0x1d, 0x02, 0x04, 0x06, 0x07, 0x08, 0x0a, 0x0b, 0x0e, 0x3f, 0x40 },
- { -1 , 0x03, 0x05, 0x13, 0x15, 0x09, 0x17, 0x18, 0x19, 0x41, 0x42 },
- { 0x0f, 0x10, 0x12, 0x14, 0x22, 0x16, 0x24, 0x25, -1 , -1 , -1 },
- { 0x3c, 0x11, 0x1f, 0x21, 0x2f, 0x23, 0x32, 0x26, -1 , 0x36, -1 },
- { 0x3b, 0x1e, 0x20, 0x2e, 0x30, 0x31, 0x34, -1 , 0x1c, 0x2a, -1 },
- { 0x44, 0x2c, 0x2d, 0x0c, 0x39, 0x33, -1 , 0x48, -1 , -1 , 0x38 },
- { 0x37, 0x3d, -1 , 0x45, 0x57, 0x58, 0x4b, 0x50, 0x4d, -1 , -1 },
- { 0x52, 0x43, 0x01, 0x47, 0x49, -1 , -1 , -1 , -1 , -1 , -1 },
-};
-
-#define SPITZ_GPIO_AK_INT 13 /* Remote control */
-#define SPITZ_GPIO_SYNC 16 /* Sync button */
-#define SPITZ_GPIO_ON_KEY 95 /* Power button */
-#define SPITZ_GPIO_SWA 97 /* Lid */
-#define SPITZ_GPIO_SWB 96 /* Tablet mode */
-
-/* The special buttons are mapped to unused keys */
-static const int spitz_gpiomap[5] = {
- SPITZ_GPIO_AK_INT, SPITZ_GPIO_SYNC, SPITZ_GPIO_ON_KEY,
- SPITZ_GPIO_SWA, SPITZ_GPIO_SWB,
-};
-
-#define TYPE_SPITZ_KEYBOARD "spitz-keyboard"
-#define SPITZ_KEYBOARD(obj) \
- OBJECT_CHECK(SpitzKeyboardState, (obj), TYPE_SPITZ_KEYBOARD)
-
-typedef struct {
- SysBusDevice parent_obj;
-
- qemu_irq sense[SPITZ_KEY_SENSE_NUM];
- qemu_irq gpiomap[5];
- int keymap[0x80];
- uint16_t keyrow[SPITZ_KEY_SENSE_NUM];
- uint16_t strobe_state;
- uint16_t sense_state;
-
- uint16_t pre_map[0x100];
- uint16_t modifiers;
- uint16_t imodifiers;
- uint8_t fifo[16];
- int fifopos, fifolen;
- QEMUTimer *kbdtimer;
-} SpitzKeyboardState;
-
-static void spitz_keyboard_sense_update(SpitzKeyboardState *s)
-{
- int i;
- uint16_t strobe, sense = 0;
- for (i = 0; i < SPITZ_KEY_SENSE_NUM; i ++) {
- strobe = s->keyrow[i] & s->strobe_state;
- if (strobe) {
- sense |= 1 << i;
- if (!(s->sense_state & (1 << i)))
- qemu_irq_raise(s->sense[i]);
- } else if (s->sense_state & (1 << i))
- qemu_irq_lower(s->sense[i]);
- }
-
- s->sense_state = sense;
-}
-
-static void spitz_keyboard_strobe(void *opaque, int line, int level)
-{
- SpitzKeyboardState *s = (SpitzKeyboardState *) opaque;
-
- if (level)
- s->strobe_state |= 1 << line;
- else
- s->strobe_state &= ~(1 << line);
- spitz_keyboard_sense_update(s);
-}
-
-static void spitz_keyboard_keydown(SpitzKeyboardState *s, int keycode)
-{
- int spitz_keycode = s->keymap[keycode & 0x7f];
- if (spitz_keycode == -1)
- return;
-
- /* Handle the additional keys */
- if ((spitz_keycode >> 4) == SPITZ_KEY_SENSE_NUM) {
- qemu_set_irq(s->gpiomap[spitz_keycode & 0xf], (keycode < 0x80));
- return;
- }
-
- if (keycode & 0x80)
- s->keyrow[spitz_keycode >> 4] &= ~(1 << (spitz_keycode & 0xf));
- else
- s->keyrow[spitz_keycode >> 4] |= 1 << (spitz_keycode & 0xf);
-
- spitz_keyboard_sense_update(s);
-}
-
-#define SPITZ_MOD_SHIFT (1 << 7)
-#define SPITZ_MOD_CTRL (1 << 8)
-#define SPITZ_MOD_FN (1 << 9)
-
-#define QUEUE_KEY(c) s->fifo[(s->fifopos + s->fifolen ++) & 0xf] = c
-
-static void spitz_keyboard_handler(void *opaque, int keycode)
-{
- SpitzKeyboardState *s = opaque;
- uint16_t code;
- int mapcode;
- switch (keycode) {
- case 0x2a: /* Left Shift */
- s->modifiers |= 1;
- break;
- case 0xaa:
- s->modifiers &= ~1;
- break;
- case 0x36: /* Right Shift */
- s->modifiers |= 2;
- break;
- case 0xb6:
- s->modifiers &= ~2;
- break;
- case 0x1d: /* Control */
- s->modifiers |= 4;
- break;
- case 0x9d:
- s->modifiers &= ~4;
- break;
- case 0x38: /* Alt */
- s->modifiers |= 8;
- break;
- case 0xb8:
- s->modifiers &= ~8;
- break;
- }
-
- code = s->pre_map[mapcode = ((s->modifiers & 3) ?
- (keycode | SPITZ_MOD_SHIFT) :
- (keycode & ~SPITZ_MOD_SHIFT))];
-
- if (code != mapcode) {
-#if 0
- if ((code & SPITZ_MOD_SHIFT) && !(s->modifiers & 1)) {
- QUEUE_KEY(0x2a | (keycode & 0x80));
- }
- if ((code & SPITZ_MOD_CTRL) && !(s->modifiers & 4)) {
- QUEUE_KEY(0x1d | (keycode & 0x80));
- }
- if ((code & SPITZ_MOD_FN) && !(s->modifiers & 8)) {
- QUEUE_KEY(0x38 | (keycode & 0x80));
- }
- if ((code & SPITZ_MOD_FN) && (s->modifiers & 1)) {
- QUEUE_KEY(0x2a | (~keycode & 0x80));
- }
- if ((code & SPITZ_MOD_FN) && (s->modifiers & 2)) {
- QUEUE_KEY(0x36 | (~keycode & 0x80));
- }
-#else
- if (keycode & 0x80) {
- if ((s->imodifiers & 1 ) && !(s->modifiers & 1))
- QUEUE_KEY(0x2a | 0x80);
- if ((s->imodifiers & 4 ) && !(s->modifiers & 4))
- QUEUE_KEY(0x1d | 0x80);
- if ((s->imodifiers & 8 ) && !(s->modifiers & 8))
- QUEUE_KEY(0x38 | 0x80);
- if ((s->imodifiers & 0x10) && (s->modifiers & 1))
- QUEUE_KEY(0x2a);
- if ((s->imodifiers & 0x20) && (s->modifiers & 2))
- QUEUE_KEY(0x36);
- s->imodifiers = 0;
- } else {
- if ((code & SPITZ_MOD_SHIFT) &&
- !((s->modifiers | s->imodifiers) & 1)) {
- QUEUE_KEY(0x2a);
- s->imodifiers |= 1;
- }
- if ((code & SPITZ_MOD_CTRL) &&
- !((s->modifiers | s->imodifiers) & 4)) {
- QUEUE_KEY(0x1d);
- s->imodifiers |= 4;
- }
- if ((code & SPITZ_MOD_FN) &&
- !((s->modifiers | s->imodifiers) & 8)) {
- QUEUE_KEY(0x38);
- s->imodifiers |= 8;
- }
- if ((code & SPITZ_MOD_FN) && (s->modifiers & 1) &&
- !(s->imodifiers & 0x10)) {
- QUEUE_KEY(0x2a | 0x80);
- s->imodifiers |= 0x10;
- }
- if ((code & SPITZ_MOD_FN) && (s->modifiers & 2) &&
- !(s->imodifiers & 0x20)) {
- QUEUE_KEY(0x36 | 0x80);
- s->imodifiers |= 0x20;
- }
- }
-#endif
- }
-
- QUEUE_KEY((code & 0x7f) | (keycode & 0x80));
-}
-
-static void spitz_keyboard_tick(void *opaque)
-{
- SpitzKeyboardState *s = (SpitzKeyboardState *) opaque;
-
- if (s->fifolen) {
- spitz_keyboard_keydown(s, s->fifo[s->fifopos ++]);
- s->fifolen --;
- if (s->fifopos >= 16)
- s->fifopos = 0;
- }
-
- timer_mod(s->kbdtimer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
- NANOSECONDS_PER_SECOND / 32);
-}
-
-static void spitz_keyboard_pre_map(SpitzKeyboardState *s)
-{
- int i;
- for (i = 0; i < 0x100; i ++)
- s->pre_map[i] = i;
- s->pre_map[0x02 | SPITZ_MOD_SHIFT] = 0x02 | SPITZ_MOD_SHIFT; /* exclam */
- s->pre_map[0x28 | SPITZ_MOD_SHIFT] = 0x03 | SPITZ_MOD_SHIFT; /* quotedbl */
- s->pre_map[0x04 | SPITZ_MOD_SHIFT] = 0x04 | SPITZ_MOD_SHIFT; /* # */
- s->pre_map[0x05 | SPITZ_MOD_SHIFT] = 0x05 | SPITZ_MOD_SHIFT; /* dollar */
- s->pre_map[0x06 | SPITZ_MOD_SHIFT] = 0x06 | SPITZ_MOD_SHIFT; /* percent */
- s->pre_map[0x08 | SPITZ_MOD_SHIFT] = 0x07 | SPITZ_MOD_SHIFT; /* ampersand */
- s->pre_map[0x28] = 0x08 | SPITZ_MOD_SHIFT; /* ' */
- s->pre_map[0x0a | SPITZ_MOD_SHIFT] = 0x09 | SPITZ_MOD_SHIFT; /* ( */
- s->pre_map[0x0b | SPITZ_MOD_SHIFT] = 0x0a | SPITZ_MOD_SHIFT; /* ) */
- s->pre_map[0x29 | SPITZ_MOD_SHIFT] = 0x0b | SPITZ_MOD_SHIFT; /* tilde */
- s->pre_map[0x03 | SPITZ_MOD_SHIFT] = 0x0c | SPITZ_MOD_SHIFT; /* at */
- s->pre_map[0xd3] = 0x0e | SPITZ_MOD_FN; /* Delete */
- s->pre_map[0x3a] = 0x0f | SPITZ_MOD_FN; /* Caps_Lock */
- s->pre_map[0x07 | SPITZ_MOD_SHIFT] = 0x11 | SPITZ_MOD_FN; /* ^ */
- s->pre_map[0x0d] = 0x12 | SPITZ_MOD_FN; /* equal */
- s->pre_map[0x0d | SPITZ_MOD_SHIFT] = 0x13 | SPITZ_MOD_FN; /* plus */
- s->pre_map[0x1a] = 0x14 | SPITZ_MOD_FN; /* [ */
- s->pre_map[0x1b] = 0x15 | SPITZ_MOD_FN; /* ] */
- s->pre_map[0x1a | SPITZ_MOD_SHIFT] = 0x16 | SPITZ_MOD_FN; /* { */
- s->pre_map[0x1b | SPITZ_MOD_SHIFT] = 0x17 | SPITZ_MOD_FN; /* } */
- s->pre_map[0x27] = 0x22 | SPITZ_MOD_FN; /* semicolon */
- s->pre_map[0x27 | SPITZ_MOD_SHIFT] = 0x23 | SPITZ_MOD_FN; /* colon */
- s->pre_map[0x09 | SPITZ_MOD_SHIFT] = 0x24 | SPITZ_MOD_FN; /* asterisk */
- s->pre_map[0x2b] = 0x25 | SPITZ_MOD_FN; /* backslash */
- s->pre_map[0x2b | SPITZ_MOD_SHIFT] = 0x26 | SPITZ_MOD_FN; /* bar */
- s->pre_map[0x0c | SPITZ_MOD_SHIFT] = 0x30 | SPITZ_MOD_FN; /* _ */
- s->pre_map[0x33 | SPITZ_MOD_SHIFT] = 0x33 | SPITZ_MOD_FN; /* less */
- s->pre_map[0x35] = 0x33 | SPITZ_MOD_SHIFT; /* slash */
- s->pre_map[0x34 | SPITZ_MOD_SHIFT] = 0x34 | SPITZ_MOD_FN; /* greater */
- s->pre_map[0x35 | SPITZ_MOD_SHIFT] = 0x34 | SPITZ_MOD_SHIFT; /* question */
- s->pre_map[0x49] = 0x48 | SPITZ_MOD_FN; /* Page_Up */
- s->pre_map[0x51] = 0x50 | SPITZ_MOD_FN; /* Page_Down */
-
- s->modifiers = 0;
- s->imodifiers = 0;
- s->fifopos = 0;
- s->fifolen = 0;
-}
-
-#undef SPITZ_MOD_SHIFT
-#undef SPITZ_MOD_CTRL
-#undef SPITZ_MOD_FN
-
-static int spitz_keyboard_post_load(void *opaque, int version_id)
-{
- SpitzKeyboardState *s = (SpitzKeyboardState *) opaque;
-
- /* Release all pressed keys */
- memset(s->keyrow, 0, sizeof(s->keyrow));
- spitz_keyboard_sense_update(s);
- s->modifiers = 0;
- s->imodifiers = 0;
- s->fifopos = 0;
- s->fifolen = 0;
-
- return 0;
-}
-
-static void spitz_keyboard_register(PXA2xxState *cpu)
-{
- int i;
- DeviceState *dev;
- SpitzKeyboardState *s;
-
- dev = sysbus_create_simple(TYPE_SPITZ_KEYBOARD, -1, NULL);
- s = SPITZ_KEYBOARD(dev);
-
- for (i = 0; i < SPITZ_KEY_SENSE_NUM; i ++)
- qdev_connect_gpio_out(dev, i, qdev_get_gpio_in(cpu->gpio, spitz_gpio_key_sense[i]));
-
- for (i = 0; i < 5; i ++)
- s->gpiomap[i] = qdev_get_gpio_in(cpu->gpio, spitz_gpiomap[i]);
-
- if (!graphic_rotate)
- s->gpiomap[4] = qemu_irq_invert(s->gpiomap[4]);
-
- for (i = 0; i < 5; i++)
- qemu_set_irq(s->gpiomap[i], 0);
-
- for (i = 0; i < SPITZ_KEY_STROBE_NUM; i ++)
- qdev_connect_gpio_out(cpu->gpio, spitz_gpio_key_strobe[i],
- qdev_get_gpio_in(dev, i));
-
- timer_mod(s->kbdtimer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
-
- qemu_add_kbd_event_handler(spitz_keyboard_handler, s);
-}
-
-static int spitz_keyboard_init(SysBusDevice *sbd)
-{
- DeviceState *dev = DEVICE(sbd);
- SpitzKeyboardState *s = SPITZ_KEYBOARD(dev);
- int i, j;
-
- for (i = 0; i < 0x80; i ++)
- s->keymap[i] = -1;
- for (i = 0; i < SPITZ_KEY_SENSE_NUM + 1; i ++)
- for (j = 0; j < SPITZ_KEY_STROBE_NUM; j ++)
- if (spitz_keymap[i][j] != -1)
- s->keymap[spitz_keymap[i][j]] = (i << 4) | j;
-
- spitz_keyboard_pre_map(s);
-
- s->kbdtimer = timer_new_ns(QEMU_CLOCK_VIRTUAL, spitz_keyboard_tick, s);
- qdev_init_gpio_in(dev, spitz_keyboard_strobe, SPITZ_KEY_STROBE_NUM);
- qdev_init_gpio_out(dev, s->sense, SPITZ_KEY_SENSE_NUM);
-
- return 0;
-}
-
-/* LCD backlight controller */
-
-#define LCDTG_RESCTL 0x00
-#define LCDTG_PHACTRL 0x01
-#define LCDTG_DUTYCTRL 0x02
-#define LCDTG_POWERREG0 0x03
-#define LCDTG_POWERREG1 0x04
-#define LCDTG_GPOR3 0x05
-#define LCDTG_PICTRL 0x06
-#define LCDTG_POLCTRL 0x07
-
-typedef struct {
- SSISlave ssidev;
- uint32_t bl_intensity;
- uint32_t bl_power;
-} SpitzLCDTG;
-
-static void spitz_bl_update(SpitzLCDTG *s)
-{
- if (s->bl_power && s->bl_intensity)
- zaurus_printf("LCD Backlight now at %i/63\n", s->bl_intensity);
- else
- zaurus_printf("LCD Backlight now off\n");
-}
-
-/* FIXME: Implement GPIO properly and remove this hack. */
-static SpitzLCDTG *spitz_lcdtg;
-
-static inline void spitz_bl_bit5(void *opaque, int line, int level)
-{
- SpitzLCDTG *s = spitz_lcdtg;
- int prev = s->bl_intensity;
-
- if (level)
- s->bl_intensity &= ~0x20;
- else
- s->bl_intensity |= 0x20;
-
- if (s->bl_power && prev != s->bl_intensity)
- spitz_bl_update(s);
-}
-
-static inline void spitz_bl_power(void *opaque, int line, int level)
-{
- SpitzLCDTG *s = spitz_lcdtg;
- s->bl_power = !!level;
- spitz_bl_update(s);
-}
-
-static uint32_t spitz_lcdtg_transfer(SSISlave *dev, uint32_t value)
-{
- SpitzLCDTG *s = FROM_SSI_SLAVE(SpitzLCDTG, dev);
- int addr;
- addr = value >> 5;
- value &= 0x1f;
-
- switch (addr) {
- case LCDTG_RESCTL:
- if (value)
- zaurus_printf("LCD in QVGA mode\n");
- else
- zaurus_printf("LCD in VGA mode\n");
- break;
-
- case LCDTG_DUTYCTRL:
- s->bl_intensity &= ~0x1f;
- s->bl_intensity |= value;
- if (s->bl_power)
- spitz_bl_update(s);
- break;
-
- case LCDTG_POWERREG0:
- /* Set common voltage to M62332FP */
- break;
- }
- return 0;
-}
-
-static int spitz_lcdtg_init(SSISlave *dev)
-{
- SpitzLCDTG *s = FROM_SSI_SLAVE(SpitzLCDTG, dev);
-
- spitz_lcdtg = s;
- s->bl_power = 0;
- s->bl_intensity = 0x20;
-
- return 0;
-}
-
-/* SSP devices */
-
-#define CORGI_SSP_PORT 2
-
-#define SPITZ_GPIO_LCDCON_CS 53
-#define SPITZ_GPIO_ADS7846_CS 14
-#define SPITZ_GPIO_MAX1111_CS 20
-#define SPITZ_GPIO_TP_INT 11
-
-static DeviceState *max1111;
-
-/* "Demux" the signal based on current chipselect */
-typedef struct {
- SSISlave ssidev;
- SSIBus *bus[3];
- uint32_t enable[3];
-} CorgiSSPState;
-
-static uint32_t corgi_ssp_transfer(SSISlave *dev, uint32_t value)
-{
- CorgiSSPState *s = FROM_SSI_SLAVE(CorgiSSPState, dev);
- int i;
-
- for (i = 0; i < 3; i++) {
- if (s->enable[i]) {
- return ssi_transfer(s->bus[i], value);
- }
- }
- return 0;
-}
-
-static void corgi_ssp_gpio_cs(void *opaque, int line, int level)
-{
- CorgiSSPState *s = (CorgiSSPState *)opaque;
- assert(line >= 0 && line < 3);
- s->enable[line] = !level;
-}
-
-#define MAX1111_BATT_VOLT 1
-#define MAX1111_BATT_TEMP 2
-#define MAX1111_ACIN_VOLT 3
-
-#define SPITZ_BATTERY_TEMP 0xe0 /* About 2.9V */
-#define SPITZ_BATTERY_VOLT 0xd0 /* About 4.0V */
-#define SPITZ_CHARGEON_ACIN 0x80 /* About 5.0V */
-
-static void spitz_adc_temp_on(void *opaque, int line, int level)
-{
- if (!max1111)
- return;
-
- if (level)
- max111x_set_input(max1111, MAX1111_BATT_TEMP, SPITZ_BATTERY_TEMP);
- else
- max111x_set_input(max1111, MAX1111_BATT_TEMP, 0);
-}
-
-static int corgi_ssp_init(SSISlave *d)
-{
- DeviceState *dev = DEVICE(d);
- CorgiSSPState *s = FROM_SSI_SLAVE(CorgiSSPState, d);
-
- qdev_init_gpio_in(dev, corgi_ssp_gpio_cs, 3);
- s->bus[0] = ssi_create_bus(dev, "ssi0");
- s->bus[1] = ssi_create_bus(dev, "ssi1");
- s->bus[2] = ssi_create_bus(dev, "ssi2");
-
- return 0;
-}
-
-static void spitz_ssp_attach(PXA2xxState *cpu)
-{
- DeviceState *mux;
- DeviceState *dev;
- void *bus;
-
- mux = ssi_create_slave(cpu->ssp[CORGI_SSP_PORT - 1], "corgi-ssp");
-
- bus = qdev_get_child_bus(mux, "ssi0");
- ssi_create_slave(bus, "spitz-lcdtg");
-
- bus = qdev_get_child_bus(mux, "ssi1");
- dev = ssi_create_slave(bus, "ads7846");
- qdev_connect_gpio_out(dev, 0,
- qdev_get_gpio_in(cpu->gpio, SPITZ_GPIO_TP_INT));
-
- bus = qdev_get_child_bus(mux, "ssi2");
- max1111 = ssi_create_slave(bus, "max1111");
- max111x_set_input(max1111, MAX1111_BATT_VOLT, SPITZ_BATTERY_VOLT);
- max111x_set_input(max1111, MAX1111_BATT_TEMP, 0);
- max111x_set_input(max1111, MAX1111_ACIN_VOLT, SPITZ_CHARGEON_ACIN);
-
- qdev_connect_gpio_out(cpu->gpio, SPITZ_GPIO_LCDCON_CS,
- qdev_get_gpio_in(mux, 0));
- qdev_connect_gpio_out(cpu->gpio, SPITZ_GPIO_ADS7846_CS,
- qdev_get_gpio_in(mux, 1));
- qdev_connect_gpio_out(cpu->gpio, SPITZ_GPIO_MAX1111_CS,
- qdev_get_gpio_in(mux, 2));
-}
-
-/* CF Microdrive */
-
-static void spitz_microdrive_attach(PXA2xxState *cpu, int slot)
-{
- PCMCIACardState *md;
- DriveInfo *dinfo;
-
- dinfo = drive_get(IF_IDE, 0, 0);
- if (!dinfo || dinfo->media_cd)
- return;
- md = dscm1xxxx_init(dinfo);
- pxa2xx_pcmcia_attach(cpu->pcmcia[slot], md);
-}
-
-/* Wm8750 and Max7310 on I2C */
-
-#define AKITA_MAX_ADDR 0x18
-#define SPITZ_WM_ADDRL 0x1b
-#define SPITZ_WM_ADDRH 0x1a
-
-#define SPITZ_GPIO_WM 5
-
-static void spitz_wm8750_addr(void *opaque, int line, int level)
-{
- I2CSlave *wm = (I2CSlave *) opaque;
- if (level)
- i2c_set_slave_address(wm, SPITZ_WM_ADDRH);
- else
- i2c_set_slave_address(wm, SPITZ_WM_ADDRL);
-}
-
-static void spitz_i2c_setup(PXA2xxState *cpu)
-{
- /* Attach the CPU on one end of our I2C bus. */
- I2CBus *bus = pxa2xx_i2c_bus(cpu->i2c[0]);
-
- DeviceState *wm;
-
- /* Attach a WM8750 to the bus */
- wm = i2c_create_slave(bus, "wm8750", 0);
-
- spitz_wm8750_addr(wm, 0, 0);
- qdev_connect_gpio_out(cpu->gpio, SPITZ_GPIO_WM,
- qemu_allocate_irq(spitz_wm8750_addr, wm, 0));
- /* .. and to the sound interface. */
- cpu->i2s->opaque = wm;
- cpu->i2s->codec_out = wm8750_dac_dat;
- cpu->i2s->codec_in = wm8750_adc_dat;
- wm8750_data_req_set(wm, cpu->i2s->data_req, cpu->i2s);
-}
-
-static void spitz_akita_i2c_setup(PXA2xxState *cpu)
-{
- /* Attach a Max7310 to Akita I2C bus. */
- i2c_create_slave(pxa2xx_i2c_bus(cpu->i2c[0]), "max7310",
- AKITA_MAX_ADDR);
-}
-
-/* Other peripherals */
-
-static void spitz_out_switch(void *opaque, int line, int level)
-{
- switch (line) {
- case 0:
- zaurus_printf("Charging %s.\n", level ? "off" : "on");
- break;
- case 1:
- zaurus_printf("Discharging %s.\n", level ? "on" : "off");
- break;
- case 2:
- zaurus_printf("Green LED %s.\n", level ? "on" : "off");
- break;
- case 3:
- zaurus_printf("Orange LED %s.\n", level ? "on" : "off");
- break;
- case 4:
- spitz_bl_bit5(opaque, line, level);
- break;
- case 5:
- spitz_bl_power(opaque, line, level);
- break;
- case 6:
- spitz_adc_temp_on(opaque, line, level);
- break;
- }
-}
-
-#define SPITZ_SCP_LED_GREEN 1
-#define SPITZ_SCP_JK_B 2
-#define SPITZ_SCP_CHRG_ON 3
-#define SPITZ_SCP_MUTE_L 4
-#define SPITZ_SCP_MUTE_R 5
-#define SPITZ_SCP_CF_POWER 6
-#define SPITZ_SCP_LED_ORANGE 7
-#define SPITZ_SCP_JK_A 8
-#define SPITZ_SCP_ADC_TEMP_ON 9
-#define SPITZ_SCP2_IR_ON 1
-#define SPITZ_SCP2_AKIN_PULLUP 2
-#define SPITZ_SCP2_BACKLIGHT_CONT 7
-#define SPITZ_SCP2_BACKLIGHT_ON 8
-#define SPITZ_SCP2_MIC_BIAS 9
-
-static void spitz_scoop_gpio_setup(PXA2xxState *cpu,
- DeviceState *scp0, DeviceState *scp1)
-{
- qemu_irq *outsignals = qemu_allocate_irqs(spitz_out_switch, cpu, 8);
-
- qdev_connect_gpio_out(scp0, SPITZ_SCP_CHRG_ON, outsignals[0]);
- qdev_connect_gpio_out(scp0, SPITZ_SCP_JK_B, outsignals[1]);
- qdev_connect_gpio_out(scp0, SPITZ_SCP_LED_GREEN, outsignals[2]);
- qdev_connect_gpio_out(scp0, SPITZ_SCP_LED_ORANGE, outsignals[3]);
-
- if (scp1) {
- qdev_connect_gpio_out(scp1, SPITZ_SCP2_BACKLIGHT_CONT, outsignals[4]);
- qdev_connect_gpio_out(scp1, SPITZ_SCP2_BACKLIGHT_ON, outsignals[5]);
- }
-
- qdev_connect_gpio_out(scp0, SPITZ_SCP_ADC_TEMP_ON, outsignals[6]);
-}
-
-#define SPITZ_GPIO_HSYNC 22
-#define SPITZ_GPIO_SD_DETECT 9
-#define SPITZ_GPIO_SD_WP 81
-#define SPITZ_GPIO_ON_RESET 89
-#define SPITZ_GPIO_BAT_COVER 90
-#define SPITZ_GPIO_CF1_IRQ 105
-#define SPITZ_GPIO_CF1_CD 94
-#define SPITZ_GPIO_CF2_IRQ 106
-#define SPITZ_GPIO_CF2_CD 93
-
-static int spitz_hsync;
-
-static void spitz_lcd_hsync_handler(void *opaque, int line, int level)
-{
- PXA2xxState *cpu = (PXA2xxState *) opaque;
- qemu_set_irq(qdev_get_gpio_in(cpu->gpio, SPITZ_GPIO_HSYNC), spitz_hsync);
- spitz_hsync ^= 1;
-}
-
-static void spitz_gpio_setup(PXA2xxState *cpu, int slots)
-{
- qemu_irq lcd_hsync;
- /*
- * Bad hack: We toggle the LCD hsync GPIO on every GPIO status
- * read to satisfy broken guests that poll-wait for hsync.
- * Simulating a real hsync event would be less practical and
- * wouldn't guarantee that a guest ever exits the loop.
- */
- spitz_hsync = 0;
- lcd_hsync = qemu_allocate_irq(spitz_lcd_hsync_handler, cpu, 0);
- pxa2xx_gpio_read_notifier(cpu->gpio, lcd_hsync);
- pxa2xx_lcd_vsync_notifier(cpu->lcd, lcd_hsync);
-
- /* MMC/SD host */
- pxa2xx_mmci_handlers(cpu->mmc,
- qdev_get_gpio_in(cpu->gpio, SPITZ_GPIO_SD_WP),
- qdev_get_gpio_in(cpu->gpio, SPITZ_GPIO_SD_DETECT));
-
- /* Battery lock always closed */
- qemu_irq_raise(qdev_get_gpio_in(cpu->gpio, SPITZ_GPIO_BAT_COVER));
-
- /* Handle reset */
- qdev_connect_gpio_out(cpu->gpio, SPITZ_GPIO_ON_RESET, cpu->reset);
-
- /* PCMCIA signals: card's IRQ and Card-Detect */
- if (slots >= 1)
- pxa2xx_pcmcia_set_irq_cb(cpu->pcmcia[0],
- qdev_get_gpio_in(cpu->gpio, SPITZ_GPIO_CF1_IRQ),
- qdev_get_gpio_in(cpu->gpio, SPITZ_GPIO_CF1_CD));
- if (slots >= 2)
- pxa2xx_pcmcia_set_irq_cb(cpu->pcmcia[1],
- qdev_get_gpio_in(cpu->gpio, SPITZ_GPIO_CF2_IRQ),
- qdev_get_gpio_in(cpu->gpio, SPITZ_GPIO_CF2_CD));
-}
-
-/* Board init. */
-enum spitz_model_e { spitz, akita, borzoi, terrier };
-
-#define SPITZ_RAM 0x04000000
-#define SPITZ_ROM 0x00800000
-
-static struct arm_boot_info spitz_binfo = {
- .loader_start = PXA2XX_SDRAM_BASE,
- .ram_size = 0x04000000,
-};
-
-static void spitz_common_init(MachineState *machine,
- enum spitz_model_e model, int arm_id)
-{
- PXA2xxState *mpu;
- DeviceState *scp0, *scp1 = NULL;
- MemoryRegion *address_space_mem = get_system_memory();
- MemoryRegion *rom = g_new(MemoryRegion, 1);
- const char *cpu_model = machine->cpu_model;
-
- if (!cpu_model)
- cpu_model = (model == terrier) ? "pxa270-c5" : "pxa270-c0";
-
- /* Setup CPU & memory */
- mpu = pxa270_init(address_space_mem, spitz_binfo.ram_size, cpu_model);
-
- sl_flash_register(mpu, (model == spitz) ? FLASH_128M : FLASH_1024M);
-
- memory_region_init_ram(rom, NULL, "spitz.rom", SPITZ_ROM, &error_fatal);
- vmstate_register_ram_global(rom);
- memory_region_set_readonly(rom, true);
- memory_region_add_subregion(address_space_mem, 0, rom);
-
- /* Setup peripherals */
- spitz_keyboard_register(mpu);
-
- spitz_ssp_attach(mpu);
-
- scp0 = sysbus_create_simple("scoop", 0x10800000, NULL);
- if (model != akita) {
- scp1 = sysbus_create_simple("scoop", 0x08800040, NULL);
- }
-
- spitz_scoop_gpio_setup(mpu, scp0, scp1);
-
- spitz_gpio_setup(mpu, (model == akita) ? 1 : 2);
-
- spitz_i2c_setup(mpu);
-
- if (model == akita)
- spitz_akita_i2c_setup(mpu);
-
- if (model == terrier)
- /* A 6.0 GB microdrive is permanently sitting in CF slot 1. */
- spitz_microdrive_attach(mpu, 1);
- else if (model != akita)
- /* A 4.0 GB microdrive is permanently sitting in CF slot 0. */
- spitz_microdrive_attach(mpu, 0);
-
- spitz_binfo.kernel_filename = machine->kernel_filename;
- spitz_binfo.kernel_cmdline = machine->kernel_cmdline;
- spitz_binfo.initrd_filename = machine->initrd_filename;
- spitz_binfo.board_id = arm_id;
- arm_load_kernel(mpu->cpu, &spitz_binfo);
- sl_bootparam_write(SL_PXA_PARAM_BASE);
-}
-
-static void spitz_init(MachineState *machine)
-{
- spitz_common_init(machine, spitz, 0x2c9);
-}
-
-static void borzoi_init(MachineState *machine)
-{
- spitz_common_init(machine, borzoi, 0x33f);
-}
-
-static void akita_init(MachineState *machine)
-{
- spitz_common_init(machine, akita, 0x2e8);
-}
-
-static void terrier_init(MachineState *machine)
-{
- spitz_common_init(machine, terrier, 0x33f);
-}
-
-static void akitapda_class_init(ObjectClass *oc, void *data)
-{
- MachineClass *mc = MACHINE_CLASS(oc);
-
- mc->desc = "Sharp SL-C1000 (Akita) PDA (PXA270)";
- mc->init = akita_init;
-}
-
-static const TypeInfo akitapda_type = {
- .name = MACHINE_TYPE_NAME("akita"),
- .parent = TYPE_MACHINE,
- .class_init = akitapda_class_init,
-};
-
-static void spitzpda_class_init(ObjectClass *oc, void *data)
-{
- MachineClass *mc = MACHINE_CLASS(oc);
-
- mc->desc = "Sharp SL-C3000 (Spitz) PDA (PXA270)";
- mc->init = spitz_init;
-}
-
-static const TypeInfo spitzpda_type = {
- .name = MACHINE_TYPE_NAME("spitz"),
- .parent = TYPE_MACHINE,
- .class_init = spitzpda_class_init,
-};
-
-static void borzoipda_class_init(ObjectClass *oc, void *data)
-{
- MachineClass *mc = MACHINE_CLASS(oc);
-
- mc->desc = "Sharp SL-C3100 (Borzoi) PDA (PXA270)";
- mc->init = borzoi_init;
-}
-
-static const TypeInfo borzoipda_type = {
- .name = MACHINE_TYPE_NAME("borzoi"),
- .parent = TYPE_MACHINE,
- .class_init = borzoipda_class_init,
-};
-
-static void terrierpda_class_init(ObjectClass *oc, void *data)
-{
- MachineClass *mc = MACHINE_CLASS(oc);
-
- mc->desc = "Sharp SL-C3200 (Terrier) PDA (PXA270)";
- mc->init = terrier_init;
-}
-
-static const TypeInfo terrierpda_type = {
- .name = MACHINE_TYPE_NAME("terrier"),
- .parent = TYPE_MACHINE,
- .class_init = terrierpda_class_init,
-};
-
-static void spitz_machine_init(void)
-{
- type_register_static(&akitapda_type);
- type_register_static(&spitzpda_type);
- type_register_static(&borzoipda_type);
- type_register_static(&terrierpda_type);
-}
-
-type_init(spitz_machine_init)
-
-static bool is_version_0(void *opaque, int version_id)
-{
- return version_id == 0;
-}
-
-static VMStateDescription vmstate_sl_nand_info = {
- .name = "sl-nand",
- .version_id = 0,
- .minimum_version_id = 0,
- .fields = (VMStateField[]) {
- VMSTATE_UINT8(ctl, SLNANDState),
- VMSTATE_STRUCT(ecc, SLNANDState, 0, vmstate_ecc_state, ECCState),
- VMSTATE_END_OF_LIST(),
- },
-};
-
-static Property sl_nand_properties[] = {
- DEFINE_PROP_UINT8("manf_id", SLNANDState, manf_id, NAND_MFR_SAMSUNG),
- DEFINE_PROP_UINT8("chip_id", SLNANDState, chip_id, 0xf1),
- DEFINE_PROP_END_OF_LIST(),
-};
-
-static void sl_nand_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
-
- k->init = sl_nand_init;
- dc->vmsd = &vmstate_sl_nand_info;
- dc->props = sl_nand_properties;
- /* Reason: init() method uses drive_get() */
- dc->cannot_instantiate_with_device_add_yet = true;
-}
-
-static const TypeInfo sl_nand_info = {
- .name = TYPE_SL_NAND,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(SLNANDState),
- .class_init = sl_nand_class_init,
-};
-
-static VMStateDescription vmstate_spitz_kbd = {
- .name = "spitz-keyboard",
- .version_id = 1,
- .minimum_version_id = 0,
- .post_load = spitz_keyboard_post_load,
- .fields = (VMStateField[]) {
- VMSTATE_UINT16(sense_state, SpitzKeyboardState),
- VMSTATE_UINT16(strobe_state, SpitzKeyboardState),
- VMSTATE_UNUSED_TEST(is_version_0, 5),
- VMSTATE_END_OF_LIST(),
- },
-};
-
-static void spitz_keyboard_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
-
- k->init = spitz_keyboard_init;
- dc->vmsd = &vmstate_spitz_kbd;
-}
-
-static const TypeInfo spitz_keyboard_info = {
- .name = TYPE_SPITZ_KEYBOARD,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(SpitzKeyboardState),
- .class_init = spitz_keyboard_class_init,
-};
-
-static const VMStateDescription vmstate_corgi_ssp_regs = {
- .name = "corgi-ssp",
- .version_id = 2,
- .minimum_version_id = 2,
- .fields = (VMStateField[]) {
- VMSTATE_SSI_SLAVE(ssidev, CorgiSSPState),
- VMSTATE_UINT32_ARRAY(enable, CorgiSSPState, 3),
- VMSTATE_END_OF_LIST(),
- }
-};
-
-static void corgi_ssp_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
- SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
-
- k->init = corgi_ssp_init;
- k->transfer = corgi_ssp_transfer;
- dc->vmsd = &vmstate_corgi_ssp_regs;
-}
-
-static const TypeInfo corgi_ssp_info = {
- .name = "corgi-ssp",
- .parent = TYPE_SSI_SLAVE,
- .instance_size = sizeof(CorgiSSPState),
- .class_init = corgi_ssp_class_init,
-};
-
-static const VMStateDescription vmstate_spitz_lcdtg_regs = {
- .name = "spitz-lcdtg",
- .version_id = 1,
- .minimum_version_id = 1,
- .fields = (VMStateField[]) {
- VMSTATE_SSI_SLAVE(ssidev, SpitzLCDTG),
- VMSTATE_UINT32(bl_intensity, SpitzLCDTG),
- VMSTATE_UINT32(bl_power, SpitzLCDTG),
- VMSTATE_END_OF_LIST(),
- }
-};
-
-static void spitz_lcdtg_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
- SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
-
- k->init = spitz_lcdtg_init;
- k->transfer = spitz_lcdtg_transfer;
- dc->vmsd = &vmstate_spitz_lcdtg_regs;
-}
-
-static const TypeInfo spitz_lcdtg_info = {
- .name = "spitz-lcdtg",
- .parent = TYPE_SSI_SLAVE,
- .instance_size = sizeof(SpitzLCDTG),
- .class_init = spitz_lcdtg_class_init,
-};
-
-static void spitz_register_types(void)
-{
- type_register_static(&corgi_ssp_info);
- type_register_static(&spitz_lcdtg_info);
- type_register_static(&spitz_keyboard_info);
- type_register_static(&sl_nand_info);
-}
-
-type_init(spitz_register_types)
diff --git a/qemu/hw/arm/stellaris.c b/qemu/hw/arm/stellaris.c
deleted file mode 100644
index c1766f856..000000000
--- a/qemu/hw/arm/stellaris.c
+++ /dev/null
@@ -1,1475 +0,0 @@
-/*
- * Luminary Micro Stellaris peripherals
- *
- * Copyright (c) 2006 CodeSourcery.
- * Written by Paul Brook
- *
- * This code is licensed under the GPL.
- */
-
-#include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "hw/sysbus.h"
-#include "hw/ssi/ssi.h"
-#include "hw/arm/arm.h"
-#include "hw/devices.h"
-#include "qemu/timer.h"
-#include "hw/i2c/i2c.h"
-#include "net/net.h"
-#include "hw/boards.h"
-#include "exec/address-spaces.h"
-#include "sysemu/sysemu.h"
-
-#define GPIO_A 0
-#define GPIO_B 1
-#define GPIO_C 2
-#define GPIO_D 3
-#define GPIO_E 4
-#define GPIO_F 5
-#define GPIO_G 6
-
-#define BP_OLED_I2C 0x01
-#define BP_OLED_SSI 0x02
-#define BP_GAMEPAD 0x04
-
-#define NUM_IRQ_LINES 64
-
-typedef const struct {
- const char *name;
- uint32_t did0;
- uint32_t did1;
- uint32_t dc0;
- uint32_t dc1;
- uint32_t dc2;
- uint32_t dc3;
- uint32_t dc4;
- uint32_t peripherals;
-} stellaris_board_info;
-
-/* General purpose timer module. */
-
-#define TYPE_STELLARIS_GPTM "stellaris-gptm"
-#define STELLARIS_GPTM(obj) \
- OBJECT_CHECK(gptm_state, (obj), TYPE_STELLARIS_GPTM)
-
-typedef struct gptm_state {
- SysBusDevice parent_obj;
-
- MemoryRegion iomem;
- uint32_t config;
- uint32_t mode[2];
- uint32_t control;
- uint32_t state;
- uint32_t mask;
- uint32_t load[2];
- uint32_t match[2];
- uint32_t prescale[2];
- uint32_t match_prescale[2];
- uint32_t rtc;
- int64_t tick[2];
- struct gptm_state *opaque[2];
- QEMUTimer *timer[2];
- /* The timers have an alternate output used to trigger the ADC. */
- qemu_irq trigger;
- qemu_irq irq;
-} gptm_state;
-
-static void gptm_update_irq(gptm_state *s)
-{
- int level;
- level = (s->state & s->mask) != 0;
- qemu_set_irq(s->irq, level);
-}
-
-static void gptm_stop(gptm_state *s, int n)
-{
- timer_del(s->timer[n]);
-}
-
-static void gptm_reload(gptm_state *s, int n, int reset)
-{
- int64_t tick;
- if (reset)
- tick = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
- else
- tick = s->tick[n];
-
- if (s->config == 0) {
- /* 32-bit CountDown. */
- uint32_t count;
- count = s->load[0] | (s->load[1] << 16);
- tick += (int64_t)count * system_clock_scale;
- } else if (s->config == 1) {
- /* 32-bit RTC. 1Hz tick. */
- tick += NANOSECONDS_PER_SECOND;
- } else if (s->mode[n] == 0xa) {
- /* PWM mode. Not implemented. */
- } else {
- hw_error("TODO: 16-bit timer mode 0x%x\n", s->mode[n]);
- }
- s->tick[n] = tick;
- timer_mod(s->timer[n], tick);
-}
-
-static void gptm_tick(void *opaque)
-{
- gptm_state **p = (gptm_state **)opaque;
- gptm_state *s;
- int n;
-
- s = *p;
- n = p - s->opaque;
- if (s->config == 0) {
- s->state |= 1;
- if ((s->control & 0x20)) {
- /* Output trigger. */
- qemu_irq_pulse(s->trigger);
- }
- if (s->mode[0] & 1) {
- /* One-shot. */
- s->control &= ~1;
- } else {
- /* Periodic. */
- gptm_reload(s, 0, 0);
- }
- } else if (s->config == 1) {
- /* RTC. */
- uint32_t match;
- s->rtc++;
- match = s->match[0] | (s->match[1] << 16);
- if (s->rtc > match)
- s->rtc = 0;
- if (s->rtc == 0) {
- s->state |= 8;
- }
- gptm_reload(s, 0, 0);
- } else if (s->mode[n] == 0xa) {
- /* PWM mode. Not implemented. */
- } else {
- hw_error("TODO: 16-bit timer mode 0x%x\n", s->mode[n]);
- }
- gptm_update_irq(s);
-}
-
-static uint64_t gptm_read(void *opaque, hwaddr offset,
- unsigned size)
-{
- gptm_state *s = (gptm_state *)opaque;
-
- switch (offset) {
- case 0x00: /* CFG */
- return s->config;
- case 0x04: /* TAMR */
- return s->mode[0];
- case 0x08: /* TBMR */
- return s->mode[1];
- case 0x0c: /* CTL */
- return s->control;
- case 0x18: /* IMR */
- return s->mask;
- case 0x1c: /* RIS */
- return s->state;
- case 0x20: /* MIS */
- return s->state & s->mask;
- case 0x24: /* CR */
- return 0;
- case 0x28: /* TAILR */
- return s->load[0] | ((s->config < 4) ? (s->load[1] << 16) : 0);
- case 0x2c: /* TBILR */
- return s->load[1];
- case 0x30: /* TAMARCHR */
- return s->match[0] | ((s->config < 4) ? (s->match[1] << 16) : 0);
- case 0x34: /* TBMATCHR */
- return s->match[1];
- case 0x38: /* TAPR */
- return s->prescale[0];
- case 0x3c: /* TBPR */
- return s->prescale[1];
- case 0x40: /* TAPMR */
- return s->match_prescale[0];
- case 0x44: /* TBPMR */
- return s->match_prescale[1];
- case 0x48: /* TAR */
- if (s->config == 1) {
- return s->rtc;
- }
- qemu_log_mask(LOG_UNIMP,
- "GPTM: read of TAR but timer read not supported");
- return 0;
- case 0x4c: /* TBR */
- qemu_log_mask(LOG_UNIMP,
- "GPTM: read of TBR but timer read not supported");
- return 0;
- default:
- qemu_log_mask(LOG_GUEST_ERROR,
- "GPTM: read at bad offset 0x%x\n", (int)offset);
- return 0;
- }
-}
-
-static void gptm_write(void *opaque, hwaddr offset,
- uint64_t value, unsigned size)
-{
- gptm_state *s = (gptm_state *)opaque;
- uint32_t oldval;
-
- /* The timers should be disabled before changing the configuration.
- We take advantage of this and defer everything until the timer
- is enabled. */
- switch (offset) {
- case 0x00: /* CFG */
- s->config = value;
- break;
- case 0x04: /* TAMR */
- s->mode[0] = value;
- break;
- case 0x08: /* TBMR */
- s->mode[1] = value;
- break;
- case 0x0c: /* CTL */
- oldval = s->control;
- s->control = value;
- /* TODO: Implement pause. */
- if ((oldval ^ value) & 1) {
- if (value & 1) {
- gptm_reload(s, 0, 1);
- } else {
- gptm_stop(s, 0);
- }
- }
- if (((oldval ^ value) & 0x100) && s->config >= 4) {
- if (value & 0x100) {
- gptm_reload(s, 1, 1);
- } else {
- gptm_stop(s, 1);
- }
- }
- break;
- case 0x18: /* IMR */
- s->mask = value & 0x77;
- gptm_update_irq(s);
- break;
- case 0x24: /* CR */
- s->state &= ~value;
- break;
- case 0x28: /* TAILR */
- s->load[0] = value & 0xffff;
- if (s->config < 4) {
- s->load[1] = value >> 16;
- }
- break;
- case 0x2c: /* TBILR */
- s->load[1] = value & 0xffff;
- break;
- case 0x30: /* TAMARCHR */
- s->match[0] = value & 0xffff;
- if (s->config < 4) {
- s->match[1] = value >> 16;
- }
- break;
- case 0x34: /* TBMATCHR */
- s->match[1] = value >> 16;
- break;
- case 0x38: /* TAPR */
- s->prescale[0] = value;
- break;
- case 0x3c: /* TBPR */
- s->prescale[1] = value;
- break;
- case 0x40: /* TAPMR */
- s->match_prescale[0] = value;
- break;
- case 0x44: /* TBPMR */
- s->match_prescale[0] = value;
- break;
- default:
- hw_error("gptm_write: Bad offset 0x%x\n", (int)offset);
- }
- gptm_update_irq(s);
-}
-
-static const MemoryRegionOps gptm_ops = {
- .read = gptm_read,
- .write = gptm_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static const VMStateDescription vmstate_stellaris_gptm = {
- .name = "stellaris_gptm",
- .version_id = 1,
- .minimum_version_id = 1,
- .fields = (VMStateField[]) {
- VMSTATE_UINT32(config, gptm_state),
- VMSTATE_UINT32_ARRAY(mode, gptm_state, 2),
- VMSTATE_UINT32(control, gptm_state),
- VMSTATE_UINT32(state, gptm_state),
- VMSTATE_UINT32(mask, gptm_state),
- VMSTATE_UNUSED(8),
- VMSTATE_UINT32_ARRAY(load, gptm_state, 2),
- VMSTATE_UINT32_ARRAY(match, gptm_state, 2),
- VMSTATE_UINT32_ARRAY(prescale, gptm_state, 2),
- VMSTATE_UINT32_ARRAY(match_prescale, gptm_state, 2),
- VMSTATE_UINT32(rtc, gptm_state),
- VMSTATE_INT64_ARRAY(tick, gptm_state, 2),
- VMSTATE_TIMER_PTR_ARRAY(timer, gptm_state, 2),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static int stellaris_gptm_init(SysBusDevice *sbd)
-{
- DeviceState *dev = DEVICE(sbd);
- gptm_state *s = STELLARIS_GPTM(dev);
-
- sysbus_init_irq(sbd, &s->irq);
- qdev_init_gpio_out(dev, &s->trigger, 1);
-
- memory_region_init_io(&s->iomem, OBJECT(s), &gptm_ops, s,
- "gptm", 0x1000);
- sysbus_init_mmio(sbd, &s->iomem);
-
- s->opaque[0] = s->opaque[1] = s;
- s->timer[0] = timer_new_ns(QEMU_CLOCK_VIRTUAL, gptm_tick, &s->opaque[0]);
- s->timer[1] = timer_new_ns(QEMU_CLOCK_VIRTUAL, gptm_tick, &s->opaque[1]);
- vmstate_register(dev, -1, &vmstate_stellaris_gptm, s);
- return 0;
-}
-
-
-/* System controller. */
-
-typedef struct {
- MemoryRegion iomem;
- uint32_t pborctl;
- uint32_t ldopctl;
- uint32_t int_status;
- uint32_t int_mask;
- uint32_t resc;
- uint32_t rcc;
- uint32_t rcc2;
- uint32_t rcgc[3];
- uint32_t scgc[3];
- uint32_t dcgc[3];
- uint32_t clkvclr;
- uint32_t ldoarst;
- uint32_t user0;
- uint32_t user1;
- qemu_irq irq;
- stellaris_board_info *board;
-} ssys_state;
-
-static void ssys_update(ssys_state *s)
-{
- qemu_set_irq(s->irq, (s->int_status & s->int_mask) != 0);
-}
-
-static uint32_t pllcfg_sandstorm[16] = {
- 0x31c0, /* 1 Mhz */
- 0x1ae0, /* 1.8432 Mhz */
- 0x18c0, /* 2 Mhz */
- 0xd573, /* 2.4576 Mhz */
- 0x37a6, /* 3.57954 Mhz */
- 0x1ae2, /* 3.6864 Mhz */
- 0x0c40, /* 4 Mhz */
- 0x98bc, /* 4.906 Mhz */
- 0x935b, /* 4.9152 Mhz */
- 0x09c0, /* 5 Mhz */
- 0x4dee, /* 5.12 Mhz */
- 0x0c41, /* 6 Mhz */
- 0x75db, /* 6.144 Mhz */
- 0x1ae6, /* 7.3728 Mhz */
- 0x0600, /* 8 Mhz */
- 0x585b /* 8.192 Mhz */
-};
-
-static uint32_t pllcfg_fury[16] = {
- 0x3200, /* 1 Mhz */
- 0x1b20, /* 1.8432 Mhz */
- 0x1900, /* 2 Mhz */
- 0xf42b, /* 2.4576 Mhz */
- 0x37e3, /* 3.57954 Mhz */
- 0x1b21, /* 3.6864 Mhz */
- 0x0c80, /* 4 Mhz */
- 0x98ee, /* 4.906 Mhz */
- 0xd5b4, /* 4.9152 Mhz */
- 0x0a00, /* 5 Mhz */
- 0x4e27, /* 5.12 Mhz */
- 0x1902, /* 6 Mhz */
- 0xec1c, /* 6.144 Mhz */
- 0x1b23, /* 7.3728 Mhz */
- 0x0640, /* 8 Mhz */
- 0xb11c /* 8.192 Mhz */
-};
-
-#define DID0_VER_MASK 0x70000000
-#define DID0_VER_0 0x00000000
-#define DID0_VER_1 0x10000000
-
-#define DID0_CLASS_MASK 0x00FF0000
-#define DID0_CLASS_SANDSTORM 0x00000000
-#define DID0_CLASS_FURY 0x00010000
-
-static int ssys_board_class(const ssys_state *s)
-{
- uint32_t did0 = s->board->did0;
- switch (did0 & DID0_VER_MASK) {
- case DID0_VER_0:
- return DID0_CLASS_SANDSTORM;
- case DID0_VER_1:
- switch (did0 & DID0_CLASS_MASK) {
- case DID0_CLASS_SANDSTORM:
- case DID0_CLASS_FURY:
- return did0 & DID0_CLASS_MASK;
- }
- /* for unknown classes, fall through */
- default:
- hw_error("ssys_board_class: Unknown class 0x%08x\n", did0);
- }
-}
-
-static uint64_t ssys_read(void *opaque, hwaddr offset,
- unsigned size)
-{
- ssys_state *s = (ssys_state *)opaque;
-
- switch (offset) {
- case 0x000: /* DID0 */
- return s->board->did0;
- case 0x004: /* DID1 */
- return s->board->did1;
- case 0x008: /* DC0 */
- return s->board->dc0;
- case 0x010: /* DC1 */
- return s->board->dc1;
- case 0x014: /* DC2 */
- return s->board->dc2;
- case 0x018: /* DC3 */
- return s->board->dc3;
- case 0x01c: /* DC4 */
- return s->board->dc4;
- case 0x030: /* PBORCTL */
- return s->pborctl;
- case 0x034: /* LDOPCTL */
- return s->ldopctl;
- case 0x040: /* SRCR0 */
- return 0;
- case 0x044: /* SRCR1 */
- return 0;
- case 0x048: /* SRCR2 */
- return 0;
- case 0x050: /* RIS */
- return s->int_status;
- case 0x054: /* IMC */
- return s->int_mask;
- case 0x058: /* MISC */
- return s->int_status & s->int_mask;
- case 0x05c: /* RESC */
- return s->resc;
- case 0x060: /* RCC */
- return s->rcc;
- case 0x064: /* PLLCFG */
- {
- int xtal;
- xtal = (s->rcc >> 6) & 0xf;
- switch (ssys_board_class(s)) {
- case DID0_CLASS_FURY:
- return pllcfg_fury[xtal];
- case DID0_CLASS_SANDSTORM:
- return pllcfg_sandstorm[xtal];
- default:
- hw_error("ssys_read: Unhandled class for PLLCFG read.\n");
- return 0;
- }
- }
- case 0x070: /* RCC2 */
- return s->rcc2;
- case 0x100: /* RCGC0 */
- return s->rcgc[0];
- case 0x104: /* RCGC1 */
- return s->rcgc[1];
- case 0x108: /* RCGC2 */
- return s->rcgc[2];
- case 0x110: /* SCGC0 */
- return s->scgc[0];
- case 0x114: /* SCGC1 */
- return s->scgc[1];
- case 0x118: /* SCGC2 */
- return s->scgc[2];
- case 0x120: /* DCGC0 */
- return s->dcgc[0];
- case 0x124: /* DCGC1 */
- return s->dcgc[1];
- case 0x128: /* DCGC2 */
- return s->dcgc[2];
- case 0x150: /* CLKVCLR */
- return s->clkvclr;
- case 0x160: /* LDOARST */
- return s->ldoarst;
- case 0x1e0: /* USER0 */
- return s->user0;
- case 0x1e4: /* USER1 */
- return s->user1;
- default:
- hw_error("ssys_read: Bad offset 0x%x\n", (int)offset);
- return 0;
- }
-}
-
-static bool ssys_use_rcc2(ssys_state *s)
-{
- return (s->rcc2 >> 31) & 0x1;
-}
-
-/*
- * Caculate the sys. clock period in ms.
- */
-static void ssys_calculate_system_clock(ssys_state *s)
-{
- if (ssys_use_rcc2(s)) {
- system_clock_scale = 5 * (((s->rcc2 >> 23) & 0x3f) + 1);
- } else {
- system_clock_scale = 5 * (((s->rcc >> 23) & 0xf) + 1);
- }
-}
-
-static void ssys_write(void *opaque, hwaddr offset,
- uint64_t value, unsigned size)
-{
- ssys_state *s = (ssys_state *)opaque;
-
- switch (offset) {
- case 0x030: /* PBORCTL */
- s->pborctl = value & 0xffff;
- break;
- case 0x034: /* LDOPCTL */
- s->ldopctl = value & 0x1f;
- break;
- case 0x040: /* SRCR0 */
- case 0x044: /* SRCR1 */
- case 0x048: /* SRCR2 */
- fprintf(stderr, "Peripheral reset not implemented\n");
- break;
- case 0x054: /* IMC */
- s->int_mask = value & 0x7f;
- break;
- case 0x058: /* MISC */
- s->int_status &= ~value;
- break;
- case 0x05c: /* RESC */
- s->resc = value & 0x3f;
- break;
- case 0x060: /* RCC */
- if ((s->rcc & (1 << 13)) != 0 && (value & (1 << 13)) == 0) {
- /* PLL enable. */
- s->int_status |= (1 << 6);
- }
- s->rcc = value;
- ssys_calculate_system_clock(s);
- break;
- case 0x070: /* RCC2 */
- if (ssys_board_class(s) == DID0_CLASS_SANDSTORM) {
- break;
- }
-
- if ((s->rcc2 & (1 << 13)) != 0 && (value & (1 << 13)) == 0) {
- /* PLL enable. */
- s->int_status |= (1 << 6);
- }
- s->rcc2 = value;
- ssys_calculate_system_clock(s);
- break;
- case 0x100: /* RCGC0 */
- s->rcgc[0] = value;
- break;
- case 0x104: /* RCGC1 */
- s->rcgc[1] = value;
- break;
- case 0x108: /* RCGC2 */
- s->rcgc[2] = value;
- break;
- case 0x110: /* SCGC0 */
- s->scgc[0] = value;
- break;
- case 0x114: /* SCGC1 */
- s->scgc[1] = value;
- break;
- case 0x118: /* SCGC2 */
- s->scgc[2] = value;
- break;
- case 0x120: /* DCGC0 */
- s->dcgc[0] = value;
- break;
- case 0x124: /* DCGC1 */
- s->dcgc[1] = value;
- break;
- case 0x128: /* DCGC2 */
- s->dcgc[2] = value;
- break;
- case 0x150: /* CLKVCLR */
- s->clkvclr = value;
- break;
- case 0x160: /* LDOARST */
- s->ldoarst = value;
- break;
- default:
- hw_error("ssys_write: Bad offset 0x%x\n", (int)offset);
- }
- ssys_update(s);
-}
-
-static const MemoryRegionOps ssys_ops = {
- .read = ssys_read,
- .write = ssys_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static void ssys_reset(void *opaque)
-{
- ssys_state *s = (ssys_state *)opaque;
-
- s->pborctl = 0x7ffd;
- s->rcc = 0x078e3ac0;
-
- if (ssys_board_class(s) == DID0_CLASS_SANDSTORM) {
- s->rcc2 = 0;
- } else {
- s->rcc2 = 0x07802810;
- }
- s->rcgc[0] = 1;
- s->scgc[0] = 1;
- s->dcgc[0] = 1;
- ssys_calculate_system_clock(s);
-}
-
-static int stellaris_sys_post_load(void *opaque, int version_id)
-{
- ssys_state *s = opaque;
-
- ssys_calculate_system_clock(s);
-
- return 0;
-}
-
-static const VMStateDescription vmstate_stellaris_sys = {
- .name = "stellaris_sys",
- .version_id = 2,
- .minimum_version_id = 1,
- .post_load = stellaris_sys_post_load,
- .fields = (VMStateField[]) {
- VMSTATE_UINT32(pborctl, ssys_state),
- VMSTATE_UINT32(ldopctl, ssys_state),
- VMSTATE_UINT32(int_mask, ssys_state),
- VMSTATE_UINT32(int_status, ssys_state),
- VMSTATE_UINT32(resc, ssys_state),
- VMSTATE_UINT32(rcc, ssys_state),
- VMSTATE_UINT32_V(rcc2, ssys_state, 2),
- VMSTATE_UINT32_ARRAY(rcgc, ssys_state, 3),
- VMSTATE_UINT32_ARRAY(scgc, ssys_state, 3),
- VMSTATE_UINT32_ARRAY(dcgc, ssys_state, 3),
- VMSTATE_UINT32(clkvclr, ssys_state),
- VMSTATE_UINT32(ldoarst, ssys_state),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static int stellaris_sys_init(uint32_t base, qemu_irq irq,
- stellaris_board_info * board,
- uint8_t *macaddr)
-{
- ssys_state *s;
-
- s = g_new0(ssys_state, 1);
- s->irq = irq;
- s->board = board;
- /* Most devices come preprogrammed with a MAC address in the user data. */
- s->user0 = macaddr[0] | (macaddr[1] << 8) | (macaddr[2] << 16);
- s->user1 = macaddr[3] | (macaddr[4] << 8) | (macaddr[5] << 16);
-
- memory_region_init_io(&s->iomem, NULL, &ssys_ops, s, "ssys", 0x00001000);
- memory_region_add_subregion(get_system_memory(), base, &s->iomem);
- ssys_reset(s);
- vmstate_register(NULL, -1, &vmstate_stellaris_sys, s);
- return 0;
-}
-
-
-/* I2C controller. */
-
-#define TYPE_STELLARIS_I2C "stellaris-i2c"
-#define STELLARIS_I2C(obj) \
- OBJECT_CHECK(stellaris_i2c_state, (obj), TYPE_STELLARIS_I2C)
-
-typedef struct {
- SysBusDevice parent_obj;
-
- I2CBus *bus;
- qemu_irq irq;
- MemoryRegion iomem;
- uint32_t msa;
- uint32_t mcs;
- uint32_t mdr;
- uint32_t mtpr;
- uint32_t mimr;
- uint32_t mris;
- uint32_t mcr;
-} stellaris_i2c_state;
-
-#define STELLARIS_I2C_MCS_BUSY 0x01
-#define STELLARIS_I2C_MCS_ERROR 0x02
-#define STELLARIS_I2C_MCS_ADRACK 0x04
-#define STELLARIS_I2C_MCS_DATACK 0x08
-#define STELLARIS_I2C_MCS_ARBLST 0x10
-#define STELLARIS_I2C_MCS_IDLE 0x20
-#define STELLARIS_I2C_MCS_BUSBSY 0x40
-
-static uint64_t stellaris_i2c_read(void *opaque, hwaddr offset,
- unsigned size)
-{
- stellaris_i2c_state *s = (stellaris_i2c_state *)opaque;
-
- switch (offset) {
- case 0x00: /* MSA */
- return s->msa;
- case 0x04: /* MCS */
- /* We don't emulate timing, so the controller is never busy. */
- return s->mcs | STELLARIS_I2C_MCS_IDLE;
- case 0x08: /* MDR */
- return s->mdr;
- case 0x0c: /* MTPR */
- return s->mtpr;
- case 0x10: /* MIMR */
- return s->mimr;
- case 0x14: /* MRIS */
- return s->mris;
- case 0x18: /* MMIS */
- return s->mris & s->mimr;
- case 0x20: /* MCR */
- return s->mcr;
- default:
- hw_error("strllaris_i2c_read: Bad offset 0x%x\n", (int)offset);
- return 0;
- }
-}
-
-static void stellaris_i2c_update(stellaris_i2c_state *s)
-{
- int level;
-
- level = (s->mris & s->mimr) != 0;
- qemu_set_irq(s->irq, level);
-}
-
-static void stellaris_i2c_write(void *opaque, hwaddr offset,
- uint64_t value, unsigned size)
-{
- stellaris_i2c_state *s = (stellaris_i2c_state *)opaque;
-
- switch (offset) {
- case 0x00: /* MSA */
- s->msa = value & 0xff;
- break;
- case 0x04: /* MCS */
- if ((s->mcr & 0x10) == 0) {
- /* Disabled. Do nothing. */
- break;
- }
- /* Grab the bus if this is starting a transfer. */
- if ((value & 2) && (s->mcs & STELLARIS_I2C_MCS_BUSBSY) == 0) {
- if (i2c_start_transfer(s->bus, s->msa >> 1, s->msa & 1)) {
- s->mcs |= STELLARIS_I2C_MCS_ARBLST;
- } else {
- s->mcs &= ~STELLARIS_I2C_MCS_ARBLST;
- s->mcs |= STELLARIS_I2C_MCS_BUSBSY;
- }
- }
- /* If we don't have the bus then indicate an error. */
- if (!i2c_bus_busy(s->bus)
- || (s->mcs & STELLARIS_I2C_MCS_BUSBSY) == 0) {
- s->mcs |= STELLARIS_I2C_MCS_ERROR;
- break;
- }
- s->mcs &= ~STELLARIS_I2C_MCS_ERROR;
- if (value & 1) {
- /* Transfer a byte. */
- /* TODO: Handle errors. */
- if (s->msa & 1) {
- /* Recv */
- s->mdr = i2c_recv(s->bus) & 0xff;
- } else {
- /* Send */
- i2c_send(s->bus, s->mdr);
- }
- /* Raise an interrupt. */
- s->mris |= 1;
- }
- if (value & 4) {
- /* Finish transfer. */
- i2c_end_transfer(s->bus);
- s->mcs &= ~STELLARIS_I2C_MCS_BUSBSY;
- }
- break;
- case 0x08: /* MDR */
- s->mdr = value & 0xff;
- break;
- case 0x0c: /* MTPR */
- s->mtpr = value & 0xff;
- break;
- case 0x10: /* MIMR */
- s->mimr = 1;
- break;
- case 0x1c: /* MICR */
- s->mris &= ~value;
- break;
- case 0x20: /* MCR */
- if (value & 1)
- hw_error(
- "stellaris_i2c_write: Loopback not implemented\n");
- if (value & 0x20)
- hw_error(
- "stellaris_i2c_write: Slave mode not implemented\n");
- s->mcr = value & 0x31;
- break;
- default:
- hw_error("stellaris_i2c_write: Bad offset 0x%x\n",
- (int)offset);
- }
- stellaris_i2c_update(s);
-}
-
-static void stellaris_i2c_reset(stellaris_i2c_state *s)
-{
- if (s->mcs & STELLARIS_I2C_MCS_BUSBSY)
- i2c_end_transfer(s->bus);
-
- s->msa = 0;
- s->mcs = 0;
- s->mdr = 0;
- s->mtpr = 1;
- s->mimr = 0;
- s->mris = 0;
- s->mcr = 0;
- stellaris_i2c_update(s);
-}
-
-static const MemoryRegionOps stellaris_i2c_ops = {
- .read = stellaris_i2c_read,
- .write = stellaris_i2c_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static const VMStateDescription vmstate_stellaris_i2c = {
- .name = "stellaris_i2c",
- .version_id = 1,
- .minimum_version_id = 1,
- .fields = (VMStateField[]) {
- VMSTATE_UINT32(msa, stellaris_i2c_state),
- VMSTATE_UINT32(mcs, stellaris_i2c_state),
- VMSTATE_UINT32(mdr, stellaris_i2c_state),
- VMSTATE_UINT32(mtpr, stellaris_i2c_state),
- VMSTATE_UINT32(mimr, stellaris_i2c_state),
- VMSTATE_UINT32(mris, stellaris_i2c_state),
- VMSTATE_UINT32(mcr, stellaris_i2c_state),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static int stellaris_i2c_init(SysBusDevice *sbd)
-{
- DeviceState *dev = DEVICE(sbd);
- stellaris_i2c_state *s = STELLARIS_I2C(dev);
- I2CBus *bus;
-
- sysbus_init_irq(sbd, &s->irq);
- bus = i2c_init_bus(dev, "i2c");
- s->bus = bus;
-
- memory_region_init_io(&s->iomem, OBJECT(s), &stellaris_i2c_ops, s,
- "i2c", 0x1000);
- sysbus_init_mmio(sbd, &s->iomem);
- /* ??? For now we only implement the master interface. */
- stellaris_i2c_reset(s);
- vmstate_register(dev, -1, &vmstate_stellaris_i2c, s);
- return 0;
-}
-
-/* Analogue to Digital Converter. This is only partially implemented,
- enough for applications that use a combined ADC and timer tick. */
-
-#define STELLARIS_ADC_EM_CONTROLLER 0
-#define STELLARIS_ADC_EM_COMP 1
-#define STELLARIS_ADC_EM_EXTERNAL 4
-#define STELLARIS_ADC_EM_TIMER 5
-#define STELLARIS_ADC_EM_PWM0 6
-#define STELLARIS_ADC_EM_PWM1 7
-#define STELLARIS_ADC_EM_PWM2 8
-
-#define STELLARIS_ADC_FIFO_EMPTY 0x0100
-#define STELLARIS_ADC_FIFO_FULL 0x1000
-
-#define TYPE_STELLARIS_ADC "stellaris-adc"
-#define STELLARIS_ADC(obj) \
- OBJECT_CHECK(stellaris_adc_state, (obj), TYPE_STELLARIS_ADC)
-
-typedef struct StellarisADCState {
- SysBusDevice parent_obj;
-
- MemoryRegion iomem;
- uint32_t actss;
- uint32_t ris;
- uint32_t im;
- uint32_t emux;
- uint32_t ostat;
- uint32_t ustat;
- uint32_t sspri;
- uint32_t sac;
- struct {
- uint32_t state;
- uint32_t data[16];
- } fifo[4];
- uint32_t ssmux[4];
- uint32_t ssctl[4];
- uint32_t noise;
- qemu_irq irq[4];
-} stellaris_adc_state;
-
-static uint32_t stellaris_adc_fifo_read(stellaris_adc_state *s, int n)
-{
- int tail;
-
- tail = s->fifo[n].state & 0xf;
- if (s->fifo[n].state & STELLARIS_ADC_FIFO_EMPTY) {
- s->ustat |= 1 << n;
- } else {
- s->fifo[n].state = (s->fifo[n].state & ~0xf) | ((tail + 1) & 0xf);
- s->fifo[n].state &= ~STELLARIS_ADC_FIFO_FULL;
- if (tail + 1 == ((s->fifo[n].state >> 4) & 0xf))
- s->fifo[n].state |= STELLARIS_ADC_FIFO_EMPTY;
- }
- return s->fifo[n].data[tail];
-}
-
-static void stellaris_adc_fifo_write(stellaris_adc_state *s, int n,
- uint32_t value)
-{
- int head;
-
- /* TODO: Real hardware has limited size FIFOs. We have a full 16 entry
- FIFO fir each sequencer. */
- head = (s->fifo[n].state >> 4) & 0xf;
- if (s->fifo[n].state & STELLARIS_ADC_FIFO_FULL) {
- s->ostat |= 1 << n;
- return;
- }
- s->fifo[n].data[head] = value;
- head = (head + 1) & 0xf;
- s->fifo[n].state &= ~STELLARIS_ADC_FIFO_EMPTY;
- s->fifo[n].state = (s->fifo[n].state & ~0xf0) | (head << 4);
- if ((s->fifo[n].state & 0xf) == head)
- s->fifo[n].state |= STELLARIS_ADC_FIFO_FULL;
-}
-
-static void stellaris_adc_update(stellaris_adc_state *s)
-{
- int level;
- int n;
-
- for (n = 0; n < 4; n++) {
- level = (s->ris & s->im & (1 << n)) != 0;
- qemu_set_irq(s->irq[n], level);
- }
-}
-
-static void stellaris_adc_trigger(void *opaque, int irq, int level)
-{
- stellaris_adc_state *s = (stellaris_adc_state *)opaque;
- int n;
-
- for (n = 0; n < 4; n++) {
- if ((s->actss & (1 << n)) == 0) {
- continue;
- }
-
- if (((s->emux >> (n * 4)) & 0xff) != 5) {
- continue;
- }
-
- /* Some applications use the ADC as a random number source, so introduce
- some variation into the signal. */
- s->noise = s->noise * 314159 + 1;
- /* ??? actual inputs not implemented. Return an arbitrary value. */
- stellaris_adc_fifo_write(s, n, 0x200 + ((s->noise >> 16) & 7));
- s->ris |= (1 << n);
- stellaris_adc_update(s);
- }
-}
-
-static void stellaris_adc_reset(stellaris_adc_state *s)
-{
- int n;
-
- for (n = 0; n < 4; n++) {
- s->ssmux[n] = 0;
- s->ssctl[n] = 0;
- s->fifo[n].state = STELLARIS_ADC_FIFO_EMPTY;
- }
-}
-
-static uint64_t stellaris_adc_read(void *opaque, hwaddr offset,
- unsigned size)
-{
- stellaris_adc_state *s = (stellaris_adc_state *)opaque;
-
- /* TODO: Implement this. */
- if (offset >= 0x40 && offset < 0xc0) {
- int n;
- n = (offset - 0x40) >> 5;
- switch (offset & 0x1f) {
- case 0x00: /* SSMUX */
- return s->ssmux[n];
- case 0x04: /* SSCTL */
- return s->ssctl[n];
- case 0x08: /* SSFIFO */
- return stellaris_adc_fifo_read(s, n);
- case 0x0c: /* SSFSTAT */
- return s->fifo[n].state;
- default:
- break;
- }
- }
- switch (offset) {
- case 0x00: /* ACTSS */
- return s->actss;
- case 0x04: /* RIS */
- return s->ris;
- case 0x08: /* IM */
- return s->im;
- case 0x0c: /* ISC */
- return s->ris & s->im;
- case 0x10: /* OSTAT */
- return s->ostat;
- case 0x14: /* EMUX */
- return s->emux;
- case 0x18: /* USTAT */
- return s->ustat;
- case 0x20: /* SSPRI */
- return s->sspri;
- case 0x30: /* SAC */
- return s->sac;
- default:
- hw_error("strllaris_adc_read: Bad offset 0x%x\n",
- (int)offset);
- return 0;
- }
-}
-
-static void stellaris_adc_write(void *opaque, hwaddr offset,
- uint64_t value, unsigned size)
-{
- stellaris_adc_state *s = (stellaris_adc_state *)opaque;
-
- /* TODO: Implement this. */
- if (offset >= 0x40 && offset < 0xc0) {
- int n;
- n = (offset - 0x40) >> 5;
- switch (offset & 0x1f) {
- case 0x00: /* SSMUX */
- s->ssmux[n] = value & 0x33333333;
- return;
- case 0x04: /* SSCTL */
- if (value != 6) {
- hw_error("ADC: Unimplemented sequence %" PRIx64 "\n",
- value);
- }
- s->ssctl[n] = value;
- return;
- default:
- break;
- }
- }
- switch (offset) {
- case 0x00: /* ACTSS */
- s->actss = value & 0xf;
- break;
- case 0x08: /* IM */
- s->im = value;
- break;
- case 0x0c: /* ISC */
- s->ris &= ~value;
- break;
- case 0x10: /* OSTAT */
- s->ostat &= ~value;
- break;
- case 0x14: /* EMUX */
- s->emux = value;
- break;
- case 0x18: /* USTAT */
- s->ustat &= ~value;
- break;
- case 0x20: /* SSPRI */
- s->sspri = value;
- break;
- case 0x28: /* PSSI */
- hw_error("Not implemented: ADC sample initiate\n");
- break;
- case 0x30: /* SAC */
- s->sac = value;
- break;
- default:
- hw_error("stellaris_adc_write: Bad offset 0x%x\n", (int)offset);
- }
- stellaris_adc_update(s);
-}
-
-static const MemoryRegionOps stellaris_adc_ops = {
- .read = stellaris_adc_read,
- .write = stellaris_adc_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static const VMStateDescription vmstate_stellaris_adc = {
- .name = "stellaris_adc",
- .version_id = 1,
- .minimum_version_id = 1,
- .fields = (VMStateField[]) {
- VMSTATE_UINT32(actss, stellaris_adc_state),
- VMSTATE_UINT32(ris, stellaris_adc_state),
- VMSTATE_UINT32(im, stellaris_adc_state),
- VMSTATE_UINT32(emux, stellaris_adc_state),
- VMSTATE_UINT32(ostat, stellaris_adc_state),
- VMSTATE_UINT32(ustat, stellaris_adc_state),
- VMSTATE_UINT32(sspri, stellaris_adc_state),
- VMSTATE_UINT32(sac, stellaris_adc_state),
- VMSTATE_UINT32(fifo[0].state, stellaris_adc_state),
- VMSTATE_UINT32_ARRAY(fifo[0].data, stellaris_adc_state, 16),
- VMSTATE_UINT32(ssmux[0], stellaris_adc_state),
- VMSTATE_UINT32(ssctl[0], stellaris_adc_state),
- VMSTATE_UINT32(fifo[1].state, stellaris_adc_state),
- VMSTATE_UINT32_ARRAY(fifo[1].data, stellaris_adc_state, 16),
- VMSTATE_UINT32(ssmux[1], stellaris_adc_state),
- VMSTATE_UINT32(ssctl[1], stellaris_adc_state),
- VMSTATE_UINT32(fifo[2].state, stellaris_adc_state),
- VMSTATE_UINT32_ARRAY(fifo[2].data, stellaris_adc_state, 16),
- VMSTATE_UINT32(ssmux[2], stellaris_adc_state),
- VMSTATE_UINT32(ssctl[2], stellaris_adc_state),
- VMSTATE_UINT32(fifo[3].state, stellaris_adc_state),
- VMSTATE_UINT32_ARRAY(fifo[3].data, stellaris_adc_state, 16),
- VMSTATE_UINT32(ssmux[3], stellaris_adc_state),
- VMSTATE_UINT32(ssctl[3], stellaris_adc_state),
- VMSTATE_UINT32(noise, stellaris_adc_state),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static int stellaris_adc_init(SysBusDevice *sbd)
-{
- DeviceState *dev = DEVICE(sbd);
- stellaris_adc_state *s = STELLARIS_ADC(dev);
- int n;
-
- for (n = 0; n < 4; n++) {
- sysbus_init_irq(sbd, &s->irq[n]);
- }
-
- memory_region_init_io(&s->iomem, OBJECT(s), &stellaris_adc_ops, s,
- "adc", 0x1000);
- sysbus_init_mmio(sbd, &s->iomem);
- stellaris_adc_reset(s);
- qdev_init_gpio_in(dev, stellaris_adc_trigger, 1);
- vmstate_register(dev, -1, &vmstate_stellaris_adc, s);
- return 0;
-}
-
-static
-void do_sys_reset(void *opaque, int n, int level)
-{
- if (level) {
- qemu_system_reset_request();
- }
-}
-
-/* Board init. */
-static stellaris_board_info stellaris_boards[] = {
- { "LM3S811EVB",
- 0,
- 0x0032000e,
- 0x001f001f, /* dc0 */
- 0x001132bf,
- 0x01071013,
- 0x3f0f01ff,
- 0x0000001f,
- BP_OLED_I2C
- },
- { "LM3S6965EVB",
- 0x10010002,
- 0x1073402e,
- 0x00ff007f, /* dc0 */
- 0x001133ff,
- 0x030f5317,
- 0x0f0f87ff,
- 0x5000007f,
- BP_OLED_SSI | BP_GAMEPAD
- }
-};
-
-static void stellaris_init(const char *kernel_filename, const char *cpu_model,
- stellaris_board_info *board)
-{
- static const int uart_irq[] = {5, 6, 33, 34};
- static const int timer_irq[] = {19, 21, 23, 35};
- static const uint32_t gpio_addr[7] =
- { 0x40004000, 0x40005000, 0x40006000, 0x40007000,
- 0x40024000, 0x40025000, 0x40026000};
- static const int gpio_irq[7] = {0, 1, 2, 3, 4, 30, 31};
-
- DeviceState *gpio_dev[7], *nvic;
- qemu_irq gpio_in[7][8];
- qemu_irq gpio_out[7][8];
- qemu_irq adc;
- int sram_size;
- int flash_size;
- I2CBus *i2c;
- DeviceState *dev;
- int i;
- int j;
-
- MemoryRegion *sram = g_new(MemoryRegion, 1);
- MemoryRegion *flash = g_new(MemoryRegion, 1);
- MemoryRegion *system_memory = get_system_memory();
-
- flash_size = (((board->dc0 & 0xffff) + 1) << 1) * 1024;
- sram_size = ((board->dc0 >> 18) + 1) * 1024;
-
- /* Flash programming is done via the SCU, so pretend it is ROM. */
- memory_region_init_ram(flash, NULL, "stellaris.flash", flash_size,
- &error_fatal);
- vmstate_register_ram_global(flash);
- memory_region_set_readonly(flash, true);
- memory_region_add_subregion(system_memory, 0, flash);
-
- memory_region_init_ram(sram, NULL, "stellaris.sram", sram_size,
- &error_fatal);
- vmstate_register_ram_global(sram);
- memory_region_add_subregion(system_memory, 0x20000000, sram);
-
- nvic = armv7m_init(system_memory, flash_size, NUM_IRQ_LINES,
- kernel_filename, cpu_model);
-
- qdev_connect_gpio_out_named(nvic, "SYSRESETREQ", 0,
- qemu_allocate_irq(&do_sys_reset, NULL, 0));
-
- if (board->dc1 & (1 << 16)) {
- dev = sysbus_create_varargs(TYPE_STELLARIS_ADC, 0x40038000,
- qdev_get_gpio_in(nvic, 14),
- qdev_get_gpio_in(nvic, 15),
- qdev_get_gpio_in(nvic, 16),
- qdev_get_gpio_in(nvic, 17),
- NULL);
- adc = qdev_get_gpio_in(dev, 0);
- } else {
- adc = NULL;
- }
- for (i = 0; i < 4; i++) {
- if (board->dc2 & (0x10000 << i)) {
- dev = sysbus_create_simple(TYPE_STELLARIS_GPTM,
- 0x40030000 + i * 0x1000,
- qdev_get_gpio_in(nvic, timer_irq[i]));
- /* TODO: This is incorrect, but we get away with it because
- the ADC output is only ever pulsed. */
- qdev_connect_gpio_out(dev, 0, adc);
- }
- }
-
- stellaris_sys_init(0x400fe000, qdev_get_gpio_in(nvic, 28),
- board, nd_table[0].macaddr.a);
-
- for (i = 0; i < 7; i++) {
- if (board->dc4 & (1 << i)) {
- gpio_dev[i] = sysbus_create_simple("pl061_luminary", gpio_addr[i],
- qdev_get_gpio_in(nvic,
- gpio_irq[i]));
- for (j = 0; j < 8; j++) {
- gpio_in[i][j] = qdev_get_gpio_in(gpio_dev[i], j);
- gpio_out[i][j] = NULL;
- }
- }
- }
-
- if (board->dc2 & (1 << 12)) {
- dev = sysbus_create_simple(TYPE_STELLARIS_I2C, 0x40020000,
- qdev_get_gpio_in(nvic, 8));
- i2c = (I2CBus *)qdev_get_child_bus(dev, "i2c");
- if (board->peripherals & BP_OLED_I2C) {
- i2c_create_slave(i2c, "ssd0303", 0x3d);
- }
- }
-
- for (i = 0; i < 4; i++) {
- if (board->dc2 & (1 << i)) {
- sysbus_create_simple("pl011_luminary", 0x4000c000 + i * 0x1000,
- qdev_get_gpio_in(nvic, uart_irq[i]));
- }
- }
- if (board->dc2 & (1 << 4)) {
- dev = sysbus_create_simple("pl022", 0x40008000,
- qdev_get_gpio_in(nvic, 7));
- if (board->peripherals & BP_OLED_SSI) {
- void *bus;
- DeviceState *sddev;
- DeviceState *ssddev;
-
- /* Some boards have both an OLED controller and SD card connected to
- * the same SSI port, with the SD card chip select connected to a
- * GPIO pin. Technically the OLED chip select is connected to the
- * SSI Fss pin. We do not bother emulating that as both devices
- * should never be selected simultaneously, and our OLED controller
- * ignores stray 0xff commands that occur when deselecting the SD
- * card.
- */
- bus = qdev_get_child_bus(dev, "ssi");
-
- sddev = ssi_create_slave(bus, "ssi-sd");
- ssddev = ssi_create_slave(bus, "ssd0323");
- gpio_out[GPIO_D][0] = qemu_irq_split(
- qdev_get_gpio_in_named(sddev, SSI_GPIO_CS, 0),
- qdev_get_gpio_in_named(ssddev, SSI_GPIO_CS, 0));
- gpio_out[GPIO_C][7] = qdev_get_gpio_in(ssddev, 0);
-
- /* Make sure the select pin is high. */
- qemu_irq_raise(gpio_out[GPIO_D][0]);
- }
- }
- if (board->dc4 & (1 << 28)) {
- DeviceState *enet;
-
- qemu_check_nic_model(&nd_table[0], "stellaris");
-
- enet = qdev_create(NULL, "stellaris_enet");
- qdev_set_nic_properties(enet, &nd_table[0]);
- qdev_init_nofail(enet);
- sysbus_mmio_map(SYS_BUS_DEVICE(enet), 0, 0x40048000);
- sysbus_connect_irq(SYS_BUS_DEVICE(enet), 0, qdev_get_gpio_in(nvic, 42));
- }
- if (board->peripherals & BP_GAMEPAD) {
- qemu_irq gpad_irq[5];
- static const int gpad_keycode[5] = { 0xc8, 0xd0, 0xcb, 0xcd, 0x1d };
-
- gpad_irq[0] = qemu_irq_invert(gpio_in[GPIO_E][0]); /* up */
- gpad_irq[1] = qemu_irq_invert(gpio_in[GPIO_E][1]); /* down */
- gpad_irq[2] = qemu_irq_invert(gpio_in[GPIO_E][2]); /* left */
- gpad_irq[3] = qemu_irq_invert(gpio_in[GPIO_E][3]); /* right */
- gpad_irq[4] = qemu_irq_invert(gpio_in[GPIO_F][1]); /* select */
-
- stellaris_gamepad_init(5, gpad_irq, gpad_keycode);
- }
- for (i = 0; i < 7; i++) {
- if (board->dc4 & (1 << i)) {
- for (j = 0; j < 8; j++) {
- if (gpio_out[i][j]) {
- qdev_connect_gpio_out(gpio_dev[i], j, gpio_out[i][j]);
- }
- }
- }
- }
-}
-
-/* FIXME: Figure out how to generate these from stellaris_boards. */
-static void lm3s811evb_init(MachineState *machine)
-{
- const char *cpu_model = machine->cpu_model;
- const char *kernel_filename = machine->kernel_filename;
- stellaris_init(kernel_filename, cpu_model, &stellaris_boards[0]);
-}
-
-static void lm3s6965evb_init(MachineState *machine)
-{
- const char *cpu_model = machine->cpu_model;
- const char *kernel_filename = machine->kernel_filename;
- stellaris_init(kernel_filename, cpu_model, &stellaris_boards[1]);
-}
-
-static void lm3s811evb_class_init(ObjectClass *oc, void *data)
-{
- MachineClass *mc = MACHINE_CLASS(oc);
-
- mc->desc = "Stellaris LM3S811EVB";
- mc->init = lm3s811evb_init;
-}
-
-static const TypeInfo lm3s811evb_type = {
- .name = MACHINE_TYPE_NAME("lm3s811evb"),
- .parent = TYPE_MACHINE,
- .class_init = lm3s811evb_class_init,
-};
-
-static void lm3s6965evb_class_init(ObjectClass *oc, void *data)
-{
- MachineClass *mc = MACHINE_CLASS(oc);
-
- mc->desc = "Stellaris LM3S6965EVB";
- mc->init = lm3s6965evb_init;
-}
-
-static const TypeInfo lm3s6965evb_type = {
- .name = MACHINE_TYPE_NAME("lm3s6965evb"),
- .parent = TYPE_MACHINE,
- .class_init = lm3s6965evb_class_init,
-};
-
-static void stellaris_machine_init(void)
-{
- type_register_static(&lm3s811evb_type);
- type_register_static(&lm3s6965evb_type);
-}
-
-type_init(stellaris_machine_init)
-
-static void stellaris_i2c_class_init(ObjectClass *klass, void *data)
-{
- SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
-
- sdc->init = stellaris_i2c_init;
-}
-
-static const TypeInfo stellaris_i2c_info = {
- .name = TYPE_STELLARIS_I2C,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(stellaris_i2c_state),
- .class_init = stellaris_i2c_class_init,
-};
-
-static void stellaris_gptm_class_init(ObjectClass *klass, void *data)
-{
- SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
-
- sdc->init = stellaris_gptm_init;
-}
-
-static const TypeInfo stellaris_gptm_info = {
- .name = TYPE_STELLARIS_GPTM,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(gptm_state),
- .class_init = stellaris_gptm_class_init,
-};
-
-static void stellaris_adc_class_init(ObjectClass *klass, void *data)
-{
- SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
-
- sdc->init = stellaris_adc_init;
-}
-
-static const TypeInfo stellaris_adc_info = {
- .name = TYPE_STELLARIS_ADC,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(stellaris_adc_state),
- .class_init = stellaris_adc_class_init,
-};
-
-static void stellaris_register_types(void)
-{
- type_register_static(&stellaris_i2c_info);
- type_register_static(&stellaris_gptm_info);
- type_register_static(&stellaris_adc_info);
-}
-
-type_init(stellaris_register_types)
diff --git a/qemu/hw/arm/stm32f205_soc.c b/qemu/hw/arm/stm32f205_soc.c
deleted file mode 100644
index a5ea1e237..000000000
--- a/qemu/hw/arm/stm32f205_soc.c
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * STM32F205 SoC
- *
- * Copyright (c) 2014 Alistair Francis <alistair@alistair23.me>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "qemu-common.h"
-#include "cpu.h"
-#include "hw/arm/arm.h"
-#include "exec/address-spaces.h"
-#include "hw/arm/stm32f205_soc.h"
-
-/* At the moment only Timer 2 to 5 are modelled */
-static const uint32_t timer_addr[STM_NUM_TIMERS] = { 0x40000000, 0x40000400,
- 0x40000800, 0x40000C00 };
-static const uint32_t usart_addr[STM_NUM_USARTS] = { 0x40011000, 0x40004400,
- 0x40004800, 0x40004C00, 0x40005000, 0x40011400 };
-
-static const int timer_irq[STM_NUM_TIMERS] = {28, 29, 30, 50};
-static const int usart_irq[STM_NUM_USARTS] = {37, 38, 39, 52, 53, 71};
-
-static void stm32f205_soc_initfn(Object *obj)
-{
- STM32F205State *s = STM32F205_SOC(obj);
- int i;
-
- object_initialize(&s->syscfg, sizeof(s->syscfg), TYPE_STM32F2XX_SYSCFG);
- qdev_set_parent_bus(DEVICE(&s->syscfg), sysbus_get_default());
-
- for (i = 0; i < STM_NUM_USARTS; i++) {
- object_initialize(&s->usart[i], sizeof(s->usart[i]),
- TYPE_STM32F2XX_USART);
- qdev_set_parent_bus(DEVICE(&s->usart[i]), sysbus_get_default());
- }
-
- for (i = 0; i < STM_NUM_TIMERS; i++) {
- object_initialize(&s->timer[i], sizeof(s->timer[i]),
- TYPE_STM32F2XX_TIMER);
- qdev_set_parent_bus(DEVICE(&s->timer[i]), sysbus_get_default());
- }
-}
-
-static void stm32f205_soc_realize(DeviceState *dev_soc, Error **errp)
-{
- STM32F205State *s = STM32F205_SOC(dev_soc);
- DeviceState *syscfgdev, *usartdev, *timerdev, *nvic;
- SysBusDevice *syscfgbusdev, *usartbusdev, *timerbusdev;
- Error *err = NULL;
- int i;
-
- MemoryRegion *system_memory = get_system_memory();
- MemoryRegion *sram = g_new(MemoryRegion, 1);
- MemoryRegion *flash = g_new(MemoryRegion, 1);
- MemoryRegion *flash_alias = g_new(MemoryRegion, 1);
-
- memory_region_init_ram(flash, NULL, "STM32F205.flash", FLASH_SIZE,
- &error_fatal);
- memory_region_init_alias(flash_alias, NULL, "STM32F205.flash.alias",
- flash, 0, FLASH_SIZE);
-
- vmstate_register_ram_global(flash);
-
- memory_region_set_readonly(flash, true);
- memory_region_set_readonly(flash_alias, true);
-
- memory_region_add_subregion(system_memory, FLASH_BASE_ADDRESS, flash);
- memory_region_add_subregion(system_memory, 0, flash_alias);
-
- memory_region_init_ram(sram, NULL, "STM32F205.sram", SRAM_SIZE,
- &error_fatal);
- vmstate_register_ram_global(sram);
- memory_region_add_subregion(system_memory, SRAM_BASE_ADDRESS, sram);
-
- nvic = armv7m_init(get_system_memory(), FLASH_SIZE, 96,
- s->kernel_filename, s->cpu_model);
-
- /* System configuration controller */
- syscfgdev = DEVICE(&s->syscfg);
- object_property_set_bool(OBJECT(&s->syscfg), true, "realized", &err);
- if (err != NULL) {
- error_propagate(errp, err);
- return;
- }
- syscfgbusdev = SYS_BUS_DEVICE(syscfgdev);
- sysbus_mmio_map(syscfgbusdev, 0, 0x40013800);
- sysbus_connect_irq(syscfgbusdev, 0, qdev_get_gpio_in(nvic, 71));
-
- /* Attach UART (uses USART registers) and USART controllers */
- for (i = 0; i < STM_NUM_USARTS; i++) {
- usartdev = DEVICE(&(s->usart[i]));
- object_property_set_bool(OBJECT(&s->usart[i]), true, "realized", &err);
- if (err != NULL) {
- error_propagate(errp, err);
- return;
- }
- usartbusdev = SYS_BUS_DEVICE(usartdev);
- sysbus_mmio_map(usartbusdev, 0, usart_addr[i]);
- sysbus_connect_irq(usartbusdev, 0,
- qdev_get_gpio_in(nvic, usart_irq[i]));
- }
-
- /* Timer 2 to 5 */
- for (i = 0; i < STM_NUM_TIMERS; i++) {
- timerdev = DEVICE(&(s->timer[i]));
- qdev_prop_set_uint64(timerdev, "clock-frequency", 1000000000);
- object_property_set_bool(OBJECT(&s->timer[i]), true, "realized", &err);
- if (err != NULL) {
- error_propagate(errp, err);
- return;
- }
- timerbusdev = SYS_BUS_DEVICE(timerdev);
- sysbus_mmio_map(timerbusdev, 0, timer_addr[i]);
- sysbus_connect_irq(timerbusdev, 0,
- qdev_get_gpio_in(nvic, timer_irq[i]));
- }
-}
-
-static Property stm32f205_soc_properties[] = {
- DEFINE_PROP_STRING("kernel-filename", STM32F205State, kernel_filename),
- DEFINE_PROP_STRING("cpu-model", STM32F205State, cpu_model),
- DEFINE_PROP_END_OF_LIST(),
-};
-
-static void stm32f205_soc_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
-
- dc->realize = stm32f205_soc_realize;
- dc->props = stm32f205_soc_properties;
-}
-
-static const TypeInfo stm32f205_soc_info = {
- .name = TYPE_STM32F205_SOC,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(STM32F205State),
- .instance_init = stm32f205_soc_initfn,
- .class_init = stm32f205_soc_class_init,
-};
-
-static void stm32f205_soc_types(void)
-{
- type_register_static(&stm32f205_soc_info);
-}
-
-type_init(stm32f205_soc_types)
diff --git a/qemu/hw/arm/strongarm.c b/qemu/hw/arm/strongarm.c
deleted file mode 100644
index 1eeb1ab39..000000000
--- a/qemu/hw/arm/strongarm.c
+++ /dev/null
@@ -1,1662 +0,0 @@
-/*
- * StrongARM SA-1100/SA-1110 emulation
- *
- * Copyright (C) 2011 Dmitry Eremin-Solenikov
- *
- * Largely based on StrongARM emulation:
- * Copyright (c) 2006 Openedhand Ltd.
- * Written by Andrzej Zaborowski <balrog@zabor.org>
- *
- * UART code based on QEMU 16550A UART emulation
- * Copyright (c) 2003-2004 Fabrice Bellard
- * Copyright (c) 2008 Citrix Systems, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- * Contributions after 2012-01-13 are licensed under the terms of the
- * GNU GPL, version 2 or (at your option) any later version.
- */
-
-#include "qemu/osdep.h"
-#include "cpu.h"
-#include "hw/boards.h"
-#include "hw/sysbus.h"
-#include "strongarm.h"
-#include "qemu/error-report.h"
-#include "hw/arm/arm.h"
-#include "sysemu/char.h"
-#include "sysemu/sysemu.h"
-#include "hw/ssi/ssi.h"
-#include "qemu/cutils.h"
-
-//#define DEBUG
-
-/*
- TODO
- - Implement cp15, c14 ?
- - Implement cp15, c15 !!! (idle used in L)
- - Implement idle mode handling/DIM
- - Implement sleep mode/Wake sources
- - Implement reset control
- - Implement memory control regs
- - PCMCIA handling
- - Maybe support MBGNT/MBREQ
- - DMA channels
- - GPCLK
- - IrDA
- - MCP
- - Enhance UART with modem signals
- */
-
-#ifdef DEBUG
-# define DPRINTF(format, ...) printf(format , ## __VA_ARGS__)
-#else
-# define DPRINTF(format, ...) do { } while (0)
-#endif
-
-static struct {
- hwaddr io_base;
- int irq;
-} sa_serial[] = {
- { 0x80010000, SA_PIC_UART1 },
- { 0x80030000, SA_PIC_UART2 },
- { 0x80050000, SA_PIC_UART3 },
- { 0, 0 }
-};
-
-/* Interrupt Controller */
-
-#define TYPE_STRONGARM_PIC "strongarm_pic"
-#define STRONGARM_PIC(obj) \
- OBJECT_CHECK(StrongARMPICState, (obj), TYPE_STRONGARM_PIC)
-
-typedef struct StrongARMPICState {
- SysBusDevice parent_obj;
-
- MemoryRegion iomem;
- qemu_irq irq;
- qemu_irq fiq;
-
- uint32_t pending;
- uint32_t enabled;
- uint32_t is_fiq;
- uint32_t int_idle;
-} StrongARMPICState;
-
-#define ICIP 0x00
-#define ICMR 0x04
-#define ICLR 0x08
-#define ICFP 0x10
-#define ICPR 0x20
-#define ICCR 0x0c
-
-#define SA_PIC_SRCS 32
-
-
-static void strongarm_pic_update(void *opaque)
-{
- StrongARMPICState *s = opaque;
-
- /* FIXME: reflect DIM */
- qemu_set_irq(s->fiq, s->pending & s->enabled & s->is_fiq);
- qemu_set_irq(s->irq, s->pending & s->enabled & ~s->is_fiq);
-}
-
-static void strongarm_pic_set_irq(void *opaque, int irq, int level)
-{
- StrongARMPICState *s = opaque;
-
- if (level) {
- s->pending |= 1 << irq;
- } else {
- s->pending &= ~(1 << irq);
- }
-
- strongarm_pic_update(s);
-}
-
-static uint64_t strongarm_pic_mem_read(void *opaque, hwaddr offset,
- unsigned size)
-{
- StrongARMPICState *s = opaque;
-
- switch (offset) {
- case ICIP:
- return s->pending & ~s->is_fiq & s->enabled;
- case ICMR:
- return s->enabled;
- case ICLR:
- return s->is_fiq;
- case ICCR:
- return s->int_idle == 0;
- case ICFP:
- return s->pending & s->is_fiq & s->enabled;
- case ICPR:
- return s->pending;
- default:
- printf("%s: Bad register offset 0x" TARGET_FMT_plx "\n",
- __func__, offset);
- return 0;
- }
-}
-
-static void strongarm_pic_mem_write(void *opaque, hwaddr offset,
- uint64_t value, unsigned size)
-{
- StrongARMPICState *s = opaque;
-
- switch (offset) {
- case ICMR:
- s->enabled = value;
- break;
- case ICLR:
- s->is_fiq = value;
- break;
- case ICCR:
- s->int_idle = (value & 1) ? 0 : ~0;
- break;
- default:
- printf("%s: Bad register offset 0x" TARGET_FMT_plx "\n",
- __func__, offset);
- break;
- }
- strongarm_pic_update(s);
-}
-
-static const MemoryRegionOps strongarm_pic_ops = {
- .read = strongarm_pic_mem_read,
- .write = strongarm_pic_mem_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static int strongarm_pic_initfn(SysBusDevice *sbd)
-{
- DeviceState *dev = DEVICE(sbd);
- StrongARMPICState *s = STRONGARM_PIC(dev);
-
- qdev_init_gpio_in(dev, strongarm_pic_set_irq, SA_PIC_SRCS);
- memory_region_init_io(&s->iomem, OBJECT(s), &strongarm_pic_ops, s,
- "pic", 0x1000);
- sysbus_init_mmio(sbd, &s->iomem);
- sysbus_init_irq(sbd, &s->irq);
- sysbus_init_irq(sbd, &s->fiq);
-
- return 0;
-}
-
-static int strongarm_pic_post_load(void *opaque, int version_id)
-{
- strongarm_pic_update(opaque);
- return 0;
-}
-
-static VMStateDescription vmstate_strongarm_pic_regs = {
- .name = "strongarm_pic",
- .version_id = 0,
- .minimum_version_id = 0,
- .post_load = strongarm_pic_post_load,
- .fields = (VMStateField[]) {
- VMSTATE_UINT32(pending, StrongARMPICState),
- VMSTATE_UINT32(enabled, StrongARMPICState),
- VMSTATE_UINT32(is_fiq, StrongARMPICState),
- VMSTATE_UINT32(int_idle, StrongARMPICState),
- VMSTATE_END_OF_LIST(),
- },
-};
-
-static void strongarm_pic_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
-
- k->init = strongarm_pic_initfn;
- dc->desc = "StrongARM PIC";
- dc->vmsd = &vmstate_strongarm_pic_regs;
-}
-
-static const TypeInfo strongarm_pic_info = {
- .name = TYPE_STRONGARM_PIC,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(StrongARMPICState),
- .class_init = strongarm_pic_class_init,
-};
-
-/* Real-Time Clock */
-#define RTAR 0x00 /* RTC Alarm register */
-#define RCNR 0x04 /* RTC Counter register */
-#define RTTR 0x08 /* RTC Timer Trim register */
-#define RTSR 0x10 /* RTC Status register */
-
-#define RTSR_AL (1 << 0) /* RTC Alarm detected */
-#define RTSR_HZ (1 << 1) /* RTC 1Hz detected */
-#define RTSR_ALE (1 << 2) /* RTC Alarm enable */
-#define RTSR_HZE (1 << 3) /* RTC 1Hz enable */
-
-/* 16 LSB of RTTR are clockdiv for internal trim logic,
- * trim delete isn't emulated, so
- * f = 32 768 / (RTTR_trim + 1) */
-
-#define TYPE_STRONGARM_RTC "strongarm-rtc"
-#define STRONGARM_RTC(obj) \
- OBJECT_CHECK(StrongARMRTCState, (obj), TYPE_STRONGARM_RTC)
-
-typedef struct StrongARMRTCState {
- SysBusDevice parent_obj;
-
- MemoryRegion iomem;
- uint32_t rttr;
- uint32_t rtsr;
- uint32_t rtar;
- uint32_t last_rcnr;
- int64_t last_hz;
- QEMUTimer *rtc_alarm;
- QEMUTimer *rtc_hz;
- qemu_irq rtc_irq;
- qemu_irq rtc_hz_irq;
-} StrongARMRTCState;
-
-static inline void strongarm_rtc_int_update(StrongARMRTCState *s)
-{
- qemu_set_irq(s->rtc_irq, s->rtsr & RTSR_AL);
- qemu_set_irq(s->rtc_hz_irq, s->rtsr & RTSR_HZ);
-}
-
-static void strongarm_rtc_hzupdate(StrongARMRTCState *s)
-{
- int64_t rt = qemu_clock_get_ms(rtc_clock);
- s->last_rcnr += ((rt - s->last_hz) << 15) /
- (1000 * ((s->rttr & 0xffff) + 1));
- s->last_hz = rt;
-}
-
-static inline void strongarm_rtc_timer_update(StrongARMRTCState *s)
-{
- if ((s->rtsr & RTSR_HZE) && !(s->rtsr & RTSR_HZ)) {
- timer_mod(s->rtc_hz, s->last_hz + 1000);
- } else {
- timer_del(s->rtc_hz);
- }
-
- if ((s->rtsr & RTSR_ALE) && !(s->rtsr & RTSR_AL)) {
- timer_mod(s->rtc_alarm, s->last_hz +
- (((s->rtar - s->last_rcnr) * 1000 *
- ((s->rttr & 0xffff) + 1)) >> 15));
- } else {
- timer_del(s->rtc_alarm);
- }
-}
-
-static inline void strongarm_rtc_alarm_tick(void *opaque)
-{
- StrongARMRTCState *s = opaque;
- s->rtsr |= RTSR_AL;
- strongarm_rtc_timer_update(s);
- strongarm_rtc_int_update(s);
-}
-
-static inline void strongarm_rtc_hz_tick(void *opaque)
-{
- StrongARMRTCState *s = opaque;
- s->rtsr |= RTSR_HZ;
- strongarm_rtc_timer_update(s);
- strongarm_rtc_int_update(s);
-}
-
-static uint64_t strongarm_rtc_read(void *opaque, hwaddr addr,
- unsigned size)
-{
- StrongARMRTCState *s = opaque;
-
- switch (addr) {
- case RTTR:
- return s->rttr;
- case RTSR:
- return s->rtsr;
- case RTAR:
- return s->rtar;
- case RCNR:
- return s->last_rcnr +
- ((qemu_clock_get_ms(rtc_clock) - s->last_hz) << 15) /
- (1000 * ((s->rttr & 0xffff) + 1));
- default:
- printf("%s: Bad register 0x" TARGET_FMT_plx "\n", __func__, addr);
- return 0;
- }
-}
-
-static void strongarm_rtc_write(void *opaque, hwaddr addr,
- uint64_t value, unsigned size)
-{
- StrongARMRTCState *s = opaque;
- uint32_t old_rtsr;
-
- switch (addr) {
- case RTTR:
- strongarm_rtc_hzupdate(s);
- s->rttr = value;
- strongarm_rtc_timer_update(s);
- break;
-
- case RTSR:
- old_rtsr = s->rtsr;
- s->rtsr = (value & (RTSR_ALE | RTSR_HZE)) |
- (s->rtsr & ~(value & (RTSR_AL | RTSR_HZ)));
-
- if (s->rtsr != old_rtsr) {
- strongarm_rtc_timer_update(s);
- }
-
- strongarm_rtc_int_update(s);
- break;
-
- case RTAR:
- s->rtar = value;
- strongarm_rtc_timer_update(s);
- break;
-
- case RCNR:
- strongarm_rtc_hzupdate(s);
- s->last_rcnr = value;
- strongarm_rtc_timer_update(s);
- break;
-
- default:
- printf("%s: Bad register 0x" TARGET_FMT_plx "\n", __func__, addr);
- }
-}
-
-static const MemoryRegionOps strongarm_rtc_ops = {
- .read = strongarm_rtc_read,
- .write = strongarm_rtc_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static int strongarm_rtc_init(SysBusDevice *dev)
-{
- StrongARMRTCState *s = STRONGARM_RTC(dev);
- struct tm tm;
-
- s->rttr = 0x0;
- s->rtsr = 0;
-
- qemu_get_timedate(&tm, 0);
-
- s->last_rcnr = (uint32_t) mktimegm(&tm);
- s->last_hz = qemu_clock_get_ms(rtc_clock);
-
- s->rtc_alarm = timer_new_ms(rtc_clock, strongarm_rtc_alarm_tick, s);
- s->rtc_hz = timer_new_ms(rtc_clock, strongarm_rtc_hz_tick, s);
-
- sysbus_init_irq(dev, &s->rtc_irq);
- sysbus_init_irq(dev, &s->rtc_hz_irq);
-
- memory_region_init_io(&s->iomem, OBJECT(s), &strongarm_rtc_ops, s,
- "rtc", 0x10000);
- sysbus_init_mmio(dev, &s->iomem);
-
- return 0;
-}
-
-static void strongarm_rtc_pre_save(void *opaque)
-{
- StrongARMRTCState *s = opaque;
-
- strongarm_rtc_hzupdate(s);
-}
-
-static int strongarm_rtc_post_load(void *opaque, int version_id)
-{
- StrongARMRTCState *s = opaque;
-
- strongarm_rtc_timer_update(s);
- strongarm_rtc_int_update(s);
-
- return 0;
-}
-
-static const VMStateDescription vmstate_strongarm_rtc_regs = {
- .name = "strongarm-rtc",
- .version_id = 0,
- .minimum_version_id = 0,
- .pre_save = strongarm_rtc_pre_save,
- .post_load = strongarm_rtc_post_load,
- .fields = (VMStateField[]) {
- VMSTATE_UINT32(rttr, StrongARMRTCState),
- VMSTATE_UINT32(rtsr, StrongARMRTCState),
- VMSTATE_UINT32(rtar, StrongARMRTCState),
- VMSTATE_UINT32(last_rcnr, StrongARMRTCState),
- VMSTATE_INT64(last_hz, StrongARMRTCState),
- VMSTATE_END_OF_LIST(),
- },
-};
-
-static void strongarm_rtc_sysbus_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
-
- k->init = strongarm_rtc_init;
- dc->desc = "StrongARM RTC Controller";
- dc->vmsd = &vmstate_strongarm_rtc_regs;
-}
-
-static const TypeInfo strongarm_rtc_sysbus_info = {
- .name = TYPE_STRONGARM_RTC,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(StrongARMRTCState),
- .class_init = strongarm_rtc_sysbus_class_init,
-};
-
-/* GPIO */
-#define GPLR 0x00
-#define GPDR 0x04
-#define GPSR 0x08
-#define GPCR 0x0c
-#define GRER 0x10
-#define GFER 0x14
-#define GEDR 0x18
-#define GAFR 0x1c
-
-#define TYPE_STRONGARM_GPIO "strongarm-gpio"
-#define STRONGARM_GPIO(obj) \
- OBJECT_CHECK(StrongARMGPIOInfo, (obj), TYPE_STRONGARM_GPIO)
-
-typedef struct StrongARMGPIOInfo StrongARMGPIOInfo;
-struct StrongARMGPIOInfo {
- SysBusDevice busdev;
- MemoryRegion iomem;
- qemu_irq handler[28];
- qemu_irq irqs[11];
- qemu_irq irqX;
-
- uint32_t ilevel;
- uint32_t olevel;
- uint32_t dir;
- uint32_t rising;
- uint32_t falling;
- uint32_t status;
- uint32_t gafr;
-
- uint32_t prev_level;
-};
-
-
-static void strongarm_gpio_irq_update(StrongARMGPIOInfo *s)
-{
- int i;
- for (i = 0; i < 11; i++) {
- qemu_set_irq(s->irqs[i], s->status & (1 << i));
- }
-
- qemu_set_irq(s->irqX, (s->status & ~0x7ff));
-}
-
-static void strongarm_gpio_set(void *opaque, int line, int level)
-{
- StrongARMGPIOInfo *s = opaque;
- uint32_t mask;
-
- mask = 1 << line;
-
- if (level) {
- s->status |= s->rising & mask &
- ~s->ilevel & ~s->dir;
- s->ilevel |= mask;
- } else {
- s->status |= s->falling & mask &
- s->ilevel & ~s->dir;
- s->ilevel &= ~mask;
- }
-
- if (s->status & mask) {
- strongarm_gpio_irq_update(s);
- }
-}
-
-static void strongarm_gpio_handler_update(StrongARMGPIOInfo *s)
-{
- uint32_t level, diff;
- int bit;
-
- level = s->olevel & s->dir;
-
- for (diff = s->prev_level ^ level; diff; diff ^= 1 << bit) {
- bit = ctz32(diff);
- qemu_set_irq(s->handler[bit], (level >> bit) & 1);
- }
-
- s->prev_level = level;
-}
-
-static uint64_t strongarm_gpio_read(void *opaque, hwaddr offset,
- unsigned size)
-{
- StrongARMGPIOInfo *s = opaque;
-
- switch (offset) {
- case GPDR: /* GPIO Pin-Direction registers */
- return s->dir;
-
- case GPSR: /* GPIO Pin-Output Set registers */
- qemu_log_mask(LOG_GUEST_ERROR,
- "strongarm GPIO: read from write only register GPSR\n");
- return 0;
-
- case GPCR: /* GPIO Pin-Output Clear registers */
- qemu_log_mask(LOG_GUEST_ERROR,
- "strongarm GPIO: read from write only register GPCR\n");
- return 0;
-
- case GRER: /* GPIO Rising-Edge Detect Enable registers */
- return s->rising;
-
- case GFER: /* GPIO Falling-Edge Detect Enable registers */
- return s->falling;
-
- case GAFR: /* GPIO Alternate Function registers */
- return s->gafr;
-
- case GPLR: /* GPIO Pin-Level registers */
- return (s->olevel & s->dir) |
- (s->ilevel & ~s->dir);
-
- case GEDR: /* GPIO Edge Detect Status registers */
- return s->status;
-
- default:
- printf("%s: Bad offset 0x" TARGET_FMT_plx "\n", __func__, offset);
- }
-
- return 0;
-}
-
-static void strongarm_gpio_write(void *opaque, hwaddr offset,
- uint64_t value, unsigned size)
-{
- StrongARMGPIOInfo *s = opaque;
-
- switch (offset) {
- case GPDR: /* GPIO Pin-Direction registers */
- s->dir = value;
- strongarm_gpio_handler_update(s);
- break;
-
- case GPSR: /* GPIO Pin-Output Set registers */
- s->olevel |= value;
- strongarm_gpio_handler_update(s);
- break;
-
- case GPCR: /* GPIO Pin-Output Clear registers */
- s->olevel &= ~value;
- strongarm_gpio_handler_update(s);
- break;
-
- case GRER: /* GPIO Rising-Edge Detect Enable registers */
- s->rising = value;
- break;
-
- case GFER: /* GPIO Falling-Edge Detect Enable registers */
- s->falling = value;
- break;
-
- case GAFR: /* GPIO Alternate Function registers */
- s->gafr = value;
- break;
-
- case GEDR: /* GPIO Edge Detect Status registers */
- s->status &= ~value;
- strongarm_gpio_irq_update(s);
- break;
-
- default:
- printf("%s: Bad offset 0x" TARGET_FMT_plx "\n", __func__, offset);
- }
-}
-
-static const MemoryRegionOps strongarm_gpio_ops = {
- .read = strongarm_gpio_read,
- .write = strongarm_gpio_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static DeviceState *strongarm_gpio_init(hwaddr base,
- DeviceState *pic)
-{
- DeviceState *dev;
- int i;
-
- dev = qdev_create(NULL, TYPE_STRONGARM_GPIO);
- qdev_init_nofail(dev);
-
- sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
- for (i = 0; i < 12; i++)
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), i,
- qdev_get_gpio_in(pic, SA_PIC_GPIO0_EDGE + i));
-
- return dev;
-}
-
-static int strongarm_gpio_initfn(SysBusDevice *sbd)
-{
- DeviceState *dev = DEVICE(sbd);
- StrongARMGPIOInfo *s = STRONGARM_GPIO(dev);
- int i;
-
- qdev_init_gpio_in(dev, strongarm_gpio_set, 28);
- qdev_init_gpio_out(dev, s->handler, 28);
-
- memory_region_init_io(&s->iomem, OBJECT(s), &strongarm_gpio_ops, s,
- "gpio", 0x1000);
-
- sysbus_init_mmio(sbd, &s->iomem);
- for (i = 0; i < 11; i++) {
- sysbus_init_irq(sbd, &s->irqs[i]);
- }
- sysbus_init_irq(sbd, &s->irqX);
-
- return 0;
-}
-
-static const VMStateDescription vmstate_strongarm_gpio_regs = {
- .name = "strongarm-gpio",
- .version_id = 0,
- .minimum_version_id = 0,
- .fields = (VMStateField[]) {
- VMSTATE_UINT32(ilevel, StrongARMGPIOInfo),
- VMSTATE_UINT32(olevel, StrongARMGPIOInfo),
- VMSTATE_UINT32(dir, StrongARMGPIOInfo),
- VMSTATE_UINT32(rising, StrongARMGPIOInfo),
- VMSTATE_UINT32(falling, StrongARMGPIOInfo),
- VMSTATE_UINT32(status, StrongARMGPIOInfo),
- VMSTATE_UINT32(gafr, StrongARMGPIOInfo),
- VMSTATE_UINT32(prev_level, StrongARMGPIOInfo),
- VMSTATE_END_OF_LIST(),
- },
-};
-
-static void strongarm_gpio_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
-
- k->init = strongarm_gpio_initfn;
- dc->desc = "StrongARM GPIO controller";
- dc->vmsd = &vmstate_strongarm_gpio_regs;
-}
-
-static const TypeInfo strongarm_gpio_info = {
- .name = TYPE_STRONGARM_GPIO,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(StrongARMGPIOInfo),
- .class_init = strongarm_gpio_class_init,
-};
-
-/* Peripheral Pin Controller */
-#define PPDR 0x00
-#define PPSR 0x04
-#define PPAR 0x08
-#define PSDR 0x0c
-#define PPFR 0x10
-
-#define TYPE_STRONGARM_PPC "strongarm-ppc"
-#define STRONGARM_PPC(obj) \
- OBJECT_CHECK(StrongARMPPCInfo, (obj), TYPE_STRONGARM_PPC)
-
-typedef struct StrongARMPPCInfo StrongARMPPCInfo;
-struct StrongARMPPCInfo {
- SysBusDevice parent_obj;
-
- MemoryRegion iomem;
- qemu_irq handler[28];
-
- uint32_t ilevel;
- uint32_t olevel;
- uint32_t dir;
- uint32_t ppar;
- uint32_t psdr;
- uint32_t ppfr;
-
- uint32_t prev_level;
-};
-
-static void strongarm_ppc_set(void *opaque, int line, int level)
-{
- StrongARMPPCInfo *s = opaque;
-
- if (level) {
- s->ilevel |= 1 << line;
- } else {
- s->ilevel &= ~(1 << line);
- }
-}
-
-static void strongarm_ppc_handler_update(StrongARMPPCInfo *s)
-{
- uint32_t level, diff;
- int bit;
-
- level = s->olevel & s->dir;
-
- for (diff = s->prev_level ^ level; diff; diff ^= 1 << bit) {
- bit = ctz32(diff);
- qemu_set_irq(s->handler[bit], (level >> bit) & 1);
- }
-
- s->prev_level = level;
-}
-
-static uint64_t strongarm_ppc_read(void *opaque, hwaddr offset,
- unsigned size)
-{
- StrongARMPPCInfo *s = opaque;
-
- switch (offset) {
- case PPDR: /* PPC Pin Direction registers */
- return s->dir | ~0x3fffff;
-
- case PPSR: /* PPC Pin State registers */
- return (s->olevel & s->dir) |
- (s->ilevel & ~s->dir) |
- ~0x3fffff;
-
- case PPAR:
- return s->ppar | ~0x41000;
-
- case PSDR:
- return s->psdr;
-
- case PPFR:
- return s->ppfr | ~0x7f001;
-
- default:
- printf("%s: Bad offset 0x" TARGET_FMT_plx "\n", __func__, offset);
- }
-
- return 0;
-}
-
-static void strongarm_ppc_write(void *opaque, hwaddr offset,
- uint64_t value, unsigned size)
-{
- StrongARMPPCInfo *s = opaque;
-
- switch (offset) {
- case PPDR: /* PPC Pin Direction registers */
- s->dir = value & 0x3fffff;
- strongarm_ppc_handler_update(s);
- break;
-
- case PPSR: /* PPC Pin State registers */
- s->olevel = value & s->dir & 0x3fffff;
- strongarm_ppc_handler_update(s);
- break;
-
- case PPAR:
- s->ppar = value & 0x41000;
- break;
-
- case PSDR:
- s->psdr = value & 0x3fffff;
- break;
-
- case PPFR:
- s->ppfr = value & 0x7f001;
- break;
-
- default:
- printf("%s: Bad offset 0x" TARGET_FMT_plx "\n", __func__, offset);
- }
-}
-
-static const MemoryRegionOps strongarm_ppc_ops = {
- .read = strongarm_ppc_read,
- .write = strongarm_ppc_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static int strongarm_ppc_init(SysBusDevice *sbd)
-{
- DeviceState *dev = DEVICE(sbd);
- StrongARMPPCInfo *s = STRONGARM_PPC(dev);
-
- qdev_init_gpio_in(dev, strongarm_ppc_set, 22);
- qdev_init_gpio_out(dev, s->handler, 22);
-
- memory_region_init_io(&s->iomem, OBJECT(s), &strongarm_ppc_ops, s,
- "ppc", 0x1000);
-
- sysbus_init_mmio(sbd, &s->iomem);
-
- return 0;
-}
-
-static const VMStateDescription vmstate_strongarm_ppc_regs = {
- .name = "strongarm-ppc",
- .version_id = 0,
- .minimum_version_id = 0,
- .fields = (VMStateField[]) {
- VMSTATE_UINT32(ilevel, StrongARMPPCInfo),
- VMSTATE_UINT32(olevel, StrongARMPPCInfo),
- VMSTATE_UINT32(dir, StrongARMPPCInfo),
- VMSTATE_UINT32(ppar, StrongARMPPCInfo),
- VMSTATE_UINT32(psdr, StrongARMPPCInfo),
- VMSTATE_UINT32(ppfr, StrongARMPPCInfo),
- VMSTATE_UINT32(prev_level, StrongARMPPCInfo),
- VMSTATE_END_OF_LIST(),
- },
-};
-
-static void strongarm_ppc_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
-
- k->init = strongarm_ppc_init;
- dc->desc = "StrongARM PPC controller";
- dc->vmsd = &vmstate_strongarm_ppc_regs;
-}
-
-static const TypeInfo strongarm_ppc_info = {
- .name = TYPE_STRONGARM_PPC,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(StrongARMPPCInfo),
- .class_init = strongarm_ppc_class_init,
-};
-
-/* UART Ports */
-#define UTCR0 0x00
-#define UTCR1 0x04
-#define UTCR2 0x08
-#define UTCR3 0x0c
-#define UTDR 0x14
-#define UTSR0 0x1c
-#define UTSR1 0x20
-
-#define UTCR0_PE (1 << 0) /* Parity enable */
-#define UTCR0_OES (1 << 1) /* Even parity */
-#define UTCR0_SBS (1 << 2) /* 2 stop bits */
-#define UTCR0_DSS (1 << 3) /* 8-bit data */
-
-#define UTCR3_RXE (1 << 0) /* Rx enable */
-#define UTCR3_TXE (1 << 1) /* Tx enable */
-#define UTCR3_BRK (1 << 2) /* Force Break */
-#define UTCR3_RIE (1 << 3) /* Rx int enable */
-#define UTCR3_TIE (1 << 4) /* Tx int enable */
-#define UTCR3_LBM (1 << 5) /* Loopback */
-
-#define UTSR0_TFS (1 << 0) /* Tx FIFO nearly empty */
-#define UTSR0_RFS (1 << 1) /* Rx FIFO nearly full */
-#define UTSR0_RID (1 << 2) /* Receiver Idle */
-#define UTSR0_RBB (1 << 3) /* Receiver begin break */
-#define UTSR0_REB (1 << 4) /* Receiver end break */
-#define UTSR0_EIF (1 << 5) /* Error in FIFO */
-
-#define UTSR1_RNE (1 << 1) /* Receive FIFO not empty */
-#define UTSR1_TNF (1 << 2) /* Transmit FIFO not full */
-#define UTSR1_PRE (1 << 3) /* Parity error */
-#define UTSR1_FRE (1 << 4) /* Frame error */
-#define UTSR1_ROR (1 << 5) /* Receive Over Run */
-
-#define RX_FIFO_PRE (1 << 8)
-#define RX_FIFO_FRE (1 << 9)
-#define RX_FIFO_ROR (1 << 10)
-
-#define TYPE_STRONGARM_UART "strongarm-uart"
-#define STRONGARM_UART(obj) \
- OBJECT_CHECK(StrongARMUARTState, (obj), TYPE_STRONGARM_UART)
-
-typedef struct StrongARMUARTState {
- SysBusDevice parent_obj;
-
- MemoryRegion iomem;
- CharDriverState *chr;
- qemu_irq irq;
-
- uint8_t utcr0;
- uint16_t brd;
- uint8_t utcr3;
- uint8_t utsr0;
- uint8_t utsr1;
-
- uint8_t tx_fifo[8];
- uint8_t tx_start;
- uint8_t tx_len;
- uint16_t rx_fifo[12]; /* value + error flags in high bits */
- uint8_t rx_start;
- uint8_t rx_len;
-
- uint64_t char_transmit_time; /* time to transmit a char in ticks*/
- bool wait_break_end;
- QEMUTimer *rx_timeout_timer;
- QEMUTimer *tx_timer;
-} StrongARMUARTState;
-
-static void strongarm_uart_update_status(StrongARMUARTState *s)
-{
- uint16_t utsr1 = 0;
-
- if (s->tx_len != 8) {
- utsr1 |= UTSR1_TNF;
- }
-
- if (s->rx_len != 0) {
- uint16_t ent = s->rx_fifo[s->rx_start];
-
- utsr1 |= UTSR1_RNE;
- if (ent & RX_FIFO_PRE) {
- s->utsr1 |= UTSR1_PRE;
- }
- if (ent & RX_FIFO_FRE) {
- s->utsr1 |= UTSR1_FRE;
- }
- if (ent & RX_FIFO_ROR) {
- s->utsr1 |= UTSR1_ROR;
- }
- }
-
- s->utsr1 = utsr1;
-}
-
-static void strongarm_uart_update_int_status(StrongARMUARTState *s)
-{
- uint16_t utsr0 = s->utsr0 &
- (UTSR0_REB | UTSR0_RBB | UTSR0_RID);
- int i;
-
- if ((s->utcr3 & UTCR3_TXE) &&
- (s->utcr3 & UTCR3_TIE) &&
- s->tx_len <= 4) {
- utsr0 |= UTSR0_TFS;
- }
-
- if ((s->utcr3 & UTCR3_RXE) &&
- (s->utcr3 & UTCR3_RIE) &&
- s->rx_len > 4) {
- utsr0 |= UTSR0_RFS;
- }
-
- for (i = 0; i < s->rx_len && i < 4; i++)
- if (s->rx_fifo[(s->rx_start + i) % 12] & ~0xff) {
- utsr0 |= UTSR0_EIF;
- break;
- }
-
- s->utsr0 = utsr0;
- qemu_set_irq(s->irq, utsr0);
-}
-
-static void strongarm_uart_update_parameters(StrongARMUARTState *s)
-{
- int speed, parity, data_bits, stop_bits, frame_size;
- QEMUSerialSetParams ssp;
-
- /* Start bit. */
- frame_size = 1;
- if (s->utcr0 & UTCR0_PE) {
- /* Parity bit. */
- frame_size++;
- if (s->utcr0 & UTCR0_OES) {
- parity = 'E';
- } else {
- parity = 'O';
- }
- } else {
- parity = 'N';
- }
- if (s->utcr0 & UTCR0_SBS) {
- stop_bits = 2;
- } else {
- stop_bits = 1;
- }
-
- data_bits = (s->utcr0 & UTCR0_DSS) ? 8 : 7;
- frame_size += data_bits + stop_bits;
- speed = 3686400 / 16 / (s->brd + 1);
- ssp.speed = speed;
- ssp.parity = parity;
- ssp.data_bits = data_bits;
- ssp.stop_bits = stop_bits;
- s->char_transmit_time = (NANOSECONDS_PER_SECOND / speed) * frame_size;
- if (s->chr) {
- qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
- }
-
- DPRINTF(stderr, "%s speed=%d parity=%c data=%d stop=%d\n", s->chr->label,
- speed, parity, data_bits, stop_bits);
-}
-
-static void strongarm_uart_rx_to(void *opaque)
-{
- StrongARMUARTState *s = opaque;
-
- if (s->rx_len) {
- s->utsr0 |= UTSR0_RID;
- strongarm_uart_update_int_status(s);
- }
-}
-
-static void strongarm_uart_rx_push(StrongARMUARTState *s, uint16_t c)
-{
- if ((s->utcr3 & UTCR3_RXE) == 0) {
- /* rx disabled */
- return;
- }
-
- if (s->wait_break_end) {
- s->utsr0 |= UTSR0_REB;
- s->wait_break_end = false;
- }
-
- if (s->rx_len < 12) {
- s->rx_fifo[(s->rx_start + s->rx_len) % 12] = c;
- s->rx_len++;
- } else
- s->rx_fifo[(s->rx_start + 11) % 12] |= RX_FIFO_ROR;
-}
-
-static int strongarm_uart_can_receive(void *opaque)
-{
- StrongARMUARTState *s = opaque;
-
- if (s->rx_len == 12) {
- return 0;
- }
- /* It's best not to get more than 2/3 of RX FIFO, so advertise that much */
- if (s->rx_len < 8) {
- return 8 - s->rx_len;
- }
- return 1;
-}
-
-static void strongarm_uart_receive(void *opaque, const uint8_t *buf, int size)
-{
- StrongARMUARTState *s = opaque;
- int i;
-
- for (i = 0; i < size; i++) {
- strongarm_uart_rx_push(s, buf[i]);
- }
-
- /* call the timeout receive callback in 3 char transmit time */
- timer_mod(s->rx_timeout_timer,
- qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + s->char_transmit_time * 3);
-
- strongarm_uart_update_status(s);
- strongarm_uart_update_int_status(s);
-}
-
-static void strongarm_uart_event(void *opaque, int event)
-{
- StrongARMUARTState *s = opaque;
- if (event == CHR_EVENT_BREAK) {
- s->utsr0 |= UTSR0_RBB;
- strongarm_uart_rx_push(s, RX_FIFO_FRE);
- s->wait_break_end = true;
- strongarm_uart_update_status(s);
- strongarm_uart_update_int_status(s);
- }
-}
-
-static void strongarm_uart_tx(void *opaque)
-{
- StrongARMUARTState *s = opaque;
- uint64_t new_xmit_ts = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
-
- if (s->utcr3 & UTCR3_LBM) /* loopback */ {
- strongarm_uart_receive(s, &s->tx_fifo[s->tx_start], 1);
- } else if (s->chr) {
- qemu_chr_fe_write(s->chr, &s->tx_fifo[s->tx_start], 1);
- }
-
- s->tx_start = (s->tx_start + 1) % 8;
- s->tx_len--;
- if (s->tx_len) {
- timer_mod(s->tx_timer, new_xmit_ts + s->char_transmit_time);
- }
- strongarm_uart_update_status(s);
- strongarm_uart_update_int_status(s);
-}
-
-static uint64_t strongarm_uart_read(void *opaque, hwaddr addr,
- unsigned size)
-{
- StrongARMUARTState *s = opaque;
- uint16_t ret;
-
- switch (addr) {
- case UTCR0:
- return s->utcr0;
-
- case UTCR1:
- return s->brd >> 8;
-
- case UTCR2:
- return s->brd & 0xff;
-
- case UTCR3:
- return s->utcr3;
-
- case UTDR:
- if (s->rx_len != 0) {
- ret = s->rx_fifo[s->rx_start];
- s->rx_start = (s->rx_start + 1) % 12;
- s->rx_len--;
- strongarm_uart_update_status(s);
- strongarm_uart_update_int_status(s);
- return ret;
- }
- return 0;
-
- case UTSR0:
- return s->utsr0;
-
- case UTSR1:
- return s->utsr1;
-
- default:
- printf("%s: Bad register 0x" TARGET_FMT_plx "\n", __func__, addr);
- return 0;
- }
-}
-
-static void strongarm_uart_write(void *opaque, hwaddr addr,
- uint64_t value, unsigned size)
-{
- StrongARMUARTState *s = opaque;
-
- switch (addr) {
- case UTCR0:
- s->utcr0 = value & 0x7f;
- strongarm_uart_update_parameters(s);
- break;
-
- case UTCR1:
- s->brd = (s->brd & 0xff) | ((value & 0xf) << 8);
- strongarm_uart_update_parameters(s);
- break;
-
- case UTCR2:
- s->brd = (s->brd & 0xf00) | (value & 0xff);
- strongarm_uart_update_parameters(s);
- break;
-
- case UTCR3:
- s->utcr3 = value & 0x3f;
- if ((s->utcr3 & UTCR3_RXE) == 0) {
- s->rx_len = 0;
- }
- if ((s->utcr3 & UTCR3_TXE) == 0) {
- s->tx_len = 0;
- }
- strongarm_uart_update_status(s);
- strongarm_uart_update_int_status(s);
- break;
-
- case UTDR:
- if ((s->utcr3 & UTCR3_TXE) && s->tx_len != 8) {
- s->tx_fifo[(s->tx_start + s->tx_len) % 8] = value;
- s->tx_len++;
- strongarm_uart_update_status(s);
- strongarm_uart_update_int_status(s);
- if (s->tx_len == 1) {
- strongarm_uart_tx(s);
- }
- }
- break;
-
- case UTSR0:
- s->utsr0 = s->utsr0 & ~(value &
- (UTSR0_REB | UTSR0_RBB | UTSR0_RID));
- strongarm_uart_update_int_status(s);
- break;
-
- default:
- printf("%s: Bad register 0x" TARGET_FMT_plx "\n", __func__, addr);
- }
-}
-
-static const MemoryRegionOps strongarm_uart_ops = {
- .read = strongarm_uart_read,
- .write = strongarm_uart_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static int strongarm_uart_init(SysBusDevice *dev)
-{
- StrongARMUARTState *s = STRONGARM_UART(dev);
-
- memory_region_init_io(&s->iomem, OBJECT(s), &strongarm_uart_ops, s,
- "uart", 0x10000);
- sysbus_init_mmio(dev, &s->iomem);
- sysbus_init_irq(dev, &s->irq);
-
- s->rx_timeout_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, strongarm_uart_rx_to, s);
- s->tx_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, strongarm_uart_tx, s);
-
- if (s->chr) {
- qemu_chr_add_handlers(s->chr,
- strongarm_uart_can_receive,
- strongarm_uart_receive,
- strongarm_uart_event,
- s);
- }
-
- return 0;
-}
-
-static void strongarm_uart_reset(DeviceState *dev)
-{
- StrongARMUARTState *s = STRONGARM_UART(dev);
-
- s->utcr0 = UTCR0_DSS; /* 8 data, no parity */
- s->brd = 23; /* 9600 */
- /* enable send & recv - this actually violates spec */
- s->utcr3 = UTCR3_TXE | UTCR3_RXE;
-
- s->rx_len = s->tx_len = 0;
-
- strongarm_uart_update_parameters(s);
- strongarm_uart_update_status(s);
- strongarm_uart_update_int_status(s);
-}
-
-static int strongarm_uart_post_load(void *opaque, int version_id)
-{
- StrongARMUARTState *s = opaque;
-
- strongarm_uart_update_parameters(s);
- strongarm_uart_update_status(s);
- strongarm_uart_update_int_status(s);
-
- /* tx and restart timer */
- if (s->tx_len) {
- strongarm_uart_tx(s);
- }
-
- /* restart rx timeout timer */
- if (s->rx_len) {
- timer_mod(s->rx_timeout_timer,
- qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + s->char_transmit_time * 3);
- }
-
- return 0;
-}
-
-static const VMStateDescription vmstate_strongarm_uart_regs = {
- .name = "strongarm-uart",
- .version_id = 0,
- .minimum_version_id = 0,
- .post_load = strongarm_uart_post_load,
- .fields = (VMStateField[]) {
- VMSTATE_UINT8(utcr0, StrongARMUARTState),
- VMSTATE_UINT16(brd, StrongARMUARTState),
- VMSTATE_UINT8(utcr3, StrongARMUARTState),
- VMSTATE_UINT8(utsr0, StrongARMUARTState),
- VMSTATE_UINT8_ARRAY(tx_fifo, StrongARMUARTState, 8),
- VMSTATE_UINT8(tx_start, StrongARMUARTState),
- VMSTATE_UINT8(tx_len, StrongARMUARTState),
- VMSTATE_UINT16_ARRAY(rx_fifo, StrongARMUARTState, 12),
- VMSTATE_UINT8(rx_start, StrongARMUARTState),
- VMSTATE_UINT8(rx_len, StrongARMUARTState),
- VMSTATE_BOOL(wait_break_end, StrongARMUARTState),
- VMSTATE_END_OF_LIST(),
- },
-};
-
-static Property strongarm_uart_properties[] = {
- DEFINE_PROP_CHR("chardev", StrongARMUARTState, chr),
- DEFINE_PROP_END_OF_LIST(),
-};
-
-static void strongarm_uart_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
-
- k->init = strongarm_uart_init;
- dc->desc = "StrongARM UART controller";
- dc->reset = strongarm_uart_reset;
- dc->vmsd = &vmstate_strongarm_uart_regs;
- dc->props = strongarm_uart_properties;
-}
-
-static const TypeInfo strongarm_uart_info = {
- .name = TYPE_STRONGARM_UART,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(StrongARMUARTState),
- .class_init = strongarm_uart_class_init,
-};
-
-/* Synchronous Serial Ports */
-
-#define TYPE_STRONGARM_SSP "strongarm-ssp"
-#define STRONGARM_SSP(obj) \
- OBJECT_CHECK(StrongARMSSPState, (obj), TYPE_STRONGARM_SSP)
-
-typedef struct StrongARMSSPState {
- SysBusDevice parent_obj;
-
- MemoryRegion iomem;
- qemu_irq irq;
- SSIBus *bus;
-
- uint16_t sscr[2];
- uint16_t sssr;
-
- uint16_t rx_fifo[8];
- uint8_t rx_level;
- uint8_t rx_start;
-} StrongARMSSPState;
-
-#define SSCR0 0x60 /* SSP Control register 0 */
-#define SSCR1 0x64 /* SSP Control register 1 */
-#define SSDR 0x6c /* SSP Data register */
-#define SSSR 0x74 /* SSP Status register */
-
-/* Bitfields for above registers */
-#define SSCR0_SPI(x) (((x) & 0x30) == 0x00)
-#define SSCR0_SSP(x) (((x) & 0x30) == 0x10)
-#define SSCR0_UWIRE(x) (((x) & 0x30) == 0x20)
-#define SSCR0_PSP(x) (((x) & 0x30) == 0x30)
-#define SSCR0_SSE (1 << 7)
-#define SSCR0_DSS(x) (((x) & 0xf) + 1)
-#define SSCR1_RIE (1 << 0)
-#define SSCR1_TIE (1 << 1)
-#define SSCR1_LBM (1 << 2)
-#define SSSR_TNF (1 << 2)
-#define SSSR_RNE (1 << 3)
-#define SSSR_TFS (1 << 5)
-#define SSSR_RFS (1 << 6)
-#define SSSR_ROR (1 << 7)
-#define SSSR_RW 0x0080
-
-static void strongarm_ssp_int_update(StrongARMSSPState *s)
-{
- int level = 0;
-
- level |= (s->sssr & SSSR_ROR);
- level |= (s->sssr & SSSR_RFS) && (s->sscr[1] & SSCR1_RIE);
- level |= (s->sssr & SSSR_TFS) && (s->sscr[1] & SSCR1_TIE);
- qemu_set_irq(s->irq, level);
-}
-
-static void strongarm_ssp_fifo_update(StrongARMSSPState *s)
-{
- s->sssr &= ~SSSR_TFS;
- s->sssr &= ~SSSR_TNF;
- if (s->sscr[0] & SSCR0_SSE) {
- if (s->rx_level >= 4) {
- s->sssr |= SSSR_RFS;
- } else {
- s->sssr &= ~SSSR_RFS;
- }
- if (s->rx_level) {
- s->sssr |= SSSR_RNE;
- } else {
- s->sssr &= ~SSSR_RNE;
- }
- /* TX FIFO is never filled, so it is always in underrun
- condition if SSP is enabled */
- s->sssr |= SSSR_TFS;
- s->sssr |= SSSR_TNF;
- }
-
- strongarm_ssp_int_update(s);
-}
-
-static uint64_t strongarm_ssp_read(void *opaque, hwaddr addr,
- unsigned size)
-{
- StrongARMSSPState *s = opaque;
- uint32_t retval;
-
- switch (addr) {
- case SSCR0:
- return s->sscr[0];
- case SSCR1:
- return s->sscr[1];
- case SSSR:
- return s->sssr;
- case SSDR:
- if (~s->sscr[0] & SSCR0_SSE) {
- return 0xffffffff;
- }
- if (s->rx_level < 1) {
- printf("%s: SSP Rx Underrun\n", __func__);
- return 0xffffffff;
- }
- s->rx_level--;
- retval = s->rx_fifo[s->rx_start++];
- s->rx_start &= 0x7;
- strongarm_ssp_fifo_update(s);
- return retval;
- default:
- printf("%s: Bad register 0x" TARGET_FMT_plx "\n", __func__, addr);
- break;
- }
- return 0;
-}
-
-static void strongarm_ssp_write(void *opaque, hwaddr addr,
- uint64_t value, unsigned size)
-{
- StrongARMSSPState *s = opaque;
-
- switch (addr) {
- case SSCR0:
- s->sscr[0] = value & 0xffbf;
- if ((s->sscr[0] & SSCR0_SSE) && SSCR0_DSS(value) < 4) {
- printf("%s: Wrong data size: %i bits\n", __func__,
- (int)SSCR0_DSS(value));
- }
- if (!(value & SSCR0_SSE)) {
- s->sssr = 0;
- s->rx_level = 0;
- }
- strongarm_ssp_fifo_update(s);
- break;
-
- case SSCR1:
- s->sscr[1] = value & 0x2f;
- if (value & SSCR1_LBM) {
- printf("%s: Attempt to use SSP LBM mode\n", __func__);
- }
- strongarm_ssp_fifo_update(s);
- break;
-
- case SSSR:
- s->sssr &= ~(value & SSSR_RW);
- strongarm_ssp_int_update(s);
- break;
-
- case SSDR:
- if (SSCR0_UWIRE(s->sscr[0])) {
- value &= 0xff;
- } else
- /* Note how 32bits overflow does no harm here */
- value &= (1 << SSCR0_DSS(s->sscr[0])) - 1;
-
- /* Data goes from here to the Tx FIFO and is shifted out from
- * there directly to the slave, no need to buffer it.
- */
- if (s->sscr[0] & SSCR0_SSE) {
- uint32_t readval;
- if (s->sscr[1] & SSCR1_LBM) {
- readval = value;
- } else {
- readval = ssi_transfer(s->bus, value);
- }
-
- if (s->rx_level < 0x08) {
- s->rx_fifo[(s->rx_start + s->rx_level++) & 0x7] = readval;
- } else {
- s->sssr |= SSSR_ROR;
- }
- }
- strongarm_ssp_fifo_update(s);
- break;
-
- default:
- printf("%s: Bad register 0x" TARGET_FMT_plx "\n", __func__, addr);
- break;
- }
-}
-
-static const MemoryRegionOps strongarm_ssp_ops = {
- .read = strongarm_ssp_read,
- .write = strongarm_ssp_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static int strongarm_ssp_post_load(void *opaque, int version_id)
-{
- StrongARMSSPState *s = opaque;
-
- strongarm_ssp_fifo_update(s);
-
- return 0;
-}
-
-static int strongarm_ssp_init(SysBusDevice *sbd)
-{
- DeviceState *dev = DEVICE(sbd);
- StrongARMSSPState *s = STRONGARM_SSP(dev);
-
- sysbus_init_irq(sbd, &s->irq);
-
- memory_region_init_io(&s->iomem, OBJECT(s), &strongarm_ssp_ops, s,
- "ssp", 0x1000);
- sysbus_init_mmio(sbd, &s->iomem);
-
- s->bus = ssi_create_bus(dev, "ssi");
- return 0;
-}
-
-static void strongarm_ssp_reset(DeviceState *dev)
-{
- StrongARMSSPState *s = STRONGARM_SSP(dev);
-
- s->sssr = 0x03; /* 3 bit data, SPI, disabled */
- s->rx_start = 0;
- s->rx_level = 0;
-}
-
-static const VMStateDescription vmstate_strongarm_ssp_regs = {
- .name = "strongarm-ssp",
- .version_id = 0,
- .minimum_version_id = 0,
- .post_load = strongarm_ssp_post_load,
- .fields = (VMStateField[]) {
- VMSTATE_UINT16_ARRAY(sscr, StrongARMSSPState, 2),
- VMSTATE_UINT16(sssr, StrongARMSSPState),
- VMSTATE_UINT16_ARRAY(rx_fifo, StrongARMSSPState, 8),
- VMSTATE_UINT8(rx_start, StrongARMSSPState),
- VMSTATE_UINT8(rx_level, StrongARMSSPState),
- VMSTATE_END_OF_LIST(),
- },
-};
-
-static void strongarm_ssp_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
-
- k->init = strongarm_ssp_init;
- dc->desc = "StrongARM SSP controller";
- dc->reset = strongarm_ssp_reset;
- dc->vmsd = &vmstate_strongarm_ssp_regs;
-}
-
-static const TypeInfo strongarm_ssp_info = {
- .name = TYPE_STRONGARM_SSP,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(StrongARMSSPState),
- .class_init = strongarm_ssp_class_init,
-};
-
-/* Main CPU functions */
-StrongARMState *sa1110_init(MemoryRegion *sysmem,
- unsigned int sdram_size, const char *rev)
-{
- StrongARMState *s;
- int i;
-
- s = g_new0(StrongARMState, 1);
-
- if (!rev) {
- rev = "sa1110-b5";
- }
-
- if (strncmp(rev, "sa1110", 6)) {
- error_report("Machine requires a SA1110 processor.");
- exit(1);
- }
-
- s->cpu = cpu_arm_init(rev);
-
- if (!s->cpu) {
- error_report("Unable to find CPU definition");
- exit(1);
- }
-
- memory_region_allocate_system_memory(&s->sdram, NULL, "strongarm.sdram",
- sdram_size);
- memory_region_add_subregion(sysmem, SA_SDCS0, &s->sdram);
-
- s->pic = sysbus_create_varargs("strongarm_pic", 0x90050000,
- qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_IRQ),
- qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_FIQ),
- NULL);
-
- sysbus_create_varargs("pxa25x-timer", 0x90000000,
- qdev_get_gpio_in(s->pic, SA_PIC_OSTC0),
- qdev_get_gpio_in(s->pic, SA_PIC_OSTC1),
- qdev_get_gpio_in(s->pic, SA_PIC_OSTC2),
- qdev_get_gpio_in(s->pic, SA_PIC_OSTC3),
- NULL);
-
- sysbus_create_simple(TYPE_STRONGARM_RTC, 0x90010000,
- qdev_get_gpio_in(s->pic, SA_PIC_RTC_ALARM));
-
- s->gpio = strongarm_gpio_init(0x90040000, s->pic);
-
- s->ppc = sysbus_create_varargs(TYPE_STRONGARM_PPC, 0x90060000, NULL);
-
- for (i = 0; sa_serial[i].io_base; i++) {
- DeviceState *dev = qdev_create(NULL, TYPE_STRONGARM_UART);
- qdev_prop_set_chr(dev, "chardev", serial_hds[i]);
- qdev_init_nofail(dev);
- sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0,
- sa_serial[i].io_base);
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0,
- qdev_get_gpio_in(s->pic, sa_serial[i].irq));
- }
-
- s->ssp = sysbus_create_varargs(TYPE_STRONGARM_SSP, 0x80070000,
- qdev_get_gpio_in(s->pic, SA_PIC_SSP), NULL);
- s->ssp_bus = (SSIBus *)qdev_get_child_bus(s->ssp, "ssi");
-
- return s;
-}
-
-static void strongarm_register_types(void)
-{
- type_register_static(&strongarm_pic_info);
- type_register_static(&strongarm_rtc_sysbus_info);
- type_register_static(&strongarm_gpio_info);
- type_register_static(&strongarm_ppc_info);
- type_register_static(&strongarm_uart_info);
- type_register_static(&strongarm_ssp_info);
-}
-
-type_init(strongarm_register_types)
diff --git a/qemu/hw/arm/strongarm.h b/qemu/hw/arm/strongarm.h
deleted file mode 100644
index 2893f9444..000000000
--- a/qemu/hw/arm/strongarm.h
+++ /dev/null
@@ -1,68 +0,0 @@
-#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/qemu/hw/arm/sysbus-fdt.c b/qemu/hw/arm/sysbus-fdt.c
deleted file mode 100644
index 5debb3348..000000000
--- a/qemu/hw/arm/sysbus-fdt.c
+++ /dev/null
@@ -1,542 +0,0 @@
-/*
- * ARM Platform Bus device tree generation helpers
- *
- * Copyright (c) 2014 Linaro Limited
- *
- * Authors:
- * Alex Graf <agraf@suse.de>
- * Eric Auger <eric.auger@linaro.org>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2 or later, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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/>.
- *
- */
-
-#include "qemu/osdep.h"
-#include "qapi/error.h"
-#include <libfdt.h>
-#include "qemu-common.h"
-#ifdef CONFIG_LINUX
-#include <linux/vfio.h>
-#endif
-#include "hw/arm/sysbus-fdt.h"
-#include "qemu/error-report.h"
-#include "sysemu/device_tree.h"
-#include "hw/platform-bus.h"
-#include "sysemu/sysemu.h"
-#include "hw/vfio/vfio-platform.h"
-#include "hw/vfio/vfio-calxeda-xgmac.h"
-#include "hw/vfio/vfio-amd-xgbe.h"
-#include "hw/arm/fdt.h"
-
-/*
- * internal struct that contains the information to create dynamic
- * sysbus device node
- */
-typedef struct PlatformBusFDTData {
- void *fdt; /* device tree handle */
- int irq_start; /* index of the first IRQ usable by platform bus devices */
- const char *pbus_node_name; /* name of the platform bus node */
- PlatformBusDevice *pbus;
-} PlatformBusFDTData;
-
-/*
- * struct used when calling the machine init done notifier
- * that constructs the fdt nodes of platform bus devices
- */
-typedef struct PlatformBusFDTNotifierParams {
- Notifier notifier;
- ARMPlatformBusFDTParams *fdt_params;
-} PlatformBusFDTNotifierParams;
-
-/* struct that associates a device type name and a node creation function */
-typedef struct NodeCreationPair {
- const char *typename;
- int (*add_fdt_node_fn)(SysBusDevice *sbdev, void *opaque);
-} NodeCreationPair;
-
-/* helpers */
-
-typedef struct HostProperty {
- const char *name;
- bool optional;
-} HostProperty;
-
-#ifdef CONFIG_LINUX
-
-/**
- * copy_properties_from_host
- *
- * copies properties listed in an array from host device tree to
- * guest device tree. If a non optional property is not found, the
- * function asserts. An optional property is ignored if not found
- * in the host device tree.
- * @props: array of HostProperty to copy
- * @nb_props: number of properties in the array
- * @host_dt: host device tree blob
- * @guest_dt: guest device tree blob
- * @node_path: host dt node path where the property is supposed to be
- found
- * @nodename: guest node name the properties should be added to
- */
-static void copy_properties_from_host(HostProperty *props, int nb_props,
- void *host_fdt, void *guest_fdt,
- char *node_path, char *nodename)
-{
- int i, prop_len;
- const void *r;
- Error *err = NULL;
-
- for (i = 0; i < nb_props; i++) {
- r = qemu_fdt_getprop(host_fdt, node_path,
- props[i].name,
- &prop_len,
- props[i].optional ? &err : &error_fatal);
- if (r) {
- qemu_fdt_setprop(guest_fdt, nodename,
- props[i].name, r, prop_len);
- } else {
- if (prop_len != -FDT_ERR_NOTFOUND) {
- /* optional property not returned although property exists */
- error_report_err(err);
- } else {
- error_free(err);
- }
- }
- }
-}
-
-/* clock properties whose values are copied/pasted from host */
-static HostProperty clock_copied_properties[] = {
- {"compatible", false},
- {"#clock-cells", false},
- {"clock-frequency", true},
- {"clock-output-names", true},
-};
-
-/**
- * fdt_build_clock_node
- *
- * Build a guest clock node, used as a dependency from a passthrough'ed
- * device. Most information are retrieved from the host clock node.
- * Also check the host clock is a fixed one.
- *
- * @host_fdt: host device tree blob from which info are retrieved
- * @guest_fdt: guest device tree blob where the clock node is added
- * @host_phandle: phandle of the clock in host device tree
- * @guest_phandle: phandle to assign to the guest node
- */
-static void fdt_build_clock_node(void *host_fdt, void *guest_fdt,
- uint32_t host_phandle,
- uint32_t guest_phandle)
-{
- char *node_path = NULL;
- char *nodename;
- const void *r;
- int ret, node_offset, prop_len, path_len = 16;
-
- node_offset = fdt_node_offset_by_phandle(host_fdt, host_phandle);
- if (node_offset <= 0) {
- error_setg(&error_fatal,
- "not able to locate clock handle %d in host device tree",
- host_phandle);
- }
- node_path = g_malloc(path_len);
- while ((ret = fdt_get_path(host_fdt, node_offset, node_path, path_len))
- == -FDT_ERR_NOSPACE) {
- path_len += 16;
- node_path = g_realloc(node_path, path_len);
- }
- if (ret < 0) {
- error_setg(&error_fatal,
- "not able to retrieve node path for clock handle %d",
- host_phandle);
- }
-
- r = qemu_fdt_getprop(host_fdt, node_path, "compatible", &prop_len,
- &error_fatal);
- if (strcmp(r, "fixed-clock")) {
- error_setg(&error_fatal,
- "clock handle %d is not a fixed clock", host_phandle);
- }
-
- nodename = strrchr(node_path, '/');
- qemu_fdt_add_subnode(guest_fdt, nodename);
-
- copy_properties_from_host(clock_copied_properties,
- ARRAY_SIZE(clock_copied_properties),
- host_fdt, guest_fdt,
- node_path, nodename);
-
- qemu_fdt_setprop_cell(guest_fdt, nodename, "phandle", guest_phandle);
-
- g_free(node_path);
-}
-
-/**
- * sysfs_to_dt_name: convert the name found in sysfs into the node name
- * for instance e0900000.xgmac is converted into xgmac@e0900000
- * @sysfs_name: directory name in sysfs
- *
- * returns the device tree name upon success or NULL in case the sysfs name
- * does not match the expected format
- */
-static char *sysfs_to_dt_name(const char *sysfs_name)
-{
- gchar **substrings = g_strsplit(sysfs_name, ".", 2);
- char *dt_name = NULL;
-
- if (!substrings || !substrings[0] || !substrings[1]) {
- goto out;
- }
- dt_name = g_strdup_printf("%s@%s", substrings[1], substrings[0]);
-out:
- g_strfreev(substrings);
- return dt_name;
-}
-
-/* Device Specific Code */
-
-/**
- * add_calxeda_midway_xgmac_fdt_node
- *
- * Generates a simple node with following properties:
- * compatible string, regs, interrupts, dma-coherent
- */
-static int add_calxeda_midway_xgmac_fdt_node(SysBusDevice *sbdev, void *opaque)
-{
- PlatformBusFDTData *data = opaque;
- PlatformBusDevice *pbus = data->pbus;
- void *fdt = data->fdt;
- const char *parent_node = data->pbus_node_name;
- int compat_str_len, i;
- char *nodename;
- uint32_t *irq_attr, *reg_attr;
- uint64_t mmio_base, irq_number;
- VFIOPlatformDevice *vdev = VFIO_PLATFORM_DEVICE(sbdev);
- VFIODevice *vbasedev = &vdev->vbasedev;
-
- mmio_base = platform_bus_get_mmio_addr(pbus, sbdev, 0);
- nodename = g_strdup_printf("%s/%s@%" PRIx64, parent_node,
- vbasedev->name, mmio_base);
- qemu_fdt_add_subnode(fdt, nodename);
-
- compat_str_len = strlen(vdev->compat) + 1;
- qemu_fdt_setprop(fdt, nodename, "compatible",
- vdev->compat, compat_str_len);
-
- qemu_fdt_setprop(fdt, nodename, "dma-coherent", "", 0);
-
- reg_attr = g_new(uint32_t, vbasedev->num_regions * 2);
- for (i = 0; i < vbasedev->num_regions; i++) {
- mmio_base = platform_bus_get_mmio_addr(pbus, sbdev, i);
- reg_attr[2 * i] = cpu_to_be32(mmio_base);
- reg_attr[2 * i + 1] = cpu_to_be32(
- memory_region_size(vdev->regions[i]->mem));
- }
- qemu_fdt_setprop(fdt, nodename, "reg", reg_attr,
- vbasedev->num_regions * 2 * sizeof(uint32_t));
-
- irq_attr = g_new(uint32_t, vbasedev->num_irqs * 3);
- for (i = 0; i < vbasedev->num_irqs; i++) {
- irq_number = platform_bus_get_irqn(pbus, sbdev , i)
- + data->irq_start;
- irq_attr[3 * i] = cpu_to_be32(GIC_FDT_IRQ_TYPE_SPI);
- irq_attr[3 * i + 1] = cpu_to_be32(irq_number);
- irq_attr[3 * i + 2] = cpu_to_be32(GIC_FDT_IRQ_FLAGS_LEVEL_HI);
- }
- qemu_fdt_setprop(fdt, nodename, "interrupts",
- irq_attr, vbasedev->num_irqs * 3 * sizeof(uint32_t));
- g_free(irq_attr);
- g_free(reg_attr);
- g_free(nodename);
- return 0;
-}
-
-/* AMD xgbe properties whose values are copied/pasted from host */
-static HostProperty amd_xgbe_copied_properties[] = {
- {"compatible", false},
- {"dma-coherent", true},
- {"amd,per-channel-interrupt", true},
- {"phy-mode", false},
- {"mac-address", true},
- {"amd,speed-set", false},
- {"amd,serdes-blwc", true},
- {"amd,serdes-cdr-rate", true},
- {"amd,serdes-pq-skew", true},
- {"amd,serdes-tx-amp", true},
- {"amd,serdes-dfe-tap-config", true},
- {"amd,serdes-dfe-tap-enable", true},
- {"clock-names", false},
-};
-
-/**
- * add_amd_xgbe_fdt_node
- *
- * Generates the combined xgbe/phy node following kernel >=4.2
- * binding documentation:
- * Documentation/devicetree/bindings/net/amd-xgbe.txt:
- * Also 2 clock nodes are created (dma and ptp)
- *
- * Asserts in case of error
- */
-static int add_amd_xgbe_fdt_node(SysBusDevice *sbdev, void *opaque)
-{
- PlatformBusFDTData *data = opaque;
- PlatformBusDevice *pbus = data->pbus;
- VFIOPlatformDevice *vdev = VFIO_PLATFORM_DEVICE(sbdev);
- VFIODevice *vbasedev = &vdev->vbasedev;
- VFIOINTp *intp;
- const char *parent_node = data->pbus_node_name;
- char **node_path, *nodename, *dt_name;
- void *guest_fdt = data->fdt, *host_fdt;
- const void *r;
- int i, prop_len;
- uint32_t *irq_attr, *reg_attr, *host_clock_phandles;
- uint64_t mmio_base, irq_number;
- uint32_t guest_clock_phandles[2];
-
- host_fdt = load_device_tree_from_sysfs();
-
- dt_name = sysfs_to_dt_name(vbasedev->name);
- if (!dt_name) {
- error_setg(&error_fatal, "%s incorrect sysfs device name %s",
- __func__, vbasedev->name);
- }
- node_path = qemu_fdt_node_path(host_fdt, dt_name, vdev->compat,
- &error_fatal);
- if (!node_path || !node_path[0]) {
- error_setg(&error_fatal, "%s unable to retrieve node path for %s/%s",
- __func__, dt_name, vdev->compat);
- }
-
- if (node_path[1]) {
- error_setg(&error_fatal, "%s more than one node matching %s/%s!",
- __func__, dt_name, vdev->compat);
- }
-
- g_free(dt_name);
-
- if (vbasedev->num_regions != 5) {
- error_setg(&error_fatal, "%s Does the host dt node combine XGBE/PHY?",
- __func__);
- }
-
- /* generate nodes for DMA_CLK and PTP_CLK */
- r = qemu_fdt_getprop(host_fdt, node_path[0], "clocks",
- &prop_len, &error_fatal);
- if (prop_len != 8) {
- error_setg(&error_fatal, "%s clocks property should contain 2 handles",
- __func__);
- }
- host_clock_phandles = (uint32_t *)r;
- guest_clock_phandles[0] = qemu_fdt_alloc_phandle(guest_fdt);
- guest_clock_phandles[1] = qemu_fdt_alloc_phandle(guest_fdt);
-
- /**
- * clock handles fetched from host dt are in be32 layout whereas
- * rest of the code uses cpu layout. Also guest clock handles are
- * in cpu layout.
- */
- fdt_build_clock_node(host_fdt, guest_fdt,
- be32_to_cpu(host_clock_phandles[0]),
- guest_clock_phandles[0]);
-
- fdt_build_clock_node(host_fdt, guest_fdt,
- be32_to_cpu(host_clock_phandles[1]),
- guest_clock_phandles[1]);
-
- /* combined XGBE/PHY node */
- mmio_base = platform_bus_get_mmio_addr(pbus, sbdev, 0);
- nodename = g_strdup_printf("%s/%s@%" PRIx64, parent_node,
- vbasedev->name, mmio_base);
- qemu_fdt_add_subnode(guest_fdt, nodename);
-
- copy_properties_from_host(amd_xgbe_copied_properties,
- ARRAY_SIZE(amd_xgbe_copied_properties),
- host_fdt, guest_fdt,
- node_path[0], nodename);
-
- qemu_fdt_setprop_cells(guest_fdt, nodename, "clocks",
- guest_clock_phandles[0],
- guest_clock_phandles[1]);
-
- reg_attr = g_new(uint32_t, vbasedev->num_regions * 2);
- for (i = 0; i < vbasedev->num_regions; i++) {
- mmio_base = platform_bus_get_mmio_addr(pbus, sbdev, i);
- reg_attr[2 * i] = cpu_to_be32(mmio_base);
- reg_attr[2 * i + 1] = cpu_to_be32(
- memory_region_size(vdev->regions[i]->mem));
- }
- qemu_fdt_setprop(guest_fdt, nodename, "reg", reg_attr,
- vbasedev->num_regions * 2 * sizeof(uint32_t));
-
- irq_attr = g_new(uint32_t, vbasedev->num_irqs * 3);
- for (i = 0; i < vbasedev->num_irqs; i++) {
- irq_number = platform_bus_get_irqn(pbus, sbdev , i)
- + data->irq_start;
- irq_attr[3 * i] = cpu_to_be32(GIC_FDT_IRQ_TYPE_SPI);
- irq_attr[3 * i + 1] = cpu_to_be32(irq_number);
- /*
- * General device interrupt and PCS auto-negotiation interrupts are
- * level-sensitive while the 4 per-channel interrupts are edge
- * sensitive
- */
- QLIST_FOREACH(intp, &vdev->intp_list, next) {
- if (intp->pin == i) {
- break;
- }
- }
- if (intp->flags & VFIO_IRQ_INFO_AUTOMASKED) {
- irq_attr[3 * i + 2] = cpu_to_be32(GIC_FDT_IRQ_FLAGS_LEVEL_HI);
- } else {
- irq_attr[3 * i + 2] = cpu_to_be32(GIC_FDT_IRQ_FLAGS_EDGE_LO_HI);
- }
- }
- qemu_fdt_setprop(guest_fdt, nodename, "interrupts",
- irq_attr, vbasedev->num_irqs * 3 * sizeof(uint32_t));
-
- g_free(host_fdt);
- g_strfreev(node_path);
- g_free(irq_attr);
- g_free(reg_attr);
- g_free(nodename);
- return 0;
-}
-
-#endif /* CONFIG_LINUX */
-
-/* list of supported dynamic sysbus devices */
-static const NodeCreationPair add_fdt_node_functions[] = {
-#ifdef CONFIG_LINUX
- {TYPE_VFIO_CALXEDA_XGMAC, add_calxeda_midway_xgmac_fdt_node},
- {TYPE_VFIO_AMD_XGBE, add_amd_xgbe_fdt_node},
-#endif
- {"", NULL}, /* last element */
-};
-
-/* Generic Code */
-
-/**
- * add_fdt_node - add the device tree node of a dynamic sysbus device
- *
- * @sbdev: handle to the sysbus device
- * @opaque: handle to the PlatformBusFDTData
- *
- * Checks the sysbus type belongs to the list of device types that
- * are dynamically instantiable and if so call the node creation
- * function.
- */
-static int add_fdt_node(SysBusDevice *sbdev, void *opaque)
-{
- int i, ret;
-
- for (i = 0; i < ARRAY_SIZE(add_fdt_node_functions); i++) {
- if (!strcmp(object_get_typename(OBJECT(sbdev)),
- add_fdt_node_functions[i].typename)) {
- ret = add_fdt_node_functions[i].add_fdt_node_fn(sbdev, opaque);
- assert(!ret);
- return 0;
- }
- }
- error_report("Device %s can not be dynamically instantiated",
- qdev_fw_name(DEVICE(sbdev)));
- exit(1);
-}
-
-/**
- * add_all_platform_bus_fdt_nodes - create all the platform bus nodes
- *
- * builds the parent platform bus node and all the nodes of dynamic
- * sysbus devices attached to it.
- */
-static void add_all_platform_bus_fdt_nodes(ARMPlatformBusFDTParams *fdt_params)
-{
- const char platcomp[] = "qemu,platform\0simple-bus";
- PlatformBusDevice *pbus;
- DeviceState *dev;
- gchar *node;
- uint64_t addr, size;
- int irq_start, dtb_size;
- struct arm_boot_info *info = fdt_params->binfo;
- const ARMPlatformBusSystemParams *params = fdt_params->system_params;
- const char *intc = fdt_params->intc;
- void *fdt = info->get_dtb(info, &dtb_size);
-
- /*
- * If the user provided a dtb, we assume the dynamic sysbus nodes
- * already are integrated there. This corresponds to a use case where
- * the dynamic sysbus nodes are complex and their generation is not yet
- * supported. In that case the user can take charge of the guest dt
- * while qemu takes charge of the qom stuff.
- */
- if (info->dtb_filename) {
- return;
- }
-
- assert(fdt);
-
- node = g_strdup_printf("/platform@%"PRIx64, params->platform_bus_base);
- addr = params->platform_bus_base;
- size = params->platform_bus_size;
- irq_start = params->platform_bus_first_irq;
-
- /* Create a /platform node that we can put all devices into */
- qemu_fdt_add_subnode(fdt, node);
- qemu_fdt_setprop(fdt, node, "compatible", platcomp, sizeof(platcomp));
-
- /* Our platform bus region is less than 32bits, so 1 cell is enough for
- * address and size
- */
- qemu_fdt_setprop_cells(fdt, node, "#size-cells", 1);
- qemu_fdt_setprop_cells(fdt, node, "#address-cells", 1);
- qemu_fdt_setprop_cells(fdt, node, "ranges", 0, addr >> 32, addr, size);
-
- qemu_fdt_setprop_phandle(fdt, node, "interrupt-parent", intc);
-
- dev = qdev_find_recursive(sysbus_get_default(), TYPE_PLATFORM_BUS_DEVICE);
- pbus = PLATFORM_BUS_DEVICE(dev);
-
- /* We can only create dt nodes for dynamic devices when they're ready */
- assert(pbus->done_gathering);
-
- PlatformBusFDTData data = {
- .fdt = fdt,
- .irq_start = irq_start,
- .pbus_node_name = node,
- .pbus = pbus,
- };
-
- /* Loop through all dynamic sysbus devices and create their node */
- foreach_dynamic_sysbus_device(add_fdt_node, &data);
-
- g_free(node);
-}
-
-static void platform_bus_fdt_notify(Notifier *notifier, void *data)
-{
- PlatformBusFDTNotifierParams *p = DO_UPCAST(PlatformBusFDTNotifierParams,
- notifier, notifier);
-
- add_all_platform_bus_fdt_nodes(p->fdt_params);
- g_free(p->fdt_params);
- g_free(p);
-}
-
-void arm_register_platform_bus_fdt_creator(ARMPlatformBusFDTParams *fdt_params)
-{
- PlatformBusFDTNotifierParams *p = g_new(PlatformBusFDTNotifierParams, 1);
-
- p->fdt_params = fdt_params;
- p->notifier.notify = platform_bus_fdt_notify;
- qemu_add_machine_init_done_notifier(&p->notifier);
-}
diff --git a/qemu/hw/arm/tosa.c b/qemu/hw/arm/tosa.c
deleted file mode 100644
index 4e9494f94..000000000
--- a/qemu/hw/arm/tosa.c
+++ /dev/null
@@ -1,303 +0,0 @@
-/* vim:set shiftwidth=4 ts=4 et: */
-/*
- * PXA255 Sharp Zaurus SL-6000 PDA platform
- *
- * Copyright (c) 2008 Dmitry Baryshkov
- *
- * Code based on spitz platform by Andrzej Zaborowski <balrog@zabor.org>
- * This code is licensed under the GNU GPL v2.
- *
- * Contributions after 2012-01-13 are licensed under the terms of the
- * GNU GPL, version 2 or (at your option) any later version.
- */
-
-#include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "hw/hw.h"
-#include "hw/arm/pxa.h"
-#include "hw/arm/arm.h"
-#include "hw/devices.h"
-#include "hw/arm/sharpsl.h"
-#include "hw/pcmcia.h"
-#include "hw/boards.h"
-#include "hw/i2c/i2c.h"
-#include "hw/ssi/ssi.h"
-#include "sysemu/block-backend.h"
-#include "hw/sysbus.h"
-#include "exec/address-spaces.h"
-
-#define TOSA_RAM 0x04000000
-#define TOSA_ROM 0x00800000
-
-#define TOSA_GPIO_USB_IN (5)
-#define TOSA_GPIO_nSD_DETECT (9)
-#define TOSA_GPIO_ON_RESET (19)
-#define TOSA_GPIO_CF_IRQ (21) /* CF slot0 Ready */
-#define TOSA_GPIO_CF_CD (13)
-#define TOSA_GPIO_TC6393XB_INT (15)
-#define TOSA_GPIO_JC_CF_IRQ (36) /* CF slot1 Ready */
-
-#define TOSA_SCOOP_GPIO_BASE 1
-#define TOSA_GPIO_IR_POWERDWN (TOSA_SCOOP_GPIO_BASE + 2)
-#define TOSA_GPIO_SD_WP (TOSA_SCOOP_GPIO_BASE + 3)
-#define TOSA_GPIO_PWR_ON (TOSA_SCOOP_GPIO_BASE + 4)
-
-#define TOSA_SCOOP_JC_GPIO_BASE 1
-#define TOSA_GPIO_BT_LED (TOSA_SCOOP_JC_GPIO_BASE + 0)
-#define TOSA_GPIO_NOTE_LED (TOSA_SCOOP_JC_GPIO_BASE + 1)
-#define TOSA_GPIO_CHRG_ERR_LED (TOSA_SCOOP_JC_GPIO_BASE + 2)
-#define TOSA_GPIO_TC6393XB_L3V_ON (TOSA_SCOOP_JC_GPIO_BASE + 5)
-#define TOSA_GPIO_WLAN_LED (TOSA_SCOOP_JC_GPIO_BASE + 7)
-
-#define DAC_BASE 0x4e
-#define DAC_CH1 0
-#define DAC_CH2 1
-
-static void tosa_microdrive_attach(PXA2xxState *cpu)
-{
- PCMCIACardState *md;
- DriveInfo *dinfo;
-
- dinfo = drive_get(IF_IDE, 0, 0);
- if (!dinfo || dinfo->media_cd)
- return;
- md = dscm1xxxx_init(dinfo);
- pxa2xx_pcmcia_attach(cpu->pcmcia[0], md);
-}
-
-static void tosa_out_switch(void *opaque, int line, int level)
-{
- switch (line) {
- case 0:
- fprintf(stderr, "blue LED %s.\n", level ? "on" : "off");
- break;
- case 1:
- fprintf(stderr, "green LED %s.\n", level ? "on" : "off");
- break;
- case 2:
- fprintf(stderr, "amber LED %s.\n", level ? "on" : "off");
- break;
- case 3:
- fprintf(stderr, "wlan LED %s.\n", level ? "on" : "off");
- break;
- default:
- fprintf(stderr, "Uhandled out event: %d = %d\n", line, level);
- break;
- }
-}
-
-
-static void tosa_gpio_setup(PXA2xxState *cpu,
- DeviceState *scp0,
- DeviceState *scp1,
- TC6393xbState *tmio)
-{
- qemu_irq *outsignals = qemu_allocate_irqs(tosa_out_switch, cpu, 4);
- /* MMC/SD host */
- pxa2xx_mmci_handlers(cpu->mmc,
- qdev_get_gpio_in(scp0, TOSA_GPIO_SD_WP),
- qemu_irq_invert(qdev_get_gpio_in(cpu->gpio, TOSA_GPIO_nSD_DETECT)));
-
- /* Handle reset */
- qdev_connect_gpio_out(cpu->gpio, TOSA_GPIO_ON_RESET, cpu->reset);
-
- /* PCMCIA signals: card's IRQ and Card-Detect */
- pxa2xx_pcmcia_set_irq_cb(cpu->pcmcia[0],
- qdev_get_gpio_in(cpu->gpio, TOSA_GPIO_CF_IRQ),
- qdev_get_gpio_in(cpu->gpio, TOSA_GPIO_CF_CD));
-
- pxa2xx_pcmcia_set_irq_cb(cpu->pcmcia[1],
- qdev_get_gpio_in(cpu->gpio, TOSA_GPIO_JC_CF_IRQ),
- NULL);
-
- qdev_connect_gpio_out(scp1, TOSA_GPIO_BT_LED, outsignals[0]);
- qdev_connect_gpio_out(scp1, TOSA_GPIO_NOTE_LED, outsignals[1]);
- qdev_connect_gpio_out(scp1, TOSA_GPIO_CHRG_ERR_LED, outsignals[2]);
- qdev_connect_gpio_out(scp1, TOSA_GPIO_WLAN_LED, outsignals[3]);
-
- qdev_connect_gpio_out(scp1, TOSA_GPIO_TC6393XB_L3V_ON, tc6393xb_l3v_get(tmio));
-
- /* UDC Vbus */
- qemu_irq_raise(qdev_get_gpio_in(cpu->gpio, TOSA_GPIO_USB_IN));
-}
-
-static uint32_t tosa_ssp_tansfer(SSISlave *dev, uint32_t value)
-{
- fprintf(stderr, "TG: %d %02x\n", value >> 5, value & 0x1f);
- return 0;
-}
-
-static int tosa_ssp_init(SSISlave *dev)
-{
- /* Nothing to do. */
- return 0;
-}
-
-#define TYPE_TOSA_DAC "tosa_dac"
-#define TOSA_DAC(obj) OBJECT_CHECK(TosaDACState, (obj), TYPE_TOSA_DAC)
-
-typedef struct {
- I2CSlave parent_obj;
-
- int len;
- char buf[3];
-} TosaDACState;
-
-static int tosa_dac_send(I2CSlave *i2c, uint8_t data)
-{
- TosaDACState *s = TOSA_DAC(i2c);
-
- s->buf[s->len] = data;
- if (s->len ++ > 2) {
-#ifdef VERBOSE
- fprintf(stderr, "%s: message too long (%i bytes)\n", __FUNCTION__, s->len);
-#endif
- return 1;
- }
-
- if (s->len == 2) {
- fprintf(stderr, "dac: channel %d value 0x%02x\n",
- s->buf[0], s->buf[1]);
- }
-
- return 0;
-}
-
-static void tosa_dac_event(I2CSlave *i2c, enum i2c_event event)
-{
- TosaDACState *s = TOSA_DAC(i2c);
-
- s->len = 0;
- switch (event) {
- case I2C_START_SEND:
- break;
- case I2C_START_RECV:
- printf("%s: recv not supported!!!\n", __FUNCTION__);
- break;
- case I2C_FINISH:
-#ifdef VERBOSE
- if (s->len < 2)
- printf("%s: message too short (%i bytes)\n", __FUNCTION__, s->len);
- if (s->len > 2)
- printf("%s: message too long\n", __FUNCTION__);
-#endif
- break;
- default:
- break;
- }
-}
-
-static int tosa_dac_recv(I2CSlave *s)
-{
- printf("%s: recv not supported!!!\n", __FUNCTION__);
- return -1;
-}
-
-static int tosa_dac_init(I2CSlave *i2c)
-{
- /* Nothing to do. */
- return 0;
-}
-
-static void tosa_tg_init(PXA2xxState *cpu)
-{
- I2CBus *bus = pxa2xx_i2c_bus(cpu->i2c[0]);
- i2c_create_slave(bus, TYPE_TOSA_DAC, DAC_BASE);
- ssi_create_slave(cpu->ssp[1], "tosa-ssp");
-}
-
-
-static struct arm_boot_info tosa_binfo = {
- .loader_start = PXA2XX_SDRAM_BASE,
- .ram_size = 0x04000000,
-};
-
-static void tosa_init(MachineState *machine)
-{
- const char *cpu_model = machine->cpu_model;
- const char *kernel_filename = machine->kernel_filename;
- const char *kernel_cmdline = machine->kernel_cmdline;
- const char *initrd_filename = machine->initrd_filename;
- MemoryRegion *address_space_mem = get_system_memory();
- MemoryRegion *rom = g_new(MemoryRegion, 1);
- PXA2xxState *mpu;
- TC6393xbState *tmio;
- DeviceState *scp0, *scp1;
-
- if (!cpu_model)
- cpu_model = "pxa255";
-
- mpu = pxa255_init(address_space_mem, tosa_binfo.ram_size);
-
- memory_region_init_ram(rom, NULL, "tosa.rom", TOSA_ROM, &error_fatal);
- vmstate_register_ram_global(rom);
- memory_region_set_readonly(rom, true);
- memory_region_add_subregion(address_space_mem, 0, rom);
-
- tmio = tc6393xb_init(address_space_mem, 0x10000000,
- qdev_get_gpio_in(mpu->gpio, TOSA_GPIO_TC6393XB_INT));
-
- scp0 = sysbus_create_simple("scoop", 0x08800000, NULL);
- scp1 = sysbus_create_simple("scoop", 0x14800040, NULL);
-
- tosa_gpio_setup(mpu, scp0, scp1, tmio);
-
- tosa_microdrive_attach(mpu);
-
- tosa_tg_init(mpu);
-
- tosa_binfo.kernel_filename = kernel_filename;
- tosa_binfo.kernel_cmdline = kernel_cmdline;
- tosa_binfo.initrd_filename = initrd_filename;
- tosa_binfo.board_id = 0x208;
- arm_load_kernel(mpu->cpu, &tosa_binfo);
- sl_bootparam_write(SL_PXA_PARAM_BASE);
-}
-
-static void tosapda_machine_init(MachineClass *mc)
-{
- mc->desc = "Sharp SL-6000 (Tosa) PDA (PXA255)";
- mc->init = tosa_init;
-}
-
-DEFINE_MACHINE("tosa", tosapda_machine_init)
-
-static void tosa_dac_class_init(ObjectClass *klass, void *data)
-{
- I2CSlaveClass *k = I2C_SLAVE_CLASS(klass);
-
- k->init = tosa_dac_init;
- k->event = tosa_dac_event;
- k->recv = tosa_dac_recv;
- k->send = tosa_dac_send;
-}
-
-static const TypeInfo tosa_dac_info = {
- .name = TYPE_TOSA_DAC,
- .parent = TYPE_I2C_SLAVE,
- .instance_size = sizeof(TosaDACState),
- .class_init = tosa_dac_class_init,
-};
-
-static void tosa_ssp_class_init(ObjectClass *klass, void *data)
-{
- SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
-
- k->init = tosa_ssp_init;
- k->transfer = tosa_ssp_tansfer;
-}
-
-static const TypeInfo tosa_ssp_info = {
- .name = "tosa-ssp",
- .parent = TYPE_SSI_SLAVE,
- .instance_size = sizeof(SSISlave),
- .class_init = tosa_ssp_class_init,
-};
-
-static void tosa_register_types(void)
-{
- type_register_static(&tosa_dac_info);
- type_register_static(&tosa_ssp_info);
-}
-
-type_init(tosa_register_types)
diff --git a/qemu/hw/arm/versatilepb.c b/qemu/hw/arm/versatilepb.c
deleted file mode 100644
index e5a80c2d2..000000000
--- a/qemu/hw/arm/versatilepb.c
+++ /dev/null
@@ -1,448 +0,0 @@
-/*
- * ARM Versatile Platform/Application Baseboard System emulation.
- *
- * Copyright (c) 2005-2007 CodeSourcery.
- * Written by Paul Brook
- *
- * This code is licensed under the GPL.
- */
-
-#include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "qemu-common.h"
-#include "cpu.h"
-#include "hw/sysbus.h"
-#include "hw/arm/arm.h"
-#include "hw/devices.h"
-#include "net/net.h"
-#include "sysemu/sysemu.h"
-#include "hw/pci/pci.h"
-#include "hw/i2c/i2c.h"
-#include "hw/boards.h"
-#include "sysemu/block-backend.h"
-#include "exec/address-spaces.h"
-#include "hw/block/flash.h"
-#include "qemu/error-report.h"
-
-#define VERSATILE_FLASH_ADDR 0x34000000
-#define VERSATILE_FLASH_SIZE (64 * 1024 * 1024)
-#define VERSATILE_FLASH_SECT_SIZE (256 * 1024)
-
-/* Primary interrupt controller. */
-
-#define TYPE_VERSATILE_PB_SIC "versatilepb_sic"
-#define VERSATILE_PB_SIC(obj) \
- OBJECT_CHECK(vpb_sic_state, (obj), TYPE_VERSATILE_PB_SIC)
-
-typedef struct vpb_sic_state {
- SysBusDevice parent_obj;
-
- MemoryRegion iomem;
- uint32_t level;
- uint32_t mask;
- uint32_t pic_enable;
- qemu_irq parent[32];
- int irq;
-} vpb_sic_state;
-
-static const VMStateDescription vmstate_vpb_sic = {
- .name = "versatilepb_sic",
- .version_id = 1,
- .minimum_version_id = 1,
- .fields = (VMStateField[]) {
- VMSTATE_UINT32(level, vpb_sic_state),
- VMSTATE_UINT32(mask, vpb_sic_state),
- VMSTATE_UINT32(pic_enable, vpb_sic_state),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static void vpb_sic_update(vpb_sic_state *s)
-{
- uint32_t flags;
-
- flags = s->level & s->mask;
- qemu_set_irq(s->parent[s->irq], flags != 0);
-}
-
-static void vpb_sic_update_pic(vpb_sic_state *s)
-{
- int i;
- uint32_t mask;
-
- for (i = 21; i <= 30; i++) {
- mask = 1u << i;
- if (!(s->pic_enable & mask))
- continue;
- qemu_set_irq(s->parent[i], (s->level & mask) != 0);
- }
-}
-
-static void vpb_sic_set_irq(void *opaque, int irq, int level)
-{
- vpb_sic_state *s = (vpb_sic_state *)opaque;
- if (level)
- s->level |= 1u << irq;
- else
- s->level &= ~(1u << irq);
- if (s->pic_enable & (1u << irq))
- qemu_set_irq(s->parent[irq], level);
- vpb_sic_update(s);
-}
-
-static uint64_t vpb_sic_read(void *opaque, hwaddr offset,
- unsigned size)
-{
- vpb_sic_state *s = (vpb_sic_state *)opaque;
-
- switch (offset >> 2) {
- case 0: /* STATUS */
- return s->level & s->mask;
- case 1: /* RAWSTAT */
- return s->level;
- case 2: /* ENABLE */
- return s->mask;
- case 4: /* SOFTINT */
- return s->level & 1;
- case 8: /* PICENABLE */
- return s->pic_enable;
- default:
- printf ("vpb_sic_read: Bad register offset 0x%x\n", (int)offset);
- return 0;
- }
-}
-
-static void vpb_sic_write(void *opaque, hwaddr offset,
- uint64_t value, unsigned size)
-{
- vpb_sic_state *s = (vpb_sic_state *)opaque;
-
- switch (offset >> 2) {
- case 2: /* ENSET */
- s->mask |= value;
- break;
- case 3: /* ENCLR */
- s->mask &= ~value;
- break;
- case 4: /* SOFTINTSET */
- if (value)
- s->mask |= 1;
- break;
- case 5: /* SOFTINTCLR */
- if (value)
- s->mask &= ~1u;
- break;
- case 8: /* PICENSET */
- s->pic_enable |= (value & 0x7fe00000);
- vpb_sic_update_pic(s);
- break;
- case 9: /* PICENCLR */
- s->pic_enable &= ~value;
- vpb_sic_update_pic(s);
- break;
- default:
- printf ("vpb_sic_write: Bad register offset 0x%x\n", (int)offset);
- return;
- }
- vpb_sic_update(s);
-}
-
-static const MemoryRegionOps vpb_sic_ops = {
- .read = vpb_sic_read,
- .write = vpb_sic_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static int vpb_sic_init(SysBusDevice *sbd)
-{
- DeviceState *dev = DEVICE(sbd);
- vpb_sic_state *s = VERSATILE_PB_SIC(dev);
- int i;
-
- qdev_init_gpio_in(dev, vpb_sic_set_irq, 32);
- for (i = 0; i < 32; i++) {
- sysbus_init_irq(sbd, &s->parent[i]);
- }
- s->irq = 31;
- memory_region_init_io(&s->iomem, OBJECT(s), &vpb_sic_ops, s,
- "vpb-sic", 0x1000);
- sysbus_init_mmio(sbd, &s->iomem);
- return 0;
-}
-
-/* Board init. */
-
-/* The AB and PB boards both use the same core, just with different
- peripherals and expansion busses. For now we emulate a subset of the
- PB peripherals and just change the board ID. */
-
-static struct arm_boot_info versatile_binfo;
-
-static void versatile_init(MachineState *machine, int board_id)
-{
- ObjectClass *cpu_oc;
- Object *cpuobj;
- ARMCPU *cpu;
- MemoryRegion *sysmem = get_system_memory();
- MemoryRegion *ram = g_new(MemoryRegion, 1);
- qemu_irq pic[32];
- qemu_irq sic[32];
- DeviceState *dev, *sysctl;
- SysBusDevice *busdev;
- DeviceState *pl041;
- PCIBus *pci_bus;
- NICInfo *nd;
- I2CBus *i2c;
- int n;
- int done_smc = 0;
- DriveInfo *dinfo;
-
- if (!machine->cpu_model) {
- machine->cpu_model = "arm926";
- }
-
- cpu_oc = cpu_class_by_name(TYPE_ARM_CPU, machine->cpu_model);
- if (!cpu_oc) {
- fprintf(stderr, "Unable to find CPU definition\n");
- exit(1);
- }
-
- cpuobj = object_new(object_class_get_name(cpu_oc));
-
- /* By default ARM1176 CPUs have EL3 enabled. This board does not
- * currently support EL3 so the CPU EL3 property is disabled before
- * realization.
- */
- if (object_property_find(cpuobj, "has_el3", NULL)) {
- object_property_set_bool(cpuobj, false, "has_el3", &error_fatal);
- }
-
- object_property_set_bool(cpuobj, true, "realized", &error_fatal);
-
- cpu = ARM_CPU(cpuobj);
-
- memory_region_allocate_system_memory(ram, NULL, "versatile.ram",
- machine->ram_size);
- /* ??? RAM should repeat to fill physical memory space. */
- /* SDRAM at address zero. */
- memory_region_add_subregion(sysmem, 0, ram);
-
- sysctl = qdev_create(NULL, "realview_sysctl");
- qdev_prop_set_uint32(sysctl, "sys_id", 0x41007004);
- qdev_prop_set_uint32(sysctl, "proc_id", 0x02000000);
- qdev_init_nofail(sysctl);
- sysbus_mmio_map(SYS_BUS_DEVICE(sysctl), 0, 0x10000000);
-
- dev = sysbus_create_varargs("pl190", 0x10140000,
- qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ),
- qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_FIQ),
- NULL);
- for (n = 0; n < 32; n++) {
- pic[n] = qdev_get_gpio_in(dev, n);
- }
- dev = sysbus_create_simple(TYPE_VERSATILE_PB_SIC, 0x10003000, NULL);
- for (n = 0; n < 32; n++) {
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), n, pic[n]);
- sic[n] = qdev_get_gpio_in(dev, n);
- }
-
- sysbus_create_simple("pl050_keyboard", 0x10006000, sic[3]);
- sysbus_create_simple("pl050_mouse", 0x10007000, sic[4]);
-
- dev = qdev_create(NULL, "versatile_pci");
- busdev = SYS_BUS_DEVICE(dev);
- qdev_init_nofail(dev);
- sysbus_mmio_map(busdev, 0, 0x10001000); /* PCI controller regs */
- sysbus_mmio_map(busdev, 1, 0x41000000); /* PCI self-config */
- sysbus_mmio_map(busdev, 2, 0x42000000); /* PCI config */
- sysbus_mmio_map(busdev, 3, 0x43000000); /* PCI I/O */
- sysbus_mmio_map(busdev, 4, 0x44000000); /* PCI memory window 1 */
- sysbus_mmio_map(busdev, 5, 0x50000000); /* PCI memory window 2 */
- sysbus_mmio_map(busdev, 6, 0x60000000); /* PCI memory window 3 */
- sysbus_connect_irq(busdev, 0, sic[27]);
- sysbus_connect_irq(busdev, 1, sic[28]);
- sysbus_connect_irq(busdev, 2, sic[29]);
- sysbus_connect_irq(busdev, 3, sic[30]);
- pci_bus = (PCIBus *)qdev_get_child_bus(dev, "pci");
-
- for(n = 0; n < nb_nics; n++) {
- nd = &nd_table[n];
-
- if (!done_smc && (!nd->model || strcmp(nd->model, "smc91c111") == 0)) {
- smc91c111_init(nd, 0x10010000, sic[25]);
- done_smc = 1;
- } else {
- pci_nic_init_nofail(nd, pci_bus, "rtl8139", NULL);
- }
- }
- if (usb_enabled()) {
- pci_create_simple(pci_bus, -1, "pci-ohci");
- }
- n = drive_get_max_bus(IF_SCSI);
- while (n >= 0) {
- pci_create_simple(pci_bus, -1, "lsi53c895a");
- n--;
- }
-
- sysbus_create_simple("pl011", 0x101f1000, pic[12]);
- sysbus_create_simple("pl011", 0x101f2000, pic[13]);
- sysbus_create_simple("pl011", 0x101f3000, pic[14]);
- sysbus_create_simple("pl011", 0x10009000, sic[6]);
-
- sysbus_create_simple("pl080", 0x10130000, pic[17]);
- sysbus_create_simple("sp804", 0x101e2000, pic[4]);
- sysbus_create_simple("sp804", 0x101e3000, pic[5]);
-
- sysbus_create_simple("pl061", 0x101e4000, pic[6]);
- sysbus_create_simple("pl061", 0x101e5000, pic[7]);
- sysbus_create_simple("pl061", 0x101e6000, pic[8]);
- sysbus_create_simple("pl061", 0x101e7000, pic[9]);
-
- /* The versatile/PB actually has a modified Color LCD controller
- that includes hardware cursor support from the PL111. */
- dev = sysbus_create_simple("pl110_versatile", 0x10120000, pic[16]);
- /* Wire up the mux control signals from the SYS_CLCD register */
- qdev_connect_gpio_out(sysctl, 0, qdev_get_gpio_in(dev, 0));
-
- sysbus_create_varargs("pl181", 0x10005000, sic[22], sic[1], NULL);
- sysbus_create_varargs("pl181", 0x1000b000, sic[23], sic[2], NULL);
-
- /* Add PL031 Real Time Clock. */
- sysbus_create_simple("pl031", 0x101e8000, pic[10]);
-
- dev = sysbus_create_simple("versatile_i2c", 0x10002000, NULL);
- i2c = (I2CBus *)qdev_get_child_bus(dev, "i2c");
- i2c_create_slave(i2c, "ds1338", 0x68);
-
- /* Add PL041 AACI Interface to the LM4549 codec */
- pl041 = qdev_create(NULL, "pl041");
- qdev_prop_set_uint32(pl041, "nc_fifo_depth", 512);
- qdev_init_nofail(pl041);
- sysbus_mmio_map(SYS_BUS_DEVICE(pl041), 0, 0x10004000);
- sysbus_connect_irq(SYS_BUS_DEVICE(pl041), 0, sic[24]);
-
- /* Memory map for Versatile/PB: */
- /* 0x10000000 System registers. */
- /* 0x10001000 PCI controller config registers. */
- /* 0x10002000 Serial bus interface. */
- /* 0x10003000 Secondary interrupt controller. */
- /* 0x10004000 AACI (audio). */
- /* 0x10005000 MMCI0. */
- /* 0x10006000 KMI0 (keyboard). */
- /* 0x10007000 KMI1 (mouse). */
- /* 0x10008000 Character LCD Interface. */
- /* 0x10009000 UART3. */
- /* 0x1000a000 Smart card 1. */
- /* 0x1000b000 MMCI1. */
- /* 0x10010000 Ethernet. */
- /* 0x10020000 USB. */
- /* 0x10100000 SSMC. */
- /* 0x10110000 MPMC. */
- /* 0x10120000 CLCD Controller. */
- /* 0x10130000 DMA Controller. */
- /* 0x10140000 Vectored interrupt controller. */
- /* 0x101d0000 AHB Monitor Interface. */
- /* 0x101e0000 System Controller. */
- /* 0x101e1000 Watchdog Interface. */
- /* 0x101e2000 Timer 0/1. */
- /* 0x101e3000 Timer 2/3. */
- /* 0x101e4000 GPIO port 0. */
- /* 0x101e5000 GPIO port 1. */
- /* 0x101e6000 GPIO port 2. */
- /* 0x101e7000 GPIO port 3. */
- /* 0x101e8000 RTC. */
- /* 0x101f0000 Smart card 0. */
- /* 0x101f1000 UART0. */
- /* 0x101f2000 UART1. */
- /* 0x101f3000 UART2. */
- /* 0x101f4000 SSPI. */
- /* 0x34000000 NOR Flash */
-
- dinfo = drive_get(IF_PFLASH, 0, 0);
- if (!pflash_cfi01_register(VERSATILE_FLASH_ADDR, NULL, "versatile.flash",
- VERSATILE_FLASH_SIZE,
- dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
- VERSATILE_FLASH_SECT_SIZE,
- VERSATILE_FLASH_SIZE / VERSATILE_FLASH_SECT_SIZE,
- 4, 0x0089, 0x0018, 0x0000, 0x0, 0)) {
- fprintf(stderr, "qemu: Error registering flash memory.\n");
- }
-
- versatile_binfo.ram_size = machine->ram_size;
- versatile_binfo.kernel_filename = machine->kernel_filename;
- versatile_binfo.kernel_cmdline = machine->kernel_cmdline;
- versatile_binfo.initrd_filename = machine->initrd_filename;
- versatile_binfo.board_id = board_id;
- arm_load_kernel(cpu, &versatile_binfo);
-}
-
-static void vpb_init(MachineState *machine)
-{
- versatile_init(machine, 0x183);
-}
-
-static void vab_init(MachineState *machine)
-{
- versatile_init(machine, 0x25e);
-}
-
-static void versatilepb_class_init(ObjectClass *oc, void *data)
-{
- MachineClass *mc = MACHINE_CLASS(oc);
-
- mc->desc = "ARM Versatile/PB (ARM926EJ-S)";
- mc->init = vpb_init;
- mc->block_default_type = IF_SCSI;
-}
-
-static const TypeInfo versatilepb_type = {
- .name = MACHINE_TYPE_NAME("versatilepb"),
- .parent = TYPE_MACHINE,
- .class_init = versatilepb_class_init,
-};
-
-static void versatileab_class_init(ObjectClass *oc, void *data)
-{
- MachineClass *mc = MACHINE_CLASS(oc);
-
- mc->desc = "ARM Versatile/AB (ARM926EJ-S)";
- mc->init = vab_init;
- mc->block_default_type = IF_SCSI;
-}
-
-static const TypeInfo versatileab_type = {
- .name = MACHINE_TYPE_NAME("versatileab"),
- .parent = TYPE_MACHINE,
- .class_init = versatileab_class_init,
-};
-
-static void versatile_machine_init(void)
-{
- type_register_static(&versatilepb_type);
- type_register_static(&versatileab_type);
-}
-
-type_init(versatile_machine_init)
-
-static void vpb_sic_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
-
- k->init = vpb_sic_init;
- dc->vmsd = &vmstate_vpb_sic;
-}
-
-static const TypeInfo vpb_sic_info = {
- .name = TYPE_VERSATILE_PB_SIC,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(vpb_sic_state),
- .class_init = vpb_sic_class_init,
-};
-
-static void versatilepb_register_types(void)
-{
- type_register_static(&vpb_sic_info);
-}
-
-type_init(versatilepb_register_types)
diff --git a/qemu/hw/arm/vexpress.c b/qemu/hw/arm/vexpress.c
deleted file mode 100644
index 70b3e701e..000000000
--- a/qemu/hw/arm/vexpress.c
+++ /dev/null
@@ -1,806 +0,0 @@
-/*
- * ARM Versatile Express emulation.
- *
- * Copyright (c) 2010 - 2011 B Labs Ltd.
- * Copyright (c) 2011 Linaro Limited
- * Written by Bahadir Balban, Amit Mahajan, Peter Maydell
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- * Contributions after 2012-01-13 are licensed under the terms of the
- * GNU GPL, version 2 or (at your option) any later version.
- */
-
-#include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "qemu-common.h"
-#include "cpu.h"
-#include "hw/sysbus.h"
-#include "hw/arm/arm.h"
-#include "hw/arm/primecell.h"
-#include "hw/devices.h"
-#include "net/net.h"
-#include "sysemu/sysemu.h"
-#include "hw/boards.h"
-#include "hw/loader.h"
-#include "exec/address-spaces.h"
-#include "sysemu/block-backend.h"
-#include "hw/block/flash.h"
-#include "sysemu/device_tree.h"
-#include "qemu/error-report.h"
-#include <libfdt.h>
-
-#define VEXPRESS_BOARD_ID 0x8e0
-#define VEXPRESS_FLASH_SIZE (64 * 1024 * 1024)
-#define VEXPRESS_FLASH_SECT_SIZE (256 * 1024)
-
-/* Number of virtio transports to create (0..8; limited by
- * number of available IRQ lines).
- */
-#define NUM_VIRTIO_TRANSPORTS 4
-
-/* Address maps for peripherals:
- * the Versatile Express motherboard has two possible maps,
- * the "legacy" one (used for A9) and the "Cortex-A Series"
- * map (used for newer cores).
- * Individual daughterboards can also have different maps for
- * their peripherals.
- */
-
-enum {
- VE_SYSREGS,
- VE_SP810,
- VE_SERIALPCI,
- VE_PL041,
- VE_MMCI,
- VE_KMI0,
- VE_KMI1,
- VE_UART0,
- VE_UART1,
- VE_UART2,
- VE_UART3,
- VE_WDT,
- VE_TIMER01,
- VE_TIMER23,
- VE_SERIALDVI,
- VE_RTC,
- VE_COMPACTFLASH,
- VE_CLCD,
- VE_NORFLASH0,
- VE_NORFLASH1,
- VE_NORFLASHALIAS,
- VE_SRAM,
- VE_VIDEORAM,
- VE_ETHERNET,
- VE_USB,
- VE_DAPROM,
- VE_VIRTIO,
-};
-
-static hwaddr motherboard_legacy_map[] = {
- [VE_NORFLASHALIAS] = 0,
- /* CS7: 0x10000000 .. 0x10020000 */
- [VE_SYSREGS] = 0x10000000,
- [VE_SP810] = 0x10001000,
- [VE_SERIALPCI] = 0x10002000,
- [VE_PL041] = 0x10004000,
- [VE_MMCI] = 0x10005000,
- [VE_KMI0] = 0x10006000,
- [VE_KMI1] = 0x10007000,
- [VE_UART0] = 0x10009000,
- [VE_UART1] = 0x1000a000,
- [VE_UART2] = 0x1000b000,
- [VE_UART3] = 0x1000c000,
- [VE_WDT] = 0x1000f000,
- [VE_TIMER01] = 0x10011000,
- [VE_TIMER23] = 0x10012000,
- [VE_VIRTIO] = 0x10013000,
- [VE_SERIALDVI] = 0x10016000,
- [VE_RTC] = 0x10017000,
- [VE_COMPACTFLASH] = 0x1001a000,
- [VE_CLCD] = 0x1001f000,
- /* CS0: 0x40000000 .. 0x44000000 */
- [VE_NORFLASH0] = 0x40000000,
- /* CS1: 0x44000000 .. 0x48000000 */
- [VE_NORFLASH1] = 0x44000000,
- /* CS2: 0x48000000 .. 0x4a000000 */
- [VE_SRAM] = 0x48000000,
- /* CS3: 0x4c000000 .. 0x50000000 */
- [VE_VIDEORAM] = 0x4c000000,
- [VE_ETHERNET] = 0x4e000000,
- [VE_USB] = 0x4f000000,
-};
-
-static hwaddr motherboard_aseries_map[] = {
- [VE_NORFLASHALIAS] = 0,
- /* CS0: 0x08000000 .. 0x0c000000 */
- [VE_NORFLASH0] = 0x08000000,
- /* CS4: 0x0c000000 .. 0x10000000 */
- [VE_NORFLASH1] = 0x0c000000,
- /* CS5: 0x10000000 .. 0x14000000 */
- /* CS1: 0x14000000 .. 0x18000000 */
- [VE_SRAM] = 0x14000000,
- /* CS2: 0x18000000 .. 0x1c000000 */
- [VE_VIDEORAM] = 0x18000000,
- [VE_ETHERNET] = 0x1a000000,
- [VE_USB] = 0x1b000000,
- /* CS3: 0x1c000000 .. 0x20000000 */
- [VE_DAPROM] = 0x1c000000,
- [VE_SYSREGS] = 0x1c010000,
- [VE_SP810] = 0x1c020000,
- [VE_SERIALPCI] = 0x1c030000,
- [VE_PL041] = 0x1c040000,
- [VE_MMCI] = 0x1c050000,
- [VE_KMI0] = 0x1c060000,
- [VE_KMI1] = 0x1c070000,
- [VE_UART0] = 0x1c090000,
- [VE_UART1] = 0x1c0a0000,
- [VE_UART2] = 0x1c0b0000,
- [VE_UART3] = 0x1c0c0000,
- [VE_WDT] = 0x1c0f0000,
- [VE_TIMER01] = 0x1c110000,
- [VE_TIMER23] = 0x1c120000,
- [VE_VIRTIO] = 0x1c130000,
- [VE_SERIALDVI] = 0x1c160000,
- [VE_RTC] = 0x1c170000,
- [VE_COMPACTFLASH] = 0x1c1a0000,
- [VE_CLCD] = 0x1c1f0000,
-};
-
-/* Structure defining the peculiarities of a specific daughterboard */
-
-typedef struct VEDBoardInfo VEDBoardInfo;
-
-typedef struct {
- MachineClass parent;
- VEDBoardInfo *daughterboard;
-} VexpressMachineClass;
-
-typedef struct {
- MachineState parent;
- bool secure;
-} VexpressMachineState;
-
-#define TYPE_VEXPRESS_MACHINE "vexpress"
-#define TYPE_VEXPRESS_A9_MACHINE MACHINE_TYPE_NAME("vexpress-a9")
-#define TYPE_VEXPRESS_A15_MACHINE MACHINE_TYPE_NAME("vexpress-a15")
-#define VEXPRESS_MACHINE(obj) \
- OBJECT_CHECK(VexpressMachineState, (obj), TYPE_VEXPRESS_MACHINE)
-#define VEXPRESS_MACHINE_GET_CLASS(obj) \
- OBJECT_GET_CLASS(VexpressMachineClass, obj, TYPE_VEXPRESS_MACHINE)
-#define VEXPRESS_MACHINE_CLASS(klass) \
- OBJECT_CLASS_CHECK(VexpressMachineClass, klass, TYPE_VEXPRESS_MACHINE)
-
-typedef void DBoardInitFn(const VexpressMachineState *machine,
- ram_addr_t ram_size,
- const char *cpu_model,
- qemu_irq *pic);
-
-struct VEDBoardInfo {
- struct arm_boot_info bootinfo;
- const hwaddr *motherboard_map;
- hwaddr loader_start;
- const hwaddr gic_cpu_if_addr;
- uint32_t proc_id;
- uint32_t num_voltage_sensors;
- const uint32_t *voltages;
- uint32_t num_clocks;
- const uint32_t *clocks;
- DBoardInitFn *init;
-};
-
-static void init_cpus(const char *cpu_model, const char *privdev,
- hwaddr periphbase, qemu_irq *pic, bool secure)
-{
- ObjectClass *cpu_oc = cpu_class_by_name(TYPE_ARM_CPU, cpu_model);
- DeviceState *dev;
- SysBusDevice *busdev;
- int n;
-
- if (!cpu_oc) {
- fprintf(stderr, "Unable to find CPU definition\n");
- exit(1);
- }
-
- /* Create the actual CPUs */
- for (n = 0; n < smp_cpus; n++) {
- Object *cpuobj = object_new(object_class_get_name(cpu_oc));
-
- if (!secure) {
- object_property_set_bool(cpuobj, false, "has_el3", NULL);
- }
-
- if (object_property_find(cpuobj, "reset-cbar", NULL)) {
- object_property_set_int(cpuobj, periphbase,
- "reset-cbar", &error_abort);
- }
- object_property_set_bool(cpuobj, true, "realized", &error_fatal);
- }
-
- /* Create the private peripheral devices (including the GIC);
- * this must happen after the CPUs are created because a15mpcore_priv
- * wires itself up to the CPU's generic_timer gpio out lines.
- */
- dev = qdev_create(NULL, privdev);
- qdev_prop_set_uint32(dev, "num-cpu", smp_cpus);
- qdev_init_nofail(dev);
- busdev = SYS_BUS_DEVICE(dev);
- sysbus_mmio_map(busdev, 0, periphbase);
-
- /* Interrupts [42:0] are from the motherboard;
- * [47:43] are reserved; [63:48] are daughterboard
- * peripherals. Note that some documentation numbers
- * external interrupts starting from 32 (because there
- * are internal interrupts 0..31).
- */
- for (n = 0; n < 64; n++) {
- pic[n] = qdev_get_gpio_in(dev, n);
- }
-
- /* Connect the CPUs to the GIC */
- for (n = 0; n < smp_cpus; n++) {
- DeviceState *cpudev = DEVICE(qemu_get_cpu(n));
-
- sysbus_connect_irq(busdev, n, qdev_get_gpio_in(cpudev, ARM_CPU_IRQ));
- sysbus_connect_irq(busdev, n + smp_cpus,
- qdev_get_gpio_in(cpudev, ARM_CPU_FIQ));
- }
-}
-
-static void a9_daughterboard_init(const VexpressMachineState *vms,
- ram_addr_t ram_size,
- const char *cpu_model,
- qemu_irq *pic)
-{
- MemoryRegion *sysmem = get_system_memory();
- MemoryRegion *ram = g_new(MemoryRegion, 1);
- MemoryRegion *lowram = g_new(MemoryRegion, 1);
- ram_addr_t low_ram_size;
-
- if (!cpu_model) {
- cpu_model = "cortex-a9";
- }
-
- if (ram_size > 0x40000000) {
- /* 1GB is the maximum the address space permits */
- fprintf(stderr, "vexpress-a9: cannot model more than 1GB RAM\n");
- exit(1);
- }
-
- memory_region_allocate_system_memory(ram, NULL, "vexpress.highmem",
- ram_size);
- low_ram_size = ram_size;
- if (low_ram_size > 0x4000000) {
- low_ram_size = 0x4000000;
- }
- /* RAM is from 0x60000000 upwards. The bottom 64MB of the
- * address space should in theory be remappable to various
- * things including ROM or RAM; we always map the RAM there.
- */
- memory_region_init_alias(lowram, NULL, "vexpress.lowmem", ram, 0, low_ram_size);
- memory_region_add_subregion(sysmem, 0x0, lowram);
- memory_region_add_subregion(sysmem, 0x60000000, ram);
-
- /* 0x1e000000 A9MPCore (SCU) private memory region */
- init_cpus(cpu_model, "a9mpcore_priv", 0x1e000000, pic, vms->secure);
-
- /* Daughterboard peripherals : 0x10020000 .. 0x20000000 */
-
- /* 0x10020000 PL111 CLCD (daughterboard) */
- sysbus_create_simple("pl111", 0x10020000, pic[44]);
-
- /* 0x10060000 AXI RAM */
- /* 0x100e0000 PL341 Dynamic Memory Controller */
- /* 0x100e1000 PL354 Static Memory Controller */
- /* 0x100e2000 System Configuration Controller */
-
- sysbus_create_simple("sp804", 0x100e4000, pic[48]);
- /* 0x100e5000 SP805 Watchdog module */
- /* 0x100e6000 BP147 TrustZone Protection Controller */
- /* 0x100e9000 PL301 'Fast' AXI matrix */
- /* 0x100ea000 PL301 'Slow' AXI matrix */
- /* 0x100ec000 TrustZone Address Space Controller */
- /* 0x10200000 CoreSight debug APB */
- /* 0x1e00a000 PL310 L2 Cache Controller */
- sysbus_create_varargs("l2x0", 0x1e00a000, NULL);
-}
-
-/* Voltage values for SYS_CFG_VOLT daughterboard registers;
- * values are in microvolts.
- */
-static const uint32_t a9_voltages[] = {
- 1000000, /* VD10 : 1.0V : SoC internal logic voltage */
- 1000000, /* VD10_S2 : 1.0V : PL310, L2 cache, RAM, non-PL310 logic */
- 1000000, /* VD10_S3 : 1.0V : Cortex-A9, cores, MPEs, SCU, PL310 logic */
- 1800000, /* VCC1V8 : 1.8V : DDR2 SDRAM, test chip DDR2 I/O supply */
- 900000, /* DDR2VTT : 0.9V : DDR2 SDRAM VTT termination voltage */
- 3300000, /* VCC3V3 : 3.3V : local board supply for misc external logic */
-};
-
-/* Reset values for daughterboard oscillators (in Hz) */
-static const uint32_t a9_clocks[] = {
- 45000000, /* AMBA AXI ACLK: 45MHz */
- 23750000, /* daughterboard CLCD clock: 23.75MHz */
- 66670000, /* Test chip reference clock: 66.67MHz */
-};
-
-static VEDBoardInfo a9_daughterboard = {
- .motherboard_map = motherboard_legacy_map,
- .loader_start = 0x60000000,
- .gic_cpu_if_addr = 0x1e000100,
- .proc_id = 0x0c000191,
- .num_voltage_sensors = ARRAY_SIZE(a9_voltages),
- .voltages = a9_voltages,
- .num_clocks = ARRAY_SIZE(a9_clocks),
- .clocks = a9_clocks,
- .init = a9_daughterboard_init,
-};
-
-static void a15_daughterboard_init(const VexpressMachineState *vms,
- ram_addr_t ram_size,
- const char *cpu_model,
- qemu_irq *pic)
-{
- MemoryRegion *sysmem = get_system_memory();
- MemoryRegion *ram = g_new(MemoryRegion, 1);
- MemoryRegion *sram = g_new(MemoryRegion, 1);
-
- if (!cpu_model) {
- cpu_model = "cortex-a15";
- }
-
- {
- /* We have to use a separate 64 bit variable here to avoid the gcc
- * "comparison is always false due to limited range of data type"
- * warning if we are on a host where ram_addr_t is 32 bits.
- */
- uint64_t rsz = ram_size;
- if (rsz > (30ULL * 1024 * 1024 * 1024)) {
- fprintf(stderr, "vexpress-a15: cannot model more than 30GB RAM\n");
- exit(1);
- }
- }
-
- memory_region_allocate_system_memory(ram, NULL, "vexpress.highmem",
- ram_size);
- /* RAM is from 0x80000000 upwards; there is no low-memory alias for it. */
- memory_region_add_subregion(sysmem, 0x80000000, ram);
-
- /* 0x2c000000 A15MPCore private memory region (GIC) */
- init_cpus(cpu_model, "a15mpcore_priv", 0x2c000000, pic, vms->secure);
-
- /* A15 daughterboard peripherals: */
-
- /* 0x20000000: CoreSight interfaces: not modelled */
- /* 0x2a000000: PL301 AXI interconnect: not modelled */
- /* 0x2a420000: SCC: not modelled */
- /* 0x2a430000: system counter: not modelled */
- /* 0x2b000000: HDLCD controller: not modelled */
- /* 0x2b060000: SP805 watchdog: not modelled */
- /* 0x2b0a0000: PL341 dynamic memory controller: not modelled */
- /* 0x2e000000: system SRAM */
- memory_region_init_ram(sram, NULL, "vexpress.a15sram", 0x10000,
- &error_fatal);
- vmstate_register_ram_global(sram);
- memory_region_add_subregion(sysmem, 0x2e000000, sram);
-
- /* 0x7ffb0000: DMA330 DMA controller: not modelled */
- /* 0x7ffd0000: PL354 static memory controller: not modelled */
-}
-
-static const uint32_t a15_voltages[] = {
- 900000, /* Vcore: 0.9V : CPU core voltage */
-};
-
-static const uint32_t a15_clocks[] = {
- 60000000, /* OSCCLK0: 60MHz : CPU_CLK reference */
- 0, /* OSCCLK1: reserved */
- 0, /* OSCCLK2: reserved */
- 0, /* OSCCLK3: reserved */
- 40000000, /* OSCCLK4: 40MHz : external AXI master clock */
- 23750000, /* OSCCLK5: 23.75MHz : HDLCD PLL reference */
- 50000000, /* OSCCLK6: 50MHz : static memory controller clock */
- 60000000, /* OSCCLK7: 60MHz : SYSCLK reference */
- 40000000, /* OSCCLK8: 40MHz : DDR2 PLL reference */
-};
-
-static VEDBoardInfo a15_daughterboard = {
- .motherboard_map = motherboard_aseries_map,
- .loader_start = 0x80000000,
- .gic_cpu_if_addr = 0x2c002000,
- .proc_id = 0x14000237,
- .num_voltage_sensors = ARRAY_SIZE(a15_voltages),
- .voltages = a15_voltages,
- .num_clocks = ARRAY_SIZE(a15_clocks),
- .clocks = a15_clocks,
- .init = a15_daughterboard_init,
-};
-
-static int add_virtio_mmio_node(void *fdt, uint32_t acells, uint32_t scells,
- hwaddr addr, hwaddr size, uint32_t intc,
- int irq)
-{
- /* Add a virtio_mmio node to the device tree blob:
- * virtio_mmio@ADDRESS {
- * compatible = "virtio,mmio";
- * reg = <ADDRESS, SIZE>;
- * interrupt-parent = <&intc>;
- * interrupts = <0, irq, 1>;
- * }
- * (Note that the format of the interrupts property is dependent on the
- * interrupt controller that interrupt-parent points to; these are for
- * the ARM GIC and indicate an SPI interrupt, rising-edge-triggered.)
- */
- int rc;
- char *nodename = g_strdup_printf("/virtio_mmio@%" PRIx64, addr);
-
- rc = qemu_fdt_add_subnode(fdt, nodename);
- rc |= qemu_fdt_setprop_string(fdt, nodename,
- "compatible", "virtio,mmio");
- rc |= qemu_fdt_setprop_sized_cells(fdt, nodename, "reg",
- acells, addr, scells, size);
- qemu_fdt_setprop_cells(fdt, nodename, "interrupt-parent", intc);
- qemu_fdt_setprop_cells(fdt, nodename, "interrupts", 0, irq, 1);
- g_free(nodename);
- if (rc) {
- return -1;
- }
- return 0;
-}
-
-static uint32_t find_int_controller(void *fdt)
-{
- /* Find the FDT node corresponding to the interrupt controller
- * for virtio-mmio devices. We do this by scanning the fdt for
- * a node with the right compatibility, since we know there is
- * only one GIC on a vexpress board.
- * We return the phandle of the node, or 0 if none was found.
- */
- const char *compat = "arm,cortex-a9-gic";
- int offset;
-
- offset = fdt_node_offset_by_compatible(fdt, -1, compat);
- if (offset >= 0) {
- return fdt_get_phandle(fdt, offset);
- }
- return 0;
-}
-
-static void vexpress_modify_dtb(const struct arm_boot_info *info, void *fdt)
-{
- uint32_t acells, scells, intc;
- const VEDBoardInfo *daughterboard = (const VEDBoardInfo *)info;
-
- acells = qemu_fdt_getprop_cell(fdt, "/", "#address-cells",
- NULL, &error_fatal);
- scells = qemu_fdt_getprop_cell(fdt, "/", "#size-cells",
- NULL, &error_fatal);
- intc = find_int_controller(fdt);
- if (!intc) {
- /* Not fatal, we just won't provide virtio. This will
- * happen with older device tree blobs.
- */
- fprintf(stderr, "QEMU: warning: couldn't find interrupt controller in "
- "dtb; will not include virtio-mmio devices in the dtb.\n");
- } else {
- int i;
- const hwaddr *map = daughterboard->motherboard_map;
-
- /* We iterate backwards here because adding nodes
- * to the dtb puts them in last-first.
- */
- for (i = NUM_VIRTIO_TRANSPORTS - 1; i >= 0; i--) {
- add_virtio_mmio_node(fdt, acells, scells,
- map[VE_VIRTIO] + 0x200 * i,
- 0x200, intc, 40 + i);
- }
- }
-}
-
-
-/* Open code a private version of pflash registration since we
- * need to set non-default device width for VExpress platform.
- */
-static pflash_t *ve_pflash_cfi01_register(hwaddr base, const char *name,
- DriveInfo *di)
-{
- DeviceState *dev = qdev_create(NULL, "cfi.pflash01");
-
- if (di) {
- qdev_prop_set_drive(dev, "drive", blk_by_legacy_dinfo(di),
- &error_abort);
- }
-
- qdev_prop_set_uint32(dev, "num-blocks",
- VEXPRESS_FLASH_SIZE / VEXPRESS_FLASH_SECT_SIZE);
- qdev_prop_set_uint64(dev, "sector-length", VEXPRESS_FLASH_SECT_SIZE);
- qdev_prop_set_uint8(dev, "width", 4);
- qdev_prop_set_uint8(dev, "device-width", 2);
- qdev_prop_set_bit(dev, "big-endian", false);
- qdev_prop_set_uint16(dev, "id0", 0x89);
- qdev_prop_set_uint16(dev, "id1", 0x18);
- qdev_prop_set_uint16(dev, "id2", 0x00);
- qdev_prop_set_uint16(dev, "id3", 0x00);
- qdev_prop_set_string(dev, "name", name);
- qdev_init_nofail(dev);
-
- sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
- return OBJECT_CHECK(pflash_t, (dev), "cfi.pflash01");
-}
-
-static void vexpress_common_init(MachineState *machine)
-{
- VexpressMachineState *vms = VEXPRESS_MACHINE(machine);
- VexpressMachineClass *vmc = VEXPRESS_MACHINE_GET_CLASS(machine);
- VEDBoardInfo *daughterboard = vmc->daughterboard;
- DeviceState *dev, *sysctl, *pl041;
- qemu_irq pic[64];
- uint32_t sys_id;
- DriveInfo *dinfo;
- pflash_t *pflash0;
- ram_addr_t vram_size, sram_size;
- MemoryRegion *sysmem = get_system_memory();
- MemoryRegion *vram = g_new(MemoryRegion, 1);
- MemoryRegion *sram = g_new(MemoryRegion, 1);
- MemoryRegion *flashalias = g_new(MemoryRegion, 1);
- MemoryRegion *flash0mem;
- const hwaddr *map = daughterboard->motherboard_map;
- int i;
-
- daughterboard->init(vms, machine->ram_size, machine->cpu_model, pic);
-
- /*
- * If a bios file was provided, attempt to map it into memory
- */
- if (bios_name) {
- char *fn;
- int image_size;
-
- if (drive_get(IF_PFLASH, 0, 0)) {
- error_report("The contents of the first flash device may be "
- "specified with -bios or with -drive if=pflash... "
- "but you cannot use both options at once");
- exit(1);
- }
- fn = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
- if (!fn) {
- error_report("Could not find ROM image '%s'", bios_name);
- exit(1);
- }
- image_size = load_image_targphys(fn, map[VE_NORFLASH0],
- VEXPRESS_FLASH_SIZE);
- g_free(fn);
- if (image_size < 0) {
- error_report("Could not load ROM image '%s'", bios_name);
- exit(1);
- }
- }
-
- /* Motherboard peripherals: the wiring is the same but the
- * addresses vary between the legacy and A-Series memory maps.
- */
-
- sys_id = 0x1190f500;
-
- sysctl = qdev_create(NULL, "realview_sysctl");
- qdev_prop_set_uint32(sysctl, "sys_id", sys_id);
- qdev_prop_set_uint32(sysctl, "proc_id", daughterboard->proc_id);
- qdev_prop_set_uint32(sysctl, "len-db-voltage",
- daughterboard->num_voltage_sensors);
- for (i = 0; i < daughterboard->num_voltage_sensors; i++) {
- char *propname = g_strdup_printf("db-voltage[%d]", i);
- qdev_prop_set_uint32(sysctl, propname, daughterboard->voltages[i]);
- g_free(propname);
- }
- qdev_prop_set_uint32(sysctl, "len-db-clock",
- daughterboard->num_clocks);
- for (i = 0; i < daughterboard->num_clocks; i++) {
- char *propname = g_strdup_printf("db-clock[%d]", i);
- qdev_prop_set_uint32(sysctl, propname, daughterboard->clocks[i]);
- g_free(propname);
- }
- qdev_init_nofail(sysctl);
- sysbus_mmio_map(SYS_BUS_DEVICE(sysctl), 0, map[VE_SYSREGS]);
-
- /* VE_SP810: not modelled */
- /* VE_SERIALPCI: not modelled */
-
- pl041 = qdev_create(NULL, "pl041");
- qdev_prop_set_uint32(pl041, "nc_fifo_depth", 512);
- qdev_init_nofail(pl041);
- sysbus_mmio_map(SYS_BUS_DEVICE(pl041), 0, map[VE_PL041]);
- sysbus_connect_irq(SYS_BUS_DEVICE(pl041), 0, pic[11]);
-
- dev = sysbus_create_varargs("pl181", map[VE_MMCI], pic[9], pic[10], NULL);
- /* Wire up MMC card detect and read-only signals */
- qdev_connect_gpio_out(dev, 0,
- qdev_get_gpio_in(sysctl, ARM_SYSCTL_GPIO_MMC_WPROT));
- qdev_connect_gpio_out(dev, 1,
- qdev_get_gpio_in(sysctl, ARM_SYSCTL_GPIO_MMC_CARDIN));
-
- sysbus_create_simple("pl050_keyboard", map[VE_KMI0], pic[12]);
- sysbus_create_simple("pl050_mouse", map[VE_KMI1], pic[13]);
-
- sysbus_create_simple("pl011", map[VE_UART0], pic[5]);
- sysbus_create_simple("pl011", map[VE_UART1], pic[6]);
- sysbus_create_simple("pl011", map[VE_UART2], pic[7]);
- sysbus_create_simple("pl011", map[VE_UART3], pic[8]);
-
- sysbus_create_simple("sp804", map[VE_TIMER01], pic[2]);
- sysbus_create_simple("sp804", map[VE_TIMER23], pic[3]);
-
- /* VE_SERIALDVI: not modelled */
-
- sysbus_create_simple("pl031", map[VE_RTC], pic[4]); /* RTC */
-
- /* VE_COMPACTFLASH: not modelled */
-
- sysbus_create_simple("pl111", map[VE_CLCD], pic[14]);
-
- dinfo = drive_get_next(IF_PFLASH);
- pflash0 = ve_pflash_cfi01_register(map[VE_NORFLASH0], "vexpress.flash0",
- dinfo);
- if (!pflash0) {
- fprintf(stderr, "vexpress: error registering flash 0.\n");
- exit(1);
- }
-
- if (map[VE_NORFLASHALIAS] != -1) {
- /* Map flash 0 as an alias into low memory */
- flash0mem = sysbus_mmio_get_region(SYS_BUS_DEVICE(pflash0), 0);
- memory_region_init_alias(flashalias, NULL, "vexpress.flashalias",
- flash0mem, 0, VEXPRESS_FLASH_SIZE);
- memory_region_add_subregion(sysmem, map[VE_NORFLASHALIAS], flashalias);
- }
-
- dinfo = drive_get_next(IF_PFLASH);
- if (!ve_pflash_cfi01_register(map[VE_NORFLASH1], "vexpress.flash1",
- dinfo)) {
- fprintf(stderr, "vexpress: error registering flash 1.\n");
- exit(1);
- }
-
- sram_size = 0x2000000;
- memory_region_init_ram(sram, NULL, "vexpress.sram", sram_size,
- &error_fatal);
- vmstate_register_ram_global(sram);
- memory_region_add_subregion(sysmem, map[VE_SRAM], sram);
-
- vram_size = 0x800000;
- memory_region_init_ram(vram, NULL, "vexpress.vram", vram_size,
- &error_fatal);
- vmstate_register_ram_global(vram);
- memory_region_add_subregion(sysmem, map[VE_VIDEORAM], vram);
-
- /* 0x4e000000 LAN9118 Ethernet */
- if (nd_table[0].used) {
- lan9118_init(&nd_table[0], map[VE_ETHERNET], pic[15]);
- }
-
- /* VE_USB: not modelled */
-
- /* VE_DAPROM: not modelled */
-
- /* Create mmio transports, so the user can create virtio backends
- * (which will be automatically plugged in to the transports). If
- * no backend is created the transport will just sit harmlessly idle.
- */
- for (i = 0; i < NUM_VIRTIO_TRANSPORTS; i++) {
- sysbus_create_simple("virtio-mmio", map[VE_VIRTIO] + 0x200 * i,
- pic[40 + i]);
- }
-
- daughterboard->bootinfo.ram_size = machine->ram_size;
- daughterboard->bootinfo.kernel_filename = machine->kernel_filename;
- daughterboard->bootinfo.kernel_cmdline = machine->kernel_cmdline;
- daughterboard->bootinfo.initrd_filename = machine->initrd_filename;
- daughterboard->bootinfo.nb_cpus = smp_cpus;
- daughterboard->bootinfo.board_id = VEXPRESS_BOARD_ID;
- daughterboard->bootinfo.loader_start = daughterboard->loader_start;
- daughterboard->bootinfo.smp_loader_start = map[VE_SRAM];
- daughterboard->bootinfo.smp_bootreg_addr = map[VE_SYSREGS] + 0x30;
- daughterboard->bootinfo.gic_cpu_if_addr = daughterboard->gic_cpu_if_addr;
- daughterboard->bootinfo.modify_dtb = vexpress_modify_dtb;
- /* Indicate that when booting Linux we should be in secure state */
- daughterboard->bootinfo.secure_boot = true;
- arm_load_kernel(ARM_CPU(first_cpu), &daughterboard->bootinfo);
-}
-
-static bool vexpress_get_secure(Object *obj, Error **errp)
-{
- VexpressMachineState *vms = VEXPRESS_MACHINE(obj);
-
- return vms->secure;
-}
-
-static void vexpress_set_secure(Object *obj, bool value, Error **errp)
-{
- VexpressMachineState *vms = VEXPRESS_MACHINE(obj);
-
- vms->secure = value;
-}
-
-static void vexpress_instance_init(Object *obj)
-{
- VexpressMachineState *vms = VEXPRESS_MACHINE(obj);
-
- /* EL3 is enabled by default on vexpress */
- vms->secure = true;
- object_property_add_bool(obj, "secure", vexpress_get_secure,
- vexpress_set_secure, NULL);
- object_property_set_description(obj, "secure",
- "Set on/off to enable/disable the ARM "
- "Security Extensions (TrustZone)",
- NULL);
-}
-
-static void vexpress_class_init(ObjectClass *oc, void *data)
-{
- MachineClass *mc = MACHINE_CLASS(oc);
-
- mc->desc = "ARM Versatile Express";
- mc->init = vexpress_common_init;
- mc->block_default_type = IF_SCSI;
- mc->max_cpus = 4;
-}
-
-static void vexpress_a9_class_init(ObjectClass *oc, void *data)
-{
- MachineClass *mc = MACHINE_CLASS(oc);
- VexpressMachineClass *vmc = VEXPRESS_MACHINE_CLASS(oc);
-
- mc->desc = "ARM Versatile Express for Cortex-A9";
-
- vmc->daughterboard = &a9_daughterboard;
-}
-
-static void vexpress_a15_class_init(ObjectClass *oc, void *data)
-{
- MachineClass *mc = MACHINE_CLASS(oc);
- VexpressMachineClass *vmc = VEXPRESS_MACHINE_CLASS(oc);
-
- mc->desc = "ARM Versatile Express for Cortex-A15";
-
- vmc->daughterboard = &a15_daughterboard;
-}
-
-static const TypeInfo vexpress_info = {
- .name = TYPE_VEXPRESS_MACHINE,
- .parent = TYPE_MACHINE,
- .abstract = true,
- .instance_size = sizeof(VexpressMachineState),
- .instance_init = vexpress_instance_init,
- .class_size = sizeof(VexpressMachineClass),
- .class_init = vexpress_class_init,
-};
-
-static const TypeInfo vexpress_a9_info = {
- .name = TYPE_VEXPRESS_A9_MACHINE,
- .parent = TYPE_VEXPRESS_MACHINE,
- .class_init = vexpress_a9_class_init,
-};
-
-static const TypeInfo vexpress_a15_info = {
- .name = TYPE_VEXPRESS_A15_MACHINE,
- .parent = TYPE_VEXPRESS_MACHINE,
- .class_init = vexpress_a15_class_init,
-};
-
-static void vexpress_machine_init(void)
-{
- type_register_static(&vexpress_info);
- type_register_static(&vexpress_a9_info);
- type_register_static(&vexpress_a15_info);
-}
-
-type_init(vexpress_machine_init);
diff --git a/qemu/hw/arm/virt-acpi-build.c b/qemu/hw/arm/virt-acpi-build.c
deleted file mode 100644
index f51fe396c..000000000
--- a/qemu/hw/arm/virt-acpi-build.c
+++ /dev/null
@@ -1,755 +0,0 @@
-/* Support for generating ACPI tables and passing them to Guests
- *
- * ARM virt ACPI generation
- *
- * Copyright (C) 2008-2010 Kevin O'Connor <kevin@koconnor.net>
- * Copyright (C) 2006 Fabrice Bellard
- * Copyright (C) 2013 Red Hat Inc
- *
- * Author: Michael S. Tsirkin <mst@redhat.com>
- *
- * Copyright (c) 2015 HUAWEI TECHNOLOGIES CO.,LTD.
- *
- * Author: Shannon Zhao <zhaoshenglong@huawei.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
-
- * 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/>.
- */
-
-#include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "qemu-common.h"
-#include "hw/arm/virt-acpi-build.h"
-#include "qemu/bitmap.h"
-#include "trace.h"
-#include "qom/cpu.h"
-#include "target-arm/cpu.h"
-#include "hw/acpi/acpi-defs.h"
-#include "hw/acpi/acpi.h"
-#include "hw/nvram/fw_cfg.h"
-#include "hw/acpi/bios-linker-loader.h"
-#include "hw/loader.h"
-#include "hw/hw.h"
-#include "hw/acpi/aml-build.h"
-#include "hw/pci/pcie_host.h"
-#include "hw/pci/pci.h"
-
-#define ARM_SPI_BASE 32
-#define ACPI_POWER_BUTTON_DEVICE "PWRB"
-
-static void acpi_dsdt_add_cpus(Aml *scope, int smp_cpus)
-{
- uint16_t i;
-
- for (i = 0; i < smp_cpus; i++) {
- Aml *dev = aml_device("C%03x", i);
- aml_append(dev, aml_name_decl("_HID", aml_string("ACPI0007")));
- aml_append(dev, aml_name_decl("_UID", aml_int(i)));
- aml_append(scope, dev);
- }
-}
-
-static void acpi_dsdt_add_uart(Aml *scope, const MemMapEntry *uart_memmap,
- uint32_t uart_irq)
-{
- Aml *dev = aml_device("COM0");
- aml_append(dev, aml_name_decl("_HID", aml_string("ARMH0011")));
- aml_append(dev, aml_name_decl("_UID", aml_int(0)));
-
- Aml *crs = aml_resource_template();
- aml_append(crs, aml_memory32_fixed(uart_memmap->base,
- uart_memmap->size, AML_READ_WRITE));
- aml_append(crs,
- aml_interrupt(AML_CONSUMER, AML_LEVEL, AML_ACTIVE_HIGH,
- AML_EXCLUSIVE, &uart_irq, 1));
- aml_append(dev, aml_name_decl("_CRS", crs));
-
- /* The _ADR entry is used to link this device to the UART described
- * in the SPCR table, i.e. SPCR.base_address.address == _ADR.
- */
- aml_append(dev, aml_name_decl("_ADR", aml_int(uart_memmap->base)));
-
- aml_append(scope, dev);
-}
-
-static void acpi_dsdt_add_fw_cfg(Aml *scope, const MemMapEntry *fw_cfg_memmap)
-{
- Aml *dev = aml_device("FWCF");
- aml_append(dev, aml_name_decl("_HID", aml_string("QEMU0002")));
- /* device present, functioning, decoding, not shown in UI */
- aml_append(dev, aml_name_decl("_STA", aml_int(0xB)));
-
- Aml *crs = aml_resource_template();
- aml_append(crs, aml_memory32_fixed(fw_cfg_memmap->base,
- fw_cfg_memmap->size, AML_READ_WRITE));
- aml_append(dev, aml_name_decl("_CRS", crs));
- aml_append(scope, dev);
-}
-
-static void acpi_dsdt_add_flash(Aml *scope, const MemMapEntry *flash_memmap)
-{
- Aml *dev, *crs;
- hwaddr base = flash_memmap->base;
- hwaddr size = flash_memmap->size / 2;
-
- dev = aml_device("FLS0");
- aml_append(dev, aml_name_decl("_HID", aml_string("LNRO0015")));
- aml_append(dev, aml_name_decl("_UID", aml_int(0)));
-
- crs = aml_resource_template();
- aml_append(crs, aml_memory32_fixed(base, size, AML_READ_WRITE));
- aml_append(dev, aml_name_decl("_CRS", crs));
- aml_append(scope, dev);
-
- dev = aml_device("FLS1");
- aml_append(dev, aml_name_decl("_HID", aml_string("LNRO0015")));
- aml_append(dev, aml_name_decl("_UID", aml_int(1)));
- crs = aml_resource_template();
- aml_append(crs, aml_memory32_fixed(base + size, size, AML_READ_WRITE));
- aml_append(dev, aml_name_decl("_CRS", crs));
- aml_append(scope, dev);
-}
-
-static void acpi_dsdt_add_virtio(Aml *scope,
- const MemMapEntry *virtio_mmio_memmap,
- uint32_t mmio_irq, int num)
-{
- hwaddr base = virtio_mmio_memmap->base;
- hwaddr size = virtio_mmio_memmap->size;
- int i;
-
- for (i = 0; i < num; i++) {
- uint32_t irq = mmio_irq + i;
- Aml *dev = aml_device("VR%02u", i);
- aml_append(dev, aml_name_decl("_HID", aml_string("LNRO0005")));
- aml_append(dev, aml_name_decl("_UID", aml_int(i)));
-
- Aml *crs = aml_resource_template();
- aml_append(crs, aml_memory32_fixed(base, size, AML_READ_WRITE));
- aml_append(crs,
- aml_interrupt(AML_CONSUMER, AML_LEVEL, AML_ACTIVE_HIGH,
- AML_EXCLUSIVE, &irq, 1));
- aml_append(dev, aml_name_decl("_CRS", crs));
- aml_append(scope, dev);
- base += size;
- }
-}
-
-static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap,
- uint32_t irq, bool use_highmem)
-{
- Aml *method, *crs, *ifctx, *UUID, *ifctx1, *elsectx, *buf;
- int i, bus_no;
- hwaddr base_mmio = memmap[VIRT_PCIE_MMIO].base;
- hwaddr size_mmio = memmap[VIRT_PCIE_MMIO].size;
- hwaddr base_pio = memmap[VIRT_PCIE_PIO].base;
- hwaddr size_pio = memmap[VIRT_PCIE_PIO].size;
- hwaddr base_ecam = memmap[VIRT_PCIE_ECAM].base;
- hwaddr size_ecam = memmap[VIRT_PCIE_ECAM].size;
- int nr_pcie_buses = size_ecam / PCIE_MMCFG_SIZE_MIN;
-
- Aml *dev = aml_device("%s", "PCI0");
- aml_append(dev, aml_name_decl("_HID", aml_string("PNP0A08")));
- aml_append(dev, aml_name_decl("_CID", aml_string("PNP0A03")));
- aml_append(dev, aml_name_decl("_SEG", aml_int(0)));
- aml_append(dev, aml_name_decl("_BBN", aml_int(0)));
- aml_append(dev, aml_name_decl("_ADR", aml_int(0)));
- aml_append(dev, aml_name_decl("_UID", aml_string("PCI0")));
- aml_append(dev, aml_name_decl("_STR", aml_unicode("PCIe 0 Device")));
- aml_append(dev, aml_name_decl("_CCA", aml_int(1)));
-
- /* Declare the PCI Routing Table. */
- Aml *rt_pkg = aml_package(nr_pcie_buses * PCI_NUM_PINS);
- for (bus_no = 0; bus_no < nr_pcie_buses; bus_no++) {
- for (i = 0; i < PCI_NUM_PINS; i++) {
- int gsi = (i + bus_no) % PCI_NUM_PINS;
- Aml *pkg = aml_package(4);
- aml_append(pkg, aml_int((bus_no << 16) | 0xFFFF));
- aml_append(pkg, aml_int(i));
- aml_append(pkg, aml_name("GSI%d", gsi));
- aml_append(pkg, aml_int(0));
- aml_append(rt_pkg, pkg);
- }
- }
- aml_append(dev, aml_name_decl("_PRT", rt_pkg));
-
- /* Create GSI link device */
- for (i = 0; i < PCI_NUM_PINS; i++) {
- uint32_t irqs = irq + i;
- Aml *dev_gsi = aml_device("GSI%d", i);
- aml_append(dev_gsi, aml_name_decl("_HID", aml_string("PNP0C0F")));
- aml_append(dev_gsi, aml_name_decl("_UID", aml_int(0)));
- crs = aml_resource_template();
- aml_append(crs,
- aml_interrupt(AML_CONSUMER, AML_LEVEL, AML_ACTIVE_HIGH,
- AML_EXCLUSIVE, &irqs, 1));
- aml_append(dev_gsi, aml_name_decl("_PRS", crs));
- crs = aml_resource_template();
- aml_append(crs,
- aml_interrupt(AML_CONSUMER, AML_LEVEL, AML_ACTIVE_HIGH,
- AML_EXCLUSIVE, &irqs, 1));
- aml_append(dev_gsi, aml_name_decl("_CRS", crs));
- method = aml_method("_SRS", 1, AML_NOTSERIALIZED);
- aml_append(dev_gsi, method);
- aml_append(dev, dev_gsi);
- }
-
- method = aml_method("_CBA", 0, AML_NOTSERIALIZED);
- aml_append(method, aml_return(aml_int(base_ecam)));
- aml_append(dev, method);
-
- method = aml_method("_CRS", 0, AML_NOTSERIALIZED);
- Aml *rbuf = aml_resource_template();
- aml_append(rbuf,
- aml_word_bus_number(AML_MIN_FIXED, AML_MAX_FIXED, AML_POS_DECODE,
- 0x0000, 0x0000, nr_pcie_buses - 1, 0x0000,
- nr_pcie_buses));
- aml_append(rbuf,
- aml_dword_memory(AML_POS_DECODE, AML_MIN_FIXED, AML_MAX_FIXED,
- AML_NON_CACHEABLE, AML_READ_WRITE, 0x0000, base_mmio,
- base_mmio + size_mmio - 1, 0x0000, size_mmio));
- aml_append(rbuf,
- aml_dword_io(AML_MIN_FIXED, AML_MAX_FIXED, AML_POS_DECODE,
- AML_ENTIRE_RANGE, 0x0000, 0x0000, size_pio - 1, base_pio,
- size_pio));
-
- if (use_highmem) {
- hwaddr base_mmio_high = memmap[VIRT_PCIE_MMIO_HIGH].base;
- hwaddr size_mmio_high = memmap[VIRT_PCIE_MMIO_HIGH].size;
-
- aml_append(rbuf,
- aml_qword_memory(AML_POS_DECODE, AML_MIN_FIXED, AML_MAX_FIXED,
- AML_NON_CACHEABLE, AML_READ_WRITE, 0x0000,
- base_mmio_high, base_mmio_high, 0x0000,
- size_mmio_high));
- }
-
- aml_append(method, aml_name_decl("RBUF", rbuf));
- aml_append(method, aml_return(rbuf));
- aml_append(dev, method);
-
- /* Declare an _OSC (OS Control Handoff) method */
- aml_append(dev, aml_name_decl("SUPP", aml_int(0)));
- aml_append(dev, aml_name_decl("CTRL", aml_int(0)));
- method = aml_method("_OSC", 4, AML_NOTSERIALIZED);
- aml_append(method,
- aml_create_dword_field(aml_arg(3), aml_int(0), "CDW1"));
-
- /* PCI Firmware Specification 3.0
- * 4.5.1. _OSC Interface for PCI Host Bridge Devices
- * The _OSC interface for a PCI/PCI-X/PCI Express hierarchy is
- * identified by the Universal Unique IDentifier (UUID)
- * 33DB4D5B-1FF7-401C-9657-7441C03DD766
- */
- UUID = aml_touuid("33DB4D5B-1FF7-401C-9657-7441C03DD766");
- ifctx = aml_if(aml_equal(aml_arg(0), UUID));
- aml_append(ifctx,
- aml_create_dword_field(aml_arg(3), aml_int(4), "CDW2"));
- aml_append(ifctx,
- aml_create_dword_field(aml_arg(3), aml_int(8), "CDW3"));
- aml_append(ifctx, aml_store(aml_name("CDW2"), aml_name("SUPP")));
- aml_append(ifctx, aml_store(aml_name("CDW3"), aml_name("CTRL")));
- aml_append(ifctx, aml_store(aml_and(aml_name("CTRL"), aml_int(0x1D), NULL),
- aml_name("CTRL")));
-
- ifctx1 = aml_if(aml_lnot(aml_equal(aml_arg(1), aml_int(0x1))));
- aml_append(ifctx1, aml_store(aml_or(aml_name("CDW1"), aml_int(0x08), NULL),
- aml_name("CDW1")));
- aml_append(ifctx, ifctx1);
-
- ifctx1 = aml_if(aml_lnot(aml_equal(aml_name("CDW3"), aml_name("CTRL"))));
- aml_append(ifctx1, aml_store(aml_or(aml_name("CDW1"), aml_int(0x10), NULL),
- aml_name("CDW1")));
- aml_append(ifctx, ifctx1);
-
- aml_append(ifctx, aml_store(aml_name("CTRL"), aml_name("CDW3")));
- aml_append(ifctx, aml_return(aml_arg(3)));
- aml_append(method, ifctx);
-
- elsectx = aml_else();
- aml_append(elsectx, aml_store(aml_or(aml_name("CDW1"), aml_int(4), NULL),
- aml_name("CDW1")));
- aml_append(elsectx, aml_return(aml_arg(3)));
- aml_append(method, elsectx);
- aml_append(dev, method);
-
- method = aml_method("_DSM", 4, AML_NOTSERIALIZED);
-
- /* PCI Firmware Specification 3.0
- * 4.6.1. _DSM for PCI Express Slot Information
- * The UUID in _DSM in this context is
- * {E5C937D0-3553-4D7A-9117-EA4D19C3434D}
- */
- UUID = aml_touuid("E5C937D0-3553-4D7A-9117-EA4D19C3434D");
- ifctx = aml_if(aml_equal(aml_arg(0), UUID));
- ifctx1 = aml_if(aml_equal(aml_arg(2), aml_int(0)));
- uint8_t byte_list[1] = {1};
- buf = aml_buffer(1, byte_list);
- aml_append(ifctx1, aml_return(buf));
- aml_append(ifctx, ifctx1);
- aml_append(method, ifctx);
-
- byte_list[0] = 0;
- buf = aml_buffer(1, byte_list);
- aml_append(method, aml_return(buf));
- aml_append(dev, method);
-
- Aml *dev_rp0 = aml_device("%s", "RP0");
- aml_append(dev_rp0, aml_name_decl("_ADR", aml_int(0)));
- aml_append(dev, dev_rp0);
- aml_append(scope, dev);
-}
-
-static void acpi_dsdt_add_gpio(Aml *scope, const MemMapEntry *gpio_memmap,
- uint32_t gpio_irq)
-{
- Aml *dev = aml_device("GPO0");
- aml_append(dev, aml_name_decl("_HID", aml_string("ARMH0061")));
- aml_append(dev, aml_name_decl("_ADR", aml_int(0)));
- aml_append(dev, aml_name_decl("_UID", aml_int(0)));
-
- Aml *crs = aml_resource_template();
- aml_append(crs, aml_memory32_fixed(gpio_memmap->base, gpio_memmap->size,
- AML_READ_WRITE));
- aml_append(crs, aml_interrupt(AML_CONSUMER, AML_LEVEL, AML_ACTIVE_HIGH,
- AML_EXCLUSIVE, &gpio_irq, 1));
- aml_append(dev, aml_name_decl("_CRS", crs));
-
- Aml *aei = aml_resource_template();
- /* Pin 3 for power button */
- const uint32_t pin_list[1] = {3};
- aml_append(aei, aml_gpio_int(AML_CONSUMER, AML_EDGE, AML_ACTIVE_HIGH,
- AML_EXCLUSIVE, AML_PULL_UP, 0, pin_list, 1,
- "GPO0", NULL, 0));
- aml_append(dev, aml_name_decl("_AEI", aei));
-
- /* _E03 is handle for power button */
- Aml *method = aml_method("_E03", 0, AML_NOTSERIALIZED);
- aml_append(method, aml_notify(aml_name(ACPI_POWER_BUTTON_DEVICE),
- aml_int(0x80)));
- aml_append(dev, method);
- aml_append(scope, dev);
-}
-
-static void acpi_dsdt_add_power_button(Aml *scope)
-{
- Aml *dev = aml_device(ACPI_POWER_BUTTON_DEVICE);
- aml_append(dev, aml_name_decl("_HID", aml_string("PNP0C0C")));
- aml_append(dev, aml_name_decl("_ADR", aml_int(0)));
- aml_append(dev, aml_name_decl("_UID", aml_int(0)));
- aml_append(scope, dev);
-}
-
-/* RSDP */
-static GArray *
-build_rsdp(GArray *rsdp_table, GArray *linker, unsigned rsdt)
-{
- AcpiRsdpDescriptor *rsdp = acpi_data_push(rsdp_table, sizeof *rsdp);
-
- bios_linker_loader_alloc(linker, ACPI_BUILD_RSDP_FILE, 16,
- true /* fseg memory */);
-
- memcpy(&rsdp->signature, "RSD PTR ", sizeof(rsdp->signature));
- memcpy(rsdp->oem_id, ACPI_BUILD_APPNAME6, sizeof(rsdp->oem_id));
- rsdp->length = cpu_to_le32(sizeof(*rsdp));
- rsdp->revision = 0x02;
-
- /* Point to RSDT */
- rsdp->rsdt_physical_address = cpu_to_le32(rsdt);
- /* Address to be filled by Guest linker */
- bios_linker_loader_add_pointer(linker, ACPI_BUILD_RSDP_FILE,
- ACPI_BUILD_TABLE_FILE,
- rsdp_table, &rsdp->rsdt_physical_address,
- sizeof rsdp->rsdt_physical_address);
- rsdp->checksum = 0;
- /* Checksum to be filled by Guest linker */
- bios_linker_loader_add_checksum(linker, ACPI_BUILD_RSDP_FILE,
- rsdp_table, rsdp, sizeof *rsdp,
- &rsdp->checksum);
-
- return rsdp_table;
-}
-
-static void
-build_spcr(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info)
-{
- AcpiSerialPortConsoleRedirection *spcr;
- const MemMapEntry *uart_memmap = &guest_info->memmap[VIRT_UART];
- int irq = guest_info->irqmap[VIRT_UART] + ARM_SPI_BASE;
-
- spcr = acpi_data_push(table_data, sizeof(*spcr));
-
- spcr->interface_type = 0x3; /* ARM PL011 UART */
-
- spcr->base_address.space_id = AML_SYSTEM_MEMORY;
- spcr->base_address.bit_width = 8;
- spcr->base_address.bit_offset = 0;
- spcr->base_address.access_width = 1;
- spcr->base_address.address = cpu_to_le64(uart_memmap->base);
-
- spcr->interrupt_types = (1 << 3); /* Bit[3] ARMH GIC interrupt */
- spcr->gsi = cpu_to_le32(irq); /* Global System Interrupt */
-
- spcr->baud = 3; /* Baud Rate: 3 = 9600 */
- spcr->parity = 0; /* No Parity */
- spcr->stopbits = 1; /* 1 Stop bit */
- spcr->flowctrl = (1 << 1); /* Bit[1] = RTS/CTS hardware flow control */
- spcr->term_type = 0; /* Terminal Type: 0 = VT100 */
-
- spcr->pci_device_id = 0xffff; /* PCI Device ID: not a PCI device */
- spcr->pci_vendor_id = 0xffff; /* PCI Vendor ID: not a PCI device */
-
- build_header(linker, table_data, (void *)spcr, "SPCR", sizeof(*spcr), 2,
- NULL, NULL);
-}
-
-static void
-build_mcfg(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info)
-{
- AcpiTableMcfg *mcfg;
- const MemMapEntry *memmap = guest_info->memmap;
- int len = sizeof(*mcfg) + sizeof(mcfg->allocation[0]);
-
- mcfg = acpi_data_push(table_data, len);
- mcfg->allocation[0].address = cpu_to_le64(memmap[VIRT_PCIE_ECAM].base);
-
- /* Only a single allocation so no need to play with segments */
- mcfg->allocation[0].pci_segment = cpu_to_le16(0);
- mcfg->allocation[0].start_bus_number = 0;
- mcfg->allocation[0].end_bus_number = (memmap[VIRT_PCIE_ECAM].size
- / PCIE_MMCFG_SIZE_MIN) - 1;
-
- build_header(linker, table_data, (void *)mcfg, "MCFG", len, 1, NULL, NULL);
-}
-
-/* GTDT */
-static void
-build_gtdt(GArray *table_data, GArray *linker)
-{
- int gtdt_start = table_data->len;
- AcpiGenericTimerTable *gtdt;
-
- gtdt = acpi_data_push(table_data, sizeof *gtdt);
- /* The interrupt values are the same with the device tree when adding 16 */
- gtdt->secure_el1_interrupt = ARCH_TIMER_S_EL1_IRQ + 16;
- gtdt->secure_el1_flags = ACPI_EDGE_SENSITIVE;
-
- gtdt->non_secure_el1_interrupt = ARCH_TIMER_NS_EL1_IRQ + 16;
- gtdt->non_secure_el1_flags = ACPI_EDGE_SENSITIVE | ACPI_GTDT_ALWAYS_ON;
-
- gtdt->virtual_timer_interrupt = ARCH_TIMER_VIRT_IRQ + 16;
- gtdt->virtual_timer_flags = ACPI_EDGE_SENSITIVE;
-
- gtdt->non_secure_el2_interrupt = ARCH_TIMER_NS_EL2_IRQ + 16;
- gtdt->non_secure_el2_flags = ACPI_EDGE_SENSITIVE;
-
- build_header(linker, table_data,
- (void *)(table_data->data + gtdt_start), "GTDT",
- table_data->len - gtdt_start, 2, NULL, NULL);
-}
-
-/* MADT */
-static void
-build_madt(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info)
-{
- int madt_start = table_data->len;
- const MemMapEntry *memmap = guest_info->memmap;
- const int *irqmap = guest_info->irqmap;
- AcpiMultipleApicTable *madt;
- AcpiMadtGenericDistributor *gicd;
- AcpiMadtGenericMsiFrame *gic_msi;
- int i;
-
- madt = acpi_data_push(table_data, sizeof *madt);
-
- gicd = acpi_data_push(table_data, sizeof *gicd);
- gicd->type = ACPI_APIC_GENERIC_DISTRIBUTOR;
- gicd->length = sizeof(*gicd);
- gicd->base_address = memmap[VIRT_GIC_DIST].base;
-
- for (i = 0; i < guest_info->smp_cpus; i++) {
- AcpiMadtGenericInterrupt *gicc = acpi_data_push(table_data,
- sizeof *gicc);
- ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(i));
-
- gicc->type = ACPI_APIC_GENERIC_INTERRUPT;
- gicc->length = sizeof(*gicc);
- if (guest_info->gic_version == 2) {
- gicc->base_address = memmap[VIRT_GIC_CPU].base;
- }
- gicc->cpu_interface_number = i;
- gicc->arm_mpidr = armcpu->mp_affinity;
- gicc->uid = i;
- gicc->flags = cpu_to_le32(ACPI_GICC_ENABLED);
- }
-
- if (guest_info->gic_version == 3) {
- AcpiMadtGenericRedistributor *gicr = acpi_data_push(table_data,
- sizeof *gicr);
-
- gicr->type = ACPI_APIC_GENERIC_REDISTRIBUTOR;
- gicr->length = sizeof(*gicr);
- gicr->base_address = cpu_to_le64(memmap[VIRT_GIC_REDIST].base);
- gicr->range_length = cpu_to_le32(memmap[VIRT_GIC_REDIST].size);
- } else {
- gic_msi = acpi_data_push(table_data, sizeof *gic_msi);
- gic_msi->type = ACPI_APIC_GENERIC_MSI_FRAME;
- gic_msi->length = sizeof(*gic_msi);
- gic_msi->gic_msi_frame_id = 0;
- gic_msi->base_address = cpu_to_le64(memmap[VIRT_GIC_V2M].base);
- gic_msi->flags = cpu_to_le32(1);
- gic_msi->spi_count = cpu_to_le16(NUM_GICV2M_SPIS);
- gic_msi->spi_base = cpu_to_le16(irqmap[VIRT_GIC_V2M] + ARM_SPI_BASE);
- }
-
- build_header(linker, table_data,
- (void *)(table_data->data + madt_start), "APIC",
- table_data->len - madt_start, 3, NULL, NULL);
-}
-
-/* FADT */
-static void
-build_fadt(GArray *table_data, GArray *linker, unsigned dsdt)
-{
- AcpiFadtDescriptorRev5_1 *fadt = acpi_data_push(table_data, sizeof(*fadt));
-
- /* Hardware Reduced = 1 and use PSCI 0.2+ and with HVC */
- fadt->flags = cpu_to_le32(1 << ACPI_FADT_F_HW_REDUCED_ACPI);
- fadt->arm_boot_flags = cpu_to_le16((1 << ACPI_FADT_ARM_USE_PSCI_G_0_2) |
- (1 << ACPI_FADT_ARM_PSCI_USE_HVC));
-
- /* ACPI v5.1 (fadt->revision.fadt->minor_revision) */
- fadt->minor_revision = 0x1;
-
- fadt->dsdt = cpu_to_le32(dsdt);
- /* DSDT address to be filled by Guest linker */
- bios_linker_loader_add_pointer(linker, ACPI_BUILD_TABLE_FILE,
- ACPI_BUILD_TABLE_FILE,
- table_data, &fadt->dsdt,
- sizeof fadt->dsdt);
-
- build_header(linker, table_data,
- (void *)fadt, "FACP", sizeof(*fadt), 5, NULL, NULL);
-}
-
-/* DSDT */
-static void
-build_dsdt(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info)
-{
- Aml *scope, *dsdt;
- const MemMapEntry *memmap = guest_info->memmap;
- const int *irqmap = guest_info->irqmap;
-
- dsdt = init_aml_allocator();
- /* Reserve space for header */
- acpi_data_push(dsdt->buf, sizeof(AcpiTableHeader));
-
- /* When booting the VM with UEFI, UEFI takes ownership of the RTC hardware.
- * While UEFI can use libfdt to disable the RTC device node in the DTB that
- * it passes to the OS, it cannot modify AML. Therefore, we won't generate
- * the RTC ACPI device at all when using UEFI.
- */
- scope = aml_scope("\\_SB");
- acpi_dsdt_add_cpus(scope, guest_info->smp_cpus);
- acpi_dsdt_add_uart(scope, &memmap[VIRT_UART],
- (irqmap[VIRT_UART] + ARM_SPI_BASE));
- acpi_dsdt_add_flash(scope, &memmap[VIRT_FLASH]);
- acpi_dsdt_add_fw_cfg(scope, &memmap[VIRT_FW_CFG]);
- acpi_dsdt_add_virtio(scope, &memmap[VIRT_MMIO],
- (irqmap[VIRT_MMIO] + ARM_SPI_BASE), NUM_VIRTIO_TRANSPORTS);
- acpi_dsdt_add_pci(scope, memmap, (irqmap[VIRT_PCIE] + ARM_SPI_BASE),
- guest_info->use_highmem);
- acpi_dsdt_add_gpio(scope, &memmap[VIRT_GPIO],
- (irqmap[VIRT_GPIO] + ARM_SPI_BASE));
- acpi_dsdt_add_power_button(scope);
-
- aml_append(dsdt, scope);
-
- /* copy AML table into ACPI tables blob and patch header there */
- g_array_append_vals(table_data, dsdt->buf->data, dsdt->buf->len);
- build_header(linker, table_data,
- (void *)(table_data->data + table_data->len - dsdt->buf->len),
- "DSDT", dsdt->buf->len, 2, NULL, NULL);
- free_aml_allocator();
-}
-
-typedef
-struct AcpiBuildState {
- /* Copy of table in RAM (for patching). */
- MemoryRegion *table_mr;
- MemoryRegion *rsdp_mr;
- MemoryRegion *linker_mr;
- /* Is table patched? */
- bool patched;
- VirtGuestInfo *guest_info;
-} AcpiBuildState;
-
-static
-void virt_acpi_build(VirtGuestInfo *guest_info, AcpiBuildTables *tables)
-{
- GArray *table_offsets;
- unsigned dsdt, rsdt;
- GArray *tables_blob = tables->table_data;
-
- table_offsets = g_array_new(false, true /* clear */,
- sizeof(uint32_t));
-
- bios_linker_loader_alloc(tables->linker, ACPI_BUILD_TABLE_FILE,
- 64, false /* high memory */);
-
- /*
- * The ACPI v5.1 tables for Hardware-reduced ACPI platform are:
- * RSDP
- * RSDT
- * FADT
- * GTDT
- * MADT
- * MCFG
- * DSDT
- */
-
- /* DSDT is pointed to by FADT */
- dsdt = tables_blob->len;
- build_dsdt(tables_blob, tables->linker, guest_info);
-
- /* FADT MADT GTDT MCFG SPCR pointed to by RSDT */
- acpi_add_table(table_offsets, tables_blob);
- build_fadt(tables_blob, tables->linker, dsdt);
-
- acpi_add_table(table_offsets, tables_blob);
- build_madt(tables_blob, tables->linker, guest_info);
-
- acpi_add_table(table_offsets, tables_blob);
- build_gtdt(tables_blob, tables->linker);
-
- acpi_add_table(table_offsets, tables_blob);
- build_mcfg(tables_blob, tables->linker, guest_info);
-
- acpi_add_table(table_offsets, tables_blob);
- build_spcr(tables_blob, tables->linker, guest_info);
-
- /* RSDT is pointed to by RSDP */
- rsdt = tables_blob->len;
- build_rsdt(tables_blob, tables->linker, table_offsets, NULL, NULL);
-
- /* RSDP is in FSEG memory, so allocate it separately */
- build_rsdp(tables->rsdp, tables->linker, rsdt);
-
- /* Cleanup memory that's no longer used. */
- g_array_free(table_offsets, true);
-}
-
-static void acpi_ram_update(MemoryRegion *mr, GArray *data)
-{
- uint32_t size = acpi_data_len(data);
-
- /* Make sure RAM size is correct - in case it got changed
- * e.g. by migration */
- memory_region_ram_resize(mr, size, &error_abort);
-
- memcpy(memory_region_get_ram_ptr(mr), data->data, size);
- memory_region_set_dirty(mr, 0, size);
-}
-
-static void virt_acpi_build_update(void *build_opaque)
-{
- AcpiBuildState *build_state = build_opaque;
- AcpiBuildTables tables;
-
- /* No state to update or already patched? Nothing to do. */
- if (!build_state || build_state->patched) {
- return;
- }
- build_state->patched = true;
-
- acpi_build_tables_init(&tables);
-
- virt_acpi_build(build_state->guest_info, &tables);
-
- acpi_ram_update(build_state->table_mr, tables.table_data);
- acpi_ram_update(build_state->rsdp_mr, tables.rsdp);
- acpi_ram_update(build_state->linker_mr, tables.linker);
-
-
- acpi_build_tables_cleanup(&tables, true);
-}
-
-static void virt_acpi_build_reset(void *build_opaque)
-{
- AcpiBuildState *build_state = build_opaque;
- build_state->patched = false;
-}
-
-static MemoryRegion *acpi_add_rom_blob(AcpiBuildState *build_state,
- GArray *blob, const char *name,
- uint64_t max_size)
-{
- return rom_add_blob(name, blob->data, acpi_data_len(blob), max_size, -1,
- name, virt_acpi_build_update, build_state);
-}
-
-static const VMStateDescription vmstate_virt_acpi_build = {
- .name = "virt_acpi_build",
- .version_id = 1,
- .minimum_version_id = 1,
- .fields = (VMStateField[]) {
- VMSTATE_BOOL(patched, AcpiBuildState),
- VMSTATE_END_OF_LIST()
- },
-};
-
-void virt_acpi_setup(VirtGuestInfo *guest_info)
-{
- AcpiBuildTables tables;
- AcpiBuildState *build_state;
-
- if (!guest_info->fw_cfg) {
- trace_virt_acpi_setup();
- return;
- }
-
- if (!acpi_enabled) {
- trace_virt_acpi_setup();
- return;
- }
-
- build_state = g_malloc0(sizeof *build_state);
- build_state->guest_info = guest_info;
-
- acpi_build_tables_init(&tables);
- virt_acpi_build(build_state->guest_info, &tables);
-
- /* Now expose it all to Guest */
- build_state->table_mr = acpi_add_rom_blob(build_state, tables.table_data,
- ACPI_BUILD_TABLE_FILE,
- ACPI_BUILD_TABLE_MAX_SIZE);
- assert(build_state->table_mr != NULL);
-
- build_state->linker_mr =
- acpi_add_rom_blob(build_state, tables.linker, "etc/table-loader", 0);
-
- fw_cfg_add_file(guest_info->fw_cfg, ACPI_BUILD_TPMLOG_FILE,
- tables.tcpalog->data, acpi_data_len(tables.tcpalog));
-
- build_state->rsdp_mr = acpi_add_rom_blob(build_state, tables.rsdp,
- ACPI_BUILD_RSDP_FILE, 0);
-
- qemu_register_reset(virt_acpi_build_reset, build_state);
- virt_acpi_build_reset(build_state);
- vmstate_register(NULL, 0, &vmstate_virt_acpi_build, build_state);
-
- /* Cleanup tables but don't free the memory: we track it
- * in build_state.
- */
- acpi_build_tables_cleanup(&tables, false);
-}
diff --git a/qemu/hw/arm/virt.c b/qemu/hw/arm/virt.c
deleted file mode 100644
index 56d35c771..000000000
--- a/qemu/hw/arm/virt.c
+++ /dev/null
@@ -1,1435 +0,0 @@
-/*
- * ARM mach-virt emulation
- *
- * Copyright (c) 2013 Linaro Limited
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2 or later, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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/>.
- *
- * Emulate a virtual board which works by passing Linux all the information
- * it needs about what devices are present via the device tree.
- * There are some restrictions about what we can do here:
- * + we can only present devices whose Linux drivers will work based
- * purely on the device tree with no platform data at all
- * + we want to present a very stripped-down minimalist platform,
- * both because this reduces the security attack surface from the guest
- * and also because it reduces our exposure to being broken when
- * the kernel updates its device tree bindings and requires further
- * information in a device binding that we aren't providing.
- * This is essentially the same approach kvmtool uses.
- */
-
-#include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "hw/sysbus.h"
-#include "hw/arm/arm.h"
-#include "hw/arm/primecell.h"
-#include "hw/arm/virt.h"
-#include "hw/devices.h"
-#include "net/net.h"
-#include "sysemu/block-backend.h"
-#include "sysemu/device_tree.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/kvm.h"
-#include "hw/boards.h"
-#include "hw/loader.h"
-#include "exec/address-spaces.h"
-#include "qemu/bitops.h"
-#include "qemu/error-report.h"
-#include "hw/pci-host/gpex.h"
-#include "hw/arm/virt-acpi-build.h"
-#include "hw/arm/sysbus-fdt.h"
-#include "hw/platform-bus.h"
-#include "hw/arm/fdt.h"
-#include "hw/intc/arm_gic_common.h"
-#include "kvm_arm.h"
-#include "hw/smbios/smbios.h"
-#include "qapi/visitor.h"
-#include "standard-headers/linux/input.h"
-
-/* Number of external interrupt lines to configure the GIC with */
-#define NUM_IRQS 256
-
-#define PLATFORM_BUS_NUM_IRQS 64
-
-static ARMPlatformBusSystemParams platform_bus_params;
-
-typedef struct VirtBoardInfo {
- struct arm_boot_info bootinfo;
- const char *cpu_model;
- const MemMapEntry *memmap;
- const int *irqmap;
- int smp_cpus;
- void *fdt;
- int fdt_size;
- uint32_t clock_phandle;
- uint32_t gic_phandle;
- uint32_t v2m_phandle;
- bool using_psci;
-} VirtBoardInfo;
-
-typedef struct {
- MachineClass parent;
- VirtBoardInfo *daughterboard;
-} VirtMachineClass;
-
-typedef struct {
- MachineState parent;
- bool secure;
- bool highmem;
- int32_t gic_version;
-} VirtMachineState;
-
-#define TYPE_VIRT_MACHINE MACHINE_TYPE_NAME("virt")
-#define VIRT_MACHINE(obj) \
- OBJECT_CHECK(VirtMachineState, (obj), TYPE_VIRT_MACHINE)
-#define VIRT_MACHINE_GET_CLASS(obj) \
- OBJECT_GET_CLASS(VirtMachineClass, obj, TYPE_VIRT_MACHINE)
-#define VIRT_MACHINE_CLASS(klass) \
- OBJECT_CLASS_CHECK(VirtMachineClass, klass, TYPE_VIRT_MACHINE)
-
-/* RAM limit in GB. Since VIRT_MEM starts at the 1GB mark, this means
- * RAM can go up to the 256GB mark, leaving 256GB of the physical
- * address space unallocated and free for future use between 256G and 512G.
- * If we need to provide more RAM to VMs in the future then we need to:
- * * allocate a second bank of RAM starting at 2TB and working up
- * * fix the DT and ACPI table generation code in QEMU to correctly
- * report two split lumps of RAM to the guest
- * * fix KVM in the host kernel to allow guests with >40 bit address spaces
- * (We don't want to fill all the way up to 512GB with RAM because
- * we might want it for non-RAM purposes later. Conversely it seems
- * reasonable to assume that anybody configuring a VM with a quarter
- * of a terabyte of RAM will be doing it on a host with more than a
- * terabyte of physical address space.)
- */
-#define RAMLIMIT_GB 255
-#define RAMLIMIT_BYTES (RAMLIMIT_GB * 1024ULL * 1024 * 1024)
-
-/* Addresses and sizes of our components.
- * 0..128MB is space for a flash device so we can run bootrom code such as UEFI.
- * 128MB..256MB is used for miscellaneous device I/O.
- * 256MB..1GB is reserved for possible future PCI support (ie where the
- * PCI memory window will go if we add a PCI host controller).
- * 1GB and up is RAM (which may happily spill over into the
- * high memory region beyond 4GB).
- * This represents a compromise between how much RAM can be given to
- * a 32 bit VM and leaving space for expansion and in particular for PCI.
- * Note that devices should generally be placed at multiples of 0x10000,
- * to accommodate guests using 64K pages.
- */
-static const MemMapEntry a15memmap[] = {
- /* Space up to 0x8000000 is reserved for a boot ROM */
- [VIRT_FLASH] = { 0, 0x08000000 },
- [VIRT_CPUPERIPHS] = { 0x08000000, 0x00020000 },
- /* GIC distributor and CPU interfaces sit inside the CPU peripheral space */
- [VIRT_GIC_DIST] = { 0x08000000, 0x00010000 },
- [VIRT_GIC_CPU] = { 0x08010000, 0x00010000 },
- [VIRT_GIC_V2M] = { 0x08020000, 0x00001000 },
- /* The space in between here is reserved for GICv3 CPU/vCPU/HYP */
- [VIRT_GIC_ITS] = { 0x08080000, 0x00020000 },
- /* This redistributor space allows up to 2*64kB*123 CPUs */
- [VIRT_GIC_REDIST] = { 0x080A0000, 0x00F60000 },
- [VIRT_UART] = { 0x09000000, 0x00001000 },
- [VIRT_RTC] = { 0x09010000, 0x00001000 },
- [VIRT_FW_CFG] = { 0x09020000, 0x00000018 },
- [VIRT_GPIO] = { 0x09030000, 0x00001000 },
- [VIRT_SECURE_UART] = { 0x09040000, 0x00001000 },
- [VIRT_MMIO] = { 0x0a000000, 0x00000200 },
- /* ...repeating for a total of NUM_VIRTIO_TRANSPORTS, each of that size */
- [VIRT_PLATFORM_BUS] = { 0x0c000000, 0x02000000 },
- [VIRT_SECURE_MEM] = { 0x0e000000, 0x01000000 },
- [VIRT_PCIE_MMIO] = { 0x10000000, 0x2eff0000 },
- [VIRT_PCIE_PIO] = { 0x3eff0000, 0x00010000 },
- [VIRT_PCIE_ECAM] = { 0x3f000000, 0x01000000 },
- [VIRT_MEM] = { 0x40000000, RAMLIMIT_BYTES },
- /* Second PCIe window, 512GB wide at the 512GB boundary */
- [VIRT_PCIE_MMIO_HIGH] = { 0x8000000000ULL, 0x8000000000ULL },
-};
-
-static const int a15irqmap[] = {
- [VIRT_UART] = 1,
- [VIRT_RTC] = 2,
- [VIRT_PCIE] = 3, /* ... to 6 */
- [VIRT_GPIO] = 7,
- [VIRT_SECURE_UART] = 8,
- [VIRT_MMIO] = 16, /* ...to 16 + NUM_VIRTIO_TRANSPORTS - 1 */
- [VIRT_GIC_V2M] = 48, /* ...to 48 + NUM_GICV2M_SPIS - 1 */
- [VIRT_PLATFORM_BUS] = 112, /* ...to 112 + PLATFORM_BUS_NUM_IRQS -1 */
-};
-
-static VirtBoardInfo machines[] = {
- {
- .cpu_model = "cortex-a15",
- .memmap = a15memmap,
- .irqmap = a15irqmap,
- },
- {
- .cpu_model = "cortex-a53",
- .memmap = a15memmap,
- .irqmap = a15irqmap,
- },
- {
- .cpu_model = "cortex-a57",
- .memmap = a15memmap,
- .irqmap = a15irqmap,
- },
- {
- .cpu_model = "host",
- .memmap = a15memmap,
- .irqmap = a15irqmap,
- },
-};
-
-static VirtBoardInfo *find_machine_info(const char *cpu)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(machines); i++) {
- if (strcmp(cpu, machines[i].cpu_model) == 0) {
- return &machines[i];
- }
- }
- return NULL;
-}
-
-static void create_fdt(VirtBoardInfo *vbi)
-{
- void *fdt = create_device_tree(&vbi->fdt_size);
-
- if (!fdt) {
- error_report("create_device_tree() failed");
- exit(1);
- }
-
- vbi->fdt = fdt;
-
- /* Header */
- qemu_fdt_setprop_string(fdt, "/", "compatible", "linux,dummy-virt");
- qemu_fdt_setprop_cell(fdt, "/", "#address-cells", 0x2);
- qemu_fdt_setprop_cell(fdt, "/", "#size-cells", 0x2);
-
- /*
- * /chosen and /memory nodes must exist for load_dtb
- * to fill in necessary properties later
- */
- qemu_fdt_add_subnode(fdt, "/chosen");
- qemu_fdt_add_subnode(fdt, "/memory");
- qemu_fdt_setprop_string(fdt, "/memory", "device_type", "memory");
-
- /* Clock node, for the benefit of the UART. The kernel device tree
- * binding documentation claims the PL011 node clock properties are
- * optional but in practice if you omit them the kernel refuses to
- * probe for the device.
- */
- vbi->clock_phandle = qemu_fdt_alloc_phandle(fdt);
- qemu_fdt_add_subnode(fdt, "/apb-pclk");
- qemu_fdt_setprop_string(fdt, "/apb-pclk", "compatible", "fixed-clock");
- qemu_fdt_setprop_cell(fdt, "/apb-pclk", "#clock-cells", 0x0);
- qemu_fdt_setprop_cell(fdt, "/apb-pclk", "clock-frequency", 24000000);
- qemu_fdt_setprop_string(fdt, "/apb-pclk", "clock-output-names",
- "clk24mhz");
- qemu_fdt_setprop_cell(fdt, "/apb-pclk", "phandle", vbi->clock_phandle);
-
-}
-
-static void fdt_add_psci_node(const VirtBoardInfo *vbi)
-{
- uint32_t cpu_suspend_fn;
- uint32_t cpu_off_fn;
- uint32_t cpu_on_fn;
- uint32_t migrate_fn;
- void *fdt = vbi->fdt;
- ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(0));
-
- if (!vbi->using_psci) {
- return;
- }
-
- qemu_fdt_add_subnode(fdt, "/psci");
- if (armcpu->psci_version == 2) {
- const char comp[] = "arm,psci-0.2\0arm,psci";
- qemu_fdt_setprop(fdt, "/psci", "compatible", comp, sizeof(comp));
-
- cpu_off_fn = QEMU_PSCI_0_2_FN_CPU_OFF;
- if (arm_feature(&armcpu->env, ARM_FEATURE_AARCH64)) {
- cpu_suspend_fn = QEMU_PSCI_0_2_FN64_CPU_SUSPEND;
- cpu_on_fn = QEMU_PSCI_0_2_FN64_CPU_ON;
- migrate_fn = QEMU_PSCI_0_2_FN64_MIGRATE;
- } else {
- cpu_suspend_fn = QEMU_PSCI_0_2_FN_CPU_SUSPEND;
- cpu_on_fn = QEMU_PSCI_0_2_FN_CPU_ON;
- migrate_fn = QEMU_PSCI_0_2_FN_MIGRATE;
- }
- } else {
- qemu_fdt_setprop_string(fdt, "/psci", "compatible", "arm,psci");
-
- cpu_suspend_fn = QEMU_PSCI_0_1_FN_CPU_SUSPEND;
- cpu_off_fn = QEMU_PSCI_0_1_FN_CPU_OFF;
- cpu_on_fn = QEMU_PSCI_0_1_FN_CPU_ON;
- migrate_fn = QEMU_PSCI_0_1_FN_MIGRATE;
- }
-
- /* We adopt the PSCI spec's nomenclature, and use 'conduit' to refer
- * to the instruction that should be used to invoke PSCI functions.
- * However, the device tree binding uses 'method' instead, so that is
- * what we should use here.
- */
- qemu_fdt_setprop_string(fdt, "/psci", "method", "hvc");
-
- qemu_fdt_setprop_cell(fdt, "/psci", "cpu_suspend", cpu_suspend_fn);
- qemu_fdt_setprop_cell(fdt, "/psci", "cpu_off", cpu_off_fn);
- qemu_fdt_setprop_cell(fdt, "/psci", "cpu_on", cpu_on_fn);
- qemu_fdt_setprop_cell(fdt, "/psci", "migrate", migrate_fn);
-}
-
-static void fdt_add_timer_nodes(const VirtBoardInfo *vbi, int gictype)
-{
- /* Note that on A15 h/w these interrupts are level-triggered,
- * but for the GIC implementation provided by both QEMU and KVM
- * they are edge-triggered.
- */
- ARMCPU *armcpu;
- uint32_t irqflags = GIC_FDT_IRQ_FLAGS_EDGE_LO_HI;
-
- if (gictype == 2) {
- irqflags = deposit32(irqflags, GIC_FDT_IRQ_PPI_CPU_START,
- GIC_FDT_IRQ_PPI_CPU_WIDTH,
- (1 << vbi->smp_cpus) - 1);
- }
-
- qemu_fdt_add_subnode(vbi->fdt, "/timer");
-
- armcpu = ARM_CPU(qemu_get_cpu(0));
- if (arm_feature(&armcpu->env, ARM_FEATURE_V8)) {
- const char compat[] = "arm,armv8-timer\0arm,armv7-timer";
- qemu_fdt_setprop(vbi->fdt, "/timer", "compatible",
- compat, sizeof(compat));
- } else {
- qemu_fdt_setprop_string(vbi->fdt, "/timer", "compatible",
- "arm,armv7-timer");
- }
- qemu_fdt_setprop(vbi->fdt, "/timer", "always-on", NULL, 0);
- qemu_fdt_setprop_cells(vbi->fdt, "/timer", "interrupts",
- GIC_FDT_IRQ_TYPE_PPI, ARCH_TIMER_S_EL1_IRQ, irqflags,
- GIC_FDT_IRQ_TYPE_PPI, ARCH_TIMER_NS_EL1_IRQ, irqflags,
- GIC_FDT_IRQ_TYPE_PPI, ARCH_TIMER_VIRT_IRQ, irqflags,
- GIC_FDT_IRQ_TYPE_PPI, ARCH_TIMER_NS_EL2_IRQ, irqflags);
-}
-
-static void fdt_add_cpu_nodes(const VirtBoardInfo *vbi)
-{
- int cpu;
- int addr_cells = 1;
-
- /*
- * From Documentation/devicetree/bindings/arm/cpus.txt
- * On ARM v8 64-bit systems value should be set to 2,
- * that corresponds to the MPIDR_EL1 register size.
- * If MPIDR_EL1[63:32] value is equal to 0 on all CPUs
- * in the system, #address-cells can be set to 1, since
- * MPIDR_EL1[63:32] bits are not used for CPUs
- * identification.
- *
- * Here we actually don't know whether our system is 32- or 64-bit one.
- * The simplest way to go is to examine affinity IDs of all our CPUs. If
- * at least one of them has Aff3 populated, we set #address-cells to 2.
- */
- for (cpu = 0; cpu < vbi->smp_cpus; cpu++) {
- ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(cpu));
-
- if (armcpu->mp_affinity & ARM_AFF3_MASK) {
- addr_cells = 2;
- break;
- }
- }
-
- qemu_fdt_add_subnode(vbi->fdt, "/cpus");
- qemu_fdt_setprop_cell(vbi->fdt, "/cpus", "#address-cells", addr_cells);
- qemu_fdt_setprop_cell(vbi->fdt, "/cpus", "#size-cells", 0x0);
-
- for (cpu = vbi->smp_cpus - 1; cpu >= 0; cpu--) {
- char *nodename = g_strdup_printf("/cpus/cpu@%d", cpu);
- ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(cpu));
-
- qemu_fdt_add_subnode(vbi->fdt, nodename);
- qemu_fdt_setprop_string(vbi->fdt, nodename, "device_type", "cpu");
- qemu_fdt_setprop_string(vbi->fdt, nodename, "compatible",
- armcpu->dtb_compatible);
-
- if (vbi->using_psci && vbi->smp_cpus > 1) {
- qemu_fdt_setprop_string(vbi->fdt, nodename,
- "enable-method", "psci");
- }
-
- if (addr_cells == 2) {
- qemu_fdt_setprop_u64(vbi->fdt, nodename, "reg",
- armcpu->mp_affinity);
- } else {
- qemu_fdt_setprop_cell(vbi->fdt, nodename, "reg",
- armcpu->mp_affinity);
- }
-
- g_free(nodename);
- }
-}
-
-static void fdt_add_v2m_gic_node(VirtBoardInfo *vbi)
-{
- vbi->v2m_phandle = qemu_fdt_alloc_phandle(vbi->fdt);
- qemu_fdt_add_subnode(vbi->fdt, "/intc/v2m");
- qemu_fdt_setprop_string(vbi->fdt, "/intc/v2m", "compatible",
- "arm,gic-v2m-frame");
- qemu_fdt_setprop(vbi->fdt, "/intc/v2m", "msi-controller", NULL, 0);
- qemu_fdt_setprop_sized_cells(vbi->fdt, "/intc/v2m", "reg",
- 2, vbi->memmap[VIRT_GIC_V2M].base,
- 2, vbi->memmap[VIRT_GIC_V2M].size);
- qemu_fdt_setprop_cell(vbi->fdt, "/intc/v2m", "phandle", vbi->v2m_phandle);
-}
-
-static void fdt_add_gic_node(VirtBoardInfo *vbi, int type)
-{
- vbi->gic_phandle = qemu_fdt_alloc_phandle(vbi->fdt);
- qemu_fdt_setprop_cell(vbi->fdt, "/", "interrupt-parent", vbi->gic_phandle);
-
- qemu_fdt_add_subnode(vbi->fdt, "/intc");
- qemu_fdt_setprop_cell(vbi->fdt, "/intc", "#interrupt-cells", 3);
- qemu_fdt_setprop(vbi->fdt, "/intc", "interrupt-controller", NULL, 0);
- qemu_fdt_setprop_cell(vbi->fdt, "/intc", "#address-cells", 0x2);
- qemu_fdt_setprop_cell(vbi->fdt, "/intc", "#size-cells", 0x2);
- qemu_fdt_setprop(vbi->fdt, "/intc", "ranges", NULL, 0);
- if (type == 3) {
- qemu_fdt_setprop_string(vbi->fdt, "/intc", "compatible",
- "arm,gic-v3");
- qemu_fdt_setprop_sized_cells(vbi->fdt, "/intc", "reg",
- 2, vbi->memmap[VIRT_GIC_DIST].base,
- 2, vbi->memmap[VIRT_GIC_DIST].size,
- 2, vbi->memmap[VIRT_GIC_REDIST].base,
- 2, vbi->memmap[VIRT_GIC_REDIST].size);
- } else {
- /* 'cortex-a15-gic' means 'GIC v2' */
- qemu_fdt_setprop_string(vbi->fdt, "/intc", "compatible",
- "arm,cortex-a15-gic");
- qemu_fdt_setprop_sized_cells(vbi->fdt, "/intc", "reg",
- 2, vbi->memmap[VIRT_GIC_DIST].base,
- 2, vbi->memmap[VIRT_GIC_DIST].size,
- 2, vbi->memmap[VIRT_GIC_CPU].base,
- 2, vbi->memmap[VIRT_GIC_CPU].size);
- }
-
- qemu_fdt_setprop_cell(vbi->fdt, "/intc", "phandle", vbi->gic_phandle);
-}
-
-static void create_v2m(VirtBoardInfo *vbi, qemu_irq *pic)
-{
- int i;
- int irq = vbi->irqmap[VIRT_GIC_V2M];
- DeviceState *dev;
-
- dev = qdev_create(NULL, "arm-gicv2m");
- sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, vbi->memmap[VIRT_GIC_V2M].base);
- qdev_prop_set_uint32(dev, "base-spi", irq);
- qdev_prop_set_uint32(dev, "num-spi", NUM_GICV2M_SPIS);
- qdev_init_nofail(dev);
-
- for (i = 0; i < NUM_GICV2M_SPIS; i++) {
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, pic[irq + i]);
- }
-
- fdt_add_v2m_gic_node(vbi);
-}
-
-static void create_gic(VirtBoardInfo *vbi, qemu_irq *pic, int type, bool secure)
-{
- /* We create a standalone GIC */
- DeviceState *gicdev;
- SysBusDevice *gicbusdev;
- const char *gictype;
- int i;
-
- gictype = (type == 3) ? gicv3_class_name() : gic_class_name();
-
- gicdev = qdev_create(NULL, gictype);
- qdev_prop_set_uint32(gicdev, "revision", type);
- qdev_prop_set_uint32(gicdev, "num-cpu", smp_cpus);
- /* Note that the num-irq property counts both internal and external
- * interrupts; there are always 32 of the former (mandated by GIC spec).
- */
- qdev_prop_set_uint32(gicdev, "num-irq", NUM_IRQS + 32);
- if (!kvm_irqchip_in_kernel()) {
- qdev_prop_set_bit(gicdev, "has-security-extensions", secure);
- }
- qdev_init_nofail(gicdev);
- gicbusdev = SYS_BUS_DEVICE(gicdev);
- sysbus_mmio_map(gicbusdev, 0, vbi->memmap[VIRT_GIC_DIST].base);
- if (type == 3) {
- sysbus_mmio_map(gicbusdev, 1, vbi->memmap[VIRT_GIC_REDIST].base);
- } else {
- sysbus_mmio_map(gicbusdev, 1, vbi->memmap[VIRT_GIC_CPU].base);
- }
-
- /* Wire the outputs from each CPU's generic timer to the
- * appropriate GIC PPI inputs, and the GIC's IRQ output to
- * the CPU's IRQ input.
- */
- for (i = 0; i < smp_cpus; i++) {
- DeviceState *cpudev = DEVICE(qemu_get_cpu(i));
- int ppibase = NUM_IRQS + i * GIC_INTERNAL + GIC_NR_SGIS;
- int irq;
- /* Mapping from the output timer irq lines from the CPU to the
- * GIC PPI inputs we use for the virt board.
- */
- const int timer_irq[] = {
- [GTIMER_PHYS] = ARCH_TIMER_NS_EL1_IRQ,
- [GTIMER_VIRT] = ARCH_TIMER_VIRT_IRQ,
- [GTIMER_HYP] = ARCH_TIMER_NS_EL2_IRQ,
- [GTIMER_SEC] = ARCH_TIMER_S_EL1_IRQ,
- };
-
- for (irq = 0; irq < ARRAY_SIZE(timer_irq); irq++) {
- qdev_connect_gpio_out(cpudev, irq,
- qdev_get_gpio_in(gicdev,
- ppibase + timer_irq[irq]));
- }
-
- sysbus_connect_irq(gicbusdev, i, qdev_get_gpio_in(cpudev, ARM_CPU_IRQ));
- sysbus_connect_irq(gicbusdev, i + smp_cpus,
- qdev_get_gpio_in(cpudev, ARM_CPU_FIQ));
- }
-
- for (i = 0; i < NUM_IRQS; i++) {
- pic[i] = qdev_get_gpio_in(gicdev, i);
- }
-
- fdt_add_gic_node(vbi, type);
-
- if (type == 2) {
- create_v2m(vbi, pic);
- }
-}
-
-static void create_uart(const VirtBoardInfo *vbi, qemu_irq *pic, int uart,
- MemoryRegion *mem)
-{
- char *nodename;
- hwaddr base = vbi->memmap[uart].base;
- hwaddr size = vbi->memmap[uart].size;
- int irq = vbi->irqmap[uart];
- const char compat[] = "arm,pl011\0arm,primecell";
- const char clocknames[] = "uartclk\0apb_pclk";
- DeviceState *dev = qdev_create(NULL, "pl011");
- SysBusDevice *s = SYS_BUS_DEVICE(dev);
-
- qdev_init_nofail(dev);
- memory_region_add_subregion(mem, base,
- sysbus_mmio_get_region(s, 0));
- sysbus_connect_irq(s, 0, pic[irq]);
-
- nodename = g_strdup_printf("/pl011@%" PRIx64, base);
- qemu_fdt_add_subnode(vbi->fdt, nodename);
- /* Note that we can't use setprop_string because of the embedded NUL */
- qemu_fdt_setprop(vbi->fdt, nodename, "compatible",
- compat, sizeof(compat));
- qemu_fdt_setprop_sized_cells(vbi->fdt, nodename, "reg",
- 2, base, 2, size);
- qemu_fdt_setprop_cells(vbi->fdt, nodename, "interrupts",
- GIC_FDT_IRQ_TYPE_SPI, irq,
- GIC_FDT_IRQ_FLAGS_LEVEL_HI);
- qemu_fdt_setprop_cells(vbi->fdt, nodename, "clocks",
- vbi->clock_phandle, vbi->clock_phandle);
- qemu_fdt_setprop(vbi->fdt, nodename, "clock-names",
- clocknames, sizeof(clocknames));
-
- if (uart == VIRT_UART) {
- qemu_fdt_setprop_string(vbi->fdt, "/chosen", "stdout-path", nodename);
- } else {
- /* Mark as not usable by the normal world */
- qemu_fdt_setprop_string(vbi->fdt, nodename, "status", "disabled");
- qemu_fdt_setprop_string(vbi->fdt, nodename, "secure-status", "okay");
- }
-
- g_free(nodename);
-}
-
-static void create_rtc(const VirtBoardInfo *vbi, qemu_irq *pic)
-{
- char *nodename;
- hwaddr base = vbi->memmap[VIRT_RTC].base;
- hwaddr size = vbi->memmap[VIRT_RTC].size;
- int irq = vbi->irqmap[VIRT_RTC];
- const char compat[] = "arm,pl031\0arm,primecell";
-
- sysbus_create_simple("pl031", base, pic[irq]);
-
- nodename = g_strdup_printf("/pl031@%" PRIx64, base);
- qemu_fdt_add_subnode(vbi->fdt, nodename);
- qemu_fdt_setprop(vbi->fdt, nodename, "compatible", compat, sizeof(compat));
- qemu_fdt_setprop_sized_cells(vbi->fdt, nodename, "reg",
- 2, base, 2, size);
- qemu_fdt_setprop_cells(vbi->fdt, nodename, "interrupts",
- GIC_FDT_IRQ_TYPE_SPI, irq,
- GIC_FDT_IRQ_FLAGS_LEVEL_HI);
- qemu_fdt_setprop_cell(vbi->fdt, nodename, "clocks", vbi->clock_phandle);
- qemu_fdt_setprop_string(vbi->fdt, nodename, "clock-names", "apb_pclk");
- g_free(nodename);
-}
-
-static DeviceState *gpio_key_dev;
-static void virt_powerdown_req(Notifier *n, void *opaque)
-{
- /* use gpio Pin 3 for power button event */
- qemu_set_irq(qdev_get_gpio_in(gpio_key_dev, 0), 1);
-}
-
-static Notifier virt_system_powerdown_notifier = {
- .notify = virt_powerdown_req
-};
-
-static void create_gpio(const VirtBoardInfo *vbi, qemu_irq *pic)
-{
- char *nodename;
- DeviceState *pl061_dev;
- hwaddr base = vbi->memmap[VIRT_GPIO].base;
- hwaddr size = vbi->memmap[VIRT_GPIO].size;
- int irq = vbi->irqmap[VIRT_GPIO];
- const char compat[] = "arm,pl061\0arm,primecell";
-
- pl061_dev = sysbus_create_simple("pl061", base, pic[irq]);
-
- uint32_t phandle = qemu_fdt_alloc_phandle(vbi->fdt);
- nodename = g_strdup_printf("/pl061@%" PRIx64, base);
- qemu_fdt_add_subnode(vbi->fdt, nodename);
- qemu_fdt_setprop_sized_cells(vbi->fdt, nodename, "reg",
- 2, base, 2, size);
- qemu_fdt_setprop(vbi->fdt, nodename, "compatible", compat, sizeof(compat));
- qemu_fdt_setprop_cell(vbi->fdt, nodename, "#gpio-cells", 2);
- qemu_fdt_setprop(vbi->fdt, nodename, "gpio-controller", NULL, 0);
- qemu_fdt_setprop_cells(vbi->fdt, nodename, "interrupts",
- GIC_FDT_IRQ_TYPE_SPI, irq,
- GIC_FDT_IRQ_FLAGS_LEVEL_HI);
- qemu_fdt_setprop_cell(vbi->fdt, nodename, "clocks", vbi->clock_phandle);
- qemu_fdt_setprop_string(vbi->fdt, nodename, "clock-names", "apb_pclk");
- qemu_fdt_setprop_cell(vbi->fdt, nodename, "phandle", phandle);
-
- gpio_key_dev = sysbus_create_simple("gpio-key", -1,
- qdev_get_gpio_in(pl061_dev, 3));
- qemu_fdt_add_subnode(vbi->fdt, "/gpio-keys");
- qemu_fdt_setprop_string(vbi->fdt, "/gpio-keys", "compatible", "gpio-keys");
- qemu_fdt_setprop_cell(vbi->fdt, "/gpio-keys", "#size-cells", 0);
- qemu_fdt_setprop_cell(vbi->fdt, "/gpio-keys", "#address-cells", 1);
-
- qemu_fdt_add_subnode(vbi->fdt, "/gpio-keys/poweroff");
- qemu_fdt_setprop_string(vbi->fdt, "/gpio-keys/poweroff",
- "label", "GPIO Key Poweroff");
- qemu_fdt_setprop_cell(vbi->fdt, "/gpio-keys/poweroff", "linux,code",
- KEY_POWER);
- qemu_fdt_setprop_cells(vbi->fdt, "/gpio-keys/poweroff",
- "gpios", phandle, 3, 0);
-
- /* connect powerdown request */
- qemu_register_powerdown_notifier(&virt_system_powerdown_notifier);
-
- g_free(nodename);
-}
-
-static void create_virtio_devices(const VirtBoardInfo *vbi, qemu_irq *pic)
-{
- int i;
- hwaddr size = vbi->memmap[VIRT_MMIO].size;
-
- /* We create the transports in forwards order. Since qbus_realize()
- * prepends (not appends) new child buses, the incrementing loop below will
- * create a list of virtio-mmio buses with decreasing base addresses.
- *
- * When a -device option is processed from the command line,
- * qbus_find_recursive() picks the next free virtio-mmio bus in forwards
- * order. The upshot is that -device options in increasing command line
- * order are mapped to virtio-mmio buses with decreasing base addresses.
- *
- * When this code was originally written, that arrangement ensured that the
- * guest Linux kernel would give the lowest "name" (/dev/vda, eth0, etc) to
- * the first -device on the command line. (The end-to-end order is a
- * function of this loop, qbus_realize(), qbus_find_recursive(), and the
- * guest kernel's name-to-address assignment strategy.)
- *
- * Meanwhile, the kernel's traversal seems to have been reversed; see eg.
- * the message, if not necessarily the code, of commit 70161ff336.
- * Therefore the loop now establishes the inverse of the original intent.
- *
- * Unfortunately, we can't counteract the kernel change by reversing the
- * loop; it would break existing command lines.
- *
- * In any case, the kernel makes no guarantee about the stability of
- * enumeration order of virtio devices (as demonstrated by it changing
- * between kernel versions). For reliable and stable identification
- * of disks users must use UUIDs or similar mechanisms.
- */
- for (i = 0; i < NUM_VIRTIO_TRANSPORTS; i++) {
- int irq = vbi->irqmap[VIRT_MMIO] + i;
- hwaddr base = vbi->memmap[VIRT_MMIO].base + i * size;
-
- sysbus_create_simple("virtio-mmio", base, pic[irq]);
- }
-
- /* We add dtb nodes in reverse order so that they appear in the finished
- * device tree lowest address first.
- *
- * Note that this mapping is independent of the loop above. The previous
- * loop influences virtio device to virtio transport assignment, whereas
- * this loop controls how virtio transports are laid out in the dtb.
- */
- for (i = NUM_VIRTIO_TRANSPORTS - 1; i >= 0; i--) {
- char *nodename;
- int irq = vbi->irqmap[VIRT_MMIO] + i;
- hwaddr base = vbi->memmap[VIRT_MMIO].base + i * size;
-
- nodename = g_strdup_printf("/virtio_mmio@%" PRIx64, base);
- qemu_fdt_add_subnode(vbi->fdt, nodename);
- qemu_fdt_setprop_string(vbi->fdt, nodename,
- "compatible", "virtio,mmio");
- qemu_fdt_setprop_sized_cells(vbi->fdt, nodename, "reg",
- 2, base, 2, size);
- qemu_fdt_setprop_cells(vbi->fdt, nodename, "interrupts",
- GIC_FDT_IRQ_TYPE_SPI, irq,
- GIC_FDT_IRQ_FLAGS_EDGE_LO_HI);
- g_free(nodename);
- }
-}
-
-static void create_one_flash(const char *name, hwaddr flashbase,
- hwaddr flashsize, const char *file,
- MemoryRegion *sysmem)
-{
- /* Create and map a single flash device. We use the same
- * parameters as the flash devices on the Versatile Express board.
- */
- DriveInfo *dinfo = drive_get_next(IF_PFLASH);
- DeviceState *dev = qdev_create(NULL, "cfi.pflash01");
- SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
- const uint64_t sectorlength = 256 * 1024;
-
- if (dinfo) {
- qdev_prop_set_drive(dev, "drive", blk_by_legacy_dinfo(dinfo),
- &error_abort);
- }
-
- qdev_prop_set_uint32(dev, "num-blocks", flashsize / sectorlength);
- qdev_prop_set_uint64(dev, "sector-length", sectorlength);
- qdev_prop_set_uint8(dev, "width", 4);
- qdev_prop_set_uint8(dev, "device-width", 2);
- qdev_prop_set_bit(dev, "big-endian", false);
- qdev_prop_set_uint16(dev, "id0", 0x89);
- qdev_prop_set_uint16(dev, "id1", 0x18);
- qdev_prop_set_uint16(dev, "id2", 0x00);
- qdev_prop_set_uint16(dev, "id3", 0x00);
- qdev_prop_set_string(dev, "name", name);
- qdev_init_nofail(dev);
-
- memory_region_add_subregion(sysmem, flashbase,
- sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0));
-
- if (file) {
- char *fn;
- int image_size;
-
- if (drive_get(IF_PFLASH, 0, 0)) {
- error_report("The contents of the first flash device may be "
- "specified with -bios or with -drive if=pflash... "
- "but you cannot use both options at once");
- exit(1);
- }
- fn = qemu_find_file(QEMU_FILE_TYPE_BIOS, file);
- if (!fn) {
- error_report("Could not find ROM image '%s'", file);
- exit(1);
- }
- image_size = load_image_mr(fn, sysbus_mmio_get_region(sbd, 0));
- g_free(fn);
- if (image_size < 0) {
- error_report("Could not load ROM image '%s'", file);
- exit(1);
- }
- }
-}
-
-static void create_flash(const VirtBoardInfo *vbi,
- MemoryRegion *sysmem,
- MemoryRegion *secure_sysmem)
-{
- /* Create two flash devices to fill the VIRT_FLASH space in the memmap.
- * Any file passed via -bios goes in the first of these.
- * sysmem is the system memory space. secure_sysmem is the secure view
- * of the system, and the first flash device should be made visible only
- * there. The second flash device is visible to both secure and nonsecure.
- * If sysmem == secure_sysmem this means there is no separate Secure
- * address space and both flash devices are generally visible.
- */
- hwaddr flashsize = vbi->memmap[VIRT_FLASH].size / 2;
- hwaddr flashbase = vbi->memmap[VIRT_FLASH].base;
- char *nodename;
-
- create_one_flash("virt.flash0", flashbase, flashsize,
- bios_name, secure_sysmem);
- create_one_flash("virt.flash1", flashbase + flashsize, flashsize,
- NULL, sysmem);
-
- if (sysmem == secure_sysmem) {
- /* Report both flash devices as a single node in the DT */
- nodename = g_strdup_printf("/flash@%" PRIx64, flashbase);
- qemu_fdt_add_subnode(vbi->fdt, nodename);
- qemu_fdt_setprop_string(vbi->fdt, nodename, "compatible", "cfi-flash");
- qemu_fdt_setprop_sized_cells(vbi->fdt, nodename, "reg",
- 2, flashbase, 2, flashsize,
- 2, flashbase + flashsize, 2, flashsize);
- qemu_fdt_setprop_cell(vbi->fdt, nodename, "bank-width", 4);
- g_free(nodename);
- } else {
- /* Report the devices as separate nodes so we can mark one as
- * only visible to the secure world.
- */
- nodename = g_strdup_printf("/secflash@%" PRIx64, flashbase);
- qemu_fdt_add_subnode(vbi->fdt, nodename);
- qemu_fdt_setprop_string(vbi->fdt, nodename, "compatible", "cfi-flash");
- qemu_fdt_setprop_sized_cells(vbi->fdt, nodename, "reg",
- 2, flashbase, 2, flashsize);
- qemu_fdt_setprop_cell(vbi->fdt, nodename, "bank-width", 4);
- qemu_fdt_setprop_string(vbi->fdt, nodename, "status", "disabled");
- qemu_fdt_setprop_string(vbi->fdt, nodename, "secure-status", "okay");
- g_free(nodename);
-
- nodename = g_strdup_printf("/flash@%" PRIx64, flashbase);
- qemu_fdt_add_subnode(vbi->fdt, nodename);
- qemu_fdt_setprop_string(vbi->fdt, nodename, "compatible", "cfi-flash");
- qemu_fdt_setprop_sized_cells(vbi->fdt, nodename, "reg",
- 2, flashbase + flashsize, 2, flashsize);
- qemu_fdt_setprop_cell(vbi->fdt, nodename, "bank-width", 4);
- g_free(nodename);
- }
-}
-
-static void create_fw_cfg(const VirtBoardInfo *vbi, AddressSpace *as)
-{
- hwaddr base = vbi->memmap[VIRT_FW_CFG].base;
- hwaddr size = vbi->memmap[VIRT_FW_CFG].size;
- char *nodename;
-
- fw_cfg_init_mem_wide(base + 8, base, 8, base + 16, as);
-
- nodename = g_strdup_printf("/fw-cfg@%" PRIx64, base);
- qemu_fdt_add_subnode(vbi->fdt, nodename);
- qemu_fdt_setprop_string(vbi->fdt, nodename,
- "compatible", "qemu,fw-cfg-mmio");
- qemu_fdt_setprop_sized_cells(vbi->fdt, nodename, "reg",
- 2, base, 2, size);
- g_free(nodename);
-}
-
-static void create_pcie_irq_map(const VirtBoardInfo *vbi, uint32_t gic_phandle,
- int first_irq, const char *nodename)
-{
- int devfn, pin;
- uint32_t full_irq_map[4 * 4 * 10] = { 0 };
- uint32_t *irq_map = full_irq_map;
-
- for (devfn = 0; devfn <= 0x18; devfn += 0x8) {
- for (pin = 0; pin < 4; pin++) {
- int irq_type = GIC_FDT_IRQ_TYPE_SPI;
- int irq_nr = first_irq + ((pin + PCI_SLOT(devfn)) % PCI_NUM_PINS);
- int irq_level = GIC_FDT_IRQ_FLAGS_LEVEL_HI;
- int i;
-
- uint32_t map[] = {
- devfn << 8, 0, 0, /* devfn */
- pin + 1, /* PCI pin */
- gic_phandle, 0, 0, irq_type, irq_nr, irq_level }; /* GIC irq */
-
- /* Convert map to big endian */
- for (i = 0; i < 10; i++) {
- irq_map[i] = cpu_to_be32(map[i]);
- }
- irq_map += 10;
- }
- }
-
- qemu_fdt_setprop(vbi->fdt, nodename, "interrupt-map",
- full_irq_map, sizeof(full_irq_map));
-
- qemu_fdt_setprop_cells(vbi->fdt, nodename, "interrupt-map-mask",
- 0x1800, 0, 0, /* devfn (PCI_SLOT(3)) */
- 0x7 /* PCI irq */);
-}
-
-static void create_pcie(const VirtBoardInfo *vbi, qemu_irq *pic,
- bool use_highmem)
-{
- hwaddr base_mmio = vbi->memmap[VIRT_PCIE_MMIO].base;
- hwaddr size_mmio = vbi->memmap[VIRT_PCIE_MMIO].size;
- hwaddr base_mmio_high = vbi->memmap[VIRT_PCIE_MMIO_HIGH].base;
- hwaddr size_mmio_high = vbi->memmap[VIRT_PCIE_MMIO_HIGH].size;
- hwaddr base_pio = vbi->memmap[VIRT_PCIE_PIO].base;
- hwaddr size_pio = vbi->memmap[VIRT_PCIE_PIO].size;
- hwaddr base_ecam = vbi->memmap[VIRT_PCIE_ECAM].base;
- hwaddr size_ecam = vbi->memmap[VIRT_PCIE_ECAM].size;
- hwaddr base = base_mmio;
- int nr_pcie_buses = size_ecam / PCIE_MMCFG_SIZE_MIN;
- int irq = vbi->irqmap[VIRT_PCIE];
- MemoryRegion *mmio_alias;
- MemoryRegion *mmio_reg;
- MemoryRegion *ecam_alias;
- MemoryRegion *ecam_reg;
- DeviceState *dev;
- char *nodename;
- int i;
- PCIHostState *pci;
-
- dev = qdev_create(NULL, TYPE_GPEX_HOST);
- qdev_init_nofail(dev);
-
- /* Map only the first size_ecam bytes of ECAM space */
- ecam_alias = g_new0(MemoryRegion, 1);
- ecam_reg = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
- memory_region_init_alias(ecam_alias, OBJECT(dev), "pcie-ecam",
- ecam_reg, 0, size_ecam);
- memory_region_add_subregion(get_system_memory(), base_ecam, ecam_alias);
-
- /* Map the MMIO window into system address space so as to expose
- * the section of PCI MMIO space which starts at the same base address
- * (ie 1:1 mapping for that part of PCI MMIO space visible through
- * the window).
- */
- mmio_alias = g_new0(MemoryRegion, 1);
- mmio_reg = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 1);
- memory_region_init_alias(mmio_alias, OBJECT(dev), "pcie-mmio",
- mmio_reg, base_mmio, size_mmio);
- memory_region_add_subregion(get_system_memory(), base_mmio, mmio_alias);
-
- if (use_highmem) {
- /* Map high MMIO space */
- MemoryRegion *high_mmio_alias = g_new0(MemoryRegion, 1);
-
- memory_region_init_alias(high_mmio_alias, OBJECT(dev), "pcie-mmio-high",
- mmio_reg, base_mmio_high, size_mmio_high);
- memory_region_add_subregion(get_system_memory(), base_mmio_high,
- high_mmio_alias);
- }
-
- /* Map IO port space */
- sysbus_mmio_map(SYS_BUS_DEVICE(dev), 2, base_pio);
-
- for (i = 0; i < GPEX_NUM_IRQS; i++) {
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, pic[irq + i]);
- }
-
- pci = PCI_HOST_BRIDGE(dev);
- if (pci->bus) {
- for (i = 0; i < nb_nics; i++) {
- NICInfo *nd = &nd_table[i];
-
- if (!nd->model) {
- nd->model = g_strdup("virtio");
- }
-
- pci_nic_init_nofail(nd, pci->bus, nd->model, NULL);
- }
- }
-
- nodename = g_strdup_printf("/pcie@%" PRIx64, base);
- qemu_fdt_add_subnode(vbi->fdt, nodename);
- qemu_fdt_setprop_string(vbi->fdt, nodename,
- "compatible", "pci-host-ecam-generic");
- qemu_fdt_setprop_string(vbi->fdt, nodename, "device_type", "pci");
- qemu_fdt_setprop_cell(vbi->fdt, nodename, "#address-cells", 3);
- qemu_fdt_setprop_cell(vbi->fdt, nodename, "#size-cells", 2);
- qemu_fdt_setprop_cells(vbi->fdt, nodename, "bus-range", 0,
- nr_pcie_buses - 1);
-
- if (vbi->v2m_phandle) {
- qemu_fdt_setprop_cells(vbi->fdt, nodename, "msi-parent",
- vbi->v2m_phandle);
- }
-
- qemu_fdt_setprop_sized_cells(vbi->fdt, nodename, "reg",
- 2, base_ecam, 2, size_ecam);
-
- if (use_highmem) {
- qemu_fdt_setprop_sized_cells(vbi->fdt, nodename, "ranges",
- 1, FDT_PCI_RANGE_IOPORT, 2, 0,
- 2, base_pio, 2, size_pio,
- 1, FDT_PCI_RANGE_MMIO, 2, base_mmio,
- 2, base_mmio, 2, size_mmio,
- 1, FDT_PCI_RANGE_MMIO_64BIT,
- 2, base_mmio_high,
- 2, base_mmio_high, 2, size_mmio_high);
- } else {
- qemu_fdt_setprop_sized_cells(vbi->fdt, nodename, "ranges",
- 1, FDT_PCI_RANGE_IOPORT, 2, 0,
- 2, base_pio, 2, size_pio,
- 1, FDT_PCI_RANGE_MMIO, 2, base_mmio,
- 2, base_mmio, 2, size_mmio);
- }
-
- qemu_fdt_setprop_cell(vbi->fdt, nodename, "#interrupt-cells", 1);
- create_pcie_irq_map(vbi, vbi->gic_phandle, irq, nodename);
-
- g_free(nodename);
-}
-
-static void create_platform_bus(VirtBoardInfo *vbi, qemu_irq *pic)
-{
- DeviceState *dev;
- SysBusDevice *s;
- int i;
- ARMPlatformBusFDTParams *fdt_params = g_new(ARMPlatformBusFDTParams, 1);
- MemoryRegion *sysmem = get_system_memory();
-
- platform_bus_params.platform_bus_base = vbi->memmap[VIRT_PLATFORM_BUS].base;
- platform_bus_params.platform_bus_size = vbi->memmap[VIRT_PLATFORM_BUS].size;
- platform_bus_params.platform_bus_first_irq = vbi->irqmap[VIRT_PLATFORM_BUS];
- platform_bus_params.platform_bus_num_irqs = PLATFORM_BUS_NUM_IRQS;
-
- fdt_params->system_params = &platform_bus_params;
- fdt_params->binfo = &vbi->bootinfo;
- fdt_params->intc = "/intc";
- /*
- * register a machine init done notifier that creates the device tree
- * nodes of the platform bus and its children dynamic sysbus devices
- */
- arm_register_platform_bus_fdt_creator(fdt_params);
-
- dev = qdev_create(NULL, TYPE_PLATFORM_BUS_DEVICE);
- dev->id = TYPE_PLATFORM_BUS_DEVICE;
- qdev_prop_set_uint32(dev, "num_irqs",
- platform_bus_params.platform_bus_num_irqs);
- qdev_prop_set_uint32(dev, "mmio_size",
- platform_bus_params.platform_bus_size);
- qdev_init_nofail(dev);
- s = SYS_BUS_DEVICE(dev);
-
- for (i = 0; i < platform_bus_params.platform_bus_num_irqs; i++) {
- int irqn = platform_bus_params.platform_bus_first_irq + i;
- sysbus_connect_irq(s, i, pic[irqn]);
- }
-
- memory_region_add_subregion(sysmem,
- platform_bus_params.platform_bus_base,
- sysbus_mmio_get_region(s, 0));
-}
-
-static void create_secure_ram(VirtBoardInfo *vbi, MemoryRegion *secure_sysmem)
-{
- MemoryRegion *secram = g_new(MemoryRegion, 1);
- char *nodename;
- hwaddr base = vbi->memmap[VIRT_SECURE_MEM].base;
- hwaddr size = vbi->memmap[VIRT_SECURE_MEM].size;
-
- memory_region_init_ram(secram, NULL, "virt.secure-ram", size, &error_fatal);
- vmstate_register_ram_global(secram);
- memory_region_add_subregion(secure_sysmem, base, secram);
-
- nodename = g_strdup_printf("/secram@%" PRIx64, base);
- qemu_fdt_add_subnode(vbi->fdt, nodename);
- qemu_fdt_setprop_string(vbi->fdt, nodename, "device_type", "memory");
- qemu_fdt_setprop_sized_cells(vbi->fdt, nodename, "reg", 2, base, 2, size);
- qemu_fdt_setprop_string(vbi->fdt, nodename, "status", "disabled");
- qemu_fdt_setprop_string(vbi->fdt, nodename, "secure-status", "okay");
-
- g_free(nodename);
-}
-
-static void *machvirt_dtb(const struct arm_boot_info *binfo, int *fdt_size)
-{
- const VirtBoardInfo *board = (const VirtBoardInfo *)binfo;
-
- *fdt_size = board->fdt_size;
- return board->fdt;
-}
-
-static void virt_build_smbios(VirtGuestInfo *guest_info)
-{
- FWCfgState *fw_cfg = guest_info->fw_cfg;
- uint8_t *smbios_tables, *smbios_anchor;
- size_t smbios_tables_len, smbios_anchor_len;
- const char *product = "QEMU Virtual Machine";
-
- if (!fw_cfg) {
- return;
- }
-
- if (kvm_enabled()) {
- product = "KVM Virtual Machine";
- }
-
- smbios_set_defaults("QEMU", product,
- "1.0", false, true, SMBIOS_ENTRY_POINT_30);
-
- smbios_get_tables(NULL, 0, &smbios_tables, &smbios_tables_len,
- &smbios_anchor, &smbios_anchor_len);
-
- if (smbios_anchor) {
- fw_cfg_add_file(fw_cfg, "etc/smbios/smbios-tables",
- smbios_tables, smbios_tables_len);
- fw_cfg_add_file(fw_cfg, "etc/smbios/smbios-anchor",
- smbios_anchor, smbios_anchor_len);
- }
-}
-
-static
-void virt_guest_info_machine_done(Notifier *notifier, void *data)
-{
- VirtGuestInfoState *guest_info_state = container_of(notifier,
- VirtGuestInfoState, machine_done);
- virt_acpi_setup(&guest_info_state->info);
- virt_build_smbios(&guest_info_state->info);
-}
-
-static void machvirt_init(MachineState *machine)
-{
- VirtMachineState *vms = VIRT_MACHINE(machine);
- qemu_irq pic[NUM_IRQS];
- MemoryRegion *sysmem = get_system_memory();
- MemoryRegion *secure_sysmem = NULL;
- int gic_version = vms->gic_version;
- int n, virt_max_cpus;
- MemoryRegion *ram = g_new(MemoryRegion, 1);
- const char *cpu_model = machine->cpu_model;
- VirtBoardInfo *vbi;
- VirtGuestInfoState *guest_info_state = g_malloc0(sizeof *guest_info_state);
- VirtGuestInfo *guest_info = &guest_info_state->info;
- char **cpustr;
- bool firmware_loaded = bios_name || drive_get(IF_PFLASH, 0, 0);
-
- if (!cpu_model) {
- cpu_model = "cortex-a15";
- }
-
- /* We can probe only here because during property set
- * KVM is not available yet
- */
- if (!gic_version) {
- gic_version = kvm_arm_vgic_probe();
- if (!gic_version) {
- error_report("Unable to determine GIC version supported by host");
- error_printf("KVM acceleration is probably not supported\n");
- exit(1);
- }
- }
-
- /* Separate the actual CPU model name from any appended features */
- cpustr = g_strsplit(cpu_model, ",", 2);
-
- vbi = find_machine_info(cpustr[0]);
-
- if (!vbi) {
- error_report("mach-virt: CPU %s not supported", cpustr[0]);
- exit(1);
- }
-
- /* If we have an EL3 boot ROM then the assumption is that it will
- * implement PSCI itself, so disable QEMU's internal implementation
- * so it doesn't get in the way. Instead of starting secondary
- * CPUs in PSCI powerdown state we will start them all running and
- * let the boot ROM sort them out.
- * The usual case is that we do use QEMU's PSCI implementation.
- */
- vbi->using_psci = !(vms->secure && firmware_loaded);
-
- /* The maximum number of CPUs depends on the GIC version, or on how
- * many redistributors we can fit into the memory map.
- */
- if (gic_version == 3) {
- virt_max_cpus = vbi->memmap[VIRT_GIC_REDIST].size / 0x20000;
- } else {
- virt_max_cpus = GIC_NCPU;
- }
-
- if (max_cpus > virt_max_cpus) {
- error_report("Number of SMP CPUs requested (%d) exceeds max CPUs "
- "supported by machine 'mach-virt' (%d)",
- max_cpus, virt_max_cpus);
- exit(1);
- }
-
- vbi->smp_cpus = smp_cpus;
-
- if (machine->ram_size > vbi->memmap[VIRT_MEM].size) {
- error_report("mach-virt: cannot model more than %dGB RAM", RAMLIMIT_GB);
- exit(1);
- }
-
- if (vms->secure) {
- if (kvm_enabled()) {
- error_report("mach-virt: KVM does not support Security extensions");
- exit(1);
- }
-
- /* The Secure view of the world is the same as the NonSecure,
- * but with a few extra devices. Create it as a container region
- * containing the system memory at low priority; any secure-only
- * devices go in at higher priority and take precedence.
- */
- secure_sysmem = g_new(MemoryRegion, 1);
- memory_region_init(secure_sysmem, OBJECT(machine), "secure-memory",
- UINT64_MAX);
- memory_region_add_subregion_overlap(secure_sysmem, 0, sysmem, -1);
- }
-
- create_fdt(vbi);
-
- for (n = 0; n < smp_cpus; n++) {
- ObjectClass *oc = cpu_class_by_name(TYPE_ARM_CPU, cpustr[0]);
- CPUClass *cc = CPU_CLASS(oc);
- Object *cpuobj;
- Error *err = NULL;
- char *cpuopts = g_strdup(cpustr[1]);
-
- if (!oc) {
- error_report("Unable to find CPU definition");
- exit(1);
- }
- cpuobj = object_new(object_class_get_name(oc));
-
- /* Handle any CPU options specified by the user */
- cc->parse_features(CPU(cpuobj), cpuopts, &err);
- g_free(cpuopts);
- if (err) {
- error_report_err(err);
- exit(1);
- }
-
- if (!vms->secure) {
- object_property_set_bool(cpuobj, false, "has_el3", NULL);
- }
-
- if (vbi->using_psci) {
- object_property_set_int(cpuobj, QEMU_PSCI_CONDUIT_HVC,
- "psci-conduit", NULL);
-
- /* Secondary CPUs start in PSCI powered-down state */
- if (n > 0) {
- object_property_set_bool(cpuobj, true,
- "start-powered-off", NULL);
- }
- }
-
- if (object_property_find(cpuobj, "reset-cbar", NULL)) {
- object_property_set_int(cpuobj, vbi->memmap[VIRT_CPUPERIPHS].base,
- "reset-cbar", &error_abort);
- }
-
- object_property_set_link(cpuobj, OBJECT(sysmem), "memory",
- &error_abort);
- if (vms->secure) {
- object_property_set_link(cpuobj, OBJECT(secure_sysmem),
- "secure-memory", &error_abort);
- }
-
- object_property_set_bool(cpuobj, true, "realized", NULL);
- }
- g_strfreev(cpustr);
- fdt_add_timer_nodes(vbi, gic_version);
- fdt_add_cpu_nodes(vbi);
- fdt_add_psci_node(vbi);
-
- memory_region_allocate_system_memory(ram, NULL, "mach-virt.ram",
- machine->ram_size);
- memory_region_add_subregion(sysmem, vbi->memmap[VIRT_MEM].base, ram);
-
- create_flash(vbi, sysmem, secure_sysmem ? secure_sysmem : sysmem);
-
- create_gic(vbi, pic, gic_version, vms->secure);
-
- create_uart(vbi, pic, VIRT_UART, sysmem);
-
- if (vms->secure) {
- create_secure_ram(vbi, secure_sysmem);
- create_uart(vbi, pic, VIRT_SECURE_UART, secure_sysmem);
- }
-
- create_rtc(vbi, pic);
-
- create_pcie(vbi, pic, vms->highmem);
-
- create_gpio(vbi, pic);
-
- /* Create mmio transports, so the user can create virtio backends
- * (which will be automatically plugged in to the transports). If
- * no backend is created the transport will just sit harmlessly idle.
- */
- create_virtio_devices(vbi, pic);
-
- create_fw_cfg(vbi, &address_space_memory);
- rom_set_fw(fw_cfg_find());
-
- guest_info->smp_cpus = smp_cpus;
- guest_info->fw_cfg = fw_cfg_find();
- guest_info->memmap = vbi->memmap;
- guest_info->irqmap = vbi->irqmap;
- guest_info->use_highmem = vms->highmem;
- guest_info->gic_version = gic_version;
- guest_info_state->machine_done.notify = virt_guest_info_machine_done;
- qemu_add_machine_init_done_notifier(&guest_info_state->machine_done);
-
- vbi->bootinfo.ram_size = machine->ram_size;
- vbi->bootinfo.kernel_filename = machine->kernel_filename;
- vbi->bootinfo.kernel_cmdline = machine->kernel_cmdline;
- vbi->bootinfo.initrd_filename = machine->initrd_filename;
- vbi->bootinfo.nb_cpus = smp_cpus;
- vbi->bootinfo.board_id = -1;
- vbi->bootinfo.loader_start = vbi->memmap[VIRT_MEM].base;
- vbi->bootinfo.get_dtb = machvirt_dtb;
- vbi->bootinfo.firmware_loaded = firmware_loaded;
- arm_load_kernel(ARM_CPU(first_cpu), &vbi->bootinfo);
-
- /*
- * arm_load_kernel machine init done notifier registration must
- * happen before the platform_bus_create call. In this latter,
- * another notifier is registered which adds platform bus nodes.
- * Notifiers are executed in registration reverse order.
- */
- create_platform_bus(vbi, pic);
-}
-
-static bool virt_get_secure(Object *obj, Error **errp)
-{
- VirtMachineState *vms = VIRT_MACHINE(obj);
-
- return vms->secure;
-}
-
-static void virt_set_secure(Object *obj, bool value, Error **errp)
-{
- VirtMachineState *vms = VIRT_MACHINE(obj);
-
- vms->secure = value;
-}
-
-static bool virt_get_highmem(Object *obj, Error **errp)
-{
- VirtMachineState *vms = VIRT_MACHINE(obj);
-
- return vms->highmem;
-}
-
-static void virt_set_highmem(Object *obj, bool value, Error **errp)
-{
- VirtMachineState *vms = VIRT_MACHINE(obj);
-
- vms->highmem = value;
-}
-
-static char *virt_get_gic_version(Object *obj, Error **errp)
-{
- VirtMachineState *vms = VIRT_MACHINE(obj);
- const char *val = vms->gic_version == 3 ? "3" : "2";
-
- return g_strdup(val);
-}
-
-static void virt_set_gic_version(Object *obj, const char *value, Error **errp)
-{
- VirtMachineState *vms = VIRT_MACHINE(obj);
-
- if (!strcmp(value, "3")) {
- vms->gic_version = 3;
- } else if (!strcmp(value, "2")) {
- vms->gic_version = 2;
- } else if (!strcmp(value, "host")) {
- vms->gic_version = 0; /* Will probe later */
- } else {
- error_setg(errp, "Invalid gic-version value");
- error_append_hint(errp, "Valid values are 3, 2, host.\n");
- }
-}
-
-static void virt_machine_class_init(ObjectClass *oc, void *data)
-{
- MachineClass *mc = MACHINE_CLASS(oc);
-
- mc->init = machvirt_init;
- /* Start max_cpus at the maximum QEMU supports. We'll further restrict
- * it later in machvirt_init, where we have more information about the
- * configuration of the particular instance.
- */
- mc->max_cpus = MAX_CPUMASK_BITS;
- mc->has_dynamic_sysbus = true;
- mc->block_default_type = IF_VIRTIO;
- mc->no_cdrom = 1;
- mc->pci_allow_0_address = true;
-}
-
-static const TypeInfo virt_machine_info = {
- .name = TYPE_VIRT_MACHINE,
- .parent = TYPE_MACHINE,
- .abstract = true,
- .instance_size = sizeof(VirtMachineState),
- .class_size = sizeof(VirtMachineClass),
- .class_init = virt_machine_class_init,
-};
-
-static void virt_2_6_instance_init(Object *obj)
-{
- VirtMachineState *vms = VIRT_MACHINE(obj);
-
- /* EL3 is disabled by default on virt: this makes us consistent
- * between KVM and TCG for this board, and it also allows us to
- * boot UEFI blobs which assume no TrustZone support.
- */
- vms->secure = false;
- object_property_add_bool(obj, "secure", virt_get_secure,
- virt_set_secure, NULL);
- object_property_set_description(obj, "secure",
- "Set on/off to enable/disable the ARM "
- "Security Extensions (TrustZone)",
- NULL);
-
- /* High memory is enabled by default */
- vms->highmem = true;
- object_property_add_bool(obj, "highmem", virt_get_highmem,
- virt_set_highmem, NULL);
- object_property_set_description(obj, "highmem",
- "Set on/off to enable/disable using "
- "physical address space above 32 bits",
- NULL);
- /* Default GIC type is v2 */
- vms->gic_version = 2;
- object_property_add_str(obj, "gic-version", virt_get_gic_version,
- virt_set_gic_version, NULL);
- object_property_set_description(obj, "gic-version",
- "Set GIC version. "
- "Valid values are 2, 3 and host", NULL);
-}
-
-static void virt_2_6_class_init(ObjectClass *oc, void *data)
-{
- MachineClass *mc = MACHINE_CLASS(oc);
- static GlobalProperty compat_props[] = {
- { /* end of list */ }
- };
-
- mc->desc = "QEMU 2.6 ARM Virtual Machine";
- mc->alias = "virt";
- mc->compat_props = compat_props;
-}
-
-static const TypeInfo machvirt_info = {
- .name = MACHINE_TYPE_NAME("virt-2.6"),
- .parent = TYPE_VIRT_MACHINE,
- .instance_init = virt_2_6_instance_init,
- .class_init = virt_2_6_class_init,
-};
-
-static void machvirt_machine_init(void)
-{
- type_register_static(&virt_machine_info);
- type_register_static(&machvirt_info);
-}
-
-type_init(machvirt_machine_init);
diff --git a/qemu/hw/arm/xilinx_zynq.c b/qemu/hw/arm/xilinx_zynq.c
deleted file mode 100644
index 98b17c9ae..000000000
--- a/qemu/hw/arm/xilinx_zynq.c
+++ /dev/null
@@ -1,318 +0,0 @@
-/*
- * Xilinx Zynq Baseboard System emulation.
- *
- * Copyright (c) 2010 Xilinx.
- * Copyright (c) 2012 Peter A.G. Crosthwaite (peter.croshtwaite@petalogix.com)
- * Copyright (c) 2012 Petalogix Pty Ltd.
- * Written by Haibing Ma
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "qemu-common.h"
-#include "cpu.h"
-#include "hw/sysbus.h"
-#include "hw/arm/arm.h"
-#include "net/net.h"
-#include "exec/address-spaces.h"
-#include "sysemu/sysemu.h"
-#include "hw/boards.h"
-#include "hw/block/flash.h"
-#include "sysemu/block-backend.h"
-#include "hw/loader.h"
-#include "hw/misc/zynq-xadc.h"
-#include "hw/ssi/ssi.h"
-#include "qemu/error-report.h"
-#include "hw/sd/sd.h"
-
-#define NUM_SPI_FLASHES 4
-#define NUM_QSPI_FLASHES 2
-#define NUM_QSPI_BUSSES 2
-
-#define FLASH_SIZE (64 * 1024 * 1024)
-#define FLASH_SECTOR_SIZE (128 * 1024)
-
-#define IRQ_OFFSET 32 /* pic interrupts start from index 32 */
-
-#define MPCORE_PERIPHBASE 0xF8F00000
-#define ZYNQ_BOARD_MIDR 0x413FC090
-
-static const int dma_irqs[8] = {
- 46, 47, 48, 49, 72, 73, 74, 75
-};
-
-#define BOARD_SETUP_ADDR 0x100
-
-#define SLCR_LOCK_OFFSET 0x004
-#define SLCR_UNLOCK_OFFSET 0x008
-#define SLCR_ARM_PLL_OFFSET 0x100
-
-#define SLCR_XILINX_UNLOCK_KEY 0xdf0d
-#define SLCR_XILINX_LOCK_KEY 0x767b
-
-#define ARMV7_IMM16(x) (extract32((x), 0, 12) | \
- extract32((x), 12, 4) << 16)
-
-/* Write immediate val to address r0 + addr. r0 should contain base offset
- * of the SLCR block. Clobbers r1.
- */
-
-#define SLCR_WRITE(addr, val) \
- 0xe3001000 + ARMV7_IMM16(extract32((val), 0, 16)), /* movw r1 ... */ \
- 0xe3401000 + ARMV7_IMM16(extract32((val), 16, 16)), /* movt r1 ... */ \
- 0xe5801000 + (addr)
-
-static void zynq_write_board_setup(ARMCPU *cpu,
- const struct arm_boot_info *info)
-{
- int n;
- uint32_t board_setup_blob[] = {
- 0xe3a004f8, /* mov r0, #0xf8000000 */
- SLCR_WRITE(SLCR_UNLOCK_OFFSET, SLCR_XILINX_UNLOCK_KEY),
- SLCR_WRITE(SLCR_ARM_PLL_OFFSET, 0x00014008),
- SLCR_WRITE(SLCR_LOCK_OFFSET, SLCR_XILINX_LOCK_KEY),
- 0xe12fff1e, /* bx lr */
- };
- for (n = 0; n < ARRAY_SIZE(board_setup_blob); n++) {
- board_setup_blob[n] = tswap32(board_setup_blob[n]);
- }
- rom_add_blob_fixed("board-setup", board_setup_blob,
- sizeof(board_setup_blob), BOARD_SETUP_ADDR);
-}
-
-static struct arm_boot_info zynq_binfo = {};
-
-static void gem_init(NICInfo *nd, uint32_t base, qemu_irq irq)
-{
- DeviceState *dev;
- SysBusDevice *s;
-
- dev = qdev_create(NULL, "cadence_gem");
- if (nd->used) {
- qemu_check_nic_model(nd, "cadence_gem");
- qdev_set_nic_properties(dev, nd);
- }
- qdev_init_nofail(dev);
- s = SYS_BUS_DEVICE(dev);
- sysbus_mmio_map(s, 0, base);
- sysbus_connect_irq(s, 0, irq);
-}
-
-static inline void zynq_init_spi_flashes(uint32_t base_addr, qemu_irq irq,
- bool is_qspi)
-{
- DeviceState *dev;
- SysBusDevice *busdev;
- SSIBus *spi;
- DeviceState *flash_dev;
- int i, j;
- int num_busses = is_qspi ? NUM_QSPI_BUSSES : 1;
- int num_ss = is_qspi ? NUM_QSPI_FLASHES : NUM_SPI_FLASHES;
-
- dev = qdev_create(NULL, is_qspi ? "xlnx.ps7-qspi" : "xlnx.ps7-spi");
- qdev_prop_set_uint8(dev, "num-txrx-bytes", is_qspi ? 4 : 1);
- qdev_prop_set_uint8(dev, "num-ss-bits", num_ss);
- qdev_prop_set_uint8(dev, "num-busses", num_busses);
- qdev_init_nofail(dev);
- busdev = SYS_BUS_DEVICE(dev);
- sysbus_mmio_map(busdev, 0, base_addr);
- if (is_qspi) {
- sysbus_mmio_map(busdev, 1, 0xFC000000);
- }
- sysbus_connect_irq(busdev, 0, irq);
-
- for (i = 0; i < num_busses; ++i) {
- char bus_name[16];
- qemu_irq cs_line;
-
- snprintf(bus_name, 16, "spi%d", i);
- spi = (SSIBus *)qdev_get_child_bus(dev, bus_name);
-
- for (j = 0; j < num_ss; ++j) {
- flash_dev = ssi_create_slave(spi, "n25q128");
-
- cs_line = qdev_get_gpio_in_named(flash_dev, SSI_GPIO_CS, 0);
- sysbus_connect_irq(busdev, i * num_ss + j + 1, cs_line);
- }
- }
-
-}
-
-static void zynq_init(MachineState *machine)
-{
- ram_addr_t ram_size = machine->ram_size;
- const char *cpu_model = machine->cpu_model;
- const char *kernel_filename = machine->kernel_filename;
- const char *kernel_cmdline = machine->kernel_cmdline;
- const char *initrd_filename = machine->initrd_filename;
- ObjectClass *cpu_oc;
- ARMCPU *cpu;
- MemoryRegion *address_space_mem = get_system_memory();
- MemoryRegion *ext_ram = g_new(MemoryRegion, 1);
- MemoryRegion *ocm_ram = g_new(MemoryRegion, 1);
- DeviceState *dev, *carddev;
- SysBusDevice *busdev;
- DriveInfo *di;
- BlockBackend *blk;
- qemu_irq pic[64];
- int n;
-
- if (!cpu_model) {
- cpu_model = "cortex-a9";
- }
- cpu_oc = cpu_class_by_name(TYPE_ARM_CPU, cpu_model);
-
- cpu = ARM_CPU(object_new(object_class_get_name(cpu_oc)));
-
- /* By default A9 CPUs have EL3 enabled. This board does not
- * currently support EL3 so the CPU EL3 property is disabled before
- * realization.
- */
- if (object_property_find(OBJECT(cpu), "has_el3", NULL)) {
- object_property_set_bool(OBJECT(cpu), false, "has_el3", &error_fatal);
- }
-
- object_property_set_int(OBJECT(cpu), ZYNQ_BOARD_MIDR, "midr",
- &error_fatal);
- object_property_set_int(OBJECT(cpu), MPCORE_PERIPHBASE, "reset-cbar",
- &error_fatal);
- object_property_set_bool(OBJECT(cpu), true, "realized", &error_fatal);
-
- /* max 2GB ram */
- if (ram_size > 0x80000000) {
- ram_size = 0x80000000;
- }
-
- /* DDR remapped to address zero. */
- memory_region_allocate_system_memory(ext_ram, NULL, "zynq.ext_ram",
- ram_size);
- memory_region_add_subregion(address_space_mem, 0, ext_ram);
-
- /* 256K of on-chip memory */
- memory_region_init_ram(ocm_ram, NULL, "zynq.ocm_ram", 256 << 10,
- &error_fatal);
- vmstate_register_ram_global(ocm_ram);
- memory_region_add_subregion(address_space_mem, 0xFFFC0000, ocm_ram);
-
- DriveInfo *dinfo = drive_get(IF_PFLASH, 0, 0);
-
- /* AMD */
- pflash_cfi02_register(0xe2000000, NULL, "zynq.pflash", FLASH_SIZE,
- dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
- FLASH_SECTOR_SIZE,
- FLASH_SIZE/FLASH_SECTOR_SIZE, 1,
- 1, 0x0066, 0x0022, 0x0000, 0x0000, 0x0555, 0x2aa,
- 0);
-
- dev = qdev_create(NULL, "xilinx,zynq_slcr");
- qdev_init_nofail(dev);
- sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, 0xF8000000);
-
- dev = qdev_create(NULL, "a9mpcore_priv");
- qdev_prop_set_uint32(dev, "num-cpu", 1);
- qdev_init_nofail(dev);
- busdev = SYS_BUS_DEVICE(dev);
- sysbus_mmio_map(busdev, 0, MPCORE_PERIPHBASE);
- sysbus_connect_irq(busdev, 0,
- qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ));
-
- for (n = 0; n < 64; n++) {
- pic[n] = qdev_get_gpio_in(dev, n);
- }
-
- zynq_init_spi_flashes(0xE0006000, pic[58-IRQ_OFFSET], false);
- zynq_init_spi_flashes(0xE0007000, pic[81-IRQ_OFFSET], false);
- zynq_init_spi_flashes(0xE000D000, pic[51-IRQ_OFFSET], true);
-
- sysbus_create_simple("xlnx,ps7-usb", 0xE0002000, pic[53-IRQ_OFFSET]);
- sysbus_create_simple("xlnx,ps7-usb", 0xE0003000, pic[76-IRQ_OFFSET]);
-
- sysbus_create_simple("cadence_uart", 0xE0000000, pic[59-IRQ_OFFSET]);
- sysbus_create_simple("cadence_uart", 0xE0001000, pic[82-IRQ_OFFSET]);
-
- sysbus_create_varargs("cadence_ttc", 0xF8001000,
- pic[42-IRQ_OFFSET], pic[43-IRQ_OFFSET], pic[44-IRQ_OFFSET], NULL);
- sysbus_create_varargs("cadence_ttc", 0xF8002000,
- pic[69-IRQ_OFFSET], pic[70-IRQ_OFFSET], pic[71-IRQ_OFFSET], NULL);
-
- gem_init(&nd_table[0], 0xE000B000, pic[54-IRQ_OFFSET]);
- gem_init(&nd_table[1], 0xE000C000, pic[77-IRQ_OFFSET]);
-
- dev = qdev_create(NULL, "generic-sdhci");
- qdev_init_nofail(dev);
- sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, 0xE0100000);
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[56-IRQ_OFFSET]);
-
- di = drive_get_next(IF_SD);
- blk = di ? blk_by_legacy_dinfo(di) : NULL;
- carddev = qdev_create(qdev_get_child_bus(dev, "sd-bus"), TYPE_SD_CARD);
- qdev_prop_set_drive(carddev, "drive", blk, &error_fatal);
- object_property_set_bool(OBJECT(carddev), true, "realized", &error_fatal);
-
- dev = qdev_create(NULL, "generic-sdhci");
- qdev_init_nofail(dev);
- sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, 0xE0101000);
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[79-IRQ_OFFSET]);
-
- di = drive_get_next(IF_SD);
- blk = di ? blk_by_legacy_dinfo(di) : NULL;
- carddev = qdev_create(qdev_get_child_bus(dev, "sd-bus"), TYPE_SD_CARD);
- qdev_prop_set_drive(carddev, "drive", blk, &error_fatal);
- object_property_set_bool(OBJECT(carddev), true, "realized", &error_fatal);
-
- dev = qdev_create(NULL, TYPE_ZYNQ_XADC);
- qdev_init_nofail(dev);
- sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, 0xF8007100);
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[39-IRQ_OFFSET]);
-
- dev = qdev_create(NULL, "pl330");
- qdev_prop_set_uint8(dev, "num_chnls", 8);
- qdev_prop_set_uint8(dev, "num_periph_req", 4);
- qdev_prop_set_uint8(dev, "num_events", 16);
-
- qdev_prop_set_uint8(dev, "data_width", 64);
- qdev_prop_set_uint8(dev, "wr_cap", 8);
- qdev_prop_set_uint8(dev, "wr_q_dep", 16);
- qdev_prop_set_uint8(dev, "rd_cap", 8);
- qdev_prop_set_uint8(dev, "rd_q_dep", 16);
- qdev_prop_set_uint16(dev, "data_buffer_dep", 256);
-
- qdev_init_nofail(dev);
- busdev = SYS_BUS_DEVICE(dev);
- sysbus_mmio_map(busdev, 0, 0xF8003000);
- sysbus_connect_irq(busdev, 0, pic[45-IRQ_OFFSET]); /* abort irq line */
- for (n = 0; n < 8; ++n) { /* event irqs */
- sysbus_connect_irq(busdev, n + 1, pic[dma_irqs[n] - IRQ_OFFSET]);
- }
-
- zynq_binfo.ram_size = ram_size;
- zynq_binfo.kernel_filename = kernel_filename;
- zynq_binfo.kernel_cmdline = kernel_cmdline;
- zynq_binfo.initrd_filename = initrd_filename;
- zynq_binfo.nb_cpus = 1;
- zynq_binfo.board_id = 0xd32;
- zynq_binfo.loader_start = 0;
- zynq_binfo.board_setup_addr = BOARD_SETUP_ADDR;
- zynq_binfo.write_board_setup = zynq_write_board_setup;
-
- arm_load_kernel(ARM_CPU(first_cpu), &zynq_binfo);
-}
-
-static void zynq_machine_init(MachineClass *mc)
-{
- mc->desc = "Xilinx Zynq Platform Baseboard for Cortex-A9";
- mc->init = zynq_init;
- mc->block_default_type = IF_SCSI;
- mc->max_cpus = 1;
- mc->no_sdcard = 1;
-}
-
-DEFINE_MACHINE("xilinx-zynq-a9", zynq_machine_init)
diff --git a/qemu/hw/arm/xlnx-ep108.c b/qemu/hw/arm/xlnx-ep108.c
deleted file mode 100644
index 5f480182b..000000000
--- a/qemu/hw/arm/xlnx-ep108.c
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Xilinx ZynqMP EP108 board
- *
- * Copyright (C) 2015 Xilinx Inc
- * Written by Peter Crosthwaite <peter.crosthwaite@xilinx.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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.
- */
-
-#include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "qemu-common.h"
-#include "cpu.h"
-#include "hw/arm/xlnx-zynqmp.h"
-#include "hw/boards.h"
-#include "qemu/error-report.h"
-#include "exec/address-spaces.h"
-
-typedef struct XlnxEP108 {
- XlnxZynqMPState soc;
- MemoryRegion ddr_ram;
-} XlnxEP108;
-
-static struct arm_boot_info xlnx_ep108_binfo;
-
-static void xlnx_ep108_init(MachineState *machine)
-{
- XlnxEP108 *s = g_new0(XlnxEP108, 1);
- int i;
- uint64_t ram_size = machine->ram_size;
-
- /* Create the memory region to pass to the SoC */
- if (ram_size > XLNX_ZYNQMP_MAX_RAM_SIZE) {
- error_report("ERROR: RAM size 0x%" PRIx64 " above max supported of "
- "0x%llx", ram_size,
- XLNX_ZYNQMP_MAX_RAM_SIZE);
- exit(1);
- }
-
- if (ram_size < 0x08000000) {
- qemu_log("WARNING: RAM size 0x%" PRIx64 " is small for EP108",
- ram_size);
- }
-
- memory_region_allocate_system_memory(&s->ddr_ram, NULL, "ddr-ram",
- ram_size);
-
- object_initialize(&s->soc, sizeof(s->soc), TYPE_XLNX_ZYNQMP);
- object_property_add_child(OBJECT(machine), "soc", OBJECT(&s->soc),
- &error_abort);
-
- object_property_set_link(OBJECT(&s->soc), OBJECT(&s->ddr_ram),
- "ddr-ram", &error_abort);
-
- object_property_set_bool(OBJECT(&s->soc), true, "realized", &error_fatal);
-
- /* Create and plug in the SD cards */
- for (i = 0; i < XLNX_ZYNQMP_NUM_SDHCI; i++) {
- BusState *bus;
- DriveInfo *di = drive_get_next(IF_SD);
- BlockBackend *blk = di ? blk_by_legacy_dinfo(di) : NULL;
- DeviceState *carddev;
- char *bus_name;
-
- bus_name = g_strdup_printf("sd-bus%d", i);
- bus = qdev_get_child_bus(DEVICE(&s->soc), bus_name);
- g_free(bus_name);
- if (!bus) {
- error_report("No SD bus found for SD card %d", i);
- exit(1);
- }
- carddev = qdev_create(bus, TYPE_SD_CARD);
- qdev_prop_set_drive(carddev, "drive", blk, &error_fatal);
- object_property_set_bool(OBJECT(carddev), true, "realized",
- &error_fatal);
- }
-
- for (i = 0; i < XLNX_ZYNQMP_NUM_SPIS; i++) {
- SSIBus *spi_bus;
- DeviceState *flash_dev;
- qemu_irq cs_line;
- gchar *bus_name = g_strdup_printf("spi%d", i);
-
- spi_bus = (SSIBus *)qdev_get_child_bus(DEVICE(&s->soc), bus_name);
- g_free(bus_name);
-
- flash_dev = ssi_create_slave(spi_bus, "sst25wf080");
- cs_line = qdev_get_gpio_in_named(flash_dev, SSI_GPIO_CS, 0);
-
- sysbus_connect_irq(SYS_BUS_DEVICE(&s->soc.spi[i]), 1, cs_line);
- }
-
- xlnx_ep108_binfo.ram_size = ram_size;
- xlnx_ep108_binfo.kernel_filename = machine->kernel_filename;
- xlnx_ep108_binfo.kernel_cmdline = machine->kernel_cmdline;
- xlnx_ep108_binfo.initrd_filename = machine->initrd_filename;
- xlnx_ep108_binfo.loader_start = 0;
- arm_load_kernel(s->soc.boot_cpu_ptr, &xlnx_ep108_binfo);
-}
-
-static void xlnx_ep108_machine_init(MachineClass *mc)
-{
- mc->desc = "Xilinx ZynqMP EP108 board";
- mc->init = xlnx_ep108_init;
-}
-
-DEFINE_MACHINE("xlnx-ep108", xlnx_ep108_machine_init)
diff --git a/qemu/hw/arm/xlnx-zynqmp.c b/qemu/hw/arm/xlnx-zynqmp.c
deleted file mode 100644
index 4d504da64..000000000
--- a/qemu/hw/arm/xlnx-zynqmp.c
+++ /dev/null
@@ -1,403 +0,0 @@
-/*
- * Xilinx Zynq MPSoC emulation
- *
- * Copyright (C) 2015 Xilinx Inc
- * Written by Peter Crosthwaite <peter.crosthwaite@xilinx.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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.
- */
-
-#include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "qemu-common.h"
-#include "cpu.h"
-#include "hw/arm/xlnx-zynqmp.h"
-#include "hw/intc/arm_gic_common.h"
-#include "exec/address-spaces.h"
-
-#define GIC_NUM_SPI_INTR 160
-
-#define ARM_PHYS_TIMER_PPI 30
-#define ARM_VIRT_TIMER_PPI 27
-
-#define GIC_BASE_ADDR 0xf9000000
-#define GIC_DIST_ADDR 0xf9010000
-#define GIC_CPU_ADDR 0xf9020000
-
-#define SATA_INTR 133
-#define SATA_ADDR 0xFD0C0000
-#define SATA_NUM_PORTS 2
-
-static const uint64_t gem_addr[XLNX_ZYNQMP_NUM_GEMS] = {
- 0xFF0B0000, 0xFF0C0000, 0xFF0D0000, 0xFF0E0000,
-};
-
-static const int gem_intr[XLNX_ZYNQMP_NUM_GEMS] = {
- 57, 59, 61, 63,
-};
-
-static const uint64_t uart_addr[XLNX_ZYNQMP_NUM_UARTS] = {
- 0xFF000000, 0xFF010000,
-};
-
-static const int uart_intr[XLNX_ZYNQMP_NUM_UARTS] = {
- 21, 22,
-};
-
-static const uint64_t sdhci_addr[XLNX_ZYNQMP_NUM_SDHCI] = {
- 0xFF160000, 0xFF170000,
-};
-
-static const int sdhci_intr[XLNX_ZYNQMP_NUM_SDHCI] = {
- 48, 49,
-};
-
-static const uint64_t spi_addr[XLNX_ZYNQMP_NUM_SPIS] = {
- 0xFF040000, 0xFF050000,
-};
-
-static const int spi_intr[XLNX_ZYNQMP_NUM_SPIS] = {
- 19, 20,
-};
-
-typedef struct XlnxZynqMPGICRegion {
- int region_index;
- uint32_t address;
-} XlnxZynqMPGICRegion;
-
-static const XlnxZynqMPGICRegion xlnx_zynqmp_gic_regions[] = {
- { .region_index = 0, .address = GIC_DIST_ADDR, },
- { .region_index = 1, .address = GIC_CPU_ADDR, },
-};
-
-static inline int arm_gic_ppi_index(int cpu_nr, int ppi_index)
-{
- return GIC_NUM_SPI_INTR + cpu_nr * GIC_INTERNAL + ppi_index;
-}
-
-static void xlnx_zynqmp_init(Object *obj)
-{
- XlnxZynqMPState *s = XLNX_ZYNQMP(obj);
- int i;
-
- for (i = 0; i < XLNX_ZYNQMP_NUM_APU_CPUS; i++) {
- object_initialize(&s->apu_cpu[i], sizeof(s->apu_cpu[i]),
- "cortex-a53-" TYPE_ARM_CPU);
- object_property_add_child(obj, "apu-cpu[*]", OBJECT(&s->apu_cpu[i]),
- &error_abort);
- }
-
- for (i = 0; i < XLNX_ZYNQMP_NUM_RPU_CPUS; i++) {
- object_initialize(&s->rpu_cpu[i], sizeof(s->rpu_cpu[i]),
- "cortex-r5-" TYPE_ARM_CPU);
- object_property_add_child(obj, "rpu-cpu[*]", OBJECT(&s->rpu_cpu[i]),
- &error_abort);
- }
-
- object_property_add_link(obj, "ddr-ram", TYPE_MEMORY_REGION,
- (Object **)&s->ddr_ram,
- qdev_prop_allow_set_link_before_realize,
- OBJ_PROP_LINK_UNREF_ON_RELEASE, &error_abort);
-
- object_initialize(&s->gic, sizeof(s->gic), TYPE_ARM_GIC);
- qdev_set_parent_bus(DEVICE(&s->gic), sysbus_get_default());
-
- for (i = 0; i < XLNX_ZYNQMP_NUM_GEMS; i++) {
- object_initialize(&s->gem[i], sizeof(s->gem[i]), TYPE_CADENCE_GEM);
- qdev_set_parent_bus(DEVICE(&s->gem[i]), sysbus_get_default());
- }
-
- for (i = 0; i < XLNX_ZYNQMP_NUM_UARTS; i++) {
- object_initialize(&s->uart[i], sizeof(s->uart[i]), TYPE_CADENCE_UART);
- qdev_set_parent_bus(DEVICE(&s->uart[i]), sysbus_get_default());
- }
-
- object_initialize(&s->sata, sizeof(s->sata), TYPE_SYSBUS_AHCI);
- qdev_set_parent_bus(DEVICE(&s->sata), sysbus_get_default());
-
- for (i = 0; i < XLNX_ZYNQMP_NUM_SDHCI; i++) {
- object_initialize(&s->sdhci[i], sizeof(s->sdhci[i]),
- TYPE_SYSBUS_SDHCI);
- qdev_set_parent_bus(DEVICE(&s->sdhci[i]),
- sysbus_get_default());
- }
-
- for (i = 0; i < XLNX_ZYNQMP_NUM_SPIS; i++) {
- object_initialize(&s->spi[i], sizeof(s->spi[i]),
- TYPE_XILINX_SPIPS);
- qdev_set_parent_bus(DEVICE(&s->spi[i]), sysbus_get_default());
- }
-}
-
-static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
-{
- XlnxZynqMPState *s = XLNX_ZYNQMP(dev);
- MemoryRegion *system_memory = get_system_memory();
- uint8_t i;
- uint64_t ram_size;
- const char *boot_cpu = s->boot_cpu ? s->boot_cpu : "apu-cpu[0]";
- ram_addr_t ddr_low_size, ddr_high_size;
- qemu_irq gic_spi[GIC_NUM_SPI_INTR];
- Error *err = NULL;
-
- ram_size = memory_region_size(s->ddr_ram);
-
- /* Create the DDR Memory Regions. User friendly checks should happen at
- * the board level
- */
- if (ram_size > XLNX_ZYNQMP_MAX_LOW_RAM_SIZE) {
- /* The RAM size is above the maximum available for the low DDR.
- * Create the high DDR memory region as well.
- */
- assert(ram_size <= XLNX_ZYNQMP_MAX_RAM_SIZE);
- ddr_low_size = XLNX_ZYNQMP_MAX_LOW_RAM_SIZE;
- ddr_high_size = ram_size - XLNX_ZYNQMP_MAX_LOW_RAM_SIZE;
-
- memory_region_init_alias(&s->ddr_ram_high, NULL,
- "ddr-ram-high", s->ddr_ram,
- ddr_low_size, ddr_high_size);
- memory_region_add_subregion(get_system_memory(),
- XLNX_ZYNQMP_HIGH_RAM_START,
- &s->ddr_ram_high);
- } else {
- /* RAM must be non-zero */
- assert(ram_size);
- ddr_low_size = ram_size;
- }
-
- memory_region_init_alias(&s->ddr_ram_low, NULL,
- "ddr-ram-low", s->ddr_ram,
- 0, ddr_low_size);
- memory_region_add_subregion(get_system_memory(), 0, &s->ddr_ram_low);
-
- /* Create the four OCM banks */
- for (i = 0; i < XLNX_ZYNQMP_NUM_OCM_BANKS; i++) {
- char *ocm_name = g_strdup_printf("zynqmp.ocm_ram_bank_%d", i);
-
- memory_region_init_ram(&s->ocm_ram[i], NULL, ocm_name,
- XLNX_ZYNQMP_OCM_RAM_SIZE, &error_fatal);
- vmstate_register_ram_global(&s->ocm_ram[i]);
- memory_region_add_subregion(get_system_memory(),
- XLNX_ZYNQMP_OCM_RAM_0_ADDRESS +
- i * XLNX_ZYNQMP_OCM_RAM_SIZE,
- &s->ocm_ram[i]);
-
- g_free(ocm_name);
- }
-
- qdev_prop_set_uint32(DEVICE(&s->gic), "num-irq", GIC_NUM_SPI_INTR + 32);
- qdev_prop_set_uint32(DEVICE(&s->gic), "revision", 2);
- qdev_prop_set_uint32(DEVICE(&s->gic), "num-cpu", XLNX_ZYNQMP_NUM_APU_CPUS);
- object_property_set_bool(OBJECT(&s->gic), true, "realized", &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
- assert(ARRAY_SIZE(xlnx_zynqmp_gic_regions) == XLNX_ZYNQMP_GIC_REGIONS);
- for (i = 0; i < XLNX_ZYNQMP_GIC_REGIONS; i++) {
- SysBusDevice *gic = SYS_BUS_DEVICE(&s->gic);
- const XlnxZynqMPGICRegion *r = &xlnx_zynqmp_gic_regions[i];
- MemoryRegion *mr = sysbus_mmio_get_region(gic, r->region_index);
- uint32_t addr = r->address;
- int j;
-
- sysbus_mmio_map(gic, r->region_index, addr);
-
- for (j = 0; j < XLNX_ZYNQMP_GIC_ALIASES; j++) {
- MemoryRegion *alias = &s->gic_mr[i][j];
-
- addr += XLNX_ZYNQMP_GIC_REGION_SIZE;
- memory_region_init_alias(alias, OBJECT(s), "zynqmp-gic-alias", mr,
- 0, XLNX_ZYNQMP_GIC_REGION_SIZE);
- memory_region_add_subregion(system_memory, addr, alias);
- }
- }
-
- for (i = 0; i < XLNX_ZYNQMP_NUM_APU_CPUS; i++) {
- qemu_irq irq;
- char *name;
-
- object_property_set_int(OBJECT(&s->apu_cpu[i]), QEMU_PSCI_CONDUIT_SMC,
- "psci-conduit", &error_abort);
-
- name = object_get_canonical_path_component(OBJECT(&s->apu_cpu[i]));
- if (strcmp(name, boot_cpu)) {
- /* Secondary CPUs start in PSCI powered-down state */
- object_property_set_bool(OBJECT(&s->apu_cpu[i]), true,
- "start-powered-off", &error_abort);
- } else {
- s->boot_cpu_ptr = &s->apu_cpu[i];
- }
- g_free(name);
-
- object_property_set_int(OBJECT(&s->apu_cpu[i]), GIC_BASE_ADDR,
- "reset-cbar", &error_abort);
- object_property_set_bool(OBJECT(&s->apu_cpu[i]), true, "realized",
- &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
-
- sysbus_connect_irq(SYS_BUS_DEVICE(&s->gic), i,
- qdev_get_gpio_in(DEVICE(&s->apu_cpu[i]),
- ARM_CPU_IRQ));
- irq = qdev_get_gpio_in(DEVICE(&s->gic),
- arm_gic_ppi_index(i, ARM_PHYS_TIMER_PPI));
- qdev_connect_gpio_out(DEVICE(&s->apu_cpu[i]), 0, irq);
- irq = qdev_get_gpio_in(DEVICE(&s->gic),
- arm_gic_ppi_index(i, ARM_VIRT_TIMER_PPI));
- qdev_connect_gpio_out(DEVICE(&s->apu_cpu[i]), 1, irq);
- }
-
- for (i = 0; i < XLNX_ZYNQMP_NUM_RPU_CPUS; i++) {
- char *name;
-
- name = object_get_canonical_path_component(OBJECT(&s->rpu_cpu[i]));
- if (strcmp(name, boot_cpu)) {
- /* Secondary CPUs start in PSCI powered-down state */
- object_property_set_bool(OBJECT(&s->rpu_cpu[i]), true,
- "start-powered-off", &error_abort);
- } else {
- s->boot_cpu_ptr = &s->rpu_cpu[i];
- }
- g_free(name);
-
- object_property_set_bool(OBJECT(&s->rpu_cpu[i]), true, "reset-hivecs",
- &error_abort);
- object_property_set_bool(OBJECT(&s->rpu_cpu[i]), true, "realized",
- &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
- }
-
- if (!s->boot_cpu_ptr) {
- error_setg(errp, "ZynqMP Boot cpu %s not found", boot_cpu);
- return;
- }
-
- for (i = 0; i < GIC_NUM_SPI_INTR; i++) {
- gic_spi[i] = qdev_get_gpio_in(DEVICE(&s->gic), i);
- }
-
- for (i = 0; i < XLNX_ZYNQMP_NUM_GEMS; i++) {
- NICInfo *nd = &nd_table[i];
-
- if (nd->used) {
- qemu_check_nic_model(nd, TYPE_CADENCE_GEM);
- qdev_set_nic_properties(DEVICE(&s->gem[i]), nd);
- }
- object_property_set_bool(OBJECT(&s->gem[i]), true, "realized", &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->gem[i]), 0, gem_addr[i]);
- sysbus_connect_irq(SYS_BUS_DEVICE(&s->gem[i]), 0,
- gic_spi[gem_intr[i]]);
- }
-
- for (i = 0; i < XLNX_ZYNQMP_NUM_UARTS; i++) {
- object_property_set_bool(OBJECT(&s->uart[i]), true, "realized", &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->uart[i]), 0, uart_addr[i]);
- sysbus_connect_irq(SYS_BUS_DEVICE(&s->uart[i]), 0,
- gic_spi[uart_intr[i]]);
- }
-
- object_property_set_int(OBJECT(&s->sata), SATA_NUM_PORTS, "num-ports",
- &error_abort);
- object_property_set_bool(OBJECT(&s->sata), true, "realized", &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
-
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->sata), 0, SATA_ADDR);
- sysbus_connect_irq(SYS_BUS_DEVICE(&s->sata), 0, gic_spi[SATA_INTR]);
-
- for (i = 0; i < XLNX_ZYNQMP_NUM_SDHCI; i++) {
- char *bus_name;
-
- object_property_set_bool(OBJECT(&s->sdhci[i]), true,
- "realized", &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->sdhci[i]), 0,
- sdhci_addr[i]);
- sysbus_connect_irq(SYS_BUS_DEVICE(&s->sdhci[i]), 0,
- gic_spi[sdhci_intr[i]]);
- /* Alias controller SD bus to the SoC itself */
- bus_name = g_strdup_printf("sd-bus%d", i);
- object_property_add_alias(OBJECT(s), bus_name,
- OBJECT(&s->sdhci[i]), "sd-bus",
- &error_abort);
- g_free(bus_name);
- }
-
- for (i = 0; i < XLNX_ZYNQMP_NUM_SPIS; i++) {
- gchar *bus_name;
-
- object_property_set_bool(OBJECT(&s->spi[i]), true, "realized", &err);
-
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi[i]), 0, spi_addr[i]);
- sysbus_connect_irq(SYS_BUS_DEVICE(&s->spi[i]), 0,
- gic_spi[spi_intr[i]]);
-
- /* Alias controller SPI bus to the SoC itself */
- bus_name = g_strdup_printf("spi%d", i);
- object_property_add_alias(OBJECT(s), bus_name,
- OBJECT(&s->spi[i]), "spi0",
- &error_abort);
- g_free(bus_name);
- }
-}
-
-static Property xlnx_zynqmp_props[] = {
- DEFINE_PROP_STRING("boot-cpu", XlnxZynqMPState, boot_cpu),
- DEFINE_PROP_END_OF_LIST()
-};
-
-static void xlnx_zynqmp_class_init(ObjectClass *oc, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
-
- dc->props = xlnx_zynqmp_props;
- dc->realize = xlnx_zynqmp_realize;
-
- /*
- * Reason: creates an ARM CPU, thus use after free(), see
- * arm_cpu_class_init()
- */
- dc->cannot_destroy_with_object_finalize_yet = true;
-}
-
-static const TypeInfo xlnx_zynqmp_type_info = {
- .name = TYPE_XLNX_ZYNQMP,
- .parent = TYPE_DEVICE,
- .instance_size = sizeof(XlnxZynqMPState),
- .instance_init = xlnx_zynqmp_init,
- .class_init = xlnx_zynqmp_class_init,
-};
-
-static void xlnx_zynqmp_register_types(void)
-{
- type_register_static(&xlnx_zynqmp_type_info);
-}
-
-type_init(xlnx_zynqmp_register_types)
diff --git a/qemu/hw/arm/z2.c b/qemu/hw/arm/z2.c
deleted file mode 100644
index aea895a50..000000000
--- a/qemu/hw/arm/z2.c
+++ /dev/null
@@ -1,382 +0,0 @@
-/*
- * PXA270-based Zipit Z2 device
- *
- * Copyright (c) 2011 by Vasily Khoruzhick <anarsoul@gmail.com>
- *
- * Code is based on mainstone platform.
- *
- * This code is licensed under the GNU GPL v2.
- *
- * Contributions after 2012-01-13 are licensed under the terms of the
- * GNU GPL, version 2 or (at your option) any later version.
- */
-
-#include "qemu/osdep.h"
-#include "hw/hw.h"
-#include "hw/arm/pxa.h"
-#include "hw/arm/arm.h"
-#include "hw/devices.h"
-#include "hw/i2c/i2c.h"
-#include "hw/ssi/ssi.h"
-#include "hw/boards.h"
-#include "sysemu/sysemu.h"
-#include "hw/block/flash.h"
-#include "sysemu/block-backend.h"
-#include "ui/console.h"
-#include "audio/audio.h"
-#include "exec/address-spaces.h"
-#include "sysemu/qtest.h"
-
-#ifdef DEBUG_Z2
-#define DPRINTF(fmt, ...) \
- printf(fmt, ## __VA_ARGS__)
-#else
-#define DPRINTF(fmt, ...)
-#endif
-
-static const struct keymap map[0x100] = {
- [0 ... 0xff] = { -1, -1 },
- [0x3b] = {0, 0}, /* Option = F1 */
- [0xc8] = {0, 1}, /* Up */
- [0xd0] = {0, 2}, /* Down */
- [0xcb] = {0, 3}, /* Left */
- [0xcd] = {0, 4}, /* Right */
- [0xcf] = {0, 5}, /* End */
- [0x0d] = {0, 6}, /* KPPLUS */
- [0xc7] = {1, 0}, /* Home */
- [0x10] = {1, 1}, /* Q */
- [0x17] = {1, 2}, /* I */
- [0x22] = {1, 3}, /* G */
- [0x2d] = {1, 4}, /* X */
- [0x1c] = {1, 5}, /* Enter */
- [0x0c] = {1, 6}, /* KPMINUS */
- [0xc9] = {2, 0}, /* PageUp */
- [0x11] = {2, 1}, /* W */
- [0x18] = {2, 2}, /* O */
- [0x23] = {2, 3}, /* H */
- [0x2e] = {2, 4}, /* C */
- [0x38] = {2, 5}, /* LeftAlt */
- [0xd1] = {3, 0}, /* PageDown */
- [0x12] = {3, 1}, /* E */
- [0x19] = {3, 2}, /* P */
- [0x24] = {3, 3}, /* J */
- [0x2f] = {3, 4}, /* V */
- [0x2a] = {3, 5}, /* LeftShift */
- [0x01] = {4, 0}, /* Esc */
- [0x13] = {4, 1}, /* R */
- [0x1e] = {4, 2}, /* A */
- [0x25] = {4, 3}, /* K */
- [0x30] = {4, 4}, /* B */
- [0x1d] = {4, 5}, /* LeftCtrl */
- [0x0f] = {5, 0}, /* Tab */
- [0x14] = {5, 1}, /* T */
- [0x1f] = {5, 2}, /* S */
- [0x26] = {5, 3}, /* L */
- [0x31] = {5, 4}, /* N */
- [0x39] = {5, 5}, /* Space */
- [0x3c] = {6, 0}, /* Stop = F2 */
- [0x15] = {6, 1}, /* Y */
- [0x20] = {6, 2}, /* D */
- [0x0e] = {6, 3}, /* Backspace */
- [0x32] = {6, 4}, /* M */
- [0x33] = {6, 5}, /* Comma */
- [0x3d] = {7, 0}, /* Play = F3 */
- [0x16] = {7, 1}, /* U */
- [0x21] = {7, 2}, /* F */
- [0x2c] = {7, 3}, /* Z */
- [0x27] = {7, 4}, /* Semicolon */
- [0x34] = {7, 5}, /* Dot */
-};
-
-#define Z2_RAM_SIZE 0x02000000
-#define Z2_FLASH_BASE 0x00000000
-#define Z2_FLASH_SIZE 0x00800000
-
-static struct arm_boot_info z2_binfo = {
- .loader_start = PXA2XX_SDRAM_BASE,
- .ram_size = Z2_RAM_SIZE,
-};
-
-#define Z2_GPIO_SD_DETECT 96
-#define Z2_GPIO_AC_IN 0
-#define Z2_GPIO_KEY_ON 1
-#define Z2_GPIO_LCD_CS 88
-
-typedef struct {
- SSISlave ssidev;
- int32_t selected;
- int32_t enabled;
- uint8_t buf[3];
- uint32_t cur_reg;
- int pos;
-} ZipitLCD;
-
-static uint32_t zipit_lcd_transfer(SSISlave *dev, uint32_t value)
-{
- ZipitLCD *z = FROM_SSI_SLAVE(ZipitLCD, dev);
- uint16_t val;
- if (z->selected) {
- z->buf[z->pos] = value & 0xff;
- z->pos++;
- }
- if (z->pos == 3) {
- switch (z->buf[0]) {
- case 0x74:
- DPRINTF("%s: reg: 0x%.2x\n", __func__, z->buf[2]);
- z->cur_reg = z->buf[2];
- break;
- case 0x76:
- val = z->buf[1] << 8 | z->buf[2];
- DPRINTF("%s: value: 0x%.4x\n", __func__, val);
- if (z->cur_reg == 0x22 && val == 0x0000) {
- z->enabled = 1;
- printf("%s: LCD enabled\n", __func__);
- } else if (z->cur_reg == 0x10 && val == 0x0000) {
- z->enabled = 0;
- printf("%s: LCD disabled\n", __func__);
- }
- break;
- default:
- DPRINTF("%s: unknown command!\n", __func__);
- break;
- }
- z->pos = 0;
- }
- return 0;
-}
-
-static void z2_lcd_cs(void *opaque, int line, int level)
-{
- ZipitLCD *z2_lcd = opaque;
- z2_lcd->selected = !level;
-}
-
-static int zipit_lcd_init(SSISlave *dev)
-{
- ZipitLCD *z = FROM_SSI_SLAVE(ZipitLCD, dev);
- z->selected = 0;
- z->enabled = 0;
- z->pos = 0;
-
- return 0;
-}
-
-static VMStateDescription vmstate_zipit_lcd_state = {
- .name = "zipit-lcd",
- .version_id = 2,
- .minimum_version_id = 2,
- .fields = (VMStateField[]) {
- VMSTATE_SSI_SLAVE(ssidev, ZipitLCD),
- VMSTATE_INT32(selected, ZipitLCD),
- VMSTATE_INT32(enabled, ZipitLCD),
- VMSTATE_BUFFER(buf, ZipitLCD),
- VMSTATE_UINT32(cur_reg, ZipitLCD),
- VMSTATE_INT32(pos, ZipitLCD),
- VMSTATE_END_OF_LIST(),
- }
-};
-
-static void zipit_lcd_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
- SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
-
- k->init = zipit_lcd_init;
- k->transfer = zipit_lcd_transfer;
- dc->vmsd = &vmstate_zipit_lcd_state;
-}
-
-static const TypeInfo zipit_lcd_info = {
- .name = "zipit-lcd",
- .parent = TYPE_SSI_SLAVE,
- .instance_size = sizeof(ZipitLCD),
- .class_init = zipit_lcd_class_init,
-};
-
-#define TYPE_AER915 "aer915"
-#define AER915(obj) OBJECT_CHECK(AER915State, (obj), TYPE_AER915)
-
-typedef struct AER915State {
- I2CSlave parent_obj;
-
- int len;
- uint8_t buf[3];
-} AER915State;
-
-static int aer915_send(I2CSlave *i2c, uint8_t data)
-{
- AER915State *s = AER915(i2c);
-
- s->buf[s->len] = data;
- if (s->len++ > 2) {
- DPRINTF("%s: message too long (%i bytes)\n",
- __func__, s->len);
- return 1;
- }
-
- if (s->len == 2) {
- DPRINTF("%s: reg %d value 0x%02x\n", __func__,
- s->buf[0], s->buf[1]);
- }
-
- return 0;
-}
-
-static void aer915_event(I2CSlave *i2c, enum i2c_event event)
-{
- AER915State *s = AER915(i2c);
-
- switch (event) {
- case I2C_START_SEND:
- s->len = 0;
- break;
- case I2C_START_RECV:
- if (s->len != 1) {
- DPRINTF("%s: short message!?\n", __func__);
- }
- break;
- case I2C_FINISH:
- break;
- default:
- break;
- }
-}
-
-static int aer915_recv(I2CSlave *slave)
-{
- AER915State *s = AER915(slave);
- int retval = 0x00;
-
- switch (s->buf[0]) {
- /* Return hardcoded battery voltage,
- * 0xf0 means ~4.1V
- */
- case 0x02:
- retval = 0xf0;
- break;
- /* Return 0x00 for other regs,
- * we don't know what they are for,
- * anyway they return 0x00 on real hardware.
- */
- default:
- break;
- }
-
- return retval;
-}
-
-static int aer915_init(I2CSlave *i2c)
-{
- /* Nothing to do. */
- return 0;
-}
-
-static VMStateDescription vmstate_aer915_state = {
- .name = "aer915",
- .version_id = 1,
- .minimum_version_id = 1,
- .fields = (VMStateField[]) {
- VMSTATE_INT32(len, AER915State),
- VMSTATE_BUFFER(buf, AER915State),
- VMSTATE_END_OF_LIST(),
- }
-};
-
-static void aer915_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
- I2CSlaveClass *k = I2C_SLAVE_CLASS(klass);
-
- k->init = aer915_init;
- k->event = aer915_event;
- k->recv = aer915_recv;
- k->send = aer915_send;
- dc->vmsd = &vmstate_aer915_state;
-}
-
-static const TypeInfo aer915_info = {
- .name = TYPE_AER915,
- .parent = TYPE_I2C_SLAVE,
- .instance_size = sizeof(AER915State),
- .class_init = aer915_class_init,
-};
-
-static void z2_init(MachineState *machine)
-{
- const char *cpu_model = machine->cpu_model;
- const char *kernel_filename = machine->kernel_filename;
- const char *kernel_cmdline = machine->kernel_cmdline;
- const char *initrd_filename = machine->initrd_filename;
- MemoryRegion *address_space_mem = get_system_memory();
- uint32_t sector_len = 0x10000;
- PXA2xxState *mpu;
- DriveInfo *dinfo;
- int be;
- void *z2_lcd;
- I2CBus *bus;
- DeviceState *wm;
-
- if (!cpu_model) {
- cpu_model = "pxa270-c5";
- }
-
- /* Setup CPU & memory */
- mpu = pxa270_init(address_space_mem, z2_binfo.ram_size, cpu_model);
-
-#ifdef TARGET_WORDS_BIGENDIAN
- be = 1;
-#else
- be = 0;
-#endif
- dinfo = drive_get(IF_PFLASH, 0, 0);
- if (!dinfo && !qtest_enabled()) {
- fprintf(stderr, "Flash image must be given with the "
- "'pflash' parameter\n");
- exit(1);
- }
-
- if (!pflash_cfi01_register(Z2_FLASH_BASE,
- NULL, "z2.flash0", Z2_FLASH_SIZE,
- dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
- sector_len, Z2_FLASH_SIZE / sector_len,
- 4, 0, 0, 0, 0, be)) {
- fprintf(stderr, "qemu: Error registering flash memory.\n");
- exit(1);
- }
-
- /* setup keypad */
- pxa27x_register_keypad(mpu->kp, map, 0x100);
-
- /* MMC/SD host */
- pxa2xx_mmci_handlers(mpu->mmc,
- NULL,
- qdev_get_gpio_in(mpu->gpio, Z2_GPIO_SD_DETECT));
-
- type_register_static(&zipit_lcd_info);
- type_register_static(&aer915_info);
- z2_lcd = ssi_create_slave(mpu->ssp[1], "zipit-lcd");
- bus = pxa2xx_i2c_bus(mpu->i2c[0]);
- i2c_create_slave(bus, TYPE_AER915, 0x55);
- wm = i2c_create_slave(bus, "wm8750", 0x1b);
- mpu->i2s->opaque = wm;
- mpu->i2s->codec_out = wm8750_dac_dat;
- mpu->i2s->codec_in = wm8750_adc_dat;
- wm8750_data_req_set(wm, mpu->i2s->data_req, mpu->i2s);
-
- qdev_connect_gpio_out(mpu->gpio, Z2_GPIO_LCD_CS,
- qemu_allocate_irq(z2_lcd_cs, z2_lcd, 0));
-
- z2_binfo.kernel_filename = kernel_filename;
- z2_binfo.kernel_cmdline = kernel_cmdline;
- z2_binfo.initrd_filename = initrd_filename;
- z2_binfo.board_id = 0x6dd;
- arm_load_kernel(mpu->cpu, &z2_binfo);
-}
-
-static void z2_machine_init(MachineClass *mc)
-{
- mc->desc = "Zipit Z2 (PXA27x)";
- mc->init = z2_init;
-}
-
-DEFINE_MACHINE("z2", z2_machine_init)