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(-)
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;
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
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 > >
© 2016 - 2024 Red Hat, Inc.