diff options
Diffstat (limited to 'hw/arm/xilinx_zynq.c')
-rw-r--r-- | hw/arm/xilinx_zynq.c | 128 |
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"; |