@samitouri / QOSamiQemu / commits / c98058bb3d

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> Reviewed-by: Kane Chen <kane_chen@aspeedtech.com> Link: https://lore.kernel.org/qemu-devel/20260811060115.1849266-14-jamin_lin@aspeedtech.com Signed-off-by: Cédric Le Goater <clg@redhat.com>

Jamin Lin committed Aug 11, 2026 at 06:01 UTC c98058bb3d3464be0923ffd5f88937ecc57a0cac
1 file changed +30 -3
hw/misc/aspeed_hace.c
+30 -3
@@ -57,6 +57,11 @@
57 #define CRYPT_CTX_KEY_OFFSET 0x10
58 #define CRYPT_CTX_SIZE 0x30
59
60 +/* AST2700 64-bit DMA high address registers for the crypto command */
61 +#define R_CRYPT_SRC_HI (0x80 / 4)
62 +#define R_CRYPT_DEST_HI (0x84 / 4)
63 +#define R_CRYPT_CONTEXT_HI (0x88 / 4)
64 +
65 #define R_STATUS (0x1c / 4)
66 #define HASH_IRQ BIT(9)
67 #define CRYPT_IRQ BIT(12)
@@ -670,6 +675,19 @@ static void crypt_be_add(uint8_t *ctr, size_t len, uint64_t add)
675 }
676 }
677
678 +static uint64_t crypt_get_addr(AspeedHACEState *s, int reg, int reg_hi)
679 +{
680 + AspeedHACEClass *ahc = ASPEED_HACE_GET_CLASS(s);
681 + uint64_t addr;
682 +
683 + addr = deposit64(0, 0, 32, s->regs[reg]);
684 + if (ahc->has_dma64) {
685 + addr = deposit64(addr, 32, 32, s->regs[reg_hi]);
686 + }
687 +
688 + return addr;
689 +}
690 +
691 /*
692 * Perform an AES/DES/3DES ECB/CBC operation. The source and destination are
693 * either single contiguous buffers (direct access mode) or scatter-gather
@@ -717,7 +735,7 @@ static void do_crypt_operation(AspeedHACEState *s, uint32_t cmd)
735 }
736
737 /* Fetch the IV and key from the context buffer in DRAM. */
720 - ctx_addr = s->regs[R_CRYPT_CONTEXT];
738 + ctx_addr = crypt_get_addr(s, R_CRYPT_CONTEXT, R_CRYPT_CONTEXT_HI);
739 if (address_space_read(&s->dram_as, ctx_addr, MEMTXATTRS_UNSPECIFIED,
740 ctx, sizeof(ctx))) {
741 qemu_log_mask(LOG_GUEST_ERROR,
@@ -758,7 +776,7 @@ static void do_crypt_operation(AspeedHACEState *s, uint32_t cmd)
776 dst_buf = g_malloc0(buf_len);
777
778 /* Gather the source into the bounce buffer, per the selected mode. */
761 - src_addr = s->regs[R_CRYPT_SRC];
779 + src_addr = crypt_get_addr(s, R_CRYPT_SRC, R_CRYPT_SRC_HI);
780 if (sg_mode) {
781 status = crypt_prepare_sg(s, src_addr, src_buf, len, false);
782 } else {
@@ -794,7 +812,7 @@ static void do_crypt_operation(AspeedHACEState *s, uint32_t cmd)
812 }
813
814 /* Scatter the result back out, per the selected mode. */
797 - dst_addr = s->regs[R_CRYPT_DEST];
815 + dst_addr = crypt_get_addr(s, R_CRYPT_DEST, R_CRYPT_DEST_HI);
816 if (sg_mode) {
817 status = crypt_prepare_sg(s, dst_addr, dst_buf, len, true);
818 } else {
@@ -958,6 +976,15 @@ static void aspeed_hace_write(void *opaque, hwaddr addr, uint64_t data,
976 case R_HASH_KEY_BUFF_HI:
977 data &= ahc->key_hi_mask;
978 break;
979 + case R_CRYPT_SRC_HI:
980 + data &= ahc->src_hi_mask;
981 + break;
982 + case R_CRYPT_DEST_HI:
983 + data &= ahc->dest_hi_mask;
984 + break;
985 + case R_CRYPT_CONTEXT_HI:
986 + data &= ahc->key_hi_mask;
987 + break;
988 default:
989 break;
990 }