Hi Cédric

> Subject: Re: [PATCH v1 08/22] hw/misc/aspeed_hace: Support DMA 64 bits
> dram address.
> 
> On 3/21/25 10:26, Jamin Lin wrote:
> > According to the AST2700 design, the data source address is 64-bit,
> > with R_HASH_SRC_HI storing bits [63:32] and R_HASH_SRC storing bits
> [31:0].
> >
> > Similarly, the digest address is 64-bit, with R_HASH_DEST_HI storing
> > bits [63:32] and R_HASH_DEST storing bits [31:0].
> >
> > Ideally, sg_addr should be 64-bit for the AST2700, using the following
> > program to obtain the 64-bit sg_addr and convert it to a DRAM offset:
> >
> > ```
> > sg_addr = deposit64(sg_addr, 32, 32,
> >                      address_space_ldl_le(&s->dram_as, src +
> SG_LIST_ADDR_SIZE,
> >
> MEMTXATTRS_UNSPECIFIED,
> > NULL); sg_addr -= 0x400000000; ```
> 
> I don't think the code extract above is useful.
> 
> > To maintain compatibility with older SoCs such as the AST2600, the
> > AST2700 HW HACE controllers automatically set bit 34 of the 64-bit sg_addr.
> 
> I suppose that's what bits [30:28] of the first word of the scatter-gather 
> entry
> are for ?
> 
> > As a result,
> > the firmware only needs to provide a 32-bit sg_addr containing bits [31:0].
> > This is sufficient for the AST2700, as it uses a DRAM offset rather
> > than a DRAM address.
> 
> yes the HACE model can use a relative address because the DRAM memory
> region is directly available. There is no need to construct a physical 
> address.
> 
> > Introduce a has_dma64 class attribute and set it to true for the AST2700.
> >
> > Signed-off-by: Jamin Lin <jamin_...@aspeedtech.com>
> > ---
> >   include/hw/misc/aspeed_hace.h |  1 +
> >   hw/misc/aspeed_hace.c         | 27 ++++++++++++++++++++++++++-
> >   2 files changed, 27 insertions(+), 1 deletion(-)
> >
> > diff --git a/include/hw/misc/aspeed_hace.h
> > b/include/hw/misc/aspeed_hace.h index a4479bd383..58fb66009a 100644
> > --- a/include/hw/misc/aspeed_hace.h
> > +++ b/include/hw/misc/aspeed_hace.h
> > @@ -52,6 +52,7 @@ struct AspeedHACEClass {
> >       uint32_t src_hi_mask;
> >       uint32_t dest_hi_mask;
> >       uint32_t key_hi_mask;
> > +    bool has_dma64;
> >   };
> >
> >   #endif /* ASPEED_HACE_H */
> > diff --git a/hw/misc/aspeed_hace.c b/hw/misc/aspeed_hace.c index
> > 51c6523fab..8f333fc97e 100644
> > --- a/hw/misc/aspeed_hace.c
> > +++ b/hw/misc/aspeed_hace.c
> > @@ -148,6 +148,7 @@ static bool has_padding(AspeedHACEState *s, struct
> iovec *iov,
> >   static void do_hash_operation(AspeedHACEState *s, int algo, bool
> sg_mode,
> >                                 bool acc_mode)
> >   {
> > +    AspeedHACEClass *ahc = ASPEED_HACE_GET_CLASS(s);
> >       bool sg_acc_mode_final_request = false;
> >       g_autofree uint8_t *digest_buf = NULL;
> >       struct iovec iov[ASPEED_HACE_MAX_SG]; @@ -182,6 +183,9 @@
> static
> > void do_hash_operation(AspeedHACEState *s, int algo, bool sg_mode,
> >               }
> >
> >               src = deposit64(src, 0, 32, s->regs[R_HASH_SRC]);
> > +            if (ahc->has_dma64) {
> > +                src = deposit64(src, 32, 32, s->regs[R_HASH_SRC_HI]);
> > +            }
> 
> That's where a little helper would be nice to have.
> 
I add hash_get_source_addr help function.
Please see patch 6 comments.

> >               src += i * SG_LIST_ENTRY_SIZE;
> >
> >               len = address_space_ldl_le(&s->dram_as, src, @@ -190,6
> > +194,21 @@ static void do_hash_operation(AspeedHACEState *s, int algo,
> bool sg_mode,
> >               sg_addr = address_space_ldl_le(&s->dram_as, src +
> SG_LIST_LEN_SIZE,
> >
> MEMTXATTRS_UNSPECIFIED, NULL);
> >               sg_addr &= SG_LIST_ADDR_MASK;
> > +            /*
> > +             * Ideally, sg_addr should be 64-bit for the AST2700, using
> the
> > +             * following program to obtain the 64-bit sg_addr and
> convert it
> > +             * to a DRAM offset:
> > +             * sg_addr = deposit64(sg_addr, 32, 32,
> > +             *      address_space_ldl_le(&s->dram_as, src +
> SG_ADDR_LEN_SIZE,
> > +             *
> MEMTXATTRS_UNSPECIFIED, NULL);
> > +             * sg_addr -= 0x400000000;
> > +             *
> 
> I don't think the above comment is useful. Please keep the one below.
> 
> > +             * To maintain compatibility with older SoCs such as the
> AST2600,
> > +             * the AST2700 HW automatically set bit 34 of the 64-bit
> sg_addr.
> > +             * As a result, the firmware only needs to provide a 32-bit
> sg_addr
> > +             * containing bits [31:0]. This is sufficient for the AST2700,
> as
> > +             * it uses a DRAM offset rather than a DRAM address.
> > +             */
> 

Thanks for suggestion will update them.

> The SG_LIST_ADDR_MASK needs an update though. AFAICT, it's bigger on
> AST2700.

The value of SG_LIST_ADDR_MASK was wrong for AST2700, AST2600 and AST1030. 
The correct value should be 0x7FFFFFF8.
Will create a new patch to fix it.
Please see patch 4 comments.
By the way, AST2500 do not support SG mode. 
Thanks-Jamin
> 
> 
> Thanks,
> 
> C.
> 
> 
> 
> >               plen = len & SG_LIST_LEN_MASK;
> >               haddr = address_space_map(&s->dram_as, sg_addr, &plen,
> > false, @@ -218,7 +237,9 @@ static void
> do_hash_operation(AspeedHACEState *s, int algo, bool sg_mode,
> >       } else {
> >           plen = s->regs[R_HASH_SRC_LEN];
> >           src = deposit64(src, 0, 32, s->regs[R_HASH_SRC]);
> > -
> > +        if (ahc->has_dma64) {
> > +            src = deposit64(src, 32, 32, s->regs[R_HASH_SRC_HI]);
> > +        }
> >           haddr = address_space_map(&s->dram_as, src,
> >                                     &plen, false,
> MEMTXATTRS_UNSPECIFIED);
> >           if (haddr == NULL) {
> > @@ -275,6 +296,9 @@ static void do_hash_operation(AspeedHACEState *s,
> int algo, bool sg_mode,
> >       }
> >
> >       digest_addr = deposit64(digest_addr, 0, 32,
> > s->regs[R_HASH_DEST]);
> > +    if (ahc->has_dma64) {
> > +        digest_addr = deposit64(digest_addr, 32, 32,
> s->regs[R_HASH_DEST_HI]);
> > +    }
> >       if (address_space_write(&s->dram_as, digest_addr,
> >                               MEMTXATTRS_UNSPECIFIED,
> >                               digest_buf, digest_len)) { @@ -601,6
> > +625,7 @@ static void aspeed_ast2700_hace_class_init(ObjectClass *klass,
> void *data)
> >        * has completed. It is a temporary workaround.
> >        */
> >       ahc->raise_crypt_interrupt_workaround = true;
> > +    ahc->has_dma64 = true;
> >   }
> >
> >   static const TypeInfo aspeed_ast2700_hace_info = {

Reply via email to