diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2021-02-03 12:55:44 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2021-02-03 12:55:44 +0000 |
commit | 99ae0cd90d3e41b424582cf74bcf32498ca81bb9 (patch) | |
tree | 6bb9bd3778c27d35c3e9c7f7c0458b7112502591 | |
parent | 8360ebeb4f4a707984cafd1a22c049ec82ddcb4c (diff) | |
parent | fd8f71b95da86f530aae3d02a14b0ccd9e024772 (diff) |
Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20210203' into staging
target-arm queue:
* hw/intc/arm_gic: Allow to use QTest without crashing
* hw/char/exynos4210_uart: Fix buffer size reporting with FIFO disabled
* hw/char/exynos4210_uart: Fix missing call to report ready for input
* hw/arm/smmuv3: Fix addr_mask for range-based invalidation
* hw/ssi/imx_spi: Fix various minor bugs
* hw/intc/arm_gic: Fix interrupt ID in GICD_SGIR register
* hw/arm: Add missing Kconfig dependencies
* hw/arm: Display CPU type in machine description
# gpg: Signature made Wed 03 Feb 2021 10:16: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-20210203: (21 commits)
hw/arm: Display CPU type in machine description
hw/net/can: ZynqMP CAN device requires PTIMER
hw/arm/xlnx-versal: Versal SoC requires ZynqMP peripherals
hw/arm/xlnx-versal: Versal SoC requires ZDMA
hw/arm/exynos4210: Add missing dependency on OR_IRQ
hw/arm/stm32f405_soc: Add missing dependency on OR_IRQ
hw/intc/arm_gic: Fix interrupt ID in GICD_SGIR register
hw/ssi: imx_spi: Correct tx and rx fifo endianness
hw/ssi: imx_spi: Correct the burst length > 32 bit transfer logic
hw/ssi: imx_spi: Round up the burst length to be multiple of 8
hw/ssi: imx_spi: Disable chip selects when controller is disabled
hw/ssi: imx_spi: Rework imx_spi_write() to handle block disabled
hw/ssi: imx_spi: Rework imx_spi_read() to handle block disabled
hw/ssi: imx_spi: Rework imx_spi_reset() to keep CONREG register value
hw/ssi: imx_spi: Remove pointless variable initialization
hw/ssi: imx_spi: Remove imx_spi_update_irq() in imx_spi_reset()
hw/ssi: imx_spi: Use a macro for number of chip selects supported
hw/arm/smmuv3: Fix addr_mask for range-based invalidation
hw/char/exynos4210_uart: Fix missing call to report ready for input
hw/char/exynos4210_uart: Fix buffer size reporting with FIFO disabled
...
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r-- | hw/Kconfig | 1 | ||||
-rw-r--r-- | hw/arm/Kconfig | 5 | ||||
-rw-r--r-- | hw/arm/digic_boards.c | 2 | ||||
-rw-r--r-- | hw/arm/microbit.c | 2 | ||||
-rw-r--r-- | hw/arm/netduino2.c | 2 | ||||
-rw-r--r-- | hw/arm/netduinoplus2.c | 2 | ||||
-rw-r--r-- | hw/arm/orangepi.c | 2 | ||||
-rw-r--r-- | hw/arm/smmuv3.c | 4 | ||||
-rw-r--r-- | hw/arm/stellaris.c | 4 | ||||
-rw-r--r-- | hw/char/exynos4210_uart.c | 7 | ||||
-rw-r--r-- | hw/dma/Kconfig | 3 | ||||
-rw-r--r-- | hw/dma/meson.build | 2 | ||||
-rw-r--r-- | hw/intc/arm_gic.c | 5 | ||||
-rw-r--r-- | hw/ssi/imx_spi.c | 153 | ||||
-rw-r--r-- | include/hw/ssi/imx_spi.h | 5 |
15 files changed, 130 insertions, 69 deletions
diff --git a/hw/Kconfig b/hw/Kconfig index 5ad3c6b5a4..d4cec9e476 100644 --- a/hw/Kconfig +++ b/hw/Kconfig @@ -81,3 +81,4 @@ config XLNX_ZYNQMP bool select REGISTER select CAN_BUS + select PTIMER diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig index 13cc42dcc8..be017b997a 100644 --- a/hw/arm/Kconfig +++ b/hw/arm/Kconfig @@ -52,6 +52,7 @@ config EXYNOS4 select PTIMER select SDHCI select USB_EHCI_SYSBUS + select OR_IRQ config HIGHBANK bool @@ -336,6 +337,7 @@ config STM32F205_SOC config STM32F405_SOC bool select ARM_V7M + select OR_IRQ select STM32F4XX_SYSCFG select STM32F4XX_EXTI @@ -352,6 +354,7 @@ config XLNX_ZYNQMP_ARM select XILINX_AXI select XILINX_SPIPS select XLNX_ZYNQMP + select XLNX_ZDMA config XLNX_VERSAL bool @@ -360,6 +363,8 @@ config XLNX_VERSAL select CADENCE select VIRTIO_MMIO select UNIMP + select XLNX_ZDMA + select XLNX_ZYNQMP config NPCM7XX bool diff --git a/hw/arm/digic_boards.c b/hw/arm/digic_boards.c index be12873673..6cdc1d83fc 100644 --- a/hw/arm/digic_boards.c +++ b/hw/arm/digic_boards.c @@ -142,7 +142,7 @@ static void canon_a1100_init(MachineState *machine) static void canon_a1100_machine_init(MachineClass *mc) { - mc->desc = "Canon PowerShot A1100 IS"; + mc->desc = "Canon PowerShot A1100 IS (ARM946)"; mc->init = &canon_a1100_init; mc->ignore_memory_transaction_failures = true; mc->default_ram_size = 64 * MiB; diff --git a/hw/arm/microbit.c b/hw/arm/microbit.c index 0947491cb9..e9494334ce 100644 --- a/hw/arm/microbit.c +++ b/hw/arm/microbit.c @@ -64,7 +64,7 @@ static void microbit_machine_class_init(ObjectClass *oc, void *data) { MachineClass *mc = MACHINE_CLASS(oc); - mc->desc = "BBC micro:bit"; + mc->desc = "BBC micro:bit (Cortex-M0)"; mc->init = microbit_init; mc->max_cpus = 1; } diff --git a/hw/arm/netduino2.c b/hw/arm/netduino2.c index 8f10334144..1733b71507 100644 --- a/hw/arm/netduino2.c +++ b/hw/arm/netduino2.c @@ -54,7 +54,7 @@ static void netduino2_init(MachineState *machine) static void netduino2_machine_init(MachineClass *mc) { - mc->desc = "Netduino 2 Machine"; + mc->desc = "Netduino 2 Machine (Cortex-M3)"; mc->init = netduino2_init; mc->ignore_memory_transaction_failures = true; } diff --git a/hw/arm/netduinoplus2.c b/hw/arm/netduinoplus2.c index 68abd3ec69..d3ad7a2b67 100644 --- a/hw/arm/netduinoplus2.c +++ b/hw/arm/netduinoplus2.c @@ -55,7 +55,7 @@ static void netduinoplus2_init(MachineState *machine) static void netduinoplus2_machine_init(MachineClass *mc) { - mc->desc = "Netduino Plus 2 Machine"; + mc->desc = "Netduino Plus 2 Machine (Cortex-M4)"; mc->init = netduinoplus2_init; } diff --git a/hw/arm/orangepi.c b/hw/arm/orangepi.c index d6306dfdda..40cdb5c6d2 100644 --- a/hw/arm/orangepi.c +++ b/hw/arm/orangepi.c @@ -113,7 +113,7 @@ static void orangepi_init(MachineState *machine) static void orangepi_machine_init(MachineClass *mc) { - mc->desc = "Orange Pi PC"; + mc->desc = "Orange Pi PC (Cortex-A7)"; mc->init = orangepi_init; mc->block_default_type = IF_SD; mc->units_per_default_bus = 1; diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c index bbca0e9f20..98b99d4fe8 100644 --- a/hw/arm/smmuv3.c +++ b/hw/arm/smmuv3.c @@ -801,7 +801,7 @@ static void smmuv3_notify_iova(IOMMUMemoryRegion *mr, { SMMUDevice *sdev = container_of(mr, SMMUDevice, iommu); IOMMUTLBEvent event; - uint8_t granule = tg; + uint8_t granule; if (!tg) { SMMUEventInfo event = {.inval_ste_allowed = true}; @@ -821,6 +821,8 @@ static void smmuv3_notify_iova(IOMMUMemoryRegion *mr, return; } granule = tt->granule_sz; + } else { + granule = tg * 2 + 10; } event.type = IOMMU_NOTIFIER_UNMAP; diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c index ad72c0959f..27292ec411 100644 --- a/hw/arm/stellaris.c +++ b/hw/arm/stellaris.c @@ -1538,7 +1538,7 @@ static void lm3s811evb_class_init(ObjectClass *oc, void *data) { MachineClass *mc = MACHINE_CLASS(oc); - mc->desc = "Stellaris LM3S811EVB"; + mc->desc = "Stellaris LM3S811EVB (Cortex-M3)"; mc->init = lm3s811evb_init; mc->ignore_memory_transaction_failures = true; mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m3"); @@ -1554,7 +1554,7 @@ static void lm3s6965evb_class_init(ObjectClass *oc, void *data) { MachineClass *mc = MACHINE_CLASS(oc); - mc->desc = "Stellaris LM3S6965EVB"; + mc->desc = "Stellaris LM3S6965EVB (Cortex-M3)"; mc->init = lm3s6965evb_init; mc->ignore_memory_transaction_failures = true; mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m3"); diff --git a/hw/char/exynos4210_uart.c b/hw/char/exynos4210_uart.c index 6361df2ad3..80d401a379 100644 --- a/hw/char/exynos4210_uart.c +++ b/hw/char/exynos4210_uart.c @@ -519,6 +519,7 @@ static uint64_t exynos4210_uart_read(void *opaque, hwaddr offset, s->reg[I_(UTRSTAT)] &= ~UTRSTAT_Rx_BUFFER_DATA_READY; res = s->reg[I_(URXH)]; } + qemu_chr_fe_accept_input(&s->chr); exynos4210_uart_update_dmabusy(s); trace_exynos_uart_read(s->channel, offset, exynos4210_uart_regname(offset), res); @@ -553,7 +554,11 @@ static int exynos4210_uart_can_receive(void *opaque) { Exynos4210UartState *s = (Exynos4210UartState *)opaque; - return fifo_empty_elements_number(&s->rx); + if (s->reg[I_(UFCON)] & UFCON_FIFO_ENABLE) { + return fifo_empty_elements_number(&s->rx); + } else { + return !(s->reg[I_(UTRSTAT)] & UTRSTAT_Rx_BUFFER_DATA_READY); + } } static void exynos4210_uart_receive(void *opaque, const uint8_t *buf, int size) diff --git a/hw/dma/Kconfig b/hw/dma/Kconfig index d67492d36c..5d6be1a7a7 100644 --- a/hw/dma/Kconfig +++ b/hw/dma/Kconfig @@ -18,6 +18,9 @@ config ZYNQ_DEVCFG bool select REGISTER +config XLNX_ZDMA + bool + config STP2000 bool diff --git a/hw/dma/meson.build b/hw/dma/meson.build index b991d7698c..47b4a7cb47 100644 --- a/hw/dma/meson.build +++ b/hw/dma/meson.build @@ -9,7 +9,7 @@ softmmu_ss.add(when: 'CONFIG_ZYNQ_DEVCFG', if_true: files('xlnx-zynq-devcfg.c')) softmmu_ss.add(when: 'CONFIG_ETRAXFS', if_true: files('etraxfs_dma.c')) softmmu_ss.add(when: 'CONFIG_STP2000', if_true: files('sparc32_dma.c')) softmmu_ss.add(when: 'CONFIG_XLNX_ZYNQMP_ARM', if_true: files('xlnx_dpdma.c')) -softmmu_ss.add(when: 'CONFIG_XLNX_ZYNQMP_ARM', if_true: files('xlnx-zdma.c')) +softmmu_ss.add(when: 'CONFIG_XLNX_ZDMA', if_true: files('xlnx-zdma.c')) softmmu_ss.add(when: 'CONFIG_OMAP', if_true: files('omap_dma.c', 'soc_dma.c')) softmmu_ss.add(when: 'CONFIG_PXA2XX', if_true: files('pxa2xx_dma.c')) softmmu_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2835_dma.c')) diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c index af41e2fb44..a994b1f024 100644 --- a/hw/intc/arm_gic.c +++ b/hw/intc/arm_gic.c @@ -28,6 +28,7 @@ #include "qemu/module.h" #include "trace.h" #include "sysemu/kvm.h" +#include "sysemu/qtest.h" /* #define DEBUG_GIC */ @@ -57,7 +58,7 @@ static const uint8_t gic_id_gicv2[] = { static inline int gic_get_current_cpu(GICState *s) { - if (s->num_cpu > 1) { + if (!qtest_enabled() && s->num_cpu > 1) { return current_cpu->cpu_index; } return 0; @@ -1476,7 +1477,7 @@ static void gic_dist_writel(void *opaque, hwaddr offset, int target_cpu; cpu = gic_get_current_cpu(s); - irq = value & 0x3ff; + irq = value & 0xf; switch ((value >> 24) & 3) { case 0: mask = (value >> 16) & ALL_CPU_MASK; diff --git a/hw/ssi/imx_spi.c b/hw/ssi/imx_spi.c index d8885ae454..189423bb3a 100644 --- a/hw/ssi/imx_spi.c +++ b/hw/ssi/imx_spi.c @@ -128,7 +128,14 @@ static uint8_t imx_spi_selected_channel(IMXSPIState *s) static uint32_t imx_spi_burst_length(IMXSPIState *s) { - return EXTRACT(s->regs[ECSPI_CONREG], ECSPI_CONREG_BURST_LENGTH) + 1; + uint32_t burst; + + burst = EXTRACT(s->regs[ECSPI_CONREG], ECSPI_CONREG_BURST_LENGTH) + 1; + if (burst % 8) { + burst = ROUND_UP(burst, 8); + } + + return burst; } static bool imx_spi_is_enabled(IMXSPIState *s) @@ -162,7 +169,6 @@ static void imx_spi_flush_txfifo(IMXSPIState *s) while (!fifo32_is_empty(&s->tx_fifo)) { int tx_burst = 0; - int index = 0; if (s->burst_length <= 0) { s->burst_length = imx_spi_burst_length(s); @@ -178,12 +184,12 @@ static void imx_spi_flush_txfifo(IMXSPIState *s) DPRINTF("data tx:0x%08x\n", tx); - tx_burst = MIN(s->burst_length, 32); + tx_burst = (s->burst_length % 32) ? : 32; rx = 0; while (tx_burst > 0) { - uint8_t byte = tx & 0xff; + uint8_t byte = tx >> (tx_burst - 8); DPRINTF("writing 0x%02x\n", (uint32_t)byte); @@ -192,13 +198,11 @@ static void imx_spi_flush_txfifo(IMXSPIState *s) DPRINTF("0x%02x read\n", (uint32_t)byte); - tx = tx >> 8; - rx |= (byte << (index * 8)); + rx = (rx << 8) | byte; /* Remove 8 bits from the actual burst */ tx_burst -= 8; s->burst_length -= 8; - index++; } DPRINTF("data rx:0x%08x\n", rx); @@ -228,22 +232,49 @@ static void imx_spi_flush_txfifo(IMXSPIState *s) fifo32_num_used(&s->tx_fifo), fifo32_num_used(&s->rx_fifo)); } -static void imx_spi_reset(DeviceState *dev) +static void imx_spi_common_reset(IMXSPIState *s) { - IMXSPIState *s = IMX_SPI(dev); - - DPRINTF("\n"); - - memset(s->regs, 0, sizeof(s->regs)); + int i; - s->regs[ECSPI_STATREG] = 0x00000003; + for (i = 0; i < ARRAY_SIZE(s->regs); i++) { + switch (i) { + case ECSPI_CONREG: + /* CONREG is not updated on soft reset */ + break; + case ECSPI_STATREG: + s->regs[i] = 0x00000003; + break; + default: + s->regs[i] = 0; + break; + } + } imx_spi_rxfifo_reset(s); imx_spi_txfifo_reset(s); + s->burst_length = 0; +} + +static void imx_spi_soft_reset(IMXSPIState *s) +{ + int i; + + imx_spi_common_reset(s); + imx_spi_update_irq(s); - s->burst_length = 0; + for (i = 0; i < ECSPI_NUM_CS; i++) { + qemu_set_irq(s->cs_lines[i], 1); + } +} + +static void imx_spi_reset(DeviceState *dev) +{ + IMXSPIState *s = IMX_SPI(dev); + + imx_spi_common_reset(s); + s->regs[ECSPI_CONREG] = 0; } static uint64_t imx_spi_read(void *opaque, hwaddr offset, unsigned size) @@ -258,42 +289,40 @@ static uint64_t imx_spi_read(void *opaque, hwaddr offset, unsigned size) return 0; } - switch (index) { - case ECSPI_RXDATA: - if (!imx_spi_is_enabled(s)) { - value = 0; - } else if (fifo32_is_empty(&s->rx_fifo)) { - /* value is undefined */ - value = 0xdeadbeef; - } else { - /* read from the RX FIFO */ - value = fifo32_pop(&s->rx_fifo); - } - - break; - case ECSPI_TXDATA: - qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Trying to read from TX FIFO\n", - TYPE_IMX_SPI, __func__); - - /* Reading from TXDATA gives 0 */ - - break; - case ECSPI_MSGDATA: - qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Trying to read from MSG FIFO\n", - TYPE_IMX_SPI, __func__); + value = s->regs[index]; + + if (imx_spi_is_enabled(s)) { + switch (index) { + case ECSPI_RXDATA: + if (fifo32_is_empty(&s->rx_fifo)) { + /* value is undefined */ + value = 0xdeadbeef; + } else { + /* read from the RX FIFO */ + value = fifo32_pop(&s->rx_fifo); + } + break; + case ECSPI_TXDATA: + qemu_log_mask(LOG_GUEST_ERROR, + "[%s]%s: Trying to read from TX FIFO\n", + TYPE_IMX_SPI, __func__); - /* Reading from MSGDATA gives 0 */ + /* Reading from TXDATA gives 0 */ + break; + case ECSPI_MSGDATA: + qemu_log_mask(LOG_GUEST_ERROR, + "[%s]%s: Trying to read from MSG FIFO\n", + TYPE_IMX_SPI, __func__); + /* Reading from MSGDATA gives 0 */ + break; + default: + break; + } - break; - default: - value = s->regs[index]; - break; + imx_spi_update_irq(s); } - DPRINTF("reg[%s] => 0x%" PRIx32 "\n", imx_spi_reg_name(index), value); - imx_spi_update_irq(s); - return (uint64_t)value; } @@ -303,6 +332,7 @@ static void imx_spi_write(void *opaque, hwaddr offset, uint64_t value, IMXSPIState *s = opaque; uint32_t index = offset >> 2; uint32_t change_mask; + uint32_t burst; if (index >= ECSPI_MAX) { qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad register at offset 0x%" @@ -313,6 +343,14 @@ static void imx_spi_write(void *opaque, hwaddr offset, uint64_t value, DPRINTF("reg[%s] <= 0x%" PRIx32 "\n", imx_spi_reg_name(index), (uint32_t)value); + if (!imx_spi_is_enabled(s)) { + /* Block is disabled */ + if (index != ECSPI_CONREG) { + /* Ignore access */ + return; + } + } + change_mask = s->regs[index] ^ value; switch (index) { @@ -321,10 +359,7 @@ static void imx_spi_write(void *opaque, hwaddr offset, uint64_t value, TYPE_IMX_SPI, __func__); break; case ECSPI_TXDATA: - if (!imx_spi_is_enabled(s)) { - /* Ignore writes if device is disabled */ - break; - } else if (fifo32_is_full(&s->tx_fifo)) { + if (fifo32_is_full(&s->tx_fifo)) { /* Ignore writes if queue is full */ break; } @@ -350,9 +385,17 @@ static void imx_spi_write(void *opaque, hwaddr offset, uint64_t value, case ECSPI_CONREG: s->regs[ECSPI_CONREG] = value; + burst = EXTRACT(s->regs[ECSPI_CONREG], ECSPI_CONREG_BURST_LENGTH) + 1; + if (burst % 8) { + qemu_log_mask(LOG_UNIMP, + "[%s]%s: burst length %d not supported: rounding up to next multiple of 8\n", + TYPE_IMX_SPI, __func__, burst); + } + if (!imx_spi_is_enabled(s)) { - /* device is disabled, so this is a reset */ - imx_spi_reset(DEVICE(s)); + /* device is disabled, so this is a soft reset */ + imx_spi_soft_reset(s); + return; } @@ -361,7 +404,7 @@ static void imx_spi_write(void *opaque, hwaddr offset, uint64_t value, /* We are in master mode */ - for (i = 0; i < 4; i++) { + for (i = 0; i < ECSPI_NUM_CS; i++) { qemu_set_irq(s->cs_lines[i], i == imx_spi_selected_channel(s) ? 0 : 1); } @@ -424,12 +467,10 @@ static void imx_spi_realize(DeviceState *dev, Error **errp) sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem); sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq); - for (i = 0; i < 4; ++i) { + for (i = 0; i < ECSPI_NUM_CS; ++i) { sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->cs_lines[i]); } - s->burst_length = 0; - fifo32_create(&s->tx_fifo, ECSPI_FIFO_SIZE); fifo32_create(&s->rx_fifo, ECSPI_FIFO_SIZE); } diff --git a/include/hw/ssi/imx_spi.h b/include/hw/ssi/imx_spi.h index b82b17f364..eeaf49bbac 100644 --- a/include/hw/ssi/imx_spi.h +++ b/include/hw/ssi/imx_spi.h @@ -77,6 +77,9 @@ #define EXTRACT(value, name) extract32(value, name##_SHIFT, name##_LENGTH) +/* number of chip selects supported */ +#define ECSPI_NUM_CS 4 + #define TYPE_IMX_SPI "imx.spi" OBJECT_DECLARE_SIMPLE_TYPE(IMXSPIState, IMX_SPI) @@ -89,7 +92,7 @@ struct IMXSPIState { qemu_irq irq; - qemu_irq cs_lines[4]; + qemu_irq cs_lines[ECSPI_NUM_CS]; SSIBus *bus; |