[PATCH v2 13/17] hw/misc/aspeed_hace: Support 64-bit DMA for the crypto command

Jamin Lin posted 17 patches 1 month, 4 weeks ago
Maintainers: "Daniel P. Berrangé" <berrange@redhat.com>, "Cédric Le Goater" <clg@kaod.org>, Peter Maydell <peter.maydell@linaro.org>, Steven Lee <steven_lee@aspeedtech.com>, Troy Lee <leetroy@gmail.com>, Jamin Lin <jamin_lin@aspeedtech.com>, Kane Chen <kane_chen@aspeedtech.com>, Andrew Jeffery <andrew@codeconstruct.com.au>, Joel Stanley <joel@jms.id.au>, Eric Blake <eblake@redhat.com>, Markus Armbruster <armbru@redhat.com>, Fabiano Rosas <farosas@suse.de>, Laurent Vivier <lvivier@redhat.com>, Paolo Bonzini <pbonzini@redhat.com>
There is a newer version of this series
[PATCH v2 13/17] hw/misc/aspeed_hace: Support 64-bit DMA for the crypto command
Posted by Jamin Lin 1 month, 4 weeks ago
The AST2700 crypto engine addresses DRAM with 64 bits, supplying the high
half of the source, destination and context addresses through HACE80,
HACE84 and HACE88. Add those registers and a crypt_get_addr() helper that
combines the low and high halves when the SoC has 64-bit DMA, mirroring
the hash engine. SoCs without 64-bit DMA (AST2500/AST2600/AST1030) ignore
the high registers, so their behaviour is unchanged.

Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
---
 hw/misc/aspeed_hace.c | 33 ++++++++++++++++++++++++++++++---
 1 file changed, 30 insertions(+), 3 deletions(-)

diff --git a/hw/misc/aspeed_hace.c b/hw/misc/aspeed_hace.c
index 09d0515271..a807cc1422 100644
--- a/hw/misc/aspeed_hace.c
+++ b/hw/misc/aspeed_hace.c
@@ -58,6 +58,11 @@
 #define CRYPT_CTX_KEY_OFFSET        0x10
 #define CRYPT_CTX_SIZE              0x30
 
+/* AST2700 64-bit DMA high address registers for the crypto command */
+#define R_CRYPT_SRC_HI      (0x80 / 4)
+#define R_CRYPT_DEST_HI     (0x84 / 4)
+#define R_CRYPT_CONTEXT_HI  (0x88 / 4)
+
 #define R_STATUS        (0x1c / 4)
 #define HASH_IRQ        BIT(9)
 #define CRYPT_IRQ       BIT(12)
@@ -672,6 +677,19 @@ static void crypt_be_add(uint8_t *ctr, size_t len, uint64_t add)
     }
 }
 
+static uint64_t crypt_get_addr(AspeedHACEState *s, int reg, int reg_hi)
+{
+    AspeedHACEClass *ahc = ASPEED_HACE_GET_CLASS(s);
+    uint64_t addr;
+
+    addr = deposit64(0, 0, 32, s->regs[reg]);
+    if (ahc->has_dma64) {
+        addr = deposit64(addr, 32, 32, s->regs[reg_hi]);
+    }
+
+    return addr;
+}
+
 /*
  * Perform an AES/DES/3DES ECB/CBC operation. The source and destination are
  * either single contiguous buffers (direct access mode) or scatter-gather
@@ -719,7 +737,7 @@ static void do_crypt_operation(AspeedHACEState *s, uint32_t cmd)
     }
 
     /* Fetch the IV and key from the context buffer in DRAM. */
