qemu-arm
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH v2] aspeed: Refactor UART init for multi-SoC machines


From: Cédric Le Goater
Subject: Re: [PATCH v2] aspeed: Refactor UART init for multi-SoC machines
Date: Sat, 2 Jul 2022 07:57:09 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.9.0

On 7/1/22 22:02, 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

Looks good. A few comments on the APIs.


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 |  5 ++++-
  5 files changed, 60 insertions(+), 20 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)

something like :

  void aspeed_soc_uart_connect(AspeedSoCState *s, int uart_default)

which could be exported from aspeed_soc.c

+{
+    AspeedMachineClass *amc = ASPEED_MACHINE_GET_CLASS(bmc);

and you wouldn't need the machine.

+    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++) {

We should test for :

  ASPEED_SOC_GET_CLASS(s)->uarts_num

I am not sure we want to stop the loop if serial_hd(i) is NULL ?

+
+        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)

We can handle errors now. So :

  bool aspeed_soc_uart_realize(AspeedSoCState *s, Error **errp)

  {
      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);

use errp instead and return false in case of failure.

+
+        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);

You introduced aspeed_mmio_map() :)

      }
  }
+void aspeed_soc_uart_set_chr(AspeedSoCState *s, int dev, Chardev *chr)

you could merge this routine in aspeed_soc_uart_connect() I think.

Thanks,

C.


+{
+    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..60ee0a84db 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,7 +81,7 @@ struct AspeedSoCState {
      AspeedSDHCIState emmc;
      AspeedLPCState lpc;
      AspeedPECIState peci;
-    uint32_t uart_default;
+    SerialMM uart[ASPEED_UARTS_NUM];
      Clock *sysclk;
      UnimplementedDeviceState iomem;
      UnimplementedDeviceState video;
@@ -176,6 +178,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,




reply via email to

[Prev in Thread] Current Thread [Next in Thread]