aboutsummaryrefslogtreecommitdiff
path: root/hw/arm/xilinx_zynq.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/arm/xilinx_zynq.c')
-rw-r--r--hw/arm/xilinx_zynq.c128
1 files changed, 95 insertions, 33 deletions
diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c
index 3c56b9a..0372cd0 100644
--- a/hw/arm/xilinx_zynq.c
+++ b/hw/arm/xilinx_zynq.c
@@ -21,7 +21,7 @@
#include "hw/sysbus.h"
#include "hw/arm/boot.h"
#include "net/net.h"
-#include "sysemu/sysemu.h"
+#include "system/system.h"
#include "hw/boards.h"
#include "hw/block/flash.h"
#include "hw/loader.h"
@@ -34,7 +34,8 @@
#include "hw/net/cadence_gem.h"
#include "hw/cpu/a9mpcore.h"
#include "hw/qdev-clock.h"
-#include "sysemu/reset.h"
+#include "hw/misc/unimp.h"
+#include "system/reset.h"
#include "qom/object.h"
#include "exec/tswap.h"
#include "target/arm/cpu-qom.h"
@@ -53,11 +54,11 @@ OBJECT_DECLARE_SIMPLE_TYPE(ZynqMachineState, ZYNQ_MACHINE)
#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
+#define GIC_EXT_IRQS 64 /* Zynq 7000 SoC */
+
static const int dma_irqs[8] = {
46, 47, 48, 49, 72, 73, 74, 75
};
@@ -206,7 +207,7 @@ static void zynq_init(MachineState *machine)
MemoryRegion *ocm_ram = g_new(MemoryRegion, 1);
DeviceState *dev, *slcr;
SysBusDevice *busdev;
- qemu_irq pic[64];
+ qemu_irq pic[GIC_EXT_IRQS];
int n;
unsigned int smp_cpus = machine->smp.cpus;
@@ -219,14 +220,6 @@ static void zynq_init(MachineState *machine)
for (n = 0; n < smp_cpus; n++) {
Object *cpuobj = object_new(machine->cpu_type);
- /*
- * 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")) {
- object_property_set_bool(cpuobj, "has_el3", false, &error_fatal);
- }
-
object_property_set_int(cpuobj, "midr", ZYNQ_BOARD_MIDR,
&error_fatal);
object_property_set_int(cpuobj, "reset-cbar", MPCORE_PERIPHBASE,
@@ -270,6 +263,7 @@ static void zynq_init(MachineState *machine)
dev = qdev_new(TYPE_A9MPCORE_PRIV);
qdev_prop_set_uint32(dev, "num-cpu", smp_cpus);
+ qdev_prop_set_uint32(dev, "num-irq", GIC_EXT_IRQS + GIC_INTERNAL);
busdev = SYS_BUS_DEVICE(dev);
sysbus_realize_and_unref(busdev, &error_fatal);
sysbus_mmio_map(busdev, 0, MPCORE_PERIPHBASE);
@@ -284,16 +278,16 @@ static void zynq_init(MachineState *machine)
qdev_get_gpio_in(cpudev, ARM_CPU_FIQ));
}
- for (n = 0; n < 64; n++) {
+ for (n = 0; n < GIC_EXT_IRQS; n++) {
pic[n] = qdev_get_gpio_in(dev, n);
}
- n = zynq_init_spi_flashes(0xE0006000, pic[58 - IRQ_OFFSET], false, 0);
- n = zynq_init_spi_flashes(0xE0007000, pic[81 - IRQ_OFFSET], false, n);
- n = zynq_init_spi_flashes(0xE000D000, pic[51 - IRQ_OFFSET], true, n);
+ n = zynq_init_spi_flashes(0xE0006000, pic[58 - GIC_INTERNAL], false, 0);
+ n = zynq_init_spi_flashes(0xE0007000, pic[81 - GIC_INTERNAL], false, n);
+ n = zynq_init_spi_flashes(0xE000D000, pic[51 - GIC_INTERNAL], true, n);
- sysbus_create_simple(TYPE_CHIPIDEA, 0xE0002000, pic[53 - IRQ_OFFSET]);
- sysbus_create_simple(TYPE_CHIPIDEA, 0xE0003000, pic[76 - IRQ_OFFSET]);
+ sysbus_create_simple(TYPE_CHIPIDEA, 0xE0002000, pic[53 - GIC_INTERNAL]);
+ sysbus_create_simple(TYPE_CHIPIDEA, 0xE0003000, pic[76 - GIC_INTERNAL]);
dev = qdev_new(TYPE_CADENCE_UART);
busdev = SYS_BUS_DEVICE(dev);
@@ -302,7 +296,7 @@ static void zynq_init(MachineState *machine)
qdev_get_clock_out(slcr, "uart0_ref_clk"));
sysbus_realize_and_unref(busdev, &error_fatal);
sysbus_mmio_map(busdev, 0, 0xE0000000);
- sysbus_connect_irq(busdev, 0, pic[59 - IRQ_OFFSET]);
+ sysbus_connect_irq(busdev, 0, pic[59 - GIC_INTERNAL]);
dev = qdev_new(TYPE_CADENCE_UART);
busdev = SYS_BUS_DEVICE(dev);
qdev_prop_set_chr(dev, "chardev", serial_hd(1));
@@ -310,15 +304,15 @@ static void zynq_init(MachineState *machine)
qdev_get_clock_out(slcr, "uart1_ref_clk"));
sysbus_realize_and_unref(busdev, &error_fatal);
sysbus_mmio_map(busdev, 0, 0xE0001000);
- sysbus_connect_irq(busdev, 0, pic[82 - IRQ_OFFSET]);
+ sysbus_connect_irq(busdev, 0, pic[82 - GIC_INTERNAL]);
sysbus_create_varargs("cadence_ttc", 0xF8001000,
- pic[42-IRQ_OFFSET], pic[43-IRQ_OFFSET], pic[44-IRQ_OFFSET], NULL);
+ pic[42-GIC_INTERNAL], pic[43-GIC_INTERNAL], pic[44-GIC_INTERNAL], NULL);
sysbus_create_varargs("cadence_ttc", 0xF8002000,
- pic[69-IRQ_OFFSET], pic[70-IRQ_OFFSET], pic[71-IRQ_OFFSET], NULL);
+ pic[69-GIC_INTERNAL], pic[70-GIC_INTERNAL], pic[71-GIC_INTERNAL], NULL);
- gem_init(0xE000B000, pic[54 - IRQ_OFFSET]);
- gem_init(0xE000C000, pic[77 - IRQ_OFFSET]);
+ gem_init(0xE000B000, pic[54 - GIC_INTERNAL]);
+ gem_init(0xE000C000, pic[77 - GIC_INTERNAL]);
for (n = 0; n < 2; n++) {
int hci_irq = n ? 79 : 56;
@@ -337,7 +331,7 @@ static void zynq_init(MachineState *machine)
qdev_prop_set_uint64(dev, "capareg", ZYNQ_SDHCI_CAPABILITIES);
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, hci_addr);
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[hci_irq - IRQ_OFFSET]);
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[hci_irq - GIC_INTERNAL]);
di = drive_get(IF_SD, 0, n);
blk = di ? blk_by_legacy_dinfo(di) : NULL;
@@ -350,7 +344,7 @@ static void zynq_init(MachineState *machine)
dev = qdev_new(TYPE_ZYNQ_XADC);
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, 0xF8007100);
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[39-IRQ_OFFSET]);
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[39-GIC_INTERNAL]);
dev = qdev_new("pl330");
object_property_set_link(OBJECT(dev), "memory",
@@ -370,17 +364,86 @@ static void zynq_init(MachineState *machine)
busdev = SYS_BUS_DEVICE(dev);
sysbus_realize_and_unref(busdev, &error_fatal);
sysbus_mmio_map(busdev, 0, 0xF8003000);
- sysbus_connect_irq(busdev, 0, pic[45-IRQ_OFFSET]); /* abort irq line */
+ sysbus_connect_irq(busdev, 0, pic[45-GIC_INTERNAL]); /* abort irq line */
for (n = 0; n < ARRAY_SIZE(dma_irqs); ++n) { /* event irqs */
- sysbus_connect_irq(busdev, n + 1, pic[dma_irqs[n] - IRQ_OFFSET]);
+ sysbus_connect_irq(busdev, n + 1, pic[dma_irqs[n] - GIC_INTERNAL]);
}
dev = qdev_new("xlnx.ps7-dev-cfg");
busdev = SYS_BUS_DEVICE(dev);
sysbus_realize_and_unref(busdev, &error_fatal);
- sysbus_connect_irq(busdev, 0, pic[40 - IRQ_OFFSET]);
+ sysbus_connect_irq(busdev, 0, pic[40 - GIC_INTERNAL]);
sysbus_mmio_map(busdev, 0, 0xF8007000);
+ /*
+ * Refer to the ug585-Zynq-7000-TRM manual B.3 (Module Summary) and
+ * the zynq-7000.dtsi. Add placeholders for unimplemented devices.
+ */
+ create_unimplemented_device("zynq.i2c0", 0xE0004000, 4 * KiB);
+ create_unimplemented_device("zynq.i2c1", 0xE0005000, 4 * KiB);
+ create_unimplemented_device("zynq.can0", 0xE0008000, 4 * KiB);
+ create_unimplemented_device("zynq.can1", 0xE0009000, 4 * KiB);
+ create_unimplemented_device("zynq.gpio", 0xE000A000, 4 * KiB);
+ create_unimplemented_device("zynq.smcc", 0xE000E000, 4 * KiB);
+
+ /* Direct Memory Access Controller, PL330, Non-Secure Mode */
+ create_unimplemented_device("zynq.dma_ns", 0xF8004000, 4 * KiB);
+
+ /* System Watchdog Timer Registers */
+ create_unimplemented_device("zynq.swdt", 0xF8005000, 4 * KiB);
+
+ /* DDR memory controller */
+ create_unimplemented_device("zynq.ddrc", 0xF8006000, 4 * KiB);
+
+ /* AXI_HP Interface (AFI) */
+ create_unimplemented_device("zynq.axi_hp0", 0xF8008000, 0x28);
+ create_unimplemented_device("zynq.axi_hp1", 0xF8009000, 0x28);
+ create_unimplemented_device("zynq.axi_hp2", 0xF800A000, 0x28);
+ create_unimplemented_device("zynq.axi_hp3", 0xF800B000, 0x28);
+
+ create_unimplemented_device("zynq.efuse", 0xF800d000, 0x20);
+
+ /* Embedded Trace Buffer */
+ create_unimplemented_device("zynq.etb", 0xF8801000, 4 * KiB);
+
+ /* Cross Trigger Interface, ETB and TPIU */
+ create_unimplemented_device("zynq.cti_etb_tpiu", 0xF8802000, 4 * KiB);
+
+ /* Trace Port Interface Unit */
+ create_unimplemented_device("zynq.tpiu", 0xF8803000, 4 * KiB);
+
+ /* CoreSight Trace Funnel */
+ create_unimplemented_device("zynq.funnel", 0xF8804000, 4 * KiB);
+
+ /* Instrumentation Trace Macrocell */
+ create_unimplemented_device("zynq.itm", 0xF8805000, 4 * KiB);
+
+ /* Cross Trigger Interface, FTM */
+ create_unimplemented_device("zynq.cti_ftm", 0xF8809000, 4 * KiB);
+
+ /* Fabric Trace Macrocell */
+ create_unimplemented_device("zynq.ftm", 0xF880B000, 4 * KiB);
+
+ /* Cortex A9 Performance Monitoring Unit, CPU */
+ create_unimplemented_device("cortex-a9.pmu0", 0xF8891000, 4 * KiB);
+ create_unimplemented_device("cortex-a9.pmu1", 0xF8893000, 4 * KiB);
+
+ /* Cross Trigger Interface, CPU */
+ create_unimplemented_device("zynq.cpu_cti0", 0xF8898000, 4 * KiB);
+ create_unimplemented_device("zynq.cpu_cti1", 0xF8899000, 4 * KiB);
+
+ /* CoreSight PTM-A9, CPU */
+ create_unimplemented_device("cortex-a9.ptm0", 0xF889c000, 4 * KiB);
+ create_unimplemented_device("cortex-a9.ptm1", 0xF889d000, 4 * KiB);
+
+ /* AMBA NIC301 TrustZone */
+ create_unimplemented_device("zynq.trustZone", 0xF8900000, 0x20);
+
+ /* AMBA Network Interconnect Advanced Quality of Service (QoS-301) */
+ create_unimplemented_device("zynq.qos301_cpu", 0xF8946000, 0x130);
+ create_unimplemented_device("zynq.qos301_dmac", 0xF8947000, 0x130);
+ create_unimplemented_device("zynq.qos301_iou", 0xF8948000, 0x130);
+
zynq_binfo.ram_size = machine->ram_size;
zynq_binfo.board_id = 0xd32;
zynq_binfo.loader_start = 0;
@@ -390,7 +453,7 @@ static void zynq_init(MachineState *machine)
arm_load_kernel(zynq_machine->cpu[0], machine, &zynq_binfo);
}
-static void zynq_machine_class_init(ObjectClass *oc, void *data)
+static void zynq_machine_class_init(ObjectClass *oc, const void *data)
{
static const char * const valid_cpu_types[] = {
ARM_CPU_TYPE_NAME("cortex-a9"),
@@ -398,10 +461,9 @@ static void zynq_machine_class_init(ObjectClass *oc, void *data)
};
MachineClass *mc = MACHINE_CLASS(oc);
ObjectProperty *prop;
- mc->desc = "Xilinx Zynq Platform Baseboard for Cortex-A9";
+ mc->desc = "Xilinx Zynq 7000 Platform Baseboard for Cortex-A9";
mc->init = zynq_init;
mc->max_cpus = ZYNQ_MAX_CPUS;
- mc->no_sdcard = 1;
mc->ignore_memory_transaction_failures = true;
mc->valid_cpu_types = valid_cpu_types;
mc->default_ram_id = "zynq.ext_ram";