RE: [PATCH v3 0/2] Fix coverity issues for AST2700

2024-06-25 Thread Jamin Lin
Hi Cedric, 

> -Original Message-
> From: Cédric Le Goater 
> Sent: Tuesday, June 25, 2024 3:22 PM
> To: Jamin Lin ; Peter Maydell
> ; Steven Lee ; Troy
> Lee ; Andrew Jeffery ;
> Joel Stanley ; open list:ASPEED BMCs
> ; open list:All patches CC here
> 
> Subject: Re: [PATCH v3 0/2] Fix coverity issues for AST2700
> 
> Hello Jamin
> 
> On 6/25/24 9:07 AM, Jamin Lin wrote:
> > change from v1:
> > aspeed/soc: coverity defect: DIVIDE_BY_ZERO
> > aspeed/sdmc: coverity defect: Control flow issues (DEADCODE)
> >
> > change from v2:
> > add more commit log from reviewer suggestion, Cédric.
> >
> > change from v3:
> > replace qemu_log_mask with assert dram size 0.
> >
> > Jamin Lin (2):
> >aspeed/soc: Fix possible divide by zero
> >aspeed/sdmc: Remove extra R_MAIN_STATUS case
> >
> >   hw/arm/aspeed_ast27x0.c | 2 ++
> >   hw/misc/aspeed_sdmc.c   | 1 -
> >   2 files changed, 2 insertions(+), 1 deletion(-)
> >
> 
> LGTM.
> 
> Could you please review :
> 
Done.
Thanks-Jamin
> https://lore.kernel.org/qemu-devel/20240625065839.485034-1-...@redhat.co
> m/T/#u
> 
> Thanks,
> 
> C.
> 



RE: [PATCH] aspeed/sdmc: Check RAM size value at realize time

2024-06-25 Thread Jamin Lin
> -Original Message-
> From: Cédric Le Goater 
> Sent: Tuesday, June 25, 2024 2:59 PM
> To: qemu-...@nongnu.org; qemu-devel@nongnu.org
> Cc: Peter Maydell ; Joel Stanley ;
> Andrew Jeffery ; Jamin Lin
> ; Cédric Le Goater 
> Subject: [PATCH] aspeed/sdmc: Check RAM size value at realize time
> 
> The RAM size of the SDMC device is validated for the SoC and set when the
> Aspeed machines are initialized and then later used by several SoC
> implementations. However, the SDMC model never checks that the RAM size
> has been actually set before being used. Do that at realize.
> 
> Signed-off-by: Cédric Le Goater 
> ---
>  hw/misc/aspeed_sdmc.c | 6 ++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/hw/misc/aspeed_sdmc.c b/hw/misc/aspeed_sdmc.c index
> 94eed9264d09..ebf139cb5c91 100644
> --- a/hw/misc/aspeed_sdmc.c
> +++ b/hw/misc/aspeed_sdmc.c
> @@ -271,6 +271,12 @@ static void aspeed_sdmc_realize(DeviceState *dev,
> Error **errp)
>  AspeedSDMCClass *asc = ASPEED_SDMC_GET_CLASS(s);
> 
>  assert(asc->max_ram_size < 4 * GiB || asc->is_bus64bit);
> +
> +if (!s->ram_size) {
> +error_setg(errp, "RAM size is not set");
> +return;
> +}
> +
>  s->max_ram_size = asc->max_ram_size;
> 
>  memory_region_init_io(>iomem, OBJECT(s), _sdmc_ops, s,
> --
> 2.45.2

Reviewed-by: Jamin_lin < jamin_...@aspeedtech.com>

Thanks-Jamin 




[PATCH v3 2/2] aspeed/sdmc: Remove extra R_MAIN_STATUS case

2024-06-25 Thread Jamin Lin via
Coverity reports that the newly added 'case R_MAIN_STATUS' is DEADCODE
because it can not be reached. This is because R_MAIN_STATUS is handled
before in the "Unprotected registers" switch statement. Remove it.

Fixes: Coverity CID 1547112
Signed-off-by: Jamin Lin 
Reviewed-by: Cédric Le Goater 
[ clg: Rewrote commit log ]
Signed-off-by: Cédric Le Goater 
---
 hw/misc/aspeed_sdmc.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/hw/misc/aspeed_sdmc.c b/hw/misc/aspeed_sdmc.c
index 93e2e29ead..94eed9264d 100644
--- a/hw/misc/aspeed_sdmc.c
+++ b/hw/misc/aspeed_sdmc.c
@@ -589,7 +589,6 @@ static void aspeed_2700_sdmc_write(AspeedSDMCState *s, 
uint32_t reg,
 case R_INT_STATUS:
 case R_INT_CLEAR:
 case R_INT_MASK:
-case R_MAIN_STATUS:
 case R_ERR_STATUS:
 case R_ECC_FAIL_STATUS:
 case R_ECC_FAIL_ADDR:
-- 
2.25.1




[PATCH v3 1/2] aspeed/soc: Fix possible divide by zero

2024-06-25 Thread Jamin Lin via
Coverity reports a possible DIVIDE_BY_ZERO issue regarding the
"ram_size" object property. This can not happen because RAM has
predefined valid sizes per SoC. Nevertheless, add a test to
close the issue.

Fixes: Coverity CID 1547113
Signed-off-by: Jamin Lin 
Reviewed-by: Cédric Le Goater 
[ clg: Rewrote commit log ]
Signed-off-by: Cédric Le Goater 
---
 hw/arm/aspeed_ast27x0.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/hw/arm/aspeed_ast27x0.c b/hw/arm/aspeed_ast27x0.c
index b6876b4862..18e6a8b10c 100644
--- a/hw/arm/aspeed_ast27x0.c
+++ b/hw/arm/aspeed_ast27x0.c
@@ -211,6 +211,8 @@ static void aspeed_ram_capacity_write(void *opaque, hwaddr 
addr, uint64_t data,
 ram_size = object_property_get_uint(OBJECT(>sdmc), "ram-size",
 _abort);
 
+assert(ram_size > 0);
+
 /*
  * Emulate ddr capacity hardware behavior.
  * If writes the data to the address which is beyond the ram size,
-- 
2.25.1




[PATCH v3 0/2] Fix coverity issues for AST2700

2024-06-25 Thread Jamin Lin via
change from v1:
aspeed/soc: coverity defect: DIVIDE_BY_ZERO
aspeed/sdmc: coverity defect: Control flow issues (DEADCODE)

change from v2:
add more commit log from reviewer suggestion, Cédric.

change from v3:
replace qemu_log_mask with assert dram size 0.

Jamin Lin (2):
  aspeed/soc: Fix possible divide by zero
  aspeed/sdmc: Remove extra R_MAIN_STATUS case

 hw/arm/aspeed_ast27x0.c | 2 ++
 hw/misc/aspeed_sdmc.c   | 1 -
 2 files changed, 2 insertions(+), 1 deletion(-)

-- 
2.25.1




RE: [PATCH v2 1/2] aspeed/soc: Fix possible divide by zero

2024-06-25 Thread Jamin Lin
Hi Cedric,

> -Original Message-
> From: Cédric Le Goater 
> Sent: Tuesday, June 25, 2024 2:38 PM
> To: Jamin Lin ; cmd
> ; Peter Maydell
> ; Steven Lee ; Troy
> Lee ; Andrew Jeffery ;
> Joel Stanley ; open list:ASPEED BMCs
> ; open list:All patches CC here
> 
> Cc: Cédric Le Goater 
> Subject: Re: [PATCH v2 1/2] aspeed/soc: Fix possible divide by zero
> 
> On 6/25/24 8:15 AM, Jamin Lin wrote:
> > Hi cmd, Cedric and Peter,
> >
> >> -Original Message-
> >> From: cmd 
> >> Sent: Tuesday, June 25, 2024 2:07 PM
> >> To: Cédric Le Goater ; Jamin Lin
> >> ; Peter Maydell ;
> >> Steven Lee ; Troy Lee
> ;
> >> Andrew Jeffery ; Joel Stanley
> >> ; open list:ASPEED BMCs ; open
> >> list:All patches CC here 
> >> Cc: Cédric Le Goater 
> >> Subject: Re: [PATCH v2 1/2] aspeed/soc: Fix possible divide by zero
> >>
> >>
> >> On 25/06/2024 08:03, Cédric Le Goater wrote:
> >>> On 6/25/24 8:00 AM, cmd wrote:
> >>>> Hi
> >>>>
> >>>> On 25/06/2024 03:50, Jamin Lin via wrote:
> >>>>> Coverity reports a possible DIVIDE_BY_ZERO issue regarding the
> >>>>> "ram_size" object property. This can not happen because RAM has
> >>>>> predefined valid sizes per SoC. Nevertheless, add a test to close
> >>>>> the issue.
> >>>>>
> >>>>> Fixes: Coverity CID 1547113
> >>>>> Signed-off-by: Jamin Lin 
> >>>>> Reviewed-by: Cédric Le Goater  [ clg: Rewrote
> >>>>> commit log ]
> >>>>> Signed-off-by: Cédric Le Goater 
> >>>>> ---
> >>>>>    hw/arm/aspeed_ast27x0.c | 6 ++
> >>>>>    1 file changed, 6 insertions(+)
> >>>>>
> >>>>> diff --git a/hw/arm/aspeed_ast27x0.c b/hw/arm/aspeed_ast27x0.c
> >>>>> index b6876b4862..d14a46df6f 100644
> >>>>> --- a/hw/arm/aspeed_ast27x0.c
> >>>>> +++ b/hw/arm/aspeed_ast27x0.c
> >>>>> @@ -211,6 +211,12 @@ static void aspeed_ram_capacity_write(void
> >>>>> *opaque, hwaddr addr, uint64_t data,
> >>>>>    ram_size = object_property_get_uint(OBJECT(>sdmc),
> >>>>> "ram-size",
> >>>>>    
> r_a
> >> bort);
> >>>>> +    if (!ram_size) {
> >>>>> +    qemu_log_mask(LOG_GUEST_ERROR,
> >>>>> +  "%s: ram_size is zero",  __func__);
> >>>>> +    return;
> >>>>> +    }
> >>>>> +
> >>>> If we are sure that the error cannot happen, shouldn't we assert
> >>>> instead?
> >>>
> >>> Yes. That is what Peter suggested. This needs to be changed.
> >>>
> > Thanks for review and suggestion.
> > How about this change?
> >
> > assert(ram_size > 0);
> 
> yes.
> 
> I will send another patch fixing a long standing issue in the SDMC model not
> checking the ram_size value in the realize handler. It relies on the 
> "ram-size"
> property being set.
> 
> Thanks,
> 
Will send v3 patch and thanks for your review and help.
Jamin

> C.
> 
> 
> > If you agree, I will send v3 patch.
> > Thanks-Jamin
> >
> >>>
> >>> Thanks,
> >>>
> >>> C.
> >>>
> >> Ok fine, I didn't see the message, sorry!
> >>
> >> Thanks
> >>
> >>   >cmd
> >>
> >>>
> >>>
> >>>>>    /*
> >>>>>     * Emulate ddr capacity hardware behavior.
> >>>>>     * If writes the data to the address which is beyond the
> >>>>> ram size,
> >>>



RE: [PATCH v2 1/2] aspeed/soc: Fix possible divide by zero

2024-06-25 Thread Jamin Lin
Hi cmd, Cedric and Peter,

> -Original Message-
> From: cmd 
> Sent: Tuesday, June 25, 2024 2:07 PM
> To: Cédric Le Goater ; Jamin Lin ;
> Peter Maydell ; Steven Lee
> ; Troy Lee ; Andrew
> Jeffery ; Joel Stanley ; open
> list:ASPEED BMCs ; open list:All patches CC here
> 
> Cc: Cédric Le Goater 
> Subject: Re: [PATCH v2 1/2] aspeed/soc: Fix possible divide by zero
> 
> 
> On 25/06/2024 08:03, Cédric Le Goater wrote:
> > On 6/25/24 8:00 AM, cmd wrote:
> >> Hi
> >>
> >> On 25/06/2024 03:50, Jamin Lin via wrote:
> >>> Coverity reports a possible DIVIDE_BY_ZERO issue regarding the
> >>> "ram_size" object property. This can not happen because RAM has
> >>> predefined valid sizes per SoC. Nevertheless, add a test to close
> >>> the issue.
> >>>
> >>> Fixes: Coverity CID 1547113
> >>> Signed-off-by: Jamin Lin 
> >>> Reviewed-by: Cédric Le Goater  [ clg: Rewrote commit
> >>> log ]
> >>> Signed-off-by: Cédric Le Goater 
> >>> ---
> >>>   hw/arm/aspeed_ast27x0.c | 6 ++
> >>>   1 file changed, 6 insertions(+)
> >>>
> >>> diff --git a/hw/arm/aspeed_ast27x0.c b/hw/arm/aspeed_ast27x0.c index
> >>> b6876b4862..d14a46df6f 100644
> >>> --- a/hw/arm/aspeed_ast27x0.c
> >>> +++ b/hw/arm/aspeed_ast27x0.c
> >>> @@ -211,6 +211,12 @@ static void aspeed_ram_capacity_write(void
> >>> *opaque, hwaddr addr, uint64_t data,
> >>>   ram_size = object_property_get_uint(OBJECT(>sdmc),
> >>> "ram-size",
> >>>   _a
> bort);
> >>> +    if (!ram_size) {
> >>> +    qemu_log_mask(LOG_GUEST_ERROR,
> >>> +  "%s: ram_size is zero",  __func__);
> >>> +    return;
> >>> +    }
> >>> +
> >> If we are sure that the error cannot happen, shouldn't we assert
> >> instead?
> >
> > Yes. That is what Peter suggested. This needs to be changed.
> >
Thanks for review and suggestion.
How about this change?

assert(ram_size > 0);

If you agree, I will send v3 patch.
Thanks-Jamin

> >
> > Thanks,
> >
> > C.
> >
> Ok fine, I didn't see the message, sorry!
> 
> Thanks
> 
>  >cmd
> 
> >
> >
> >>>   /*
> >>>    * Emulate ddr capacity hardware behavior.
> >>>    * If writes the data to the address which is beyond the ram
> >>> size,
> >


RE: [PATCH v1 1/2] aspeed/soc: fix coverity issue

2024-06-24 Thread Jamin Lin
Hi Cedric,
> -Original Message-
> From: Cédric Le Goater 
> Sent: Monday, June 24, 2024 9:58 PM
> To: Peter Maydell ; Jamin Lin
> 
> Cc: Steven Lee ; Troy Lee
> ; Andrew Jeffery ; Joel
> Stanley ; open list:ASPEED BMCs ;
> open list:All patches CC here ; Troy Lee
> ; Yunlin Tang 
> Subject: Re: [PATCH v1 1/2] aspeed/soc: fix coverity issue
> 
> On 6/24/24 2:18 PM, Peter Maydell wrote:
> > On Wed, 19 Jun 2024 at 10:35, Jamin Lin 
> wrote:
> >>
> >> Fix coverity defect: DIVIDE_BY_ZERO.
> >>
> >> Signed-off-by: Jamin Lin 
> >> ---
> >>   hw/arm/aspeed_ast27x0.c | 6 ++
> >>   1 file changed, 6 insertions(+)
> >>
> >> diff --git a/hw/arm/aspeed_ast27x0.c b/hw/arm/aspeed_ast27x0.c index
> >> b6876b4862..d14a46df6f 100644
> >> --- a/hw/arm/aspeed_ast27x0.c
> >> +++ b/hw/arm/aspeed_ast27x0.c
> >> @@ -211,6 +211,12 @@ static void aspeed_ram_capacity_write(void
> *opaque, hwaddr addr, uint64_t data,
> >>   ram_size = object_property_get_uint(OBJECT(>sdmc),
> "ram-size",
> >>   _abort);
> >>
> >> +if (!ram_size) {
> >> +qemu_log_mask(LOG_GUEST_ERROR,
> >> +  "%s: ram_size is zero",  __func__);
> >> +return;
> >> +}
> >> +
> >
> > Isn't this a QEMU bug rather than a guest error? The RAM size
> > presumably should never be zero unless the board set the ram-size
> > property on the SDMC incorrectly. So the SDMC device should check (and
> > return an error from its realize
> > method) that the ram-size property is valid,
> 
> That's the case in aspeed_sdmc_set_ram_size() which is called from the
> aspeed machine init routine when the ram size is set.
> 
> Setting the machine ram size to zero on the command line doesn't report an
> error though and the size is the default.
> 
> > and then here we can just assert(ram_size != 0).
> 
> Yes.
> 
> Jamin, could you please send a v2 with the commit logs update I proposed ?
> See the patches on my aspeed-9.1 branch.
I resend v2 patch with your commit log, 
https://www.mail-archive.com/qemu-devel@nongnu.org/msg1050302.html
Do we need to drop this patch, 
https://www.mail-archive.com/qemu-devel@nongnu.org/msg1050301.html? 

Thanks-Jamin
> 
> Thanks,
> 
> C.


[PATCH v2 2/2] aspeed/sdmc: Remove extra R_MAIN_STATUS case

2024-06-24 Thread Jamin Lin via
Coverity reports that the newly added 'case R_MAIN_STATUS' is DEADCODE
because it can not be reached. This is because R_MAIN_STATUS is handled
before in the "Unprotected registers" switch statement. Remove it.

Fixes: Coverity CID 1547112
Signed-off-by: Jamin Lin 
Reviewed-by: Cédric Le Goater 
[ clg: Rewrote commit log ]
Signed-off-by: Cédric Le Goater 
---
 hw/misc/aspeed_sdmc.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/hw/misc/aspeed_sdmc.c b/hw/misc/aspeed_sdmc.c
index 93e2e29ead..94eed9264d 100644
--- a/hw/misc/aspeed_sdmc.c
+++ b/hw/misc/aspeed_sdmc.c
@@ -589,7 +589,6 @@ static void aspeed_2700_sdmc_write(AspeedSDMCState *s, 
uint32_t reg,
 case R_INT_STATUS:
 case R_INT_CLEAR:
 case R_INT_MASK:
-case R_MAIN_STATUS:
 case R_ERR_STATUS:
 case R_ECC_FAIL_STATUS:
 case R_ECC_FAIL_ADDR:
-- 
2.25.1




[PATCH v2 0/2] Fix coverity issues for AST2700

2024-06-24 Thread Jamin Lin via
change from v1:
aspeed/soc: coverity defect: DIVIDE_BY_ZERO
aspeed/sdmc: coverity defect: Control flow issues (DEADCODE)

change from v2:
add more commit log from reviewer, Cédric.

Jamin Lin (2):
  aspeed/soc: Fix possible divide by zero
  aspeed/sdmc: Remove extra R_MAIN_STATUS case

 hw/arm/aspeed_ast27x0.c | 6 ++
 hw/misc/aspeed_sdmc.c   | 1 -
 2 files changed, 6 insertions(+), 1 deletion(-)

-- 
2.25.1




[PATCH v2 1/2] aspeed/soc: Fix possible divide by zero

2024-06-24 Thread Jamin Lin via
Coverity reports a possible DIVIDE_BY_ZERO issue regarding the
"ram_size" object property. This can not happen because RAM has
predefined valid sizes per SoC. Nevertheless, add a test to
close the issue.

Fixes: Coverity CID 1547113
Signed-off-by: Jamin Lin 
Reviewed-by: Cédric Le Goater 
[ clg: Rewrote commit log ]
Signed-off-by: Cédric Le Goater 
---
 hw/arm/aspeed_ast27x0.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/hw/arm/aspeed_ast27x0.c b/hw/arm/aspeed_ast27x0.c
index b6876b4862..d14a46df6f 100644
--- a/hw/arm/aspeed_ast27x0.c
+++ b/hw/arm/aspeed_ast27x0.c
@@ -211,6 +211,12 @@ static void aspeed_ram_capacity_write(void *opaque, hwaddr 
addr, uint64_t data,
 ram_size = object_property_get_uint(OBJECT(>sdmc), "ram-size",
 _abort);
 
+if (!ram_size) {
+qemu_log_mask(LOG_GUEST_ERROR,
+  "%s: ram_size is zero",  __func__);
+return;
+}
+
 /*
  * Emulate ddr capacity hardware behavior.
  * If writes the data to the address which is beyond the ram size,
-- 
2.25.1




[PATCH v1 0/2] hw/net:ftgmac100: support AST2700

2024-06-19 Thread Jamin Lin via
change from v1:
- ftgmac100
 - fix coding style
 - support 64 bits dma dram address for AST2700

Jamin Lin (2):
  hw/net:ftgmac100: fix coding style
  hw/net:ftgmac100: support 64 bits dma dram address for AST2700

 hw/net/ftgmac100.c | 83 ++
 include/hw/net/ftgmac100.h |  9 ++---
 2 files changed, 61 insertions(+), 31 deletions(-)

-- 
2.34.1




[PATCH v1 1/2] hw/net:ftgmac100: fix coding style

2024-06-19 Thread Jamin Lin via
Fix coding style issues from checkpatch.pl

Test command:
./scripts/checkpatch.pl --no-tree -f hw/net/ftgmac100.c

Signed-off-by: Jamin Lin 
---
 hw/net/ftgmac100.c | 12 
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/hw/net/ftgmac100.c b/hw/net/ftgmac100.c
index 74b6c3d9a7..25e4c0cd5b 100644
--- a/hw/net/ftgmac100.c
+++ b/hw/net/ftgmac100.c
@@ -238,7 +238,8 @@ typedef struct {
  */
 #define FTGMAC100_MAX_FRAME_SIZE9220
 
-/* Limits depending on the type of the frame
+/*
+ * Limits depending on the type of the frame
  *
  *   9216 for Jumbo frames (+ 4 for VLAN)
  *   1518 for other frames (+ 4 for VLAN)
@@ -533,8 +534,10 @@ static void ftgmac100_do_tx(FTGMAC100State *s, uint32_t 
tx_ring,
 break;
 }
 
-/* record transmit flags as they are valid only on the first
- * segment */
+/*
+ * record transmit flags as they are valid only on the first
+ * segment
+ */
 if (bd.des0 & FTGMAC100_TXDES0_FTS) {
 flags = bd.des1;
 }
@@ -639,7 +642,8 @@ static bool ftgmac100_can_receive(NetClientState *nc)
  */
 static uint32_t ftgmac100_rxpoll(FTGMAC100State *s)
 {
-/* Polling times :
+/*
+ * Polling times :
  *
  * Speed  TIME_SEL=0TIME_SEL=1
  *
-- 
2.34.1




[PATCH v1 2/2] hw/net:ftgmac100: support 64 bits dma dram address for AST2700

2024-06-19 Thread Jamin Lin via
ASPEED AST2700 SOC is a 64 bits quad core CPUs (Cortex-a35)
And the base address of dram is "0x4 " which
is 64bits address.

It have "Normal Priority Transmit Ring Base Address Register High(0x17C)",
"High Priority Transmit Ring Base Address Register High(0x184)" and
"Receive Ring Base Address Register High(0x18C)" to save the high part physical
address of descriptor manager.
Ex: TX descriptor manager address [34:0]
The "Normal Priority Transmit Ring Base Address Register High(0x17C)"
bits [2:0] which corresponds the bits [34:32] of the 64 bits address of
the TX ring buffer address.
The "Normal Priority Transmit Ring Base Address Register(0x20)" bits [31:0]
which corresponds the bits [31:0] of the 64 bits address
of the TX ring buffer address.

Besides, it have "TXDES 2 and 3" and "RXDES 2 and 3"
to save the high part physical address of packet buffer.
Ex: TX packet buffer address [34:0]
The "TXDES 2" bits [18:16] which corresponds the bits [34:32]
of the 64 bits address of the TX packet buffer address
and "TXDES 3" bits [31:0] which corresponds the bits [31:0]
of the 64 bits address of the TX packet buffer address.

Update TX/RX ring and descriptor data type to uint64_t
and supports TX/RX ring, descriptor and packet buffers
64 bits address for all ASPEED SOCs models.

Incrementing the version of vmstate to 2.

Signed-off-by: Jamin Lin 
---
 hw/net/ftgmac100.c | 71 ++
 include/hw/net/ftgmac100.h |  9 +++--
 2 files changed, 53 insertions(+), 27 deletions(-)

diff --git a/hw/net/ftgmac100.c b/hw/net/ftgmac100.c
index 25e4c0cd5b..add3c0e270 100644
--- a/hw/net/ftgmac100.c
+++ b/hw/net/ftgmac100.c
@@ -56,6 +56,10 @@
 #define FTGMAC100_PHYDATA 0x64
 #define FTGMAC100_FCR 0x68
 
+#define FTGMAC100_NPTXR_BADR_HIGH   0x17C
+#define FTGMAC100_HPTXR_BADR_HIGH   0x184
+#define FTGMAC100_RXR_BADR_HIGH 0x18C
+
 /*
  * Interrupt status register & interrupt enable register
  */
@@ -165,6 +169,8 @@
 #define FTGMAC100_TXDES1_TX2FIC  (1 << 30)
 #define FTGMAC100_TXDES1_TXIC(1 << 31)
 
+#define FTGMAC100_TXDES2_TXBUF_BADR_HI(x)   (((x) >> 16) & 0x7)
+
 /*
  * Receive descriptor
  */
@@ -198,6 +204,8 @@
 #define FTGMAC100_RXDES1_UDP_CHKSUM_ERR  (1 << 26)
 #define FTGMAC100_RXDES1_IP_CHKSUM_ERR   (1 << 27)
 
+#define FTGMAC100_RXDES2_RXBUF_BADR_HI(x)   (((x) >> 16) & 0x7)
+
 /*
  * Receive and transmit Buffer Descriptor
  */
@@ -515,12 +523,13 @@ out:
 return frame_size;
 }
 
-static void ftgmac100_do_tx(FTGMAC100State *s, uint32_t tx_ring,
-uint32_t tx_descriptor)
+static void ftgmac100_do_tx(FTGMAC100State *s, uint64_t tx_ring,
+uint64_t tx_descriptor)
 {
 int frame_size = 0;
 uint8_t *ptr = s->frame;
-uint32_t addr = tx_descriptor;
+uint64_t addr = tx_descriptor;
+uint64_t buf_addr = 0;
 uint32_t flags = 0;
 
 while (1) {
@@ -559,7 +568,10 @@ static void ftgmac100_do_tx(FTGMAC100State *s, uint32_t 
tx_ring,
 len =  sizeof(s->frame) - frame_size;
 }
 
-if (dma_memory_read(_space_memory, bd.des3,
+buf_addr = deposit64(buf_addr, 32, 32,
+ FTGMAC100_TXDES2_TXBUF_BADR_HI(bd.des2));
+buf_addr = deposit64(buf_addr, 0, 32, bd.des3);
+if (dma_memory_read(_space_memory, buf_addr,
 ptr, len, MEMTXATTRS_UNSPECIFIED)) {
 qemu_log_mask(LOG_GUEST_ERROR, "%s: failed to read packet @ 
0x%x\n",
   __func__, bd.des3);
@@ -710,7 +722,7 @@ static uint64_t ftgmac100_read(void *opaque, hwaddr addr, 
unsigned size)
 {
 FTGMAC100State *s = FTGMAC100(opaque);
 
-switch (addr & 0xff) {
+switch (addr) {
 case FTGMAC100_ISR:
 return s->isr;
 case FTGMAC100_IER:
@@ -726,9 +738,9 @@ static uint64_t ftgmac100_read(void *opaque, hwaddr addr, 
unsigned size)
 case FTGMAC100_MATH1:
 return s->math[1];
 case FTGMAC100_RXR_BADR:
-return s->rx_ring;
+return extract64(s->rx_ring, 0, 32);
 case FTGMAC100_NPTXR_BADR:
-return s->tx_ring;
+return extract64(s->tx_ring, 0, 32);
 case FTGMAC100_ITC:
 return s->itc;
 case FTGMAC100_DBLAC:
@@ -751,10 +763,15 @@ static uint64_t ftgmac100_read(void *opaque, hwaddr addr, 
unsigned size)
 /* We might want to support these one day */
 case FTGMAC100_HPTXPD: /* High Priority Transmit Poll Demand */
 case FTGMAC100_HPTXR_BADR: /* High Priority Transmit Ring Base Address */
+case FTGMAC100_HPTXR_BADR_HIGH:
 case FTGMAC100_MACSR: /* MAC Status Register (MACSR) */
 qemu_log_mask(LOG_UNIMP, "%s: read to unimplemented register 0x%"
   HWADDR_PRIx "\n", __fun

[PATCH v1 2/2] aspeed/sdmc: fix coverity issue

2024-06-19 Thread Jamin Lin via
Fix coverity defect: Control flow issues (DEADCODE)

Signed-off-by: Jamin Lin 
---
 hw/misc/aspeed_sdmc.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/hw/misc/aspeed_sdmc.c b/hw/misc/aspeed_sdmc.c
index 93e2e29ead..94eed9264d 100644
--- a/hw/misc/aspeed_sdmc.c
+++ b/hw/misc/aspeed_sdmc.c
@@ -589,7 +589,6 @@ static void aspeed_2700_sdmc_write(AspeedSDMCState *s, 
uint32_t reg,
 case R_INT_STATUS:
 case R_INT_CLEAR:
 case R_INT_MASK:
-case R_MAIN_STATUS:
 case R_ERR_STATUS:
 case R_ECC_FAIL_STATUS:
 case R_ECC_FAIL_ADDR:
-- 
2.34.1




[PATCH v1 0/2] Fix coverity issues for AST2700

2024-06-19 Thread Jamin Lin via
change from v1:
aspeed/soc: coverity defect: DIVIDE_BY_ZERO
aspeed/sdmc: coverity defect: Control flow issues (DEADCODE)

Jamin Lin (2):
  aspeed/soc: fix coverity issue
  aspeed/sdmc: fix coverity issue

 hw/arm/aspeed_ast27x0.c | 6 ++
 hw/misc/aspeed_sdmc.c   | 1 -
 2 files changed, 6 insertions(+), 1 deletion(-)

-- 
2.34.1




[PATCH v1 1/2] aspeed/soc: fix coverity issue

2024-06-19 Thread Jamin Lin via
Fix coverity defect: DIVIDE_BY_ZERO.

Signed-off-by: Jamin Lin 
---
 hw/arm/aspeed_ast27x0.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/hw/arm/aspeed_ast27x0.c b/hw/arm/aspeed_ast27x0.c
index b6876b4862..d14a46df6f 100644
--- a/hw/arm/aspeed_ast27x0.c
+++ b/hw/arm/aspeed_ast27x0.c
@@ -211,6 +211,12 @@ static void aspeed_ram_capacity_write(void *opaque, hwaddr 
addr, uint64_t data,
 ram_size = object_property_get_uint(OBJECT(>sdmc), "ram-size",
 _abort);
 
+if (!ram_size) {
+qemu_log_mask(LOG_GUEST_ERROR,
+  "%s: ram_size is zero",  __func__);
+return;
+}
+
 /*
  * Emulate ddr capacity hardware behavior.
  * If writes the data to the address which is beyond the ram size,
-- 
2.34.1




[PATCH] MAINTAINERS: Add reviewers for ASPEED BMCs

2024-06-05 Thread Jamin Lin via
Add ASPEED members "Steven Lee", "Troy Lee" and "Jamin Lin"
to be reviewers of ASPEED BMCs.

Signed-off-by: Jamin Lin 
Signed-off-by: Troy Lee 
Signed-off-by: Steven Lee 
---
 MAINTAINERS | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 951556224a..0f63bcdc7d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1158,6 +1158,9 @@ F: docs/system/arm/emcraft-sf2.rst
 ASPEED BMCs
 M: Cédric Le Goater 
 M: Peter Maydell 
+R: Steven Lee 
+R: Troy Lee 
+R: Jamin Lin 
 R: Andrew Jeffery 
 R: Joel Stanley 
 L: qemu-...@nongnu.org
-- 
2.25.1




RE: [PATCH] MAINTAINERS: Add maintainers for ASPEED BMCs

2024-06-05 Thread Jamin Lin
Hi Cedric,
> From: Cédric Le Goater 
> Sent: Wednesday, June 5, 2024 1:58 PM
> To: Jamin Lin ; Philippe Mathieu-Daudé
> ; Thomas Huth ; Michael S. Tsirkin
> ; Peter Maydell ; open list:All
> patches CC here 
> Cc: Steven Lee ; Troy Lee
> 
> Subject: Re: [PATCH] MAINTAINERS: Add maintainers for ASPEED BMCs
> 
> On 6/5/24 05:44, Jamin Lin wrote:
> > Add ASPEED members "Steven Lee", "Troy Lee" and "Jamin Lin"
> > to be maintainers of ASPEED BMCs.
> 
> Let's start with Reviewers. please resend.
> 
Got it. resend 
Thanks-Jamin

> https://qemu.readthedocs.io/en/v9.0.0/devel/maintainers.html
> 
> Thanks,
> 
> C.
> 
> 
> >
> > Signed-off-by: Jamin Lin 
> > Signed-off-by: Troy Lee 
> > Signed-off-by: Steven Lee 
> > ---
> >   MAINTAINERS | 3 +++
> >   1 file changed, 3 insertions(+)
> >
> > diff --git a/MAINTAINERS b/MAINTAINERS index 951556224a..39651be467
> > 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -1158,6 +1158,9 @@ F: docs/system/arm/emcraft-sf2.rst
> >   ASPEED BMCs
> >   M: Cédric Le Goater 
> >   M: Peter Maydell 
> > +M: Steven Lee 
> > +M: Troy Lee 
> > +M: Jamin Lin 
> >   R: Andrew Jeffery 
> >   R: Joel Stanley 
> >   L: qemu-...@nongnu.org



RE: [PATCH v4 00/16] Add AST2700 support

2024-06-04 Thread Jamin Lin
Hi Cedric, 

> From: Jamin Lin
> Subject: RE: [PATCH v4 00/16] Add AST2700 support
> 
> Hi Cedric,
> 
> > From: Cédric Le Goater 
> > On 5/28/24 12:02, Jamin Lin wrote:
> > > Hi Cedric,
> > >
> > >> -Original Message-
> > >> From: Cédric Le Goater 
> > >> Sent: Tuesday, May 28, 2024 5:56 PM
> > >> To: Jamin Lin ; Peter Maydell
> > >> ; Andrew Jeffery
> > >> ; Joel Stanley ;
> > >> Alistair Francis ; Cleber Rosa
> > >> ; Philippe Mathieu-Daudé ;
> > >> Wainer dos Santos Moschetta ; Beraldo Leal
> > >> ; open list:ASPEED BMCs ;
> > open
> > >> list:All patches CC here 
> > >> Cc: Troy Lee ; Yunlin Tang
> > >> 
> > >> Subject: Re: [PATCH v4 00/16] Add AST2700 support
> > >>
> > >> Jamin,
> > >>
> > >> I think you should add your self as a Reviewer to the ASPEED BMCs
> > >> machine in the MAINTAINERS files. Would you agree ?
> > >>
> > > Agree.
> > >
> > > Could you please add me, Troy and Steven in the MAINTAINERS files?
> > > steven_...@aspeedtech.com
> > > troy_...@aspeedtech.com
> > > jamin_...@aspeedtech.com
> >
> > You should send a patch updating the MAINTAINERS file with new names
> > and those promoted should reply that they agree, or not.
> >
> > See https://qemu.readthedocs.io/en/v9.0.0/devel/maintainers.html for
> > more info and the git history of MAINTAINERS also.
> >
> Will send a patch to updating the MAINTAINERS file.
> Thanks-Jamin
> > Thanks,
https://patchew.org/QEMU/20240605034413.1064845-1-jamin._5f...@aspeedtech.com/
Thanks-Jamin

> >
> > C.
> >



[PATCH] MAINTAINERS: Add maintainers for ASPEED BMCs

2024-06-04 Thread Jamin Lin via
Add ASPEED members "Steven Lee", "Troy Lee" and "Jamin Lin"
to be maintainers of ASPEED BMCs.

Signed-off-by: Jamin Lin 
Signed-off-by: Troy Lee 
Signed-off-by: Steven Lee 
---
 MAINTAINERS | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 951556224a..39651be467 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1158,6 +1158,9 @@ F: docs/system/arm/emcraft-sf2.rst
 ASPEED BMCs
 M: Cédric Le Goater 
 M: Peter Maydell 
+M: Steven Lee 
+M: Troy Lee 
+M: Jamin Lin 
 R: Andrew Jeffery 
 R: Joel Stanley 
 L: qemu-...@nongnu.org
-- 
2.25.1




RE: [PATCH v5 00/17] Add AST2700 support

2024-06-04 Thread Jamin Lin
Hi Cedric,

> From: Cédric Le Goater 
> Sent: Tuesday, June 4, 2024 7:52 PM
> To: Jamin Lin ; Peter Maydell
> ; Andrew Jeffery ;
> Joel Stanley ; Alistair Francis ; 
> Cleber
> Rosa ; Philippe Mathieu-Daudé ;
> Wainer dos Santos Moschetta ; Beraldo Leal
> ; open list:ASPEED BMCs ; open
> list:All patches CC here 
> Cc: Troy Lee ; Yunlin Tang
> 
> Subject: Re: [PATCH v5 00/17] Add AST2700 support
> 
> On 6/4/24 07:44, Jamin Lin wrote:
> > Changes from v1:
> > The patch series supports WDT, SDMC, SMC, SCU, SLI and INTC for AST2700
> SoC.
> >
> > Changes from v2:
> > - replace is_aarch64 with is_bus64bit for sdmc patch review.
> > - fix incorrect dram size for AST2700
> >
> > Changes from v3:
> > - Add AST2700 Evaluation board in ASPEED document
> > - Add avocado test cases for AST2700 Evaluation board
> > - Fix reviewers review issues and add reviewers suggestions
> > - Implement INTC model GICINT 128 to GICINT136 for AST2700
> >
> > Changes from v4:
> > - support 64 bits dma dram address associated with review issues
> > - support dma start length and 1 byte length unit associated with
> > review issues
> > - refactor intc model to fix serial console stuck issue and associated
> > with review issues
> >
> > Changes from v5:
> > - sdmc: incrementing the version of vmstate to 2.
> > - smc: support different memory region ops for SMC flash region
> > introduce a new "const MemoryRegionOps *" attribute in
> AspeedSMCClass and
> > use it in aspeed_smc_flash_realize function.
> > - intc: fix associated with review issues
> > - dram size detect: change to use address space API and simplify with write
> >  transaction on the DRAM memory region of the
> SoC.
> > - ast27x0_soc: update aspeed_soc_ast2700_gic function associated with
> review issues
> > and rename to aspeed_soc_ast2700_gic_realize
> 
> v5 looks good to me.
> 
> Do you plan to send a MAINTAINERS file ?
> 
Thanks for your kindly support and appreciate your help.
Yes, I am studying MAINTAINERS rules and will send a patch.
I will notify you via this email after I send the patch.
Thanks-Jamin

> Thanks,
> 
> C.
> 
> 
> 
> 
> >
> > Test Version:
> > qemu commit:
> >
> https://github.com/qemu/qemu/commit/74abb45dac6979e7ff76172b7f0a24e
> 869
> > 405184
> > applied patch:
> > https://patchew.org/QEMU/20240527124315.35356-1-...@redhat.com/
> >
> > Test steps:
> > 1. Download the latest openbmc image for AST2700 from
> AspeedTech-BMC/openbmc
> > repository,
> https://github.com/AspeedTech-BMC/openbmc/releases/tag/v09.01
> > link:
> >
> https://github.com/AspeedTech-BMC/openbmc/releases/download/v09.01/ast
> > 2700-default-obmc.tar.gz
> > 2. untar ast2700-default-obmc.tar.gz
> > ```
> > tar -xf ast2700-default-obmc.tar.gz
> > ```
> > 3. Run and the contents of scripts as following IMGDIR=ast2700-default
> > UBOOT_SIZE=$(stat --format=%s -L ${IMGDIR}/u-boot-nodtb.bin)
> > UBOOT_DTB_ADDR=$((0x4 + ${UBOOT_SIZE}))
> >
> > qemu-system-aarch64 -M ast2700-evb -nographic\
> >   -device
> loader,addr=0x4,file=${IMGDIR}/u-boot-nodtb.bin,force-raw=on\
> >   -device
> loader,addr=${UBOOT_DTB_ADDR},file=${IMGDIR}/u-boot.dtb,force-raw=on\
> >   -device loader,addr=0x43000,file=${IMGDIR}/bl31.bin,force-raw=on\
> >   -device
> loader,addr=0x43008,file=${IMGDIR}/optee/tee-raw.bin,force-raw=on\
> >   -device loader,addr=0x43000,cpu-num=0\
> >   -device loader,addr=0x43000,cpu-num=1\
> >   -device loader,addr=0x43000,cpu-num=2\
> >   -device loader,addr=0x43000,cpu-num=3\
> >   -smp 4\
> >   -drive file=${IMGDIR}/image-bmc,format=raw,if=mtd\
> >   -serial mon:stdio\
> >   -snapshot
> >
> > Jamin Lin (17):
> >aspeed/wdt: Add AST2700 support
> >aspeed/sli: Add AST2700 support
> >aspeed/sdmc: remove redundant macros
> >aspeed/sdmc: fix coding style
> >aspeed/sdmc: Add AST2700 support
> >aspeed/smc: correct device description
> >aspeed/smc: support dma start length and 1 byte length unit
> >aspeed/smc: support 64 bits dma dram address
> >aspeed/smc: support different memory region ops for SMC flash region
> >aspeed/smc: Add AST2700 support
> >aspeed/scu: Add AST2700 support
> >aspeed/intc: Add AST2700 support
> >aspeed/soc: Add AST2700 support
> >aspeed: Add an AST2700 eval board
> >aspeed/soc

[PATCH v5 03/17] aspeed/sdmc: remove redundant macros

2024-06-03 Thread Jamin Lin via
These macros are no longer used for ASPEED SOCs, so removes them.

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 
Reviewed-by: Cédric Le Goater 
---
 hw/misc/aspeed_sdmc.c | 15 ---
 1 file changed, 15 deletions(-)

diff --git a/hw/misc/aspeed_sdmc.c b/hw/misc/aspeed_sdmc.c
index 64cd1a81dc..74279bbe8e 100644
--- a/hw/misc/aspeed_sdmc.c
+++ b/hw/misc/aspeed_sdmc.c
@@ -76,10 +76,6 @@
 #define ASPEED_SDMC_VGA_32MB0x2
 #define ASPEED_SDMC_VGA_64MB0x3
 #define ASPEED_SDMC_DRAM_SIZE(x)(x & 0x3)
-#define ASPEED_SDMC_DRAM_64MB   0x0
-#define ASPEED_SDMC_DRAM_128MB  0x1
-#define ASPEED_SDMC_DRAM_256MB  0x2
-#define ASPEED_SDMC_DRAM_512MB  0x3
 
 #define ASPEED_SDMC_READONLY_MASK   \
 (ASPEED_SDMC_RESERVED | ASPEED_SDMC_VGA_COMPAT |\
@@ -100,17 +96,6 @@
 #define ASPEED_SDMC_CACHE_ENABLE(1 << 10) /* differs from AST2400 */
 #define ASPEED_SDMC_DRAM_TYPE   (1 << 4)  /* differs from AST2400 */
 
-/* DRAM size definitions differs */
-#define ASPEED_SDMC_AST2500_128MB   0x0
-#define ASPEED_SDMC_AST2500_256MB   0x1
-#define ASPEED_SDMC_AST2500_512MB   0x2
-#define ASPEED_SDMC_AST2500_1024MB  0x3
-
-#define ASPEED_SDMC_AST2600_256MB   0x0
-#define ASPEED_SDMC_AST2600_512MB   0x1
-#define ASPEED_SDMC_AST2600_1024MB  0x2
-#define ASPEED_SDMC_AST2600_2048MB  0x3
-
 #define ASPEED_SDMC_AST2500_READONLY_MASK   \
 (ASPEED_SDMC_HW_VERSION(0xf) | ASPEED_SDMC_CACHE_INITIAL_DONE | \
  ASPEED_SDMC_AST2500_RESERVED | ASPEED_SDMC_VGA_COMPAT |\
-- 
2.25.1




[PATCH v5 08/17] aspeed/smc: support 64 bits dma dram address

2024-06-03 Thread Jamin Lin via
AST2700 support the maximum dram size is 8GiB
and has a "DMA DRAM Side Address High Part(0x7C)"
register to support 64 bits dma dram address.
Add helper routines functions to compute the dma dram
address, new features and update trace-event
to support 64 bits dram address.

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 
Reviewed-by: Cédric Le Goater 
---
 hw/ssi/aspeed_smc.c | 51 ++---
 hw/ssi/trace-events |  2 +-
 2 files changed, 44 insertions(+), 9 deletions(-)

diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
index 0b8488a113..df0c63469c 100644
--- a/hw/ssi/aspeed_smc.c
+++ b/hw/ssi/aspeed_smc.c
@@ -132,6 +132,9 @@
 #define   FMC_WDT2_CTRL_BOOT_SOURCE  BIT(4) /* O: primary 1: alternate */
 #define   FMC_WDT2_CTRL_EN   BIT(0)
 
+/* DMA DRAM Side Address High Part (AST2700) */
+#define R_DMA_DRAM_ADDR_HIGH   (0x7c / 4)
+
 /* DMA Control/Status Register */
 #define R_DMA_CTRL(0x80 / 4)
 #define   DMA_CTRL_REQUEST  (1 << 31)
@@ -187,6 +190,7 @@
  *   0x1FF: 32M bytes
  */
 #define DMA_DRAM_ADDR(asc, val)   ((val) & (asc)->dma_dram_mask)
+#define DMA_DRAM_ADDR_HIGH(val)   ((val) & 0xf)
 #define DMA_FLASH_ADDR(asc, val)  ((val) & (asc)->dma_flash_mask)
 #define DMA_LENGTH(val) ((val) & 0x01FF)
 
@@ -207,6 +211,7 @@ static const AspeedSegments aspeed_2500_spi2_segments[];
 #define ASPEED_SMC_FEATURE_DMA   0x1
 #define ASPEED_SMC_FEATURE_DMA_GRANT 0x2
 #define ASPEED_SMC_FEATURE_WDT_CONTROL 0x4
+#define ASPEED_SMC_FEATURE_DMA_DRAM_ADDR_HIGH 0x08
 
 static inline bool aspeed_smc_has_dma(const AspeedSMCClass *asc)
 {
@@ -218,6 +223,11 @@ static inline bool aspeed_smc_has_wdt_control(const 
AspeedSMCClass *asc)
 return !!(asc->features & ASPEED_SMC_FEATURE_WDT_CONTROL);
 }
 
+static inline bool aspeed_smc_has_dma64(const AspeedSMCClass *asc)
+{
+return !!(asc->features & ASPEED_SMC_FEATURE_DMA_DRAM_ADDR_HIGH);
+}
+
 #define aspeed_smc_error(fmt, ...)  \
 qemu_log_mask(LOG_GUEST_ERROR, "%s: " fmt "\n", __func__, ## __VA_ARGS__)
 
@@ -747,6 +757,8 @@ static uint64_t aspeed_smc_read(void *opaque, hwaddr addr, 
unsigned int size)
 (aspeed_smc_has_dma(asc) && addr == R_DMA_CTRL) ||
 (aspeed_smc_has_dma(asc) && addr == R_DMA_FLASH_ADDR) ||
 (aspeed_smc_has_dma(asc) && addr == R_DMA_DRAM_ADDR) ||
+(aspeed_smc_has_dma(asc) && aspeed_smc_has_dma64(asc) &&
+ addr == R_DMA_DRAM_ADDR_HIGH) ||
 (aspeed_smc_has_dma(asc) && addr == R_DMA_LEN) ||
 (aspeed_smc_has_dma(asc) && addr == R_DMA_CHECKSUM) ||
 (addr >= R_SEG_ADDR0 &&
@@ -847,6 +859,12 @@ static bool aspeed_smc_inject_read_failure(AspeedSMCState 
*s)
 }
 }
 
+static uint64_t aspeed_smc_dma_dram_addr(AspeedSMCState *s)
+{
+return s->regs[R_DMA_DRAM_ADDR] |
+((uint64_t) s->regs[R_DMA_DRAM_ADDR_HIGH] << 32);
+}
+
 static uint32_t aspeed_smc_dma_len(AspeedSMCState *s)
 {
 AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s);
@@ -903,24 +921,34 @@ static void aspeed_smc_dma_checksum(AspeedSMCState *s)
 
 static void aspeed_smc_dma_rw(AspeedSMCState *s)
 {
+AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s);
+uint64_t dma_dram_offset;
+uint64_t dma_dram_addr;
 MemTxResult result;
 uint32_t dma_len;
 uint32_t data;
 
 dma_len = aspeed_smc_dma_len(s);
+dma_dram_addr = aspeed_smc_dma_dram_addr(s);
+
+if (aspeed_smc_has_dma64(asc)) {
+dma_dram_offset = dma_dram_addr - s->dram_base;
+} else {
+dma_dram_offset = dma_dram_addr;
+}
 
 trace_aspeed_smc_dma_rw(s->regs[R_DMA_CTRL] & DMA_CTRL_WRITE ?
 "write" : "read",
 s->regs[R_DMA_FLASH_ADDR],
-s->regs[R_DMA_DRAM_ADDR],
+dma_dram_offset,
 dma_len);
 while (dma_len) {
 if (s->regs[R_DMA_CTRL] & DMA_CTRL_WRITE) {
-data = address_space_ldl_le(>dram_as, s->regs[R_DMA_DRAM_ADDR],
+data = address_space_ldl_le(>dram_as, dma_dram_offset,
 MEMTXATTRS_UNSPECIFIED, );
 if (result != MEMTX_OK) {
-aspeed_smc_error("DRAM read failed @%08x",
- s->regs[R_DMA_DRAM_ADDR]);
+aspeed_smc_error("DRAM read failed @%" PRIx64,
+ dma_dram_offset);
 return;
 }
 
@@ -940,11 +968,11 @@ static void aspeed_smc_dma_rw(AspeedSMCState *s)
 return;
 }
 
-address_space_stl_le(>dram_as, s->regs[R_DMA_DRAM_ADDR],
+address_space_stl_le(>dram_as, dma_dr

[PATCH v5 16/17] test/avocado/machine_aspeed.py: Add AST2700 test case

2024-06-03 Thread Jamin Lin via
Add a test case to test Aspeed OpenBMC SDK v09.01 on AST2700 board.

It loads u-boot-nodtb.bin, u-boot.dtb, tfa and optee-os
images to dram first which base address is 0x4.
Then, boot and launch 4 cpu cores.

```
qemu-system-aarch64 -machine ast2700-evb
-device loader,force-raw=on,addr=0x4,file=workdir/u-boot-nodtb.bin \
-device 
loader,force-raw=on,addr=uboot_dtb_load_addr,file=workdir/u-boot.dtb\
-device loader,force-raw=on,addr=0x43000,file=workdir/bl31.bin\
-device loader,force-raw=on,addr=0x43008,file=workdir/optee/tee-raw.bin\
-device loader,cpu-num=0,addr=0x43000 \
-device loader,cpu-num=1,addr=0x43000 \
-device loader,cpu-num=2,addr=0x43000 \
-device loader,cpu-num=3,addr=0x43000 \
-smp 4 \
-drive file=workdir/image-bmc,format=raw,if=mtd
```

A test image is downloaded from the ASPEED Forked OpenBMC GitHub release 
repository :
https://github.com/AspeedTech-BMC/openbmc/releases/

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 
Reviewed-by: Cédric Le Goater 
---
 tests/avocado/machine_aspeed.py | 62 +
 1 file changed, 62 insertions(+)

diff --git a/tests/avocado/machine_aspeed.py b/tests/avocado/machine_aspeed.py
index cec0181424..3a20644fb2 100644
--- a/tests/avocado/machine_aspeed.py
+++ b/tests/avocado/machine_aspeed.py
@@ -311,6 +311,17 @@ def do_test_arm_aspeed_sdk_start(self, image):
 self, 'boot', '## Loading kernel from FIT Image')
 self.wait_for_console_pattern('Starting kernel ...')
 
+def do_test_aarch64_aspeed_sdk_start(self, image):
+self.vm.set_console()
+self.vm.add_args('-drive', 'file=' + image + ',if=mtd,format=raw')
+
+self.vm.launch()
+
+self.wait_for_console_pattern('U-Boot 2023.10')
+self.wait_for_console_pattern('## Loading kernel from FIT Image')
+self.wait_for_console_pattern('Starting kernel ...')
+self.wait_for_console_pattern("systemd[1]: Hostname set to")
+
 @skipUnless(os.getenv('QEMU_TEST_FLAKY_TESTS'), 'Test is unstable on 
GitLab')
 
 def test_arm_ast2500_evb_sdk(self):
@@ -375,3 +386,54 @@ def test_arm_ast2600_evb_sdk(self):
  'i2c i2c-5: new_device: Instantiated device ds1307 at 0x32');
 year = time.strftime("%Y")
 self.ssh_command_output_contains('/sbin/hwclock -f /dev/rtc1', year);
+
+def test_aarch64_ast2700_evb_sdk_v09_01(self):
+"""
+:avocado: tags=arch:aarch64
+:avocado: tags=machine:ast2700-evb
+"""
+
+image_url = ('https://github.com/AspeedTech-BMC/openbmc/releases/'
+ 'download/v09.01/ast2700-default-obmc.tar.gz')
+image_hash = 
'b1cc0fd73c7650d34c9c8459a243f52a91e9e27144b8608b2645ab19461d1e07'
+image_path = self.fetch_asset(image_url, asset_hash=image_hash,
+  algorithm='sha256')
+archive.extract(image_path, self.workdir)
+
+num_cpu = 4
+image_dir = self.workdir + '/ast2700-default/'
+uboot_size = os.path.getsize(image_dir + 'u-boot-nodtb.bin')
+uboot_dtb_load_addr = hex(0x4 + uboot_size)
+
+load_images_list = [
+{
+'addr': '0x4',
+'file': image_dir + 'u-boot-nodtb.bin'
+},
+{
+'addr': str(uboot_dtb_load_addr),
+'file': image_dir + 'u-boot.dtb'
+},
+{
+'addr': '0x43000',
+'file': image_dir + 'bl31.bin'
+},
+{
+'addr': '0x43008',
+'file': image_dir + 'optee/tee-raw.bin'
+}
+]
+
+for load_image in load_images_list:
+addr = load_image['addr']
+file = load_image['file']
+self.vm.add_args('-device',
+ f'loader,force-raw=on,addr={addr},file={file}')
+
+for i in range(num_cpu):
+self.vm.add_args('-device',
+ f'loader,addr=0x43000,cpu-num={i}')
+
+self.vm.add_args('-smp', str(num_cpu))
+self.do_test_aarch64_aspeed_sdk_start(image_dir + 'image-bmc')
+
-- 
2.25.1




[PATCH v5 04/17] aspeed/sdmc: fix coding style

2024-06-03 Thread Jamin Lin via
Fix coding style issues from checkpatch.pl

Test command:
scripts/checkpatch.pl --no-tree -f hw/misc/aspeed_sdmc.c

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 
Reviewed-by: Cédric Le Goater 
---
 hw/misc/aspeed_sdmc.c | 11 +++
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/hw/misc/aspeed_sdmc.c b/hw/misc/aspeed_sdmc.c
index 74279bbe8e..873d67c592 100644
--- a/hw/misc/aspeed_sdmc.c
+++ b/hw/misc/aspeed_sdmc.c
@@ -296,7 +296,8 @@ static void aspeed_2400_sdmc_write(AspeedSDMCState *s, 
uint32_t reg,
uint32_t data)
 {
 if (reg == R_PROT) {
-s->regs[reg] = (data == PROT_KEY_UNLOCK) ? PROT_UNLOCKED : 
PROT_SOFTLOCKED;
+s->regs[reg] =
+(data == PROT_KEY_UNLOCK) ? PROT_UNLOCKED : PROT_SOFTLOCKED;
 return;
 }
 
@@ -354,7 +355,8 @@ static void aspeed_2500_sdmc_write(AspeedSDMCState *s, 
uint32_t reg,
uint32_t data)
 {
 if (reg == R_PROT) {
-s->regs[reg] = (data == PROT_KEY_UNLOCK) ? PROT_UNLOCKED : 
PROT_SOFTLOCKED;
+s->regs[reg] =
+(data == PROT_KEY_UNLOCK) ? PROT_UNLOCKED : PROT_SOFTLOCKED;
 return;
 }
 
@@ -434,8 +436,9 @@ static void aspeed_2600_sdmc_write(AspeedSDMCState *s, 
uint32_t reg,
 }
 
 if (s->regs[R_PROT] == PROT_HARDLOCKED) {
-qemu_log_mask(LOG_GUEST_ERROR, "%s: SDMC is locked until system 
reset!\n",
-__func__);
+qemu_log_mask(LOG_GUEST_ERROR,
+  "%s: SDMC is locked until system reset!\n",
+  __func__);
 return;
 }
 
-- 
2.25.1




[PATCH v5 07/17] aspeed/smc: support dma start length and 1 byte length unit

2024-06-03 Thread Jamin Lin via
DMA length is from 1 byte to 32MB for AST2600 and AST10x0
and DMA length is from 4 bytes to 32MB for AST2500.

In other words, if "R_DMA_LEN" is 0, it should move at least 1 byte
data for AST2600 and AST10x0 and 4 bytes data for AST2500.
To support all ASPEED SOCs, adds dma_start_length parameter to store
the start length, add helper routines function to compute the dma length
and update DMA_LENGTH mask to "1FF" to support dma 1 byte
length unit for AST2600 and AST1030.
Currently, only supports dma length 4 bytes aligned.

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 
Reviewed-by: Cédric Le Goater 
---
 hw/ssi/aspeed_smc.c | 43 ++---
 include/hw/ssi/aspeed_smc.h |  1 +
 2 files changed, 36 insertions(+), 8 deletions(-)

diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
index fe1cd96b80..0b8488a113 100644
--- a/hw/ssi/aspeed_smc.c
+++ b/hw/ssi/aspeed_smc.c
@@ -178,13 +178,17 @@
  * DMA flash addresses should be 4 bytes aligned and the valid address
  * range is 0x2000 - 0x2FFF.
  *
- * DMA length is from 4 bytes to 32MB
+ * DMA length is from 4 bytes to 32MB (AST2500)
  *   0: 4 bytes
- *   0x7F: 32M bytes
+ *   0x1FC: 32M bytes
+ *
+ * DMA length is from 1 byte to 32MB (AST2600, AST10x0)
+ *   0: 1 byte
+ *   0x1FF: 32M bytes
  */
 #define DMA_DRAM_ADDR(asc, val)   ((val) & (asc)->dma_dram_mask)
 #define DMA_FLASH_ADDR(asc, val)  ((val) & (asc)->dma_flash_mask)
-#define DMA_LENGTH(val) ((val) & 0x01FC)
+#define DMA_LENGTH(val) ((val) & 0x01FF)
 
 /* Flash opcodes. */
 #define SPI_OP_READ   0x03/* Read data bytes (low frequency) */
@@ -843,6 +847,13 @@ static bool aspeed_smc_inject_read_failure(AspeedSMCState 
*s)
 }
 }
 
+static uint32_t aspeed_smc_dma_len(AspeedSMCState *s)
+{
+AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s);
+
+return QEMU_ALIGN_UP(s->regs[R_DMA_LEN] + asc->dma_start_length, 4);
+}
+
 /*
  * Accumulate the result of the reads to provide a checksum that will
  * be used to validate the read timing settings.
@@ -850,6 +861,7 @@ static bool aspeed_smc_inject_read_failure(AspeedSMCState 
*s)
 static void aspeed_smc_dma_checksum(AspeedSMCState *s)
 {
 MemTxResult result;
+uint32_t dma_len;
 uint32_t data;
 
 if (s->regs[R_DMA_CTRL] & DMA_CTRL_WRITE) {
@@ -861,7 +873,9 @@ static void aspeed_smc_dma_checksum(AspeedSMCState *s)
 aspeed_smc_dma_calibration(s);
 }
 
-while (s->regs[R_DMA_LEN]) {
+dma_len = aspeed_smc_dma_len(s);
+
+while (dma_len) {
 data = address_space_ldl_le(>flash_as, s->regs[R_DMA_FLASH_ADDR],
 MEMTXATTRS_UNSPECIFIED, );
 if (result != MEMTX_OK) {
@@ -877,7 +891,8 @@ static void aspeed_smc_dma_checksum(AspeedSMCState *s)
  */
 s->regs[R_DMA_CHECKSUM] += data;
 s->regs[R_DMA_FLASH_ADDR] += 4;
-s->regs[R_DMA_LEN] -= 4;
+dma_len -= 4;
+s->regs[R_DMA_LEN] = dma_len;
 }
 
 if (s->inject_failure && aspeed_smc_inject_read_failure(s)) {
@@ -889,14 +904,17 @@ static void aspeed_smc_dma_checksum(AspeedSMCState *s)
 static void aspeed_smc_dma_rw(AspeedSMCState *s)
 {
 MemTxResult result;
+uint32_t dma_len;
 uint32_t data;
 
+dma_len = aspeed_smc_dma_len(s);
+
 trace_aspeed_smc_dma_rw(s->regs[R_DMA_CTRL] & DMA_CTRL_WRITE ?
 "write" : "read",
 s->regs[R_DMA_FLASH_ADDR],
 s->regs[R_DMA_DRAM_ADDR],
-s->regs[R_DMA_LEN]);
-while (s->regs[R_DMA_LEN]) {
+dma_len);
+while (dma_len) {
 if (s->regs[R_DMA_CTRL] & DMA_CTRL_WRITE) {
 data = address_space_ldl_le(>dram_as, s->regs[R_DMA_DRAM_ADDR],
 MEMTXATTRS_UNSPECIFIED, );
@@ -937,7 +955,8 @@ static void aspeed_smc_dma_rw(AspeedSMCState *s)
  */
 s->regs[R_DMA_FLASH_ADDR] += 4;
 s->regs[R_DMA_DRAM_ADDR] += 4;
-s->regs[R_DMA_LEN] -= 4;
+dma_len -= 4;
+s->regs[R_DMA_LEN] = dma_len;
 s->regs[R_DMA_CHECKSUM] += data;
 }
 }
@@ -1382,6 +1401,7 @@ static void aspeed_2400_fmc_class_init(ObjectClass 
*klass, void *data)
 asc->features  = ASPEED_SMC_FEATURE_DMA;
 asc->dma_flash_mask= 0x0FFC;
 asc->dma_dram_mask = 0x1FFC;
+asc->dma_start_length  = 4;
 asc->nregs = ASPEED_SMC_R_MAX;
 asc->segment_to_reg= aspeed_smc_segment_to_reg;
 asc->reg_to_segment= aspeed_smc_reg_to_segment;
@@ -1465,6 +1485,7 @@ static void aspeed_2500_fmc_class_init(ObjectClass 
*klass, void *data)
 asc->features  = ASPEED_SMC_FEATURE_DMA;
 asc->dma_flash_mask= 0x0FF

[PATCH v5 05/17] aspeed/sdmc: Add AST2700 support

2024-06-03 Thread Jamin Lin via
The SDRAM memory controller(DRAMC) controls the access to external
DDR4 and DDR5 SDRAM and power up to DDR4 and DDR5 PHY.

The DRAM memory controller of AST2700 is not backward compatible
to previous chips such AST2600, AST2500 and AST2400.

Max memory is now 8GiB on the AST2700. Introduce new
aspeed_2700_sdmc and class with read/write operation and
reset handlers.

Define DRAMC necessary protected registers and
unprotected registers for AST2700 and increase
the register set to 0x1000.

Add unlocked property to change controller protected status.

Incrementing the version of vmstate to 2.

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 
---
 hw/misc/aspeed_sdmc.c | 194 +-
 include/hw/misc/aspeed_sdmc.h |   5 +-
 2 files changed, 195 insertions(+), 4 deletions(-)

diff --git a/hw/misc/aspeed_sdmc.c b/hw/misc/aspeed_sdmc.c
index 873d67c592..93e2e29ead 100644
--- a/hw/misc/aspeed_sdmc.c
+++ b/hw/misc/aspeed_sdmc.c
@@ -27,6 +27,7 @@
 #define   PROT_SOFTLOCKED0x00
 
 #define   PROT_KEY_UNLOCK 0xFC600309
+#define   PROT_2700_KEY_UNLOCK  0x1688A8A8
 #define   PROT_KEY_HARDLOCK   0xDEADDEAD /* AST2600 */
 
 /* Configuration Register */
@@ -54,6 +55,46 @@
 #define R_DRAM_TIME   (0x8c / 4)
 #define R_ECC_ERR_INJECT  (0xb4 / 4)
 
+/* AST2700 Register */
+#define R_2700_PROT (0x00 / 4)
+#define R_INT_STATUS(0x04 / 4)
+#define R_INT_CLEAR (0x08 / 4)
+#define R_INT_MASK  (0x0c / 4)
+#define R_MAIN_CONF (0x10 / 4)
+#define R_MAIN_CONTROL  (0x14 / 4)
+#define R_MAIN_STATUS   (0x18 / 4)
+#define R_ERR_STATUS(0x1c / 4)
+#define R_ECC_FAIL_STATUS   (0x78 / 4)
+#define R_ECC_FAIL_ADDR (0x7c / 4)
+#define R_ECC_TESTING_CONTROL   (0x80 / 4)
+#define R_PROT_REGION_LOCK_STATUS   (0x94 / 4)
+#define R_TEST_FAIL_ADDR(0xd4 / 4)
+#define R_TEST_FAIL_D0  (0xd8 / 4)
+#define R_TEST_FAIL_D1  (0xdc / 4)
+#define R_TEST_FAIL_D2  (0xe0 / 4)
+#define R_TEST_FAIL_D3  (0xe4 / 4)
+#define R_DBG_STATUS(0xf4 / 4)
+#define R_PHY_INTERFACE_STATUS  (0xf8 / 4)
+#define R_GRAPHIC_MEM_BASE_ADDR (0x10c / 4)
+#define R_PORT0_INTERFACE_MONITOR0  (0x240 / 4)
+#define R_PORT0_INTERFACE_MONITOR1  (0x244 / 4)
+#define R_PORT0_INTERFACE_MONITOR2  (0x248 / 4)
+#define R_PORT1_INTERFACE_MONITOR0  (0x2c0 / 4)
+#define R_PORT1_INTERFACE_MONITOR1  (0x2c4 / 4)
+#define R_PORT1_INTERFACE_MONITOR2  (0x2c8 / 4)
+#define R_PORT2_INTERFACE_MONITOR0  (0x340 / 4)
+#define R_PORT2_INTERFACE_MONITOR1  (0x344 / 4)
+#define R_PORT2_INTERFACE_MONITOR2  (0x348 / 4)
+#define R_PORT3_INTERFACE_MONITOR0  (0x3c0 / 4)
+#define R_PORT3_INTERFACE_MONITOR1  (0x3c4 / 4)
+#define R_PORT3_INTERFACE_MONITOR2  (0x3c8 / 4)
+#define R_PORT4_INTERFACE_MONITOR0  (0x440 / 4)
+#define R_PORT4_INTERFACE_MONITOR1  (0x444 / 4)
+#define R_PORT4_INTERFACE_MONITOR2  (0x448 / 4)
+#define R_PORT5_INTERFACE_MONITOR0  (0x4c0 / 4)
+#define R_PORT5_INTERFACE_MONITOR1  (0x4c4 / 4)
+#define R_PORT5_INTERFACE_MONITOR2  (0x4c8 / 4)
+
 /*
  * Configuration register Ox4 (for Aspeed AST2400 SOC)
  *
@@ -101,6 +142,19 @@
  ASPEED_SDMC_AST2500_RESERVED | ASPEED_SDMC_VGA_COMPAT |\
  ASPEED_SDMC_VGA_APERTURE(ASPEED_SDMC_VGA_64MB))
 
+/*
+ * Main Configuration register Ox10 (for Aspeed AST2700 SOC and higher)
+ *
+ */
+#define ASPEED_SDMC_AST2700_RESERVED0x2082 /* 31:16, 13, 7, 1 */
+#define ASPEED_SDMC_AST2700_DATA_SCRAMBLE   (1 << 8)
+#define ASPEED_SDMC_AST2700_ECC_ENABLE  (1 << 6)
+#define ASPEED_SDMC_AST2700_PAGE_MATCHING_ENABLE(1 << 5)
+#define ASPEED_SDMC_AST2700_DRAM_SIZE(x)((x & 0x7) << 2)
+
+#define ASPEED_SDMC_AST2700_READONLY_MASK   \
+ (ASPEED_SDMC_AST2700_RESERVED)
+
 static uint64_t aspeed_sdmc_read(void *opaque, hwaddr addr, unsigned size)
 {
 AspeedSDMCState *s = ASPEED_SDMC(opaque);
@@ -216,7 +270,7 @@ static void aspeed_sdmc_realize(DeviceState *dev, Error 
**errp)
 AspeedSDMCState *s = ASPEED_SDMC(dev);
 AspeedSDMCClass *asc = ASPEED_SDMC_GET_CLASS(s);
 
-assert(asc->max_ram_size < 4 * GiB); /* 32-bit address bus */
+assert(asc->max_ram_size < 4 * GiB || asc->is_bus64bit);
 s->max_ram_size = asc->max_ram_size;
 
 memory_region_init_io(>iomem, OBJECT(s), _sdmc_ops, s,
@@ -226,8 +280,8 @@ static void aspeed_sdmc_realize(DeviceState *dev, Error 
**errp)
 
 static const VMStateDescription vmstate_aspeed_sdmc = {
 .name = "aspeed.sdmc",
-.version_id = 1,
-.minimum_version_id = 1,
+.version_id = 2,
+.minimum_version_id = 2,
 .fields = (const VMStateField[]) {
 VMSTATE_UINT32_ARRAY(regs, AspeedSDMCState, ASPEED_SDMC_NR_REGS),
 VMSTATE_END_OF_LIST()
@@ -236,6 +290,7 @@ static const VMStateDescription vms

[PATCH v5 17/17] docs:aspeed: Add AST2700 Evaluation board

2024-06-03 Thread Jamin Lin via
Add AST2700 Evaluation board and its boot command.

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 
Reviewed-by: Cédric Le Goater 
---
 docs/system/arm/aspeed.rst | 39 ++
 1 file changed, 35 insertions(+), 4 deletions(-)

diff --git a/docs/system/arm/aspeed.rst b/docs/system/arm/aspeed.rst
index b2dea54eed..cd9559e3e2 100644
--- a/docs/system/arm/aspeed.rst
+++ b/docs/system/arm/aspeed.rst
@@ -1,11 +1,12 @@
-Aspeed family boards (``*-bmc``, ``ast2500-evb``, ``ast2600-evb``)
-==
+Aspeed family boards (``*-bmc``, ``ast2500-evb``, ``ast2600-evb``, 
``ast2700-evb``)
+===
 
 The QEMU Aspeed machines model BMCs of various OpenPOWER systems and
 Aspeed evaluation boards. They are based on different releases of the
 Aspeed SoC : the AST2400 integrating an ARM926EJ-S CPU (400MHz), the
-AST2500 with an ARM1176JZS CPU (800MHz) and more recently the AST2600
-with dual cores ARM Cortex-A7 CPUs (1.2GHz).
+AST2500 with an ARM1176JZS CPU (800MHz), the AST2600
+with dual cores ARM Cortex-A7 CPUs (1.2GHz) and more recently the AST2700
+with quad cores ARM Cortex-A35 64 bits CPUs (1.6GHz)
 
 The SoC comes with RAM, Gigabit ethernet, USB, SD/MMC, USB, SPI, I2C,
 etc.
@@ -38,6 +39,10 @@ AST2600 SoC based machines :
 - ``qcom-dc-scm-v1-bmc``   Qualcomm DC-SCM V1 BMC
 - ``qcom-firework-bmc``Qualcomm Firework BMC
 
+AST2700 SoC based machines :
+
+- ``ast2700-evb``  Aspeed AST2700 Evaluation board (Cortex-A35)
+
 Supported devices
 -
 
@@ -66,6 +71,7 @@ Supported devices
  * eMMC Boot Controller (dummy)
  * PECI Controller (minimal)
  * I3C Controller
+ * Internal Bridge Controller (SLI dummy)
 
 
 Missing devices
@@ -95,6 +101,10 @@ or directly from the OpenBMC GitHub release repository :
 
https://github.com/openbmc/openbmc/releases
 
+or directly from the ASPEED Forked OpenBMC GitHub release repository :
+
+   https://github.com/AspeedTech-BMC/openbmc/releases
+
 To boot a kernel directly from a Linux build tree:
 
 .. code-block:: bash
@@ -164,6 +174,27 @@ under Linux), use :
 
   -M ast2500-evb,bmc-console=uart3
 
+
+Boot the AST2700 machine from the flash image, use an MTD drive :
+
+.. code-block:: bash
+
+  IMGDIR=ast2700-default
+  UBOOT_SIZE=$(stat --format=%s -L ${IMGDIR}/u-boot-nodtb.bin)
+
+  $ qemu-system-aarch64 -M ast2700-evb \
+   -device 
loader,force-raw=on,addr=0x4,file=${IMGDIR}/u-boot-nodtb.bin \
+   -device loader,force-raw=on,addr=$((0x4 + 
${UBOOT_SIZE})),file=${IMGDIR}/u-boot.dtb \
+   -device loader,force-raw=on,addr=0x43000,file=${IMGDIR}/bl31.bin \
+   -device 
loader,force-raw=on,addr=0x43008,file=${IMGDIR}/optee/tee-raw.bin \
+   -device loader,cpu-num=0,addr=0x43000 \
+   -device loader,cpu-num=1,addr=0x43000 \
+   -device loader,cpu-num=2,addr=0x43000 \
+   -device loader,cpu-num=3,addr=0x43000 \
+   -smp 4 \
+   -drive file=${IMGDIR}/image-bmc,format=raw,if=mtd \
+   -nographic
+
 Aspeed minibmc family boards (``ast1030-evb``)
 ==
 
-- 
2.25.1




[PATCH v5 12/17] aspeed/intc: Add AST2700 support

2024-06-03 Thread Jamin Lin via
AST2700 interrupt controller(INTC) provides hardware interrupt interfaces
to interrupt of processors PSP, SSP and TSP. In INTC, each interrupt of
INT 128 to INT136 combines 32 interrupts.

Introduce a new aspeed_intc class with instance_init and realize handlers.

So far, this model only supports GICINT128 to GICINT136.
It creates 9 GICINT or-gates to connect 32 interrupts sources
from GICINT128 to GICINT136 as IRQ GPIO-OUTPUT pins.
Then, this model registers IRQ handler with its IRQ GPIO-INPUT pins which
connect to GICINT or-gates. And creates 9 GICINT IRQ GPIO-OUTPUT pins which
connect to GIC device with GIC IRQ 128 to 136.

If one interrupt source from GICINT128 to GICINT136
set irq, the OR-GATE irq callback function is called and set irq to INTC by
OR-GATE GPIO-OUTPUT pins. Then, the INTC irq callback function is called and
set irq to GIC by its GICINT IRQ GPIO-OUTPUT pins. Finally, the GIC irq
callback function is called and set irq to CPUs and
CPUs execute Interrupt Service Routine (ISR).

Block diagram of GICINT132:

GICINT132
  ETH1+---+
+>+0 3|
  ETH2|  4|
+>+1 5|
  ETH3|  6|
+>+219|  INTC  
GIC
  UART0   | 20|+--+
+>+721||  |
+--+
  UART1   | 22||orgate0 +> 
output_pin0+--->+GIC128|
+>+823||  ||
  |
  UART2   | 24||orgate1 +> 
output_pin1+--->+GIC129|
+>+925||  ||
  |
  UART3   | 26||orgate2 +> 
output_pin2+--->+GIC130|
+->10   27||  ||
  |
  UART5   | 28||orgate3 +> 
output_pin3+--->+GIC131|
+>+11   29||  ||
  |
  UART6   |   +--->+orgate4 +> 
output_pin4+--->+GIC132|
+>+12   30||  ||
  |
  UART7   | 31||orgate5 +> 
output_pin5+--->+GIC133|
+>+13 ||  ||
  |
  UART8   |  OR[0:31] ||orgate6 +> 
output_pin6+--->+GIC134|
-->14 ||  ||
  |
  UART9   |   ||orgate7 +> 
output_pin7+--->+GIC135|
->+15 ||  ||
  |
  UART10  |   ||orgate8 +> 
output_pin8+--->+GIC136|
->+16 ||  |
+--+
  UART11  |   |+--+
+>+17 |
  UART12  |   |
+->18 |
  |   |
  |       |
  |   |
  +---+

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 
---
 hw/intc/aspeed_intc.c | 360 ++
 hw/intc/meson.build   |   1 +
 hw/intc/trace-events  |  13 ++
 include/hw/intc/aspeed_intc.h |  44 +
 4 files changed, 418 insertions(+)
 create mode 100644 hw/intc/aspeed_intc.c
 create mode 100644 include/hw/intc/aspeed_intc.h

diff --git a/hw/intc/aspeed_intc.c b/hw/intc/aspeed_intc.c
new file mode 100644
index 00..e232361791
--- /dev/null
+++ b/hw/intc/aspeed_intc.c
@@ -0,0 +1,360 @@
+/*
+ * ASPEED INTC Controller
+ *
+ * Copyright (C) 2024 ASPEED Technology Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "hw/intc/aspeed_intc.h"
+#include "hw/irq.h"
+#include "qemu/log.h"
+#include "trace.h"
+#include "hw/registerfields.h"
+#include "qapi/error.h"
+
+/* INTC Registers */
+REG32(GICINT128_EN, 0x1000)
+REG32(GICINT128_STATUS, 0x1004)
+REG32(GICINT129_EN, 0x1100)
+REG32(GICINT129_STATUS, 0x1104)
+REG32(GICINT130_EN, 0x1200)
+REG32(GICINT130_STATUS, 0x1204)
+REG32(GICINT131_EN, 0x1300)
+REG32(GICINT131_STATUS, 0x1304)
+REG32(GICINT132_EN, 0x1400)
+REG32(GICINT132_STATUS, 0x1404)
+REG32(GICINT133_EN, 0x1500)
+REG32(GICINT133_STATUS, 0x1504)
+REG32(GICINT134_EN, 0x1600)
+REG32(GICINT134_STATUS, 0x1604)
+REG32(GICINT135_EN, 0x1700)
+REG32(GICINT135_STATUS, 0x1704)
+REG32(GICIN

[PATCH v5 13/17] aspeed/soc: Add AST2700 support

2024-06-03 Thread Jamin Lin via
Initial definitions for a simple machine using an AST2700 SOC (Cortex-a35 CPU).

AST2700 SOC and its interrupt controller are too complex to handle
in the common Aspeed SoC framework. We introduce a new ast2700
class with instance_init and realize handlers.

AST2700 is a 64 bits quad core cpus and support 8 watchdog.
Update maximum ASPEED_CPUS_NUM to 4 and ASPEED_WDTS_NUM to 8.
In addition, update AspeedSocState to support scuio, sli, sliio and intc.

Add TYPE_ASPEED27X0_SOC machine type.

The SDMC controller is unlocked at SPL stage.
At present, only supports to emulate booting
start from u-boot stage. Set SDMC controller
unlocked by default.

In INTC, each interrupt of INT 128 to INT 136 combines 32 interrupts.
It connect GICINT IRQ GPIO-OUTPUT pins to GIC device with irq 128 to 136.
And, if a device irq is 128 to 136, its irq GPIO-OUTPUT pin is connected to
GICINT or-gates instead of GIC device.

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 
---
 hw/arm/aspeed_ast27x0.c | 563 
 hw/arm/meson.build  |   1 +
 include/hw/arm/aspeed_soc.h |  28 +-
 3 files changed, 590 insertions(+), 2 deletions(-)
 create mode 100644 hw/arm/aspeed_ast27x0.c

diff --git a/hw/arm/aspeed_ast27x0.c b/hw/arm/aspeed_ast27x0.c
new file mode 100644
index 00..29e75072c4
--- /dev/null
+++ b/hw/arm/aspeed_ast27x0.c
@@ -0,0 +1,563 @@
+/*
+ * ASPEED SoC 27x0 family
+ *
+ * Copyright (C) 2024 ASPEED Technology Inc.
+ *
+ * This code is licensed under the GPL version 2 or later.  See
+ * the COPYING file in the top-level directory.
+ *
+ * Implementation extracted from the AST2600 and adapted for AST27x0.
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "hw/misc/unimp.h"
+#include "hw/arm/aspeed_soc.h"
+#include "qemu/module.h"
+#include "qemu/error-report.h"
+#include "hw/i2c/aspeed_i2c.h"
+#include "net/net.h"
+#include "sysemu/sysemu.h"
+#include "hw/intc/arm_gicv3.h"
+#include "qapi/qmp/qlist.h"
+
+static const hwaddr aspeed_soc_ast2700_memmap[] = {
+[ASPEED_DEV_SPI_BOOT]  =  0x4,
+[ASPEED_DEV_SRAM]  =  0x1000,
+[ASPEED_DEV_SDMC]  =  0x12C0,
+[ASPEED_DEV_SCU]   =  0x12C02000,
+[ASPEED_DEV_SCUIO] =  0x14C02000,
+[ASPEED_DEV_UART0] =  0X14C33000,
+[ASPEED_DEV_UART1] =  0X14C33100,
+[ASPEED_DEV_UART2] =  0X14C33200,
+[ASPEED_DEV_UART3] =  0X14C33300,
+[ASPEED_DEV_UART4] =  0X12C1A000,
+[ASPEED_DEV_UART5] =  0X14C33400,
+[ASPEED_DEV_UART6] =  0X14C33500,
+[ASPEED_DEV_UART7] =  0X14C33600,
+[ASPEED_DEV_UART8] =  0X14C33700,
+[ASPEED_DEV_UART9] =  0X14C33800,
+[ASPEED_DEV_UART10]=  0X14C33900,
+[ASPEED_DEV_UART11]=  0X14C33A00,
+[ASPEED_DEV_UART12]=  0X14C33B00,
+[ASPEED_DEV_WDT]   =  0x14C37000,
+[ASPEED_DEV_VUART] =  0X14C3,
+[ASPEED_DEV_FMC]   =  0x1400,
+[ASPEED_DEV_SPI0]  =  0x1401,
+[ASPEED_DEV_SPI1]  =  0x1402,
+[ASPEED_DEV_SPI2]  =  0x1403,
+[ASPEED_DEV_SDRAM] =  0x4,
+[ASPEED_DEV_MII1]  =  0x1404,
+[ASPEED_DEV_MII2]  =  0x14040008,
+[ASPEED_DEV_MII3]  =  0x14040010,
+[ASPEED_DEV_ETH1]  =  0x1405,
+[ASPEED_DEV_ETH2]  =  0x1406,
+[ASPEED_DEV_ETH3]  =  0x1407,
+[ASPEED_DEV_EMMC]  =  0x1209,
+[ASPEED_DEV_INTC]  =  0x1210,
+[ASPEED_DEV_SLI]   =  0x12C17000,
+[ASPEED_DEV_SLIIO] =  0x14C1E000,
+[ASPEED_GIC_DIST]  =  0x1220,
+[ASPEED_GIC_REDIST]=  0x1228,
+};
+
+#define AST2700_MAX_IRQ 288
+
+/* Shared Peripheral Interrupt values below are offset by -32 from datasheet */
+static const int aspeed_soc_ast2700_irqmap[] = {
+[ASPEED_DEV_UART0] = 132,
+[ASPEED_DEV_UART1] = 132,
+[ASPEED_DEV_UART2] = 132,
+[ASPEED_DEV_UART3] = 132,
+[ASPEED_DEV_UART4] = 8,
+[ASPEED_DEV_UART5] = 132,
+[ASPEED_DEV_UART6] = 132,
+[ASPEED_DEV_UART7] = 132,
+[ASPEED_DEV_UART8] = 132,
+[ASPEED_DEV_UART9] = 132,
+[ASPEED_DEV_UART10]= 132,
+[ASPEED_DEV_UART11]= 132,
+[ASPEED_DEV_UART12]= 132,
+[ASPEED_DEV_FMC]   = 131,
+[ASPEED_DEV_SDMC]  = 0,
+[ASPEED_DEV_SCU]   = 12,
+[ASPEED_DEV_ADC]   = 130,
+[ASPEED_DEV_XDMA]  = 5,
+[ASPEED_DEV_EMMC]  = 15,
+[ASPEED_DEV_GPIO]  = 11,
+[ASPEED_DEV_GPIO_1_8V] = 130,
+[ASPEED_DEV_RTC]   = 13,
+[ASPEED_DEV_TIMER1]= 16,
+[ASPEED_DEV_TIMER2]= 17,
+[ASPEED_DEV_TIMER3]= 18,
+[ASPEED_DEV_TIMER4]= 19,
+[ASPEED_DEV_TIMER5]= 20,
+[ASPEED_DEV_TIMER6]= 21,
+[ASPEED_DEV_TIMER7]= 22,
+[ASPEED_DEV_TIMER8]= 23,
+[ASPEED_DEV_WDT]   = 131,
+[ASPEED_DE

[PATCH v5 06/17] aspeed/smc: correct device description

2024-06-03 Thread Jamin Lin via
Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 
Reviewed-by: Cédric Le Goater 
---
 hw/ssi/aspeed_smc.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
index 7075bc9d61..fe1cd96b80 100644
--- a/hw/ssi/aspeed_smc.c
+++ b/hw/ssi/aspeed_smc.c
@@ -1449,7 +1449,7 @@ static void aspeed_2500_fmc_class_init(ObjectClass 
*klass, void *data)
 DeviceClass *dc = DEVICE_CLASS(klass);
 AspeedSMCClass *asc = ASPEED_SMC_CLASS(klass);
 
-dc->desc   = "Aspeed 2600 FMC Controller";
+dc->desc   = "Aspeed 2500 FMC Controller";
 asc->r_conf= R_CONF;
 asc->r_ce_ctrl = R_CE_CTRL;
 asc->r_ctrl0   = R_CTRL0;
@@ -1487,7 +1487,7 @@ static void aspeed_2500_spi1_class_init(ObjectClass 
*klass, void *data)
 DeviceClass *dc = DEVICE_CLASS(klass);
 AspeedSMCClass *asc = ASPEED_SMC_CLASS(klass);
 
-dc->desc   = "Aspeed 2600 SPI1 Controller";
+dc->desc   = "Aspeed 2500 SPI1 Controller";
 asc->r_conf= R_CONF;
 asc->r_ce_ctrl = R_CE_CTRL;
 asc->r_ctrl0   = R_CTRL0;
@@ -1522,7 +1522,7 @@ static void aspeed_2500_spi2_class_init(ObjectClass 
*klass, void *data)
 DeviceClass *dc = DEVICE_CLASS(klass);
 AspeedSMCClass *asc = ASPEED_SMC_CLASS(klass);
 
-dc->desc   = "Aspeed 2600 SPI2 Controller";
+dc->desc   = "Aspeed 2500 SPI2 Controller";
 asc->r_conf= R_CONF;
 asc->r_ce_ctrl = R_CE_CTRL;
 asc->r_ctrl0   = R_CTRL0;
-- 
2.25.1




[PATCH v5 14/17] aspeed: Add an AST2700 eval board

2024-06-03 Thread Jamin Lin via
AST2700 CPU is ARM Cortex-A35 which is 64 bits.
Add TARGET_AARCH64 to build this machine.

According to the design of ast2700, it has a bootmcu(riscv-32) which
is used for executing SPL.
Then, CPUs(cortex-a35) execute u-boot, kernel and rofs.

Currently, qemu not support emulate two CPU architectures
at the same machine. Therefore, qemu will only support
to emulate CPU(cortex-a35) side for ast2700

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 
Reviewed-by: Cédric Le Goater 
---
 hw/arm/aspeed.c | 32 
 1 file changed, 32 insertions(+)

diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index 93ca87fda2..40dc0e4c76 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -178,6 +178,12 @@ struct AspeedMachineState {
 #define AST2600_EVB_HW_STRAP1 0x00C0
 #define AST2600_EVB_HW_STRAP2 0x0003
 
+#ifdef TARGET_AARCH64
+/* AST2700 evb hardware value */
+#define AST2700_EVB_HW_STRAP1 0x00C0
+#define AST2700_EVB_HW_STRAP2 0x0003
+#endif
+
 /* Tacoma hardware value */
 #define TACOMA_BMC_HW_STRAP1  0x
 #define TACOMA_BMC_HW_STRAP2  0x0040
@@ -1588,6 +1594,26 @@ static void 
aspeed_minibmc_machine_ast1030_evb_class_init(ObjectClass *oc,
 aspeed_machine_class_init_cpus_defaults(mc);
 }
 
+#ifdef TARGET_AARCH64
+static void aspeed_machine_ast2700_evb_class_init(ObjectClass *oc, void *data)
+{
+MachineClass *mc = MACHINE_CLASS(oc);
+AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
+
+mc->desc = "Aspeed AST2700 EVB (Cortex-A35)";
+amc->soc_name  = "ast2700-a0";
+amc->hw_strap1 = AST2700_EVB_HW_STRAP1;
+amc->hw_strap2 = AST2700_EVB_HW_STRAP2;
+amc->fmc_model = "w25q01jvq";
+amc->spi_model = "w25q512jv";
+amc->num_cs= 2;
+amc->macs_mask = ASPEED_MAC0_ON | ASPEED_MAC1_ON | ASPEED_MAC2_ON;
+amc->uart_default = ASPEED_DEV_UART12;
+mc->default_ram_size = 1 * GiB;
+aspeed_machine_class_init_cpus_defaults(mc);
+}
+#endif
+
 static void aspeed_machine_qcom_dc_scm_v1_class_init(ObjectClass *oc,
  void *data)
 {
@@ -1711,6 +1737,12 @@ static const TypeInfo aspeed_machine_types[] = {
 .name   = MACHINE_TYPE_NAME("ast1030-evb"),
 .parent = TYPE_ASPEED_MACHINE,
 .class_init = aspeed_minibmc_machine_ast1030_evb_class_init,
+#ifdef TARGET_AARCH64
+}, {
+.name  = MACHINE_TYPE_NAME("ast2700-evb"),
+.parent= TYPE_ASPEED_MACHINE,
+.class_init= aspeed_machine_ast2700_evb_class_init,
+#endif
 }, {
 .name  = TYPE_ASPEED_MACHINE,
 .parent= TYPE_MACHINE,
-- 
2.25.1




[PATCH v5 15/17] aspeed/soc: fix incorrect dram size for AST2700

2024-06-03 Thread Jamin Lin via
AST2700 dram size calculation is not back compatible AST2600.
According to the DDR capacity hardware behavior,
if users write the data to the address which is beyond the ram size,
it would write the data to the "address % ram_size".
For example:
a. sdram base address "0x4 "
b. sdram size 1 GiB
The available address range is from "0x4 " to "0x4 3FFF".
If users write 0x12345678 to address "0x5 ",
the value of DRAM address 0 (base address 0x4 ) will be 0x12345678.

Add aspeed_soc_ast2700_dram_init to calculate the dram size and add
memory I/O whose address range is from "max_ram_size - ram_size" to max_ram_size
and its read/write handler to emulate DDR capacity hardware behavior.

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 
---
 hw/arm/aspeed_ast27x0.c | 87 -
 include/hw/arm/aspeed_soc.h |  2 +
 2 files changed, 88 insertions(+), 1 deletion(-)

diff --git a/hw/arm/aspeed_ast27x0.c b/hw/arm/aspeed_ast27x0.c
index 29e75072c4..b6876b4862 100644
--- a/hw/arm/aspeed_ast27x0.c
+++ b/hw/arm/aspeed_ast27x0.c
@@ -20,6 +20,7 @@
 #include "sysemu/sysemu.h"
 #include "hw/intc/arm_gicv3.h"
 #include "qapi/qmp/qlist.h"
+#include "qemu/log.h"
 
 static const hwaddr aspeed_soc_ast2700_memmap[] = {
 [ASPEED_DEV_SPI_BOOT]  =  0x4,
@@ -191,6 +192,90 @@ static qemu_irq aspeed_soc_ast2700_get_irq(AspeedSoCState 
*s, int dev)
 return qdev_get_gpio_in(DEVICE(>gic), sc->irqmap[dev]);
 }
 
+static uint64_t aspeed_ram_capacity_read(void *opaque, hwaddr addr,
+unsigned int size)
+{
+qemu_log_mask(LOG_GUEST_ERROR,
+  "%s: DRAM read out of ram size, addr:0x%" PRIx64 "\n",
+   __func__, addr);
+return 0;
+}
+
+static void aspeed_ram_capacity_write(void *opaque, hwaddr addr, uint64_t data,
+unsigned int size)
+{
+AspeedSoCState *s = ASPEED_SOC(opaque);
+ram_addr_t ram_size;
+MemTxResult result;
+
+ram_size = object_property_get_uint(OBJECT(>sdmc), "ram-size",
+_abort);
+
+/*
+ * Emulate ddr capacity hardware behavior.
+ * If writes the data to the address which is beyond the ram size,
+ * it would write the data to the "address % ram_size".
+ */
+result = address_space_write(>dram_as, addr % ram_size,
+ MEMTXATTRS_UNSPECIFIED, , 4);
+if (result != MEMTX_OK) {
+qemu_log_mask(LOG_GUEST_ERROR,
+  "%s: DRAM write failed, addr:0x%" HWADDR_PRIx
+  ", data :0x%" PRIx64  "\n",
+  __func__, addr % ram_size, data);
+}
+}
+
+static const MemoryRegionOps aspeed_ram_capacity_ops = {
+.read = aspeed_ram_capacity_read,
+.write = aspeed_ram_capacity_write,
+.endianness = DEVICE_LITTLE_ENDIAN,
+.valid = {
+.min_access_size = 1,
+.max_access_size = 8,
+},
+};
+
+/*
+ * SDMC should be realized first to get correct RAM size and max size
+ * values
+ */
+static bool aspeed_soc_ast2700_dram_init(DeviceState *dev, Error **errp)
+{
+ram_addr_t ram_size, max_ram_size;
+Aspeed27x0SoCState *a = ASPEED27X0_SOC(dev);
+AspeedSoCState *s = ASPEED_SOC(dev);
+AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
+
+ram_size = object_property_get_uint(OBJECT(>sdmc), "ram-size",
+_abort);
+max_ram_size = object_property_get_uint(OBJECT(>sdmc), "max-ram-size",
+_abort);
+
+memory_region_init(>dram_container, OBJECT(s), "ram-container",
+   ram_size);
+memory_region_add_subregion(>dram_container, 0, s->dram_mr);
+address_space_init(>dram_as, s->dram_mr, "dram");
+
+/*
+ * Add a memory region beyond the RAM region to emulate
+ * ddr capacity hardware behavior.
+ */
+if (ram_size < max_ram_size) {
+memory_region_init_io(>dram_empty, OBJECT(s),
+  _ram_capacity_ops, s,
+  "ram-empty", max_ram_size - ram_size);
+
+memory_region_add_subregion(s->memory,
+sc->memmap[ASPEED_DEV_SDRAM] + ram_size,
+>dram_empty);
+}
+
+memory_region_add_subregion(s->memory,
+  sc->memmap[ASPEED_DEV_SDRAM], >dram_container);
+return true;
+}
+
 static void aspeed_soc_ast2700_init(Object *obj)
 {
 Aspeed27x0SoCState *a = ASPEED27X0_SOC(obj);
@@ -461,7 +546,7 @@ static void aspeed_soc_ast2700_realize(DeviceState *dev, 
Error **errp)
   

[PATCH v5 10/17] aspeed/smc: Add AST2700 support

2024-06-03 Thread Jamin Lin via
AST2700 fmc/spi controller's address decoding unit is 64KB
and only bits [31:16] are used for decoding. Introduce seg_to_reg
and reg_to_seg handlers for ast2700 fmc/spi controller.
In addition, adds ast2700 fmc, spi0, spi1, and spi2 class init handler.

AST2700 is a 64 bits quad core CPUs(Cortex-a35). Introduce a new
"aspeed_2700_smc_flash_ops" and set its valid "max_access_size"
8 for 64 bits data format access.

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 
---
 hw/ssi/aspeed_smc.c | 234 +++-
 1 file changed, 233 insertions(+), 1 deletion(-)

diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
index 129d06690d..49205ab76d 100644
--- a/hw/ssi/aspeed_smc.c
+++ b/hw/ssi/aspeed_smc.c
@@ -185,7 +185,7 @@
  *   0: 4 bytes
  *   0x1FC: 32M bytes
  *
- * DMA length is from 1 byte to 32MB (AST2600, AST10x0)
+ * DMA length is from 1 byte to 32MB (AST2600, AST10x0 and AST2700)
  *   0: 1 byte
  *   0x1FF: 32M bytes
  */
@@ -1938,6 +1938,234 @@ static const TypeInfo aspeed_1030_spi2_info = {
 .class_init = aspeed_1030_spi2_class_init,
 };
 
+/*
+ * The FMC Segment Registers of the AST2700 have a 64KB unit.
+ * Only bits [31:16] are used for decoding.
+ */
+#define AST2700_SEG_ADDR_MASK 0x
+
+static uint32_t aspeed_2700_smc_segment_to_reg(const AspeedSMCState *s,
+   const AspeedSegments *seg)
+{
+uint32_t reg = 0;
+
+/* Disabled segments have a nil register */
+if (!seg->size) {
+return 0;
+}
+
+reg |= (seg->addr & AST2700_SEG_ADDR_MASK) >> 16; /* start offset */
+reg |= (seg->addr + seg->size - 1) & AST2700_SEG_ADDR_MASK; /* end offset 
*/
+return reg;
+}
+
+static void aspeed_2700_smc_reg_to_segment(const AspeedSMCState *s,
+   uint32_t reg, AspeedSegments *seg)
+{
+uint32_t start_offset = (reg << 16) & AST2700_SEG_ADDR_MASK;
+uint32_t end_offset = reg & AST2700_SEG_ADDR_MASK;
+AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s);
+
+if (reg) {
+seg->addr = asc->flash_window_base + start_offset;
+seg->size = end_offset + (64 * KiB) - start_offset;
+} else {
+seg->addr = asc->flash_window_base;
+seg->size = 0;
+}
+}
+
+static const uint32_t aspeed_2700_fmc_resets[ASPEED_SMC_R_MAX] = {
+[R_CONF] = (CONF_FLASH_TYPE_SPI << CONF_FLASH_TYPE0 |
+CONF_FLASH_TYPE_SPI << CONF_FLASH_TYPE1),
+[R_CE_CTRL] = 0xaa00,
+[R_CTRL0] = 0x406b0641,
+[R_CTRL1] = 0x0400,
+[R_CTRL2] = 0x0400,
+[R_CTRL3] = 0x0400,
+[R_SEG_ADDR0] = 0x0800,
+[R_SEG_ADDR1] = 0x1800,
+[R_SEG_ADDR2] = 0x,
+[R_SEG_ADDR3] = 0x,
+[R_DUMMY_DATA] = 0x0001,
+[R_DMA_DRAM_ADDR_HIGH] = 0x,
+[R_TIMINGS] = 0x007b,
+};
+
+static const MemoryRegionOps aspeed_2700_smc_flash_ops = {
+.read = aspeed_smc_flash_read,
+.write = aspeed_smc_flash_write,
+.endianness = DEVICE_LITTLE_ENDIAN,
+.valid = {
+.min_access_size = 1,
+.max_access_size = 8,
+},
+};
+
+static const AspeedSegments aspeed_2700_fmc_segments[] = {
+{ 0x0, 128 * MiB }, /* start address is readonly */
+{ 128 * MiB, 128 * MiB }, /* default is disabled but needed for -kernel */
+{ 256 * MiB, 128 * MiB }, /* default is disabled but needed for -kernel */
+{ 0x0, 0 }, /* disabled */
+};
+
+static void aspeed_2700_fmc_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+AspeedSMCClass *asc = ASPEED_SMC_CLASS(klass);
+
+dc->desc   = "Aspeed 2700 FMC Controller";
+asc->r_conf= R_CONF;
+asc->r_ce_ctrl = R_CE_CTRL;
+asc->r_ctrl0   = R_CTRL0;
+asc->r_timings = R_TIMINGS;
+asc->nregs_timings = 3;
+asc->conf_enable_w0= CONF_ENABLE_W0;
+asc->cs_num_max= 3;
+asc->segments  = aspeed_2700_fmc_segments;
+asc->segment_addr_mask = 0x;
+asc->resets= aspeed_2700_fmc_resets;
+asc->flash_window_base = 0x1;
+asc->flash_window_size = 1 * GiB;
+asc->features  = ASPEED_SMC_FEATURE_DMA |
+ ASPEED_SMC_FEATURE_DMA_DRAM_ADDR_HIGH;
+asc->dma_flash_mask= 0x2FFC;
+asc->dma_dram_mask = 0xFFFC;
+asc->dma_start_length  = 1;
+asc->nregs = ASPEED_SMC_R_MAX;
+asc->segment_to_reg= aspeed_2700_smc_segment_to_reg;
+asc->reg_to_segment= aspeed_2700_smc_reg_to_segment;
+asc->dma_ctrl  = aspeed_2600_smc_dma_ctrl;
+asc->reg_ops   = _2700_smc_flash_ops;
+}
+
+static const TypeInfo aspeed_2700_fmc_info = {
+.name =  "aspeed.fmc-ast2700",
+.parent = TYPE_ASPEED_SMC,
+

[PATCH v5 09/17] aspeed/smc: support different memory region ops for SMC flash region

2024-06-03 Thread Jamin Lin via
It set "aspeed_smc_flash_ops" struct which containing
read and write callbacks to be used when I/O is performed
on the SMC flash region. And it set the valid max_access_size 4
by default for all ASPEED SMC models.

However, the valid max_access_size 4 only support 32 bits CPUs.
To support all ASPEED SMC model, introduce a new
"const MemoryRegionOps *" attribute in AspeedSMCClass and
use it in aspeed_smc_flash_realize function.

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 
---
 hw/ssi/aspeed_smc.c | 14 +-
 include/hw/ssi/aspeed_smc.h |  1 +
 2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
index df0c63469c..129d06690d 100644
--- a/hw/ssi/aspeed_smc.c
+++ b/hw/ssi/aspeed_smc.c
@@ -1316,7 +1316,7 @@ static void aspeed_smc_flash_realize(DeviceState *dev, 
Error **errp)
  * Use the default segment value to size the memory region. This
  * can be changed by FW at runtime.
  */
-memory_region_init_io(>mmio, OBJECT(s), _smc_flash_ops,
+memory_region_init_io(>mmio, OBJECT(s), s->asc->reg_ops,
   s, name, s->asc->segments[s->cs].size);
 sysbus_init_mmio(SYS_BUS_DEVICE(dev), >mmio);
 }
@@ -1391,6 +1391,7 @@ static void aspeed_2400_smc_class_init(ObjectClass 
*klass, void *data)
 asc->segment_to_reg= aspeed_smc_segment_to_reg;
 asc->reg_to_segment= aspeed_smc_reg_to_segment;
 asc->dma_ctrl  = aspeed_smc_dma_ctrl;
+asc->reg_ops   = _smc_flash_ops;
 }
 
 static const TypeInfo aspeed_2400_smc_info = {
@@ -1441,6 +1442,7 @@ static void aspeed_2400_fmc_class_init(ObjectClass 
*klass, void *data)
 asc->segment_to_reg= aspeed_smc_segment_to_reg;
 asc->reg_to_segment= aspeed_smc_reg_to_segment;
 asc->dma_ctrl  = aspeed_smc_dma_ctrl;
+asc->reg_ops   = _smc_flash_ops;
 }
 
 static const TypeInfo aspeed_2400_fmc_info = {
@@ -1480,6 +1482,7 @@ static void aspeed_2400_spi1_class_init(ObjectClass 
*klass, void *data)
 asc->reg_to_segment= aspeed_smc_reg_to_segment;
 asc->dma_ctrl  = aspeed_smc_dma_ctrl;
 asc->addr_width= aspeed_2400_spi1_addr_width;
+asc->reg_ops   = _smc_flash_ops;
 }
 
 static const TypeInfo aspeed_2400_spi1_info = {
@@ -1525,6 +1528,7 @@ static void aspeed_2500_fmc_class_init(ObjectClass 
*klass, void *data)
 asc->segment_to_reg= aspeed_smc_segment_to_reg;
 asc->reg_to_segment= aspeed_smc_reg_to_segment;
 asc->dma_ctrl  = aspeed_smc_dma_ctrl;
+asc->reg_ops   = _smc_flash_ops;
 }
 
 static const TypeInfo aspeed_2500_fmc_info = {
@@ -1560,6 +1564,7 @@ static void aspeed_2500_spi1_class_init(ObjectClass 
*klass, void *data)
 asc->segment_to_reg= aspeed_smc_segment_to_reg;
 asc->reg_to_segment= aspeed_smc_reg_to_segment;
 asc->dma_ctrl  = aspeed_smc_dma_ctrl;
+asc->reg_ops   = _smc_flash_ops;
 }
 
 static const TypeInfo aspeed_2500_spi1_info = {
@@ -1595,6 +1600,7 @@ static void aspeed_2500_spi2_class_init(ObjectClass 
*klass, void *data)
 asc->segment_to_reg= aspeed_smc_segment_to_reg;
 asc->reg_to_segment= aspeed_smc_reg_to_segment;
 asc->dma_ctrl  = aspeed_smc_dma_ctrl;
+asc->reg_ops   = _smc_flash_ops;
 }
 
 static const TypeInfo aspeed_2500_spi2_info = {
@@ -1682,6 +1688,7 @@ static void aspeed_2600_fmc_class_init(ObjectClass 
*klass, void *data)
 asc->segment_to_reg= aspeed_2600_smc_segment_to_reg;
 asc->reg_to_segment= aspeed_2600_smc_reg_to_segment;
 asc->dma_ctrl  = aspeed_2600_smc_dma_ctrl;
+asc->reg_ops   = _smc_flash_ops;
 }
 
 static const TypeInfo aspeed_2600_fmc_info = {
@@ -1721,6 +1728,7 @@ static void aspeed_2600_spi1_class_init(ObjectClass 
*klass, void *data)
 asc->segment_to_reg= aspeed_2600_smc_segment_to_reg;
 asc->reg_to_segment= aspeed_2600_smc_reg_to_segment;
 asc->dma_ctrl  = aspeed_2600_smc_dma_ctrl;
+asc->reg_ops   = _smc_flash_ops;
 }
 
 static const TypeInfo aspeed_2600_spi1_info = {
@@ -1761,6 +1769,7 @@ static void aspeed_2600_spi2_class_init(ObjectClass 
*klass, void *data)
 asc->segment_to_reg= aspeed_2600_smc_segment_to_reg;
 asc->reg_to_segment= aspeed_2600_smc_reg_to_segment;
 asc->dma_ctrl  = aspeed_2600_smc_dma_ctrl;
+asc->reg_ops   = _smc_flash_ops;
 }
 
 static const TypeInfo aspeed_2600_spi2_info = {
@@ -1843,6 +1852,7 @@ static void aspeed_1030_fmc_class_init(ObjectClass 
*klass, void *data)
 asc->segment_to_reg= aspeed_1030_smc_segment_to_reg;
 asc->reg_to_segment= aspeed_1030_smc_reg_to_segment;
 asc->dma_ctrl  = aspeed_2600_smc_dma_ctrl;
+asc->reg_ops   = _smc_flash_ops;
 }
 
 st

[PATCH v5 01/17] aspeed/wdt: Add AST2700 support

2024-06-03 Thread Jamin Lin via
AST2700 wdt controller is similiar to AST2600's wdt, but
the AST2700 has 8 watchdogs, and they each have 0x80 of registers.
Introduce ast2700 object class and increase the number of regs(offset) of
ast2700 model.

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 
Reviewed-by: Cédric Le Goater 
---
 hw/watchdog/wdt_aspeed.c | 24 
 include/hw/watchdog/wdt_aspeed.h |  3 ++-
 2 files changed, 26 insertions(+), 1 deletion(-)

diff --git a/hw/watchdog/wdt_aspeed.c b/hw/watchdog/wdt_aspeed.c
index d70b656f8e..75685c5647 100644
--- a/hw/watchdog/wdt_aspeed.c
+++ b/hw/watchdog/wdt_aspeed.c
@@ -422,12 +422,36 @@ static const TypeInfo aspeed_1030_wdt_info = {
 .class_init = aspeed_1030_wdt_class_init,
 };
 
+static void aspeed_2700_wdt_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+AspeedWDTClass *awc = ASPEED_WDT_CLASS(klass);
+
+dc->desc = "ASPEED 2700 Watchdog Controller";
+awc->iosize = 0x80;
+awc->ext_pulse_width_mask = 0xf; /* TODO */
+awc->reset_ctrl_reg = AST2600_SCU_RESET_CONTROL1;
+awc->reset_pulse = aspeed_2500_wdt_reset_pulse;
+awc->wdt_reload = aspeed_wdt_reload_1mhz;
+awc->sanitize_ctrl = aspeed_2600_sanitize_ctrl;
+awc->default_status = 0x014FB180;
+awc->default_reload_value = 0x014FB180;
+}
+
+static const TypeInfo aspeed_2700_wdt_info = {
+.name = TYPE_ASPEED_2700_WDT,
+.parent = TYPE_ASPEED_WDT,
+.instance_size = sizeof(AspeedWDTState),
+.class_init = aspeed_2700_wdt_class_init,
+};
+
 static void wdt_aspeed_register_types(void)
 {
 type_register_static(_wdt_info);
 type_register_static(_2400_wdt_info);
 type_register_static(_2500_wdt_info);
 type_register_static(_2600_wdt_info);
+type_register_static(_2700_wdt_info);
 type_register_static(_1030_wdt_info);
 }
 
diff --git a/include/hw/watchdog/wdt_aspeed.h b/include/hw/watchdog/wdt_aspeed.h
index e90ef86651..830b0a7936 100644
--- a/include/hw/watchdog/wdt_aspeed.h
+++ b/include/hw/watchdog/wdt_aspeed.h
@@ -19,9 +19,10 @@ OBJECT_DECLARE_TYPE(AspeedWDTState, AspeedWDTClass, 
ASPEED_WDT)
 #define TYPE_ASPEED_2400_WDT TYPE_ASPEED_WDT "-ast2400"
 #define TYPE_ASPEED_2500_WDT TYPE_ASPEED_WDT "-ast2500"
 #define TYPE_ASPEED_2600_WDT TYPE_ASPEED_WDT "-ast2600"
+#define TYPE_ASPEED_2700_WDT TYPE_ASPEED_WDT "-ast2700"
 #define TYPE_ASPEED_1030_WDT TYPE_ASPEED_WDT "-ast1030"
 
-#define ASPEED_WDT_REGS_MAX(0x30 / 4)
+#define ASPEED_WDT_REGS_MAX(0x80 / 4)
 
 struct AspeedWDTState {
 /*< private >*/
-- 
2.25.1




[PATCH v5 11/17] aspeed/scu: Add AST2700 support

2024-06-03 Thread Jamin Lin via
AST2700 have two SCU controllers which are SCU and SCUIO.
Both SCU and SCUIO registers are not compatible previous SOCs
, introduces new registers and adds ast2700 scu, sucio class init handler.

The pclk divider selection of SCUIO is defined in SCUIO280[20:18] and
the pclk divider selection of SCU is defined in SCU280[25:23].
Both of them are not compatible AST2600 SOCs, adds a get_apb_freq function
and trace-event for AST2700 SCU and SCUIO.

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 
Reviewed-by: Cédric Le Goater 
---
 hw/misc/aspeed_scu.c | 306 ++-
 hw/misc/trace-events |   4 +
 include/hw/misc/aspeed_scu.h |  47 +-
 3 files changed, 351 insertions(+), 6 deletions(-)

diff --git a/hw/misc/aspeed_scu.c b/hw/misc/aspeed_scu.c
index 1ac04b6cb0..eb38ea8e19 100644
--- a/hw/misc/aspeed_scu.c
+++ b/hw/misc/aspeed_scu.c
@@ -134,6 +134,48 @@
 
 #define AST2600_CLK TO_REG(0x40)
 
+#define AST2700_SILICON_REV   TO_REG(0x00)
+#define AST2700_HW_STRAP1 TO_REG(0x10)
+#define AST2700_HW_STRAP1_CLR TO_REG(0x14)
+#define AST2700_HW_STRAP1_LOCKTO_REG(0x20)
+#define AST2700_HW_STRAP1_SEC1TO_REG(0x24)
+#define AST2700_HW_STRAP1_SEC2TO_REG(0x28)
+#define AST2700_HW_STRAP1_SEC3TO_REG(0x2C)
+
+#define AST2700_SCU_CLK_SEL_1   TO_REG(0x280)
+#define AST2700_SCU_HPLL_PARAM  TO_REG(0x300)
+#define AST2700_SCU_HPLL_EXT_PARAM  TO_REG(0x304)
+#define AST2700_SCU_DPLL_PARAM  TO_REG(0x308)
+#define AST2700_SCU_DPLL_EXT_PARAM  TO_REG(0x30c)
+#define AST2700_SCU_MPLL_PARAM  TO_REG(0x310)
+#define AST2700_SCU_MPLL_EXT_PARAM  TO_REG(0x314)
+#define AST2700_SCU_D1CLK_PARAM TO_REG(0x320)
+#define AST2700_SCU_D2CLK_PARAM TO_REG(0x330)
+#define AST2700_SCU_CRT1CLK_PARAM   TO_REG(0x340)
+#define AST2700_SCU_CRT2CLK_PARAM   TO_REG(0x350)
+#define AST2700_SCU_MPHYCLK_PARAM   TO_REG(0x360)
+#define AST2700_SCU_FREQ_CNTR   TO_REG(0x3b0)
+#define AST2700_SCU_CPU_SCRATCH_0   TO_REG(0x780)
+#define AST2700_SCU_CPU_SCRATCH_1   TO_REG(0x784)
+
+#define AST2700_SCUIO_CLK_STOP_CTL_1TO_REG(0x240)
+#define AST2700_SCUIO_CLK_STOP_CLR_1TO_REG(0x244)
+#define AST2700_SCUIO_CLK_STOP_CTL_2TO_REG(0x260)
+#define AST2700_SCUIO_CLK_STOP_CLR_2TO_REG(0x264)
+#define AST2700_SCUIO_CLK_SEL_1 TO_REG(0x280)
+#define AST2700_SCUIO_CLK_SEL_2 TO_REG(0x284)
+#define AST2700_SCUIO_HPLL_PARAMTO_REG(0x300)
+#define AST2700_SCUIO_HPLL_EXT_PARAMTO_REG(0x304)
+#define AST2700_SCUIO_APLL_PARAMTO_REG(0x310)
+#define AST2700_SCUIO_APLL_EXT_PARAMTO_REG(0x314)
+#define AST2700_SCUIO_DPLL_PARAMTO_REG(0x320)
+#define AST2700_SCUIO_DPLL_EXT_PARAMTO_REG(0x324)
+#define AST2700_SCUIO_DPLL_PARAM_READ   TO_REG(0x328)
+#define AST2700_SCUIO_DPLL_EXT_PARAM_READ TO_REG(0x32c)
+#define AST2700_SCUIO_UARTCLK_GEN   TO_REG(0x330)
+#define AST2700_SCUIO_HUARTCLK_GEN  TO_REG(0x334)
+#define AST2700_SCUIO_CLK_DUTY_MEAS_RST TO_REG(0x388)
+
 #define SCU_IO_REGION_SIZE 0x1000
 
 static const uint32_t ast2400_a0_resets[ASPEED_SCU_NR_REGS] = {
@@ -244,6 +286,25 @@ static uint32_t 
aspeed_1030_scu_get_apb_freq(AspeedSCUState *s)
 / asc->apb_divider;
 }
 
+static uint32_t aspeed_2700_scu_get_apb_freq(AspeedSCUState *s)
+{
+AspeedSCUClass *asc = ASPEED_SCU_GET_CLASS(s);
+uint32_t hpll = asc->calc_hpll(s, s->regs[AST2700_SCU_HPLL_PARAM]);
+
+return hpll / (SCU_CLK_GET_PCLK_DIV(s->regs[AST2700_SCU_CLK_SEL_1]) + 1)
+   / asc->apb_divider;
+}
+
+static uint32_t aspeed_2700_scuio_get_apb_freq(AspeedSCUState *s)
+{
+AspeedSCUClass *asc = ASPEED_SCU_GET_CLASS(s);
+uint32_t hpll = asc->calc_hpll(s, s->regs[AST2700_SCUIO_HPLL_PARAM]);
+
+return hpll /
+(SCUIO_AST2700_CLK_GET_PCLK_DIV(s->regs[AST2700_SCUIO_CLK_SEL_1]) + 1)
+/ asc->apb_divider;
+}
+
 static uint64_t aspeed_scu_read(void *opaque, hwaddr offset, unsigned size)
 {
 AspeedSCUState *s = ASPEED_SCU(opaque);
@@ -258,7 +319,8 @@ static uint64_t aspeed_scu_read(void *opaque, hwaddr 
offset, unsigned size)
 
 switch (reg) {
 case RNG_DATA:
-/* On hardware, RNG_DATA works regardless of
+/*
+ * On hardware, RNG_DATA works regardless of
  * the state of the enable bit in RNG_CTRL
  */
 s->regs[RNG_DATA] = aspeed_scu_get_random();
@@ -494,6 +556,9 @@ static uint32_t aspeed_silicon_revs[] = {
 AST2600_A3_SILICON_REV,
 AST1030_A0_SILICON_REV,
 AST1030_A1_SILICON_REV,
+AST2700_A0_SILICON_REV,
+AST2720_A0_SILICON_REV,
+AST2750_A0_SILICON_REV,
 };
 
 bool is_supported_silicon_rev(uint32_t silicon_rev)
@@ -783,6 +848,243 @@ static const TypeInfo aspeed_2600_scu_info = {
 .class_init = aspeed_2600_scu_class_init,
 };
 
+static uint64_t aspeed_ast2700_scu_read(void *opaque, hwaddr offset,
+unsigned size)
+{
+AspeedSCUState *s = ASPEED_SCU(opaque);
+int reg = 

[PATCH v5 02/17] aspeed/sli: Add AST2700 support

2024-06-03 Thread Jamin Lin via
AST2700 SLI engine is designed to accelerate the
throughput between cross-die connections.
It have CPU_SLI at CPU die and IO_SLI at IO die.

Introduce dummy AST2700 SLI and SLIIO models.

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 
Reviewed-by: Cédric Le Goater 
---
 hw/misc/aspeed_sli.c | 177 +++
 hw/misc/meson.build  |   3 +-
 hw/misc/trace-events |   7 ++
 include/hw/misc/aspeed_sli.h |  27 ++
 4 files changed, 213 insertions(+), 1 deletion(-)
 create mode 100644 hw/misc/aspeed_sli.c
 create mode 100644 include/hw/misc/aspeed_sli.h

diff --git a/hw/misc/aspeed_sli.c b/hw/misc/aspeed_sli.c
new file mode 100644
index 00..fe720ead50
--- /dev/null
+++ b/hw/misc/aspeed_sli.c
@@ -0,0 +1,177 @@
+/*
+ * ASPEED SLI Controller
+ *
+ * Copyright (C) 2024 ASPEED Technology Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "qemu/error-report.h"
+#include "hw/qdev-properties.h"
+#include "hw/misc/aspeed_sli.h"
+#include "qapi/error.h"
+#include "migration/vmstate.h"
+#include "trace.h"
+
+#define SLI_REGION_SIZE 0x500
+#define TO_REG(addr) ((addr) >> 2)
+
+static uint64_t aspeed_sli_read(void *opaque, hwaddr addr, unsigned int size)
+{
+AspeedSLIState *s = ASPEED_SLI(opaque);
+int reg = TO_REG(addr);
+
+if (reg >= ARRAY_SIZE(s->regs)) {
+qemu_log_mask(LOG_GUEST_ERROR,
+  "%s: Out-of-bounds read at offset 0x%" HWADDR_PRIx "\n",
+  __func__, addr);
+return 0;
+}
+
+trace_aspeed_sli_read(addr, size, s->regs[reg]);
+return s->regs[reg];
+}
+
+static void aspeed_sli_write(void *opaque, hwaddr addr, uint64_t data,
+  unsigned int size)
+{
+AspeedSLIState *s = ASPEED_SLI(opaque);
+int reg = TO_REG(addr);
+
+if (reg >= ARRAY_SIZE(s->regs)) {
+qemu_log_mask(LOG_GUEST_ERROR,
+  "%s: Out-of-bounds write at offset 0x%" HWADDR_PRIx "\n",
+  __func__, addr);
+return;
+}
+
+trace_aspeed_sli_write(addr, size, data);
+s->regs[reg] = data;
+}
+
+static uint64_t aspeed_sliio_read(void *opaque, hwaddr addr, unsigned int size)
+{
+AspeedSLIState *s = ASPEED_SLI(opaque);
+int reg = TO_REG(addr);
+
+if (reg >= ARRAY_SIZE(s->regs)) {
+qemu_log_mask(LOG_GUEST_ERROR,
+  "%s: Out-of-bounds read at offset 0x%" HWADDR_PRIx "\n",
+  __func__, addr);
+return 0;
+}
+
+trace_aspeed_sliio_read(addr, size, s->regs[reg]);
+return s->regs[reg];
+}
+
+static void aspeed_sliio_write(void *opaque, hwaddr addr, uint64_t data,
+  unsigned int size)
+{
+AspeedSLIState *s = ASPEED_SLI(opaque);
+int reg = TO_REG(addr);
+
+if (reg >= ARRAY_SIZE(s->regs)) {
+qemu_log_mask(LOG_GUEST_ERROR,
+  "%s: Out-of-bounds write at offset 0x%" HWADDR_PRIx "\n",
+  __func__, addr);
+return;
+}
+
+trace_aspeed_sliio_write(addr, size, data);
+s->regs[reg] = data;
+}
+
+static const MemoryRegionOps aspeed_sli_ops = {
+.read = aspeed_sli_read,
+.write = aspeed_sli_write,
+.endianness = DEVICE_LITTLE_ENDIAN,
+.valid = {
+.min_access_size = 1,
+.max_access_size = 4,
+},
+};
+
+static const MemoryRegionOps aspeed_sliio_ops = {
+.read = aspeed_sliio_read,
+.write = aspeed_sliio_write,
+.endianness = DEVICE_LITTLE_ENDIAN,
+.valid = {
+.min_access_size = 1,
+.max_access_size = 4,
+},
+};
+
+static void aspeed_sli_realize(DeviceState *dev, Error **errp)
+{
+AspeedSLIState *s = ASPEED_SLI(dev);
+SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
+
+memory_region_init_io(>iomem, OBJECT(s), _sli_ops, s,
+  TYPE_ASPEED_SLI, SLI_REGION_SIZE);
+sysbus_init_mmio(sbd, >iomem);
+}
+
+static void aspeed_sliio_realize(DeviceState *dev, Error **errp)
+{
+AspeedSLIState *s = ASPEED_SLI(dev);
+SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
+
+memory_region_init_io(>iomem, OBJECT(s), _sliio_ops, s,
+  TYPE_ASPEED_SLI, SLI_REGION_SIZE);
+sysbus_init_mmio(sbd, >iomem);
+}
+
+static void aspeed_sli_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+
+dc->desc = "Aspeed SLI Controller";
+dc->realize = aspeed_sli_realize;
+}
+
+static const TypeInfo aspeed_sli_info = {
+.name  = TYPE_ASPEED_SLI,
+.parent= TYPE_SYS_BUS_DEVICE,
+.instance_size = sizeof(AspeedSLIState),
+.class_init= aspeed_sli_class_init,
+.abstract  = true,
+};
+
+sta

[PATCH v5 00/17] Add AST2700 support

2024-06-03 Thread Jamin Lin via
Changes from v1:
The patch series supports WDT, SDMC, SMC, SCU, SLI and INTC for AST2700 SoC.

Changes from v2:
- replace is_aarch64 with is_bus64bit for sdmc patch review.
- fix incorrect dram size for AST2700

Changes from v3:
- Add AST2700 Evaluation board in ASPEED document
- Add avocado test cases for AST2700 Evaluation board
- Fix reviewers review issues and add reviewers suggestions
- Implement INTC model GICINT 128 to GICINT136 for AST2700

Changes from v4:
- support 64 bits dma dram address associated with review issues
- support dma start length and 1 byte length unit associated with review issues
- refactor intc model to fix serial console stuck issue and associated with 
review issues

Changes from v5:
- sdmc: incrementing the version of vmstate to 2.
- smc: support different memory region ops for SMC flash region
   introduce a new "const MemoryRegionOps *" attribute in AspeedSMCClass and
   use it in aspeed_smc_flash_realize function.
- intc: fix associated with review issues
- dram size detect: change to use address space API and simplify with write
transaction on the DRAM memory region of the SoC.
- ast27x0_soc: update aspeed_soc_ast2700_gic function associated with review 
issues
   and rename to aspeed_soc_ast2700_gic_realize

Test Version:
qemu commit:
https://github.com/qemu/qemu/commit/74abb45dac6979e7ff76172b7f0a24e869405184
applied patch:
https://patchew.org/QEMU/20240527124315.35356-1-...@redhat.com/

Test steps:
1. Download the latest openbmc image for AST2700 from AspeedTech-BMC/openbmc
   repository, https://github.com/AspeedTech-BMC/openbmc/releases/tag/v09.01
   link: 
https://github.com/AspeedTech-BMC/openbmc/releases/download/v09.01/ast2700-default-obmc.tar.gz
2. untar ast2700-default-obmc.tar.gz
   ```
   tar -xf ast2700-default-obmc.tar.gz
   ```
3. Run and the contents of scripts as following
IMGDIR=ast2700-default
UBOOT_SIZE=$(stat --format=%s -L ${IMGDIR}/u-boot-nodtb.bin)
UBOOT_DTB_ADDR=$((0x4 + ${UBOOT_SIZE}))

qemu-system-aarch64 -M ast2700-evb -nographic\
 -device loader,addr=0x4,file=${IMGDIR}/u-boot-nodtb.bin,force-raw=on\
 -device loader,addr=${UBOOT_DTB_ADDR},file=${IMGDIR}/u-boot.dtb,force-raw=on\
 -device loader,addr=0x43000,file=${IMGDIR}/bl31.bin,force-raw=on\
 -device loader,addr=0x43008,file=${IMGDIR}/optee/tee-raw.bin,force-raw=on\
 -device loader,addr=0x43000,cpu-num=0\
 -device loader,addr=0x43000,cpu-num=1\
 -device loader,addr=0x43000,cpu-num=2\
 -device loader,addr=0x43000,cpu-num=3\
 -smp 4\
 -drive file=${IMGDIR}/image-bmc,format=raw,if=mtd\
 -serial mon:stdio\
 -snapshot

Jamin Lin (17):
  aspeed/wdt: Add AST2700 support
  aspeed/sli: Add AST2700 support
  aspeed/sdmc: remove redundant macros
  aspeed/sdmc: fix coding style
  aspeed/sdmc: Add AST2700 support
  aspeed/smc: correct device description
  aspeed/smc: support dma start length and 1 byte length unit
  aspeed/smc: support 64 bits dma dram address
  aspeed/smc: support different memory region ops for SMC flash region
  aspeed/smc: Add AST2700 support
  aspeed/scu: Add AST2700 support
  aspeed/intc: Add AST2700 support
  aspeed/soc: Add AST2700 support
  aspeed: Add an AST2700 eval board
  aspeed/soc: fix incorrect dram size for AST2700
  test/avocado/machine_aspeed.py: Add AST2700 test case
  docs:aspeed: Add AST2700 Evaluation board

 docs/system/arm/aspeed.rst   |  39 +-
 hw/arm/aspeed.c  |  32 ++
 hw/arm/aspeed_ast27x0.c  | 648 +++
 hw/arm/meson.build   |   1 +
 hw/intc/aspeed_intc.c| 360 +
 hw/intc/meson.build  |   1 +
 hw/intc/trace-events |  13 +
 hw/misc/aspeed_scu.c | 306 ++-
 hw/misc/aspeed_sdmc.c| 220 +--
 hw/misc/aspeed_sli.c | 177 +
 hw/misc/meson.build  |   3 +-
 hw/misc/trace-events |  11 +
 hw/ssi/aspeed_smc.c  | 346 -
 hw/ssi/trace-events  |   2 +-
 hw/watchdog/wdt_aspeed.c |  24 ++
 include/hw/arm/aspeed_soc.h  |  30 +-
 include/hw/intc/aspeed_intc.h|  44 +++
 include/hw/misc/aspeed_scu.h |  47 ++-
 include/hw/misc/aspeed_sdmc.h|   5 +-
 include/hw/misc/aspeed_sli.h |  27 ++
 include/hw/ssi/aspeed_smc.h  |   2 +
 include/hw/watchdog/wdt_aspeed.h |   3 +-
 tests/avocado/machine_aspeed.py  |  62 +++
 23 files changed, 2345 insertions(+), 58 deletions(-)
 create mode 100644 hw/arm/aspeed_ast27x0.c
 create mode 100644 hw/intc/aspeed_intc.c
 create mode 100644 hw/misc/aspeed_sli.c
 create mode 100644 include/hw/intc/aspeed_intc.h
 create mode 100644 include/hw/misc/aspeed_sli.h

-- 
2.25.1




RE: [SPAM] Re: [PATCH v4 09/16] aspeed/smc: Add AST2700 support

2024-06-03 Thread Jamin Lin
Hi Cedric,

> From: Cédric Le Goater 
> Subject: Re: [SPAM] Re: [PATCH v4 09/16] aspeed/smc: Add AST2700 support
> 
> On 6/3/24 11:49, Jamin Lin wrote:
> > Hi Cedric,
> >
> >> From: Cédric Le Goater 
> >> Subject: Re: [SPAM] Re: [PATCH v4 09/16] aspeed/smc: Add AST2700
> >> support
> >>
> >>>>>> @@ -670,7 +670,7 @@ static const MemoryRegionOps
> >>>> aspeed_smc_flash_ops
> >>>>>> = {
> >>>>>>     .endianness = DEVICE_LITTLE_ENDIAN,
> >>>>>>     .valid = {
> >>>>>>     .min_access_size = 1,
> >>>>>> -    .max_access_size = 4,
> >>>>>> +    .max_access_size = 8,
> >>>>>
> >>>>> Is this a bugfix? If so, please use a separate patch. Otherwise
> >>>>> please mention why it is OK to widen access for AST2600 & AST10x0.
> >>>>
> >>> According the design of SPI drivers, it uses this "memcpy_fromio"
> >>> KERNEL API
> >> for SPI calibration.
> >>>
> >>
> https://github.com/AspeedTech-BMC/linux/blob/1062a07420f9aed4ed7dc9de
> >> b
> >>> 3429b8e7828f5cf/drivers/spi/spi-aspeed-smc.c#L1832
> >>> AST2700 is a 64 bits quad core cpus(Cortex-a35), so kernel API use
> >>> 64 bits for
> >> data access.
> >>> https://github.com/AspeedTech-BMC/linux/blob/aspeed-master-v6.6/arch
> >>> /a
> >>> rm64/kernel/io.c#L25 I simply set the max_access_size to 8 for
> >>> AST2700 support.
> >>> AST2500, AST2600 and AST10x0 are all 32bits CPUS, that was why this
> >> max_access_size 8 did not impact these models.
> >>> https://github.com/AspeedTech-BMC/linux/blob/aspeed-master-v6.6/arch
> >>> /a
> >>> rm/kernel/io.c#L45
> >>
> >> Yes. I think we are safe on that side.
> >>
> >>> If you have any suggestion about this patch modification, please let me
> know.
> >>> I am going to re-send v5 patch for AST2700 support.
> >>
> >> Please move this change in its own commit explaining the reason and
> >> add a TODO comment in the code.
> >>
> >> The aspeed_smc_flash_ops MemoryRegionOps should be copied in
> >> _realize() to set a different width for the AST2700 SoC. You could do that
> too.
> >>
> >> Thanks,
> >>
> >> C.
> > I will do the following changes. Could you give me any suggestion?
> >
> > 1. add asc->max_access_size = 8 in aspeed_2700_fmc_class_init,
> > aspeed_2700_spi0_class_init, aspeed_2700_spi1_class_init and
> > aspeed_2700_spi2_class_init 2. Update aspeed_smc_flash_realize as
> > below static void aspeed_smc_flash_realize(DeviceState *dev, Error **errp)
> {
> > --
> > s->asc = ASPEED_SMC_GET_CLASS(s->controller)
> > if (s->asc->max_access_size ==8) --> check max_access_size
> >aspeed_smc_flash_ops.valid.max_access_size =
> s->asc->max_access
> > --> update max_access_size
> 
> You can not because aspeed_smc_flash_ops is a static const shared by all
> models
> 
> Best option is to introduce a new 'const MemoryRegionOps*' attribute in
> AspeedSMCClass and use it in aspeed_smc_flash_realize().
> 
Thanks for your suggestion. How about these changes?

1. aspeed_smc.h
struct AspeedSMCClass {
const MemoryRegionOps *reg_ops;
}

2. aspeed_smc.c
a. create new memory region opts for ast2700 
static const MemoryRegionOps aspeed_2700_smc_flash_ops = {
.read = aspeed_smc_flash_read,
.write = aspeed_smc_flash_write,
.endianness = DEVICE_LITTLE_ENDIAN,
.valid = {
.min_access_size = 1,
.max_access_size = 8,
},
};

b. set memory region opts in all model class init
static void aspeed_2400_smc_class_init(ObjectClass *klass, void *data){
asc->reg_ops   = _smc_flash_ops;
}
static void aspeed_2400_fmc_class_init (ObjectClass *klass, void *data){
asc->reg_ops   = _smc_flash_ops;
}
static void aspeed_2400_spi1_class_init (ObjectClass *klass, void *data){
asc->reg_ops   = _smc_flash_ops;
}
static void aspeed_2500_fmc_class_init (ObjectClass *klass, void *data){
asc->reg_ops   = _smc_flash_ops;
}
static void aspeed_2500_spi1_class_init (ObjectClass *klass, void *data){
asc->reg_ops   = _smc_flash_ops;
}
static void aspeed_2500_spi2_class_init (ObjectClass *klass, void *data){
asc->reg_ops   = _smc_flash_ops;
}
static void aspeed_2600_fmc_class_init (ObjectClass *klass, void *data){
asc->reg_ops 

RE: [SPAM] Re: [PATCH v4 09/16] aspeed/smc: Add AST2700 support

2024-06-03 Thread Jamin Lin
Hi Cedric, 

> From: Cédric Le Goater 
> Subject: Re: [SPAM] Re: [PATCH v4 09/16] aspeed/smc: Add AST2700 support
> 
>  @@ -670,7 +670,7 @@ static const MemoryRegionOps
> >> aspeed_smc_flash_ops
>  = {
>     .endianness = DEVICE_LITTLE_ENDIAN,
>     .valid = {
>     .min_access_size = 1,
>  -    .max_access_size = 4,
>  +    .max_access_size = 8,
> >>>
> >>> Is this a bugfix? If so, please use a separate patch. Otherwise
> >>> please mention why it is OK to widen access for AST2600 & AST10x0.
> >>
> > According the design of SPI drivers, it uses this "memcpy_fromio" KERNEL API
> for SPI calibration.
> >
> https://github.com/AspeedTech-BMC/linux/blob/1062a07420f9aed4ed7dc9deb
> > 3429b8e7828f5cf/drivers/spi/spi-aspeed-smc.c#L1832
> > AST2700 is a 64 bits quad core cpus(Cortex-a35), so kernel API use 64 bits 
> > for
> data access.
> > https://github.com/AspeedTech-BMC/linux/blob/aspeed-master-v6.6/arch/a
> > rm64/kernel/io.c#L25 I simply set the max_access_size to 8 for AST2700
> > support.
> > AST2500, AST2600 and AST10x0 are all 32bits CPUS, that was why this
> max_access_size 8 did not impact these models.
> > https://github.com/AspeedTech-BMC/linux/blob/aspeed-master-v6.6/arch/a
> > rm/kernel/io.c#L45
> 
> Yes. I think we are safe on that side.
> 
> > If you have any suggestion about this patch modification, please let me 
> > know.
> > I am going to re-send v5 patch for AST2700 support.
> 
> Please move this change in its own commit explaining the reason and add a
> TODO comment in the code.
> 
> The aspeed_smc_flash_ops MemoryRegionOps should be copied in _realize()
> to set a different width for the AST2700 SoC. You could do that too.
> 
> Thanks,
> 
> C.
I will do the following changes. Could you give me any suggestion?

1. add asc->max_access_size = 8 in aspeed_2700_fmc_class_init, 
aspeed_2700_spi0_class_init, aspeed_2700_spi1_class_init and 
aspeed_2700_spi2_class_init
2. Update aspeed_smc_flash_realize as below
static void aspeed_smc_flash_realize(DeviceState *dev, Error **errp)
{
   --
   s->asc = ASPEED_SMC_GET_CLASS(s->controller)
   if (s->asc->max_access_size ==8) --> check max_access_size
  aspeed_smc_flash_ops.valid.max_access_size = s->asc->max_access --> 
update max_access_size
/*
 * Use the default segment value to size the memory region. This
 * can be changed by FW at runtime.
 */
memory_region_init_io(>mmio, OBJECT(s), _smc_flash_ops,
  s, name, s->asc->segments[s->cs].size);
   --
}

Thanks-Jamin



RE: [SPAM] Re: [PATCH v4 09/16] aspeed/smc: Add AST2700 support

2024-06-03 Thread Jamin Lin
Hi Cedric, Philippe

> From: Cédric Le Goater 
> Sent: Tuesday, May 28, 2024 3:03 PM
> To: Philippe Mathieu-Daudé ; Jamin Lin
> ; Peter Maydell ;
> Andrew Jeffery ; Joel Stanley
> ; Alistair Francis ; Cleber Rosa
> ; Wainer dos Santos Moschetta ;
> Beraldo Leal ; open list:ASPEED BMCs
> ; open list:All patches CC here
> 
> Cc: Troy Lee ; Yunlin Tang
> 
> Subject: Re: [SPAM] Re: [PATCH v4 09/16] aspeed/smc: Add AST2700 support
> 
> On 5/27/24 17:58, Philippe Mathieu-Daudé wrote:
> > Hi,
> >
> > On 27/5/24 10:02, Jamin Lin wrote:
> >> AST2700 fmc/spi controller's address decoding unit is 64KB and only
> >> bits [31:16] are used for decoding. Introduce seg_to_reg and
> >> reg_to_seg handlers for ast2700 fmc/spi controller.
> >> In addition, adds ast2700 fmc, spi0, spi1, and spi2 class init handler.
> >>
> >> Signed-off-by: Troy Lee 
> >> Signed-off-by: Jamin Lin 
> >> Reviewed-by: Cédric Le Goater 
> >> ---
> >>   hw/ssi/aspeed_smc.c | 222
> >> +++-
> >>   1 file changed, 220 insertions(+), 2 deletions(-)
> >>
> >> diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c index
> >> df0c63469c..b4006c8339 100644
> >> --- a/hw/ssi/aspeed_smc.c
> >> +++ b/hw/ssi/aspeed_smc.c
> >> @@ -185,7 +185,7 @@
> >>    *   0: 4 bytes
> >>    *   0x1FC: 32M bytes
> >>    *
> >> - * DMA length is from 1 byte to 32MB (AST2600, AST10x0)
> >> + * DMA length is from 1 byte to 32MB (AST2600, AST10x0 and AST2700)
> >>    *   0: 1 byte
> >>    *   0x1FF: 32M bytes
> >>    */
> >> @@ -670,7 +670,7 @@ static const MemoryRegionOps
> aspeed_smc_flash_ops
> >> = {
> >>   .endianness = DEVICE_LITTLE_ENDIAN,
> >>   .valid = {
> >>   .min_access_size = 1,
> >> -    .max_access_size = 4,
> >> +    .max_access_size = 8,
> >
> > Is this a bugfix? If so, please use a separate patch. Otherwise please
> > mention why it is OK to widen access for AST2600 & AST10x0.
> 
According the design of SPI drivers, it uses this "memcpy_fromio" KERNEL API 
for SPI calibration.
https://github.com/AspeedTech-BMC/linux/blob/1062a07420f9aed4ed7dc9deb3429b8e7828f5cf/drivers/spi/spi-aspeed-smc.c#L1832
 
AST2700 is a 64 bits quad core cpus(Cortex-a35), so kernel API use 64 bits for 
data access.
https://github.com/AspeedTech-BMC/linux/blob/aspeed-master-v6.6/arch/arm64/kernel/io.c#L25
 
I simply set the max_access_size to 8 for AST2700 support.
AST2500, AST2600 and AST10x0 are all 32bits CPUS, that was why this 
max_access_size 8 did not impact these models.
https://github.com/AspeedTech-BMC/linux/blob/aspeed-master-v6.6/arch/arm/kernel/io.c#L45
 

If you have any suggestion about this patch modification, please let me know.
I am going to re-send v5 patch for AST2700 support.
Thanks-Jamin

> Ah I missed that. I wonder how we could set different access width tough on
> the model ?
> 
> Should we allocate a MemoryRegionOps in the realize() handler and set the
> width depending on the SoC ?
> 
> 
> Thanks,
> 
> C.
> 
> 
> 



RE: [PATCH v4 11/16] aspeed/intc: Add AST2700 support

2024-06-02 Thread Jamin Lin
Hi Cedric,

> From: Cédric Le Goater 
> Subject: Re: [PATCH v4 11/16] aspeed/intc: Add AST2700 support
> 
> On 5/27/24 10:02, Jamin Lin wrote:
> > AST2700 interrupt controller(INTC) provides hardware interrupt
> > interfaces to interrupt of processors PSP, SSP and TSP. In INTC, each
> > interrupt of INT 128 to INT136 combines 32 interrupts.
> >
> > Introduce a new aspeed_intc class with instance_init and realize handlers.
> >
> > So far, this model only supports GICINT128 to GICINT136.
> > It creates 9 GICINT or-gates to connect 32 interrupts sources from
> > GICINT128 to GICINT136 as IRQ GPIO-OUTPUT pins.
> > Then, this model registers IRQ handler with its IRQ GPIO-INPUT pins
> > which connect to GICINT or-gates. And creates 9 GICINT IRQ GPIO-OUTPUT
> > pins which connect to GIC device with GIC IRQ 128 to 136.
> >
> > If one interrupt source from GICINT128 to GICINT136 set irq, the
> > OR-GATE irq callback function is called and set irq to INTC by OR-GATE
> > GPIO-OUTPUT pins. Then, the INTC irq callback function is called and
> > set irq to GIC by its GICINT IRQ GPIO-OUTPUT pins. Finally, the GIC
> > irq callback function is called and set irq to CPUs and CPUs execute
> > Interrupt Service Routine (ISR).
> >
> > Block diagram of GICINT132:
> >
> >  GICINT132
> >ETH1+---+
> > +>+0 3|
> >ETH2|  4|
> > +>+1 5|
> >ETH3|  6|
> > +>+219|  INTC
> GIC
> >UART0   | 20|+--+
> > +>+721||  |
> +--+
> >UART1   | 22||orgate0 +>
> output_pin0+--->+GIC128|
> > +>+823||  |
> |  |
> >UART2   | 24||orgate1 +>
> output_pin1+--->+GIC129|
> > +>+925||  |
> |  |
> >UART3   | 26||orgate2 +>
> output_pin2+--->+GIC130|
> > +->10   27||  |
> |  |
> >UART5   | 28||orgate3 +>
> output_pin3+--->+GIC131|
> > +>+11   29||  |
> |  |
> >UART6   |   +--->+orgate4 +>
> output_pin4+--->+GIC132|
> > +>+12   30||  |
> |  |
> >UART7   | 31||orgate5 +>
> output_pin5+--->+GIC133|
> > +>+13 ||  |
> |  |
> >UART8   |  OR[0:31] ||orgate6 +>
> output_pin6+--->+GIC134|
> > -->14 ||  |
> |  |
> >UART9   |   ||orgate7 +>
> output_pin7+--->+GIC135|
> > ->+15 ||  |
> |  |
> >UART10  |   ||orgate8 +>
> output_pin8+--->+GIC136|
> > ->+16 ||  |
> +--+
> >UART11  |   |+--+
> > +>+17 |
> >UART12  |   |
> > +->18 |
> >|   |
> >|   |
> >|   |
> >+---+
> >
> > Signed-off-by: Troy Lee 
> > Signed-off-by: Jamin Lin 
> > ---
> >   hw/intc/aspeed_intc.c | 355
> ++
> >   hw/intc/meson.build   |   1 +
> >   hw/intc/trace-events  |   6 +
> >   include/hw/intc/aspeed_intc.h |  46 +
> >   4 files changed, 408 insertions(+)
> >   create mode 100644 hw/intc/aspeed_intc.c
> >   create mode 100644 include/hw/intc/aspeed_intc.h
> >
> > diff --git a/hw/intc/aspeed_intc.c b/hw/intc/aspeed_intc.c new file
> > mode 100644 index 00..cb6111d79c
> > --- /dev/null
> > +++ b/hw/intc/aspeed_intc.c
> > @@ -0,0 +1,355 @@
> > +/*
> > + * ASPEED INTC Controller
> > + *
> > + * Copyright (C) 2024 ASPEED Technology Inc.
> > + *
> 

RE: [PATCH v4 12/16] aspeed/soc: Add AST2700 support

2024-05-31 Thread Jamin Lin
Hi Cedric,

> From: Cédric Le Goater 
> On 5/27/24 10:02, Jamin Lin wrote:
> > Initial definitions for a simple machine using an AST2700 SOC (Cortex-a35
> CPU).
> >
> > AST2700 SOC and its interrupt controller are too complex to handle in
> > the common Aspeed SoC framework. We introduce a new ast2700 class with
> > instance_init and realize handlers.
> >
> > AST2700 is a 64 bits quad core cpus and support 8 watchdog.
> > Update maximum ASPEED_CPUS_NUM to 4 and ASPEED_WDTS_NUM to 8.
> > In addition, update AspeedSocState to support scuio, sli, sliio and intc.
> >
> > Add TYPE_ASPEED27X0_SOC machine type.
> >
> > The SDMC controller is unlocked at SPL stage.
> > At present, only supports to emulate booting start from u-boot stage.
> > Set SDMC controller unlocked by default.
> >
> > In INTC, each interrupt of INT 128 to INT 136 combines 32 interrupts.
> > It connect GICINT IRQ GPIO-OUTPUT pins to GIC device with irq 128 to 136.
> > And, if a device irq is 128 to 136, its irq GPIO-OUTPUT pin is
> > connected to GICINT or-gates instead of GIC device.
> >
> > Signed-off-by: Troy Lee 
> > Signed-off-by: Jamin Lin 
> > ---
> >   hw/arm/aspeed_ast27x0.c | 563
> 
> >   hw/arm/meson.build  |   1 +
> >   include/hw/arm/aspeed_soc.h |  26 +-
> >   3 files changed, 588 insertions(+), 2 deletions(-)
> >   create mode 100644 hw/arm/aspeed_ast27x0.c
> >
> > diff --git a/hw/arm/aspeed_ast27x0.c b/hw/arm/aspeed_ast27x0.c new
> > file mode 100644 index 00..a3a03fc1ca
> > --- /dev/null
> > +++ b/hw/arm/aspeed_ast27x0.c
> > @@ -0,0 +1,563 @@
> > +/*
> > + * ASPEED SoC 27x0 family
> > + *
> > + * Copyright (C) 2024 ASPEED Technology Inc.
> > + *
> > + * This code is licensed under the GPL version 2 or later.  See
> > + * the COPYING file in the top-level directory.
> > + *
> > + * Implementation extracted from the AST2600 and adapted for AST27x0.
> > + */
> > +
> > +#include "qemu/osdep.h"
> > +#include "qapi/error.h"
> > +#include "hw/misc/unimp.h"
> > +#include "hw/arm/aspeed_soc.h"
> > +#include "qemu/module.h"
> > +#include "qemu/error-report.h"
> > +#include "hw/i2c/aspeed_i2c.h"
> > +#include "net/net.h"
> > +#include "sysemu/sysemu.h"
> > +#include "hw/intc/arm_gicv3.h"
> > +#include "qapi/qmp/qlist.h"
> > +
> > +static const hwaddr aspeed_soc_ast2700_memmap[] = {
> > +[ASPEED_DEV_SPI_BOOT]  =  0x4,
> > +[ASPEED_DEV_SRAM]  =  0x1000,
> > +[ASPEED_DEV_SDMC]  =  0x12C0,
> > +[ASPEED_DEV_SCU]   =  0x12C02000,
> > +[ASPEED_DEV_SCUIO] =  0x14C02000,
> > +[ASPEED_DEV_UART0] =  0X14C33000,
> > +[ASPEED_DEV_UART1] =  0X14C33100,
> > +[ASPEED_DEV_UART2] =  0X14C33200,
> > +[ASPEED_DEV_UART3] =  0X14C33300,
> > +[ASPEED_DEV_UART4] =  0X12C1A000,
> > +[ASPEED_DEV_UART5] =  0X14C33400,
> > +[ASPEED_DEV_UART6] =  0X14C33500,
> > +[ASPEED_DEV_UART7] =  0X14C33600,
> > +[ASPEED_DEV_UART8] =  0X14C33700,
> > +[ASPEED_DEV_UART9] =  0X14C33800,
> > +[ASPEED_DEV_UART10]=  0X14C33900,
> > +[ASPEED_DEV_UART11]=  0X14C33A00,
> > +[ASPEED_DEV_UART12]=  0X14C33B00,
> > +[ASPEED_DEV_WDT]   =  0x14C37000,
> > +[ASPEED_DEV_VUART] =  0X14C3,
> > +[ASPEED_DEV_FMC]   =  0x1400,
> > +[ASPEED_DEV_SPI0]  =  0x1401,
> > +[ASPEED_DEV_SPI1]  =  0x1402,
> > +[ASPEED_DEV_SPI2]  =  0x1403,
> > +[ASPEED_DEV_SDRAM] =  0x4,
> > +[ASPEED_DEV_MII1]  =  0x1404,
> > +[ASPEED_DEV_MII2]  =  0x14040008,
> > +[ASPEED_DEV_MII3]  =  0x14040010,
> > +[ASPEED_DEV_ETH1]  =  0x1405,
> > +[ASPEED_DEV_ETH2]  =  0x1406,
> > +[ASPEED_DEV_ETH3]  =  0x1407,
> > +[ASPEED_DEV_EMMC]  =  0x1209,
> > +[ASPEED_DEV_INTC]  =  0x1210,
> > +[ASPEED_DEV_SLI]   =  0x12C17000,
> > +[ASPEED_DEV_SLIIO] =  0x14C1E000,
> > +[ASPEED_GIC_DIST]  =  0x1220,
> > +[ASPEED_GIC_REDIST]=  0x1228,
> > +};
> > +
> > +#define AST2700_MAX_IRQ 288
> > +
> > +/* Shared Peripheral Interrupt values below are offset by -32 from
> > +datasheet */ static c

RE: [PATCH v4 12/16] aspeed/soc: Add AST2700 support

2024-05-31 Thread Jamin Lin
Hi Cedric,

> From: Cédric Le Goater 
> Subject: Re: [PATCH v4 12/16] aspeed/soc: Add AST2700 support
> 
> 
> Hello Jamin,
> > I refer to versal_create_apu_gic function,
> https://github.com/qemu/qemu/blob/master/hw/arm/xlnx-versal.c#L67
> > and updated aspeed_soc_ast2700_gic as following.
> > If you have any concerned about the new changes, please let me know.
> > Thanks-Jamin
> >
> > static bool aspeed_soc_ast2700_gic(DeviceState *dev, Error **errp)
> 
> Please rename to aspeed_soc_ast2700_gic_realize()
Will fix in v5 patch
> 
> > {
> >  Aspeed27x0SoCState *a = ASPEED27X0_SOC(dev);
> >  AspeedSoCState *s = ASPEED_SOC(dev);
> >  AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
> >  SysBusDevice *gicbusdev;
> >  DeviceState *gicdev;
> >  QList *redist_region_count;
> >  int i;
> >
> >  object_initialize_child(OBJECT(a), "ast2700-gic", >gic,
> >  gicv3_class_name());
> 
> and object_initialize_child() can be called in aspeed_soc_ast2700_init().
Will fix in v5 patch

My new changes as following,
static void aspeed_soc_ast2700_init(Object *obj) {
--
object_initialize_child(obj, "gic", >gic, gicv3_class_name());
--
}

> 
> >  gicbusdev = SYS_BUS_DEVICE(>gic);
> >  gicdev = DEVICE(>gic);
> >  qdev_prop_set_uint32(gicdev, "revision", 3);
> >  qdev_prop_set_uint32(gicdev, "num-cpu", sc->num_cpus);
> >  qdev_prop_set_uint32(gicdev, "num-irq", AST2700_MAX_IRQ);
> >
> >  redist_region_count = qlist_new();
> >  qlist_append_int(redist_region_count, sc->num_cpus);
> >  qdev_prop_set_array(gicdev, "redist-region-count",
> redist_region_count);
> >
> >  if (!sysbus_realize(gicbusdev, errp)) {
> >  return false;
> >  }
> >  sysbus_mmio_map(gicbusdev, 0, sc->memmap[ASPEED_GIC_DIST]);
> >  sysbus_mmio_map(gicbusdev, 1,
> sc->memmap[ASPEED_GIC_REDIST]);
> >
> >  for (i = 0; i < sc->num_cpus; i++) {
> >  DeviceState *cpudev = DEVICE(qemu_get_cpu(i));
> 
> Could we avoid qemu_get_cpu() and use the cpu array of the SoC instead ?
Yes, I can change it and my new changes as following.
  DeviceState *cpudev = DEVICE(>cpu[i]);
Will fix in v5 patch.

Thanks for review.
Jamin

> 
> >  int NUM_IRQS = 256, ARCH_GIC_MAINT_IRQ = 9,
> VIRTUAL_PMU_IRQ = 7;
> >  int ppibase = NUM_IRQS + i * GIC_INTERNAL + GIC_NR_SGIS;
> >
> >  const int timer_irq[] = {
> >  [GTIMER_PHYS] = 14,
> >  [GTIMER_VIRT] = 11,
> >  [GTIMER_HYP]  = 10,
> >  [GTIMER_SEC]  = 13,
> >  };
> >  int j;
> >
> >  for (j = 0; j < ARRAY_SIZE(timer_irq); j++) {
> >  qdev_connect_gpio_out(cpudev, j,
> >  qdev_get_gpio_in(gicdev, ppibase + timer_irq[j]));
> >  }
> >
> >  qemu_irq irq = qdev_get_gpio_in(gicdev,
> >  ppibase +
> ARCH_GIC_MAINT_IRQ);
> >  qdev_connect_gpio_out_named(cpudev,
> "gicv3-maintenance-interrupt",
> >  0, irq);
> >  qdev_connect_gpio_out_named(cpudev, "pmu-interrupt", 0,
> >  qdev_get_gpio_in(gicdev, ppibase +
> VIRTUAL_PMU_IRQ));
> >
> >  sysbus_connect_irq(gicbusdev, i, qdev_get_gpio_in(cpudev,
> ARM_CPU_IRQ));
> >  sysbus_connect_irq(gicbusdev, i + sc->num_cpus,
> > qdev_get_gpio_in(cpudev,
> ARM_CPU_FIQ));
> >  sysbus_connect_irq(gicbusdev, i + 2 * sc->num_cpus,
> > qdev_get_gpio_in(cpudev,
> ARM_CPU_VIRQ));
> >  sysbus_connect_irq(gicbusdev, i + 3 * sc->num_cpus,
> > qdev_get_gpio_in(cpudev,
> ARM_CPU_VFIQ));
> >  }
> >
> >  return true;
> > }
> >
> > struct Aspeed27x0SoCState {
> >  AspeedSoCState parent;
> >
> >  ARMCPU cpu[ASPEED_CPUS_NUM];
> >  AspeedINTCState intc;
> >  GICv3State gic;
> > };
> >
> > #define TYPE_ASPEED27X0_SOC "aspeed27x0-soc"
> > OBJECT_DECLARE_SIMPLE_TYPE(Aspeed27x0SoCState, ASPEED27X0_SOC)
> 
> Thanks,
> 
> C.
> 
> 



RE: [PATCH v4 12/16] aspeed/soc: Add AST2700 support

2024-05-30 Thread Jamin Lin
Hi Cedric,

> From: Cédric Le Goater 
> Subject: Re: [PATCH v4 12/16] aspeed/soc: Add AST2700 support
> 
> On 5/27/24 10:02, Jamin Lin wrote:
> > Initial definitions for a simple machine using an AST2700 SOC (Cortex-a35
> CPU).
> >
> > AST2700 SOC and its interrupt controller are too complex to handle in
> > the common Aspeed SoC framework. We introduce a new ast2700 class with
> > instance_init and realize handlers.
> >
> > AST2700 is a 64 bits quad core cpus and support 8 watchdog.
> > Update maximum ASPEED_CPUS_NUM to 4 and ASPEED_WDTS_NUM to 8.
> > In addition, update AspeedSocState to support scuio, sli, sliio and intc.
> >
> > Add TYPE_ASPEED27X0_SOC machine type.
> >
> > The SDMC controller is unlocked at SPL stage.
> > At present, only supports to emulate booting start from u-boot stage.
> > Set SDMC controller unlocked by default.
> >
> > In INTC, each interrupt of INT 128 to INT 136 combines 32 interrupts.
> > It connect GICINT IRQ GPIO-OUTPUT pins to GIC device with irq 128 to 136.
> > And, if a device irq is 128 to 136, its irq GPIO-OUTPUT pin is
> > connected to GICINT or-gates instead of GIC device.
> >
> > Signed-off-by: Troy Lee 
> > Signed-off-by: Jamin Lin 
> > ---
> >   hw/arm/aspeed_ast27x0.c | 563
> 
> >   hw/arm/meson.build  |   1 +
> >   include/hw/arm/aspeed_soc.h |  26 +-
> >   3 files changed, 588 insertions(+), 2 deletions(-)
> >   create mode 100644 hw/arm/aspeed_ast27x0.c
> >
> > diff --git a/hw/arm/aspeed_ast27x0.c b/hw/arm/aspeed_ast27x0.c new
> > file mode 100644 index 00..a3a03fc1ca
> > --- /dev/null
> > +++ b/hw/arm/aspeed_ast27x0.c
> > @@ -0,0 +1,563 @@
> > +/*
> > + * ASPEED SoC 27x0 family
> > + *
> > + * Copyright (C) 2024 ASPEED Technology Inc.
> > + *
> > + * This code is licensed under the GPL version 2 or later.  See
> > + * the COPYING file in the top-level directory.
> > + *
> > + * Implementation extracted from the AST2600 and adapted for AST27x0.
> > + */
> > +
> > +#include "qemu/osdep.h"
> > +#include "qapi/error.h"
> > +#include "hw/misc/unimp.h"
> > +#include "hw/arm/aspeed_soc.h"
> > +#include "qemu/module.h"
> > +#include "qemu/error-report.h"
> > +#include "hw/i2c/aspeed_i2c.h"
> > +#include "net/net.h"
> > +#include "sysemu/sysemu.h"
> > +#include "hw/intc/arm_gicv3.h"
> > +#include "qapi/qmp/qlist.h"
> > +
> > +static const hwaddr aspeed_soc_ast2700_memmap[] = {
> > +[ASPEED_DEV_SPI_BOOT]  =  0x4,
> > +[ASPEED_DEV_SRAM]  =  0x1000,
> > +[ASPEED_DEV_SDMC]  =  0x12C0,
> > +[ASPEED_DEV_SCU]   =  0x12C02000,
> > +[ASPEED_DEV_SCUIO] =  0x14C02000,
> > +[ASPEED_DEV_UART0] =  0X14C33000,
> > +[ASPEED_DEV_UART1] =  0X14C33100,
> > +[ASPEED_DEV_UART2] =  0X14C33200,
> > +[ASPEED_DEV_UART3] =  0X14C33300,
> > +[ASPEED_DEV_UART4] =  0X12C1A000,
> > +[ASPEED_DEV_UART5] =  0X14C33400,
> > +[ASPEED_DEV_UART6] =  0X14C33500,
> > +[ASPEED_DEV_UART7] =  0X14C33600,
> > +[ASPEED_DEV_UART8] =  0X14C33700,
> > +[ASPEED_DEV_UART9] =  0X14C33800,
> > +[ASPEED_DEV_UART10]=  0X14C33900,
> > +[ASPEED_DEV_UART11]=  0X14C33A00,
> > +[ASPEED_DEV_UART12]=  0X14C33B00,
> > +[ASPEED_DEV_WDT]   =  0x14C37000,
> > +[ASPEED_DEV_VUART] =  0X14C3,
> > +[ASPEED_DEV_FMC]   =  0x1400,
> > +[ASPEED_DEV_SPI0]  =  0x1401,
> > +[ASPEED_DEV_SPI1]  =  0x1402,
> > +[ASPEED_DEV_SPI2]  =  0x1403,
> > +[ASPEED_DEV_SDRAM] =  0x4,
> > +[ASPEED_DEV_MII1]  =  0x1404,
> > +[ASPEED_DEV_MII2]  =  0x14040008,
> > +[ASPEED_DEV_MII3]  =  0x14040010,
> > +[ASPEED_DEV_ETH1]  =  0x1405,
> > +[ASPEED_DEV_ETH2]  =  0x1406,
> > +[ASPEED_DEV_ETH3]  =  0x1407,
> > +[ASPEED_DEV_EMMC]  =  0x1209,
> > +[ASPEED_DEV_INTC]  =  0x1210,
> > +[ASPEED_DEV_SLI]   =  0x12C17000,
> > +[ASPEED_DEV_SLIIO] =  0x14C1E000,
> > +[ASPEED_GIC_DIST]  =  0x1220,
> > +[ASPEED_GIC_REDIST]=  0x1228,
> > +};
> > +
> > +#define AST2700_MAX_IRQ 288
> > +
> > +/* Shared Peripheral Interrupt values below

RE: [PATCH v4 14/16] aspeed/soc: fix incorrect dram size for AST2700

2024-05-30 Thread Jamin Lin
Hi Cedric, 
> From: Cédric Le Goater 
> On 5/30/24 09:42, Jamin Lin wrote:
> > Hi Cedric,
> >> From: Cédric Le Goater > Hello Jamin
> >>
> >> On 5/27/24 10:02, Jamin Lin wrote:
> >>> AST2700 dram size calculation is not back compatible AST2600.
> >>> According to the DDR capacity hardware behavior, if users write the
> >>> data to address which is beyond the ram size, it would write the
> >>> data to address 0.
> >>> For example:
> >>> a. sdram base address "0x4 "
> >>> b. sdram size is 1 GiB
> >>> The available address range is from "0x4 " to "0x4 4000".
> >>> If users write 0xdeadbeef to address "0x6 ", the value of
> >>> DRAM address 0 (base address 0x4 ) should be 0xdeadbeef.
> >>>
> >>> Add aspeed_soc_ast2700_dram_init to calculate the dram size and add
> >>> memory I/O whose address range is from max_ram_size - ram_size to
> >>> max_ram_size and its read/write handler to emulate DDR capacity
> >>> hardware
> >> behavior.
> >>>
> >>> Signed-off-by: Troy Lee 
> >>> Signed-off-by: Jamin Lin 
> >>> ---
> >>>hw/arm/aspeed_ast27x0.c | 94
> >> -
> >>>include/hw/arm/aspeed_soc.h |  1 +
> >>>2 files changed, 94 insertions(+), 1 deletion(-)
> >>>
> >>> diff --git a/hw/arm/aspeed_ast27x0.c b/hw/arm/aspeed_ast27x0.c index
> >>> a3a03fc1ca..19380087fa 100644
> >>> --- a/hw/arm/aspeed_ast27x0.c
> >>> +++ b/hw/arm/aspeed_ast27x0.c
> >>> @@ -20,6 +20,7 @@
> >>>#include "sysemu/sysemu.h"
> >>>#include "hw/intc/arm_gicv3.h"
> >>>#include "qapi/qmp/qlist.h"
> >>> +#include "qemu/log.h"
> >>>
> >>>static const hwaddr aspeed_soc_ast2700_memmap[] = {
> >>>[ASPEED_DEV_SPI_BOOT]  =  0x4, @@ -191,6
> +192,97
> >> @@
> >>> static qemu_irq aspeed_soc_ast2700_get_irq(AspeedSoCState *s, int dev)
> >>>return qdev_get_gpio_in(a->intc.gic, sc->irqmap[dev]);
> >>>}
> >>>
> >>> +static uint64_t aspeed_ram_capacity_read(void *opaque, hwaddr addr,
> >>> +unsigned
> >> int
> >>> +size) {
> >>> +qemu_log_mask(LOG_GUEST_ERROR,
> >>> +  "%s: read @%" PRIx64 " out of ram size\n",
> >>> +   __func__, addr);
> >>> +return 0;
> >>> +}
> >>> +
> >>> +static void aspeed_ram_capacity_write(void *opaque, hwaddr addr,
> >> uint64_t data,
> >>> +unsigned int
> size)
> >> {
> >>> +AspeedSoCState *s = ASPEED_SOC(opaque);
> >>> +uint32_t test_pattern = 0xdeadbeef;
> >>> +bool invalid_pattern = true;
> >>> +uint32_t *ram_ptr;
> >>> +int sz;
> >>> +
> >>> +ram_ptr = memory_region_get_ram_ptr(s->dram_mr);
> >>> +
> >>> +   /*
> >>> +* Emulate ddr capacity hardware behavior.
> >>> +* If writes the test_pattern to address which is beyond the ram size,
> >>> +* it would write the test_pattern to address 0.
> >>> +*/
> >>> +for (sz = 4; sz > 0 ; sz--) {
> >>> +test_pattern = (test_pattern << 4) + sz;
> >>> +if (data == test_pattern) {
> >>> +ram_ptr[0] = test_pattern;
> >>> +invalid_pattern = false;
> >>> +break;
> >>> +}
> >>> +}
> >>> +
> >>> +if (invalid_pattern) {
> >>> +qemu_log_mask(LOG_GUEST_ERROR,
> >>> +  "%s: write invalid pattern @%" PRIx64
> >>> +  " to addr @%" HWADDR_PRIx "]\n",
> >>> +  __func__, data, addr);
> >>> +}
> >>> +}
> >>
> >>
> >> I would simplify with write transaction on the DRAM memory region of
> >> the SoC.
> >>
> >> For that, initialize a 'dram_as' on top of 'dram_mr' in
> >> aspeed_soc_ast2700_dram_init():
> >>
>

RE: [PATCH v4 14/16] aspeed/soc: fix incorrect dram size for AST2700

2024-05-30 Thread Jamin Lin
Hi Cedric, 
> From: Cédric Le Goater > 
> Hello Jamin
> 
> On 5/27/24 10:02, Jamin Lin wrote:
> > AST2700 dram size calculation is not back compatible AST2600.
> > According to the DDR capacity hardware behavior, if users write the
> > data to address which is beyond the ram size, it would write the data
> > to address 0.
> > For example:
> > a. sdram base address "0x4 "
> > b. sdram size is 1 GiB
> > The available address range is from "0x4 " to "0x4 4000".
> > If users write 0xdeadbeef to address "0x6 ", the value of DRAM
> > address 0 (base address 0x4 ) should be 0xdeadbeef.
> >
> > Add aspeed_soc_ast2700_dram_init to calculate the dram size and add
> > memory I/O whose address range is from max_ram_size - ram_size to
> > max_ram_size and its read/write handler to emulate DDR capacity hardware
> behavior.
> >
> > Signed-off-by: Troy Lee 
> > Signed-off-by: Jamin Lin 
> > ---
> >   hw/arm/aspeed_ast27x0.c | 94
> -
> >   include/hw/arm/aspeed_soc.h |  1 +
> >   2 files changed, 94 insertions(+), 1 deletion(-)
> >
> > diff --git a/hw/arm/aspeed_ast27x0.c b/hw/arm/aspeed_ast27x0.c index
> > a3a03fc1ca..19380087fa 100644
> > --- a/hw/arm/aspeed_ast27x0.c
> > +++ b/hw/arm/aspeed_ast27x0.c
> > @@ -20,6 +20,7 @@
> >   #include "sysemu/sysemu.h"
> >   #include "hw/intc/arm_gicv3.h"
> >   #include "qapi/qmp/qlist.h"
> > +#include "qemu/log.h"
> >
> >   static const hwaddr aspeed_soc_ast2700_memmap[] = {
> >   [ASPEED_DEV_SPI_BOOT]  =  0x4, @@ -191,6 +192,97
> @@
> > static qemu_irq aspeed_soc_ast2700_get_irq(AspeedSoCState *s, int dev)
> >   return qdev_get_gpio_in(a->intc.gic, sc->irqmap[dev]);
> >   }
> >
> > +static uint64_t aspeed_ram_capacity_read(void *opaque, hwaddr addr,
> > +unsigned
> int
> > +size) {
> > +qemu_log_mask(LOG_GUEST_ERROR,
> > +  "%s: read @%" PRIx64 " out of ram size\n",
> > +   __func__, addr);
> > +return 0;
> > +}
> > +
> > +static void aspeed_ram_capacity_write(void *opaque, hwaddr addr,
> uint64_t data,
> > +unsigned int size)
> {
> > +AspeedSoCState *s = ASPEED_SOC(opaque);
> > +uint32_t test_pattern = 0xdeadbeef;
> > +bool invalid_pattern = true;
> > +uint32_t *ram_ptr;
> > +int sz;
> > +
> > +ram_ptr = memory_region_get_ram_ptr(s->dram_mr);
> > +
> > +   /*
> > +* Emulate ddr capacity hardware behavior.
> > +* If writes the test_pattern to address which is beyond the ram size,
> > +* it would write the test_pattern to address 0.
> > +*/
> > +for (sz = 4; sz > 0 ; sz--) {
> > +test_pattern = (test_pattern << 4) + sz;
> > +if (data == test_pattern) {
> > +ram_ptr[0] = test_pattern;
> > +invalid_pattern = false;
> > +break;
> > +}
> > +}
> > +
> > +if (invalid_pattern) {
> > +qemu_log_mask(LOG_GUEST_ERROR,
> > +  "%s: write invalid pattern @%" PRIx64
> > +  " to addr @%" HWADDR_PRIx "]\n",
> > +  __func__, data, addr);
> > +}
> > +}
> 
> 
> I would simplify with write transaction on the DRAM memory region of the
> SoC.
> 
> For that, initialize a 'dram_as' on top of 'dram_mr' in
> aspeed_soc_ast2700_dram_init():
> 
> address_space_init(>dram_as, s->dram_mr, "dram");
> 
> Then, in aspeed_ram_capacity_write(), add :
> 
>address_space_write(>dram_as, addr % ram_size,
> MEMTXATTRS_UNSPECIFIED,
>   , size);
> 
> and check returned error.
> 
> It should be enough to detect the RAM size from FW.
> 
> 
> Thanks,
> 
> C.
> 
Thanks for your suggestion and review.
I changed to use address space APIs to write DRAM memory region(s->dram_mr).
I have a question about aspeed_ram_capacity_write function implementation.
Could you tell me which solution you prefer? Do you want to use solution 1?
Thanks-Jamin

Solution 1:
static void aspeed_ram_capacity_write(void *opaque, hwaddr addr, uint64_t data,
unsigned int size)
{
AspeedSoCState *s = ASPEED_SOC(opaque);
ram_ad

RE: [PATCH v4 00/16] Add AST2700 support

2024-05-28 Thread Jamin Lin
Hi Cedric,

> From: Cédric Le Goater 
> On 5/28/24 12:02, Jamin Lin wrote:
> > Hi Cedric,
> >
> >> -Original Message-
> >> From: Cédric Le Goater 
> >> Sent: Tuesday, May 28, 2024 5:56 PM
> >> To: Jamin Lin ; Peter Maydell
> >> ; Andrew Jeffery
> >> ; Joel Stanley ;
> >> Alistair Francis ; Cleber Rosa
> >> ; Philippe Mathieu-Daudé ;
> >> Wainer dos Santos Moschetta ; Beraldo Leal
> >> ; open list:ASPEED BMCs ;
> open
> >> list:All patches CC here 
> >> Cc: Troy Lee ; Yunlin Tang
> >> 
> >> Subject: Re: [PATCH v4 00/16] Add AST2700 support
> >>
> >> Jamin,
> >>
> >> I think you should add your self as a Reviewer to the ASPEED BMCs
> >> machine in the MAINTAINERS files. Would you agree ?
> >>
> > Agree.
> >
> > Could you please add me, Troy and Steven in the MAINTAINERS files?
> > steven_...@aspeedtech.com
> > troy_...@aspeedtech.com
> > jamin_...@aspeedtech.com
> 
> You should send a patch updating the MAINTAINERS file with new names and
> those promoted should reply that they agree, or not.
> 
> See https://qemu.readthedocs.io/en/v9.0.0/devel/maintainers.html for more
> info and the git history of MAINTAINERS also.
> 
Will send a patch to updating the MAINTAINERS file.
Thanks-Jamin
> Thanks,
> 
> C.
> 



RE: [PATCH v4 00/16] Add AST2700 support

2024-05-28 Thread Jamin Lin
Hi Cedric,

> -Original Message-
> From: Cédric Le Goater 
> Sent: Tuesday, May 28, 2024 5:56 PM
> To: Jamin Lin ; Peter Maydell
> ; Andrew Jeffery ;
> Joel Stanley ; Alistair Francis ; 
> Cleber
> Rosa ; Philippe Mathieu-Daudé ;
> Wainer dos Santos Moschetta ; Beraldo Leal
> ; open list:ASPEED BMCs ; open
> list:All patches CC here 
> Cc: Troy Lee ; Yunlin Tang
> 
> Subject: Re: [PATCH v4 00/16] Add AST2700 support
> 
> Jamin,
> 
> I think you should add your self as a Reviewer to the ASPEED BMCs machine in
> the MAINTAINERS files. Would you agree ?
> 
Agree.

Could you please add me, Troy and Steven in the MAINTAINERS files?
steven_...@aspeedtech.com
troy_...@aspeedtech.com
jamin_...@aspeedtech.com

Thanks-Jamin

> Thanks,
> 
> C.
> 
> 
> 
> On 5/27/24 10:02, Jamin Lin wrote:
> > Changes from v1:
> > The patch series supports WDT, SDMC, SMC, SCU, SLI and INTC for AST2700
> SoC.
> >
> > Changes from v2:
> > - replace is_aarch64 with is_bus64bit for sdmc patch review.
> > - fix incorrect dram size for AST2700
> >
> > Changes from v3:
> > - Add AST2700 Evaluation board in ASPEED document
> > - Add avocado test cases for AST2700 Evaluation board
> > - Fix reviewers review issues and add reviewers suggestions
> > - Implement INTC model GICINT 128 to GICINT136 for AST2700
> >
> > Changes from v4:
> > - support 64 bits dma dram address associated with review issues
> > - support dma start length and 1 byte length unit associated with
> > review issues
> > - refactor intc model to fix serial console stuck issue and associated
> > with review issues
> >
> > Test Version:
> >
> https://github.com/qemu/qemu/commit/0c2a3807483b4ebe360cfa475dbfc9df
> d2
> > f6d16d
> >
> > Test steps:
> > 1. Download the latest openbmc image for AST2700 from
> AspeedTech-BMC/openbmc
> > repository,
> https://github.com/AspeedTech-BMC/openbmc/releases/tag/v09.01
> > link:
> >
> https://github.com/AspeedTech-BMC/openbmc/releases/download/v09.01/ast
> > 2700-default-obmc.tar.gz
> > 2. untar ast2700-default-obmc.tar.gz
> > ```
> > tar -xf ast2700-default-obmc.tar.gz
> > ```
> > 3. Run and the contents of scripts as following IMGDIR=ast2700-default
> > UBOOT_SIZE=$(stat --format=%s -L ${IMGDIR}/u-boot-nodtb.bin)
> > UBOOT_DTB_ADDR=$((0x4 + ${UBOOT_SIZE}))
> >
> > qemu-system-aarch64 -M ast2700-evb -nographic\
> >   -device
> loader,addr=0x4,file=${IMGDIR}/u-boot-nodtb.bin,force-raw=on\
> >   -device
> loader,addr=${UBOOT_DTB_ADDR},file=${IMGDIR}/u-boot.dtb,force-raw=on\
> >   -device loader,addr=0x43000,file=${IMGDIR}/bl31.bin,force-raw=on\
> >   -device
> loader,addr=0x430080000,file=${IMGDIR}/optee/tee-raw.bin,force-raw=on\
> >   -device loader,addr=0x43000,cpu-num=0\
> >   -device loader,addr=0x43000,cpu-num=1\
> >   -device loader,addr=0x43000,cpu-num=2\
> >   -device loader,addr=0x43000,cpu-num=3\
> >   -smp 4\
> >   -drive file=${IMGDIR}/image-bmc,format=raw,if=mtd\
> >   -serial mon:stdio\
> >   -snapshot
> >
> > Jamin Lin (16):
> >aspeed/wdt: Add AST2700 support
> >aspeed/sli: Add AST2700 support
> >aspeed/sdmc: remove redundant macros
> >aspeed/sdmc: fix coding style
> >aspeed/sdmc: Add AST2700 support
> >aspeed/smc: correct device description
> >aspeed/smc: support dma start length and 1 byte length unit
> >aspeed/smc: support 64 bits dma dram address
> >aspeed/smc: Add AST2700 support
> >aspeed/scu: Add AST2700 support
> >aspeed/intc: Add AST2700 support
> >aspeed/soc: Add AST2700 support
> >aspeed: Add an AST2700 eval board
> >aspeed/soc: fix incorrect dram size for AST2700
> >test/avocado/machine_aspeed.py: Add AST2700 test case
> >docs:aspeed: Add AST2700 Evaluation board
> >
> >   docs/system/arm/aspeed.rst   |  39 +-
> >   hw/arm/aspeed.c  |  32 ++
> >   hw/arm/aspeed_ast27x0.c  | 655
> +++
> >   hw/arm/meson.build   |   1 +
> >   hw/intc/aspeed_intc.c| 355 +
> >   hw/intc/meson.build  |   1 +
> >   hw/intc/trace-events |   6 +
> >   hw/misc/aspeed_scu.c | 306 ++-
> >   hw/misc/aspeed_sdmc.c| 216 +-
> >   hw/misc/aspeed_sli.c | 177 +
> >   hw/misc/meson.build  |   3 +-
> >   hw/misc/trace-events |  1

RE: [PATCH v4 05/16] aspeed/sdmc: Add AST2700 support

2024-05-28 Thread Jamin Lin
Hi Cedric,
> From: Cédric Le Goater 
> [ ... ]
> 
> >> I don't think this is necessary to do so now. Possibly, increase the
> >> version number in the vmstate when resending a v5.
> >>
> > If I understand your request, do you mean to change as following in this
> patch?
> >
> > static const VMStateDescription vmstate_aspeed_sdmc = {
> >  .name = "aspeed.sdmc",
> >  .version_id = 1,  ---> Change 2
> >  .minimum_version_id = 1, ---> Change 2 };
> 
> yes.
> 
> 
> >> Also, all Aspeed models should be addressed and that's beyond the
> >> scope of this series.
> >>
> >
> > And create a new patch series to update all vmstate version for all ASPEED
> models?
> 
> That would be to remove migration support for Aspeed machines. For later.
> Let's address AST2700 first.
> 
> Thanks,
>
> C.
Will fix it in v5.
Thanks-Jamin


RE: [PATCH v4 05/16] aspeed/sdmc: Add AST2700 support

2024-05-28 Thread Jamin Lin
Hi Cedric,
> -Original Message-
> From: Cédric Le Goater 
> Sent: Tuesday, May 28, 2024 2:34 PM
> To: Jamin Lin ; Philippe Mathieu-Daudé
> ; Peter Maydell ; Andrew
> Jeffery ; Joel Stanley ;
> Alistair Francis ; Cleber Rosa ;
> Wainer dos Santos Moschetta ; Beraldo Leal
> ; open list:ASPEED BMCs ; open
> list:All patches CC here 
> Cc: Troy Lee ; Yunlin Tang
> 
> Subject: Re: [PATCH v4 05/16] aspeed/sdmc: Add AST2700 support
> 
> On 5/28/24 03:26, Jamin Lin wrote:
> > Hi Philippe, Cedric
> >
> >> On 27/5/24 13:18, Cédric Le Goater wrote:
> >>> On 5/27/24 12:24, Philippe Mathieu-Daudé wrote:
> >>>> Hi Jamin,
> >>>>
> >>>> On 27/5/24 10:02, Jamin Lin wrote:
> >>>>> The SDRAM memory controller(DRAMC) controls the access to external
> >>>>> DDR4 and DDR5 SDRAM and power up to DDR4 and DDR5 PHY.
> >>>>>
> >>>>> The DRAM memory controller of AST2700 is not backward compatible
> >>>>> to previous chips such AST2600, AST2500 and AST2400.
> >>>>>
> >>>>> Max memory is now 8GiB on the AST2700. Introduce new
> >>>>> aspeed_2700_sdmc and class with read/write operation and reset
> >>>>> handlers.
> >>>>>
> >>>>> Define DRAMC necessary protected registers and unprotected
> >>>>> registers for AST2700 and increase the register set to 0x1000.
> >>>>>
> >>>>> Add unlocked property to change controller protected status.
> >>>>>
> >>>>> Signed-off-by: Troy Lee 
> >>>>> Signed-off-by: Jamin Lin 
> >>>>> Reviewed-by: Cédric Le Goater 
> >>>>> ---
> >>>>>    hw/misc/aspeed_sdmc.c | 190
> >>>>> +-
> >>>>>    include/hw/misc/aspeed_sdmc.h |   5 +-
> >>>>>    2 files changed, 193 insertions(+), 2 deletions(-)
> >>>>
> >>>>
> >>>>> diff --git a/include/hw/misc/aspeed_sdmc.h
> >>>>> b/include/hw/misc/aspeed_sdmc.h index ec2d59a14f..61c979583a
> >>>>> 100644
> >>>>> --- a/include/hw/misc/aspeed_sdmc.h
> >>>>> +++ b/include/hw/misc/aspeed_sdmc.h
> >>>>> @@ -17,6 +17,7 @@ OBJECT_DECLARE_TYPE(AspeedSDMCState,
> >>>>> AspeedSDMCClass, ASPEED_SDMC)
> >>>>>    #define TYPE_ASPEED_2400_SDMC TYPE_ASPEED_SDMC
> "-ast2400"
> >>>>>    #define TYPE_ASPEED_2500_SDMC TYPE_ASPEED_SDMC
> "-ast2500"
> >>>>>    #define TYPE_ASPEED_2600_SDMC TYPE_ASPEED_SDMC
> "-ast2600"
> >>>>> +#define TYPE_ASPEED_2700_SDMC TYPE_ASPEED_SDMC "-ast2700"
> >>>>>    /*
> >>>>>     * SDMC has 174 documented registers. In addition the u-boot
> >>>>> device tree @@ -29,7 +30,7 @@
> >> OBJECT_DECLARE_TYPE(AspeedSDMCState,
> >>>>> AspeedSDMCClass, ASPEED_SDMC)
> >>>>>     * time, and the other is in the DDR-PHY IP which is used
> >>>>> during DDR-PHY
> >>>>>     * training.
> >>>>>     */
> >>>>> -#define ASPEED_SDMC_NR_REGS (0x500 >> 2)
> >>>>> +#define ASPEED_SDMC_NR_REGS (0x1000 >> 2)
> >>>>
> >>>> This change breaks the migration stream.
> >>>
> >>> Do you mean migration compat ? We never cared much about that for
> >>> the Aspeed machines.
> >>
> >> So let's just remove the VMSTATE to reduce code burden?
> >>
> >> Otherwise incrementing the vmstate.version is enough.
> >>
> >> Regards,
> >>
> >> Phil.
> > If you both okay, I will remove it.
> > Do I need to create a new patch or just update in this patch?
> 
> I don't think this is necessary to do so now. Possibly, increase the version
> number in the vmstate when resending a v5.
> 
If I understand your request, do you mean to change as following in this patch?

static const VMStateDescription vmstate_aspeed_sdmc = {
.name = "aspeed.sdmc",
.version_id = 1,  ---> Change 2
.minimum_version_id = 1, ---> Change 2
};
> Also, all Aspeed models should be addressed and that's beyond the scope of
> this series.
>

And create a new patch series to update all vmstate version for all ASPEED 
models?
Take asoeed_gpio.c for example:
static const VMStateDescription vmstate_gpio_regs = {
.name = TYPE_ASPEED_GPIO"/regs",
.version_id = 1, ---> Change 2
.minimum_version_id = 1, ---> Change --> 2
}

Thanks-Jamin
> 
> Thanks,
> 
> C.
> 



RE: [PATCH v4 08/16] aspeed/smc: support 64 bits dma dram address

2024-05-27 Thread Jamin Lin
Hi Philippe,

> Hi Jamin,
> 
> On 27/5/24 10:02, Jamin Lin wrote:
> > AST2700 support the maximum dram size is 8GiB and has a "DMA DRAM
> Side
> > Address High Part(0x7C)"
> > register to support 64 bits dma dram address.
> > Add helper routines functions to compute the dma dram address, new
> > features and update trace-event to support 64 bits dram address.
> >
> > Signed-off-by: Troy Lee 
> > Signed-off-by: Jamin Lin 
> > ---
> >   hw/ssi/aspeed_smc.c | 52
> +++--
> >   hw/ssi/trace-events |  2 +-
> >   include/hw/ssi/aspeed_smc.h |  1 +
> >   3 files changed, 46 insertions(+), 9 deletions(-)
> 
> 
> > +static uint64_t aspeed_smc_dma_dram_addr(AspeedSMCState *s) {
> > +return s->regs[R_DMA_DRAM_ADDR] |
> > +((uint64_t) s->regs[R_DMA_DRAM_ADDR_HIGH] << 32); }
> > +
> >   static uint32_t aspeed_smc_dma_len(AspeedSMCState *s)
> >   {
> >   AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s); @@ -903,24
> > +921,34 @@ static void aspeed_smc_dma_checksum(AspeedSMCState *s)
> >
> >   static void aspeed_smc_dma_rw(AspeedSMCState *s)
> >   {
> > +AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s);
> > +uint64_t dma_dram_offset;
> > +uint64_t dma_dram_addr;
> >   MemTxResult result;
> >   uint32_t dma_len;
> >   uint32_t data;
> >
> >   dma_len = aspeed_smc_dma_len(s);
> > +dma_dram_addr = aspeed_smc_dma_dram_addr(s);
> > +
> > +if (aspeed_smc_has_dma64(asc)) {
> > +dma_dram_offset = dma_dram_addr - s->dram_base;
> > +} else {
> > +dma_dram_offset = dma_dram_addr;
> 
> Here s->dram_base is 0x0. Do we really need to check
> aspeed_smc_has_dma64?
> 

Yes, it is required to check aspeed_smc_has_dma64 to support dram 64bit address.
s->dram_base has been changed to "0x4 ".
Thanks-Jamin

> > +}
> 
> Maybe simplify improving aspeed_smc_dma_dram_addr() as:
> 
>static uint64_t aspeed_smc_dma_dram_addr(AspeedSMCState *s)
>{
>return (s->regs[R_DMA_DRAM_ADDR]
>| ((uint64_t) s->regs[R_DMA_DRAM_ADDR_HIGH] << 32))
>- s->dram_base;
>}
> 
> Then no need for dma_dram_offset, dma_dram_addr is enough.
> 
> >
> >   trace_aspeed_smc_dma_rw(s->regs[R_DMA_CTRL] &
> DMA_CTRL_WRITE ?
> >   "write" : "read",
> >   s->regs[R_DMA_FLASH_ADDR],
> > -s->regs[R_DMA_DRAM_ADDR],
> > +dma_dram_offset,
> >   dma_len);
> >   while (dma_len) {
> >   if (s->regs[R_DMA_CTRL] & DMA_CTRL_WRITE) {
> > -data = address_space_ldl_le(>dram_as,
> s->regs[R_DMA_DRAM_ADDR],
> > +data = address_space_ldl_le(>dram_as,
> dma_dram_offset,
> >
> MEMTXATTRS_UNSPECIFIED, );
> >   if (result != MEMTX_OK) {
> > -aspeed_smc_error("DRAM read failed @%08x",
> > - s->regs[R_DMA_DRAM_ADDR]);
> > +aspeed_smc_error("DRAM read failed @%" PRIx64,
> > + dma_dram_offset);
> >   return;
> >   }
> >
> > @@ -940,11 +968,11 @@ static void aspeed_smc_dma_rw(AspeedSMCState
> *s)
> >   return;
> >   }
> >
> > -address_space_stl_le(>dram_as,
> s->regs[R_DMA_DRAM_ADDR],
> > +address_space_stl_le(>dram_as, dma_dram_offset,
> >data,
> MEMTXATTRS_UNSPECIFIED, );
> >   if (result != MEMTX_OK) {
> > -aspeed_smc_error("DRAM write failed @%08x",
> > - s->regs[R_DMA_DRAM_ADDR]);
> > +aspeed_smc_error("DRAM write failed @%" PRIx64,
> > + dma_dram_offset);
> >   return;
> >   }
> >   }
> > @@ -953,8 +981,12 @@ static void aspeed_smc_dma_rw(AspeedSMCState
> *s)
> >* When the DMA is on-going, the DMA registers are updated
> >* with the current working addresses and length.
> >*/
> > +dma_dram_offset += 4;
> > +dma_dram_addr += 4;
> > +
> > +s->regs[R_DMA_DRAM_ADDR_HIGH] = dma_dram_addr >&

RE: [PATCH v4 08/16] aspeed/smc: support 64 bits dma dram address

2024-05-27 Thread Jamin Lin
Hi Cedric,

> On 5/27/24 10:02, Jamin Lin wrote:
> > AST2700 support the maximum dram size is 8GiB and has a "DMA DRAM
> Side
> > Address High Part(0x7C)"
> > register to support 64 bits dma dram address.
> > Add helper routines functions to compute the dma dram address, new
> > features and update trace-event to support 64 bits dram address.
> >
> > Signed-off-by: Troy Lee 
> > Signed-off-by: Jamin Lin 
> 
> I will move the addition of the "dram-base" property to another patch. See :
> 
>https://patchew.org/QEMU/20240527124315.35356-1-...@redhat.com/
> 
> (Please review)
Review done.
If I need to resend v5 patch series, I will remove "dram-base property" from 
this patch.
Thanks for your help, Jamin
> 
> Else,
> 
> Reviewed-by: Cédric Le Goater 
> 
> Thanks,
> 
> C.
> 
> 
> > ---
> >   hw/ssi/aspeed_smc.c | 52
> +++--
> >   hw/ssi/trace-events |  2 +-
> >   include/hw/ssi/aspeed_smc.h |  1 +
> >   3 files changed, 46 insertions(+), 9 deletions(-)
> >
> > diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c index
> > ffb13a12e8..df0c63469c 100644
> > --- a/hw/ssi/aspeed_smc.c
> > +++ b/hw/ssi/aspeed_smc.c
> > @@ -132,6 +132,9 @@
> >   #define   FMC_WDT2_CTRL_BOOT_SOURCE  BIT(4) /* O: primary
> 1: alternate */
> >   #define   FMC_WDT2_CTRL_EN   BIT(0)
> >
> > +/* DMA DRAM Side Address High Part (AST2700) */
> > +#define R_DMA_DRAM_ADDR_HIGH   (0x7c / 4)
> > +
> >   /* DMA Control/Status Register */
> >   #define R_DMA_CTRL(0x80 / 4)
> >   #define   DMA_CTRL_REQUEST  (1 << 31)
> > @@ -187,6 +190,7 @@
> >*   0x1FF: 32M bytes
> >*/
> >   #define DMA_DRAM_ADDR(asc, val)   ((val) & (asc)->dma_dram_mask)
> > +#define DMA_DRAM_ADDR_HIGH(val)   ((val) & 0xf)
> >   #define DMA_FLASH_ADDR(asc, val)  ((val) & (asc)->dma_flash_mask)
> >   #define DMA_LENGTH(val) ((val) & 0x01FF)
> >
> > @@ -207,6 +211,7 @@ static const AspeedSegments
> aspeed_2500_spi2_segments[];
> >   #define ASPEED_SMC_FEATURE_DMA   0x1
> >   #define ASPEED_SMC_FEATURE_DMA_GRANT 0x2
> >   #define ASPEED_SMC_FEATURE_WDT_CONTROL 0x4
> > +#define ASPEED_SMC_FEATURE_DMA_DRAM_ADDR_HIGH 0x08
> >
> >   static inline bool aspeed_smc_has_dma(const AspeedSMCClass *asc)
> >   {
> > @@ -218,6 +223,11 @@ static inline bool
> aspeed_smc_has_wdt_control(const AspeedSMCClass *asc)
> >   return !!(asc->features & ASPEED_SMC_FEATURE_WDT_CONTROL);
> >   }
> >
> > +static inline bool aspeed_smc_has_dma64(const AspeedSMCClass *asc) {
> > +return !!(asc->features &
> ASPEED_SMC_FEATURE_DMA_DRAM_ADDR_HIGH);
> > +}
> > +
> >   #define aspeed_smc_error(fmt, ...)
> \
> >   qemu_log_mask(LOG_GUEST_ERROR, "%s: " fmt "\n", __func__, ##
> > __VA_ARGS__)
> >
> > @@ -747,6 +757,8 @@ static uint64_t aspeed_smc_read(void *opaque,
> hwaddr addr, unsigned int size)
> >   (aspeed_smc_has_dma(asc) && addr == R_DMA_CTRL) ||
> >   (aspeed_smc_has_dma(asc) && addr == R_DMA_FLASH_ADDR)
> ||
> >   (aspeed_smc_has_dma(asc) && addr == R_DMA_DRAM_ADDR)
> ||
> > +(aspeed_smc_has_dma(asc) && aspeed_smc_has_dma64(asc)
> &&
> > + addr == R_DMA_DRAM_ADDR_HIGH) ||
> >   (aspeed_smc_has_dma(asc) && addr == R_DMA_LEN) ||
> >   (aspeed_smc_has_dma(asc) && addr == R_DMA_CHECKSUM)
> ||
> >   (addr >= R_SEG_ADDR0 &&
> > @@ -847,6 +859,12 @@ static bool
> aspeed_smc_inject_read_failure(AspeedSMCState *s)
> >   }
> >   }
> >
> > +static uint64_t aspeed_smc_dma_dram_addr(AspeedSMCState *s) {
> > +return s->regs[R_DMA_DRAM_ADDR] |
> > +((uint64_t) s->regs[R_DMA_DRAM_ADDR_HIGH] << 32); }
> > +
> >   static uint32_t aspeed_smc_dma_len(AspeedSMCState *s)
> >   {
> >   AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s); @@ -903,24
> > +921,34 @@ static void aspeed_smc_dma_checksum(AspeedSMCState *s)
> >
> >   static void aspeed_smc_dma_rw(AspeedSMCState *s)
> >   {
> > +AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s);
> > +uint64_t dma_dram_offset;
> > +uint64_t dma_dram_addr;
> >   MemTxResult result;
> >   uint32_t dma_len;
> >   uint32_t data;
> >
> >   dma_len = aspeed_smc_dma_len(s);
> > +d

RE: [PATCH] aspeed/smc: Reintroduce "dram-base" property for AST2700

2024-05-27 Thread Jamin Lin
> 
> The Aspeed SMC device model use to have a 'sdram_base' property. It was
> removed by commit d177892d4a48 ("aspeed/smc: Remove unused
> "sdram-base" property") because previous changes simplified the DMA
> transaction model to use an offset in RAM and not the physical address.
> 
> The AST2700 SoC has larger address space (64-bit) and a new register DMA
> DRAM Side Address High Part (0x7C) is introduced to deal with the high bits of
> the DMA address. To be able to compute the offset of the DMA transaction, as
> done on the other SoCs, we will need to know where the DRAM is mapped in
> the address space. Re-introduce a "dram-base"
> property to hold this value.
> 
> Signed-off-by: Cédric Le Goater 
> ---
>  include/hw/ssi/aspeed_smc.h | 1 +
>  hw/ssi/aspeed_smc.c | 1 +
>  2 files changed, 2 insertions(+)
> 
> diff --git a/include/hw/ssi/aspeed_smc.h b/include/hw/ssi/aspeed_smc.h index
> 8e1dda556b91..8791cc0ecb11 100644
> --- a/include/hw/ssi/aspeed_smc.h
> +++ b/include/hw/ssi/aspeed_smc.h
> @@ -76,6 +76,7 @@ struct AspeedSMCState {
>  AddressSpace flash_as;
>  MemoryRegion *dram_mr;
>  AddressSpace dram_as;
> +uint64_t dram_base;
> 
>  AspeedSMCFlash flashes[ASPEED_SMC_CS_MAX];
> 
> diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c index
> 6e1a84c19713..7075bc9d61b0 100644
> --- a/hw/ssi/aspeed_smc.c
> +++ b/hw/ssi/aspeed_smc.c
> @@ -1220,6 +1220,7 @@ static const VMStateDescription
> vmstate_aspeed_smc = {
> 
>  static Property aspeed_smc_properties[] = {
>  DEFINE_PROP_BOOL("inject-failure", AspeedSMCState, inject_failure,
> false),
> +DEFINE_PROP_UINT64("dram-base", AspeedSMCState, dram_base, 0),
>  DEFINE_PROP_LINK("dram", AspeedSMCState, dram_mr,
>   TYPE_MEMORY_REGION, MemoryRegion *),
>  DEFINE_PROP_END_OF_LIST(),
> --
> 2.45.1

Reviewed-by: Jamin Lin 

Thanks-Jamin




RE: [PATCH v4 05/16] aspeed/sdmc: Add AST2700 support

2024-05-27 Thread Jamin Lin
Hi Philippe, Cedric

> On 27/5/24 13:18, Cédric Le Goater wrote:
> > On 5/27/24 12:24, Philippe Mathieu-Daudé wrote:
> >> Hi Jamin,
> >>
> >> On 27/5/24 10:02, Jamin Lin wrote:
> >>> The SDRAM memory controller(DRAMC) controls the access to external
> >>> DDR4 and DDR5 SDRAM and power up to DDR4 and DDR5 PHY.
> >>>
> >>> The DRAM memory controller of AST2700 is not backward compatible to
> >>> previous chips such AST2600, AST2500 and AST2400.
> >>>
> >>> Max memory is now 8GiB on the AST2700. Introduce new
> >>> aspeed_2700_sdmc and class with read/write operation and reset
> >>> handlers.
> >>>
> >>> Define DRAMC necessary protected registers and unprotected registers
> >>> for AST2700 and increase the register set to 0x1000.
> >>>
> >>> Add unlocked property to change controller protected status.
> >>>
> >>> Signed-off-by: Troy Lee 
> >>> Signed-off-by: Jamin Lin 
> >>> Reviewed-by: Cédric Le Goater 
> >>> ---
> >>>   hw/misc/aspeed_sdmc.c | 190
> >>> +-
> >>>   include/hw/misc/aspeed_sdmc.h |   5 +-
> >>>   2 files changed, 193 insertions(+), 2 deletions(-)
> >>
> >>
> >>> diff --git a/include/hw/misc/aspeed_sdmc.h
> >>> b/include/hw/misc/aspeed_sdmc.h index ec2d59a14f..61c979583a 100644
> >>> --- a/include/hw/misc/aspeed_sdmc.h
> >>> +++ b/include/hw/misc/aspeed_sdmc.h
> >>> @@ -17,6 +17,7 @@ OBJECT_DECLARE_TYPE(AspeedSDMCState,
> >>> AspeedSDMCClass, ASPEED_SDMC)
> >>>   #define TYPE_ASPEED_2400_SDMC TYPE_ASPEED_SDMC "-ast2400"
> >>>   #define TYPE_ASPEED_2500_SDMC TYPE_ASPEED_SDMC "-ast2500"
> >>>   #define TYPE_ASPEED_2600_SDMC TYPE_ASPEED_SDMC "-ast2600"
> >>> +#define TYPE_ASPEED_2700_SDMC TYPE_ASPEED_SDMC "-ast2700"
> >>>   /*
> >>>    * SDMC has 174 documented registers. In addition the u-boot
> >>> device tree @@ -29,7 +30,7 @@
> OBJECT_DECLARE_TYPE(AspeedSDMCState,
> >>> AspeedSDMCClass, ASPEED_SDMC)
> >>>    * time, and the other is in the DDR-PHY IP which is used during
> >>> DDR-PHY
> >>>    * training.
> >>>    */
> >>> -#define ASPEED_SDMC_NR_REGS (0x500 >> 2)
> >>> +#define ASPEED_SDMC_NR_REGS (0x1000 >> 2)
> >>
> >> This change breaks the migration stream.
> >
> > Do you mean migration compat ? We never cared much about that for the
> > Aspeed machines.
> 
> So let's just remove the VMSTATE to reduce code burden?
> 
> Otherwise incrementing the vmstate.version is enough.
> 
> Regards,
> 
> Phil.
If you both okay, I will remove it.
Do I need to create a new patch or just update in this patch?
Thanks-Jamin





[PATCH v4 15/16] test/avocado/machine_aspeed.py: Add AST2700 test case

2024-05-27 Thread Jamin Lin via
Add a test case to test Aspeed OpenBMC SDK v09.01 on AST2700 board.

It loads u-boot-nodtb.bin, u-boot.dtb, tfa and optee-os
images to dram first which base address is 0x4.
Then, boot and launch 4 cpu cores.

```
qemu-system-aarch64 -machine ast2700-evb
-device loader,force-raw=on,addr=0x4,file=workdir/u-boot-nodtb.bin \
-device 
loader,force-raw=on,addr=uboot_dtb_load_addr,file=workdir/u-boot.dtb\
-device loader,force-raw=on,addr=0x43000,file=workdir/bl31.bin\
-device loader,force-raw=on,addr=0x43008,file=workdir/optee/tee-raw.bin\
-device loader,cpu-num=0,addr=0x43000 \
-device loader,cpu-num=1,addr=0x43000 \
-device loader,cpu-num=2,addr=0x43000 \
-device loader,cpu-num=3,addr=0x43000 \
-smp 4 \
-drive file=workdir/image-bmc,format=raw,if=mtd
```

A test image is downloaded from the ASPEED Forked OpenBMC GitHub release 
repository :
https://github.com/AspeedTech-BMC/openbmc/releases/

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 
Reviewed-by: Cédric Le Goater 
---
 tests/avocado/machine_aspeed.py | 62 +
 1 file changed, 62 insertions(+)

diff --git a/tests/avocado/machine_aspeed.py b/tests/avocado/machine_aspeed.py
index cec0181424..3a20644fb2 100644
--- a/tests/avocado/machine_aspeed.py
+++ b/tests/avocado/machine_aspeed.py
@@ -311,6 +311,17 @@ def do_test_arm_aspeed_sdk_start(self, image):
 self, 'boot', '## Loading kernel from FIT Image')
 self.wait_for_console_pattern('Starting kernel ...')
 
+def do_test_aarch64_aspeed_sdk_start(self, image):
+self.vm.set_console()
+self.vm.add_args('-drive', 'file=' + image + ',if=mtd,format=raw')
+
+self.vm.launch()
+
+self.wait_for_console_pattern('U-Boot 2023.10')
+self.wait_for_console_pattern('## Loading kernel from FIT Image')
+self.wait_for_console_pattern('Starting kernel ...')
+self.wait_for_console_pattern("systemd[1]: Hostname set to")
+
 @skipUnless(os.getenv('QEMU_TEST_FLAKY_TESTS'), 'Test is unstable on 
GitLab')
 
 def test_arm_ast2500_evb_sdk(self):
@@ -375,3 +386,54 @@ def test_arm_ast2600_evb_sdk(self):
  'i2c i2c-5: new_device: Instantiated device ds1307 at 0x32');
 year = time.strftime("%Y")
 self.ssh_command_output_contains('/sbin/hwclock -f /dev/rtc1', year);
+
+def test_aarch64_ast2700_evb_sdk_v09_01(self):
+"""
+:avocado: tags=arch:aarch64
+:avocado: tags=machine:ast2700-evb
+"""
+
+image_url = ('https://github.com/AspeedTech-BMC/openbmc/releases/'
+ 'download/v09.01/ast2700-default-obmc.tar.gz')
+image_hash = 
'b1cc0fd73c7650d34c9c8459a243f52a91e9e27144b8608b2645ab19461d1e07'
+image_path = self.fetch_asset(image_url, asset_hash=image_hash,
+  algorithm='sha256')
+archive.extract(image_path, self.workdir)
+
+num_cpu = 4
+image_dir = self.workdir + '/ast2700-default/'
+uboot_size = os.path.getsize(image_dir + 'u-boot-nodtb.bin')
+uboot_dtb_load_addr = hex(0x4 + uboot_size)
+
+load_images_list = [
+{
+'addr': '0x4',
+'file': image_dir + 'u-boot-nodtb.bin'
+},
+{
+'addr': str(uboot_dtb_load_addr),
+'file': image_dir + 'u-boot.dtb'
+},
+{
+'addr': '0x43000',
+'file': image_dir + 'bl31.bin'
+},
+{
+'addr': '0x43008',
+'file': image_dir + 'optee/tee-raw.bin'
+}
+]
+
+for load_image in load_images_list:
+addr = load_image['addr']
+file = load_image['file']
+self.vm.add_args('-device',
+ f'loader,force-raw=on,addr={addr},file={file}')
+
+for i in range(num_cpu):
+self.vm.add_args('-device',
+ f'loader,addr=0x43000,cpu-num={i}')
+
+self.vm.add_args('-smp', str(num_cpu))
+self.do_test_aarch64_aspeed_sdk_start(image_dir + 'image-bmc')
+
-- 
2.25.1




[PATCH v4 01/16] aspeed/wdt: Add AST2700 support

2024-05-27 Thread Jamin Lin via
AST2700 wdt controller is similiar to AST2600's wdt, but
the AST2700 has 8 watchdogs, and they each have 0x80 of registers.
Introduce ast2700 object class and increase the number of regs(offset) of
ast2700 model.

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 
Reviewed-by: Cédric Le Goater 
---
 hw/watchdog/wdt_aspeed.c | 24 
 include/hw/watchdog/wdt_aspeed.h |  3 ++-
 2 files changed, 26 insertions(+), 1 deletion(-)

diff --git a/hw/watchdog/wdt_aspeed.c b/hw/watchdog/wdt_aspeed.c
index d70b656f8e..75685c5647 100644
--- a/hw/watchdog/wdt_aspeed.c
+++ b/hw/watchdog/wdt_aspeed.c
@@ -422,12 +422,36 @@ static const TypeInfo aspeed_1030_wdt_info = {
 .class_init = aspeed_1030_wdt_class_init,
 };
 
+static void aspeed_2700_wdt_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+AspeedWDTClass *awc = ASPEED_WDT_CLASS(klass);
+
+dc->desc = "ASPEED 2700 Watchdog Controller";
+awc->iosize = 0x80;
+awc->ext_pulse_width_mask = 0xf; /* TODO */
+awc->reset_ctrl_reg = AST2600_SCU_RESET_CONTROL1;
+awc->reset_pulse = aspeed_2500_wdt_reset_pulse;
+awc->wdt_reload = aspeed_wdt_reload_1mhz;
+awc->sanitize_ctrl = aspeed_2600_sanitize_ctrl;
+awc->default_status = 0x014FB180;
+awc->default_reload_value = 0x014FB180;
+}
+
+static const TypeInfo aspeed_2700_wdt_info = {
+.name = TYPE_ASPEED_2700_WDT,
+.parent = TYPE_ASPEED_WDT,
+.instance_size = sizeof(AspeedWDTState),
+.class_init = aspeed_2700_wdt_class_init,
+};
+
 static void wdt_aspeed_register_types(void)
 {
 type_register_static(_wdt_info);
 type_register_static(_2400_wdt_info);
 type_register_static(_2500_wdt_info);
 type_register_static(_2600_wdt_info);
+type_register_static(_2700_wdt_info);
 type_register_static(_1030_wdt_info);
 }
 
diff --git a/include/hw/watchdog/wdt_aspeed.h b/include/hw/watchdog/wdt_aspeed.h
index e90ef86651..830b0a7936 100644
--- a/include/hw/watchdog/wdt_aspeed.h
+++ b/include/hw/watchdog/wdt_aspeed.h
@@ -19,9 +19,10 @@ OBJECT_DECLARE_TYPE(AspeedWDTState, AspeedWDTClass, 
ASPEED_WDT)
 #define TYPE_ASPEED_2400_WDT TYPE_ASPEED_WDT "-ast2400"
 #define TYPE_ASPEED_2500_WDT TYPE_ASPEED_WDT "-ast2500"
 #define TYPE_ASPEED_2600_WDT TYPE_ASPEED_WDT "-ast2600"
+#define TYPE_ASPEED_2700_WDT TYPE_ASPEED_WDT "-ast2700"
 #define TYPE_ASPEED_1030_WDT TYPE_ASPEED_WDT "-ast1030"
 
-#define ASPEED_WDT_REGS_MAX(0x30 / 4)
+#define ASPEED_WDT_REGS_MAX(0x80 / 4)
 
 struct AspeedWDTState {
 /*< private >*/
-- 
2.25.1




[PATCH v4 10/16] aspeed/scu: Add AST2700 support

2024-05-27 Thread Jamin Lin via
AST2700 have two SCU controllers which are SCU and SCUIO.
Both SCU and SCUIO registers are not compatible previous SOCs
, introduces new registers and adds ast2700 scu, sucio class init handler.

The pclk divider selection of SCUIO is defined in SCUIO280[20:18] and
the pclk divider selection of SCU is defined in SCU280[25:23].
Both of them are not compatible AST2600 SOCs, adds a get_apb_freq function
and trace-event for AST2700 SCU and SCUIO.

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 
Reviewed-by: Cédric Le Goater 
---
 hw/misc/aspeed_scu.c | 306 ++-
 hw/misc/trace-events |   4 +
 include/hw/misc/aspeed_scu.h |  47 +-
 3 files changed, 351 insertions(+), 6 deletions(-)

diff --git a/hw/misc/aspeed_scu.c b/hw/misc/aspeed_scu.c
index 1ac04b6cb0..eb38ea8e19 100644
--- a/hw/misc/aspeed_scu.c
+++ b/hw/misc/aspeed_scu.c
@@ -134,6 +134,48 @@
 
 #define AST2600_CLK TO_REG(0x40)
 
+#define AST2700_SILICON_REV   TO_REG(0x00)
+#define AST2700_HW_STRAP1 TO_REG(0x10)
+#define AST2700_HW_STRAP1_CLR TO_REG(0x14)
+#define AST2700_HW_STRAP1_LOCKTO_REG(0x20)
+#define AST2700_HW_STRAP1_SEC1TO_REG(0x24)
+#define AST2700_HW_STRAP1_SEC2TO_REG(0x28)
+#define AST2700_HW_STRAP1_SEC3TO_REG(0x2C)
+
+#define AST2700_SCU_CLK_SEL_1   TO_REG(0x280)
+#define AST2700_SCU_HPLL_PARAM  TO_REG(0x300)
+#define AST2700_SCU_HPLL_EXT_PARAM  TO_REG(0x304)
+#define AST2700_SCU_DPLL_PARAM  TO_REG(0x308)
+#define AST2700_SCU_DPLL_EXT_PARAM  TO_REG(0x30c)
+#define AST2700_SCU_MPLL_PARAM  TO_REG(0x310)
+#define AST2700_SCU_MPLL_EXT_PARAM  TO_REG(0x314)
+#define AST2700_SCU_D1CLK_PARAM TO_REG(0x320)
+#define AST2700_SCU_D2CLK_PARAM TO_REG(0x330)
+#define AST2700_SCU_CRT1CLK_PARAM   TO_REG(0x340)
+#define AST2700_SCU_CRT2CLK_PARAM   TO_REG(0x350)
+#define AST2700_SCU_MPHYCLK_PARAM   TO_REG(0x360)
+#define AST2700_SCU_FREQ_CNTR   TO_REG(0x3b0)
+#define AST2700_SCU_CPU_SCRATCH_0   TO_REG(0x780)
+#define AST2700_SCU_CPU_SCRATCH_1   TO_REG(0x784)
+
+#define AST2700_SCUIO_CLK_STOP_CTL_1TO_REG(0x240)
+#define AST2700_SCUIO_CLK_STOP_CLR_1TO_REG(0x244)
+#define AST2700_SCUIO_CLK_STOP_CTL_2TO_REG(0x260)
+#define AST2700_SCUIO_CLK_STOP_CLR_2TO_REG(0x264)
+#define AST2700_SCUIO_CLK_SEL_1 TO_REG(0x280)
+#define AST2700_SCUIO_CLK_SEL_2 TO_REG(0x284)
+#define AST2700_SCUIO_HPLL_PARAMTO_REG(0x300)
+#define AST2700_SCUIO_HPLL_EXT_PARAMTO_REG(0x304)
+#define AST2700_SCUIO_APLL_PARAMTO_REG(0x310)
+#define AST2700_SCUIO_APLL_EXT_PARAMTO_REG(0x314)
+#define AST2700_SCUIO_DPLL_PARAMTO_REG(0x320)
+#define AST2700_SCUIO_DPLL_EXT_PARAMTO_REG(0x324)
+#define AST2700_SCUIO_DPLL_PARAM_READ   TO_REG(0x328)
+#define AST2700_SCUIO_DPLL_EXT_PARAM_READ TO_REG(0x32c)
+#define AST2700_SCUIO_UARTCLK_GEN   TO_REG(0x330)
+#define AST2700_SCUIO_HUARTCLK_GEN  TO_REG(0x334)
+#define AST2700_SCUIO_CLK_DUTY_MEAS_RST TO_REG(0x388)
+
 #define SCU_IO_REGION_SIZE 0x1000
 
 static const uint32_t ast2400_a0_resets[ASPEED_SCU_NR_REGS] = {
@@ -244,6 +286,25 @@ static uint32_t 
aspeed_1030_scu_get_apb_freq(AspeedSCUState *s)
 / asc->apb_divider;
 }
 
+static uint32_t aspeed_2700_scu_get_apb_freq(AspeedSCUState *s)
+{
+AspeedSCUClass *asc = ASPEED_SCU_GET_CLASS(s);
+uint32_t hpll = asc->calc_hpll(s, s->regs[AST2700_SCU_HPLL_PARAM]);
+
+return hpll / (SCU_CLK_GET_PCLK_DIV(s->regs[AST2700_SCU_CLK_SEL_1]) + 1)
+   / asc->apb_divider;
+}
+
+static uint32_t aspeed_2700_scuio_get_apb_freq(AspeedSCUState *s)
+{
+AspeedSCUClass *asc = ASPEED_SCU_GET_CLASS(s);
+uint32_t hpll = asc->calc_hpll(s, s->regs[AST2700_SCUIO_HPLL_PARAM]);
+
+return hpll /
+(SCUIO_AST2700_CLK_GET_PCLK_DIV(s->regs[AST2700_SCUIO_CLK_SEL_1]) + 1)
+/ asc->apb_divider;
+}
+
 static uint64_t aspeed_scu_read(void *opaque, hwaddr offset, unsigned size)
 {
 AspeedSCUState *s = ASPEED_SCU(opaque);
@@ -258,7 +319,8 @@ static uint64_t aspeed_scu_read(void *opaque, hwaddr 
offset, unsigned size)
 
 switch (reg) {
 case RNG_DATA:
-/* On hardware, RNG_DATA works regardless of
+/*
+ * On hardware, RNG_DATA works regardless of
  * the state of the enable bit in RNG_CTRL
  */
 s->regs[RNG_DATA] = aspeed_scu_get_random();
@@ -494,6 +556,9 @@ static uint32_t aspeed_silicon_revs[] = {
 AST2600_A3_SILICON_REV,
 AST1030_A0_SILICON_REV,
 AST1030_A1_SILICON_REV,
+AST2700_A0_SILICON_REV,
+AST2720_A0_SILICON_REV,
+AST2750_A0_SILICON_REV,
 };
 
 bool is_supported_silicon_rev(uint32_t silicon_rev)
@@ -783,6 +848,243 @@ static const TypeInfo aspeed_2600_scu_info = {
 .class_init = aspeed_2600_scu_class_init,
 };
 
+static uint64_t aspeed_ast2700_scu_read(void *opaque, hwaddr offset,
+unsigned size)
+{
+AspeedSCUState *s = ASPEED_SCU(opaque);
+int reg = 

[PATCH v4 06/16] aspeed/smc: correct device description

2024-05-27 Thread Jamin Lin via
Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 
Reviewed-by: Cédric Le Goater 
---
 hw/ssi/aspeed_smc.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
index 6e1a84c197..8a8d77b480 100644
--- a/hw/ssi/aspeed_smc.c
+++ b/hw/ssi/aspeed_smc.c
@@ -1448,7 +1448,7 @@ static void aspeed_2500_fmc_class_init(ObjectClass 
*klass, void *data)
 DeviceClass *dc = DEVICE_CLASS(klass);
 AspeedSMCClass *asc = ASPEED_SMC_CLASS(klass);
 
-dc->desc   = "Aspeed 2600 FMC Controller";
+dc->desc   = "Aspeed 2500 FMC Controller";
 asc->r_conf= R_CONF;
 asc->r_ce_ctrl = R_CE_CTRL;
 asc->r_ctrl0   = R_CTRL0;
@@ -1486,7 +1486,7 @@ static void aspeed_2500_spi1_class_init(ObjectClass 
*klass, void *data)
 DeviceClass *dc = DEVICE_CLASS(klass);
 AspeedSMCClass *asc = ASPEED_SMC_CLASS(klass);
 
-dc->desc   = "Aspeed 2600 SPI1 Controller";
+dc->desc   = "Aspeed 2500 SPI1 Controller";
 asc->r_conf= R_CONF;
 asc->r_ce_ctrl = R_CE_CTRL;
 asc->r_ctrl0   = R_CTRL0;
@@ -1521,7 +1521,7 @@ static void aspeed_2500_spi2_class_init(ObjectClass 
*klass, void *data)
 DeviceClass *dc = DEVICE_CLASS(klass);
 AspeedSMCClass *asc = ASPEED_SMC_CLASS(klass);
 
-dc->desc   = "Aspeed 2600 SPI2 Controller";
+dc->desc   = "Aspeed 2500 SPI2 Controller";
 asc->r_conf= R_CONF;
 asc->r_ce_ctrl = R_CE_CTRL;
 asc->r_ctrl0   = R_CTRL0;
-- 
2.25.1




[PATCH v4 04/16] aspeed/sdmc: fix coding style

2024-05-27 Thread Jamin Lin via
Fix coding style issues from checkpatch.pl

Test command:
scripts/checkpatch.pl --no-tree -f hw/misc/aspeed_sdmc.c

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 
Reviewed-by: Cédric Le Goater 
---
 hw/misc/aspeed_sdmc.c | 11 +++
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/hw/misc/aspeed_sdmc.c b/hw/misc/aspeed_sdmc.c
index 74279bbe8e..873d67c592 100644
--- a/hw/misc/aspeed_sdmc.c
+++ b/hw/misc/aspeed_sdmc.c
@@ -296,7 +296,8 @@ static void aspeed_2400_sdmc_write(AspeedSDMCState *s, 
uint32_t reg,
uint32_t data)
 {
 if (reg == R_PROT) {
-s->regs[reg] = (data == PROT_KEY_UNLOCK) ? PROT_UNLOCKED : 
PROT_SOFTLOCKED;
+s->regs[reg] =
+(data == PROT_KEY_UNLOCK) ? PROT_UNLOCKED : PROT_SOFTLOCKED;
 return;
 }
 
@@ -354,7 +355,8 @@ static void aspeed_2500_sdmc_write(AspeedSDMCState *s, 
uint32_t reg,
uint32_t data)
 {
 if (reg == R_PROT) {
-s->regs[reg] = (data == PROT_KEY_UNLOCK) ? PROT_UNLOCKED : 
PROT_SOFTLOCKED;
+s->regs[reg] =
+(data == PROT_KEY_UNLOCK) ? PROT_UNLOCKED : PROT_SOFTLOCKED;
 return;
 }
 
@@ -434,8 +436,9 @@ static void aspeed_2600_sdmc_write(AspeedSDMCState *s, 
uint32_t reg,
 }
 
 if (s->regs[R_PROT] == PROT_HARDLOCKED) {
-qemu_log_mask(LOG_GUEST_ERROR, "%s: SDMC is locked until system 
reset!\n",
-__func__);
+qemu_log_mask(LOG_GUEST_ERROR,
+  "%s: SDMC is locked until system reset!\n",
+  __func__);
 return;
 }
 
-- 
2.25.1




[PATCH v4 16/16] docs:aspeed: Add AST2700 Evaluation board

2024-05-27 Thread Jamin Lin via
Add AST2700 Evaluation board and its boot command.

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 
Reviewed-by: Cédric Le Goater 
---
 docs/system/arm/aspeed.rst | 39 ++
 1 file changed, 35 insertions(+), 4 deletions(-)

diff --git a/docs/system/arm/aspeed.rst b/docs/system/arm/aspeed.rst
index b2dea54eed..cd9559e3e2 100644
--- a/docs/system/arm/aspeed.rst
+++ b/docs/system/arm/aspeed.rst
@@ -1,11 +1,12 @@
-Aspeed family boards (``*-bmc``, ``ast2500-evb``, ``ast2600-evb``)
-==
+Aspeed family boards (``*-bmc``, ``ast2500-evb``, ``ast2600-evb``, 
``ast2700-evb``)
+===
 
 The QEMU Aspeed machines model BMCs of various OpenPOWER systems and
 Aspeed evaluation boards. They are based on different releases of the
 Aspeed SoC : the AST2400 integrating an ARM926EJ-S CPU (400MHz), the
-AST2500 with an ARM1176JZS CPU (800MHz) and more recently the AST2600
-with dual cores ARM Cortex-A7 CPUs (1.2GHz).
+AST2500 with an ARM1176JZS CPU (800MHz), the AST2600
+with dual cores ARM Cortex-A7 CPUs (1.2GHz) and more recently the AST2700
+with quad cores ARM Cortex-A35 64 bits CPUs (1.6GHz)
 
 The SoC comes with RAM, Gigabit ethernet, USB, SD/MMC, USB, SPI, I2C,
 etc.
@@ -38,6 +39,10 @@ AST2600 SoC based machines :
 - ``qcom-dc-scm-v1-bmc``   Qualcomm DC-SCM V1 BMC
 - ``qcom-firework-bmc``Qualcomm Firework BMC
 
+AST2700 SoC based machines :
+
+- ``ast2700-evb``  Aspeed AST2700 Evaluation board (Cortex-A35)
+
 Supported devices
 -
 
@@ -66,6 +71,7 @@ Supported devices
  * eMMC Boot Controller (dummy)
  * PECI Controller (minimal)
  * I3C Controller
+ * Internal Bridge Controller (SLI dummy)
 
 
 Missing devices
@@ -95,6 +101,10 @@ or directly from the OpenBMC GitHub release repository :
 
https://github.com/openbmc/openbmc/releases
 
+or directly from the ASPEED Forked OpenBMC GitHub release repository :
+
+   https://github.com/AspeedTech-BMC/openbmc/releases
+
 To boot a kernel directly from a Linux build tree:
 
 .. code-block:: bash
@@ -164,6 +174,27 @@ under Linux), use :
 
   -M ast2500-evb,bmc-console=uart3
 
+
+Boot the AST2700 machine from the flash image, use an MTD drive :
+
+.. code-block:: bash
+
+  IMGDIR=ast2700-default
+  UBOOT_SIZE=$(stat --format=%s -L ${IMGDIR}/u-boot-nodtb.bin)
+
+  $ qemu-system-aarch64 -M ast2700-evb \
+   -device 
loader,force-raw=on,addr=0x4,file=${IMGDIR}/u-boot-nodtb.bin \
+   -device loader,force-raw=on,addr=$((0x4 + 
${UBOOT_SIZE})),file=${IMGDIR}/u-boot.dtb \
+   -device loader,force-raw=on,addr=0x43000,file=${IMGDIR}/bl31.bin \
+   -device 
loader,force-raw=on,addr=0x43008,file=${IMGDIR}/optee/tee-raw.bin \
+   -device loader,cpu-num=0,addr=0x43000 \
+   -device loader,cpu-num=1,addr=0x43000 \
+   -device loader,cpu-num=2,addr=0x43000 \
+   -device loader,cpu-num=3,addr=0x43000 \
+   -smp 4 \
+   -drive file=${IMGDIR}/image-bmc,format=raw,if=mtd \
+   -nographic
+
 Aspeed minibmc family boards (``ast1030-evb``)
 ==
 
-- 
2.25.1




[PATCH v4 11/16] aspeed/intc: Add AST2700 support

2024-05-27 Thread Jamin Lin via
AST2700 interrupt controller(INTC) provides hardware interrupt interfaces
to interrupt of processors PSP, SSP and TSP. In INTC, each interrupt of
INT 128 to INT136 combines 32 interrupts.

Introduce a new aspeed_intc class with instance_init and realize handlers.

So far, this model only supports GICINT128 to GICINT136.
It creates 9 GICINT or-gates to connect 32 interrupts sources
from GICINT128 to GICINT136 as IRQ GPIO-OUTPUT pins.
Then, this model registers IRQ handler with its IRQ GPIO-INPUT pins which
connect to GICINT or-gates. And creates 9 GICINT IRQ GPIO-OUTPUT pins which
connect to GIC device with GIC IRQ 128 to 136.

If one interrupt source from GICINT128 to GICINT136
set irq, the OR-GATE irq callback function is called and set irq to INTC by
OR-GATE GPIO-OUTPUT pins. Then, the INTC irq callback function is called and
set irq to GIC by its GICINT IRQ GPIO-OUTPUT pins. Finally, the GIC irq
callback function is called and set irq to CPUs and
CPUs execute Interrupt Service Routine (ISR).

Block diagram of GICINT132:

GICINT132
  ETH1+---+
+>+0 3|
  ETH2|  4|
+>+1 5|
  ETH3|  6|
+>+219|  INTC  
GIC
  UART0   | 20|+--+
+>+721||  |
+--+
  UART1   | 22||orgate0 +> 
output_pin0+--->+GIC128|
+>+823||  ||
  |
  UART2   | 24||orgate1 +> 
output_pin1+--->+GIC129|
+>+925||  ||
  |
  UART3   | 26||orgate2 +> 
output_pin2+--->+GIC130|
+->10   27||  ||
  |
  UART5   | 28||orgate3 +> 
output_pin3+--->+GIC131|
+>+11   29||  ||
  |
  UART6   |   +--->+orgate4 +> 
output_pin4+--->+GIC132|
+>+12   30||  ||
  |
  UART7   | 31||orgate5 +> 
output_pin5+--->+GIC133|
+>+13 ||  ||
  |
  UART8   |  OR[0:31] ||orgate6 +> 
output_pin6+--->+GIC134|
-->14 ||  ||
  |
  UART9   |   ||orgate7 +> 
output_pin7+--->+GIC135|
->+15 ||  ||
  |
  UART10  |   ||orgate8 +> 
output_pin8+--->+GIC136|
->+16 ||  |
+--+
  UART11  |   |+--+
+>+17 |
  UART12  |   |
+->18 |
  |   |
  |       |
  |   |
  +---+

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 
---
 hw/intc/aspeed_intc.c | 355 ++
 hw/intc/meson.build   |   1 +
 hw/intc/trace-events  |   6 +
 include/hw/intc/aspeed_intc.h |  46 +
 4 files changed, 408 insertions(+)
 create mode 100644 hw/intc/aspeed_intc.c
 create mode 100644 include/hw/intc/aspeed_intc.h

diff --git a/hw/intc/aspeed_intc.c b/hw/intc/aspeed_intc.c
new file mode 100644
index 00..cb6111d79c
--- /dev/null
+++ b/hw/intc/aspeed_intc.c
@@ -0,0 +1,355 @@
+/*
+ * ASPEED INTC Controller
+ *
+ * Copyright (C) 2024 ASPEED Technology Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "hw/intc/aspeed_intc.h"
+#include "hw/irq.h"
+#include "migration/vmstate.h"
+#include "qemu/bitops.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "hw/intc/arm_gicv3.h"
+#include "trace.h"
+#include "hw/registerfields.h"
+#include "qapi/error.h"
+#include "hw/qdev-properties.h"
+
+/* INTC Registers */
+REG32(GICINT128_EN, 0x1000)
+REG32(GICINT128_STATUS, 0x1004)
+REG32(GICINT129_EN, 0x1100)
+REG32(GICINT129_STATUS, 0x1104)
+REG32(GICINT130_EN, 0x1200)
+REG32(GICINT130_STATUS, 0x1204)
+REG32(GICINT131_EN, 0x1300)
+REG32(GICINT131_STATUS, 0x1304)
+REG32(GICINT132_EN, 0x1400)
+REG32(GICINT132_STATUS, 0x1404)
+REG32(GICINT133_EN, 0x1500

[PATCH v4 03/16] aspeed/sdmc: remove redundant macros

2024-05-27 Thread Jamin Lin via
These macros are no longer used for ASPEED SOCs, so removes them.

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 
Reviewed-by: Cédric Le Goater 
---
 hw/misc/aspeed_sdmc.c | 15 ---
 1 file changed, 15 deletions(-)

diff --git a/hw/misc/aspeed_sdmc.c b/hw/misc/aspeed_sdmc.c
index 64cd1a81dc..74279bbe8e 100644
--- a/hw/misc/aspeed_sdmc.c
+++ b/hw/misc/aspeed_sdmc.c
@@ -76,10 +76,6 @@
 #define ASPEED_SDMC_VGA_32MB0x2
 #define ASPEED_SDMC_VGA_64MB0x3
 #define ASPEED_SDMC_DRAM_SIZE(x)(x & 0x3)
-#define ASPEED_SDMC_DRAM_64MB   0x0
-#define ASPEED_SDMC_DRAM_128MB  0x1
-#define ASPEED_SDMC_DRAM_256MB  0x2
-#define ASPEED_SDMC_DRAM_512MB  0x3
 
 #define ASPEED_SDMC_READONLY_MASK   \
 (ASPEED_SDMC_RESERVED | ASPEED_SDMC_VGA_COMPAT |\
@@ -100,17 +96,6 @@
 #define ASPEED_SDMC_CACHE_ENABLE(1 << 10) /* differs from AST2400 */
 #define ASPEED_SDMC_DRAM_TYPE   (1 << 4)  /* differs from AST2400 */
 
-/* DRAM size definitions differs */
-#define ASPEED_SDMC_AST2500_128MB   0x0
-#define ASPEED_SDMC_AST2500_256MB   0x1
-#define ASPEED_SDMC_AST2500_512MB   0x2
-#define ASPEED_SDMC_AST2500_1024MB  0x3
-
-#define ASPEED_SDMC_AST2600_256MB   0x0
-#define ASPEED_SDMC_AST2600_512MB   0x1
-#define ASPEED_SDMC_AST2600_1024MB  0x2
-#define ASPEED_SDMC_AST2600_2048MB  0x3
-
 #define ASPEED_SDMC_AST2500_READONLY_MASK   \
 (ASPEED_SDMC_HW_VERSION(0xf) | ASPEED_SDMC_CACHE_INITIAL_DONE | \
  ASPEED_SDMC_AST2500_RESERVED | ASPEED_SDMC_VGA_COMPAT |\
-- 
2.25.1




[PATCH v4 05/16] aspeed/sdmc: Add AST2700 support

2024-05-27 Thread Jamin Lin via
The SDRAM memory controller(DRAMC) controls the access to external
DDR4 and DDR5 SDRAM and power up to DDR4 and DDR5 PHY.

The DRAM memory controller of AST2700 is not backward compatible
to previous chips such AST2600, AST2500 and AST2400.

Max memory is now 8GiB on the AST2700. Introduce new
aspeed_2700_sdmc and class with read/write operation and
reset handlers.

Define DRAMC necessary protected registers and
unprotected registers for AST2700 and increase
the register set to 0x1000.

Add unlocked property to change controller protected status.

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 
Reviewed-by: Cédric Le Goater 
---
 hw/misc/aspeed_sdmc.c | 190 +-
 include/hw/misc/aspeed_sdmc.h |   5 +-
 2 files changed, 193 insertions(+), 2 deletions(-)

diff --git a/hw/misc/aspeed_sdmc.c b/hw/misc/aspeed_sdmc.c
index 873d67c592..69a34903db 100644
--- a/hw/misc/aspeed_sdmc.c
+++ b/hw/misc/aspeed_sdmc.c
@@ -27,6 +27,7 @@
 #define   PROT_SOFTLOCKED0x00
 
 #define   PROT_KEY_UNLOCK 0xFC600309
+#define   PROT_2700_KEY_UNLOCK  0x1688A8A8
 #define   PROT_KEY_HARDLOCK   0xDEADDEAD /* AST2600 */
 
 /* Configuration Register */
@@ -54,6 +55,46 @@
 #define R_DRAM_TIME   (0x8c / 4)
 #define R_ECC_ERR_INJECT  (0xb4 / 4)
 
+/* AST2700 Register */
+#define R_2700_PROT (0x00 / 4)
+#define R_INT_STATUS(0x04 / 4)
+#define R_INT_CLEAR (0x08 / 4)
+#define R_INT_MASK  (0x0c / 4)
+#define R_MAIN_CONF (0x10 / 4)
+#define R_MAIN_CONTROL  (0x14 / 4)
+#define R_MAIN_STATUS   (0x18 / 4)
+#define R_ERR_STATUS(0x1c / 4)
+#define R_ECC_FAIL_STATUS   (0x78 / 4)
+#define R_ECC_FAIL_ADDR (0x7c / 4)
+#define R_ECC_TESTING_CONTROL   (0x80 / 4)
+#define R_PROT_REGION_LOCK_STATUS   (0x94 / 4)
+#define R_TEST_FAIL_ADDR(0xd4 / 4)
+#define R_TEST_FAIL_D0  (0xd8 / 4)
+#define R_TEST_FAIL_D1  (0xdc / 4)
+#define R_TEST_FAIL_D2  (0xe0 / 4)
+#define R_TEST_FAIL_D3  (0xe4 / 4)
+#define R_DBG_STATUS(0xf4 / 4)
+#define R_PHY_INTERFACE_STATUS  (0xf8 / 4)
+#define R_GRAPHIC_MEM_BASE_ADDR (0x10c / 4)
+#define R_PORT0_INTERFACE_MONITOR0  (0x240 / 4)
+#define R_PORT0_INTERFACE_MONITOR1  (0x244 / 4)
+#define R_PORT0_INTERFACE_MONITOR2  (0x248 / 4)
+#define R_PORT1_INTERFACE_MONITOR0  (0x2c0 / 4)
+#define R_PORT1_INTERFACE_MONITOR1  (0x2c4 / 4)
+#define R_PORT1_INTERFACE_MONITOR2  (0x2c8 / 4)
+#define R_PORT2_INTERFACE_MONITOR0  (0x340 / 4)
+#define R_PORT2_INTERFACE_MONITOR1  (0x344 / 4)
+#define R_PORT2_INTERFACE_MONITOR2  (0x348 / 4)
+#define R_PORT3_INTERFACE_MONITOR0  (0x3c0 / 4)
+#define R_PORT3_INTERFACE_MONITOR1  (0x3c4 / 4)
+#define R_PORT3_INTERFACE_MONITOR2  (0x3c8 / 4)
+#define R_PORT4_INTERFACE_MONITOR0  (0x440 / 4)
+#define R_PORT4_INTERFACE_MONITOR1  (0x444 / 4)
+#define R_PORT4_INTERFACE_MONITOR2  (0x448 / 4)
+#define R_PORT5_INTERFACE_MONITOR0  (0x4c0 / 4)
+#define R_PORT5_INTERFACE_MONITOR1  (0x4c4 / 4)
+#define R_PORT5_INTERFACE_MONITOR2  (0x4c8 / 4)
+
 /*
  * Configuration register Ox4 (for Aspeed AST2400 SOC)
  *
@@ -101,6 +142,19 @@
  ASPEED_SDMC_AST2500_RESERVED | ASPEED_SDMC_VGA_COMPAT |\
  ASPEED_SDMC_VGA_APERTURE(ASPEED_SDMC_VGA_64MB))
 
+/*
+ * Main Configuration register Ox10 (for Aspeed AST2700 SOC and higher)
+ *
+ */
+#define ASPEED_SDMC_AST2700_RESERVED0x2082 /* 31:16, 13, 7, 1 */
+#define ASPEED_SDMC_AST2700_DATA_SCRAMBLE   (1 << 8)
+#define ASPEED_SDMC_AST2700_ECC_ENABLE  (1 << 6)
+#define ASPEED_SDMC_AST2700_PAGE_MATCHING_ENABLE(1 << 5)
+#define ASPEED_SDMC_AST2700_DRAM_SIZE(x)((x & 0x7) << 2)
+
+#define ASPEED_SDMC_AST2700_READONLY_MASK   \
+ (ASPEED_SDMC_AST2700_RESERVED)
+
 static uint64_t aspeed_sdmc_read(void *opaque, hwaddr addr, unsigned size)
 {
 AspeedSDMCState *s = ASPEED_SDMC(opaque);
@@ -216,7 +270,7 @@ static void aspeed_sdmc_realize(DeviceState *dev, Error 
**errp)
 AspeedSDMCState *s = ASPEED_SDMC(dev);
 AspeedSDMCClass *asc = ASPEED_SDMC_GET_CLASS(s);
 
-assert(asc->max_ram_size < 4 * GiB); /* 32-bit address bus */
+assert(asc->max_ram_size < 4 * GiB || asc->is_bus64bit);
 s->max_ram_size = asc->max_ram_size;
 
 memory_region_init_io(>iomem, OBJECT(s), _sdmc_ops, s,
@@ -236,6 +290,7 @@ static const VMStateDescription vmstate_aspeed_sdmc = {
 
 static Property aspeed_sdmc_properties[] = {
 DEFINE_PROP_UINT64("max-ram-size", AspeedSDMCState, max_ram_size, 0),
+DEFINE_PROP_BOOL("unlocked", AspeedSDMCState, unlocked, false),
 DEFINE_PROP_END_OF_LIST(),
 };
 
@@ -500,12 +555,145 @@ static const TypeInfo aspeed_2600_sdmc_info = {
 .class_init = aspeed_2600_sdmc_class_init,
 };
 
+static void aspeed_2700_sdmc_reset(DeviceState *dev)

[PATCH v4 08/16] aspeed/smc: support 64 bits dma dram address

2024-05-27 Thread Jamin Lin via
AST2700 support the maximum dram size is 8GiB
and has a "DMA DRAM Side Address High Part(0x7C)"
register to support 64 bits dma dram address.
Add helper routines functions to compute the dma dram
address, new features and update trace-event
to support 64 bits dram address.

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 
---
 hw/ssi/aspeed_smc.c | 52 +++--
 hw/ssi/trace-events |  2 +-
 include/hw/ssi/aspeed_smc.h |  1 +
 3 files changed, 46 insertions(+), 9 deletions(-)

diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
index ffb13a12e8..df0c63469c 100644
--- a/hw/ssi/aspeed_smc.c
+++ b/hw/ssi/aspeed_smc.c
@@ -132,6 +132,9 @@
 #define   FMC_WDT2_CTRL_BOOT_SOURCE  BIT(4) /* O: primary 1: alternate */
 #define   FMC_WDT2_CTRL_EN   BIT(0)
 
+/* DMA DRAM Side Address High Part (AST2700) */
+#define R_DMA_DRAM_ADDR_HIGH   (0x7c / 4)
+
 /* DMA Control/Status Register */
 #define R_DMA_CTRL(0x80 / 4)
 #define   DMA_CTRL_REQUEST  (1 << 31)
@@ -187,6 +190,7 @@
  *   0x1FF: 32M bytes
  */
 #define DMA_DRAM_ADDR(asc, val)   ((val) & (asc)->dma_dram_mask)
+#define DMA_DRAM_ADDR_HIGH(val)   ((val) & 0xf)
 #define DMA_FLASH_ADDR(asc, val)  ((val) & (asc)->dma_flash_mask)
 #define DMA_LENGTH(val) ((val) & 0x01FF)
 
@@ -207,6 +211,7 @@ static const AspeedSegments aspeed_2500_spi2_segments[];
 #define ASPEED_SMC_FEATURE_DMA   0x1
 #define ASPEED_SMC_FEATURE_DMA_GRANT 0x2
 #define ASPEED_SMC_FEATURE_WDT_CONTROL 0x4
+#define ASPEED_SMC_FEATURE_DMA_DRAM_ADDR_HIGH 0x08
 
 static inline bool aspeed_smc_has_dma(const AspeedSMCClass *asc)
 {
@@ -218,6 +223,11 @@ static inline bool aspeed_smc_has_wdt_control(const 
AspeedSMCClass *asc)
 return !!(asc->features & ASPEED_SMC_FEATURE_WDT_CONTROL);
 }
 
+static inline bool aspeed_smc_has_dma64(const AspeedSMCClass *asc)
+{
+return !!(asc->features & ASPEED_SMC_FEATURE_DMA_DRAM_ADDR_HIGH);
+}
+
 #define aspeed_smc_error(fmt, ...)  \
 qemu_log_mask(LOG_GUEST_ERROR, "%s: " fmt "\n", __func__, ## __VA_ARGS__)
 
@@ -747,6 +757,8 @@ static uint64_t aspeed_smc_read(void *opaque, hwaddr addr, 
unsigned int size)
 (aspeed_smc_has_dma(asc) && addr == R_DMA_CTRL) ||
 (aspeed_smc_has_dma(asc) && addr == R_DMA_FLASH_ADDR) ||
 (aspeed_smc_has_dma(asc) && addr == R_DMA_DRAM_ADDR) ||
+(aspeed_smc_has_dma(asc) && aspeed_smc_has_dma64(asc) &&
+ addr == R_DMA_DRAM_ADDR_HIGH) ||
 (aspeed_smc_has_dma(asc) && addr == R_DMA_LEN) ||
 (aspeed_smc_has_dma(asc) && addr == R_DMA_CHECKSUM) ||
 (addr >= R_SEG_ADDR0 &&
@@ -847,6 +859,12 @@ static bool aspeed_smc_inject_read_failure(AspeedSMCState 
*s)
 }
 }
 
+static uint64_t aspeed_smc_dma_dram_addr(AspeedSMCState *s)
+{
+return s->regs[R_DMA_DRAM_ADDR] |
+((uint64_t) s->regs[R_DMA_DRAM_ADDR_HIGH] << 32);
+}
+
 static uint32_t aspeed_smc_dma_len(AspeedSMCState *s)
 {
 AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s);
@@ -903,24 +921,34 @@ static void aspeed_smc_dma_checksum(AspeedSMCState *s)
 
 static void aspeed_smc_dma_rw(AspeedSMCState *s)
 {
+AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s);
+uint64_t dma_dram_offset;
+uint64_t dma_dram_addr;
 MemTxResult result;
 uint32_t dma_len;
 uint32_t data;
 
 dma_len = aspeed_smc_dma_len(s);
+dma_dram_addr = aspeed_smc_dma_dram_addr(s);
+
+if (aspeed_smc_has_dma64(asc)) {
+dma_dram_offset = dma_dram_addr - s->dram_base;
+} else {
+dma_dram_offset = dma_dram_addr;
+}
 
 trace_aspeed_smc_dma_rw(s->regs[R_DMA_CTRL] & DMA_CTRL_WRITE ?
 "write" : "read",
 s->regs[R_DMA_FLASH_ADDR],
-s->regs[R_DMA_DRAM_ADDR],
+dma_dram_offset,
 dma_len);
 while (dma_len) {
 if (s->regs[R_DMA_CTRL] & DMA_CTRL_WRITE) {
-data = address_space_ldl_le(>dram_as, s->regs[R_DMA_DRAM_ADDR],
+data = address_space_ldl_le(>dram_as, dma_dram_offset,
 MEMTXATTRS_UNSPECIFIED, );
 if (result != MEMTX_OK) {
-aspeed_smc_error("DRAM read failed @%08x",
- s->regs[R_DMA_DRAM_ADDR]);
+aspeed_smc_error("DRAM read failed @%" PRIx64,
+ dma_dram_offset);
 return;
 }
 
@@ -940,11 +968,11 @@ static void aspeed_smc_dma_rw(AspeedSMCState *s)
 return;
 }
 
-address_space_stl_le(>dram_as, s->regs[R_DMA_DRAM_ADDR],
+address_space_stl_le(>dram_as, dma_dr

[PATCH v4 14/16] aspeed/soc: fix incorrect dram size for AST2700

2024-05-27 Thread Jamin Lin via
AST2700 dram size calculation is not back compatible AST2600.
According to the DDR capacity hardware behavior,
if users write the data to address which is beyond the ram size,
it would write the data to address 0.
For example:
a. sdram base address "0x4 "
b. sdram size is 1 GiB
The available address range is from "0x4 " to "0x4 4000".
If users write 0xdeadbeef to address "0x6 ",
the value of DRAM address 0 (base address 0x4 ) should be 0xdeadbeef.

Add aspeed_soc_ast2700_dram_init to calculate the dram size and add
memory I/O whose address range is from max_ram_size - ram_size to max_ram_size
and its read/write handler to emulate DDR capacity hardware behavior.

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 
---
 hw/arm/aspeed_ast27x0.c | 94 -
 include/hw/arm/aspeed_soc.h |  1 +
 2 files changed, 94 insertions(+), 1 deletion(-)

diff --git a/hw/arm/aspeed_ast27x0.c b/hw/arm/aspeed_ast27x0.c
index a3a03fc1ca..19380087fa 100644
--- a/hw/arm/aspeed_ast27x0.c
+++ b/hw/arm/aspeed_ast27x0.c
@@ -20,6 +20,7 @@
 #include "sysemu/sysemu.h"
 #include "hw/intc/arm_gicv3.h"
 #include "qapi/qmp/qlist.h"
+#include "qemu/log.h"
 
 static const hwaddr aspeed_soc_ast2700_memmap[] = {
 [ASPEED_DEV_SPI_BOOT]  =  0x4,
@@ -191,6 +192,97 @@ static qemu_irq aspeed_soc_ast2700_get_irq(AspeedSoCState 
*s, int dev)
 return qdev_get_gpio_in(a->intc.gic, sc->irqmap[dev]);
 }
 
+static uint64_t aspeed_ram_capacity_read(void *opaque, hwaddr addr,
+unsigned int size)
+{
+qemu_log_mask(LOG_GUEST_ERROR,
+  "%s: read @%" PRIx64 " out of ram size\n",
+   __func__, addr);
+return 0;
+}
+
+static void aspeed_ram_capacity_write(void *opaque, hwaddr addr, uint64_t data,
+unsigned int size)
+{
+AspeedSoCState *s = ASPEED_SOC(opaque);
+uint32_t test_pattern = 0xdeadbeef;
+bool invalid_pattern = true;
+uint32_t *ram_ptr;
+int sz;
+
+ram_ptr = memory_region_get_ram_ptr(s->dram_mr);
+
+   /*
+* Emulate ddr capacity hardware behavior.
+* If writes the test_pattern to address which is beyond the ram size,
+* it would write the test_pattern to address 0.
+*/
+for (sz = 4; sz > 0 ; sz--) {
+test_pattern = (test_pattern << 4) + sz;
+if (data == test_pattern) {
+ram_ptr[0] = test_pattern;
+invalid_pattern = false;
+break;
+}
+}
+
+if (invalid_pattern) {
+qemu_log_mask(LOG_GUEST_ERROR,
+  "%s: write invalid pattern @%" PRIx64
+  " to addr @%" HWADDR_PRIx "]\n",
+  __func__, data, addr);
+}
+}
+
+static const MemoryRegionOps aspeed_ram_capacity_ops = {
+.read = aspeed_ram_capacity_read,
+.write = aspeed_ram_capacity_write,
+.endianness = DEVICE_LITTLE_ENDIAN,
+.valid = {
+.min_access_size = 1,
+.max_access_size = 8,
+},
+};
+
+/*
+ * SDMC should be realized first to get correct RAM size and max size
+ * values
+ */
+static bool aspeed_soc_ast2700_dram_init(DeviceState *dev, Error **errp)
+{
+ram_addr_t ram_size, max_ram_size;
+Aspeed27x0SoCState *a = ASPEED27X0_SOC(dev);
+AspeedSoCState *s = ASPEED_SOC(dev);
+AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
+
+ram_size = object_property_get_uint(OBJECT(>sdmc), "ram-size",
+_abort);
+max_ram_size = object_property_get_uint(OBJECT(>sdmc), "max-ram-size",
+_abort);
+
+memory_region_init(>dram_container, OBJECT(s), "ram-container",
+   ram_size);
+memory_region_add_subregion(>dram_container, 0, s->dram_mr);
+
+/*
+ * Add a memory region beyond the RAM region to emulate
+ * ddr capacity hardware behavior.
+ */
+if (ram_size < max_ram_size) {
+memory_region_init_io(>dram_empty, OBJECT(s),
+  _ram_capacity_ops, s,
+  "ram-empty", max_ram_size - ram_size);
+
+memory_region_add_subregion(s->memory,
+sc->memmap[ASPEED_DEV_SDRAM] + ram_size,
+>dram_empty);
+}
+
+memory_region_add_subregion(s->memory,
+  sc->memmap[ASPEED_DEV_SDRAM], >dram_container);
+return true;
+}
+
 static void aspeed_soc_ast2700_init(Object *obj)
 {
 Aspeed27x0SoCState *a = ASPEED27X0_SOC(obj);
@@ -461,7 +553,7 @@ static void aspeed_soc_ast2700_realize(DeviceState *dev, 
Error **errp)
 sc->memmap[ASPEED_DEV_SDMC]);
 
 /

[PATCH v4 12/16] aspeed/soc: Add AST2700 support

2024-05-27 Thread Jamin Lin via
Initial definitions for a simple machine using an AST2700 SOC (Cortex-a35 CPU).

AST2700 SOC and its interrupt controller are too complex to handle
in the common Aspeed SoC framework. We introduce a new ast2700
class with instance_init and realize handlers.

AST2700 is a 64 bits quad core cpus and support 8 watchdog.
Update maximum ASPEED_CPUS_NUM to 4 and ASPEED_WDTS_NUM to 8.
In addition, update AspeedSocState to support scuio, sli, sliio and intc.

Add TYPE_ASPEED27X0_SOC machine type.

The SDMC controller is unlocked at SPL stage.
At present, only supports to emulate booting
start from u-boot stage. Set SDMC controller
unlocked by default.

In INTC, each interrupt of INT 128 to INT 136 combines 32 interrupts.
It connect GICINT IRQ GPIO-OUTPUT pins to GIC device with irq 128 to 136.
And, if a device irq is 128 to 136, its irq GPIO-OUTPUT pin is connected to
GICINT or-gates instead of GIC device.

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 
---
 hw/arm/aspeed_ast27x0.c | 563 
 hw/arm/meson.build  |   1 +
 include/hw/arm/aspeed_soc.h |  26 +-
 3 files changed, 588 insertions(+), 2 deletions(-)
 create mode 100644 hw/arm/aspeed_ast27x0.c

diff --git a/hw/arm/aspeed_ast27x0.c b/hw/arm/aspeed_ast27x0.c
new file mode 100644
index 00..a3a03fc1ca
--- /dev/null
+++ b/hw/arm/aspeed_ast27x0.c
@@ -0,0 +1,563 @@
+/*
+ * ASPEED SoC 27x0 family
+ *
+ * Copyright (C) 2024 ASPEED Technology Inc.
+ *
+ * This code is licensed under the GPL version 2 or later.  See
+ * the COPYING file in the top-level directory.
+ *
+ * Implementation extracted from the AST2600 and adapted for AST27x0.
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "hw/misc/unimp.h"
+#include "hw/arm/aspeed_soc.h"
+#include "qemu/module.h"
+#include "qemu/error-report.h"
+#include "hw/i2c/aspeed_i2c.h"
+#include "net/net.h"
+#include "sysemu/sysemu.h"
+#include "hw/intc/arm_gicv3.h"
+#include "qapi/qmp/qlist.h"
+
+static const hwaddr aspeed_soc_ast2700_memmap[] = {
+[ASPEED_DEV_SPI_BOOT]  =  0x4,
+[ASPEED_DEV_SRAM]  =  0x1000,
+[ASPEED_DEV_SDMC]  =  0x12C0,
+[ASPEED_DEV_SCU]   =  0x12C02000,
+[ASPEED_DEV_SCUIO] =  0x14C02000,
+[ASPEED_DEV_UART0] =  0X14C33000,
+[ASPEED_DEV_UART1] =  0X14C33100,
+[ASPEED_DEV_UART2] =  0X14C33200,
+[ASPEED_DEV_UART3] =  0X14C33300,
+[ASPEED_DEV_UART4] =  0X12C1A000,
+[ASPEED_DEV_UART5] =  0X14C33400,
+[ASPEED_DEV_UART6] =  0X14C33500,
+[ASPEED_DEV_UART7] =  0X14C33600,
+[ASPEED_DEV_UART8] =  0X14C33700,
+[ASPEED_DEV_UART9] =  0X14C33800,
+[ASPEED_DEV_UART10]=  0X14C33900,
+[ASPEED_DEV_UART11]=  0X14C33A00,
+[ASPEED_DEV_UART12]=  0X14C33B00,
+[ASPEED_DEV_WDT]   =  0x14C37000,
+[ASPEED_DEV_VUART] =  0X14C3,
+[ASPEED_DEV_FMC]   =  0x1400,
+[ASPEED_DEV_SPI0]  =  0x1401,
+[ASPEED_DEV_SPI1]  =  0x1402,
+[ASPEED_DEV_SPI2]  =  0x1403,
+[ASPEED_DEV_SDRAM] =  0x4,
+[ASPEED_DEV_MII1]  =  0x1404,
+[ASPEED_DEV_MII2]  =  0x14040008,
+[ASPEED_DEV_MII3]  =  0x14040010,
+[ASPEED_DEV_ETH1]  =  0x1405,
+[ASPEED_DEV_ETH2]  =  0x1406,
+[ASPEED_DEV_ETH3]  =  0x1407,
+[ASPEED_DEV_EMMC]  =  0x1209,
+[ASPEED_DEV_INTC]  =  0x1210,
+[ASPEED_DEV_SLI]   =  0x12C17000,
+[ASPEED_DEV_SLIIO] =  0x14C1E000,
+[ASPEED_GIC_DIST]  =  0x1220,
+[ASPEED_GIC_REDIST]=  0x1228,
+};
+
+#define AST2700_MAX_IRQ 288
+
+/* Shared Peripheral Interrupt values below are offset by -32 from datasheet */
+static const int aspeed_soc_ast2700_irqmap[] = {
+[ASPEED_DEV_UART0] = 132,
+[ASPEED_DEV_UART1] = 132,
+[ASPEED_DEV_UART2] = 132,
+[ASPEED_DEV_UART3] = 132,
+[ASPEED_DEV_UART4] = 8,
+[ASPEED_DEV_UART5] = 132,
+[ASPEED_DEV_UART6] = 132,
+[ASPEED_DEV_UART7] = 132,
+[ASPEED_DEV_UART8] = 132,
+[ASPEED_DEV_UART9] = 132,
+[ASPEED_DEV_UART10]= 132,
+[ASPEED_DEV_UART11]= 132,
+[ASPEED_DEV_UART12]= 132,
+[ASPEED_DEV_FMC]   = 131,
+[ASPEED_DEV_SDMC]  = 0,
+[ASPEED_DEV_SCU]   = 12,
+[ASPEED_DEV_ADC]   = 130,
+[ASPEED_DEV_XDMA]  = 5,
+[ASPEED_DEV_EMMC]  = 15,
+[ASPEED_DEV_GPIO]  = 11,
+[ASPEED_DEV_GPIO_1_8V] = 130,
+[ASPEED_DEV_RTC]   = 13,
+[ASPEED_DEV_TIMER1]= 16,
+[ASPEED_DEV_TIMER2]= 17,
+[ASPEED_DEV_TIMER3]= 18,
+[ASPEED_DEV_TIMER4]= 19,
+[ASPEED_DEV_TIMER5]= 20,
+[ASPEED_DEV_TIMER6]= 21,
+[ASPEED_DEV_TIMER7]= 22,
+[ASPEED_DEV_TIMER8]= 23,
+[ASPEED_DEV_WDT]   = 131,
+[ASPEED_DE

[PATCH v4 07/16] aspeed/smc: support dma start length and 1 byte length unit

2024-05-27 Thread Jamin Lin via
DMA length is from 1 byte to 32MB for AST2600 and AST10x0
and DMA length is from 4 bytes to 32MB for AST2500.

In other words, if "R_DMA_LEN" is 0, it should move at least 1 byte
data for AST2600 and AST10x0 and 4 bytes data for AST2500.
To support all ASPEED SOCs, adds dma_start_length parameter to store
the start length, add helper routines function to compute the dma length
and update DMA_LENGTH mask to "1FF" to support dma 1 byte
length unit for AST2600 and AST1030.
Currently, only supports dma length 4 bytes aligned.

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 
---
 hw/ssi/aspeed_smc.c | 43 ++---
 include/hw/ssi/aspeed_smc.h |  1 +
 2 files changed, 36 insertions(+), 8 deletions(-)

diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
index 8a8d77b480..ffb13a12e8 100644
--- a/hw/ssi/aspeed_smc.c
+++ b/hw/ssi/aspeed_smc.c
@@ -178,13 +178,17 @@
  * DMA flash addresses should be 4 bytes aligned and the valid address
  * range is 0x2000 - 0x2FFF.
  *
- * DMA length is from 4 bytes to 32MB
+ * DMA length is from 4 bytes to 32MB (AST2500)
  *   0: 4 bytes
- *   0x7F: 32M bytes
+ *   0x1FC: 32M bytes
+ *
+ * DMA length is from 1 byte to 32MB (AST2600, AST10x0)
+ *   0: 1 byte
+ *   0x1FF: 32M bytes
  */
 #define DMA_DRAM_ADDR(asc, val)   ((val) & (asc)->dma_dram_mask)
 #define DMA_FLASH_ADDR(asc, val)  ((val) & (asc)->dma_flash_mask)
-#define DMA_LENGTH(val) ((val) & 0x01FC)
+#define DMA_LENGTH(val) ((val) & 0x01FF)
 
 /* Flash opcodes. */
 #define SPI_OP_READ   0x03/* Read data bytes (low frequency) */
@@ -843,6 +847,13 @@ static bool aspeed_smc_inject_read_failure(AspeedSMCState 
*s)
 }
 }
 
+static uint32_t aspeed_smc_dma_len(AspeedSMCState *s)
+{
+AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s);
+
+return QEMU_ALIGN_UP(s->regs[R_DMA_LEN] + asc->dma_start_length, 4);
+}
+
 /*
  * Accumulate the result of the reads to provide a checksum that will
  * be used to validate the read timing settings.
@@ -850,6 +861,7 @@ static bool aspeed_smc_inject_read_failure(AspeedSMCState 
*s)
 static void aspeed_smc_dma_checksum(AspeedSMCState *s)
 {
 MemTxResult result;
+uint32_t dma_len;
 uint32_t data;
 
 if (s->regs[R_DMA_CTRL] & DMA_CTRL_WRITE) {
@@ -861,7 +873,9 @@ static void aspeed_smc_dma_checksum(AspeedSMCState *s)
 aspeed_smc_dma_calibration(s);
 }
 
-while (s->regs[R_DMA_LEN]) {
+dma_len = aspeed_smc_dma_len(s);
+
+while (dma_len) {
 data = address_space_ldl_le(>flash_as, s->regs[R_DMA_FLASH_ADDR],
 MEMTXATTRS_UNSPECIFIED, );
 if (result != MEMTX_OK) {
@@ -877,7 +891,8 @@ static void aspeed_smc_dma_checksum(AspeedSMCState *s)
  */
 s->regs[R_DMA_CHECKSUM] += data;
 s->regs[R_DMA_FLASH_ADDR] += 4;
-s->regs[R_DMA_LEN] -= 4;
+dma_len -= 4;
+s->regs[R_DMA_LEN] = dma_len;
 }
 
 if (s->inject_failure && aspeed_smc_inject_read_failure(s)) {
@@ -889,14 +904,17 @@ static void aspeed_smc_dma_checksum(AspeedSMCState *s)
 static void aspeed_smc_dma_rw(AspeedSMCState *s)
 {
 MemTxResult result;
+uint32_t dma_len;
 uint32_t data;
 
+dma_len = aspeed_smc_dma_len(s);
+
 trace_aspeed_smc_dma_rw(s->regs[R_DMA_CTRL] & DMA_CTRL_WRITE ?
 "write" : "read",
 s->regs[R_DMA_FLASH_ADDR],
 s->regs[R_DMA_DRAM_ADDR],
-s->regs[R_DMA_LEN]);
-while (s->regs[R_DMA_LEN]) {
+dma_len);
+while (dma_len) {
 if (s->regs[R_DMA_CTRL] & DMA_CTRL_WRITE) {
 data = address_space_ldl_le(>dram_as, s->regs[R_DMA_DRAM_ADDR],
 MEMTXATTRS_UNSPECIFIED, );
@@ -937,7 +955,8 @@ static void aspeed_smc_dma_rw(AspeedSMCState *s)
  */
 s->regs[R_DMA_FLASH_ADDR] += 4;
 s->regs[R_DMA_DRAM_ADDR] += 4;
-s->regs[R_DMA_LEN] -= 4;
+dma_len -= 4;
+s->regs[R_DMA_LEN] = dma_len;
 s->regs[R_DMA_CHECKSUM] += data;
 }
 }
@@ -1381,6 +1400,7 @@ static void aspeed_2400_fmc_class_init(ObjectClass 
*klass, void *data)
 asc->features  = ASPEED_SMC_FEATURE_DMA;
 asc->dma_flash_mask= 0x0FFC;
 asc->dma_dram_mask = 0x1FFC;
+asc->dma_start_length  = 4;
 asc->nregs = ASPEED_SMC_R_MAX;
 asc->segment_to_reg= aspeed_smc_segment_to_reg;
 asc->reg_to_segment= aspeed_smc_reg_to_segment;
@@ -1464,6 +1484,7 @@ static void aspeed_2500_fmc_class_init(ObjectClass 
*klass, void *data)
 asc->features  = ASPEED_SMC_FEATURE_DMA;
 asc->dma_flash_mask= 0x0FFC;
 asc->dma_dram_m

[PATCH v4 00/16] Add AST2700 support

2024-05-27 Thread Jamin Lin via
Changes from v1:
The patch series supports WDT, SDMC, SMC, SCU, SLI and INTC for AST2700 SoC.

Changes from v2:
- replace is_aarch64 with is_bus64bit for sdmc patch review.
- fix incorrect dram size for AST2700

Changes from v3:
- Add AST2700 Evaluation board in ASPEED document
- Add avocado test cases for AST2700 Evaluation board
- Fix reviewers review issues and add reviewers suggestions
- Implement INTC model GICINT 128 to GICINT136 for AST2700

Changes from v4:
- support 64 bits dma dram address associated with review issues
- support dma start length and 1 byte length unit associated with review issues
- refactor intc model to fix serial console stuck issue and associated with 
review issues

Test Version:
https://github.com/qemu/qemu/commit/0c2a3807483b4ebe360cfa475dbfc9dfd2f6d16d

Test steps:
1. Download the latest openbmc image for AST2700 from AspeedTech-BMC/openbmc
   repository, https://github.com/AspeedTech-BMC/openbmc/releases/tag/v09.01
   link: 
https://github.com/AspeedTech-BMC/openbmc/releases/download/v09.01/ast2700-default-obmc.tar.gz
2. untar ast2700-default-obmc.tar.gz
   ```
   tar -xf ast2700-default-obmc.tar.gz
   ```
3. Run and the contents of scripts as following
IMGDIR=ast2700-default
UBOOT_SIZE=$(stat --format=%s -L ${IMGDIR}/u-boot-nodtb.bin)
UBOOT_DTB_ADDR=$((0x4 + ${UBOOT_SIZE}))

qemu-system-aarch64 -M ast2700-evb -nographic\
 -device loader,addr=0x4,file=${IMGDIR}/u-boot-nodtb.bin,force-raw=on\
 -device loader,addr=${UBOOT_DTB_ADDR},file=${IMGDIR}/u-boot.dtb,force-raw=on\
 -device loader,addr=0x43000,file=${IMGDIR}/bl31.bin,force-raw=on\
 -device loader,addr=0x43008,file=${IMGDIR}/optee/tee-raw.bin,force-raw=on\
 -device loader,addr=0x43000,cpu-num=0\
 -device loader,addr=0x43000,cpu-num=1\
 -device loader,addr=0x43000,cpu-num=2\
 -device loader,addr=0x43000,cpu-num=3\
 -smp 4\
 -drive file=${IMGDIR}/image-bmc,format=raw,if=mtd\
 -serial mon:stdio\
 -snapshot

Jamin Lin (16):
  aspeed/wdt: Add AST2700 support
  aspeed/sli: Add AST2700 support
  aspeed/sdmc: remove redundant macros
  aspeed/sdmc: fix coding style
  aspeed/sdmc: Add AST2700 support
  aspeed/smc: correct device description
  aspeed/smc: support dma start length and 1 byte length unit
  aspeed/smc: support 64 bits dma dram address
  aspeed/smc: Add AST2700 support
  aspeed/scu: Add AST2700 support
  aspeed/intc: Add AST2700 support
  aspeed/soc: Add AST2700 support
  aspeed: Add an AST2700 eval board
  aspeed/soc: fix incorrect dram size for AST2700
  test/avocado/machine_aspeed.py: Add AST2700 test case
  docs:aspeed: Add AST2700 Evaluation board

 docs/system/arm/aspeed.rst   |  39 +-
 hw/arm/aspeed.c  |  32 ++
 hw/arm/aspeed_ast27x0.c  | 655 +++
 hw/arm/meson.build   |   1 +
 hw/intc/aspeed_intc.c| 355 +
 hw/intc/meson.build  |   1 +
 hw/intc/trace-events |   6 +
 hw/misc/aspeed_scu.c | 306 ++-
 hw/misc/aspeed_sdmc.c| 216 +-
 hw/misc/aspeed_sli.c | 177 +
 hw/misc/meson.build  |   3 +-
 hw/misc/trace-events |  11 +
 hw/ssi/aspeed_smc.c  | 321 ++-
 hw/ssi/trace-events  |   2 +-
 hw/watchdog/wdt_aspeed.c |  24 ++
 include/hw/arm/aspeed_soc.h  |  27 +-
 include/hw/intc/aspeed_intc.h|  46 +++
 include/hw/misc/aspeed_scu.h |  47 ++-
 include/hw/misc/aspeed_sdmc.h|   5 +-
 include/hw/misc/aspeed_sli.h |  27 ++
 include/hw/ssi/aspeed_smc.h  |   2 +
 include/hw/watchdog/wdt_aspeed.h |   3 +-
 tests/avocado/machine_aspeed.py  |  62 +++
 23 files changed, 2312 insertions(+), 56 deletions(-)
 create mode 100644 hw/arm/aspeed_ast27x0.c
 create mode 100644 hw/intc/aspeed_intc.c
 create mode 100644 hw/misc/aspeed_sli.c
 create mode 100644 include/hw/intc/aspeed_intc.h
 create mode 100644 include/hw/misc/aspeed_sli.h

-- 
2.25.1




[PATCH v4 09/16] aspeed/smc: Add AST2700 support

2024-05-27 Thread Jamin Lin via
AST2700 fmc/spi controller's address decoding unit is 64KB
and only bits [31:16] are used for decoding. Introduce seg_to_reg
and reg_to_seg handlers for ast2700 fmc/spi controller.
In addition, adds ast2700 fmc, spi0, spi1, and spi2 class init handler.

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 
Reviewed-by: Cédric Le Goater 
---
 hw/ssi/aspeed_smc.c | 222 +++-
 1 file changed, 220 insertions(+), 2 deletions(-)

diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
index df0c63469c..b4006c8339 100644
--- a/hw/ssi/aspeed_smc.c
+++ b/hw/ssi/aspeed_smc.c
@@ -185,7 +185,7 @@
  *   0: 4 bytes
  *   0x1FC: 32M bytes
  *
- * DMA length is from 1 byte to 32MB (AST2600, AST10x0)
+ * DMA length is from 1 byte to 32MB (AST2600, AST10x0 and AST2700)
  *   0: 1 byte
  *   0x1FF: 32M bytes
  */
@@ -670,7 +670,7 @@ static const MemoryRegionOps aspeed_smc_flash_ops = {
 .endianness = DEVICE_LITTLE_ENDIAN,
 .valid = {
 .min_access_size = 1,
-.max_access_size = 4,
+.max_access_size = 8,
 },
 };
 
@@ -1926,6 +1926,220 @@ static const TypeInfo aspeed_1030_spi2_info = {
 .class_init = aspeed_1030_spi2_class_init,
 };
 
+/*
+ * The FMC Segment Registers of the AST2700 have a 64KB unit.
+ * Only bits [31:16] are used for decoding.
+ */
+#define AST2700_SEG_ADDR_MASK 0x
+
+static uint32_t aspeed_2700_smc_segment_to_reg(const AspeedSMCState *s,
+   const AspeedSegments *seg)
+{
+uint32_t reg = 0;
+
+/* Disabled segments have a nil register */
+if (!seg->size) {
+return 0;
+}
+
+reg |= (seg->addr & AST2700_SEG_ADDR_MASK) >> 16; /* start offset */
+reg |= (seg->addr + seg->size - 1) & AST2700_SEG_ADDR_MASK; /* end offset 
*/
+return reg;
+}
+
+static void aspeed_2700_smc_reg_to_segment(const AspeedSMCState *s,
+   uint32_t reg, AspeedSegments *seg)
+{
+uint32_t start_offset = (reg << 16) & AST2700_SEG_ADDR_MASK;
+uint32_t end_offset = reg & AST2700_SEG_ADDR_MASK;
+AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s);
+
+if (reg) {
+seg->addr = asc->flash_window_base + start_offset;
+seg->size = end_offset + (64 * KiB) - start_offset;
+} else {
+seg->addr = asc->flash_window_base;
+seg->size = 0;
+}
+}
+
+static const uint32_t aspeed_2700_fmc_resets[ASPEED_SMC_R_MAX] = {
+[R_CONF] = (CONF_FLASH_TYPE_SPI << CONF_FLASH_TYPE0 |
+CONF_FLASH_TYPE_SPI << CONF_FLASH_TYPE1),
+[R_CE_CTRL] = 0xaa00,
+[R_CTRL0] = 0x406b0641,
+[R_CTRL1] = 0x0400,
+[R_CTRL2] = 0x0400,
+[R_CTRL3] = 0x0400,
+[R_SEG_ADDR0] = 0x0800,
+[R_SEG_ADDR1] = 0x1800,
+[R_SEG_ADDR2] = 0x,
+[R_SEG_ADDR3] = 0x,
+[R_DUMMY_DATA] = 0x0001,
+[R_DMA_DRAM_ADDR_HIGH] = 0x,
+[R_TIMINGS] = 0x007b,
+};
+
+static const AspeedSegments aspeed_2700_fmc_segments[] = {
+{ 0x0, 128 * MiB }, /* start address is readonly */
+{ 128 * MiB, 128 * MiB }, /* default is disabled but needed for -kernel */
+{ 256 * MiB, 128 * MiB }, /* default is disabled but needed for -kernel */
+{ 0x0, 0 }, /* disabled */
+};
+
+static void aspeed_2700_fmc_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+AspeedSMCClass *asc = ASPEED_SMC_CLASS(klass);
+
+dc->desc   = "Aspeed 2700 FMC Controller";
+asc->r_conf= R_CONF;
+asc->r_ce_ctrl = R_CE_CTRL;
+asc->r_ctrl0   = R_CTRL0;
+asc->r_timings = R_TIMINGS;
+asc->nregs_timings = 3;
+asc->conf_enable_w0= CONF_ENABLE_W0;
+asc->cs_num_max= 3;
+asc->segments  = aspeed_2700_fmc_segments;
+asc->segment_addr_mask = 0x;
+asc->resets= aspeed_2700_fmc_resets;
+asc->flash_window_base = 0x1;
+asc->flash_window_size = 1 * GiB;
+asc->features  = ASPEED_SMC_FEATURE_DMA |
+ ASPEED_SMC_FEATURE_DMA_DRAM_ADDR_HIGH;
+asc->dma_flash_mask= 0x2FFC;
+asc->dma_dram_mask = 0xFFFC;
+asc->dma_start_length  = 1;
+asc->nregs = ASPEED_SMC_R_MAX;
+asc->segment_to_reg= aspeed_2700_smc_segment_to_reg;
+asc->reg_to_segment= aspeed_2700_smc_reg_to_segment;
+asc->dma_ctrl  = aspeed_2600_smc_dma_ctrl;
+}
+
+static const TypeInfo aspeed_2700_fmc_info = {
+.name =  "aspeed.fmc-ast2700",
+.parent = TYPE_ASPEED_SMC,
+.class_init = aspeed_2700_fmc_class_init,
+};
+
+static const AspeedSegments aspeed_2700_spi0_segments[] = {
+{ 0x0, 128 * MiB }, /* start address is readonly */
+{ 128 * MiB, 128 * MiB }, /* start address is readonly */
+ 

[PATCH v4 13/16] aspeed: Add an AST2700 eval board

2024-05-27 Thread Jamin Lin via
AST2700 CPU is ARM Cortex-A35 which is 64 bits.
Add TARGET_AARCH64 to build this machine.

According to the design of ast2700, it has a bootmcu(riscv-32) which
is used for executing SPL.
Then, CPUs(cortex-a35) execute u-boot, kernel and rofs.

Currently, qemu not support emulate two CPU architectures
at the same machine. Therefore, qemu will only support
to emulate CPU(cortex-a35) side for ast2700

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 
Reviewed-by: Cédric Le Goater 
---
 hw/arm/aspeed.c | 32 
 1 file changed, 32 insertions(+)

diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index 93ca87fda2..40dc0e4c76 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -178,6 +178,12 @@ struct AspeedMachineState {
 #define AST2600_EVB_HW_STRAP1 0x00C0
 #define AST2600_EVB_HW_STRAP2 0x0003
 
+#ifdef TARGET_AARCH64
+/* AST2700 evb hardware value */
+#define AST2700_EVB_HW_STRAP1 0x00C0
+#define AST2700_EVB_HW_STRAP2 0x0003
+#endif
+
 /* Tacoma hardware value */
 #define TACOMA_BMC_HW_STRAP1  0x
 #define TACOMA_BMC_HW_STRAP2  0x0040
@@ -1588,6 +1594,26 @@ static void 
aspeed_minibmc_machine_ast1030_evb_class_init(ObjectClass *oc,
 aspeed_machine_class_init_cpus_defaults(mc);
 }
 
+#ifdef TARGET_AARCH64
+static void aspeed_machine_ast2700_evb_class_init(ObjectClass *oc, void *data)
+{
+MachineClass *mc = MACHINE_CLASS(oc);
+AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
+
+mc->desc = "Aspeed AST2700 EVB (Cortex-A35)";
+amc->soc_name  = "ast2700-a0";
+amc->hw_strap1 = AST2700_EVB_HW_STRAP1;
+amc->hw_strap2 = AST2700_EVB_HW_STRAP2;
+amc->fmc_model = "w25q01jvq";
+amc->spi_model = "w25q512jv";
+amc->num_cs= 2;
+amc->macs_mask = ASPEED_MAC0_ON | ASPEED_MAC1_ON | ASPEED_MAC2_ON;
+amc->uart_default = ASPEED_DEV_UART12;
+mc->default_ram_size = 1 * GiB;
+aspeed_machine_class_init_cpus_defaults(mc);
+}
+#endif
+
 static void aspeed_machine_qcom_dc_scm_v1_class_init(ObjectClass *oc,
  void *data)
 {
@@ -1711,6 +1737,12 @@ static const TypeInfo aspeed_machine_types[] = {
 .name   = MACHINE_TYPE_NAME("ast1030-evb"),
 .parent = TYPE_ASPEED_MACHINE,
 .class_init = aspeed_minibmc_machine_ast1030_evb_class_init,
+#ifdef TARGET_AARCH64
+}, {
+.name  = MACHINE_TYPE_NAME("ast2700-evb"),
+.parent= TYPE_ASPEED_MACHINE,
+.class_init= aspeed_machine_ast2700_evb_class_init,
+#endif
 }, {
 .name  = TYPE_ASPEED_MACHINE,
 .parent= TYPE_MACHINE,
-- 
2.25.1




[PATCH v4 02/16] aspeed/sli: Add AST2700 support

2024-05-27 Thread Jamin Lin via
AST2700 SLI engine is designed to accelerate the
throughput between cross-die connections.
It have CPU_SLI at CPU die and IO_SLI at IO die.

Introduce dummy AST2700 SLI and SLIIO models.

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 
Reviewed-by: Cédric Le Goater 
---
 hw/misc/aspeed_sli.c | 177 +++
 hw/misc/meson.build  |   3 +-
 hw/misc/trace-events |   7 ++
 include/hw/misc/aspeed_sli.h |  27 ++
 4 files changed, 213 insertions(+), 1 deletion(-)
 create mode 100644 hw/misc/aspeed_sli.c
 create mode 100644 include/hw/misc/aspeed_sli.h

diff --git a/hw/misc/aspeed_sli.c b/hw/misc/aspeed_sli.c
new file mode 100644
index 00..fe720ead50
--- /dev/null
+++ b/hw/misc/aspeed_sli.c
@@ -0,0 +1,177 @@
+/*
+ * ASPEED SLI Controller
+ *
+ * Copyright (C) 2024 ASPEED Technology Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "qemu/error-report.h"
+#include "hw/qdev-properties.h"
+#include "hw/misc/aspeed_sli.h"
+#include "qapi/error.h"
+#include "migration/vmstate.h"
+#include "trace.h"
+
+#define SLI_REGION_SIZE 0x500
+#define TO_REG(addr) ((addr) >> 2)
+
+static uint64_t aspeed_sli_read(void *opaque, hwaddr addr, unsigned int size)
+{
+AspeedSLIState *s = ASPEED_SLI(opaque);
+int reg = TO_REG(addr);
+
+if (reg >= ARRAY_SIZE(s->regs)) {
+qemu_log_mask(LOG_GUEST_ERROR,
+  "%s: Out-of-bounds read at offset 0x%" HWADDR_PRIx "\n",
+  __func__, addr);
+return 0;
+}
+
+trace_aspeed_sli_read(addr, size, s->regs[reg]);
+return s->regs[reg];
+}
+
+static void aspeed_sli_write(void *opaque, hwaddr addr, uint64_t data,
+  unsigned int size)
+{
+AspeedSLIState *s = ASPEED_SLI(opaque);
+int reg = TO_REG(addr);
+
+if (reg >= ARRAY_SIZE(s->regs)) {
+qemu_log_mask(LOG_GUEST_ERROR,
+  "%s: Out-of-bounds write at offset 0x%" HWADDR_PRIx "\n",
+  __func__, addr);
+return;
+}
+
+trace_aspeed_sli_write(addr, size, data);
+s->regs[reg] = data;
+}
+
+static uint64_t aspeed_sliio_read(void *opaque, hwaddr addr, unsigned int size)
+{
+AspeedSLIState *s = ASPEED_SLI(opaque);
+int reg = TO_REG(addr);
+
+if (reg >= ARRAY_SIZE(s->regs)) {
+qemu_log_mask(LOG_GUEST_ERROR,
+  "%s: Out-of-bounds read at offset 0x%" HWADDR_PRIx "\n",
+  __func__, addr);
+return 0;
+}
+
+trace_aspeed_sliio_read(addr, size, s->regs[reg]);
+return s->regs[reg];
+}
+
+static void aspeed_sliio_write(void *opaque, hwaddr addr, uint64_t data,
+  unsigned int size)
+{
+AspeedSLIState *s = ASPEED_SLI(opaque);
+int reg = TO_REG(addr);
+
+if (reg >= ARRAY_SIZE(s->regs)) {
+qemu_log_mask(LOG_GUEST_ERROR,
+  "%s: Out-of-bounds write at offset 0x%" HWADDR_PRIx "\n",
+  __func__, addr);
+return;
+}
+
+trace_aspeed_sliio_write(addr, size, data);
+s->regs[reg] = data;
+}
+
+static const MemoryRegionOps aspeed_sli_ops = {
+.read = aspeed_sli_read,
+.write = aspeed_sli_write,
+.endianness = DEVICE_LITTLE_ENDIAN,
+.valid = {
+.min_access_size = 1,
+.max_access_size = 4,
+},
+};
+
+static const MemoryRegionOps aspeed_sliio_ops = {
+.read = aspeed_sliio_read,
+.write = aspeed_sliio_write,
+.endianness = DEVICE_LITTLE_ENDIAN,
+.valid = {
+.min_access_size = 1,
+.max_access_size = 4,
+},
+};
+
+static void aspeed_sli_realize(DeviceState *dev, Error **errp)
+{
+AspeedSLIState *s = ASPEED_SLI(dev);
+SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
+
+memory_region_init_io(>iomem, OBJECT(s), _sli_ops, s,
+  TYPE_ASPEED_SLI, SLI_REGION_SIZE);
+sysbus_init_mmio(sbd, >iomem);
+}
+
+static void aspeed_sliio_realize(DeviceState *dev, Error **errp)
+{
+AspeedSLIState *s = ASPEED_SLI(dev);
+SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
+
+memory_region_init_io(>iomem, OBJECT(s), _sliio_ops, s,
+  TYPE_ASPEED_SLI, SLI_REGION_SIZE);
+sysbus_init_mmio(sbd, >iomem);
+}
+
+static void aspeed_sli_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+
+dc->desc = "Aspeed SLI Controller";
+dc->realize = aspeed_sli_realize;
+}
+
+static const TypeInfo aspeed_sli_info = {
+.name  = TYPE_ASPEED_SLI,
+.parent= TYPE_SYS_BUS_DEVICE,
+.instance_size = sizeof(AspeedSLIState),
+.class_init= aspeed_sli_class_init,
+.abstract  = true,
+};
+
+sta

RE: [PATCH v3 08/16] aspeed/smc: support 64 bits dma dram address

2024-05-27 Thread Jamin Lin
> Hello Jamin,
> 
> 
> [ ... ]
> 
> >> See my aspeed-9.1 branch, I did some changes, mostly in the last patch.
> >>
> >> * aspeed_smc_dma_len()
> >>
> >> - can use QEMU_ALIGN_UP(). simpler.
> >>
> >> * aspeed_smc_dma_rw():
> >>
> >> - dram_addr ->  dma_dram_offset
> >> - There is no need to protect updates of the
> R_DMA_DRAM_ADDR_HIGH
> >>   register with aspeed_smc_has_dma_dram_addr_high() since it is
> >>   already protected with MMIO accesses. Skip the check and update
> >>   always.
> >>
> >> * aspeed_smc_dma_dram_addr()
> >>
> >> - same as above.
> >>
> >> You can merge the changes in the respective patches if you agree.
> >>
> >> Still on the TODO list :
> >>
> >> - GIC review
> >> - aspeed/soc: fix incorrect dram size for AST2700
> >>
> >> Thanks,
> >>
> >> C.
> >>
> > I merged this commit into my code base and thanks for your kindly support.
> >
> https://github.com/legoater/qemu/commit/d1bc2c776422a9d0d6af2b4414fae
> 83fde1832ba
> >
> > About GIC settings, you can refer to our kernel DTS setting for detail.
> >
> https://github.com/AspeedTech-BMC/linux/blob/aspeed-master-v6.6/arch/arm
> 64/boot/dts/aspeed/aspeed-g7.dtsi#L143-L164
> 
> Could you please resend a v4 including all the changes we discussed ?
> 
> Thanks,
> 
> C.
> 
> 
OK
Thanks-Jamin



RE: [PATCH v3 11/16] aspeed/intc: Add AST2700 support

2024-05-21 Thread Jamin Lin
Hi Cedric,

It is a partial block diagram.
Thanks-Jamin

GIC132
  ETH1+---+
+>+0 3|
  ETH2|  4|
+>+1 5|
  ETH3|  6|
+>+219|  INTC  
GIC
  UART0   | 20|+--+
+>+721||  |
+--+
  UART1   | 22||orgate0 +> 
output_pin0+--->+GIC128|
+>+823||  ||
  |
  UART2   | 24||orgate1 +> 
output_pin1+--->+GIC129|
+>+925||  ||
  |
  UART3   | 26||orgate2 +> 
output_pin2+--->+GIC130|
+->10   27||  ||
  |
  UART5   | 28||orgate3 +> 
output_pin3+--->+GIC131|
+>+11   29||  ||
  |
  UART6   |   +--->+orgate4 +> 
output_pin4+--->+GIC132|
+>+12   30||  ||
  |
  UART7   | 31||orgate5 +> 
output_pin5+--->+GIC133|
+>+13 ||  ||
  |
  UART8   |  OR[0:31] ||orgate6 +> 
output_pin6+--->+GIC134|
-->14 ||  ||
  |
  UART9   |   ||orgate7 +> 
output_pin7+--->+GIC135|
->+15 ||  ||
  |
  UART10  |   ||orgate8 +> 
output_pin8+--->+GIC136|
->+16 ||  |
+--+
  UART11  |   |+--+
+>+17 |
  UART12  |   |
+->18 |
  |   |
  |   |
      |       |
  +---+  

> Hi Cedric,
> 
> > Hello Jamin
> >
> > On 4/16/24 11:18, Jamin Lin wrote:
> > > AST2700 interrupt controller(INTC) provides hardware interrupt
> > > interfaces to interrupt of processors PSP, SSP and TSP. In INTC,
> > > each interrupt of INT 128 to INT136 combines 32 interrupts.
> > >
> > > Introduce a new aspeed_intc class with instance_init and realize handlers.
> > >
> > > So far, this model only supports GICINT128 to GICINT136.
> > > It creates 9 GICINT or-gates to connect 32 interrupts sources from
> > > GICINT128 to GICINT136 as IRQ GPIO-OUTPUT pins.
> > > Then, this model registers IRQ handler with its IRQ GPIO-INPUT pins
> > > which connect to GICINT or-gates. And creates 9 GICINT IRQ
> > > GPIO-OUTPUT pins which connect to GIC device with GIC IRQ 128 to 136.
> > >
> > > If one interrupt source from GICINT128 to GICINT136 set irq, the
> > > OR-GATE irq callback function is called and set irq to INTC by
> > > OR-GATE GPIO-OUTPUT pins. Then, the INTC irq callback function is
> > > called and set irq to GIC by its GICINT IRQ GPIO-OUTPUT pins.
> > > Finally, the GIC irq callback function is called and set irq to CPUs
> > > and CPUs execute Interrupt Service Routine (ISR).
> >
> > It is difficult to understand what the model does :/
> >
> I noticed serial console stuck if I run the following commands. In this 
> situation,
> I need to type keyboard any keys to trigger serial interrupt again.
> The contents of my test script as following.
> Test.sh
> ```
> while true;
> do
>   ifconfig
>   ip addr
>   cat /proc/cpuinfo
>   cat /proc/meminfo
>   systemctl status
>   hexdump /dev/mtd0
> done
> ```
> 
> I refactor INTC model and believe this issues has been fixed because I run 
> this
> scripts stress test INTC model over 3 days.
> Could you please help to review the new changes and give me your
> suggestions?
> 
> To make you more understand this model behavior my briefly instruction as
> following.
> 1.A source trigger interrupt from a orgate, the aspeed_intc_set_irq is 
> called.
> In this function, it checks orgate level index from bit 0 to 31 with INTC 
> enable
> variable to find the valid source interrupt.
> Then, set source bit 1 to status register. Finally, FW known to run which 

RE: [PATCH v3 11/16] aspeed/intc: Add AST2700 support

2024-05-21 Thread Jamin Lin
Hi Cedric,

> Hello Jamin
> 
> On 4/16/24 11:18, Jamin Lin wrote:
> > AST2700 interrupt controller(INTC) provides hardware interrupt
> > interfaces to interrupt of processors PSP, SSP and TSP. In INTC, each
> > interrupt of INT 128 to INT136 combines 32 interrupts.
> >
> > Introduce a new aspeed_intc class with instance_init and realize handlers.
> >
> > So far, this model only supports GICINT128 to GICINT136.
> > It creates 9 GICINT or-gates to connect 32 interrupts sources from
> > GICINT128 to GICINT136 as IRQ GPIO-OUTPUT pins.
> > Then, this model registers IRQ handler with its IRQ GPIO-INPUT pins
> > which connect to GICINT or-gates. And creates 9 GICINT IRQ GPIO-OUTPUT
> > pins which connect to GIC device with GIC IRQ 128 to 136.
> >
> > If one interrupt source from GICINT128 to GICINT136 set irq, the
> > OR-GATE irq callback function is called and set irq to INTC by OR-GATE
> > GPIO-OUTPUT pins. Then, the INTC irq callback function is called and
> > set irq to GIC by its GICINT IRQ GPIO-OUTPUT pins. Finally, the GIC
> > irq callback function is called and set irq to CPUs and CPUs execute
> > Interrupt Service Routine (ISR).
> 
> It is difficult to understand what the model does :/
> 
I noticed serial console stuck if I run the following commands. In this 
situation, I need to type keyboard any keys to trigger serial interrupt again.
The contents of my test script as following.
Test.sh
```
while true;
do
  ifconfig
  ip addr
  cat /proc/cpuinfo
  cat /proc/meminfo
  systemctl status
  hexdump /dev/mtd0
done
```

I refactor INTC model and believe this issues has been fixed because I run this 
scripts stress test INTC model over 3 days. 
Could you please help to review the new changes and give me your suggestions?

To make you more understand this model behavior my briefly instruction as 
following.
1.  A source trigger interrupt from a orgate, the aspeed_intc_set_irq is 
called.
In this function, it checks orgate level index from bit 0 to 31 with INTC 
enable variable to find the valid source interrupt.
Then, set source bit 1 to status register. Finally, FW known to run which 
source ISR by reading status register.
https://github.com/AspeedTech-BMC/linux/blob/aspeed-master-v6.6/drivers/irqchip/irq-aspeed-intc.c#L30
 
For example: According to the data sheet description, serial console(tty12) is 
in gic132 at bit18. Therefore, it is in orgate index 4(132-128) and level index 
18.
s->regs[status_addr] = select;
trace_aspeed_intc_debug("trigger source interrupt",
  s->regs[status_addr]);
aspeed_intc_update(s, irq, 1)

2.  Once CPU enters ISR mode, FW masks enable register first, clear source 
bit in status register after it executes source ISR and unmasks enable register.
a.  Mask 
https://github.com/AspeedTech-BMC/linux/blob/aspeed-master-v6.6/drivers/irqchip/irq-aspeed-intc.c#L39
b.  After executes source ISR, clear status register at source bit, 
https://github.com/AspeedTech-BMC/linux/blob/aspeed-master-v6.6/drivers/irqchip/irq-aspeed-intc.c#L33
c.  Unmask 
https://github.com/AspeedTech-BMC/linux/blob/aspeed-master-v6.6/drivers/irqchip/irq-aspeed-intc.c#L46

3.  If status register is 0, it means ALL source ISR execution are done. If 
no pending interrupt, it clear gic else set gic to handle source pending 
interrupts.
/* All source ISR execution are done */
if (!s->regs[addr]) {
  if (s->pending[irq]) {
 /*
  * handle pending source interrupt
  * notify firmware which source interrupt are pending
  * by setting status register
  */
  s->regs[addr] = s->pending[irq];
  s->pending[irq] = 0;
  trace_aspeed_intc_debug("trigger pending interrupt",
   s->regs[addr]);
  aspeed_intc_update(s, irq, 1);
 } else {
   /* clear irq */
   aspeed_intc_update(s, irq, 0);
 }
 }

4.  According to the design of INTC controller, it only have Enable 
register. This register is used for enable source interrupt, mask and unmake 
source interrupt if executing ISR mode.
We don’t know users want to “mask or disable” specific source interrupt because 
it only have one register.
So, I create enable variables to save the source interrupt enable status if 
enable register has been set to 1.

old_enable = s->enable[irq];
s->enable[irq] |= data;

/* enable new source interrupt */
if (old_enable != s->enable[irq]) {
trace_aspeed_intc_debug("enable new source interrupt",
s->enable[irq]);
s->regs[addr] = data;
return;
}

If no new bits set to 1, it means mask/unmask behavior. It set mask status in 
s->mask variables, so aspeed_intc_set_irq function know it is in ISR mode, and 
all source interrupts are saved to pending variables.
After ISR done, t

RE: [PATCH v3 08/16] aspeed/smc: support 64 bits dma dram address

2024-05-19 Thread Jamin Lin
Hi Cedric,

> 
> Hello Jamin
> 
> On 5/15/24 11:01, Jamin Lin wrote:
> > Hi Cedric,
> >
> > Sorry reply you late.
> >> Hello Jamin,
> >>
> >> To handle the DMA DRAM Side Address High register, we should
> >> reintroduce an "dram-base" property which I removed a while ago.
> Something like :
> >>
> >>
> >>
> >> diff --git a/include/hw/ssi/aspeed_smc.h
> >> b/include/hw/ssi/aspeed_smc.h index 7f32e43ff6f3..6d8ef6bc968f 100644
> >> --- a/include/hw/ssi/aspeed_smc.h
> >> +++ b/include/hw/ssi/aspeed_smc.h
> >> @@ -76,6 +76,7 @@ struct AspeedSMCState {
> >>AddressSpace flash_as;
> >>MemoryRegion *dram_mr;
> >>AddressSpace dram_as;
> >> +uint64_t dram_base;
> >>
> >>AddressSpace wdt2_as;
> >>MemoryRegion *wdt2_mr;
> >> diff --git a/hw/arm/aspeed_ast27x0.c b/hw/arm/aspeed_ast27x0.c index
> >> 38858e4fdec1..3417949ad8a3 100644
> >> --- a/hw/arm/aspeed_ast27x0.c
> >> +++ b/hw/arm/aspeed_ast27x0.c
> >> @@ -500,6 +500,8 @@ static void
> >> aspeed_soc_ast2700_realize(DeviceState
> >> *dev, Error **errp)
> >>}
> >>
> >>/* FMC, The number of CS is set at the board level */
> >> +object_property_set_int(OBJECT(>fmc), "dram-base",
> >> +sc->memmap[ASPEED_DEV_SDRAM],
> >> + _abort);
> >>object_property_set_link(OBJECT(>fmc), "dram",
> >> OBJECT(s->dram_mr),
> >> _abort);
> >>if (!sysbus_realize(SYS_BUS_DEVICE(>fmc), errp)) { diff
> >> --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c index
> >> 3fa783578e9e..29ebfc0fd8c8 100644
> >> --- a/hw/ssi/aspeed_smc.c
> >> +++ b/hw/ssi/aspeed_smc.c
> >> @@ -1372,6 +1372,7 @@ static const VMStateDescription
> >> vmstate_aspeed_smc = {
> >>
> >>static Property aspeed_smc_properties[] = {
> >>DEFINE_PROP_BOOL("inject-failure", AspeedSMCState,
> >> inject_failure, false),
> >> +DEFINE_PROP_UINT64("dram-base", AspeedSMCState, dram_base,
> 0),
> >>DEFINE_PROP_LINK("dram", AspeedSMCState, dram_mr,
> >> TYPE_MEMORY_REGION, MemoryRegion *),
> >>DEFINE_PROP_LINK("wdt2", AspeedSMCState, wdt2_mr,
> >>
> >>
> > I appreciate your kindly support and thanks for your suggestion.
> > Will add it.
> 
> See my aspeed-9.1 branch, I did some changes, mostly in the last patch.
> 
> * aspeed_smc_dma_len()
> 
>- can use QEMU_ALIGN_UP(). simpler.
> 
> * aspeed_smc_dma_rw():
> 
>- dram_addr ->  dma_dram_offset
>- There is no need to protect updates of the R_DMA_DRAM_ADDR_HIGH
>  register with aspeed_smc_has_dma_dram_addr_high() since it is
>  already protected with MMIO accesses. Skip the check and update
>  always.
> 
> * aspeed_smc_dma_dram_addr()
> 
>- same as above.
> 
> You can merge the changes in the respective patches if you agree.
> 
> Still on the TODO list :
> 
>- GIC review
>- aspeed/soc: fix incorrect dram size for AST2700
> 
> 
> 
> 
> Thanks,
> 
> C.
> 
I merged this commit into my code base and thanks for your kindly support.
https://github.com/legoater/qemu/commit/d1bc2c776422a9d0d6af2b4414fae83fde1832ba
 

About GIC settings, you can refer to our kernel DTS setting for detail.
https://github.com/AspeedTech-BMC/linux/blob/aspeed-master-v6.6/arch/arm64/boot/dts/aspeed/aspeed-g7.dtsi#L143-L164
 

Thanks-Jamin

> 
> 
> >
> >>
> >> With that, see below for more comments,
> >>
> >> On 4/16/24 11:18, Jamin Lin wrote:
> >>> AST2700 support the maximum dram size is 8GiB and has a "DMA DRAM
> >> Side
> >>> Address High Part(0x7C)"
> >>> register to support 64 bits dma dram address.
> >>> Add helper routines functions to compute the dma dram address, new
> >>> features and update trace-event to support 64 bits dram address.
> >>>
> >>> Signed-off-by: Troy Lee 
> >>> Signed-off-by: Jamin Lin 
> >>> ---
> >>>hw/ssi/aspeed_smc.c | 66
> >> +++--
> >>>hw/ssi/trace-events |  2 +-
> >>>2 files changed, 59 insertions(+), 9 deletions(-)
> >>>
> >>> diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc

RE: [PATCH v3 12/16] aspeed/soc: Add AST2700 support

2024-05-17 Thread Jamin Lin
Hi Cerdric,

> On 4/19/24 09:58, Jamin Lin wrote:
> > Hi Cedric,
> >> On 4/16/24 11:18, Jamin Lin wrote:
> >>> Initial definitions for a simple machine using an AST2700 SOC
> >>> (Cortex-a35
> >> CPU).
> >>>
> >>> AST2700 SOC and its interrupt controller are too complex to handle
> >>> in the common Aspeed SoC framework. We introduce a new ast2700 class
> >>> with instance_init and realize handlers.
> >>>
> >>> AST2700 is a 64 bits quad core cpus and support 8 watchdog.
> >>> Update maximum ASPEED_CPUS_NUM to 4 and ASPEED_WDTS_NUM to
> 8.
> >>> In addition, update AspeedSocState to support scuio, sli, sliio and intc.
> >>>
> >>> Add TYPE_ASPEED27X0_SOC machine type.
> >>>
> >>> The SDMC controller is unlocked at SPL stage.
> >>> At present, only supports to emulate booting start from u-boot stage.
> >>> Set SDMC controller unlocked by default.
> >>>
> >>> In INTC, each interrupt of INT 128 to INT 136 combines 32 interrupts.
> >>> It connect GICINT IRQ GPIO-OUTPUT pins to GIC device with irq 128 to
> 136.
> >>> And, if a device irq is 128 to 136, its irq GPIO-OUTPUT pin is
> >>> connected to GICINT or-gates instead of GIC device.
> >>>
> >>> Signed-off-by: Troy Lee 
> >>> Signed-off-by: Jamin Lin 
> >>
> >> Before I forget, please see a little comment below regarding user
> >> creatable devices.
> >>
> >> The model looks fine. The interrupt controller part is more complex
> >> than the previous SoCs so I will come back to it later when I have more
> time.
> > Thanks for your kindly support.
> >>> ---
> >>>hw/arm/aspeed_ast27x0.c | 554
> >> 
> >>>hw/arm/meson.build  |   1 +
> >>>include/hw/arm/aspeed_soc.h |  26 +-
> >>>3 files changed, 579 insertions(+), 2 deletions(-)
> >>>create mode 100644 hw/arm/aspeed_ast27x0.c
> >>>
> >>> diff --git a/hw/arm/aspeed_ast27x0.c b/hw/arm/aspeed_ast27x0.c new
> >>> file mode 100644 index 00..754c963230
> >>> --- /dev/null
> >>> +++ b/hw/arm/aspeed_ast27x0.c
> >>> @@ -0,0 +1,554 @@
> >>> +/*
> >>> + * ASPEED SoC 27x0 family
> >>> + *
> >>> + * Copyright (C) 2024 ASPEED Technology Inc.
> >>> + *
> >>> + * This code is licensed under the GPL version 2 or later.  See
> >>> + * the COPYING file in the top-level directory.
> >>> + *
> >>> + * Implementation extracted from the AST2600 and adapted for AST27x0.
> >>> + */
> >>> +
> >>> +#include "qemu/osdep.h"
> >>> +#include "qapi/error.h"
> >>> +#include "hw/misc/unimp.h"
> >>> +#include "hw/arm/aspeed_soc.h"
> >>> +#include "qemu/module.h"
> >>> +#include "qemu/error-report.h"
> >>> +#include "hw/i2c/aspeed_i2c.h"
> >>> +#include "net/net.h"
> >>> +#include "sysemu/sysemu.h"
> >>> +#include "hw/intc/arm_gicv3.h"
> >>> +#include "qapi/qmp/qlist.h"
> >>> +
> >>> +static const hwaddr aspeed_soc_ast2700_memmap[] = {
> >>> +[ASPEED_DEV_SPI_BOOT]  =  0x4,
> >>> +[ASPEED_DEV_SRAM]  =  0x1000,
> >>> +[ASPEED_DEV_SDMC]  =  0x12C0,
> >>> +[ASPEED_DEV_SCU]   =  0x12C02000,
> >>> +[ASPEED_DEV_SCUIO] =  0x14C02000,
> >>> +[ASPEED_DEV_UART0] =  0X14C33000,
> >>> +[ASPEED_DEV_UART1] =  0X14C33100,
> >>> +[ASPEED_DEV_UART2] =  0X14C33200,
> >>> +[ASPEED_DEV_UART3] =  0X14C33300,
> >>> +[ASPEED_DEV_UART4] =  0X12C1A000,
> >>> +[ASPEED_DEV_UART5] =  0X14C33400,
> >>> +[ASPEED_DEV_UART6] =  0X14C33500,
> >>> +[ASPEED_DEV_UART7] =  0X14C33600,
> >>> +[ASPEED_DEV_UART8] =  0X14C33700,
> >>> +[ASPEED_DEV_UART9] =  0X14C33800,
> >>> +[ASPEED_DEV_UART10]=  0X14C33900,
> >>> +[ASPEED_DEV_UART11]=  0X14C33A00,
> >>> +[ASPEED_DEV_UART12]=  0X14C33B00,
> >>> +[ASPEED_DEV_WDT]   =  0x14C37000,
> >>> +[ASPEED_DEV_VUART] =  0X14C3,
> >>> +[A

RE: [PATCH v3 08/16] aspeed/smc: support 64 bits dma dram address

2024-05-15 Thread Jamin Lin
Hi Cedric,

Sorry reply you late.
> Hello Jamin,
> 
> To handle the DMA DRAM Side Address High register, we should reintroduce an
> "dram-base" property which I removed a while ago. Something like :
> 
> 
> 
> diff --git a/include/hw/ssi/aspeed_smc.h b/include/hw/ssi/aspeed_smc.h index
> 7f32e43ff6f3..6d8ef6bc968f 100644
> --- a/include/hw/ssi/aspeed_smc.h
> +++ b/include/hw/ssi/aspeed_smc.h
> @@ -76,6 +76,7 @@ struct AspeedSMCState {
>   AddressSpace flash_as;
>   MemoryRegion *dram_mr;
>   AddressSpace dram_as;
> +uint64_t dram_base;
> 
>   AddressSpace wdt2_as;
>   MemoryRegion *wdt2_mr;
> diff --git a/hw/arm/aspeed_ast27x0.c b/hw/arm/aspeed_ast27x0.c index
> 38858e4fdec1..3417949ad8a3 100644
> --- a/hw/arm/aspeed_ast27x0.c
> +++ b/hw/arm/aspeed_ast27x0.c
> @@ -500,6 +500,8 @@ static void aspeed_soc_ast2700_realize(DeviceState
> *dev, Error **errp)
>   }
> 
>   /* FMC, The number of CS is set at the board level */
> +object_property_set_int(OBJECT(>fmc), "dram-base",
> +sc->memmap[ASPEED_DEV_SDRAM],
> + _abort);
>   object_property_set_link(OBJECT(>fmc), "dram",
> OBJECT(s->dram_mr),
>_abort);
>   if (!sysbus_realize(SYS_BUS_DEVICE(>fmc), errp)) { diff --git
> a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c index
> 3fa783578e9e..29ebfc0fd8c8 100644
> --- a/hw/ssi/aspeed_smc.c
> +++ b/hw/ssi/aspeed_smc.c
> @@ -1372,6 +1372,7 @@ static const VMStateDescription
> vmstate_aspeed_smc = {
> 
>   static Property aspeed_smc_properties[] = {
>   DEFINE_PROP_BOOL("inject-failure", AspeedSMCState, inject_failure,
> false),
> +DEFINE_PROP_UINT64("dram-base", AspeedSMCState, dram_base, 0),
>   DEFINE_PROP_LINK("dram", AspeedSMCState, dram_mr,
>TYPE_MEMORY_REGION, MemoryRegion *),
>   DEFINE_PROP_LINK("wdt2", AspeedSMCState, wdt2_mr,
> 
> 
I appreciate your kindly support and thanks for your suggestion.
Will add it. 

> 
> With that, see below for more comments,
> 
> On 4/16/24 11:18, Jamin Lin wrote:
> > AST2700 support the maximum dram size is 8GiB and has a "DMA DRAM
> Side
> > Address High Part(0x7C)"
> > register to support 64 bits dma dram address.
> > Add helper routines functions to compute the dma dram address, new
> > features and update trace-event to support 64 bits dram address.
> >
> > Signed-off-by: Troy Lee 
> > Signed-off-by: Jamin Lin 
> > ---
> >   hw/ssi/aspeed_smc.c | 66
> +++--
> >   hw/ssi/trace-events |  2 +-
> >   2 files changed, 59 insertions(+), 9 deletions(-)
> >
> > diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c index
> > 71abc7a2d8..a67cac3d0f 100644
> > --- a/hw/ssi/aspeed_smc.c
> > +++ b/hw/ssi/aspeed_smc.c
> > @@ -132,6 +132,9 @@
> >   #define   FMC_WDT2_CTRL_BOOT_SOURCE  BIT(4) /* O: primary
> 1: alternate */
> >   #define   FMC_WDT2_CTRL_EN   BIT(0)
> >
> > +/* DMA DRAM Side Address High Part (AST2700) */
> > +#define R_DMA_DRAM_ADDR_HIGH   (0x7c / 4)
> > +
> >   /* DMA Control/Status Register */
> >   #define R_DMA_CTRL(0x80 / 4)
> >   #define   DMA_CTRL_REQUEST  (1 << 31)
> > @@ -187,6 +190,7 @@
> >*   0x1FF: 32M bytes
> >*/
> >   #define DMA_DRAM_ADDR(asc, val)   ((val) & (asc)->dma_dram_mask)
> > +#define DMA_DRAM_ADDR_HIGH(val)   ((val) & 0xf)
> >   #define DMA_FLASH_ADDR(asc, val)  ((val) & (asc)->dma_flash_mask)
> >   #define DMA_LENGTH(val) ((val) & 0x01FF)
> >
> > @@ -207,6 +211,7 @@ static const AspeedSegments
> aspeed_2500_spi2_segments[];
> >   #define ASPEED_SMC_FEATURE_DMA   0x1
> >   #define ASPEED_SMC_FEATURE_DMA_GRANT 0x2
> >   #define ASPEED_SMC_FEATURE_WDT_CONTROL 0x4
> > +#define ASPEED_SMC_FEATURE_DMA_DRAM_ADDR_HIGH 0x08
> >
> >   static inline bool aspeed_smc_has_dma(const AspeedSMCClass *asc)
> >   {
> > @@ -218,6 +223,11 @@ static inline bool
> aspeed_smc_has_wdt_control(const AspeedSMCClass *asc)
> >   return !!(asc->features & ASPEED_SMC_FEATURE_WDT_CONTROL);
> >   }
> >
> > +static inline bool aspeed_smc_has_dma_dram_addr_high(const
> > +AspeedSMCClass *asc) {
> > +return !!(asc->features &
> ASPEED_SMC_FEATURE_DMA_DRAM_ADDR_HIGH);
> > +}
> > +
> >   #define aspeed_smc_error(fmt, ...)
> \
> >   qemu_log_mask(LOG_GUEST_ERROR, "%s: " fmt "\n&q

RE: [PATCH v3 08/16] aspeed/smc: support 64 bits dma dram address

2024-05-15 Thread Jamin Lin
Hi Cedric,

Sorry reply you late.
> Hello Jamin,
> 
> On 4/30/24 09:56, Jamin Lin wrote:
> > Hi Cedric,
> >
> >> -Original Message-
> >> From: Cédric Le Goater 
> >> Sent: Tuesday, April 30, 2024 3:26 PM
> >> To: Jamin Lin ; Peter Maydell
> >> ; Andrew Jeffery
> >> ; Joel Stanley ;
> >> Alistair Francis ; Cleber Rosa
> >> ; Philippe Mathieu-Daudé ;
> >> Wainer dos Santos Moschetta ; Beraldo Leal
> >> ; open list:ASPEED BMCs ;
> open
> >> list:All patches CC here 
> >> Cc: Troy Lee ; Yunlin Tang
> >> 
> >> Subject: Re: [PATCH v3 08/16] aspeed/smc: support 64 bits dma dram
> >> address
> >>
> >> On 4/19/24 08:00, Jamin Lin wrote:
> >>> Hi Cedric,
> >>>>
> >>>> Hello Jamin,
> >>>>
> >>>> On 4/16/24 11:18, Jamin Lin wrote:
> >>>>> AST2700 support the maximum dram size is 8GiB and has a "DMA
> DRAM
> >>>> Side
> >>>>> Address High Part(0x7C)"
> >>>>> register to support 64 bits dma dram address.
> >>>>> Add helper routines functions to compute the dma dram address, new
> >>>>> features and update trace-event to support 64 bits dram address.
> >>>>>
> >>>>> Signed-off-by: Troy Lee 
> >>>>> Signed-off-by: Jamin Lin 
> >>>>> ---
> >>>>> hw/ssi/aspeed_smc.c | 66
> >>>> +++--
> >>>>> hw/ssi/trace-events |  2 +-
> >>>>> 2 files changed, 59 insertions(+), 9 deletions(-)
> >>>>>
> >>>>> diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c index
> >>>>> 71abc7a2d8..a67cac3d0f 100644
> >>>>> --- a/hw/ssi/aspeed_smc.c
> >>>>> +++ b/hw/ssi/aspeed_smc.c
> >>>>> @@ -132,6 +132,9 @@
> >>>>> #define   FMC_WDT2_CTRL_BOOT_SOURCE  BIT(4) /* O:
> >> primary
> >>>> 1: alternate */
> >>>>> #define   FMC_WDT2_CTRL_EN   BIT(0)
> >>>>>
> >>>>> +/* DMA DRAM Side Address High Part (AST2700) */
> >>>>> +#define R_DMA_DRAM_ADDR_HIGH   (0x7c / 4)
> >>>>> +
> >>>>> /* DMA Control/Status Register */
> >>>>> #define R_DMA_CTRL(0x80 / 4)
> >>>>> #define   DMA_CTRL_REQUEST  (1 << 31)
> >>>>> @@ -187,6 +190,7 @@
> >>>>>  *   0x1FF: 32M bytes
> >>>>>  */
> >>>>> #define DMA_DRAM_ADDR(asc, val)   ((val) &
> >> (asc)->dma_dram_mask)
> >>>>> +#define DMA_DRAM_ADDR_HIGH(val)   ((val) & 0xf)
> >>>>> #define DMA_FLASH_ADDR(asc, val)  ((val) &
> >> (asc)->dma_flash_mask)
> >>>>> #define DMA_LENGTH(val) ((val) & 0x01FF)
> >>>>>
> >>>>> @@ -207,6 +211,7 @@ static const AspeedSegments
> >>>> aspeed_2500_spi2_segments[];
> >>>>> #define ASPEED_SMC_FEATURE_DMA   0x1
> >>>>> #define ASPEED_SMC_FEATURE_DMA_GRANT 0x2
> >>>>> #define ASPEED_SMC_FEATURE_WDT_CONTROL 0x4
> >>>>> +#define ASPEED_SMC_FEATURE_DMA_DRAM_ADDR_HIGH 0x08
> >>>>>
> >>>>> static inline bool aspeed_smc_has_dma(const AspeedSMCClass
> *asc)
> >>>>> {
> >>>>> @@ -218,6 +223,11 @@ static inline bool
> >>>> aspeed_smc_has_wdt_control(const AspeedSMCClass *asc)
> >>>>> return !!(asc->features &
> >> ASPEED_SMC_FEATURE_WDT_CONTROL);
> >>>>> }
> >>>>>
> >>>>> +static inline bool aspeed_smc_has_dma_dram_addr_high(const
> >>>>> +AspeedSMCClass *asc)
> >>>>
> >>>> To ease the reading, I would call the helper aspeed_smc_has_dma64()
> >>> Will fix it
> >>>>
> >>>>> +{
> >>>>> +return !!(asc->features &
> >>>> ASPEED_SMC_FEATURE_DMA_DRAM_ADDR_HIGH);
> >>>>> +}
> >>>>> +
> >>>>> #define aspeed_smc_error(fmt, ...)
> >>>> \
> >>>>> qemu_log_mask(LOG_GUEST_ERROR, "%s: " fmt "\n",
> __func__,
> >> ##
>

RE: [PATCH v3 07/16] aspeed/smc: fix dma moving incorrect data length issue

2024-05-14 Thread Jamin Lin
Hi Cedric,

Sorry reply you late.
> On 4/30/24 10:51, Jamin Lin wrote:
> > Hi Cedric,
> >> On 4/19/24 15:41, Cédric Le Goater wrote:
> >>> On 4/16/24 11:18, Jamin Lin wrote:
> >>>> DMA length is from 1 byte to 32MB for AST2600 and AST10x0 and DMA
> >>>> length is from 4 bytes to 32MB for AST2500.
> >>>>
> >>>> In other words, if "R_DMA_LEN" is 0, it should move at least 1 byte
> >>>> data for AST2600 and AST10x0 and 4 bytes data for AST2500.
> >>>>> To support all ASPEED SOCs, adds dma_start_length parameter to
> >>>>> store
> >>>> the start length, add helper routines function to compute the dma
> >>>> length and update DMA_LENGTH mask to "1FF" to fix dma moving
> >>>> incorrect data length issue.
> >>>
> >>> OK. There are two problems to address, the "zero" length transfer
> >>> and the DMA length unit, which is missing today. Newer SoC use a 1
> >>> bit / byte and older ones, AST2400 and AST2500, use 1 bit / 4 bytes.
> >>>
> >>> We can introduce a AspeedSMCClass::dma_len_unit and rework the loop
> to :
> >>>
> >>>       do {
> >>>
> >>>     
> >>>
> >>>      if (s->regs[R_DMA_LEN]) {
> >>>       s->regs[R_DMA_LEN] -= 4 / asc->dma_len_unit;
> >>>       }
> >>>       } while (s->regs[R_DMA_LEN]);
> >>>
> >>> It should fix the current implementation.
> >>
> >>
> >> I checked what FW is doing on a QEMU ast2500-evb machine :
> >>
> >>   U-Boot 2019.04-v00.04.12 (Sep 29 2022 - 10:40:37 +)
> >>   ...
> >>
> >>  Loading Kernel Image ... aspeed_smc_write @0x88 size 4:
> >> 0x80001000
> >>   aspeed_smc_write @0x84 size 4: 0x20100130
> >>   aspeed_smc_write @0x8c size 4: 0x3c6770
> >>   aspeed_smc_write @0x80 size 4: 0x1
> >>   aspeed_smc_dma_rw read flash:@0x00100130 dram:@0x1000
> >> size:0x003c6774
> >>   aspeed_smc_read @0x8 size 4: 0x800
> >>   aspeed_smc_write @0x80 size 4: 0x0
> >>   OK
> >>  Loading Ramdisk to 8fef2000, end 8604 ...
> >> aspeed_smc_write
> >> @0x88 size 4: 0x8fef2000
> >>   aspeed_smc_write @0x84 size 4: 0x204cdde0
> >>   aspeed_smc_write @0x8c size 4: 0x10d604
> >>   aspeed_smc_write @0x80 size 4: 0x1
> >>   aspeed_smc_dma_rw read flash:@0x004cdde0 dram:@0xfef2000
> >> size:0x0010d608
> >>   aspeed_smc_read @0x8 size 4: 0x800
> >>   aspeed_smc_write @0x80 size 4: 0x0
> >>   OK
> >>  Loading Device Tree to 8fee7000, end 8fef135e ...
> >> aspeed_smc_write
> >> @0x88 size 4: 0x8fee7000
> >>   aspeed_smc_write @0x84 size 4: 0x204c69b4
> >>   aspeed_smc_write @0x8c size 4: 0x7360
> >>   aspeed_smc_write @0x80 size 4: 0x1
> >>   aspeed_smc_dma_rw read flash:@0x004c69b4 dram:@0xfee7000
> >> size:0x7364
> >>   aspeed_smc_read @0x8 size 4: 0x800
> >>   aspeed_smc_write @0x80 size 4: 0x0
> >>   OK
> >>
> >>   Starting kernel ...
> >>
> >> It seems that the R_DMA_LEN register is set by FW without taking into
> >> account the length unit ( bit / 4 bytes). Would you know why ?
> >>
After I discussed with designers, my explanation as below.
AST2500 datasheet description:
FMC8C: DMA Length Register
31:25  Reserved(0)
24:2  RW  DMA_LENGTH
  From 4bytes to 32MB
  0: 4bytes
  0x7F: 32MB
1:0   Reserved

If users set this register 0, SPI DMA controller would move 4 bytes data.
If users set this register bits[24:2] 0x7F, SPI DMC controller would move 
32MB data because this register includes reserved bits [1:0].
Ex: bits 24:2 --> 0x7f
   bits 1:0 --> 0 Reserved  
bits[24:0] is (0x1FC + start length 4) --> 200 --> 32MB  
   111       00
LENGTH[24:2] 7   FF   F   FFReserved [1:0]

That was why AST2500 DMA length should 4 bytes alignment and you do not see 
handling length units because it includes reserved bits 1 and 0.
If user want to move 3 bytes data, our firmware set this register 4 ensure it 
4bytes alignment and the value of register as following
bits[2:0] = "b100" Finally, SPI DMA controller move 8 bytes data(4bytes input 
count + start length 4bytes) 

And that was why it set DMA_LENGTH 0x01FC
https:/

RE: [PATCH v3 07/16] aspeed/smc: fix dma moving incorrect data length issue

2024-04-30 Thread Jamin Lin
Hi Cedric,
> On 4/19/24 15:41, Cédric Le Goater wrote:
> > On 4/16/24 11:18, Jamin Lin wrote:
> >> DMA length is from 1 byte to 32MB for AST2600 and AST10x0 and DMA
> >> length is from 4 bytes to 32MB for AST2500.
> >>
> >> In other words, if "R_DMA_LEN" is 0, it should move at least 1 byte
> >> data for AST2600 and AST10x0 and 4 bytes data for AST2500.
> >>> To support all ASPEED SOCs, adds dma_start_length parameter to store
> >> the start length, add helper routines function to compute the dma
> >> length and update DMA_LENGTH mask to "1FF" to fix dma moving
> >> incorrect data length issue.
> >
> > OK. There are two problems to address, the "zero" length transfer and
> > the DMA length unit, which is missing today. Newer SoC use a 1 bit /
> > byte and older ones, AST2400 and AST2500, use 1 bit / 4 bytes.
> >
> > We can introduce a AspeedSMCClass::dma_len_unit and rework the loop to :
> >
> >      do {
> >
> >    
> >
> >     if (s->regs[R_DMA_LEN]) {
> >      s->regs[R_DMA_LEN] -= 4 / asc->dma_len_unit;
> >      }
> >      } while (s->regs[R_DMA_LEN]);
> >
> > It should fix the current implementation.
> 
> 
> I checked what FW is doing on a QEMU ast2500-evb machine :
> 
>  U-Boot 2019.04-v00.04.12 (Sep 29 2022 - 10:40:37 +)
>  ...
> 
> Loading Kernel Image ... aspeed_smc_write @0x88 size 4:
> 0x80001000
>  aspeed_smc_write @0x84 size 4: 0x20100130
>  aspeed_smc_write @0x8c size 4: 0x3c6770
>  aspeed_smc_write @0x80 size 4: 0x1
>  aspeed_smc_dma_rw read flash:@0x00100130 dram:@0x1000
> size:0x003c6774
>  aspeed_smc_read @0x8 size 4: 0x800
>  aspeed_smc_write @0x80 size 4: 0x0
>  OK
> Loading Ramdisk to 8fef2000, end 8604 ... aspeed_smc_write
> @0x88 size 4: 0x8fef2000
>  aspeed_smc_write @0x84 size 4: 0x204cdde0
>  aspeed_smc_write @0x8c size 4: 0x10d604
>  aspeed_smc_write @0x80 size 4: 0x1
>  aspeed_smc_dma_rw read flash:@0x004cdde0 dram:@0xfef2000
> size:0x0010d608
>  aspeed_smc_read @0x8 size 4: 0x800
>  aspeed_smc_write @0x80 size 4: 0x0
>  OK
> Loading Device Tree to 8fee7000, end 8fef135e ... aspeed_smc_write
> @0x88 size 4: 0x8fee7000
>  aspeed_smc_write @0x84 size 4: 0x204c69b4
>  aspeed_smc_write @0x8c size 4: 0x7360
>  aspeed_smc_write @0x80 size 4: 0x1
>  aspeed_smc_dma_rw read flash:@0x004c69b4 dram:@0xfee7000
> size:0x7364
>  aspeed_smc_read @0x8 size 4: 0x800
>  aspeed_smc_write @0x80 size 4: 0x0
>  OK
> 
>  Starting kernel ...
> 
> It seems that the R_DMA_LEN register is set by FW without taking into account
> the length unit ( bit / 4 bytes). Would you know why ?
> 
https://github.com/AspeedTech-BMC/u-boot/blob/aspeed-master-v2019.04/lib/string.c#L559
This line make user input data length 4 bytes alignment.
https://github.com/AspeedTech-BMC/u-boot/blob/aspeed-master-v2019.04/arch/arm/mach-aspeed/ast2500/utils.S#L35
This line set the value of count parameter to AST_FMC_DNA_LENGTH.
AST_FMC_DMA_LENGTH is 4 bytes alignment value.
Example: input 4
((4+3)/4) * 4 --> (7/4) *4 ---> 4
If AST_FMC_DMA_LENGTH is 0, it means it should move 4 bytes data and 
AST_FMC_DMA_LENGTH do not need to be divided by 4. 

> If I change the model to match 1 bit / 4 bytes unit of the R_DMA_LEN register.
> Linux fails to boot. I didn't dig further and this is something we need to
> understand before committing.
> 
> > I don't think this is necessary to add a Fixes tag because the problem
> > has been there for ages and no one reported it. Probably because the
> > only place DMA transfers are used is in U-Boot and transfers have a
> > non-zero length.
> >
> >> Currently, only supports dma length 4 bytes aligned.
> 
> Is this 4 bytes alignment new for the AST2700 or is this something you added
> because the mask of DMA_LENGTH is now relaxed to match all addresses ?
> 
> #define DMA_LENGTH(val) ((val) & 0x01FF)
AST2700, AST2600 and AST1030 is from 1 byte to 1FF, so I change this Micro 
to fix data lost.
https://github.com/AspeedTech-BMC/u-boot/blob/aspeed-master-v2023.10/arch/arm/mach-aspeed/ast2700/spi.c#L186
Please see this line, it decrease dma_len 1 byte first then, set to DMA_LEN 
register because DMA_LEN is 0 which means should move 1 byte data if DMA 
enables for AST2600, AST1030 and AST2700. 
> 
> Thanks,
> 
> C.

Only AST2500 need 4 bytes alignment for DMA Length. However, according to the 
design of sapped_smc_dma_rw function,
it utilizes address_space_stl_le API and it only works data 4 

RE: [PATCH v3 08/16] aspeed/smc: support 64 bits dma dram address

2024-04-30 Thread Jamin Lin
Hi Cedric,

> -Original Message-
> From: Cédric Le Goater 
> Sent: Tuesday, April 30, 2024 3:26 PM
> To: Jamin Lin ; Peter Maydell
> ; Andrew Jeffery ;
> Joel Stanley ; Alistair Francis ; 
> Cleber
> Rosa ; Philippe Mathieu-Daudé ;
> Wainer dos Santos Moschetta ; Beraldo Leal
> ; open list:ASPEED BMCs ; open
> list:All patches CC here 
> Cc: Troy Lee ; Yunlin Tang
> 
> Subject: Re: [PATCH v3 08/16] aspeed/smc: support 64 bits dma dram address
> 
> On 4/19/24 08:00, Jamin Lin wrote:
> > Hi Cedric,
> >>
> >> Hello Jamin,
> >>
> >> On 4/16/24 11:18, Jamin Lin wrote:
> >>> AST2700 support the maximum dram size is 8GiB and has a "DMA DRAM
> >> Side
> >>> Address High Part(0x7C)"
> >>> register to support 64 bits dma dram address.
> >>> Add helper routines functions to compute the dma dram address, new
> >>> features and update trace-event to support 64 bits dram address.
> >>>
> >>> Signed-off-by: Troy Lee 
> >>> Signed-off-by: Jamin Lin 
> >>> ---
> >>>hw/ssi/aspeed_smc.c | 66
> >> +++--
> >>>hw/ssi/trace-events |  2 +-
> >>>2 files changed, 59 insertions(+), 9 deletions(-)
> >>>
> >>> diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c index
> >>> 71abc7a2d8..a67cac3d0f 100644
> >>> --- a/hw/ssi/aspeed_smc.c
> >>> +++ b/hw/ssi/aspeed_smc.c
> >>> @@ -132,6 +132,9 @@
> >>>#define   FMC_WDT2_CTRL_BOOT_SOURCE  BIT(4) /* O:
> primary
> >> 1: alternate */
> >>>#define   FMC_WDT2_CTRL_EN   BIT(0)
> >>>
> >>> +/* DMA DRAM Side Address High Part (AST2700) */
> >>> +#define R_DMA_DRAM_ADDR_HIGH   (0x7c / 4)
> >>> +
> >>>/* DMA Control/Status Register */
> >>>#define R_DMA_CTRL(0x80 / 4)
> >>>#define   DMA_CTRL_REQUEST  (1 << 31)
> >>> @@ -187,6 +190,7 @@
> >>> *   0x1FF: 32M bytes
> >>> */
> >>>#define DMA_DRAM_ADDR(asc, val)   ((val) &
> (asc)->dma_dram_mask)
> >>> +#define DMA_DRAM_ADDR_HIGH(val)   ((val) & 0xf)
> >>>#define DMA_FLASH_ADDR(asc, val)  ((val) &
> (asc)->dma_flash_mask)
> >>>#define DMA_LENGTH(val) ((val) & 0x01FF)
> >>>
> >>> @@ -207,6 +211,7 @@ static const AspeedSegments
> >> aspeed_2500_spi2_segments[];
> >>>#define ASPEED_SMC_FEATURE_DMA   0x1
> >>>#define ASPEED_SMC_FEATURE_DMA_GRANT 0x2
> >>>#define ASPEED_SMC_FEATURE_WDT_CONTROL 0x4
> >>> +#define ASPEED_SMC_FEATURE_DMA_DRAM_ADDR_HIGH 0x08
> >>>
> >>>static inline bool aspeed_smc_has_dma(const AspeedSMCClass *asc)
> >>>{
> >>> @@ -218,6 +223,11 @@ static inline bool
> >> aspeed_smc_has_wdt_control(const AspeedSMCClass *asc)
> >>>return !!(asc->features &
> ASPEED_SMC_FEATURE_WDT_CONTROL);
> >>>}
> >>>
> >>> +static inline bool aspeed_smc_has_dma_dram_addr_high(const
> >>> +AspeedSMCClass *asc)
> >>
> >> To ease the reading, I would call the helper aspeed_smc_has_dma64()
> > Will fix it
> >>
> >>> +{
> >>> +return !!(asc->features &
> >> ASPEED_SMC_FEATURE_DMA_DRAM_ADDR_HIGH);
> >>> +}
> >>> +
> >>>#define aspeed_smc_error(fmt, ...)
> >> \
> >>>qemu_log_mask(LOG_GUEST_ERROR, "%s: " fmt "\n", __func__,
> ##
> >>> __VA_ARGS__)
> >>>
> >>> @@ -747,6 +757,9 @@ static uint64_t aspeed_smc_read(void *opaque,
> >> hwaddr addr, unsigned int size)
> >>>(aspeed_smc_has_dma(asc) && addr == R_DMA_CTRL) ||
> >>>(aspeed_smc_has_dma(asc) && addr ==
> R_DMA_FLASH_ADDR)
> >> ||
> >>>(aspeed_smc_has_dma(asc) && addr ==
> R_DMA_DRAM_ADDR)
> >> ||
> >>> +(aspeed_smc_has_dma(asc) &&
> >>> + aspeed_smc_has_dma_dram_addr_high(asc) &&
> >>> + addr == R_DMA_DRAM_ADDR_HIGH) ||
> >>>(aspeed_smc_has_dma(asc) && addr == R_DMA_LEN) ||
> >>>(aspeed_smc_has_dma(asc) && addr ==
> R_DMA_CHECKSUM)
> >> ||
> >>>(addr >= R_SEG_ADD

RE: [PATCH v3 12/16] aspeed/soc: Add AST2700 support

2024-04-19 Thread Jamin Lin
Hi Cedric, 
> On 4/16/24 11:18, Jamin Lin wrote:
> > Initial definitions for a simple machine using an AST2700 SOC (Cortex-a35
> CPU).
> >
> > AST2700 SOC and its interrupt controller are too complex to handle in
> > the common Aspeed SoC framework. We introduce a new ast2700 class with
> > instance_init and realize handlers.
> >
> > AST2700 is a 64 bits quad core cpus and support 8 watchdog.
> > Update maximum ASPEED_CPUS_NUM to 4 and ASPEED_WDTS_NUM to 8.
> > In addition, update AspeedSocState to support scuio, sli, sliio and intc.
> >
> > Add TYPE_ASPEED27X0_SOC machine type.
> >
> > The SDMC controller is unlocked at SPL stage.
> > At present, only supports to emulate booting start from u-boot stage.
> > Set SDMC controller unlocked by default.
> >
> > In INTC, each interrupt of INT 128 to INT 136 combines 32 interrupts.
> > It connect GICINT IRQ GPIO-OUTPUT pins to GIC device with irq 128 to 136.
> > And, if a device irq is 128 to 136, its irq GPIO-OUTPUT pin is
> > connected to GICINT or-gates instead of GIC device.
> >
> > Signed-off-by: Troy Lee 
> > Signed-off-by: Jamin Lin 
> 
> Before I forget, please see a little comment below regarding user creatable
> devices.
> 
> The model looks fine. The interrupt controller part is more complex than the
> previous SoCs so I will come back to it later when I have more time. 
Thanks for your kindly support.
> > ---
> >   hw/arm/aspeed_ast27x0.c | 554
> 
> >   hw/arm/meson.build  |   1 +
> >   include/hw/arm/aspeed_soc.h |  26 +-
> >   3 files changed, 579 insertions(+), 2 deletions(-)
> >   create mode 100644 hw/arm/aspeed_ast27x0.c
> >
> > diff --git a/hw/arm/aspeed_ast27x0.c b/hw/arm/aspeed_ast27x0.c new
> > file mode 100644 index 00..754c963230
> > --- /dev/null
> > +++ b/hw/arm/aspeed_ast27x0.c
> > @@ -0,0 +1,554 @@
> > +/*
> > + * ASPEED SoC 27x0 family
> > + *
> > + * Copyright (C) 2024 ASPEED Technology Inc.
> > + *
> > + * This code is licensed under the GPL version 2 or later.  See
> > + * the COPYING file in the top-level directory.
> > + *
> > + * Implementation extracted from the AST2600 and adapted for AST27x0.
> > + */
> > +
> > +#include "qemu/osdep.h"
> > +#include "qapi/error.h"
> > +#include "hw/misc/unimp.h"
> > +#include "hw/arm/aspeed_soc.h"
> > +#include "qemu/module.h"
> > +#include "qemu/error-report.h"
> > +#include "hw/i2c/aspeed_i2c.h"
> > +#include "net/net.h"
> > +#include "sysemu/sysemu.h"
> > +#include "hw/intc/arm_gicv3.h"
> > +#include "qapi/qmp/qlist.h"
> > +
> > +static const hwaddr aspeed_soc_ast2700_memmap[] = {
> > +[ASPEED_DEV_SPI_BOOT]  =  0x4,
> > +[ASPEED_DEV_SRAM]  =  0x1000,
> > +[ASPEED_DEV_SDMC]  =  0x12C0,
> > +[ASPEED_DEV_SCU]   =  0x12C02000,
> > +[ASPEED_DEV_SCUIO] =  0x14C02000,
> > +[ASPEED_DEV_UART0] =  0X14C33000,
> > +[ASPEED_DEV_UART1] =  0X14C33100,
> > +[ASPEED_DEV_UART2] =  0X14C33200,
> > +[ASPEED_DEV_UART3] =  0X14C33300,
> > +[ASPEED_DEV_UART4] =  0X12C1A000,
> > +[ASPEED_DEV_UART5] =  0X14C33400,
> > +[ASPEED_DEV_UART6] =  0X14C33500,
> > +[ASPEED_DEV_UART7] =  0X14C33600,
> > +[ASPEED_DEV_UART8] =  0X14C33700,
> > +[ASPEED_DEV_UART9] =  0X14C33800,
> > +[ASPEED_DEV_UART10]=  0X14C33900,
> > +[ASPEED_DEV_UART11]=  0X14C33A00,
> > +[ASPEED_DEV_UART12]=  0X14C33B00,
> > +[ASPEED_DEV_WDT]   =  0x14C37000,
> > +[ASPEED_DEV_VUART] =  0X14C3,
> > +[ASPEED_DEV_FMC]   =  0x1400,
> > +[ASPEED_DEV_SPI0]  =  0x1401,
> > +[ASPEED_DEV_SPI1]  =  0x1402,
> > +[ASPEED_DEV_SPI2]  =  0x1403,
> > +[ASPEED_DEV_SDRAM] =  0x4,
> > +[ASPEED_DEV_MII1]  =  0x1404,
> > +[ASPEED_DEV_MII2]  =  0x14040008,
> > +[ASPEED_DEV_MII3]  =  0x14040010,
> > +[ASPEED_DEV_ETH1]  =  0x1405,
> > +[ASPEED_DEV_ETH2]  =  0x1406,
> > +[ASPEED_DEV_ETH3]  =  0x1407,
> > +[ASPEED_DEV_EMMC]  =  0x1209,
> > +[ASPEED_DEV_INTC]  =  0x1210,
> > +[ASPEED_DEV_SLI]   =  0x12C17000,
> > +[ASPEED_DEV_SLIIO] =  0x14C1E000,
> > +[ASPEED_GIC_DIST]  =  0x122000

RE: [PATCH v3 08/16] aspeed/smc: support 64 bits dma dram address

2024-04-19 Thread Jamin Lin
Hi Cedric,
> 
> Hello Jamin,
> 
> On 4/16/24 11:18, Jamin Lin wrote:
> > AST2700 support the maximum dram size is 8GiB and has a "DMA DRAM
> Side
> > Address High Part(0x7C)"
> > register to support 64 bits dma dram address.
> > Add helper routines functions to compute the dma dram address, new
> > features and update trace-event to support 64 bits dram address.
> >
> > Signed-off-by: Troy Lee 
> > Signed-off-by: Jamin Lin 
> > ---
> >   hw/ssi/aspeed_smc.c | 66
> +++--
> >   hw/ssi/trace-events |  2 +-
> >   2 files changed, 59 insertions(+), 9 deletions(-)
> >
> > diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c index
> > 71abc7a2d8..a67cac3d0f 100644
> > --- a/hw/ssi/aspeed_smc.c
> > +++ b/hw/ssi/aspeed_smc.c
> > @@ -132,6 +132,9 @@
> >   #define   FMC_WDT2_CTRL_BOOT_SOURCE  BIT(4) /* O: primary
> 1: alternate */
> >   #define   FMC_WDT2_CTRL_EN   BIT(0)
> >
> > +/* DMA DRAM Side Address High Part (AST2700) */
> > +#define R_DMA_DRAM_ADDR_HIGH   (0x7c / 4)
> > +
> >   /* DMA Control/Status Register */
> >   #define R_DMA_CTRL(0x80 / 4)
> >   #define   DMA_CTRL_REQUEST  (1 << 31)
> > @@ -187,6 +190,7 @@
> >*   0x1FF: 32M bytes
> >*/
> >   #define DMA_DRAM_ADDR(asc, val)   ((val) & (asc)->dma_dram_mask)
> > +#define DMA_DRAM_ADDR_HIGH(val)   ((val) & 0xf)
> >   #define DMA_FLASH_ADDR(asc, val)  ((val) & (asc)->dma_flash_mask)
> >   #define DMA_LENGTH(val) ((val) & 0x01FF)
> >
> > @@ -207,6 +211,7 @@ static const AspeedSegments
> aspeed_2500_spi2_segments[];
> >   #define ASPEED_SMC_FEATURE_DMA   0x1
> >   #define ASPEED_SMC_FEATURE_DMA_GRANT 0x2
> >   #define ASPEED_SMC_FEATURE_WDT_CONTROL 0x4
> > +#define ASPEED_SMC_FEATURE_DMA_DRAM_ADDR_HIGH 0x08
> >
> >   static inline bool aspeed_smc_has_dma(const AspeedSMCClass *asc)
> >   {
> > @@ -218,6 +223,11 @@ static inline bool
> aspeed_smc_has_wdt_control(const AspeedSMCClass *asc)
> >   return !!(asc->features & ASPEED_SMC_FEATURE_WDT_CONTROL);
> >   }
> >
> > +static inline bool aspeed_smc_has_dma_dram_addr_high(const
> > +AspeedSMCClass *asc)
> 
> To ease the reading, I would call the helper aspeed_smc_has_dma64()
Will fix it
> 
> > +{
> > +return !!(asc->features &
> ASPEED_SMC_FEATURE_DMA_DRAM_ADDR_HIGH);
> > +}
> > +
> >   #define aspeed_smc_error(fmt, ...)
> \
> >   qemu_log_mask(LOG_GUEST_ERROR, "%s: " fmt "\n", __func__, ##
> > __VA_ARGS__)
> >
> > @@ -747,6 +757,9 @@ static uint64_t aspeed_smc_read(void *opaque,
> hwaddr addr, unsigned int size)
> >   (aspeed_smc_has_dma(asc) && addr == R_DMA_CTRL) ||
> >   (aspeed_smc_has_dma(asc) && addr == R_DMA_FLASH_ADDR)
> ||
> >   (aspeed_smc_has_dma(asc) && addr == R_DMA_DRAM_ADDR)
> ||
> > +(aspeed_smc_has_dma(asc) &&
> > + aspeed_smc_has_dma_dram_addr_high(asc) &&
> > + addr == R_DMA_DRAM_ADDR_HIGH) ||
> >   (aspeed_smc_has_dma(asc) && addr == R_DMA_LEN) ||
> >   (aspeed_smc_has_dma(asc) && addr == R_DMA_CHECKSUM)
> ||
> >   (addr >= R_SEG_ADDR0 &&
> > @@ -847,6 +860,23 @@ static bool
> aspeed_smc_inject_read_failure(AspeedSMCState *s)
> >   }
> >   }
> >
> > +static uint64_t aspeed_smc_dma_dram_addr(AspeedSMCState *s) {
> > +AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s);
> > +uint64_t dram_addr_high;
> > +uint64_t dma_dram_addr;
> > +
> > +if (aspeed_smc_has_dma_dram_addr_high(asc)) {
> > +dram_addr_high = s->regs[R_DMA_DRAM_ADDR_HIGH];
> > +dram_addr_high <<= 32;
> > +dma_dram_addr = dram_addr_high |
> s->regs[R_DMA_DRAM_ADDR];
> 
> Here is a proposal to shorten the routine :
> 
>  return ((uint64_t) s->regs[R_DMA_DRAM_ADDR_HIGH] << 32) |
>  s->regs[R_DMA_DRAM_ADDR];
> 
> 
> > +} else {
> > +dma_dram_addr = s->regs[R_DMA_DRAM_ADDR];
> 
> and
>  return s->regs[R_DMA_DRAM_ADDR];
> 
> > +}
> > +
> > +return dma_dram_addr;
> > +}
> > +
Thanks for your suggestion. Will fix.
> >   static uint32_t aspeed_smc_dma_len(AspeedSMCState *s)
> >   {
> >   AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s); @@ -914,24
> > +944,34 @@ static void aspeed_sm

[PATCH v3 16/16] docs:aspeed: Add AST2700 Evaluation board

2024-04-16 Thread Jamin Lin via
Add AST2700 Evaluation board and its boot command.

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 
---
 docs/system/arm/aspeed.rst | 39 ++
 1 file changed, 35 insertions(+), 4 deletions(-)

diff --git a/docs/system/arm/aspeed.rst b/docs/system/arm/aspeed.rst
index b2dea54eed..320ff2a4cd 100644
--- a/docs/system/arm/aspeed.rst
+++ b/docs/system/arm/aspeed.rst
@@ -1,11 +1,12 @@
-Aspeed family boards (``*-bmc``, ``ast2500-evb``, ``ast2600-evb``)
-==
+Aspeed family boards (``*-bmc``, ``ast2500-evb``, ``ast2600-evb``, 
``ast2700-evb``)
+===
 
 The QEMU Aspeed machines model BMCs of various OpenPOWER systems and
 Aspeed evaluation boards. They are based on different releases of the
 Aspeed SoC : the AST2400 integrating an ARM926EJ-S CPU (400MHz), the
-AST2500 with an ARM1176JZS CPU (800MHz) and more recently the AST2600
-with dual cores ARM Cortex-A7 CPUs (1.2GHz).
+AST2500 with an ARM1176JZS CPU (800MHz), the AST2600
+with dual cores ARM Cortex-A7 CPUs (1.2GHz) and more recently the AST2700
+with quad cores ARM Cortex-A35 64 bits CPUs (1.6GHz)
 
 The SoC comes with RAM, Gigabit ethernet, USB, SD/MMC, USB, SPI, I2C,
 etc.
@@ -38,6 +39,10 @@ AST2600 SoC based machines :
 - ``qcom-dc-scm-v1-bmc``   Qualcomm DC-SCM V1 BMC
 - ``qcom-firework-bmc``Qualcomm Firework BMC
 
+AST2700 SoC based machines :
+
+- ``ast2700-evb``  Aspeed AST2700 Evaluation board (Cortex-A35)
+
 Supported devices
 -
 
@@ -66,6 +71,7 @@ Supported devices
  * eMMC Boot Controller (dummy)
  * PECI Controller (minimal)
  * I3C Controller
+ * Internal Bridge Controller (SLI dummy)
 
 
 Missing devices
@@ -95,6 +101,10 @@ or directly from the OpenBMC GitHub release repository :
 
https://github.com/openbmc/openbmc/releases
 
+or directly from the ASPEED Forked OpenBMC GitHub release repository :
+
+   https://github.com/AspeedTech-BMC/openbmc/releases
+
 To boot a kernel directly from a Linux build tree:
 
 .. code-block:: bash
@@ -164,6 +174,27 @@ under Linux), use :
 
   -M ast2500-evb,bmc-console=uart3
 
+
+Boot the AST2700 machine from the flash image, use an MTD drive :
+
+.. code-block:: bash
+
+  IMGDIR=ast2700-default
+  UBOOT_SIZE=$(stat --format=%s -L ${IMGDIR}/u-boot-nodtb.bin)
+
+  $ qemu-system-aarch64 -M ast2700-evb \
+   -device 
loader,force-raw=on,addr=0x4,file=${IMGDIR}/u-boot-nodtb.bin \
+   -device loader,force-raw=on,addr=$((0x4 + 
${UBOOT_SIZE})),file=u-boot.dtb \
+   -device loader,force-raw=on,addr=0x43000,file=${IMGDIR}/bl31.bin \
+   -device 
loader,force-raw=on,addr=0x43008,file=${IMGDIR}/optee/tee-raw.bin \
+   -device loader,cpu-num=0,addr=0x43000 \
+   -device loader,cpu-num=1,addr=0x43000 \
+   -device loader,cpu-num=2,addr=0x43000 \
+   -device loader,cpu-num=3,addr=0x43000 \
+   -smp 4 \
+   -drive file=${IMGDIR}/image-bmc,format=raw,if=mtd \
+   -nographic
+
 Aspeed minibmc family boards (``ast1030-evb``)
 ==
 
-- 
2.25.1




[PATCH v3 11/16] aspeed/intc: Add AST2700 support

2024-04-16 Thread Jamin Lin via
AST2700 interrupt controller(INTC) provides hardware interrupt interfaces
to interrupt of processors PSP, SSP and TSP. In INTC, each interrupt of
INT 128 to INT136 combines 32 interrupts.

Introduce a new aspeed_intc class with instance_init and realize handlers.

So far, this model only supports GICINT128 to GICINT136.
It creates 9 GICINT or-gates to connect 32 interrupts sources
from GICINT128 to GICINT136 as IRQ GPIO-OUTPUT pins.
Then, this model registers IRQ handler with its IRQ GPIO-INPUT pins which
connect to GICINT or-gates. And creates 9 GICINT IRQ GPIO-OUTPUT pins which
connect to GIC device with GIC IRQ 128 to 136.

If one interrupt source from GICINT128 to GICINT136
set irq, the OR-GATE irq callback function is called and set irq to INTC by
OR-GATE GPIO-OUTPUT pins. Then, the INTC irq callback function is called and
set irq to GIC by its GICINT IRQ GPIO-OUTPUT pins. Finally, the GIC irq
callback function is called and set irq to CPUs and
CPUs execute Interrupt Service Routine (ISR).

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 
---
 hw/intc/aspeed_intc.c | 269 ++
 hw/intc/meson.build   |   1 +
 hw/intc/trace-events  |   6 +
 include/hw/intc/aspeed_intc.h |  35 +
 4 files changed, 311 insertions(+)
 create mode 100644 hw/intc/aspeed_intc.c
 create mode 100644 include/hw/intc/aspeed_intc.h

diff --git a/hw/intc/aspeed_intc.c b/hw/intc/aspeed_intc.c
new file mode 100644
index 00..df31900d56
--- /dev/null
+++ b/hw/intc/aspeed_intc.c
@@ -0,0 +1,269 @@
+/*
+ * ASPEED INTC Controller
+ *
+ * Copyright (C) 2024 ASPEED Technology Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "hw/intc/aspeed_intc.h"
+#include "hw/irq.h"
+#include "migration/vmstate.h"
+#include "qemu/bitops.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "hw/intc/arm_gicv3.h"
+#include "trace.h"
+#include "hw/registerfields.h"
+#include "qapi/error.h"
+
+/* INTC Registers */
+REG32(GICINT128_EN, 0x1000)
+REG32(GICINT128_STATUS, 0x1004)
+REG32(GICINT129_EN, 0x1100)
+REG32(GICINT129_STATUS, 0x1104)
+REG32(GICINT130_EN, 0x1200)
+REG32(GICINT130_STATUS, 0x1204)
+REG32(GICINT131_EN, 0x1300)
+REG32(GICINT131_STATUS, 0x1304)
+REG32(GICINT132_EN, 0x1400)
+REG32(GICINT132_STATUS, 0x1404)
+REG32(GICINT133_EN, 0x1500)
+REG32(GICINT133_STATUS, 0x1504)
+REG32(GICINT134_EN, 0x1600)
+REG32(GICINT134_STATUS, 0x1604)
+REG32(GICINT135_EN, 0x1700)
+REG32(GICINT135_STATUS, 0x1704)
+REG32(GICINT136_EN, 0x1800)
+REG32(GICINT136_STATUS, 0x1804)
+
+#define GICINT_EN_BASE R_GICINT128_EN
+
+/*
+ * The address of GICINT128 to GICINT136 are from 0x1000 to 0x1804.
+ * Utilize "address & 0x0f00" to get the gicint_out index and
+ * its gic irq.
+ */
+static void aspeed_intc_update(AspeedINTCState *s, int irq, int level)
+{
+uint32_t gicint_enable_addr = GICINT_EN_BASE + ((0x100 * irq) >> 2);
+uint32_t gicint_status_addr = gicint_enable_addr + (0x4 >> 2);
+
+if (s->trigger[irq]) {
+if (!level && !s->regs[gicint_status_addr]) {
+/* clear irq */
+trace_aspeed_intc_update_irq(irq, 0);
+qemu_set_irq(s->gicint_out[irq], 0);
+s->trigger[irq] = false;
+}
+} else {
+if (s->new_gicint_status[irq]) {
+/* set irq */
+trace_aspeed_intc_update_irq(irq, 1);
+s->regs[gicint_status_addr] = s->new_gicint_status[irq];
+s->new_gicint_status[irq] = 0;
+qemu_set_irq(s->gicint_out[irq], 1);
+s->trigger[irq] = true;
+}
+}
+}
+
+/*
+ * The value of irq should be 0 to ASPEED_INTC_NR_GICS.
+ * The irq 0 indicates GICINT128, irq 1 indicates GICINT129 and so on.
+ */
+static void aspeed_intc_set_irq(void *opaque, int irq, int level)
+{
+AspeedINTCState *s = (AspeedINTCState *)opaque;
+uint32_t gicint_enable_addr = GICINT_EN_BASE + ((0x100 * irq) >> 2);
+uint32_t enable = s->regs[gicint_enable_addr];
+int i;
+
+if (irq > ASPEED_INTC_NR_GICS) {
+qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid interrupt number: %d\n",
+  __func__, irq);
+return;
+}
+
+trace_aspeed_intc_set_irq(irq, level);
+
+for (i = 0; i < 32; i++) {
+if (s->gicint_orgate[irq].levels[i]) {
+if (enable & BIT(i)) {
+s->new_gicint_status[irq] |= BIT(i);
+}
+}
+}
+
+aspeed_intc_update(s, irq, level);
+}
+
+static uint64_t aspeed_intc_read(void *opaque, hwaddr offset, unsigned int 
size)
+{
+AspeedINTCState *s = ASPEED_INTC(opaque);
+uint32_t addr = offset >> 2;
+uint32

[PATCH v3 13/16] aspeed: Add an AST2700 eval board

2024-04-16 Thread Jamin Lin via
AST2700 CPU is ARM Cortex-A35 which is 64 bits.
Add TARGET_AARCH64 to build this machine.

According to the design of ast2700, it has a bootmcu(riscv-32) which
is used for executing SPL.
Then, CPUs(cortex-a35) execute u-boot, kernel and rofs.

Currently, qemu not support emulate two CPU architectures
at the same machine. Therefore, qemu will only support
to emulate CPU(cortex-a35) side for ast2700

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 
Reviewed-by: Cédric Le Goater 
---
 hw/arm/aspeed.c | 32 
 1 file changed, 32 insertions(+)

diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index 93ca87fda2..40dc0e4c76 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -178,6 +178,12 @@ struct AspeedMachineState {
 #define AST2600_EVB_HW_STRAP1 0x00C0
 #define AST2600_EVB_HW_STRAP2 0x0003
 
+#ifdef TARGET_AARCH64
+/* AST2700 evb hardware value */
+#define AST2700_EVB_HW_STRAP1 0x00C0
+#define AST2700_EVB_HW_STRAP2 0x0003
+#endif
+
 /* Tacoma hardware value */
 #define TACOMA_BMC_HW_STRAP1  0x
 #define TACOMA_BMC_HW_STRAP2  0x0040
@@ -1588,6 +1594,26 @@ static void 
aspeed_minibmc_machine_ast1030_evb_class_init(ObjectClass *oc,
 aspeed_machine_class_init_cpus_defaults(mc);
 }
 
+#ifdef TARGET_AARCH64
+static void aspeed_machine_ast2700_evb_class_init(ObjectClass *oc, void *data)
+{
+MachineClass *mc = MACHINE_CLASS(oc);
+AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
+
+mc->desc = "Aspeed AST2700 EVB (Cortex-A35)";
+amc->soc_name  = "ast2700-a0";
+amc->hw_strap1 = AST2700_EVB_HW_STRAP1;
+amc->hw_strap2 = AST2700_EVB_HW_STRAP2;
+amc->fmc_model = "w25q01jvq";
+amc->spi_model = "w25q512jv";
+amc->num_cs= 2;
+amc->macs_mask = ASPEED_MAC0_ON | ASPEED_MAC1_ON | ASPEED_MAC2_ON;
+amc->uart_default = ASPEED_DEV_UART12;
+mc->default_ram_size = 1 * GiB;
+aspeed_machine_class_init_cpus_defaults(mc);
+}
+#endif
+
 static void aspeed_machine_qcom_dc_scm_v1_class_init(ObjectClass *oc,
  void *data)
 {
@@ -1711,6 +1737,12 @@ static const TypeInfo aspeed_machine_types[] = {
 .name   = MACHINE_TYPE_NAME("ast1030-evb"),
 .parent = TYPE_ASPEED_MACHINE,
 .class_init = aspeed_minibmc_machine_ast1030_evb_class_init,
+#ifdef TARGET_AARCH64
+}, {
+.name  = MACHINE_TYPE_NAME("ast2700-evb"),
+.parent= TYPE_ASPEED_MACHINE,
+.class_init= aspeed_machine_ast2700_evb_class_init,
+#endif
 }, {
 .name  = TYPE_ASPEED_MACHINE,
 .parent= TYPE_MACHINE,
-- 
2.25.1




[PATCH v3 15/16] test/avocado/machine_aspeed.py: Add AST2700 test case

2024-04-16 Thread Jamin Lin via
Add a test case to test Aspeed OpenBMC SDK v09.01 on AST2700 board.

It loads u-boot-nodtb.bin, u-boot.dtb, tfa and optee-os
images to dram first which base address is 0x4.
Then, boot and launch 4 cpu cores.

```
qemu-system-aarch64 -machine ast2700-evb
-device loader,force-raw=on,addr=0x4,file=workdir/u-boot-nodtb.bin \
-device loader,force-raw=on,addr=uboot_dtb_load_addr,file=u-boot.dtb\
-device loader,force-raw=on,addr=0x43000,file=workdir/bl31.bin\
-device loader,force-raw=on,addr=0x43008,file=workdir/optee/tee-raw.bin\
-device loader,cpu-num=0,addr=0x43000 \
-device loader,cpu-num=1,addr=0x43000 \
-device loader,cpu-num=2,addr=0x43000 \
-device loader,cpu-num=3,addr=0x43000 \
-smp 4 \
-drive file=workdir/image-bmc,format=raw,if=mtd
```

A test image is downloaded from the ASPEED Forked OpenBMC GitHub release 
repository :
https://github.com/AspeedTech-BMC/openbmc/releases/

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 
---
 tests/avocado/machine_aspeed.py | 62 +
 1 file changed, 62 insertions(+)

diff --git a/tests/avocado/machine_aspeed.py b/tests/avocado/machine_aspeed.py
index cec0181424..3a20644fb2 100644
--- a/tests/avocado/machine_aspeed.py
+++ b/tests/avocado/machine_aspeed.py
@@ -311,6 +311,17 @@ def do_test_arm_aspeed_sdk_start(self, image):
 self, 'boot', '## Loading kernel from FIT Image')
 self.wait_for_console_pattern('Starting kernel ...')
 
+def do_test_aarch64_aspeed_sdk_start(self, image):
+self.vm.set_console()
+self.vm.add_args('-drive', 'file=' + image + ',if=mtd,format=raw')
+
+self.vm.launch()
+
+self.wait_for_console_pattern('U-Boot 2023.10')
+self.wait_for_console_pattern('## Loading kernel from FIT Image')
+self.wait_for_console_pattern('Starting kernel ...')
+self.wait_for_console_pattern("systemd[1]: Hostname set to")
+
 @skipUnless(os.getenv('QEMU_TEST_FLAKY_TESTS'), 'Test is unstable on 
GitLab')
 
 def test_arm_ast2500_evb_sdk(self):
@@ -375,3 +386,54 @@ def test_arm_ast2600_evb_sdk(self):
  'i2c i2c-5: new_device: Instantiated device ds1307 at 0x32');
 year = time.strftime("%Y")
 self.ssh_command_output_contains('/sbin/hwclock -f /dev/rtc1', year);
+
+def test_aarch64_ast2700_evb_sdk_v09_01(self):
+"""
+:avocado: tags=arch:aarch64
+:avocado: tags=machine:ast2700-evb
+"""
+
+image_url = ('https://github.com/AspeedTech-BMC/openbmc/releases/'
+ 'download/v09.01/ast2700-default-obmc.tar.gz')
+image_hash = 
'b1cc0fd73c7650d34c9c8459a243f52a91e9e27144b8608b2645ab19461d1e07'
+image_path = self.fetch_asset(image_url, asset_hash=image_hash,
+  algorithm='sha256')
+archive.extract(image_path, self.workdir)
+
+num_cpu = 4
+image_dir = self.workdir + '/ast2700-default/'
+uboot_size = os.path.getsize(image_dir + 'u-boot-nodtb.bin')
+uboot_dtb_load_addr = hex(0x4 + uboot_size)
+
+load_images_list = [
+{
+'addr': '0x4',
+'file': image_dir + 'u-boot-nodtb.bin'
+},
+{
+'addr': str(uboot_dtb_load_addr),
+'file': image_dir + 'u-boot.dtb'
+},
+{
+'addr': '0x43000',
+'file': image_dir + 'bl31.bin'
+},
+{
+'addr': '0x43008',
+'file': image_dir + 'optee/tee-raw.bin'
+}
+]
+
+for load_image in load_images_list:
+addr = load_image['addr']
+file = load_image['file']
+self.vm.add_args('-device',
+ f'loader,force-raw=on,addr={addr},file={file}')
+
+for i in range(num_cpu):
+self.vm.add_args('-device',
+ f'loader,addr=0x43000,cpu-num={i}')
+
+self.vm.add_args('-smp', str(num_cpu))
+self.do_test_aarch64_aspeed_sdk_start(image_dir + 'image-bmc')
+
-- 
2.25.1




[PATCH v3 03/16] aspeed/sdmc: remove redundant macros

2024-04-16 Thread Jamin Lin via
These macros are no longer used for ASPEED SOCs, so removes them.

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 
---
 hw/misc/aspeed_sdmc.c | 15 ---
 1 file changed, 15 deletions(-)

diff --git a/hw/misc/aspeed_sdmc.c b/hw/misc/aspeed_sdmc.c
index 64cd1a81dc..74279bbe8e 100644
--- a/hw/misc/aspeed_sdmc.c
+++ b/hw/misc/aspeed_sdmc.c
@@ -76,10 +76,6 @@
 #define ASPEED_SDMC_VGA_32MB0x2
 #define ASPEED_SDMC_VGA_64MB0x3
 #define ASPEED_SDMC_DRAM_SIZE(x)(x & 0x3)
-#define ASPEED_SDMC_DRAM_64MB   0x0
-#define ASPEED_SDMC_DRAM_128MB  0x1
-#define ASPEED_SDMC_DRAM_256MB  0x2
-#define ASPEED_SDMC_DRAM_512MB  0x3
 
 #define ASPEED_SDMC_READONLY_MASK   \
 (ASPEED_SDMC_RESERVED | ASPEED_SDMC_VGA_COMPAT |\
@@ -100,17 +96,6 @@
 #define ASPEED_SDMC_CACHE_ENABLE(1 << 10) /* differs from AST2400 */
 #define ASPEED_SDMC_DRAM_TYPE   (1 << 4)  /* differs from AST2400 */
 
-/* DRAM size definitions differs */
-#define ASPEED_SDMC_AST2500_128MB   0x0
-#define ASPEED_SDMC_AST2500_256MB   0x1
-#define ASPEED_SDMC_AST2500_512MB   0x2
-#define ASPEED_SDMC_AST2500_1024MB  0x3
-
-#define ASPEED_SDMC_AST2600_256MB   0x0
-#define ASPEED_SDMC_AST2600_512MB   0x1
-#define ASPEED_SDMC_AST2600_1024MB  0x2
-#define ASPEED_SDMC_AST2600_2048MB  0x3
-
 #define ASPEED_SDMC_AST2500_READONLY_MASK   \
 (ASPEED_SDMC_HW_VERSION(0xf) | ASPEED_SDMC_CACHE_INITIAL_DONE | \
  ASPEED_SDMC_AST2500_RESERVED | ASPEED_SDMC_VGA_COMPAT |\
-- 
2.25.1




[PATCH v3 01/16] aspeed/wdt: Add AST2700 support

2024-04-16 Thread Jamin Lin via
AST2700 wdt controller is similiar to AST2600's wdt, but
the AST2700 has 8 watchdogs, and they each have 0x80 of registers.
Introduce ast2700 object class and increase the number of regs(offset) of
ast2700 model.

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 
Reviewed-by: Cédric Le Goater 
---
 hw/watchdog/wdt_aspeed.c | 24 
 include/hw/watchdog/wdt_aspeed.h |  3 ++-
 2 files changed, 26 insertions(+), 1 deletion(-)

diff --git a/hw/watchdog/wdt_aspeed.c b/hw/watchdog/wdt_aspeed.c
index d70b656f8e..75685c5647 100644
--- a/hw/watchdog/wdt_aspeed.c
+++ b/hw/watchdog/wdt_aspeed.c
@@ -422,12 +422,36 @@ static const TypeInfo aspeed_1030_wdt_info = {
 .class_init = aspeed_1030_wdt_class_init,
 };
 
+static void aspeed_2700_wdt_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+AspeedWDTClass *awc = ASPEED_WDT_CLASS(klass);
+
+dc->desc = "ASPEED 2700 Watchdog Controller";
+awc->iosize = 0x80;
+awc->ext_pulse_width_mask = 0xf; /* TODO */
+awc->reset_ctrl_reg = AST2600_SCU_RESET_CONTROL1;
+awc->reset_pulse = aspeed_2500_wdt_reset_pulse;
+awc->wdt_reload = aspeed_wdt_reload_1mhz;
+awc->sanitize_ctrl = aspeed_2600_sanitize_ctrl;
+awc->default_status = 0x014FB180;
+awc->default_reload_value = 0x014FB180;
+}
+
+static const TypeInfo aspeed_2700_wdt_info = {
+.name = TYPE_ASPEED_2700_WDT,
+.parent = TYPE_ASPEED_WDT,
+.instance_size = sizeof(AspeedWDTState),
+.class_init = aspeed_2700_wdt_class_init,
+};
+
 static void wdt_aspeed_register_types(void)
 {
 type_register_static(_wdt_info);
 type_register_static(_2400_wdt_info);
 type_register_static(_2500_wdt_info);
 type_register_static(_2600_wdt_info);
+type_register_static(_2700_wdt_info);
 type_register_static(_1030_wdt_info);
 }
 
diff --git a/include/hw/watchdog/wdt_aspeed.h b/include/hw/watchdog/wdt_aspeed.h
index e90ef86651..830b0a7936 100644
--- a/include/hw/watchdog/wdt_aspeed.h
+++ b/include/hw/watchdog/wdt_aspeed.h
@@ -19,9 +19,10 @@ OBJECT_DECLARE_TYPE(AspeedWDTState, AspeedWDTClass, 
ASPEED_WDT)
 #define TYPE_ASPEED_2400_WDT TYPE_ASPEED_WDT "-ast2400"
 #define TYPE_ASPEED_2500_WDT TYPE_ASPEED_WDT "-ast2500"
 #define TYPE_ASPEED_2600_WDT TYPE_ASPEED_WDT "-ast2600"
+#define TYPE_ASPEED_2700_WDT TYPE_ASPEED_WDT "-ast2700"
 #define TYPE_ASPEED_1030_WDT TYPE_ASPEED_WDT "-ast1030"
 
-#define ASPEED_WDT_REGS_MAX(0x30 / 4)
+#define ASPEED_WDT_REGS_MAX(0x80 / 4)
 
 struct AspeedWDTState {
 /*< private >*/
-- 
2.25.1




[PATCH v3 14/16] aspeed/soc: fix incorrect dram size for AST2700

2024-04-16 Thread Jamin Lin via
AST2700 dram size calculation is not back compatible AST2600.
According to the DDR capacity hardware behavior,
if users write the data to address which is beyond the ram size,
it would write the data to address 0.
For example:
a. sdram base address "0x4 "
b. sdram size is 1 GiB
The available address range is from "0x4 " to "0x4 4000".
If users write 0xdeadbeef to address "0x6 ",
the value of DRAM address 0 (base address 0x4 ) should be 0xdeadbeef.

Add aspeed_soc_ast2700_dram_init to calculate the dram size and add
memory I/O whose address range is from max_ram_size - ram_size to max_ram_size
and its read/write handler to emulate DDR capacity hardware behavior.

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 
---
 hw/arm/aspeed_ast27x0.c | 94 -
 include/hw/arm/aspeed_soc.h |  1 +
 2 files changed, 94 insertions(+), 1 deletion(-)

diff --git a/hw/arm/aspeed_ast27x0.c b/hw/arm/aspeed_ast27x0.c
index 754c963230..38858e4fde 100644
--- a/hw/arm/aspeed_ast27x0.c
+++ b/hw/arm/aspeed_ast27x0.c
@@ -20,6 +20,7 @@
 #include "sysemu/sysemu.h"
 #include "hw/intc/arm_gicv3.h"
 #include "qapi/qmp/qlist.h"
+#include "qemu/log.h"
 
 static const hwaddr aspeed_soc_ast2700_memmap[] = {
 [ASPEED_DEV_SPI_BOOT]  =  0x4,
@@ -191,6 +192,97 @@ static qemu_irq aspeed_soc_ast2700_get_irq(AspeedSoCState 
*s, int dev)
 return qdev_get_gpio_in(a->intc.gic, sc->irqmap[dev]);
 }
 
+static uint64_t aspeed_ram_capacity_read(void *opaque, hwaddr addr,
+unsigned int size)
+{
+qemu_log_mask(LOG_GUEST_ERROR,
+  "%s: read @%" PRIx64 " out of ram size\n",
+   __func__, addr);
+return 0;
+}
+
+static void aspeed_ram_capacity_write(void *opaque, hwaddr addr, uint64_t data,
+unsigned int size)
+{
+AspeedSoCState *s = ASPEED_SOC(opaque);
+uint32_t test_pattern = 0xdeadbeef;
+bool invalid_pattern = true;
+uint32_t *ram_ptr;
+int sz;
+
+ram_ptr = memory_region_get_ram_ptr(s->dram_mr);
+
+   /*
+* Emulate ddr capacity hardware behavior.
+* If writes the test_pattern to address which is beyond the ram size,
+* it would write the test_pattern to address 0.
+*/
+for (sz = 4; sz > 0 ; sz--) {
+test_pattern = (test_pattern << 4) + sz;
+if (data == test_pattern) {
+ram_ptr[0] = test_pattern;
+invalid_pattern = false;
+break;
+}
+}
+
+if (invalid_pattern) {
+qemu_log_mask(LOG_GUEST_ERROR,
+  "%s: write invalid pattern @%" PRIx64
+  " to addr @%" HWADDR_PRIx "]\n",
+  __func__, data, addr);
+}
+}
+
+static const MemoryRegionOps aspeed_ram_capacity_ops = {
+.read = aspeed_ram_capacity_read,
+.write = aspeed_ram_capacity_write,
+.endianness = DEVICE_LITTLE_ENDIAN,
+.valid = {
+.min_access_size = 1,
+.max_access_size = 8,
+},
+};
+
+/*
+ * SDMC should be realized first to get correct RAM size and max size
+ * values
+ */
+static bool aspeed_soc_ast2700_dram_init(DeviceState *dev, Error **errp)
+{
+ram_addr_t ram_size, max_ram_size;
+Aspeed27x0SoCState *a = ASPEED27X0_SOC(dev);
+AspeedSoCState *s = ASPEED_SOC(dev);
+AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
+
+ram_size = object_property_get_uint(OBJECT(>sdmc), "ram-size",
+_abort);
+max_ram_size = object_property_get_uint(OBJECT(>sdmc), "max-ram-size",
+_abort);
+
+memory_region_init(>dram_container, OBJECT(s), "ram-container",
+   ram_size);
+memory_region_add_subregion(>dram_container, 0, s->dram_mr);
+
+/*
+ * Add a memory region beyond the RAM region to emulate
+ * ddr capacity hardware behavior.
+ */
+if (ram_size < max_ram_size) {
+memory_region_init_io(>dram_empty, OBJECT(s),
+  _ram_capacity_ops, s,
+  "ram-empty", max_ram_size - ram_size);
+
+memory_region_add_subregion(s->memory,
+sc->memmap[ASPEED_DEV_SDRAM] + ram_size,
+>dram_empty);
+}
+
+memory_region_add_subregion(s->memory,
+  sc->memmap[ASPEED_DEV_SDRAM], >dram_container);
+return true;
+}
+
 static void aspeed_soc_ast2700_init(Object *obj)
 {
 Aspeed27x0SoCState *a = ASPEED27X0_SOC(obj);
@@ -454,7 +546,7 @@ static void aspeed_soc_ast2700_realize(DeviceState *dev, 
Error **errp)
 sc->memmap[ASPEED_DEV_SDMC]);
 
 /

[PATCH v3 07/16] aspeed/smc: fix dma moving incorrect data length issue

2024-04-16 Thread Jamin Lin via
DMA length is from 1 byte to 32MB for AST2600 and AST10x0
and DMA length is from 4 bytes to 32MB for AST2500.

In other words, if "R_DMA_LEN" is 0, it should move at least 1 byte
data for AST2600 and AST10x0 and 4 bytes data for AST2500.
To support all ASPEED SOCs, adds dma_start_length parameter to store
the start length, add helper routines function to compute the dma length
and update DMA_LENGTH mask to "1FF" to fix dma moving
incorrect data length issue.

Currently, only supports dma length 4 bytes aligned.

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 
---
 hw/ssi/aspeed_smc.c | 52 -
 include/hw/ssi/aspeed_smc.h |  1 +
 2 files changed, 46 insertions(+), 7 deletions(-)

diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
index 8a8d77b480..71abc7a2d8 100644
--- a/hw/ssi/aspeed_smc.c
+++ b/hw/ssi/aspeed_smc.c
@@ -178,13 +178,17 @@
  * DMA flash addresses should be 4 bytes aligned and the valid address
  * range is 0x2000 - 0x2FFF.
  *
- * DMA length is from 4 bytes to 32MB
+ * DMA length is from 4 bytes to 32MB (AST2500)
  *   0: 4 bytes
  *   0x7F: 32M bytes
+ *
+ * DMA length is from 1 byte to 32MB (AST2600, AST10x0)
+ *   0: 1 byte
+ *   0x1FF: 32M bytes
  */
 #define DMA_DRAM_ADDR(asc, val)   ((val) & (asc)->dma_dram_mask)
 #define DMA_FLASH_ADDR(asc, val)  ((val) & (asc)->dma_flash_mask)
-#define DMA_LENGTH(val) ((val) & 0x01FC)
+#define DMA_LENGTH(val) ((val) & 0x01FF)
 
 /* Flash opcodes. */
 #define SPI_OP_READ   0x03/* Read data bytes (low frequency) */
@@ -843,6 +847,24 @@ static bool aspeed_smc_inject_read_failure(AspeedSMCState 
*s)
 }
 }
 
+static uint32_t aspeed_smc_dma_len(AspeedSMCState *s)
+{
+AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s);
+uint32_t dma_len;
+uint32_t extra;
+
+dma_len = s->regs[R_DMA_LEN] + asc->dma_start_length;
+
+/* dma length 4 bytes aligned */
+extra = dma_len % 4;
+
+if (extra != 0) {
+dma_len += 4 - extra;
+}
+
+return dma_len;
+}
+
 /*
  * Accumulate the result of the reads to provide a checksum that will
  * be used to validate the read timing settings.
@@ -850,6 +872,7 @@ static bool aspeed_smc_inject_read_failure(AspeedSMCState 
*s)
 static void aspeed_smc_dma_checksum(AspeedSMCState *s)
 {
 MemTxResult result;
+uint32_t dma_len;
 uint32_t data;
 
 if (s->regs[R_DMA_CTRL] & DMA_CTRL_WRITE) {
@@ -861,7 +884,9 @@ static void aspeed_smc_dma_checksum(AspeedSMCState *s)
 aspeed_smc_dma_calibration(s);
 }
 
-while (s->regs[R_DMA_LEN]) {
+dma_len = aspeed_smc_dma_len(s);
+
+while (dma_len) {
 data = address_space_ldl_le(>flash_as, s->regs[R_DMA_FLASH_ADDR],
 MEMTXATTRS_UNSPECIFIED, );
 if (result != MEMTX_OK) {
@@ -877,7 +902,8 @@ static void aspeed_smc_dma_checksum(AspeedSMCState *s)
  */
 s->regs[R_DMA_CHECKSUM] += data;
 s->regs[R_DMA_FLASH_ADDR] += 4;
-s->regs[R_DMA_LEN] -= 4;
+dma_len -= 4;
+s->regs[R_DMA_LEN] = dma_len;
 }
 
 if (s->inject_failure && aspeed_smc_inject_read_failure(s)) {
@@ -889,14 +915,17 @@ static void aspeed_smc_dma_checksum(AspeedSMCState *s)
 static void aspeed_smc_dma_rw(AspeedSMCState *s)
 {
 MemTxResult result;
+uint32_t dma_len;
 uint32_t data;
 
+dma_len = aspeed_smc_dma_len(s);
+
 trace_aspeed_smc_dma_rw(s->regs[R_DMA_CTRL] & DMA_CTRL_WRITE ?
 "write" : "read",
 s->regs[R_DMA_FLASH_ADDR],
 s->regs[R_DMA_DRAM_ADDR],
-s->regs[R_DMA_LEN]);
-while (s->regs[R_DMA_LEN]) {
+dma_len);
+while (dma_len) {
 if (s->regs[R_DMA_CTRL] & DMA_CTRL_WRITE) {
 data = address_space_ldl_le(>dram_as, s->regs[R_DMA_DRAM_ADDR],
 MEMTXATTRS_UNSPECIFIED, );
@@ -937,7 +966,8 @@ static void aspeed_smc_dma_rw(AspeedSMCState *s)
  */
 s->regs[R_DMA_FLASH_ADDR] += 4;
 s->regs[R_DMA_DRAM_ADDR] += 4;
-s->regs[R_DMA_LEN] -= 4;
+dma_len -= 4;
+s->regs[R_DMA_LEN] = dma_len;
 s->regs[R_DMA_CHECKSUM] += data;
 }
 }
@@ -1381,6 +1411,7 @@ static void aspeed_2400_fmc_class_init(ObjectClass 
*klass, void *data)
 asc->features  = ASPEED_SMC_FEATURE_DMA;
 asc->dma_flash_mask= 0x0FFC;
 asc->dma_dram_mask = 0x1FFC;
+asc->dma_start_length  = 4;
 asc->nregs = ASPEED_SMC_R_MAX;
 asc->segment_to_reg= aspeed_smc_segment_to_reg;
 asc->reg_to_segment= aspeed_smc_reg_to_segment;
@@ -1464,6 +1495,7 @@ static void aspeed_2500_fmc_class_init(ObjectClass 
*klass, void *

[PATCH v3 09/16] aspeed/smc: Add AST2700 support

2024-04-16 Thread Jamin Lin via
AST2700 fmc/spi controller's address decoding unit is 64KB
and only bits [31:16] are used for decoding. Introduce seg_to_reg
and reg_to_seg handlers for ast2700 fmc/spi controller.
In addition, adds ast2700 fmc, spi0, spi1, and spi2 class init handler.

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 
---
 hw/ssi/aspeed_smc.c | 222 +++-
 1 file changed, 220 insertions(+), 2 deletions(-)

diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
index a67cac3d0f..e768e5463c 100644
--- a/hw/ssi/aspeed_smc.c
+++ b/hw/ssi/aspeed_smc.c
@@ -185,7 +185,7 @@
  *   0: 4 bytes
  *   0x7F: 32M bytes
  *
- * DMA length is from 1 byte to 32MB (AST2600, AST10x0)
+ * DMA length is from 1 byte to 32MB (AST2600, AST10x0 and AST2700)
  *   0: 1 byte
  *   0x1FF: 32M bytes
  */
@@ -670,7 +670,7 @@ static const MemoryRegionOps aspeed_smc_flash_ops = {
 .endianness = DEVICE_LITTLE_ENDIAN,
 .valid = {
 .min_access_size = 1,
-.max_access_size = 4,
+.max_access_size = 8,
 },
 };
 
@@ -1951,6 +1951,220 @@ static const TypeInfo aspeed_1030_spi2_info = {
 .class_init = aspeed_1030_spi2_class_init,
 };
 
+/*
+ * The FMC Segment Registers of the AST2700 have a 64KB unit.
+ * Only bits [31:16] are used for decoding.
+ */
+#define AST2700_SEG_ADDR_MASK 0x
+
+static uint32_t aspeed_2700_smc_segment_to_reg(const AspeedSMCState *s,
+   const AspeedSegments *seg)
+{
+uint32_t reg = 0;
+
+/* Disabled segments have a nil register */
+if (!seg->size) {
+return 0;
+}
+
+reg |= (seg->addr & AST2700_SEG_ADDR_MASK) >> 16; /* start offset */
+reg |= (seg->addr + seg->size - 1) & AST2700_SEG_ADDR_MASK; /* end offset 
*/
+return reg;
+}
+
+static void aspeed_2700_smc_reg_to_segment(const AspeedSMCState *s,
+   uint32_t reg, AspeedSegments *seg)
+{
+uint32_t start_offset = (reg << 16) & AST2700_SEG_ADDR_MASK;
+uint32_t end_offset = reg & AST2700_SEG_ADDR_MASK;
+AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s);
+
+if (reg) {
+seg->addr = asc->flash_window_base + start_offset;
+seg->size = end_offset + (64 * KiB) - start_offset;
+} else {
+seg->addr = asc->flash_window_base;
+seg->size = 0;
+}
+}
+
+static const uint32_t aspeed_2700_fmc_resets[ASPEED_SMC_R_MAX] = {
+[R_CONF] = (CONF_FLASH_TYPE_SPI << CONF_FLASH_TYPE0 |
+CONF_FLASH_TYPE_SPI << CONF_FLASH_TYPE1),
+[R_CE_CTRL] = 0xaa00,
+[R_CTRL0] = 0x406b0641,
+[R_CTRL1] = 0x0400,
+[R_CTRL2] = 0x0400,
+[R_CTRL3] = 0x0400,
+[R_SEG_ADDR0] = 0x0800,
+[R_SEG_ADDR1] = 0x1800,
+[R_SEG_ADDR2] = 0x,
+[R_SEG_ADDR3] = 0x,
+[R_DUMMY_DATA] = 0x0001,
+[R_DMA_DRAM_ADDR_HIGH] = 0x,
+[R_TIMINGS] = 0x007b,
+};
+
+static const AspeedSegments aspeed_2700_fmc_segments[] = {
+{ 0x0, 128 * MiB }, /* start address is readonly */
+{ 128 * MiB, 128 * MiB }, /* default is disabled but needed for -kernel */
+{ 256 * MiB, 128 * MiB }, /* default is disabled but needed for -kernel */
+{ 0x0, 0 }, /* disabled */
+};
+
+static void aspeed_2700_fmc_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+AspeedSMCClass *asc = ASPEED_SMC_CLASS(klass);
+
+dc->desc   = "Aspeed 2700 FMC Controller";
+asc->r_conf= R_CONF;
+asc->r_ce_ctrl = R_CE_CTRL;
+asc->r_ctrl0   = R_CTRL0;
+asc->r_timings = R_TIMINGS;
+asc->nregs_timings = 3;
+asc->conf_enable_w0= CONF_ENABLE_W0;
+asc->cs_num_max= 3;
+asc->segments  = aspeed_2700_fmc_segments;
+asc->segment_addr_mask = 0x;
+asc->resets= aspeed_2700_fmc_resets;
+asc->flash_window_base = 0x1;
+asc->flash_window_size = 1 * GiB;
+asc->features  = ASPEED_SMC_FEATURE_DMA |
+ ASPEED_SMC_FEATURE_DMA_DRAM_ADDR_HIGH;
+asc->dma_flash_mask= 0x2FFC;
+asc->dma_dram_mask = 0xFFFC;
+asc->dma_start_length  = 1;
+asc->nregs = ASPEED_SMC_R_MAX;
+asc->segment_to_reg= aspeed_2700_smc_segment_to_reg;
+asc->reg_to_segment= aspeed_2700_smc_reg_to_segment;
+asc->dma_ctrl  = aspeed_2600_smc_dma_ctrl;
+}
+
+static const TypeInfo aspeed_2700_fmc_info = {
+.name =  "aspeed.fmc-ast2700",
+.parent = TYPE_ASPEED_SMC,
+.class_init = aspeed_2700_fmc_class_init,
+};
+
+static const AspeedSegments aspeed_2700_spi0_segments[] = {
+{ 0x0, 128 * MiB }, /* start address is readonly */
+{ 128 * MiB, 128 * MiB }, /* start address is readonly */
+{ 0x0, 0 }, /* disabled 

[PATCH v3 02/16] aspeed/sli: Add AST2700 support

2024-04-16 Thread Jamin Lin via
AST2700 SLI engine is designed to accelerate the
throughput between cross-die connections.
It have CPU_SLI at CPU die and IO_SLI at IO die.

Introduce dummy AST2700 SLI and SLIIO models.

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 
---
 hw/misc/aspeed_sli.c | 178 +++
 hw/misc/meson.build  |   3 +-
 hw/misc/trace-events |   7 ++
 include/hw/misc/aspeed_sli.h |  31 ++
 4 files changed, 218 insertions(+), 1 deletion(-)
 create mode 100644 hw/misc/aspeed_sli.c
 create mode 100644 include/hw/misc/aspeed_sli.h

diff --git a/hw/misc/aspeed_sli.c b/hw/misc/aspeed_sli.c
new file mode 100644
index 00..e84fd6a4ca
--- /dev/null
+++ b/hw/misc/aspeed_sli.c
@@ -0,0 +1,178 @@
+/*
+ * ASPEED SLI Controller
+ *
+ * Copyright (C) 2024 ASPEED Technology Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "qemu/error-report.h"
+#include "hw/qdev-properties.h"
+#include "hw/misc/aspeed_sli.h"
+#include "qapi/error.h"
+#include "migration/vmstate.h"
+#include "trace.h"
+
+#define SLI_REGION_SIZE 0x500
+#define TO_REG(addr) ((addr) >> 2)
+
+static uint64_t aspeed_sli_read(void *opaque, hwaddr addr, unsigned int size)
+{
+AspeedSLIState *s = ASPEED_SLI(opaque);
+int reg = TO_REG(addr);
+
+if (reg >= ARRAY_SIZE(s->regs)) {
+qemu_log_mask(LOG_GUEST_ERROR,
+  "%s: Out-of-bounds read at offset 0x%" HWADDR_PRIx "\n",
+  __func__, addr);
+return 0;
+}
+
+trace_aspeed_sli_read(addr, size, s->regs[reg]);
+return s->regs[reg];
+}
+
+static void aspeed_sli_write(void *opaque, hwaddr addr, uint64_t data,
+  unsigned int size)
+{
+AspeedSLIState *s = ASPEED_SLI(opaque);
+int reg = TO_REG(addr);
+
+if (reg >= ARRAY_SIZE(s->regs)) {
+qemu_log_mask(LOG_GUEST_ERROR,
+  "%s: Out-of-bounds write at offset 0x%" HWADDR_PRIx "\n",
+  __func__, addr);
+return;
+}
+
+trace_aspeed_sli_write(addr, size, data);
+s->regs[reg] = data;
+}
+
+static uint64_t aspeed_sliio_read(void *opaque, hwaddr addr, unsigned int size)
+{
+AspeedSLIState *s = ASPEED_SLI(opaque);
+int reg = TO_REG(addr);
+
+if (reg >= ARRAY_SIZE(s->regs)) {
+qemu_log_mask(LOG_GUEST_ERROR,
+  "%s: Out-of-bounds read at offset 0x%" HWADDR_PRIx "\n",
+  __func__, addr);
+return 0;
+}
+
+trace_aspeed_sliio_read(addr, size, s->regs[reg]);
+return s->regs[reg];
+}
+
+static void aspeed_sliio_write(void *opaque, hwaddr addr, uint64_t data,
+  unsigned int size)
+{
+AspeedSLIState *s = ASPEED_SLI(opaque);
+int reg = TO_REG(addr);
+
+if (reg >= ARRAY_SIZE(s->regs)) {
+qemu_log_mask(LOG_GUEST_ERROR,
+  "%s: Out-of-bounds write at offset 0x%" HWADDR_PRIx "\n",
+  __func__, addr);
+return;
+}
+
+trace_aspeed_sliio_write(addr, size, data);
+s->regs[reg] = data;
+}
+
+static const MemoryRegionOps aspeed_sli_ops = {
+.read = aspeed_sli_read,
+.write = aspeed_sli_write,
+.endianness = DEVICE_LITTLE_ENDIAN,
+.valid = {
+.min_access_size = 1,
+.max_access_size = 4,
+},
+};
+
+static const MemoryRegionOps aspeed_sliio_ops = {
+.read = aspeed_sliio_read,
+.write = aspeed_sliio_write,
+.endianness = DEVICE_LITTLE_ENDIAN,
+.valid = {
+.min_access_size = 1,
+.max_access_size = 4,
+},
+};
+
+static void aspeed_sli_realize(DeviceState *dev, Error **errp)
+{
+AspeedSLIState *s = ASPEED_SLI(dev);
+SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
+
+memory_region_init_io(>iomem, OBJECT(s), _sli_ops, s,
+  TYPE_ASPEED_SLI, SLI_REGION_SIZE);
+sysbus_init_mmio(sbd, >iomem);
+}
+
+static void aspeed_sliio_realize(DeviceState *dev, Error **errp)
+{
+AspeedSLIState *s = ASPEED_SLI(dev);
+SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
+
+memory_region_init_io(>iomem, OBJECT(s), _sliio_ops, s,
+  TYPE_ASPEED_SLI, SLI_REGION_SIZE);
+sysbus_init_mmio(sbd, >iomem);
+}
+
+static void aspeed_sli_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+
+dc->desc = "Aspeed SLI Controller";
+dc->realize = aspeed_sli_realize;
+}
+
+static const TypeInfo aspeed_sli_info = {
+.name  = TYPE_ASPEED_SLI,
+.parent= TYPE_SYS_BUS_DEVICE,
+.instance_size = sizeof(AspeedSLIState),
+.class_init= aspeed_sli_class_init,
+.class_size= sizeof(AspeedSLIClass),
+.abstract  = true

[PATCH v3 12/16] aspeed/soc: Add AST2700 support

2024-04-16 Thread Jamin Lin via
Initial definitions for a simple machine using an AST2700 SOC (Cortex-a35 CPU).

AST2700 SOC and its interrupt controller are too complex to handle
in the common Aspeed SoC framework. We introduce a new ast2700
class with instance_init and realize handlers.

AST2700 is a 64 bits quad core cpus and support 8 watchdog.
Update maximum ASPEED_CPUS_NUM to 4 and ASPEED_WDTS_NUM to 8.
In addition, update AspeedSocState to support scuio, sli, sliio and intc.

Add TYPE_ASPEED27X0_SOC machine type.

The SDMC controller is unlocked at SPL stage.
At present, only supports to emulate booting
start from u-boot stage. Set SDMC controller
unlocked by default.

In INTC, each interrupt of INT 128 to INT 136 combines 32 interrupts.
It connect GICINT IRQ GPIO-OUTPUT pins to GIC device with irq 128 to 136.
And, if a device irq is 128 to 136, its irq GPIO-OUTPUT pin is connected to
GICINT or-gates instead of GIC device.

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 
---
 hw/arm/aspeed_ast27x0.c | 554 
 hw/arm/meson.build  |   1 +
 include/hw/arm/aspeed_soc.h |  26 +-
 3 files changed, 579 insertions(+), 2 deletions(-)
 create mode 100644 hw/arm/aspeed_ast27x0.c

diff --git a/hw/arm/aspeed_ast27x0.c b/hw/arm/aspeed_ast27x0.c
new file mode 100644
index 00..754c963230
--- /dev/null
+++ b/hw/arm/aspeed_ast27x0.c
@@ -0,0 +1,554 @@
+/*
+ * ASPEED SoC 27x0 family
+ *
+ * Copyright (C) 2024 ASPEED Technology Inc.
+ *
+ * This code is licensed under the GPL version 2 or later.  See
+ * the COPYING file in the top-level directory.
+ *
+ * Implementation extracted from the AST2600 and adapted for AST27x0.
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "hw/misc/unimp.h"
+#include "hw/arm/aspeed_soc.h"
+#include "qemu/module.h"
+#include "qemu/error-report.h"
+#include "hw/i2c/aspeed_i2c.h"
+#include "net/net.h"
+#include "sysemu/sysemu.h"
+#include "hw/intc/arm_gicv3.h"
+#include "qapi/qmp/qlist.h"
+
+static const hwaddr aspeed_soc_ast2700_memmap[] = {
+[ASPEED_DEV_SPI_BOOT]  =  0x4,
+[ASPEED_DEV_SRAM]  =  0x1000,
+[ASPEED_DEV_SDMC]  =  0x12C0,
+[ASPEED_DEV_SCU]   =  0x12C02000,
+[ASPEED_DEV_SCUIO] =  0x14C02000,
+[ASPEED_DEV_UART0] =  0X14C33000,
+[ASPEED_DEV_UART1] =  0X14C33100,
+[ASPEED_DEV_UART2] =  0X14C33200,
+[ASPEED_DEV_UART3] =  0X14C33300,
+[ASPEED_DEV_UART4] =  0X12C1A000,
+[ASPEED_DEV_UART5] =  0X14C33400,
+[ASPEED_DEV_UART6] =  0X14C33500,
+[ASPEED_DEV_UART7] =  0X14C33600,
+[ASPEED_DEV_UART8] =  0X14C33700,
+[ASPEED_DEV_UART9] =  0X14C33800,
+[ASPEED_DEV_UART10]=  0X14C33900,
+[ASPEED_DEV_UART11]=  0X14C33A00,
+[ASPEED_DEV_UART12]=  0X14C33B00,
+[ASPEED_DEV_WDT]   =  0x14C37000,
+[ASPEED_DEV_VUART] =  0X14C3,
+[ASPEED_DEV_FMC]   =  0x1400,
+[ASPEED_DEV_SPI0]  =  0x1401,
+[ASPEED_DEV_SPI1]  =  0x1402,
+[ASPEED_DEV_SPI2]  =  0x1403,
+[ASPEED_DEV_SDRAM] =  0x4,
+[ASPEED_DEV_MII1]  =  0x1404,
+[ASPEED_DEV_MII2]  =  0x14040008,
+[ASPEED_DEV_MII3]  =  0x14040010,
+[ASPEED_DEV_ETH1]  =  0x1405,
+[ASPEED_DEV_ETH2]  =  0x1406,
+[ASPEED_DEV_ETH3]  =  0x1407,
+[ASPEED_DEV_EMMC]  =  0x1209,
+[ASPEED_DEV_INTC]  =  0x1210,
+[ASPEED_DEV_SLI]   =  0x12C17000,
+[ASPEED_DEV_SLIIO] =  0x14C1E000,
+[ASPEED_GIC_DIST]  =  0x1220,
+[ASPEED_GIC_REDIST]=  0x1228,
+};
+
+#define AST2700_MAX_IRQ 288
+
+/* Shared Peripheral Interrupt values below are offset by -32 from datasheet */
+static const int aspeed_soc_ast2700_irqmap[] = {
+[ASPEED_DEV_UART0] = 132,
+[ASPEED_DEV_UART1] = 132,
+[ASPEED_DEV_UART2] = 132,
+[ASPEED_DEV_UART3] = 132,
+[ASPEED_DEV_UART4] = 8,
+[ASPEED_DEV_UART5] = 132,
+[ASPEED_DEV_UART6] = 132,
+[ASPEED_DEV_UART7] = 132,
+[ASPEED_DEV_UART8] = 132,
+[ASPEED_DEV_UART9] = 132,
+[ASPEED_DEV_UART10]= 132,
+[ASPEED_DEV_UART11]= 132,
+[ASPEED_DEV_UART12]= 132,
+[ASPEED_DEV_FMC]   = 131,
+[ASPEED_DEV_SDMC]  = 0,
+[ASPEED_DEV_SCU]   = 12,
+[ASPEED_DEV_ADC]   = 130,
+[ASPEED_DEV_XDMA]  = 5,
+[ASPEED_DEV_EMMC]  = 15,
+[ASPEED_DEV_GPIO]  = 11,
+[ASPEED_DEV_GPIO_1_8V] = 130,
+[ASPEED_DEV_RTC]   = 13,
+[ASPEED_DEV_TIMER1]= 16,
+[ASPEED_DEV_TIMER2]= 17,
+[ASPEED_DEV_TIMER3]= 18,
+[ASPEED_DEV_TIMER4]= 19,
+[ASPEED_DEV_TIMER5]= 20,
+[ASPEED_DEV_TIMER6]= 21,
+[ASPEED_DEV_TIMER7]= 22,
+[ASPEED_DEV_TIMER8]= 23,
+[ASPEED_DEV_WDT]   = 131,
+[ASPEED_DE

[PATCH v3 05/16] aspeed/sdmc: Add AST2700 support

2024-04-16 Thread Jamin Lin via
The SDRAM memory controller(DRAMC) controls the access to external
DDR4 and DDR5 SDRAM and power up to DDR4 and DDR5 PHY.

The DRAM memory controller of AST2700 is not backward compatible
to previous chips such AST2600, AST2500 and AST2400.

Max memory is now 8GiB on the AST2700. Introduce new
aspeed_2700_sdmc and class with read/write operation and
reset handlers.

Define DRAMC necessary protected registers and
unprotected registers for AST2700 and increase
the register set to 0x1000.

Add unlocked property to change controller protected status.

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 
---
 hw/misc/aspeed_sdmc.c | 190 +-
 include/hw/misc/aspeed_sdmc.h |   5 +-
 2 files changed, 193 insertions(+), 2 deletions(-)

diff --git a/hw/misc/aspeed_sdmc.c b/hw/misc/aspeed_sdmc.c
index 873d67c592..69a34903db 100644
--- a/hw/misc/aspeed_sdmc.c
+++ b/hw/misc/aspeed_sdmc.c
@@ -27,6 +27,7 @@
 #define   PROT_SOFTLOCKED0x00
 
 #define   PROT_KEY_UNLOCK 0xFC600309
+#define   PROT_2700_KEY_UNLOCK  0x1688A8A8
 #define   PROT_KEY_HARDLOCK   0xDEADDEAD /* AST2600 */
 
 /* Configuration Register */
@@ -54,6 +55,46 @@
 #define R_DRAM_TIME   (0x8c / 4)
 #define R_ECC_ERR_INJECT  (0xb4 / 4)
 
+/* AST2700 Register */
+#define R_2700_PROT (0x00 / 4)
+#define R_INT_STATUS(0x04 / 4)
+#define R_INT_CLEAR (0x08 / 4)
+#define R_INT_MASK  (0x0c / 4)
+#define R_MAIN_CONF (0x10 / 4)
+#define R_MAIN_CONTROL  (0x14 / 4)
+#define R_MAIN_STATUS   (0x18 / 4)
+#define R_ERR_STATUS(0x1c / 4)
+#define R_ECC_FAIL_STATUS   (0x78 / 4)
+#define R_ECC_FAIL_ADDR (0x7c / 4)
+#define R_ECC_TESTING_CONTROL   (0x80 / 4)
+#define R_PROT_REGION_LOCK_STATUS   (0x94 / 4)
+#define R_TEST_FAIL_ADDR(0xd4 / 4)
+#define R_TEST_FAIL_D0  (0xd8 / 4)
+#define R_TEST_FAIL_D1  (0xdc / 4)
+#define R_TEST_FAIL_D2  (0xe0 / 4)
+#define R_TEST_FAIL_D3  (0xe4 / 4)
+#define R_DBG_STATUS(0xf4 / 4)
+#define R_PHY_INTERFACE_STATUS  (0xf8 / 4)
+#define R_GRAPHIC_MEM_BASE_ADDR (0x10c / 4)
+#define R_PORT0_INTERFACE_MONITOR0  (0x240 / 4)
+#define R_PORT0_INTERFACE_MONITOR1  (0x244 / 4)
+#define R_PORT0_INTERFACE_MONITOR2  (0x248 / 4)
+#define R_PORT1_INTERFACE_MONITOR0  (0x2c0 / 4)
+#define R_PORT1_INTERFACE_MONITOR1  (0x2c4 / 4)
+#define R_PORT1_INTERFACE_MONITOR2  (0x2c8 / 4)
+#define R_PORT2_INTERFACE_MONITOR0  (0x340 / 4)
+#define R_PORT2_INTERFACE_MONITOR1  (0x344 / 4)
+#define R_PORT2_INTERFACE_MONITOR2  (0x348 / 4)
+#define R_PORT3_INTERFACE_MONITOR0  (0x3c0 / 4)
+#define R_PORT3_INTERFACE_MONITOR1  (0x3c4 / 4)
+#define R_PORT3_INTERFACE_MONITOR2  (0x3c8 / 4)
+#define R_PORT4_INTERFACE_MONITOR0  (0x440 / 4)
+#define R_PORT4_INTERFACE_MONITOR1  (0x444 / 4)
+#define R_PORT4_INTERFACE_MONITOR2  (0x448 / 4)
+#define R_PORT5_INTERFACE_MONITOR0  (0x4c0 / 4)
+#define R_PORT5_INTERFACE_MONITOR1  (0x4c4 / 4)
+#define R_PORT5_INTERFACE_MONITOR2  (0x4c8 / 4)
+
 /*
  * Configuration register Ox4 (for Aspeed AST2400 SOC)
  *
@@ -101,6 +142,19 @@
  ASPEED_SDMC_AST2500_RESERVED | ASPEED_SDMC_VGA_COMPAT |\
  ASPEED_SDMC_VGA_APERTURE(ASPEED_SDMC_VGA_64MB))
 
+/*
+ * Main Configuration register Ox10 (for Aspeed AST2700 SOC and higher)
+ *
+ */
+#define ASPEED_SDMC_AST2700_RESERVED0x2082 /* 31:16, 13, 7, 1 */
+#define ASPEED_SDMC_AST2700_DATA_SCRAMBLE   (1 << 8)
+#define ASPEED_SDMC_AST2700_ECC_ENABLE  (1 << 6)
+#define ASPEED_SDMC_AST2700_PAGE_MATCHING_ENABLE(1 << 5)
+#define ASPEED_SDMC_AST2700_DRAM_SIZE(x)((x & 0x7) << 2)
+
+#define ASPEED_SDMC_AST2700_READONLY_MASK   \
+ (ASPEED_SDMC_AST2700_RESERVED)
+
 static uint64_t aspeed_sdmc_read(void *opaque, hwaddr addr, unsigned size)
 {
 AspeedSDMCState *s = ASPEED_SDMC(opaque);
@@ -216,7 +270,7 @@ static void aspeed_sdmc_realize(DeviceState *dev, Error 
**errp)
 AspeedSDMCState *s = ASPEED_SDMC(dev);
 AspeedSDMCClass *asc = ASPEED_SDMC_GET_CLASS(s);
 
-assert(asc->max_ram_size < 4 * GiB); /* 32-bit address bus */
+assert(asc->max_ram_size < 4 * GiB || asc->is_bus64bit);
 s->max_ram_size = asc->max_ram_size;
 
 memory_region_init_io(>iomem, OBJECT(s), _sdmc_ops, s,
@@ -236,6 +290,7 @@ static const VMStateDescription vmstate_aspeed_sdmc = {
 
 static Property aspeed_sdmc_properties[] = {
 DEFINE_PROP_UINT64("max-ram-size", AspeedSDMCState, max_ram_size, 0),
+DEFINE_PROP_BOOL("unlocked", AspeedSDMCState, unlocked, false),
 DEFINE_PROP_END_OF_LIST(),
 };
 
@@ -500,12 +555,145 @@ static const TypeInfo aspeed_2600_sdmc_info = {
 .class_init = aspeed_2600_sdmc_class_init,
 };
 
+static void aspeed_2700_sdmc_reset(DeviceState *dev)
+{
+AspeedSDMCState *s = ASPEED_SDMC(dev);
+A

[PATCH v3 10/16] aspeed/scu: Add AST2700 support

2024-04-16 Thread Jamin Lin via
AST2700 have two SCU controllers which are SCU and SCUIO.
Both SCU and SCUIO registers are not compatible previous SOCs
, introduces new registers and adds ast2700 scu, sucio class init handler.

The pclk divider selection of SCUIO is defined in SCUIO280[20:18] and
the pclk divider selection of SCU is defined in SCU280[25:23].
Both of them are not compatible AST2600 SOCs, adds a get_apb_freq function
and trace-event for AST2700 SCU and SCUIO.

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 
Reviewed-by: Cédric Le Goater 
---
 hw/misc/aspeed_scu.c | 306 ++-
 hw/misc/trace-events |   4 +
 include/hw/misc/aspeed_scu.h |  47 +-
 3 files changed, 351 insertions(+), 6 deletions(-)

diff --git a/hw/misc/aspeed_scu.c b/hw/misc/aspeed_scu.c
index 1ac04b6cb0..eb38ea8e19 100644
--- a/hw/misc/aspeed_scu.c
+++ b/hw/misc/aspeed_scu.c
@@ -134,6 +134,48 @@
 
 #define AST2600_CLK TO_REG(0x40)
 
+#define AST2700_SILICON_REV   TO_REG(0x00)
+#define AST2700_HW_STRAP1 TO_REG(0x10)
+#define AST2700_HW_STRAP1_CLR TO_REG(0x14)
+#define AST2700_HW_STRAP1_LOCKTO_REG(0x20)
+#define AST2700_HW_STRAP1_SEC1TO_REG(0x24)
+#define AST2700_HW_STRAP1_SEC2TO_REG(0x28)
+#define AST2700_HW_STRAP1_SEC3TO_REG(0x2C)
+
+#define AST2700_SCU_CLK_SEL_1   TO_REG(0x280)
+#define AST2700_SCU_HPLL_PARAM  TO_REG(0x300)
+#define AST2700_SCU_HPLL_EXT_PARAM  TO_REG(0x304)
+#define AST2700_SCU_DPLL_PARAM  TO_REG(0x308)
+#define AST2700_SCU_DPLL_EXT_PARAM  TO_REG(0x30c)
+#define AST2700_SCU_MPLL_PARAM  TO_REG(0x310)
+#define AST2700_SCU_MPLL_EXT_PARAM  TO_REG(0x314)
+#define AST2700_SCU_D1CLK_PARAM TO_REG(0x320)
+#define AST2700_SCU_D2CLK_PARAM TO_REG(0x330)
+#define AST2700_SCU_CRT1CLK_PARAM   TO_REG(0x340)
+#define AST2700_SCU_CRT2CLK_PARAM   TO_REG(0x350)
+#define AST2700_SCU_MPHYCLK_PARAM   TO_REG(0x360)
+#define AST2700_SCU_FREQ_CNTR   TO_REG(0x3b0)
+#define AST2700_SCU_CPU_SCRATCH_0   TO_REG(0x780)
+#define AST2700_SCU_CPU_SCRATCH_1   TO_REG(0x784)
+
+#define AST2700_SCUIO_CLK_STOP_CTL_1TO_REG(0x240)
+#define AST2700_SCUIO_CLK_STOP_CLR_1TO_REG(0x244)
+#define AST2700_SCUIO_CLK_STOP_CTL_2TO_REG(0x260)
+#define AST2700_SCUIO_CLK_STOP_CLR_2TO_REG(0x264)
+#define AST2700_SCUIO_CLK_SEL_1 TO_REG(0x280)
+#define AST2700_SCUIO_CLK_SEL_2 TO_REG(0x284)
+#define AST2700_SCUIO_HPLL_PARAMTO_REG(0x300)
+#define AST2700_SCUIO_HPLL_EXT_PARAMTO_REG(0x304)
+#define AST2700_SCUIO_APLL_PARAMTO_REG(0x310)
+#define AST2700_SCUIO_APLL_EXT_PARAMTO_REG(0x314)
+#define AST2700_SCUIO_DPLL_PARAMTO_REG(0x320)
+#define AST2700_SCUIO_DPLL_EXT_PARAMTO_REG(0x324)
+#define AST2700_SCUIO_DPLL_PARAM_READ   TO_REG(0x328)
+#define AST2700_SCUIO_DPLL_EXT_PARAM_READ TO_REG(0x32c)
+#define AST2700_SCUIO_UARTCLK_GEN   TO_REG(0x330)
+#define AST2700_SCUIO_HUARTCLK_GEN  TO_REG(0x334)
+#define AST2700_SCUIO_CLK_DUTY_MEAS_RST TO_REG(0x388)
+
 #define SCU_IO_REGION_SIZE 0x1000
 
 static const uint32_t ast2400_a0_resets[ASPEED_SCU_NR_REGS] = {
@@ -244,6 +286,25 @@ static uint32_t 
aspeed_1030_scu_get_apb_freq(AspeedSCUState *s)
 / asc->apb_divider;
 }
 
+static uint32_t aspeed_2700_scu_get_apb_freq(AspeedSCUState *s)
+{
+AspeedSCUClass *asc = ASPEED_SCU_GET_CLASS(s);
+uint32_t hpll = asc->calc_hpll(s, s->regs[AST2700_SCU_HPLL_PARAM]);
+
+return hpll / (SCU_CLK_GET_PCLK_DIV(s->regs[AST2700_SCU_CLK_SEL_1]) + 1)
+   / asc->apb_divider;
+}
+
+static uint32_t aspeed_2700_scuio_get_apb_freq(AspeedSCUState *s)
+{
+AspeedSCUClass *asc = ASPEED_SCU_GET_CLASS(s);
+uint32_t hpll = asc->calc_hpll(s, s->regs[AST2700_SCUIO_HPLL_PARAM]);
+
+return hpll /
+(SCUIO_AST2700_CLK_GET_PCLK_DIV(s->regs[AST2700_SCUIO_CLK_SEL_1]) + 1)
+/ asc->apb_divider;
+}
+
 static uint64_t aspeed_scu_read(void *opaque, hwaddr offset, unsigned size)
 {
 AspeedSCUState *s = ASPEED_SCU(opaque);
@@ -258,7 +319,8 @@ static uint64_t aspeed_scu_read(void *opaque, hwaddr 
offset, unsigned size)
 
 switch (reg) {
 case RNG_DATA:
-/* On hardware, RNG_DATA works regardless of
+/*
+ * On hardware, RNG_DATA works regardless of
  * the state of the enable bit in RNG_CTRL
  */
 s->regs[RNG_DATA] = aspeed_scu_get_random();
@@ -494,6 +556,9 @@ static uint32_t aspeed_silicon_revs[] = {
 AST2600_A3_SILICON_REV,
 AST1030_A0_SILICON_REV,
 AST1030_A1_SILICON_REV,
+AST2700_A0_SILICON_REV,
+AST2720_A0_SILICON_REV,
+AST2750_A0_SILICON_REV,
 };
 
 bool is_supported_silicon_rev(uint32_t silicon_rev)
@@ -783,6 +848,243 @@ static const TypeInfo aspeed_2600_scu_info = {
 .class_init = aspeed_2600_scu_class_init,
 };
 
+static uint64_t aspeed_ast2700_scu_read(void *opaque, hwaddr offset,
+unsigned size)
+{
+AspeedSCUState *s = ASPEED_SCU(opaque);
+int reg = 

[PATCH v3 08/16] aspeed/smc: support 64 bits dma dram address

2024-04-16 Thread Jamin Lin via
AST2700 support the maximum dram size is 8GiB
and has a "DMA DRAM Side Address High Part(0x7C)"
register to support 64 bits dma dram address.
Add helper routines functions to compute the dma dram
address, new features and update trace-event
to support 64 bits dram address.

Signed-off-by: Troy Lee 
Signed-off-by: Jamin Lin 
---
 hw/ssi/aspeed_smc.c | 66 +++--
 hw/ssi/trace-events |  2 +-
 2 files changed, 59 insertions(+), 9 deletions(-)

diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
index 71abc7a2d8..a67cac3d0f 100644
--- a/hw/ssi/aspeed_smc.c
+++ b/hw/ssi/aspeed_smc.c
@@ -132,6 +132,9 @@
 #define   FMC_WDT2_CTRL_BOOT_SOURCE  BIT(4) /* O: primary 1: alternate */
 #define   FMC_WDT2_CTRL_EN   BIT(0)
 
+/* DMA DRAM Side Address High Part (AST2700) */
+#define R_DMA_DRAM_ADDR_HIGH   (0x7c / 4)
+
 /* DMA Control/Status Register */
 #define R_DMA_CTRL(0x80 / 4)
 #define   DMA_CTRL_REQUEST  (1 << 31)
@@ -187,6 +190,7 @@
  *   0x1FF: 32M bytes
  */
 #define DMA_DRAM_ADDR(asc, val)   ((val) & (asc)->dma_dram_mask)
+#define DMA_DRAM_ADDR_HIGH(val)   ((val) & 0xf)
 #define DMA_FLASH_ADDR(asc, val)  ((val) & (asc)->dma_flash_mask)
 #define DMA_LENGTH(val) ((val) & 0x01FF)
 
@@ -207,6 +211,7 @@ static const AspeedSegments aspeed_2500_spi2_segments[];
 #define ASPEED_SMC_FEATURE_DMA   0x1
 #define ASPEED_SMC_FEATURE_DMA_GRANT 0x2
 #define ASPEED_SMC_FEATURE_WDT_CONTROL 0x4
+#define ASPEED_SMC_FEATURE_DMA_DRAM_ADDR_HIGH 0x08
 
 static inline bool aspeed_smc_has_dma(const AspeedSMCClass *asc)
 {
@@ -218,6 +223,11 @@ static inline bool aspeed_smc_has_wdt_control(const 
AspeedSMCClass *asc)
 return !!(asc->features & ASPEED_SMC_FEATURE_WDT_CONTROL);
 }
 
+static inline bool aspeed_smc_has_dma_dram_addr_high(const AspeedSMCClass *asc)
+{
+return !!(asc->features & ASPEED_SMC_FEATURE_DMA_DRAM_ADDR_HIGH);
+}
+
 #define aspeed_smc_error(fmt, ...)  \
 qemu_log_mask(LOG_GUEST_ERROR, "%s: " fmt "\n", __func__, ## __VA_ARGS__)
 
@@ -747,6 +757,9 @@ static uint64_t aspeed_smc_read(void *opaque, hwaddr addr, 
unsigned int size)
 (aspeed_smc_has_dma(asc) && addr == R_DMA_CTRL) ||
 (aspeed_smc_has_dma(asc) && addr == R_DMA_FLASH_ADDR) ||
 (aspeed_smc_has_dma(asc) && addr == R_DMA_DRAM_ADDR) ||
+(aspeed_smc_has_dma(asc) &&
+ aspeed_smc_has_dma_dram_addr_high(asc) &&
+ addr == R_DMA_DRAM_ADDR_HIGH) ||
 (aspeed_smc_has_dma(asc) && addr == R_DMA_LEN) ||
 (aspeed_smc_has_dma(asc) && addr == R_DMA_CHECKSUM) ||
 (addr >= R_SEG_ADDR0 &&
@@ -847,6 +860,23 @@ static bool aspeed_smc_inject_read_failure(AspeedSMCState 
*s)
 }
 }
 
+static uint64_t aspeed_smc_dma_dram_addr(AspeedSMCState *s)
+{
+AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s);
+uint64_t dram_addr_high;
+uint64_t dma_dram_addr;
+
+if (aspeed_smc_has_dma_dram_addr_high(asc)) {
+dram_addr_high = s->regs[R_DMA_DRAM_ADDR_HIGH];
+dram_addr_high <<= 32;
+dma_dram_addr = dram_addr_high | s->regs[R_DMA_DRAM_ADDR];
+} else {
+dma_dram_addr = s->regs[R_DMA_DRAM_ADDR];
+}
+
+return dma_dram_addr;
+}
+
 static uint32_t aspeed_smc_dma_len(AspeedSMCState *s)
 {
 AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s);
@@ -914,24 +944,34 @@ static void aspeed_smc_dma_checksum(AspeedSMCState *s)
 
 static void aspeed_smc_dma_rw(AspeedSMCState *s)
 {
+AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s);
+uint64_t dram_addr_high;
+uint64_t dma_dram_addr;
+uint64_t dram_addr;
 MemTxResult result;
 uint32_t dma_len;
 uint32_t data;
 
 dma_len = aspeed_smc_dma_len(s);
+dma_dram_addr = aspeed_smc_dma_dram_addr(s);
+
+if (aspeed_smc_has_dma_dram_addr_high(asc)) {
+dram_addr = dma_dram_addr - s->dram_mr->container->addr;
+} else {
+dram_addr = dma_dram_addr;
+}
 
 trace_aspeed_smc_dma_rw(s->regs[R_DMA_CTRL] & DMA_CTRL_WRITE ?
 "write" : "read",
 s->regs[R_DMA_FLASH_ADDR],
-s->regs[R_DMA_DRAM_ADDR],
+dram_addr,
 dma_len);
 while (dma_len) {
 if (s->regs[R_DMA_CTRL] & DMA_CTRL_WRITE) {
-data = address_space_ldl_le(>dram_as, s->regs[R_DMA_DRAM_ADDR],
+data = address_space_ldl_le(>dram_as, dram_addr,
 MEMTXATTRS_UNSPECIFIED, );
 if (result != MEMTX_OK) {
-aspeed_smc_error("DRAM read failed @%08x",
- s->regs[R_DMA_DRAM_ADDR]);
+aspeed_smc_error("DRAM read failed 

  1   2   3   >