[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 20/20] hw/arm/exynos4210: Connect serial port DMA busy signals wit
From: |
Peter Maydell |
Subject: |
[PULL 20/20] hw/arm/exynos4210: Connect serial port DMA busy signals with pl330 |
Date: |
Thu, 23 Jan 2020 15:30:41 +0000 |
From: Guenter Roeck <address@hidden>
The Exynos4210 serial driver uses an interrupt line to signal if receive
data is available. Connect that interrupt with the DMA controller's
'peripheral busy' gpio pin to stop the DMA if there is no more receive
data available. Without this patch, receive DMA runs wild and fills the
entire receive DMA buffer with invalid data.
Reviewed-by: Peter Maydell <address@hidden>
Signed-off-by: Guenter Roeck <address@hidden>
Message-id: address@hidden
Signed-off-by: Peter Maydell <address@hidden>
---
hw/arm/exynos4210.c | 42 +++++++++++++++++++++++++++++-------------
1 file changed, 29 insertions(+), 13 deletions(-)
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
index 7701a3fa8bd..59a27bdd68f 100644
--- a/hw/arm/exynos4210.c
+++ b/hw/arm/exynos4210.c
@@ -166,8 +166,8 @@ static uint64_t exynos4210_calc_affinity(int cpu)
return (0x9 << ARM_AFF1_SHIFT) | cpu;
}
-static void pl330_create(uint32_t base, qemu_or_irq *orgate, qemu_irq irq,
- int nreq, int nevents, int width)
+static DeviceState *pl330_create(uint32_t base, qemu_or_irq *orgate,
+ qemu_irq irq, int nreq, int nevents, int
width)
{
SysBusDevice *busdev;
DeviceState *dev;
@@ -196,6 +196,7 @@ static void pl330_create(uint32_t base, qemu_or_irq
*orgate, qemu_irq irq,
sysbus_connect_irq(busdev, i, qdev_get_gpio_in(DEVICE(orgate), i));
}
qdev_connect_gpio_out(DEVICE(orgate), 0, irq);
+ return dev;
}
static void exynos4210_realize(DeviceState *socdev, Error **errp)
@@ -204,7 +205,7 @@ static void exynos4210_realize(DeviceState *socdev, Error
**errp)
MemoryRegion *system_mem = get_system_memory();
qemu_irq gate_irq[EXYNOS4210_NCPUS][EXYNOS4210_IRQ_GATE_NINPUTS];
SysBusDevice *busdev;
- DeviceState *dev;
+ DeviceState *dev, *uart[4], *pl330[3];
int i, n;
for (n = 0; n < EXYNOS4210_NCPUS; n++) {
@@ -390,19 +391,19 @@ static void exynos4210_realize(DeviceState *socdev, Error
**errp)
/*** UARTs ***/
- exynos4210_uart_create(EXYNOS4210_UART0_BASE_ADDR,
+ uart[0] = exynos4210_uart_create(EXYNOS4210_UART0_BASE_ADDR,
EXYNOS4210_UART0_FIFO_SIZE, 0, serial_hd(0),
s->irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP,
0)]);
- exynos4210_uart_create(EXYNOS4210_UART1_BASE_ADDR,
+ uart[1] = exynos4210_uart_create(EXYNOS4210_UART1_BASE_ADDR,
EXYNOS4210_UART1_FIFO_SIZE, 1, serial_hd(1),
s->irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP,
1)]);
- exynos4210_uart_create(EXYNOS4210_UART2_BASE_ADDR,
+ uart[2] = exynos4210_uart_create(EXYNOS4210_UART2_BASE_ADDR,
EXYNOS4210_UART2_FIFO_SIZE, 2, serial_hd(2),
s->irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP,
2)]);
- exynos4210_uart_create(EXYNOS4210_UART3_BASE_ADDR,
+ uart[3] = exynos4210_uart_create(EXYNOS4210_UART3_BASE_ADDR,
EXYNOS4210_UART3_FIFO_SIZE, 3, serial_hd(3),
s->irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP,
3)]);
@@ -450,12 +451,27 @@ static void exynos4210_realize(DeviceState *socdev, Error
**errp)
s->irq_table[exynos4210_get_irq(28, 3)]);
/*** DMA controllers ***/
- pl330_create(EXYNOS4210_PL330_BASE0_ADDR, &s->pl330_irq_orgate[0],
- s->irq_table[exynos4210_get_irq(21, 0)], 32, 32, 32);
- pl330_create(EXYNOS4210_PL330_BASE1_ADDR, &s->pl330_irq_orgate[1],
- s->irq_table[exynos4210_get_irq(21, 1)], 32, 32, 32);
- pl330_create(EXYNOS4210_PL330_BASE2_ADDR, &s->pl330_irq_orgate[2],
- s->irq_table[exynos4210_get_irq(20, 1)], 1, 31, 64);
+ pl330[0] = pl330_create(EXYNOS4210_PL330_BASE0_ADDR,
+ &s->pl330_irq_orgate[0],
+ s->irq_table[exynos4210_get_irq(21, 0)],
+ 32, 32, 32);
+ pl330[1] = pl330_create(EXYNOS4210_PL330_BASE1_ADDR,
+ &s->pl330_irq_orgate[1],
+ s->irq_table[exynos4210_get_irq(21, 1)],
+ 32, 32, 32);
+ pl330[2] = pl330_create(EXYNOS4210_PL330_BASE2_ADDR,
+ &s->pl330_irq_orgate[2],
+ s->irq_table[exynos4210_get_irq(20, 1)],
+ 1, 31, 64);
+
+ sysbus_connect_irq(SYS_BUS_DEVICE(uart[0]), 1,
+ qdev_get_gpio_in(pl330[0], 15));
+ sysbus_connect_irq(SYS_BUS_DEVICE(uart[1]), 1,
+ qdev_get_gpio_in(pl330[1], 15));
+ sysbus_connect_irq(SYS_BUS_DEVICE(uart[2]), 1,
+ qdev_get_gpio_in(pl330[0], 17));
+ sysbus_connect_irq(SYS_BUS_DEVICE(uart[3]), 1,
+ qdev_get_gpio_in(pl330[1], 17));
}
static void exynos4210_init(Object *obj)
--
2.20.1
- [PULL 02/20] target/arm: Fix PAuth sbox functions, (continued)
- [PULL 02/20] target/arm: Fix PAuth sbox functions, Peter Maydell, 2020/01/23
- [PULL 09/20] docs: Create stub system manual, Peter Maydell, 2020/01/23
- [PULL 08/20] qemu-nbd: Convert invocation documentation to rST, Peter Maydell, 2020/01/23
- [PULL 12/20] hw/misc/stm32f4xx_syscfg: Fix copy/paste error, Peter Maydell, 2020/01/23
- [PULL 14/20] hw/core/or-irq: Increase limit of or-lines to 48, Peter Maydell, 2020/01/23
- [PULL 13/20] dma/pl330: Convert to support tracing, Peter Maydell, 2020/01/23
- [PULL 15/20] hw/arm/exynos4210: Fix DMA initialization, Peter Maydell, 2020/01/23
- [PULL 11/20] target/arm/arch_dump: Add SVE notes, Peter Maydell, 2020/01/23
- [PULL 17/20] hw/char/exynos4210_uart: Implement post_load function, Peter Maydell, 2020/01/23
- [PULL 19/20] hw/char/exynos4210_uart: Add receive DMA support, Peter Maydell, 2020/01/23
- [PULL 20/20] hw/arm/exynos4210: Connect serial port DMA busy signals with pl330,
Peter Maydell <=
- [PULL 16/20] hw/char/exynos4210_uart: Convert to support tracing, Peter Maydell, 2020/01/23
- [PULL 18/20] hw/char/exynos4210_uart: Implement Rx FIFO level triggers and timeouts, Peter Maydell, 2020/01/23
- [PULL 10/20] qemu-block-drivers: Convert to rST, Peter Maydell, 2020/01/23