diff mbox series

[v2,5/5] hw: aspeed: Init all UART's with serial devices

Message ID 20220516062328.298336-6-pdel@fb.com
State New
Headers show
Series hw: aspeed: Init all UART's with serial devices | expand

Commit Message

Peter Delevoryas May 16, 2022, 6:23 a.m. UTC
Background:

AspeedMachineClass.uart_default specifies the serial console UART, which
usually corresponds to the "stdout-path" in the device tree.

The default value is UART5, since most boards use UART5 for this:

    amc->uart_default = ASPEED_DEV_UART5;

Users can override AspeedMachineClass.uart_default in their board's machine
class init to specify something besides UART5. For example, for fuji-bmc:

    amc->uart_default = ASPEED_DEV_UART1;

We only connect this one UART, of the 5 UART's on the AST2400 and AST2500
and the 13 UART's on the AST2600 and AST1030, to a serial device that QEMU
users can use. None of the other UART's are initialized, and the only way
to override this attribute is by creating a specialized board definition,
requiring QEMU source code changes and rebuilding.

The result of this is that if you want to get serial console output on a
board that uses UART3, you need to add a board definition. This was
encountered by Zev in OpenBMC. [1]

Changes:

This commit initializes all of the UART's present on each Aspeed chip with
serial devices and allows the QEMU user to connect as many or few as they
like to serial devices. For example, you can still run QEMU and just connect
stdout to the machine's default UART, without specifying any additional
serial devices:

    qemu-system-arm -machine fuji-bmc \
        -drive file=fuji.mtd,format=raw,if=mtd \
        -nographic

However, if you don't want to add a special machine definition, you can now
manually configure UART1 to connect to stdout and get serial console output,
even if the machine's default is UART5:

    qemu-system-arm -machine ast2600-evb \
        -drive file=fuji.mtd,format=raw,if=mtd \
        -serial null -serial mon:stdio -display none

In the example above, the first "-serial null" argument is connected to
UART5, and "-serial mon:stdio" is connected to UART1.

Another example: you can get serial console output from Wedge100, which uses
UART3, by reusing the palmetto AST2400 machine and rewiring the serial
device arguments:

    qemu-system-arm -machine palmetto-bmc \
        -drive file=wedge100.mtd,format=raw,if=mtd \
        -serial null -serial null -serial null \
        -serial mon:stdio -display none

There is a slight change in behavior introduced with this change: now, each
UART's memory-mapped IO region will have a serial device model connected to
it. Previously, all reads and writes to those regions would be ineffective
and return zero values, but now some values will be nonzero, even when the
user doesn't connect a serial device backend (like a socket, file, etc). For
example, the line status register might indicate that the transmit buffer is
empty now, whereas previously it might have always indicated it was full.

[1] https://lore.kernel.org/openbmc/YnzGnWjkYdMUUNyM@hatter.bewilderbeest.net/
[2] https://github.com/facebook/openbmc/releases/download/v2021.49.0/fuji.mtd
[3] https://github.com/facebook/openbmc/releases/download/v2021.49.0/wedge100.mtd

Signed-off-by: Peter Delevoryas <pdel@fb.com>
---
 hw/arm/aspeed_soc.c | 9 +++++++++
 1 file changed, 9 insertions(+)

Comments

