mirror of https://github.com/xemu-project/xemu.git
aspeed: Refactor UART init for multi-SoC machines
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: 6827ff20b2
("hw: aspeed: Init all UART's with serial devices")
Signed-off-by: Peter Delevoryas <peter@pjd.dev>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20220705191400.41632-4-peter@pjd.dev>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
This commit is contained in:
parent
72a7c47393
commit
d2b3eaefb4
|
@ -26,6 +26,7 @@
|
||||||
#include "qemu/error-report.h"
|
#include "qemu/error-report.h"
|
||||||
#include "qemu/units.h"
|
#include "qemu/units.h"
|
||||||
#include "hw/qdev-clock.h"
|
#include "hw/qdev-clock.h"
|
||||||
|
#include "sysemu/sysemu.h"
|
||||||
|
|
||||||
static struct arm_boot_info aspeed_board_binfo = {
|
static struct arm_boot_info aspeed_board_binfo = {
|
||||||
.board_id = -1, /* device-tree-only board */
|
.board_id = -1, /* device-tree-only board */
|
||||||
|
@ -301,6 +302,21 @@ static void sdhci_attach_drive(SDHCIState *sdhci, DriveInfo *dinfo)
|
||||||
&error_fatal);
|
&error_fatal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void connect_serial_hds_to_uarts(AspeedMachineState *bmc)
|
||||||
|
{
|
||||||
|
AspeedMachineClass *amc = ASPEED_MACHINE_GET_CLASS(bmc);
|
||||||
|
AspeedSoCState *s = &bmc->soc;
|
||||||
|
AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
|
||||||
|
|
||||||
|
aspeed_soc_uart_set_chr(s, amc->uart_default, serial_hd(0));
|
||||||
|
for (int i = 1, uart = ASPEED_DEV_UART1; i < sc->uarts_num; 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)
|
static void aspeed_machine_init(MachineState *machine)
|
||||||
{
|
{
|
||||||
AspeedMachineState *bmc = ASPEED_MACHINE(machine);
|
AspeedMachineState *bmc = ASPEED_MACHINE(machine);
|
||||||
|
@ -346,8 +362,7 @@ static void aspeed_machine_init(MachineState *machine)
|
||||||
object_property_set_int(OBJECT(&bmc->soc), "hw-prot-key",
|
object_property_set_int(OBJECT(&bmc->soc), "hw-prot-key",
|
||||||
ASPEED_SCU_PROT_KEY, &error_abort);
|
ASPEED_SCU_PROT_KEY, &error_abort);
|
||||||
}
|
}
|
||||||
qdev_prop_set_uint32(DEVICE(&bmc->soc), "uart-default",
|
connect_serial_hds_to_uarts(bmc);
|
||||||
amc->uart_default);
|
|
||||||
qdev_realize(DEVICE(&bmc->soc), NULL, &error_abort);
|
qdev_realize(DEVICE(&bmc->soc), NULL, &error_abort);
|
||||||
|
|
||||||
aspeed_board_init_flashes(&bmc->soc.fmc,
|
aspeed_board_init_flashes(&bmc->soc.fmc,
|
||||||
|
@ -1383,8 +1398,7 @@ static void aspeed_minibmc_machine_init(MachineState *machine)
|
||||||
|
|
||||||
object_property_set_link(OBJECT(&bmc->soc), "memory",
|
object_property_set_link(OBJECT(&bmc->soc), "memory",
|
||||||
OBJECT(get_system_memory()), &error_abort);
|
OBJECT(get_system_memory()), &error_abort);
|
||||||
qdev_prop_set_uint32(DEVICE(&bmc->soc), "uart-default",
|
connect_serial_hds_to_uarts(bmc);
|
||||||
amc->uart_default);
|
|
||||||
qdev_realize(DEVICE(&bmc->soc), NULL, &error_abort);
|
qdev_realize(DEVICE(&bmc->soc), NULL, &error_abort);
|
||||||
|
|
||||||
aspeed_board_init_flashes(&bmc->soc.fmc,
|
aspeed_board_init_flashes(&bmc->soc.fmc,
|
||||||
|
|
|
@ -144,6 +144,10 @@ static void aspeed_soc_ast1030_init(Object *obj)
|
||||||
object_initialize_child(obj, "wdt[*]", &s->wdt[i], typename);
|
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);
|
snprintf(typename, sizeof(typename), "aspeed.gpio-%s", socname);
|
||||||
object_initialize_child(obj, "gpio", &s->gpio, typename);
|
object_initialize_child(obj, "gpio", &s->gpio, typename);
|
||||||
|
|
||||||
|
@ -255,7 +259,9 @@ static void aspeed_soc_ast1030_realize(DeviceState *dev_soc, Error **errp)
|
||||||
sc->irqmap[ASPEED_DEV_KCS] + aspeed_lpc_kcs_4));
|
sc->irqmap[ASPEED_DEV_KCS] + aspeed_lpc_kcs_4));
|
||||||
|
|
||||||
/* UART */
|
/* UART */
|
||||||
aspeed_soc_uart_init(s);
|
if (!aspeed_soc_uart_realize(s, errp)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Timer */
|
/* Timer */
|
||||||
object_property_set_link(OBJECT(&s->timerctrl), "scu", OBJECT(&s->scu),
|
object_property_set_link(OBJECT(&s->timerctrl), "scu", OBJECT(&s->scu),
|
||||||
|
|
|
@ -214,6 +214,10 @@ static void aspeed_soc_ast2600_init(Object *obj)
|
||||||
object_initialize_child(obj, "mii[*]", &s->mii[i], TYPE_ASPEED_MII);
|
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);
|
snprintf(typename, sizeof(typename), TYPE_ASPEED_XDMA "-%s", socname);
|
||||||
object_initialize_child(obj, "xdma", &s->xdma, typename);
|
object_initialize_child(obj, "xdma", &s->xdma, typename);
|
||||||
|
|
||||||
|
@ -386,7 +390,9 @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
|
||||||
aspeed_soc_get_irq(s, ASPEED_DEV_ADC));
|
aspeed_soc_get_irq(s, ASPEED_DEV_ADC));
|
||||||
|
|
||||||
/* UART */
|
/* UART */
|
||||||
aspeed_soc_uart_init(s);
|
if (!aspeed_soc_uart_realize(s, errp)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* I2C */
|
/* I2C */
|
||||||
object_property_set_link(OBJECT(&s->i2c), "dram", OBJECT(s->dram_mr),
|
object_property_set_link(OBJECT(&s->i2c), "dram", OBJECT(s->dram_mr),
|
||||||
|
|
|
@ -208,6 +208,10 @@ static void aspeed_soc_init(Object *obj)
|
||||||
TYPE_FTGMAC100);
|
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);
|
snprintf(typename, sizeof(typename), TYPE_ASPEED_XDMA "-%s", socname);
|
||||||
object_initialize_child(obj, "xdma", &s->xdma, typename);
|
object_initialize_child(obj, "xdma", &s->xdma, typename);
|
||||||
|
|
||||||
|
@ -315,7 +319,9 @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
|
||||||
aspeed_soc_get_irq(s, ASPEED_DEV_ADC));
|
aspeed_soc_get_irq(s, ASPEED_DEV_ADC));
|
||||||
|
|
||||||
/* UART */
|
/* UART */
|
||||||
aspeed_soc_uart_init(s);
|
if (!aspeed_soc_uart_realize(s, errp)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* I2C */
|
/* I2C */
|
||||||
object_property_set_link(OBJECT(&s->i2c), "dram", OBJECT(s->dram_mr),
|
object_property_set_link(OBJECT(&s->i2c), "dram", OBJECT(s->dram_mr),
|
||||||
|
@ -482,8 +488,6 @@ static Property aspeed_soc_properties[] = {
|
||||||
MemoryRegion *),
|
MemoryRegion *),
|
||||||
DEFINE_PROP_LINK("dram", AspeedSoCState, dram_mr, TYPE_MEMORY_REGION,
|
DEFINE_PROP_LINK("dram", AspeedSoCState, dram_mr, TYPE_MEMORY_REGION,
|
||||||
MemoryRegion *),
|
MemoryRegion *),
|
||||||
DEFINE_PROP_UINT32("uart-default", AspeedSoCState, uart_default,
|
|
||||||
ASPEED_DEV_UART5),
|
|
||||||
DEFINE_PROP_END_OF_LIST(),
|
DEFINE_PROP_END_OF_LIST(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -573,23 +577,37 @@ qemu_irq aspeed_soc_get_irq(AspeedSoCState *s, int dev)
|
||||||
return ASPEED_SOC_GET_CLASS(s)->get_irq(s, dev);
|
return ASPEED_SOC_GET_CLASS(s)->get_irq(s, dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
void aspeed_soc_uart_init(AspeedSoCState *s)
|
bool aspeed_soc_uart_realize(AspeedSoCState *s, Error **errp)
|
||||||
{
|
{
|
||||||
AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
|
AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
|
||||||
int i, uart;
|
SerialMM *smm;
|
||||||
|
|
||||||
/* Attach an 8250 to the IO space as our UART */
|
for (int i = 0, uart = ASPEED_DEV_UART1; i < sc->uarts_num; i++, uart++) {
|
||||||
serial_mm_init(s->memory, sc->memmap[s->uart_default], 2,
|
smm = &s->uart[i];
|
||||||
aspeed_soc_get_irq(s, s->uart_default), 38400,
|
|
||||||
serial_hd(0), DEVICE_LITTLE_ENDIAN);
|
/* Chardev property is set by the machine. */
|
||||||
for (i = 1, uart = ASPEED_DEV_UART1; i < sc->uarts_num; i++, uart++) {
|
qdev_prop_set_uint8(DEVICE(smm), "regshift", 2);
|
||||||
if (uart == s->uart_default) {
|
qdev_prop_set_uint32(DEVICE(smm), "baudbase", 38400);
|
||||||
uart++;
|
qdev_set_legacy_instance_id(DEVICE(smm), sc->memmap[uart], 2);
|
||||||
|
qdev_prop_set_uint8(DEVICE(smm), "endianness", DEVICE_LITTLE_ENDIAN);
|
||||||
|
if (!sysbus_realize(SYS_BUS_DEVICE(smm), errp)) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
serial_mm_init(s->memory, sc->memmap[uart], 2,
|
|
||||||
aspeed_soc_get_irq(s, uart), 38400,
|
sysbus_connect_irq(SYS_BUS_DEVICE(smm), 0, aspeed_soc_get_irq(s, uart));
|
||||||
serial_hd(i), DEVICE_LITTLE_ENDIAN);
|
aspeed_mmio_map(s, SYS_BUS_DEVICE(smm), 0, sc->memmap[uart]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -36,12 +36,14 @@
|
||||||
#include "hw/misc/aspeed_lpc.h"
|
#include "hw/misc/aspeed_lpc.h"
|
||||||
#include "hw/misc/unimp.h"
|
#include "hw/misc/unimp.h"
|
||||||
#include "hw/misc/aspeed_peci.h"
|
#include "hw/misc/aspeed_peci.h"
|
||||||
|
#include "hw/char/serial.h"
|
||||||
|
|
||||||
#define ASPEED_SPIS_NUM 2
|
#define ASPEED_SPIS_NUM 2
|
||||||
#define ASPEED_EHCIS_NUM 2
|
#define ASPEED_EHCIS_NUM 2
|
||||||
#define ASPEED_WDTS_NUM 4
|
#define ASPEED_WDTS_NUM 4
|
||||||
#define ASPEED_CPUS_NUM 2
|
#define ASPEED_CPUS_NUM 2
|
||||||
#define ASPEED_MACS_NUM 4
|
#define ASPEED_MACS_NUM 4
|
||||||
|
#define ASPEED_UARTS_NUM 13
|
||||||
|
|
||||||
struct AspeedSoCState {
|
struct AspeedSoCState {
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
|
@ -79,7 +81,7 @@ struct AspeedSoCState {
|
||||||
AspeedSDHCIState emmc;
|
AspeedSDHCIState emmc;
|
||||||
AspeedLPCState lpc;
|
AspeedLPCState lpc;
|
||||||
AspeedPECIState peci;
|
AspeedPECIState peci;
|
||||||
uint32_t uart_default;
|
SerialMM uart[ASPEED_UARTS_NUM];
|
||||||
Clock *sysclk;
|
Clock *sysclk;
|
||||||
UnimplementedDeviceState iomem;
|
UnimplementedDeviceState iomem;
|
||||||
UnimplementedDeviceState video;
|
UnimplementedDeviceState video;
|
||||||
|
@ -175,7 +177,8 @@ enum {
|
||||||
};
|
};
|
||||||
|
|
||||||
qemu_irq aspeed_soc_get_irq(AspeedSoCState *s, int dev);
|
qemu_irq aspeed_soc_get_irq(AspeedSoCState *s, int dev);
|
||||||
void aspeed_soc_uart_init(AspeedSoCState *s);
|
bool aspeed_soc_uart_realize(AspeedSoCState *s, Error **errp);
|
||||||
|
void aspeed_soc_uart_set_chr(AspeedSoCState *s, int dev, Chardev *chr);
|
||||||
bool aspeed_soc_dram_init(AspeedSoCState *s, Error **errp);
|
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(AspeedSoCState *s, SysBusDevice *dev, int n, hwaddr addr);
|
||||||
void aspeed_mmio_map_unimplemented(AspeedSoCState *s, SysBusDevice *dev,
|
void aspeed_mmio_map_unimplemented(AspeedSoCState *s, SysBusDevice *dev,
|
||||||
|
|
Loading…
Reference in New Issue