diff mbox series

[v2,1/2] aspeed: introduce a new UART0 device name

Message ID 20240207200220.453244-2-jamin_lin@aspeedtech.com (mailing list archive)
State New, archived
Headers show
Series [v2,1/2] aspeed: introduce a new UART0 device name | expand

Commit Message

Jamin Lin Feb. 7, 2024, 8:02 p.m. UTC
The Aspeed datasheet refers to the UART controllers
as UART1 - UART13 for the ast10x0, ast2600, ast2500
and ast2400 SoCs and the Aspeed ast2700 introduces an UART0
and the UART controllers as UART0 - UART12.

To keep the naming in the QEMU models
in sync with the datasheet, let's introduce a new  UART0 device name
and do the required adjustements, etc ...

Signed-off-by: Troy Lee <troy_lee@aspeedtech.com>
Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
---
 hw/arm/aspeed.c             | 13 ++++++++-----
 hw/arm/aspeed_ast10x0.c     |  1 +
 hw/arm/aspeed_ast2400.c     |  2 ++
 hw/arm/aspeed_ast2600.c     |  1 +
 hw/arm/aspeed_soc_common.c  | 14 +++++++++-----
 include/hw/arm/aspeed_soc.h |  2 ++
 6 files changed, 23 insertions(+), 10 deletions(-)

Comments

Cédric Le Goater Feb. 9, 2024, 8:27 a.m. UTC | #1
Hello Jamin,

On 2/7/24 21:02, Jamin Lin via wrote:
> The Aspeed datasheet refers to the UART controllers
> as UART1 - UART13 for the ast10x0, ast2600, ast2500
> and ast2400 SoCs and the Aspeed ast2700 introduces an UART0
> and the UART controllers as UART0 - UART12.
> 
> To keep the naming in the QEMU models
> in sync with the datasheet, let's introduce a new  UART0 device name
> and do the required adjustements, etc ...

Please drop the etc...