Cédric Le Goater May 16, 2022, 7:22 a.m. UTC | #1
On 5/16/22 08:23, Peter Delevoryas wrote:
> Background:
> 
> AspeedMachineClass.uart_default specifies the serial console UART, which
> usually corresponds to the "stdout-path" in the device tree.
> 
> The default value is UART5, since most boards use UART5 for this:
> 
>      amc->uart_default = ASPEED_DEV_UART5;
> 
> Users can override AspeedMachineClass.uart_default in their board's machine
> class init to specify something besides UART5. For example, for fuji-bmc:
> 
>      amc->uart_default = ASPEED_DEV_UART1;
> 
> We only connect this one UART, of the 5 UART's on the AST2400 and AST2500
> and the 13 UART's on the AST2600 and AST1030, to a serial device that QEMU
> users can use. None of the other UART's are initialized, and the only way
> to override this attribute is by creating a specialized board definition,
> requiring QEMU source code changes and rebuilding.
> 
> The result of this is that if you want to get serial console output on a
> board that uses UART3, you need to add a board definition. This was
> encountered by Zev in OpenBMC. [1]
> 
> Changes:
> 
> This commit initializes all of the UART's present on each Aspeed chip with
> serial devices and allows the QEMU user to connect as many or few as they
> like to serial devices. For example, you can still run QEMU and just connect
> stdout to the machine's default UART, without specifying any additional
> serial devices:
> 
>      qemu-system-arm -machine fuji-bmc \
>          -drive file=fuji.mtd,format=raw,if=mtd \
>          -nographic
> 
> However, if you don't want to add a special machine definition, you can now
> manually configure UART1 to connect to stdout and get serial console output,
> even if the machine's default is UART5:
> 
>      qemu-system-arm -machine ast2600-evb \
>          -drive file=fuji.mtd,format=raw,if=mtd \
>          -serial null -serial mon:stdio -display none
> 
> In the example above, the first "-serial null" argument is connected to
> UART5, and "-serial mon:stdio" is connected to UART1.
> 
> Another example: you can get serial console output from Wedge100, which uses
> UART3, by reusing the palmetto AST2400 machine and rewiring the serial
> device arguments:
> 
>      qemu-system-arm -machine palmetto-bmc \
>          -drive file=wedge100.mtd,format=raw,if=mtd \
>          -serial null -serial null -serial null \
>          -serial mon:stdio -display none
> 
> There is a slight change in behavior introduced with this change: now, each
> UART's memory-mapped IO region will have a serial device model connected to
> it. Previously, all reads and writes to those regions would be ineffective
> and return zero values, but now some values will be nonzero, even when the
> user doesn't connect a serial device backend (like a socket, file, etc). For
> example, the line status register might indicate that the transmit buffer is
> empty now, whereas previously it might have always indicated it was full.
> 
> [1] https://lore.kernel.org/openbmc/YnzGnWjkYdMUUNyM@hatter.bewilderbeest.net/
> [2] https://github.com/facebook/openbmc/releases/download/v2021.49.0/fuji.mtd
> [3] https://github.com/facebook/openbmc/releases/download/v2021.49.0/wedge100.mtd
> 
> Signed-off-by: Peter Delevoryas <pdel@fb.com>


Reviewed-by: Cédric Le Goater <clg@kaod.org>

Thanks,

C.


> ---
>   hw/arm/aspeed_soc.c | 9 +++++++++
>   1 file changed, 9 insertions(+)
> 
> diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
> index 912798a9c9..30574d4276 100644
> --- a/hw/arm/aspeed_soc.c
> +++ b/hw/arm/aspeed_soc.c
> @@ -546,9 +546,18 @@ qemu_irq aspeed_soc_get_irq(AspeedSoCState *s, int dev)
>   void aspeed_soc_uart_init(AspeedSoCState *s)
>   {
>       AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
> +    int i, uart;
>   
>       /* Attach an 8250 to the IO space as our UART */
>       serial_mm_init(get_system_memory(), sc->memmap[s->uart_default], 2,
>                      aspeed_soc_get_irq(s, s->uart_default), 38400,
>                      serial_hd(0), DEVICE_LITTLE_ENDIAN);
> +    for (i = 1, uart = ASPEED_DEV_UART1; i < sc->uarts_num; i++, uart++) {
> +        if (uart == s->uart_default) {
> +            uart++;
> +        }
> +        serial_mm_init(get_system_memory(), sc->memmap[uart], 2,
> +                       aspeed_soc_get_irq(s, uart), 38400,
> +                       serial_hd(i), DEVICE_LITTLE_ENDIAN);
> +    }
>   }
diff mbox series

Patch

diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
index 912798a9c9..30574d4276 100644
--- a/hw/arm/aspeed_soc.c
+++ b/hw/arm/aspeed_soc.c
@@ -546,9 +546,18 @@  qemu_irq aspeed_soc_get_irq(AspeedSoCState *s, int dev)
 void aspeed_soc_uart_init(AspeedSoCState *s)
 {
     AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
+    int i, uart;
 
     /* Attach an 8250 to the IO space as our UART */
     serial_mm_init(get_system_memory(), sc->memmap[s->uart_default], 2,
                    aspeed_soc_get_irq(s, s->uart_default), 38400,
                    serial_hd(0), DEVICE_LITTLE_ENDIAN);
+    for (i = 1, uart = ASPEED_DEV_UART1; i < sc->uarts_num; i++, uart++) {
+        if (uart == s->uart_default) {
+            uart++;
+        }
+        serial_mm_init(get_system_memory(), sc->memmap[uart], 2,
+                       aspeed_soc_get_irq(s, uart), 38400,
+                       serial_hd(i), DEVICE_LITTLE_ENDIAN);
+    }
 }