-    ctx_addr = s->regs[R_CRYPT_CONTEXT];
+    ctx_addr = crypt_get_addr(s, R_CRYPT_CONTEXT, R_CRYPT_CONTEXT_HI);
     if (address_space_read(&s->dram_as, ctx_addr, MEMTXATTRS_UNSPECIFIED,
                            ctx, sizeof(ctx))) {
         qemu_log_mask(LOG_GUEST_ERROR,
@@ -760,7 +778,7 @@ static void do_crypt_operation(AspeedHACEState *s, uint32_t cmd)
     dst_buf = g_malloc0(buf_len);
 
     /* Gather the source into the bounce buffer, per the selected mode. */
-    src_addr = s->regs[R_CRYPT_SRC];
+    src_addr = crypt_get_addr(s, R_CRYPT_SRC, R_CRYPT_SRC_HI);
     if (sg_mode) {
         status = crypt_prepare_sg(s, src_addr, src_buf, len, false);
     } else {
@@ -796,7 +814,7 @@ static void do_crypt_operation(AspeedHACEState *s, uint32_t cmd)
     }
 
     /* Scatter the result back out, per the selected mode. */
-    dst_addr = s->regs[R_CRYPT_DEST];
+    dst_addr = crypt_get_addr(s, R_CRYPT_DEST, R_CRYPT_DEST_HI);
     if (sg_mode) {
         status = crypt_prepare_sg(s, dst_addr, dst_buf, len, true);
     } else {
@@ -960,6 +978,15 @@ static void aspeed_hace_write(void *opaque, hwaddr addr, uint64_t data,
     case R_HASH_KEY_BUFF_HI:
         data &= ahc->key_hi_mask;
         break;
+    case R_CRYPT_SRC_HI:
+        data &= ahc->src_hi_mask;
+        break;
+    case R_CRYPT_DEST_HI:
+        data &= ahc->dest_hi_mask;
+        break;
+    case R_CRYPT_CONTEXT_HI:
+        data &= ahc->key_hi_mask;
+        break;
     default:
         break;
     }
-- 
2.43.0
RE: [PATCH v2 13/17] hw/misc/aspeed_hace: Support 64-bit DMA for the crypto command
Posted by Kane Chen 1 month ago
> -----Original Message-----
> From: Jamin Lin <jamin_lin@aspeedtech.com>
> Sent: Wednesday, July 15, 2026 11:34 AM
> To: Daniel P. Berrangé <berrange@redhat.com>; Cédric Le Goater
> <clg@kaod.org>; Peter Maydell <peter.maydell@linaro.org>; Steven Lee
> <steven_lee@aspeedtech.com>; Troy Lee <leetroy@gmail.com>; Kane Chen
> <kane_chen@aspeedtech.com>; Andrew Jeffery
> <andrew@codeconstruct.com.au>; Joel Stanley <joel@jms.id.au>; Eric Blake
> <eblake@redhat.com>; Markus Armbruster <armbru@redhat.com>; Fabiano
> Rosas <farosas@suse.de>; Laurent Vivier <lvivier@redhat.com>; Paolo Bonzini
> <pbonzini@redhat.com>; open list:All patches CC here
> <qemu-devel@nongnu.org>; open list:ASPEED BMCs
> <qemu-arm@nongnu.org>
> Cc: Jamin Lin <jamin_lin@aspeedtech.com>; Troy Lee
> <troy_lee@aspeedtech.com>
> Subject: [PATCH v2 13/17] hw/misc/aspeed_hace: Support 64-bit DMA for the
> crypto command
> 
> The AST2700 crypto engine addresses DRAM with 64 bits, supplying the high
> half of the source, destination and context addresses through HACE80,
> HACE84 and HACE88. Add those registers and a crypt_get_addr() helper that
> combines the low and high halves when the SoC has 64-bit DMA, mirroring the
> hash engine. SoCs without 64-bit DMA (AST2500/AST2600/AST1030) ignore the
> high registers, so their behaviour is unchanged.
> 
> Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
> ---
>  hw/misc/aspeed_hace.c | 33 ++++++++++++++++++++++++++++++---
>  1 file changed, 30 insertions(+), 3 deletions(-)
> 
> diff --git a/hw/misc/aspeed_hace.c b/hw/misc/aspeed_hace.c index
> 09d0515271..a807cc1422 100644
> --- a/hw/misc/aspeed_hace.c
> +++ b/hw/misc/aspeed_hace.c
> @@ -58,6 +58,11 @@
>  #define CRYPT_CTX_KEY_OFFSET        0x10
>  #define CRYPT_CTX_SIZE              0x30
> 
> +/* AST2700 64-bit DMA high address registers for the crypto command */
> +#define R_CRYPT_SRC_HI      (0x80 / 4)
> +#define R_CRYPT_DEST_HI     (0x84 / 4)
> +#define R_CRYPT_CONTEXT_HI  (0x88 / 4)
> +
>  #define R_STATUS        (0x1c / 4)
>  #define HASH_IRQ        BIT(9)
>  #define CRYPT_IRQ       BIT(12)
> @@ -672,6 +677,19 @@ static void crypt_be_add(uint8_t *ctr, size_t len,
> uint64_t add)
>      }
>  }
> 
> +static uint64_t crypt_get_addr(AspeedHACEState *s, int reg, int reg_hi)
> +{
> +    AspeedHACEClass *ahc = ASPEED_HACE_GET_CLASS(s);
> +    uint64_t addr;
> +
> +    addr = deposit64(0, 0, 32, s->regs[reg]);
> +    if (ahc->has_dma64) {
> +        addr = deposit64(addr, 32, 32, s->regs[reg_hi]);
> +    }
> +
> +    return addr;
> +}
> +
>  /*
>   * Perform an AES/DES/3DES ECB/CBC operation. The source and destination
> are
>   * either single contiguous buffers (direct access mode) or scatter-gather
> @@ -719,7 +737,7 @@ static void do_crypt_operation(AspeedHACEState *s,
> uint32_t cmd)
>      }
> 
>      /* Fetch the IV and key from the context buffer in DRAM. */
> -    ctx_addr = s->regs[R_CRYPT_CONTEXT];
> +    ctx_addr = crypt_get_addr(s, R_CRYPT_CONTEXT,
> R_CRYPT_CONTEXT_HI);
>      if (address_space_read(&s->dram_as, ctx_addr,
> MEMTXATTRS_UNSPECIFIED,
>                             ctx, sizeof(ctx))) {
>          qemu_log_mask(LOG_GUEST_ERROR,
> @@ -760,7 +778,7 @@ static void do_crypt_operation(AspeedHACEState *s,
> uint32_t cmd)
>      dst_buf = g_malloc0(buf_len);
> 
>      /* Gather the source into the bounce buffer, per the selected mode. */
> -    src_addr = s->regs[R_CRYPT_SRC];
> +    src_addr = crypt_get_addr(s, R_CRYPT_SRC, R_CRYPT_SRC_HI);
>      if (sg_mode) {
>          status = crypt_prepare_sg(s, src_addr, src_buf, len, false);
>      } else {
> @@ -796,7 +814,7 @@ static void do_crypt_operation(AspeedHACEState *s,
> uint32_t cmd)
>      }
> 
>      /* Scatter the result back out, per the selected mode. */
> -    dst_addr = s->regs[R_CRYPT_DEST];
> +    dst_addr = crypt_get_addr(s, R_CRYPT_DEST, R_CRYPT_DEST_HI);
>      if (sg_mode) {
>          status = crypt_prepare_sg(s, dst_addr, dst_buf, len, true);
>      } else {
> @@ -960,6 +978,15 @@ static void aspeed_hace_write(void *opaque, hwaddr
> addr, uint64_t data,
>      case R_HASH_KEY_BUFF_HI:
>          data &= ahc->key_hi_mask;
>          break;
> +    case R_CRYPT_SRC_HI:
> +        data &= ahc->src_hi_mask;
> +        break;
> +    case R_CRYPT_DEST_HI:
> +        data &= ahc->dest_hi_mask;
> +        break;
> +    case R_CRYPT_CONTEXT_HI:
> +        data &= ahc->key_hi_mask;
> +        break;
>      default:
>          break;
>      }
> --
> 2.43.0

Reviewed-by: Kane Chen <kane_chen@aspeedtech.com>