diff options
author | Peter Maydell | 2022-01-28 17:59:56 +0100 |
---|---|---|
committer | Peter Maydell | 2022-01-28 17:59:57 +0100 |
commit | 95a6af2a006e7160c958215c20e513ed29a0a76c (patch) | |
tree | a9a59028cf7a68b2cea32629c2666dbdf0af9717 /hw/arm/xlnx-versal.c | |
parent | Merge remote-tracking branch 'remotes/bonzini-gitlab/tags/for-upstream' into ... (diff) | |
parent | target/arm: Use correct entrypoint for SVC taken from Hyp to Hyp (diff) | |
download | qemu-95a6af2a006e7160c958215c20e513ed29a0a76c.tar.gz qemu-95a6af2a006e7160c958215c20e513ed29a0a76c.tar.xz qemu-95a6af2a006e7160c958215c20e513ed29a0a76c.zip |
Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20220128' into staging
target-arm queue:
* Update copyright dates to 2022
* hw/armv7m: Fix broken VMStateDescription
* hw/char/exynos4210_uart: Fix crash on trying to load VM state
* rtc: Move RTC function prototypes to their own header
* xlnx-versal-virt: Support PMC SLCR
* xlnx-versal-virt: Support OSPI flash memory controller
* scripts: Explain the difference between linux-headers and standard-headers
* target/arm: Log CPU index in 'Taking exception' log
* arm_gicv3_its: Various bugfixes and cleanups
* arm_gicv3_its: Implement the missing MOVI and MOVALL commands
* ast2600: Fix address mapping of second SPI controller
* target/arm: Use correct entrypoint for SVC taken from Hyp to Hyp
# gpg: Signature made Fri 28 Jan 2022 15:29:36 GMT
# gpg: using RSA key E1A5C593CD419DE28E8315CF3C2525ED14360CDE
# gpg: issuer "peter.maydell@linaro.org"
# gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" [ultimate]
# gpg: aka "Peter Maydell <pmaydell@gmail.com>" [ultimate]
# gpg: aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" [ultimate]
# Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83 15CF 3C25 25ED 1436 0CDE
* remotes/pmaydell/tags/pull-target-arm-20220128: (32 commits)
target/arm: Use correct entrypoint for SVC taken from Hyp to Hyp
hw/arm: ast2600: Fix address mapping of second SPI controller
hw/intc/arm_gicv3_its: Implement MOVI
hw/intc/arm_gicv3_its: Implement MOVALL
hw/intc/arm_gicv3_its: Check table bounds against correct limit
hw/intc/arm_gicv3_its: Make GITS_BASER<n> RAZ/WI for unimplemented registers
hw/intc/arm_gicv3_its: Provide read accessor for translation_ops
hw/intc/arm_gicv3: Set GICR_CTLR.CES if LPIs are supported
hw/intc/arm_gicv3_redist: Remove unnecessary zero checks
hw/intc/arm_gicv3_its: Sort ITS command list into numeric order
hw/intc/arm_gicv3: Honour GICD_CTLR.EnableGrp1NS for LPIs
hw/intc/arm_gicv3_its: Don't clear GITS_CWRITER on writes to GITS_CBASER
hw/intc/arm_gicv3_its: Don't clear GITS_CREADR when GITS_CTLR.ENABLED is set
hw/intc/arm_gicv3: Initialise dma_as in GIC, not ITS
hw/intc/arm_gicv3_its: Add tracepoints
target/arm: Log CPU index in 'Taking exception' log
scripts: Explain the difference between linux-headers and standard-headers
MAINTAINERS: Remove myself (for raspi).
MAINTAINERS: Add an entry for Xilinx Versal OSPI
hw/arm/xlnx-versal-virt: Connect mt35xu01g flashes to the OSPI
...
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/arm/xlnx-versal.c')
-rw-r--r-- | hw/arm/xlnx-versal.c | 190 |
1 files changed, 188 insertions, 2 deletions
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c index b2705b6925..ab58bebfd2 100644 --- a/hw/arm/xlnx-versal.c +++ b/hw/arm/xlnx-versal.c @@ -21,10 +21,15 @@ #include "kvm_arm.h" #include "hw/misc/unimp.h" #include "hw/arm/xlnx-versal.h" +#include "qemu/log.h" +#include "hw/sysbus.h" #define XLNX_VERSAL_ACPU_TYPE ARM_CPU_TYPE_NAME("cortex-a72") #define GEM_REVISION 0x40070106 +#define VERSAL_NUM_PMC_APB_IRQS 3 +#define NUM_OSPI_IRQ_LINES 3 + static void versal_create_apu_cpus(Versal *s) { int i; @@ -260,6 +265,26 @@ static void versal_create_sds(Versal *s, qemu_irq *pic) } } +static void versal_create_pmc_apb_irq_orgate(Versal *s, qemu_irq *pic) +{ + DeviceState *orgate; + + /* + * The VERSAL_PMC_APB_IRQ is an 'or' of the interrupts from the following + * models: + * - RTC + * - BBRAM + * - PMC SLCR + */ + object_initialize_child(OBJECT(s), "pmc-apb-irq-orgate", + &s->pmc.apb_irq_orgate, TYPE_OR_IRQ); + orgate = DEVICE(&s->pmc.apb_irq_orgate); + object_property_set_int(OBJECT(orgate), + "num-lines", VERSAL_NUM_PMC_APB_IRQS, &error_fatal); + qdev_realize(orgate, NULL, &error_fatal); + qdev_connect_gpio_out(orgate, 0, pic[VERSAL_PMC_APB_IRQ]); +} + static void versal_create_rtc(Versal *s, qemu_irq *pic) { SysBusDevice *sbd; @@ -277,7 +302,8 @@ static void versal_create_rtc(Versal *s, qemu_irq *pic) * TODO: Connect the ALARM and SECONDS interrupts once our RTC model * supports them. */ - sysbus_connect_irq(sbd, 1, pic[VERSAL_RTC_APB_ERR_IRQ]); + sysbus_connect_irq(sbd, 1, + qdev_get_gpio_in(DEVICE(&s->pmc.apb_irq_orgate), 0)); } static void versal_create_xrams(Versal *s, qemu_irq *pic) @@ -328,7 +354,8 @@ static void versal_create_bbram(Versal *s, qemu_irq *pic) sysbus_realize(sbd, &error_fatal); memory_region_add_subregion(&s->mr_ps, MM_PMC_BBRAM_CTRL, sysbus_mmio_get_region(sbd, 0)); - sysbus_connect_irq(sbd, 0, pic[VERSAL_BBRAM_APB_IRQ_0]); + sysbus_connect_irq(sbd, 0, + qdev_get_gpio_in(DEVICE(&s->pmc.apb_irq_orgate), 1)); } static void versal_realize_efuse_part(Versal *s, Object *dev, hwaddr base) @@ -369,6 +396,114 @@ static void versal_create_efuse(Versal *s, qemu_irq *pic) sysbus_connect_irq(SYS_BUS_DEVICE(ctrl), 0, pic[VERSAL_EFUSE_IRQ]); } +static void versal_create_pmc_iou_slcr(Versal *s, qemu_irq *pic) +{ + SysBusDevice *sbd; + + object_initialize_child(OBJECT(s), "versal-pmc-iou-slcr", &s->pmc.iou.slcr, + TYPE_XILINX_VERSAL_PMC_IOU_SLCR); + + sbd = SYS_BUS_DEVICE(&s->pmc.iou.slcr); + sysbus_realize(sbd, &error_fatal); + + memory_region_add_subregion(&s->mr_ps, MM_PMC_PMC_IOU_SLCR, + sysbus_mmio_get_region(sbd, 0)); + + sysbus_connect_irq(sbd, 0, + qdev_get_gpio_in(DEVICE(&s->pmc.apb_irq_orgate), 2)); +} + +static void versal_create_ospi(Versal *s, qemu_irq *pic) +{ + SysBusDevice *sbd; + MemoryRegion *mr_dac; + qemu_irq ospi_mux_sel; + DeviceState *orgate; + + memory_region_init(&s->pmc.iou.ospi.linear_mr, OBJECT(s), + "versal-ospi-linear-mr" , MM_PMC_OSPI_DAC_SIZE); + + object_initialize_child(OBJECT(s), "versal-ospi", &s->pmc.iou.ospi.ospi, + TYPE_XILINX_VERSAL_OSPI); + + mr_dac = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->pmc.iou.ospi.ospi), 1); + memory_region_add_subregion(&s->pmc.iou.ospi.linear_mr, 0x0, mr_dac); + + /* Create the OSPI destination DMA */ + object_initialize_child(OBJECT(s), "versal-ospi-dma-dst", + &s->pmc.iou.ospi.dma_dst, + TYPE_XLNX_CSU_DMA); + + object_property_set_link(OBJECT(&s->pmc.iou.ospi.dma_dst), + "dma", OBJECT(get_system_memory()), + &error_abort); + + sbd = SYS_BUS_DEVICE(&s->pmc.iou.ospi.dma_dst); + sysbus_realize(sbd, &error_fatal); + + memory_region_add_subregion(&s->mr_ps, MM_PMC_OSPI_DMA_DST, + sysbus_mmio_get_region(sbd, 0)); + + /* Create the OSPI source DMA */ + object_initialize_child(OBJECT(s), "versal-ospi-dma-src", + &s->pmc.iou.ospi.dma_src, + TYPE_XLNX_CSU_DMA); + + object_property_set_bool(OBJECT(&s->pmc.iou.ospi.dma_src), "is-dst", + false, &error_abort); + + object_property_set_link(OBJECT(&s->pmc.iou.ospi.dma_src), + "dma", OBJECT(mr_dac), &error_abort); + + object_property_set_link(OBJECT(&s->pmc.iou.ospi.dma_src), + "stream-connected-dma", + OBJECT(&s->pmc.iou.ospi.dma_dst), + &error_abort); + + sbd = SYS_BUS_DEVICE(&s->pmc.iou.ospi.dma_src); + sysbus_realize(sbd, &error_fatal); + + memory_region_add_subregion(&s->mr_ps, MM_PMC_OSPI_DMA_SRC, + sysbus_mmio_get_region(sbd, 0)); + + /* Realize the OSPI */ + object_property_set_link(OBJECT(&s->pmc.iou.ospi.ospi), "dma-src", + OBJECT(&s->pmc.iou.ospi.dma_src), &error_abort); + + sbd = SYS_BUS_DEVICE(&s->pmc.iou.ospi.ospi); + sysbus_realize(sbd, &error_fatal); + + memory_region_add_subregion(&s->mr_ps, MM_PMC_OSPI, + sysbus_mmio_get_region(sbd, 0)); + + memory_region_add_subregion(&s->mr_ps, MM_PMC_OSPI_DAC, + &s->pmc.iou.ospi.linear_mr); + + /* ospi_mux_sel */ + ospi_mux_sel = qdev_get_gpio_in_named(DEVICE(&s->pmc.iou.ospi.ospi), + "ospi-mux-sel", 0); + qdev_connect_gpio_out_named(DEVICE(&s->pmc.iou.slcr), "ospi-mux-sel", 0, + ospi_mux_sel); + + /* OSPI irq */ + object_initialize_child(OBJECT(s), "ospi-irq-orgate", + &s->pmc.iou.ospi.irq_orgate, TYPE_OR_IRQ); + object_property_set_int(OBJECT(&s->pmc.iou.ospi.irq_orgate), + "num-lines", NUM_OSPI_IRQ_LINES, &error_fatal); + + orgate = DEVICE(&s->pmc.iou.ospi.irq_orgate); + qdev_realize(orgate, NULL, &error_fatal); + + sysbus_connect_irq(SYS_BUS_DEVICE(&s->pmc.iou.ospi.ospi), 0, + qdev_get_gpio_in(orgate, 0)); + sysbus_connect_irq(SYS_BUS_DEVICE(&s->pmc.iou.ospi.dma_src), 0, + qdev_get_gpio_in(orgate, 1)); + sysbus_connect_irq(SYS_BUS_DEVICE(&s->pmc.iou.ospi.dma_dst), 0, + qdev_get_gpio_in(orgate, 2)); + + qdev_connect_gpio_out(orgate, 0, pic[VERSAL_OSPI_IRQ]); +} + /* This takes the board allocated linear DDR memory and creates aliases * for each split DDR range/aperture on the Versal address map. */ @@ -425,8 +560,31 @@ static void versal_unimp_area(Versal *s, const char *name, memory_region_add_subregion(mr, base, mr_dev); } +static void versal_unimp_sd_emmc_sel(void *opaque, int n, int level) +{ + qemu_log_mask(LOG_UNIMP, + "Selecting between enabling SD mode or eMMC mode on " + "controller %d is not yet implemented\n", n); +} + +static void versal_unimp_qspi_ospi_mux_sel(void *opaque, int n, int level) +{ + qemu_log_mask(LOG_UNIMP, + "Selecting between enabling the QSPI or OSPI linear address " + "region is not yet implemented\n"); +} + +static void versal_unimp_irq_parity_imr(void *opaque, int n, int level) +{ + qemu_log_mask(LOG_UNIMP, + "PMC SLCR parity interrupt behaviour " + "is not yet implemented\n"); +} + static void versal_unimp(Versal *s) { + qemu_irq gpio_in; + versal_unimp_area(s, "psm", &s->mr_ps, MM_PSM_START, MM_PSM_END - MM_PSM_START); versal_unimp_area(s, "crl", &s->mr_ps, @@ -441,6 +599,31 @@ static void versal_unimp(Versal *s) MM_IOU_SCNTR, MM_IOU_SCNTR_SIZE); versal_unimp_area(s, "iou-scntr-seucre", &s->mr_ps, MM_IOU_SCNTRS, MM_IOU_SCNTRS_SIZE); + + qdev_init_gpio_in_named(DEVICE(s), versal_unimp_sd_emmc_sel, + "sd-emmc-sel-dummy", 2); + qdev_init_gpio_in_named(DEVICE(s), versal_unimp_qspi_ospi_mux_sel, + "qspi-ospi-mux-sel-dummy", 1); + qdev_init_gpio_in_named(DEVICE(s), versal_unimp_irq_parity_imr, + "irq-parity-imr-dummy", 1); + + gpio_in = qdev_get_gpio_in_named(DEVICE(s), "sd-emmc-sel-dummy", 0); + qdev_connect_gpio_out_named(DEVICE(&s->pmc.iou.slcr), "sd-emmc-sel", 0, + gpio_in); + + gpio_in = qdev_get_gpio_in_named(DEVICE(s), "sd-emmc-sel-dummy", 1); + qdev_connect_gpio_out_named(DEVICE(&s->pmc.iou.slcr), "sd-emmc-sel", 1, + gpio_in); + + gpio_in = qdev_get_gpio_in_named(DEVICE(s), "qspi-ospi-mux-sel-dummy", 0); + qdev_connect_gpio_out_named(DEVICE(&s->pmc.iou.slcr), + "qspi-ospi-mux-sel", 0, + gpio_in); + + gpio_in = qdev_get_gpio_in_named(DEVICE(s), "irq-parity-imr-dummy", 0); + qdev_connect_gpio_out_named(DEVICE(&s->pmc.iou.slcr), + SYSBUS_DEVICE_GPIO_IRQ, 0, + gpio_in); } static void versal_realize(DeviceState *dev, Error **errp) @@ -455,10 +638,13 @@ static void versal_realize(DeviceState *dev, Error **errp) versal_create_gems(s, pic); versal_create_admas(s, pic); versal_create_sds(s, pic); + versal_create_pmc_apb_irq_orgate(s, pic); versal_create_rtc(s, pic); versal_create_xrams(s, pic); versal_create_bbram(s, pic); versal_create_efuse(s, pic); + versal_create_pmc_iou_slcr(s, pic); + versal_create_ospi(s, pic); versal_map_ddr(s); versal_unimp(s); |