[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH] aspeed: Refactor UART init for multi-SoC machines
From: |
Peter Delevoryas |
Subject: |
Re: [PATCH] aspeed: Refactor UART init for multi-SoC machines |
Date: |
Fri, 1 Jul 2022 13:02:03 -0700 |
On Fri, Jul 01, 2022 at 12:56:19PM -0700, Peter Delevoryas wrote:
> This change moves the code that connects the SoC UART's to serial_hd's
> to the machine.
>
> It makes each UART a proper child member of the SoC, and then allows the
> machine to selectively initialize the chardev for each UART with a
> serial_hd.
>
> This should preserve backwards compatibility, but also allow multi-SoC
> boards to completely change the wiring of serial devices from the
> command line to specific SoC UART's.
>
> This also removes the uart-default property from the SoC, since the SoC
> doesn't need to know what UART is the "default" on the machine anymore.
>
> I tested this using the images and commands from the previous
> refactoring, and another test image for the ast1030:
>
> wget
> https://github.com/facebook/openbmc/releases/download/v2021.49.0/fuji.mtd
> wget
> https://github.com/facebook/openbmc/releases/download/v2021.49.0/wedge100.mtd
> wget
> https://github.com/peterdelevoryas/OpenBIC/releases/download/oby35-cl-2022.13.01/Y35BCL.elf
>
> Fuji uses UART1:
>
> qemu-system-arm -machine fuji-bmc \
> -drive file=fuji.mtd,format=raw,if=mtd \
> -nographic
>
> ast2600-evb uses uart-default=UART5:
>
> qemu-system-arm -machine ast2600-evb \
> -drive file=fuji.mtd,format=raw,if=mtd \
> -serial null -serial mon:stdio -display none
>
> Wedge100 uses UART3:
>
> 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
>
> AST1030 EVB uses UART5:
>
> qemu-system-arm -machine ast1030-evb \
> -kernel Y35BCL.elf -nographic
>
> Fixes: 6827ff20b2975 ("hw: aspeed: Init all UART's with serial devices")
> Signed-off-by: Peter Delevoryas <me@pjd.dev>
> ---
> hw/arm/aspeed.c | 23 +++++++++++++++----
> hw/arm/aspeed_ast10x0.c | 4 ++++
> hw/arm/aspeed_ast2600.c | 4 ++++
> hw/arm/aspeed_soc.c | 44 ++++++++++++++++++++++++-------------
> include/hw/arm/aspeed_soc.h | 4 ++++
> 5 files changed, 60 insertions(+), 19 deletions(-)
>
> diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
> index 6fe9b13548..fdca0abd95 100644
> --- a/hw/arm/aspeed.c
> +++ b/hw/arm/aspeed.c
> @@ -26,6 +26,7 @@
> #include "qemu/error-report.h"
> #include "qemu/units.h"
> #include "hw/qdev-clock.h"
> +#include "sysemu/sysemu.h"
>
> static struct arm_boot_info aspeed_board_binfo = {
> .board_id = -1, /* device-tree-only board */
> @@ -301,6 +302,22 @@ static void sdhci_attach_drive(SDHCIState *sdhci,
> DriveInfo *dinfo)
> &error_fatal);
> }
>
> +static void connect_serial_hds_to_uarts(AspeedMachineState *bmc)
> +{
> + AspeedMachineClass *amc = ASPEED_MACHINE_GET_CLASS(bmc);
> + AspeedSoCState *s = &bmc->soc;
> +
> + aspeed_soc_uart_set_chr(s, amc->uart_default, serial_hd(0));
> + for (int i = 1, uart = ASPEED_DEV_UART1;
> + serial_hd(i) && uart <= ASPEED_DEV_UART13; i++, uart++) {
> +
> + if (uart == amc->uart_default) {
> + continue;
> + }
> + aspeed_soc_uart_set_chr(s, uart, serial_hd(i));
> + }
> +}
> +
> static void aspeed_machine_init(MachineState *machine)
> {
> AspeedMachineState *bmc = ASPEED_MACHINE(machine);
> @@ -346,8 +363,7 @@ static void aspeed_machine_init(MachineState *machine)
> object_property_set_int(OBJECT(&bmc->soc), "hw-prot-key",
> ASPEED_SCU_PROT_KEY, &error_abort);
> }
> - qdev_prop_set_uint32(DEVICE(&bmc->soc), "uart-default",
> - amc->uart_default);
> + connect_serial_hds_to_uarts(bmc);
> qdev_realize(DEVICE(&bmc->soc), NULL, &error_abort);
>
> aspeed_board_init_flashes(&bmc->soc.fmc,
> @@ -1383,8 +1399,7 @@ static void aspeed_minibmc_machine_init(MachineState
> *machine)
>
> object_property_set_link(OBJECT(&bmc->soc), "memory",
> OBJECT(get_system_memory()), &error_abort);
> - qdev_prop_set_uint32(DEVICE(&bmc->soc), "uart-default",
> - amc->uart_default);
> + connect_serial_hds_to_uarts(bmc);
> qdev_realize(DEVICE(&bmc->soc), NULL, &error_abort);
>
> aspeed_board_init_flashes(&bmc->soc.fmc,
> diff --git a/hw/arm/aspeed_ast10x0.c b/hw/arm/aspeed_ast10x0.c
> index 33ef331771..a221f5d6fe 100644
> --- a/hw/arm/aspeed_ast10x0.c
> +++ b/hw/arm/aspeed_ast10x0.c
> @@ -144,6 +144,10 @@ static void aspeed_soc_ast1030_init(Object *obj)
> object_initialize_child(obj, "wdt[*]", &s->wdt[i], typename);
> }
>
> + for (i = 0; i < sc->uarts_num; i++) {
> + object_initialize_child(obj, "uart[*]", &s->uart[i], TYPE_SERIAL_MM);
> + }
> +
> snprintf(typename, sizeof(typename), "aspeed.gpio-%s", socname);
> object_initialize_child(obj, "gpio", &s->gpio, typename);
>
> diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
> index 3f0611ac11..c4ad26a046 100644
> --- a/hw/arm/aspeed_ast2600.c
> +++ b/hw/arm/aspeed_ast2600.c
> @@ -214,6 +214,10 @@ static void aspeed_soc_ast2600_init(Object *obj)
> object_initialize_child(obj, "mii[*]", &s->mii[i], TYPE_ASPEED_MII);
> }
>
> + for (i = 0; i < sc->uarts_num; i++) {
> + object_initialize_child(obj, "uart[*]", &s->uart[i], TYPE_SERIAL_MM);
> + }
> +
> snprintf(typename, sizeof(typename), TYPE_ASPEED_XDMA "-%s", socname);
> object_initialize_child(obj, "xdma", &s->xdma, typename);
>
> diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
> index 0f675e7fcd..2ac18cbf27 100644
> --- a/hw/arm/aspeed_soc.c
> +++ b/hw/arm/aspeed_soc.c
> @@ -208,6 +208,10 @@ static void aspeed_soc_init(Object *obj)
> TYPE_FTGMAC100);
> }
>
> + for (i = 0; i < sc->uarts_num; i++) {
> + object_initialize_child(obj, "uart[*]", &s->uart[i], TYPE_SERIAL_MM);
> + }
> +
> snprintf(typename, sizeof(typename), TYPE_ASPEED_XDMA "-%s", socname);
> object_initialize_child(obj, "xdma", &s->xdma, typename);
>
> @@ -481,8 +485,6 @@ static Property aspeed_soc_properties[] = {
> MemoryRegion *),
> DEFINE_PROP_LINK("dram", AspeedSoCState, dram_mr, TYPE_MEMORY_REGION,
> MemoryRegion *),
> - DEFINE_PROP_UINT32("uart-default", AspeedSoCState, uart_default,
> - ASPEED_DEV_UART5),
> DEFINE_PROP_END_OF_LIST(),
> };
>
> @@ -575,22 +577,34 @@ 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(s->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(s->memory, sc->memmap[uart], 2,
> - aspeed_soc_get_irq(s, uart), 38400,
> - serial_hd(i), DEVICE_LITTLE_ENDIAN);
> + SerialMM *smm;
> + MemoryRegion *mr;
> +
> + for (int i = 0, uart = ASPEED_DEV_UART1; i < sc->uarts_num; i++, uart++)
> {
> + smm = &s->uart[i];
> +
> + /* Chardev property is set by the machine. */
> + qdev_prop_set_uint8(DEVICE(smm), "regshift", 2);
> + qdev_prop_set_uint32(DEVICE(smm), "baudbase", 38400);
> + qdev_set_legacy_instance_id(DEVICE(smm), sc->memmap[uart], 2);
> + qdev_prop_set_uint8(DEVICE(smm), "endianness", DEVICE_LITTLE_ENDIAN);
> + sysbus_realize(SYS_BUS_DEVICE(smm), &error_fatal);
> +
> + sysbus_connect_irq(SYS_BUS_DEVICE(smm), 0, aspeed_soc_get_irq(s,
> uart));
> + mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(smm), 0);
> + memory_region_add_subregion(s->memory, sc->memmap[uart], mr);
> }
> }
>
> +void aspeed_soc_uart_set_chr(AspeedSoCState *s, int dev, Chardev *chr)
> +{
> + AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
> + int i = dev - ASPEED_DEV_UART1;
> +
> + g_assert(0 <= i && i < ARRAY_SIZE(s->uart) && i < sc->uarts_num);
> + qdev_prop_set_chr(DEVICE(&s->uart[i]), "chardev", chr);
> +}
> +
> /*
> * SDMC should be realized first to get correct RAM size and max size
> * values
> diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h
> index e65926a667..06c9ab20f8 100644
> --- a/include/hw/arm/aspeed_soc.h
> +++ b/include/hw/arm/aspeed_soc.h
> @@ -36,12 +36,14 @@
> #include "hw/misc/aspeed_lpc.h"
> #include "hw/misc/unimp.h"
> #include "hw/misc/aspeed_peci.h"
> +#include "hw/char/serial.h"
>
> #define ASPEED_SPIS_NUM 2
> #define ASPEED_EHCIS_NUM 2
> #define ASPEED_WDTS_NUM 4
> #define ASPEED_CPUS_NUM 2
> #define ASPEED_MACS_NUM 4
> +#define ASPEED_UARTS_NUM 13
>
> struct AspeedSoCState {
> /*< private >*/
> @@ -79,6 +81,7 @@ struct AspeedSoCState {
> AspeedSDHCIState emmc;
> AspeedLPCState lpc;
> AspeedPECIState peci;
> + SerialMM uart[ASPEED_UARTS_NUM];
> uint32_t uart_default;
^^^^^^^^^^^^^^^^^^^^^^
Forgot to remove this, I'll send a v2 really quick.
The machine state should keep the one it has, but
the SoC one should go away.
> Clock *sysclk;
> UnimplementedDeviceState iomem;
> @@ -176,6 +179,7 @@ enum {
>
> qemu_irq aspeed_soc_get_irq(AspeedSoCState *s, int dev);
> void aspeed_soc_uart_init(AspeedSoCState *s);
> +void aspeed_soc_uart_set_chr(AspeedSoCState *s, int dev, Chardev *chr);
> bool aspeed_soc_dram_init(AspeedSoCState *s, Error **errp);
> void aspeed_mmio_map(AspeedSoCState *s, SysBusDevice *dev, int n, hwaddr
> addr);
> void aspeed_mmio_map_unimplemented(AspeedSoCState *s, SysBusDevice *dev,
> --
> 2.37.0
>
>