> 
> Signed-off-by: Troy Lee <troy_lee@aspeedtech.com>
> Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
> ---
>   hw/arm/aspeed.c             | 13 ++++++++-----
>   hw/arm/aspeed_ast10x0.c     |  1 +
>   hw/arm/aspeed_ast2400.c     |  2 ++
>   hw/arm/aspeed_ast2600.c     |  1 +
>   hw/arm/aspeed_soc_common.c  | 14 +++++++++-----
>   include/hw/arm/aspeed_soc.h |  2 ++
>   6 files changed, 23 insertions(+), 10 deletions(-)
> 
> diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
> index 09b1e823ba..06d863958b 100644
> --- a/hw/arm/aspeed.c
> +++ b/hw/arm/aspeed.c
> @@ -342,7 +342,7 @@ static void connect_serial_hds_to_uarts(AspeedMachineState *bmc)
>       int uart_chosen = bmc->uart_chosen ? bmc->uart_chosen : amc->uart_default;
>   
>       aspeed_soc_uart_set_chr(s, uart_chosen, serial_hd(0));
> -    for (int i = 1, uart = ASPEED_DEV_UART1; i < sc->uarts_num; i++, uart++) {
> +    for (int i = 0, uart = sc->uarts_base; i < sc->uarts_num; i++, uart++) {
>           if (uart == uart_chosen) {
>               continue;
>           }
> @@ -1094,7 +1094,7 @@ static char *aspeed_get_bmc_console(Object *obj, Error **errp)
>       AspeedMachineClass *amc = ASPEED_MACHINE_GET_CLASS(bmc);
>       int uart_chosen = bmc->uart_chosen ? bmc->uart_chosen : amc->uart_default;
>   
> -    return g_strdup_printf("uart%d", uart_chosen - ASPEED_DEV_UART1 + 1);
> +    return g_strdup_printf("uart%d", uart_chosen - ASPEED_DEV_UART0);
>   }
>   
>   static void aspeed_set_bmc_console(Object *obj, const char *value, Error **errp)
> @@ -1103,6 +1103,8 @@ static void aspeed_set_bmc_console(Object *obj, const char *value, Error **errp)
>       AspeedMachineClass *amc = ASPEED_MACHINE_GET_CLASS(bmc);
>       AspeedSoCClass *sc = ASPEED_SOC_CLASS(object_class_by_name(amc->soc_name));
>       int val;
> +    int start = sc->uarts_base - ASPEED_DEV_UART0;
> +    int end = start + sc->uarts_num;


To help the reader, I would introduce these helpers at the end of
aspeed_soc.h :

     static inline int aspeed_uart_index(int uart_dev)
     {
         return uart_dev - ASPEED_DEV_UART0;
     }
     
     static inline int aspeed_uart_first(AspeedSoCClass *sc)
     {
         return aspeed_uart_index(sc->uarts_base);
     }
     
     static inline int aspeed_uart_last(AspeedSoCClass *sc)
     {
         return aspeed_uart_first(sc) + sc->uarts_num - 1;
     }
     

>       if (sscanf(value, "uart%u", &val) != 1) {
>           error_setg(errp, "Bad value for \"uart\" property");
> @@ -1110,11 +1112,12 @@ static void aspeed_set_bmc_console(Object *obj, const char *value, Error **errp)
>       }
>   
>       /* The number of UART depends on the SoC */
> -    if (val < 1 || val > sc->uarts_num) {
> -        error_setg(errp, "\"uart\" should be in range [1 - %d]", sc->uarts_num);
> +    if (val < start || val >= end) {
> +        error_setg(errp, "\"uart\" should be in range [%d - %d]",
> +                   start, end - 1);
>           return;
>       }
> -    bmc->uart_chosen = ASPEED_DEV_UART1 + val - 1;
> +    bmc->uart_chosen = val + ASPEED_DEV_UART0;
>   }
>   
>   static void aspeed_machine_class_props_init(ObjectClass *oc)
> diff --git a/hw/arm/aspeed_ast10x0.c b/hw/arm/aspeed_ast10x0.c
> index c3b5116a6a..2634e0f654 100644
> --- a/hw/arm/aspeed_ast10x0.c
> +++ b/hw/arm/aspeed_ast10x0.c
> @@ -436,6 +436,7 @@ static void aspeed_soc_ast1030_class_init(ObjectClass *klass, void *data)
>       sc->wdts_num = 4;
>       sc->macs_num = 1;
>       sc->uarts_num = 13;
> +    sc->uarts_base = ASPEED_DEV_UART1;
>       sc->irqmap = aspeed_soc_ast1030_irqmap;
>       sc->memmap = aspeed_soc_ast1030_memmap;
>       sc->num_cpus = 1;
> diff --git a/hw/arm/aspeed_ast2400.c b/hw/arm/aspeed_ast2400.c
> index 8829561bb6..95da85fee0 100644
> --- a/hw/arm/aspeed_ast2400.c
> +++ b/hw/arm/aspeed_ast2400.c
> @@ -523,6 +523,7 @@ static void aspeed_soc_ast2400_class_init(ObjectClass *oc, void *data)
>       sc->wdts_num     = 2;
>       sc->macs_num     = 2;
>       sc->uarts_num    = 5;
> +    sc->uarts_base   = ASPEED_DEV_UART1;
>       sc->irqmap       = aspeed_soc_ast2400_irqmap;
>       sc->memmap       = aspeed_soc_ast2400_memmap;
>       sc->num_cpus     = 1;
> @@ -551,6 +552,7 @@ static void aspeed_soc_ast2500_class_init(ObjectClass *oc, void *data)
>       sc->wdts_num     = 3;
>       sc->macs_num     = 2;
>       sc->uarts_num    = 5;
> +    sc->uarts_base   = ASPEED_DEV_UART1;
>       sc->irqmap       = aspeed_soc_ast2500_irqmap;
>       sc->memmap       = aspeed_soc_ast2500_memmap;
>       sc->num_cpus     = 1;
> diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
> index 4ee32ea99d..f74561ecdc 100644
> --- a/hw/arm/aspeed_ast2600.c
> +++ b/hw/arm/aspeed_ast2600.c
> @@ -666,6 +666,7 @@ static void aspeed_soc_ast2600_class_init(ObjectClass *oc, void *data)
>       sc->wdts_num     = 4;
>       sc->macs_num     = 4;
>       sc->uarts_num    = 13;
> +    sc->uarts_base   = ASPEED_DEV_UART1;
>       sc->irqmap       = aspeed_soc_ast2600_irqmap;
>       sc->memmap       = aspeed_soc_ast2600_memmap;
>       sc->num_cpus     = 2;
> diff --git a/hw/arm/aspeed_soc_common.c b/hw/arm/aspeed_soc_common.c
> index 123a0c432c..54c875c8d5 100644
> --- a/hw/arm/aspeed_soc_common.c
> +++ b/hw/arm/aspeed_soc_common.c
> @@ -36,7 +36,7 @@ bool aspeed_soc_uart_realize(AspeedSoCState *s, Error **errp)
>       AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
>       SerialMM *smm;
>   
> -    for (int i = 0, uart = ASPEED_DEV_UART1; i < sc->uarts_num; i++, uart++) {
> +    for (int i = 0, uart = sc->uarts_base; i < sc->uarts_num; i++, uart++) {
>           smm = &s->uart[i];
>   
>           /* Chardev property is set by the machine. */
> @@ -58,10 +58,14 @@ bool aspeed_soc_uart_realize(AspeedSoCState *s, Error **errp)
>   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);
> +    int uart_num = dev - ASPEED_DEV_UART0;
> +    int start = sc->uarts_base - ASPEED_DEV_UART0;
> +    int end = start + sc->uarts_num;
> +    int index = uart_num - start;
> +
> +    g_assert(uart_num >= start && uart_num < end);

I don't think this assert is necessary. Only the second one is.

If you want to check the range and return an error, please add an
Error **errp argument and have the callers pass &error_fatal. It would
have the same effect.


Thanks,

C.


> +    g_assert(index < ARRAY_SIZE(s->uart));
> +    qdev_prop_set_chr(DEVICE(&s->uart[index]), "chardev", chr);
>   }
>   
>   /*
> diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h
> index 9d0af84a8c..5ab0902da0 100644
> --- a/include/hw/arm/aspeed_soc.h
> +++ b/include/hw/arm/aspeed_soc.h
> @@ -140,6 +140,7 @@ struct AspeedSoCClass {
>       int wdts_num;
>       int macs_num;
>       int uarts_num;
> +    int uarts_base;
>       const int *irqmap;
>       const hwaddr *memmap;
>       uint32_t num_cpus;
> @@ -151,6 +152,7 @@ const char *aspeed_soc_cpu_type(AspeedSoCClass *sc);
>   enum {
>       ASPEED_DEV_SPI_BOOT,
>       ASPEED_DEV_IOMEM,
> +    ASPEED_DEV_UART0,
>       ASPEED_DEV_UART1,
>       ASPEED_DEV_UART2,
>       ASPEED_DEV_UART3,
Jamin Lin Feb. 15, 2024, 1:31 a.m. UTC | #2
> -----Original Message-----
> From: Cédric Le Goater <clegoate@redhat.com>
> Sent: Friday, February 9, 2024 4:27 PM
> To: Jamin Lin <jamin_lin@aspeedtech.com>; Cédric Le Goater <clg@kaod.org>;
> Peter Maydell <peter.maydell@linaro.org>; Andrew Jeffery
> <andrew@codeconstruct.com.au>; Joel Stanley <joel@jms.id.au>; open
> list:ASPEED BMCs <qemu-arm@nongnu.org>; open list:All patches CC here
> <qemu-devel@nongnu.org>
> Cc: Troy Lee <troy_lee@aspeedtech.com>
> Subject: Re: [PATCH v2 1/2] aspeed: introduce a new UART0 device name
> 
> Hello Jamin,
> 
Thanks for review and sorry reply you late due to my Chinese new year holiday.
> On 2/7/24 21:02, Jamin Lin via wrote:
> > The Aspeed datasheet refers to the UART controllers as UART1 - UART13
> > for the ast10x0, ast2600, ast2500 and ast2400 SoCs and the Aspeed
> > ast2700 introduces an UART0 and the UART controllers as UART0 -
> > UART12.
> >
> > To keep the naming in the QEMU models
> > in sync with the datasheet, let's introduce a new  UART0 device name
> > and do the required adjustements, etc ...
> 
> Please drop the etc...
Will fix

> 
> >
> > Signed-off-by: Troy Lee <troy_lee@aspeedtech.com>
> > Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
> > ---
> >   hw/arm/aspeed.c             | 13 ++++++++-----
> >   hw/arm/aspeed_ast10x0.c     |  1 +
> >   hw/arm/aspeed_ast2400.c     |  2 ++
> >   hw/arm/aspeed_ast2600.c     |  1 +
> >   hw/arm/aspeed_soc_common.c  | 14 +++++++++-----
> >   include/hw/arm/aspeed_soc.h |  2 ++
> >   6 files changed, 23 insertions(+), 10 deletions(-)
> >
> > diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c index
> > 09b1e823ba..06d863958b 100644
> > --- a/hw/arm/aspeed.c
> > +++ b/hw/arm/aspeed.c
> > @@ -342,7 +342,7 @@ static void
> connect_serial_hds_to_uarts(AspeedMachineState *bmc)
> >       int uart_chosen = bmc->uart_chosen ? bmc->uart_chosen :
> > amc->uart_default;
> >
> >       aspeed_soc_uart_set_chr(s, uart_chosen, serial_hd(0));
> > -    for (int i = 1, uart = ASPEED_DEV_UART1; i < sc->uarts_num; i++,
> uart++) {
> > +    for (int i = 0, uart = sc->uarts_base; i < sc->uarts_num; i++,
> > + uart++) {
> >           if (uart == uart_chosen) {
> >               continue;
> >           }
> > @@ -1094,7 +1094,7 @@ static char *aspeed_get_bmc_console(Object *obj,
> Error **errp)
> >       AspeedMachineClass *amc = ASPEED_MACHINE_GET_CLASS(bmc);
> >       int uart_chosen = bmc->uart_chosen ? bmc->uart_chosen :
> > amc->uart_default;
> >
> > -    return g_strdup_printf("uart%d", uart_chosen - ASPEED_DEV_UART1 +
> 1);
> > +    return g_strdup_printf("uart%d", uart_chosen - ASPEED_DEV_UART0);
> >   }
> >
> >   static void aspeed_set_bmc_console(Object *obj, const char *value,
> > Error **errp) @@ -1103,6 +1103,8 @@ static void
> aspeed_set_bmc_console(Object *obj, const char *value, Error **errp)
> >       AspeedMachineClass *amc = ASPEED_MACHINE_GET_CLASS(bmc);
> >       AspeedSoCClass *sc =
> ASPEED_SOC_CLASS(object_class_by_name(amc->soc_name));
> >       int val;
> > +    int start = sc->uarts_base - ASPEED_DEV_UART0;
> > +    int end = start + sc->uarts_num;
> 
> 
> To help the reader, I would introduce these helpers at the end of aspeed_soc.h :
> 
>      static inline int aspeed_uart_index(int uart_dev)
>      {
>          return uart_dev - ASPEED_DEV_UART0;
>      }
> 
>      static inline int aspeed_uart_first(AspeedSoCClass *sc)
>      {
>          return aspeed_uart_index(sc->uarts_base);
>      }
> 
>      static inline int aspeed_uart_last(AspeedSoCClass *sc)
>      {
>          return aspeed_uart_first(sc) + sc->uarts_num - 1;
>      }
> 
Will add
> 
> >       if (sscanf(value, "uart%u", &val) != 1) {
> >           error_setg(errp, "Bad value for \"uart\" property"); @@
> > -1110,11 +1112,12 @@ static void aspeed_set_bmc_console(Object *obj,
> const char *value, Error **errp)
> >       }
> >
> >       /* The number of UART depends on the SoC */
> > -    if (val < 1 || val > sc->uarts_num) {
> > -        error_setg(errp, "\"uart\" should be in range [1 - %d]",
> sc->uarts_num);
> > +    if (val < start || val >= end) {
> > +        error_setg(errp, "\"uart\" should be in range [%d - %d]",
> > +                   start, end - 1);
> >           return;
> >       }
> > -    bmc->uart_chosen = ASPEED_DEV_UART1 + val - 1;
> > +    bmc->uart_chosen = val + ASPEED_DEV_UART0;
> >   }
> >
> >   static void aspeed_machine_class_props_init(ObjectClass *oc) diff
> > --git a/hw/arm/aspeed_ast10x0.c b/hw/arm/aspeed_ast10x0.c index
> > c3b5116a6a..2634e0f654 100644
> > --- a/hw/arm/aspeed_ast10x0.c
> > +++ b/hw/arm/aspeed_ast10x0.c
> > @@ -436,6 +436,7 @@ static void
> aspeed_soc_ast1030_class_init(ObjectClass *klass, void *data)
> >       sc->wdts_num = 4;
> >       sc->macs_num = 1;
> >       sc->uarts_num = 13;
> > +    sc->uarts_base = ASPEED_DEV_UART1;
> >       sc->irqmap = aspeed_soc_ast1030_irqmap;
> >       sc->memmap = aspeed_soc_ast1030_memmap;
> >       sc->num_cpus = 1;
> > diff --git a/hw/arm/aspeed_ast2400.c b/hw/arm/aspeed_ast2400.c index
> > 8829561bb6..95da85fee0 100644
> > --- a/hw/arm/aspeed_ast2400.c
> > +++ b/hw/arm/aspeed_ast2400.c
> > @@ -523,6 +523,7 @@ static void
> aspeed_soc_ast2400_class_init(ObjectClass *oc, void *data)
> >       sc->wdts_num     = 2;
> >       sc->macs_num     = 2;
> >       sc->uarts_num    = 5;
> > +    sc->uarts_base   = ASPEED_DEV_UART1;
> >       sc->irqmap       = aspeed_soc_ast2400_irqmap;
> >       sc->memmap       = aspeed_soc_ast2400_memmap;
> >       sc->num_cpus     = 1;
> > @@ -551,6 +552,7 @@ static void
> aspeed_soc_ast2500_class_init(ObjectClass *oc, void *data)
> >       sc->wdts_num     = 3;
> >       sc->macs_num     = 2;
> >       sc->uarts_num    = 5;
> > +    sc->uarts_base   = ASPEED_DEV_UART1;
> >       sc->irqmap       = aspeed_soc_ast2500_irqmap;
> >       sc->memmap       = aspeed_soc_ast2500_memmap;
> >       sc->num_cpus     = 1;
> > diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c index
> > 4ee32ea99d..f74561ecdc 100644
> > --- a/hw/arm/aspeed_ast2600.c
> > +++ b/hw/arm/aspeed_ast2600.c
> > @@ -666,6 +666,7 @@ static void
> aspeed_soc_ast2600_class_init(ObjectClass *oc, void *data)
> >       sc->wdts_num     = 4;
> >       sc->macs_num     = 4;
> >       sc->uarts_num    = 13;
> > +    sc->uarts_base   = ASPEED_DEV_UART1;
> >       sc->irqmap       = aspeed_soc_ast2600_irqmap;
> >       sc->memmap       = aspeed_soc_ast2600_memmap;
> >       sc->num_cpus     = 2;
> > diff --git a/hw/arm/aspeed_soc_common.c
> b/hw/arm/aspeed_soc_common.c
> > index 123a0c432c..54c875c8d5 100644
> > --- a/hw/arm/aspeed_soc_common.c
> > +++ b/hw/arm/aspeed_soc_common.c
> > @@ -36,7 +36,7 @@ bool aspeed_soc_uart_realize(AspeedSoCState *s,
> Error **errp)
> >       AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
> >       SerialMM *smm;
> >
> > -    for (int i = 0, uart = ASPEED_DEV_UART1; i < sc->uarts_num; i++,
> uart++) {
> > +    for (int i = 0, uart = sc->uarts_base; i < sc->uarts_num; i++,
> > + uart++) {
> >           smm = &s->uart[i];
> >
> >           /* Chardev property is set by the machine. */ @@ -58,10
> > +58,14 @@ bool aspeed_soc_uart_realize(AspeedSoCState *s, Error **errp)
> >   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);
> > +    int uart_num = dev - ASPEED_DEV_UART0;
> > +    int start = sc->uarts_base - ASPEED_DEV_UART0;
> > +    int end = start + sc->uarts_num;
> > +    int index = uart_num - start;
> > +
> > +    g_assert(uart_num >= start && uart_num < end);
> 
> I don't think this assert is necessary. Only the second one is.
> 
> If you want to check the range and return an error, please add an Error **errp
> argument and have the callers pass &error_fatal. It would have the same
> effect.
> 
Will fix.
> 
> Thanks,
> 
> C.
> 
> 
> > +    g_assert(index < ARRAY_SIZE(s->uart));
> > +    qdev_prop_set_chr(DEVICE(&s->uart[index]), "chardev", chr);
> >   }
> >
> >   /*
> > diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h
> > index 9d0af84a8c..5ab0902da0 100644
> > --- a/include/hw/arm/aspeed_soc.h
> > +++ b/include/hw/arm/aspeed_soc.h
> > @@ -140,6 +140,7 @@ struct AspeedSoCClass {
> >       int wdts_num;
> >       int macs_num;
> >       int uarts_num;
> > +    int uarts_base;
> >       const int *irqmap;
> >       const hwaddr *memmap;
> >       uint32_t num_cpus;
> > @@ -151,6 +152,7 @@ const char *aspeed_soc_cpu_type(AspeedSoCClass
> *sc);
> >   enum {
> >       ASPEED_DEV_SPI_BOOT,
> >       ASPEED_DEV_IOMEM,
> > +    ASPEED_DEV_UART0,
> >       ASPEED_DEV_UART1,
> >       ASPEED_DEV_UART2,
> >       ASPEED_DEV_UART3,
diff mbox series

Patch

diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index 09b1e823ba..06d863958b 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -342,7 +342,7 @@  static void connect_serial_hds_to_uarts(AspeedMachineState *bmc)
     int uart_chosen = bmc->uart_chosen ? bmc->uart_chosen : amc->uart_default;
 
     aspeed_soc_uart_set_chr(s, uart_chosen, serial_hd(0));
-    for (int i = 1, uart = ASPEED_DEV_UART1; i < sc->uarts_num; i++, uart++) {
+    for (int i = 0, uart = sc->uarts_base; i < sc->uarts_num; i++, uart++) {
         if (uart == uart_chosen) {
             continue;
         }
@@ -1094,7 +1094,7 @@  static char *aspeed_get_bmc_console(Object *obj, Error **errp)
     AspeedMachineClass *amc = ASPEED_MACHINE_GET_CLASS(bmc);
     int uart_chosen = bmc->uart_chosen ? bmc->uart_chosen : amc->uart_default;
 
-    return g_strdup_printf("uart%d", uart_chosen - ASPEED_DEV_UART1 + 1);
+    return g_strdup_printf("uart%d", uart_chosen - ASPEED_DEV_UART0);
 }
 
 static void aspeed_set_bmc_console(Object *obj, const char *value, Error **errp)
@@ -1103,6 +1103,8 @@  static void aspeed_set_bmc_console(Object *obj, const char *value, Error **errp)
     AspeedMachineClass *amc = ASPEED_MACHINE_GET_CLASS(bmc);
     AspeedSoCClass *sc = ASPEED_SOC_CLASS(object_class_by_name(amc->soc_name));
     int val;
+    int start = sc->uarts_base - ASPEED_DEV_UART0;
+    int end = start + sc->uarts_num;
 
     if (sscanf(value, "uart%u", &val) != 1) {
         error_setg(errp, "Bad value for \"uart\" property");
@@ -1110,11 +1112,12 @@  static void aspeed_set_bmc_console(Object *obj, const char *value, Error **errp)
     }
 
     /* The number of UART depends on the SoC */
-    if (val < 1 || val > sc->uarts_num) {
-        error_setg(errp, "\"uart\" should be in range [1 - %d]", sc->uarts_num);
+    if (val < start || val >= end) {
+        error_setg(errp, "\"uart\" should be in range [%d - %d]",
+                   start, end - 1);
         return;
     }
-    bmc->uart_chosen = ASPEED_DEV_UART1 + val - 1;
+    bmc->uart_chosen = val + ASPEED_DEV_UART0;
 }
 
 static void aspeed_machine_class_props_init(ObjectClass *oc)
diff --git a/hw/arm/aspeed_ast10x0.c b/hw/arm/aspeed_ast10x0.c
index c3b5116a6a..2634e0f654 100644
--- a/hw/arm/aspeed_ast10x0.c
+++ b/hw/arm/aspeed_ast10x0.c
@@ -436,6 +436,7 @@  static void aspeed_soc_ast1030_class_init(ObjectClass *klass, void *data)
     sc->wdts_num = 4;
     sc->macs_num = 1;
     sc->uarts_num = 13;
+    sc->uarts_base = ASPEED_DEV_UART1;
     sc->irqmap = aspeed_soc_ast1030_irqmap;
     sc->memmap = aspeed_soc_ast1030_memmap;
     sc->num_cpus = 1;
diff --git a/hw/arm/aspeed_ast2400.c b/hw/arm/aspeed_ast2400.c
index 8829561bb6..95da85fee0 100644
--- a/hw/arm/aspeed_ast2400.c
+++ b/hw/arm/aspeed_ast2400.c
@@ -523,6 +523,7 @@  static void aspeed_soc_ast2400_class_init(ObjectClass *oc, void *data)
     sc->wdts_num     = 2;
     sc->macs_num     = 2;
     sc->uarts_num    = 5;
+    sc->uarts_base   = ASPEED_DEV_UART1;
     sc->irqmap       = aspeed_soc_ast2400_irqmap;
     sc->memmap       = aspeed_soc_ast2400_memmap;
     sc->num_cpus     = 1;
@@ -551,6 +552,7 @@  static void aspeed_soc_ast2500_class_init(ObjectClass *oc, void *data)
     sc->wdts_num     = 3;
     sc->macs_num     = 2;
     sc->uarts_num    = 5;
+    sc->uarts_base   = ASPEED_DEV_UART1;
     sc->irqmap       = aspeed_soc_ast2500_irqmap;
     sc->memmap       = aspeed_soc_ast2500_memmap;
     sc->num_cpus     = 1;
diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
index 4ee32ea99d..f74561ecdc 100644
--- a/hw/arm/aspeed_ast2600.c
+++ b/hw/arm/aspeed_ast2600.c
@@ -666,6 +666,7 @@  static void aspeed_soc_ast2600_class_init(ObjectClass *oc, void *data)
     sc->wdts_num     = 4;
     sc->macs_num     = 4;
     sc->uarts_num    = 13;
+    sc->uarts_base   = ASPEED_DEV_UART1;
     sc->irqmap       = aspeed_soc_ast2600_irqmap;
     sc->memmap       = aspeed_soc_ast2600_memmap;
     sc->num_cpus     = 2;
diff --git a/hw/arm/aspeed_soc_common.c b/hw/arm/aspeed_soc_common.c
index 123a0c432c..54c875c8d5 100644
--- a/hw/arm/aspeed_soc_common.c
+++ b/hw/arm/aspeed_soc_common.c
@@ -36,7 +36,7 @@  bool aspeed_soc_uart_realize(AspeedSoCState *s, Error **errp)
     AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
     SerialMM *smm;
 
-    for (int i = 0, uart = ASPEED_DEV_UART1; i < sc->uarts_num; i++, uart++) {
+    for (int i = 0, uart = sc->uarts_base; i < sc->uarts_num; i++, uart++) {
         smm = &s->uart[i];
 
         /* Chardev property is set by the machine. */
@@ -58,10 +58,14 @@  bool aspeed_soc_uart_realize(AspeedSoCState *s, Error **errp)
 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);
+    int uart_num = dev - ASPEED_DEV_UART0;
+    int start = sc->uarts_base - ASPEED_DEV_UART0;
+    int end = start + sc->uarts_num;
+    int index = uart_num - start;
+
+    g_assert(uart_num >= start && uart_num < end);
+    g_assert(index < ARRAY_SIZE(s->uart));
+    qdev_prop_set_chr(DEVICE(&s->uart[index]), "chardev", chr);
 }
 
 /*
diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h
index 9d0af84a8c..5ab0902da0 100644
--- a/include/hw/arm/aspeed_soc.h
+++ b/include/hw/arm/aspeed_soc.h
@@ -140,6 +140,7 @@  struct AspeedSoCClass {
     int wdts_num;
     int macs_num;
     int uarts_num;
+    int uarts_base;
     const int *irqmap;
     const hwaddr *memmap;
     uint32_t num_cpus;
@@ -151,6 +152,7 @@  const char *aspeed_soc_cpu_type(AspeedSoCClass *sc);
 enum {
     ASPEED_DEV_SPI_BOOT,
     ASPEED_DEV_IOMEM,
+    ASPEED_DEV_UART0,
     ASPEED_DEV_UART1,
     ASPEED_DEV_UART2,
     ASPEED_DEV_UART3,