[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
RE: [PATCH v3 08/16] aspeed/smc: support 64 bits dma dram address
From: |
Jamin Lin |
Subject: |
RE: [PATCH v3 08/16] aspeed/smc: support 64 bits dma dram address |
Date: |
Tue, 30 Apr 2024 07:56:57 +0000 |
Hi Cedric,
> -----Original Message-----
> From: Cédric Le Goater <clg@kaod.org>
> Sent: Tuesday, April 30, 2024 3:26 PM
> To: Jamin Lin <jamin_lin@aspeedtech.com>; Peter Maydell
> <peter.maydell@linaro.org>; Andrew Jeffery <andrew@codeconstruct.com.au>;
> Joel Stanley <joel@jms.id.au>; Alistair Francis <alistair@alistair23.me>;
> Cleber
> Rosa <crosa@redhat.com>; Philippe Mathieu-Daudé <philmd@linaro.org>;
> Wainer dos Santos Moschetta <wainersm@redhat.com>; Beraldo Leal
> <bleal@redhat.com>; open list:ASPEED BMCs <qemu-arm@nongnu.org>; open
> list:All patches CC here <qemu-devel@nongnu.org>
> Cc: Troy Lee <troy_lee@aspeedtech.com>; Yunlin Tang
> <yunlin.tang@aspeedtech.com>
> 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 <troy_lee@aspeedtech.com>
> >>> Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
> >>> ---
> >>> 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 @@
> >>> * 0x1FFFFFF: 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) & 0x01FFFFFF)
> >>>
> >>> @@ -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_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;
> >>
> >> This variable doesn't look very useful
> > Will try to remove it.
> >>
> >>> + uint64_t dma_dram_addr;
> >>> + uint64_t dram_addr;
> >>
> >> and dram_addr is redundant with dma_dram_addr. Please use only one.
> > Please see my below description and please give us any suggestion.
> >>
> >>
> >>> 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;
> >>
> >> Why do you truncate the address again ? It should already be done
> >> with
> >>
> >> #define DMA_DRAM_ADDR_HIGH(val) ((val) & 0xf)
> >>
> > The reason is that our firmware set the real address in SMC registers.
> > For example: If users want to move data from flash to the DRAM at
> > address 0, It set R_DMA_DRAM_ADDR_HIGH 4 and R_DMA_DRAM_ADDR 0
> because
> > the dram base address is 0x 4 00000000 for AST2700.
>
>
> Could you please share the specs of the R_DMA_DRAM_ADDR and
> R_DMA_DRAM_ADDR_HIGH registers to see what are the init values, how
> these registers should be set, their alignment constraints if any, how the
> values
> evolve while the HW does the DMA transactions, etc.
>
DMA_DRAM_SIDE_ADDRESS 0x088 Init=0x00000000
31:0 RW DMA_RO
DRAM side start address
For DMA Read flash, this the destination address.
For DMA Write flash, the is the source address
DMA only execute on 4 bytes boundary
When read, it shows the current working address
DMA DRAM Side Address High Part 0x07c Init=0x00000000
32:8 RO reserved
7:0 RW DMA_RO_HI
dma_ro[39:32]
Therefore, DMA address is dma_ro[39:0]
Our FW settings,
In u-boot shell, execute the following command
cp.b 100220000 403000000 100
100220000 flash address for kernel fit image
403000000 dram address at offset 3000000
https://github.com/AspeedTech-BMC/u-boot/blob/aspeed-master-v2023.10/lib/string.c#L553C8-L553C29
https://github.com/AspeedTech-BMC/u-boot/blob/aspeed-master-v2023.10/arch/arm/mach-aspeed/ast2700/spi.c#L156
https://github.com/AspeedTech-BMC/u-boot/blob/aspeed-master-v2023.10/arch/arm/mach-aspeed/ast2700/spi.c#L179-L183
Thanks-Jamin
> Thanks,
>
> C.
>
>
[PATCH v3 09/16] aspeed/smc: Add AST2700 support, Jamin Lin, 2024/04/16
[PATCH v3 10/16] aspeed/scu: Add AST2700 support, Jamin Lin, 2024/04/16
[PATCH v3 11/16] aspeed/intc: Add AST2700 support, Jamin Lin, 2024/04/16
[PATCH v3 14/16] aspeed/soc: fix incorrect dram size for AST2700, Jamin Lin, 2024/04/16
[PATCH v3 16/16] docs:aspeed: Add AST2700 Evaluation board, Jamin Lin, 2024/04/16
[PATCH v3 12/16] aspeed/soc: Add AST2700 support, Jamin Lin, 2024/04/16