qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v1 00/22] Fix incorrect hash results on AST2700
@ 2025-03-21  9:25 Jamin Lin via
  2025-03-21  9:25 ` [PATCH v1 01/22] hw/misc/aspeed_hace: Remove unused code for better readability Jamin Lin via
                   ` (23 more replies)
  0 siblings, 24 replies; 71+ messages in thread
From: Jamin Lin via @ 2025-03-21  9:25 UTC (permalink / raw)
  To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
	Andrew Jeffery, Joel Stanley, Fabiano Rosas, Laurent Vivier,
	Paolo Bonzini, open list:ASPEED BMCs,
	open list:All patches CC here
  Cc: jamin_lin, troy_lee

v1:
 1. Added support for 64-bit DMA in the HACE model
 2. Refactored the do_hash operation in the HACE model
 3. Fixed a crash caused by out-of-bound memory access in HACE
 4. Added more trace events and implemented dumping of source hash data and
    resulting digests to improve debugging
 5. Refactored the HACE QTest framework to support both AST1030 and AST2700
 6. Added a test case for SHA384

This patchset resolves incorrect hash results reported on the AST2700 platform.
This update addresses the following kernel warnings and test failures related to
the crypto self-test framework:

aspeed-hmac-sha512 test failed (incorrect result)
aspeed-hmac-sha384 test failed (incorrect result)
aspeed-sha512 test failed (incorrect result)
aspeed-sha384 test failed (incorrect result)
aspeed-hmac-sha256 test failed (incorrect result)
aspeed-hmac-sha224 test failed (incorrect result)
aspeed-hmac-sha1 test failed (incorrect result)
aspeed-sha224 test failed (incorrect result)
aspeed-sha256 test failed (incorrect result)
aspeed-sha1 test failed (incorrect result)

How to test it

Use the following command to dump information about the supported digest methods
via the afalg hardware engine:

root@ast2700-default:~# openssl engine -pre DUMP_INFO afalg

Digest SHA1, NID=64, AF_ALG info: name=sha1ALG_ERR: , driver=aspeed-sha1 (hw accelerated)
Digest SHA224, NID=675, AF_ALG info: name=sha224ALG_ERR: , driver=aspeed-sha224 (hw accelerated)
Digest SHA256, NID=672, AF_ALG info: name=sha256ALG_ERR: , driver=aspeed-sha256 (hw accelerated)
Digest SHA384, NID=673, AF_ALG info: name=sha384ALG_ERR: , driver=aspeed-sha384 (hw accelerated)
Digest SHA512, NID=674, AF_ALG info: name=sha512ALG_ERR: , driver=aspeed-sha512 (hw accelerated)

The status of SHA1, SHA224, SHA256, SHA384, and SHA512 should be marked as
hw accelerated, indicating that these algorithms are supported by hardware
acceleration via the aspeed drivers.

Create a test file on the host machine and compute its HASH value as the
expected result

Create a 256MB test file

$ dd if=/dev/random of=/tmp/256M bs=1M count=256
Generate Hash Values Using SHA1, SHA224, SHA256, SHA384, and SHA512

Use the following commands to generate HASH values for a 256MB file using
different SHA algorithms:

$ sha1sum /tmp/256M
7fc628811a31ab87b0502dab3ed8d3ef07565885  /tmp/256M

$ sha224sum /tmp/256M
2d261c11ba05b3a62e0efeab51c307d9933426c7e18204683ef3da54  /tmp/256M

$ sha256sum /tmp/256M
5716d1700ee35c92ca5ca5b466639e9c36eed3f1447c1aec27f16d0fe113f94d  /tmp/256M

$ sha384sum /tmp/256M
fb6bc62afa1096dcd3b870e7d2546b7a5a177b5f2bbd5c9759218182454709e0c504a2d9c26404e04aa8010a291b7f1c  /tmp/256M

$ sha512sum /tmp/256M
fbceda7be34836fe857781656318ecd5b457a833a24c8736d5b8ef8d07e1950eebcdb140eebe4f12b5ff59586f7eb1c64fa95869c63dd9e4703d91261093c5c9  /tmp/256M

Generate HASH Values Using the Hardware Engine

Use the following commands to generate HASH values for a 256MB file using
various SHA algorithms with the afalg hardware engine:


root@ast2700-default:~# openssl dgst -sha1 -engine afalg /tmp/256M
Engine "afalg" set.
SHA1(/tmp/256M)= 7fc628811a31ab87b0502dab3ed8d3ef07565885

root@ast2700-default:~# openssl dgst -sha224 -engine ast_crypto_engine /tmp/256M
Engine "afalg" set.
SHA2-224(/tmp/256M)= 2d261c11ba05b3a62e0efeab51c307d9933426c7e18204683ef3da54

root@ast2700-default:~# openssl dgst -sha256 -engine afalg /tmp/256M
Engine "afalg" set.
SHA2-256(/tmp/256M)= 5716d1700ee35c92ca5ca5b466639e9c36eed3f1447c1aec27f16d0fe113f94d

root@ast2700-default:~# openssl dgst -sha384 -engine afalg /tmp/256M
Engine "afalg" set.
SHA2-384(/tmp/256M)= fb6bc62afa1096dcd3b870e7d2546b7a5a177b5f2bbd5c9759218182454709e0c504a2d9c26404e04aa8010a291b7f1c

root@ast2700-default:~# openssl dgst -sha512 -engine afalg /tmp/256M
Engine "afalg" set.
SHA2-512(/tmp/256M)= fbceda7be34836fe857781656318ecd5b457a833a24c8736d5b8ef8d07e1950eebcdb140eebe4f12b5ff59586f7eb1c64fa95869c63dd9e4703d91261093c5c9


The HASH values generated here should exactly match those computed on the host
machine using software-based OpenSSL, verifying both the correctness of the
hardware-accelerated results and the functionality of the afalg.


Jamin Lin (22):
  hw/misc/aspeed_hace: Remove unused code for better readability
  hw/misc/aspeed_hace: Fix buffer overflow in has_padding function
  hw/misc/aspeed_hace: Improve readability and consistency in variable
    naming
  hw/misc/aspeed_hace: Update hash source address handling to 64-bit for
    AST2700
  hw/misc/aspeed_hace: Introduce 64-bit digest_addr variable for AST2700
  hw/misc/aspeed_hace: Support accumulative mode for direct access mode
  hw/misc/aspeed_hace: Add support for source, digest, key buffer 64 bit
    addresses
  hw/misc/aspeed_hace: Support DMA 64 bits dram address.
  hw/misc/aspeed_hace: Ensure HASH_IRQ is always set to prevent firmware
    hang
  hw/misc/aspeed_hace:: Support setting different memory size
  hw/misc/aspeed_hace: Add trace-events for better debugging
  hw/misc/aspeed_hace Support to dump plaintext and digest for better
    debugging
  test/qtest: Introduce a new aspeed-hace-utils.c to place common
    testcases
  test/qtest/hace: Adjust test address range for AST1030 due to SRAM
    limitations
  test/qtest/hace: Add SHA-384 test cases for ASPEED HACE model
  test/qtest/hace: Add SHA-384 tests for AST2600
  test/qtest/hace: Add tests for AST1030
  test/qtest/hace: Update source data and digest data type to 64-bit
  test/qtest/hace: Support 64-bit source and digest addresses for
    AST2700
  test/qtest/hace: Support to test upper 32 bits of digest and source
    addresses
  test/qtest/hace: Support to validate 64-bit hmac key buffer addresses
  test/qtest/hace: Add tests for AST2700

 include/hw/misc/aspeed_hace.h   |   9 +-
 tests/qtest/aspeed-hace-utils.h |  84 +++++
 hw/misc/aspeed_hace.c           | 194 ++++++----
 tests/qtest/aspeed-hace-utils.c | 646 ++++++++++++++++++++++++++++++++
 tests/qtest/aspeed_hace-test.c  | 577 +++++-----------------------
 tests/qtest/ast2700-hace-test.c |  98 +++++
 hw/misc/trace-events            |   6 +
 tests/qtest/meson.build         |   5 +-
 8 files changed, 1074 insertions(+), 545 deletions(-)
 create mode 100644 tests/qtest/aspeed-hace-utils.h
 create mode 100644 tests/qtest/aspeed-hace-utils.c
 create mode 100644 tests/qtest/ast2700-hace-test.c

-- 
2.43.0



^ permalink raw reply	[flat|nested] 71+ messages in thread

* [PATCH v1 01/22] hw/misc/aspeed_hace: Remove unused code for better readability
  2025-03-21  9:25 [PATCH v1 00/22] Fix incorrect hash results on AST2700 Jamin Lin via
@ 2025-03-21  9:25 ` Jamin Lin via
  2025-04-01 13:08   ` Cédric Le Goater
  2025-03-21  9:25 ` [PATCH v1 02/22] hw/misc/aspeed_hace: Fix buffer overflow in has_padding function Jamin Lin via
                   ` (22 subsequent siblings)
  23 siblings, 1 reply; 71+ messages in thread
From: Jamin Lin via @ 2025-03-21  9:25 UTC (permalink / raw)
  To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
	Andrew Jeffery, Joel Stanley, Fabiano Rosas, Laurent Vivier,
	Paolo Bonzini, open list:ASPEED BMCs,
	open list:All patches CC here
  Cc: jamin_lin, troy_lee

This cleanup follows significant changes in commit 4c1d0af4a28d, making the
model more readable.

- Deleted "iov_cache" and "iov_count" from "AspeedHACEState".
- Removed "reconstruct_iov" function and related logic.
- Simplified "do_hash_operation" by eliminating redundant checks.

Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
---
 include/hw/misc/aspeed_hace.h |  2 --
 hw/misc/aspeed_hace.c         | 35 -----------------------------------
 2 files changed, 37 deletions(-)

diff --git a/include/hw/misc/aspeed_hace.h b/include/hw/misc/aspeed_hace.h
index 5d4aa19cfe..b69a038d35 100644
--- a/include/hw/misc/aspeed_hace.h
+++ b/include/hw/misc/aspeed_hace.h
@@ -31,10 +31,8 @@ struct AspeedHACEState {
     MemoryRegion iomem;
     qemu_irq irq;
 
-    struct iovec iov_cache[ASPEED_HACE_MAX_SG];
     uint32_t regs[ASPEED_HACE_NR_REGS];
     uint32_t total_req_len;
-    uint32_t iov_count;
 
     MemoryRegion *dram_mr;
     AddressSpace dram_as;
diff --git a/hw/misc/aspeed_hace.c b/hw/misc/aspeed_hace.c
index 32a5dbded3..8e7e8113a5 100644
--- a/hw/misc/aspeed_hace.c
+++ b/hw/misc/aspeed_hace.c
@@ -137,25 +137,6 @@ static bool has_padding(AspeedHACEState *s, struct iovec *iov,
     return false;
 }
 
-static int reconstruct_iov(AspeedHACEState *s, struct iovec *iov, int id,
-                           uint32_t *pad_offset)
-{
-    int i, iov_count;
-    if (*pad_offset != 0) {
-        s->iov_cache[s->iov_count].iov_base = iov[id].iov_base;
-        s->iov_cache[s->iov_count].iov_len = *pad_offset;
-        ++s->iov_count;
-    }
-    for (i = 0; i < s->iov_count; i++) {
-        iov[i].iov_base = s->iov_cache[i].iov_base;
-        iov[i].iov_len = s->iov_cache[i].iov_len;
-    }
-    iov_count = s->iov_count;
-    s->iov_count = 0;
-    s->total_req_len = 0;
-    return iov_count;
-}
-
 static void do_hash_operation(AspeedHACEState *s, int algo, bool sg_mode,
                               bool acc_mode)
 {
@@ -237,19 +218,6 @@ static void do_hash_operation(AspeedHACEState *s, int algo, bool sg_mode,
         iov[0].iov_base = haddr;
         iov[0].iov_len = len;
         i = 1;
-
-        if (s->iov_count) {
-            /*
-             * In aspeed sdk kernel driver, sg_mode is disabled in hash_final().
-             * Thus if we received a request with sg_mode disabled, it is
-             * required to check whether cache is empty. If no, we should
-             * combine cached iov and the current iov.
-             */
-            s->total_req_len += len;
-            if (has_padding(s, iov, len, &total_msg_len, &pad_offset)) {
-                i = reconstruct_iov(s, iov, 0, &pad_offset);
-            }
-        }
     }
 
     if (acc_mode) {
@@ -273,7 +241,6 @@ static void do_hash_operation(AspeedHACEState *s, int algo, bool sg_mode,
             qcrypto_hash_free(s->hash_ctx);
 
             s->hash_ctx = NULL;
-            s->iov_count = 0;
             s->total_req_len = 0;
         }
     } else if (qcrypto_hash_bytesv(algo, iov, i, &digest_buf,
@@ -432,7 +399,6 @@ static void aspeed_hace_reset(DeviceState *dev)
     }
 
     memset(s->regs, 0, sizeof(s->regs));
-    s->iov_count = 0;
     s->total_req_len = 0;
 }
 
@@ -469,7 +435,6 @@ static const VMStateDescription vmstate_aspeed_hace = {
     .fields = (const VMStateField[]) {
         VMSTATE_UINT32_ARRAY(regs, AspeedHACEState, ASPEED_HACE_NR_REGS),
         VMSTATE_UINT32(total_req_len, AspeedHACEState),
-        VMSTATE_UINT32(iov_count, AspeedHACEState),
         VMSTATE_END_OF_LIST(),
     }
 };
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 71+ messages in thread

* [PATCH v1 02/22] hw/misc/aspeed_hace: Fix buffer overflow in has_padding function
  2025-03-21  9:25 [PATCH v1 00/22] Fix incorrect hash results on AST2700 Jamin Lin via
  2025-03-21  9:25 ` [PATCH v1 01/22] hw/misc/aspeed_hace: Remove unused code for better readability Jamin Lin via
@ 2025-03-21  9:25 ` Jamin Lin via
  2025-03-21  9:47   ` Jamin Lin
  2025-03-21  9:25 ` [PATCH v1 03/22] hw/misc/aspeed_hace: Improve readability and consistency in variable naming Jamin Lin via
                   ` (21 subsequent siblings)
  23 siblings, 1 reply; 71+ messages in thread
From: Jamin Lin via @ 2025-03-21  9:25 UTC (permalink / raw)
  To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
	Andrew Jeffery, Joel Stanley, Fabiano Rosas, Laurent Vivier,
	Paolo Bonzini, open list:ASPEED BMCs,
	open list:All patches CC here
  Cc: jamin_lin, troy_lee

The maximum padding size is either 64 or 128 bytes and should always be smaller
than "req_len". If "padding_size" exceeds "req_len", then
"req_len - padding_size" underflows due to "uint32_t" data type, leading to a
large incorrect value (e.g., `0xFFXXXXXX`). This causes an out-of-bounds memory
access, potentially leading to a buffer overflow.

Added a check to ensure "padding_size" does not exceed "req_len" before
computing "pad_offset". This prevents "req_len - padding_size" from underflowing
and avoids accessing invalid memory.

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

diff --git a/hw/misc/aspeed_hace.c b/hw/misc/aspeed_hace.c
index 8e7e8113a5..d8b5f048bb 100644
--- a/hw/misc/aspeed_hace.c
+++ b/hw/misc/aspeed_hace.c
@@ -128,6 +128,11 @@ static bool has_padding(AspeedHACEState *s, struct iovec *iov,
     if (*total_msg_len <= s->total_req_len) {
         uint32_t padding_size = s->total_req_len - *total_msg_len;
         uint8_t *padding = iov->iov_base;
+
+        if (padding_size > req_len) {
+            return false;
+        }
+
         *pad_offset = req_len - padding_size;
         if (padding[*pad_offset] == 0x80) {
             return true;
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 71+ messages in thread

* [PATCH v1 03/22] hw/misc/aspeed_hace: Improve readability and consistency in variable naming
  2025-03-21  9:25 [PATCH v1 00/22] Fix incorrect hash results on AST2700 Jamin Lin via
  2025-03-21  9:25 ` [PATCH v1 01/22] hw/misc/aspeed_hace: Remove unused code for better readability Jamin Lin via
  2025-03-21  9:25 ` [PATCH v1 02/22] hw/misc/aspeed_hace: Fix buffer overflow in has_padding function Jamin Lin via
@ 2025-03-21  9:25 ` Jamin Lin via
  2025-04-01 13:17   ` Cédric Le Goater
  2025-03-21  9:26 ` [PATCH v1 04/22] hw/misc/aspeed_hace: Update hash source address handling to 64-bit for AST2700 Jamin Lin via
                   ` (20 subsequent siblings)
  23 siblings, 1 reply; 71+ messages in thread
From: Jamin Lin via @ 2025-03-21  9:25 UTC (permalink / raw)
  To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
	Andrew Jeffery, Joel Stanley, Fabiano Rosas, Laurent Vivier,
	Paolo Bonzini, open list:ASPEED BMCs,
	open list:All patches CC here
  Cc: jamin_lin, troy_lee

Currently, users define multiple local variables within different if-statements.
To improve readability and maintain consistency in variable naming, rename the
variables accordingly.
Introduced "sg_addr" to clearly indicate the scatter-gather mode buffer address.

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

diff --git a/hw/misc/aspeed_hace.c b/hw/misc/aspeed_hace.c
index d8b5f048bb..4bcf6ed074 100644
--- a/hw/misc/aspeed_hace.c
+++ b/hw/misc/aspeed_hace.c
@@ -145,15 +145,19 @@ static bool has_padding(AspeedHACEState *s, struct iovec *iov,
 static void do_hash_operation(AspeedHACEState *s, int algo, bool sg_mode,
                               bool acc_mode)
 {
+    bool sg_acc_mode_final_request = false;
+    g_autofree uint8_t *digest_buf = NULL;
     struct iovec iov[ASPEED_HACE_MAX_SG];
+    Error *local_err = NULL;
     uint32_t total_msg_len;
-    uint32_t pad_offset;
-    g_autofree uint8_t *digest_buf = NULL;
     size_t digest_len = 0;
-    bool sg_acc_mode_final_request = false;
-    int i;
+    uint32_t sg_addr = 0;
+    uint32_t pad_offset;
+    uint32_t len = 0;
+    uint32_t src = 0;
     void *haddr;
-    Error *local_err = NULL;
+    hwaddr plen;
+    int i;
 
     if (acc_mode && s->hash_ctx == NULL) {
         s->hash_ctx = qcrypto_hash_new(algo, &local_err);
@@ -166,12 +170,7 @@ static void do_hash_operation(AspeedHACEState *s, int algo, bool sg_mode,
     }
 
     if (sg_mode) {
-        uint32_t len = 0;
-
         for (i = 0; !(len & SG_LIST_LEN_LAST); i++) {
-            uint32_t addr, src;
-            hwaddr plen;
-
             if (i == ASPEED_HACE_MAX_SG) {
                 qemu_log_mask(LOG_GUEST_ERROR,
                         "aspeed_hace: guest failed to set end of sg list marker\n");
@@ -183,12 +182,12 @@ static void do_hash_operation(AspeedHACEState *s, int algo, bool sg_mode,
             len = address_space_ldl_le(&s->dram_as, src,
                                        MEMTXATTRS_UNSPECIFIED, NULL);
 
-            addr = address_space_ldl_le(&s->dram_as, src + SG_LIST_LEN_SIZE,
-                                        MEMTXATTRS_UNSPECIFIED, NULL);
-            addr &= SG_LIST_ADDR_MASK;
+            sg_addr = address_space_ldl_le(&s->dram_as, src + SG_LIST_LEN_SIZE,
+                                           MEMTXATTRS_UNSPECIFIED, NULL);
+            sg_addr &= SG_LIST_ADDR_MASK;
 
             plen = len & SG_LIST_LEN_MASK;
-            haddr = address_space_map(&s->dram_as, addr, &plen, false,
+            haddr = address_space_map(&s->dram_as, sg_addr, &plen, false,
                                       MEMTXATTRS_UNSPECIFIED);
             if (haddr == NULL) {
                 qemu_log_mask(LOG_GUEST_ERROR,
@@ -212,16 +211,16 @@ static void do_hash_operation(AspeedHACEState *s, int algo, bool sg_mode,
             }
         }
     } else {
-        hwaddr len = s->regs[R_HASH_SRC_LEN];
+        plen = s->regs[R_HASH_SRC_LEN];
 
         haddr = address_space_map(&s->dram_as, s->regs[R_HASH_SRC],
-                                  &len, false, MEMTXATTRS_UNSPECIFIED);
+                                  &plen, false, MEMTXATTRS_UNSPECIFIED);
         if (haddr == NULL) {
             qemu_log_mask(LOG_GUEST_ERROR, "%s: qcrypto failed\n", __func__);
             return;
         }
         iov[0].iov_base = haddr;
-        iov[0].iov_len = len;
+        iov[0].iov_len = plen;
         i = 1;
     }
 
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 71+ messages in thread

* [PATCH v1 04/22] hw/misc/aspeed_hace: Update hash source address handling to 64-bit for AST2700
  2025-03-21  9:25 [PATCH v1 00/22] Fix incorrect hash results on AST2700 Jamin Lin via
                   ` (2 preceding siblings ...)
  2025-03-21  9:25 ` [PATCH v1 03/22] hw/misc/aspeed_hace: Improve readability and consistency in variable naming Jamin Lin via
@ 2025-03-21  9:26 ` Jamin Lin via
  2025-04-01 13:52   ` Cédric Le Goater
  2025-03-21  9:26 ` [PATCH v1 05/22] hw/misc/aspeed_hace: Introduce 64-bit digest_addr variable " Jamin Lin via
                   ` (19 subsequent siblings)
  23 siblings, 1 reply; 71+ messages in thread
From: Jamin Lin via @ 2025-03-21  9:26 UTC (permalink / raw)
  To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
	Andrew Jeffery, Joel Stanley, Fabiano Rosas, Laurent Vivier,
	Paolo Bonzini, open list:ASPEED BMCs,
	open list:All patches CC here
  Cc: jamin_lin, troy_lee

The AST2700 CPU, based on the Cortex-A35, is a 64-bit processor, and its DRAM
address space is also 64-bit. To support future AST2700 updates, the source
hash buffer address data type is being updated to 64-bit.

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

diff --git a/hw/misc/aspeed_hace.c b/hw/misc/aspeed_hace.c
index 4bcf6ed074..9771d6e490 100644
--- a/hw/misc/aspeed_hace.c
+++ b/hw/misc/aspeed_hace.c
@@ -154,7 +154,7 @@ static void do_hash_operation(AspeedHACEState *s, int algo, bool sg_mode,
     uint32_t sg_addr = 0;
     uint32_t pad_offset;
     uint32_t len = 0;
-    uint32_t src = 0;
+    uint64_t src = 0;
     void *haddr;
     hwaddr plen;
     int i;
@@ -177,7 +177,8 @@ static void do_hash_operation(AspeedHACEState *s, int algo, bool sg_mode,
                 break;
             }
 
-            src = s->regs[R_HASH_SRC] + (i * SG_LIST_ENTRY_SIZE);
+            src = deposit64(src, 0, 32, s->regs[R_HASH_SRC]);
+            src += i * SG_LIST_ENTRY_SIZE;
 
             len = address_space_ldl_le(&s->dram_as, src,
                                        MEMTXATTRS_UNSPECIFIED, NULL);
@@ -212,8 +213,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]);
 
-        haddr = address_space_map(&s->dram_as, s->regs[R_HASH_SRC],
+        haddr = address_space_map(&s->dram_as, src,
                                   &plen, false, MEMTXATTRS_UNSPECIFIED);
         if (haddr == NULL) {
             qemu_log_mask(LOG_GUEST_ERROR, "%s: qcrypto failed\n", __func__);
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 71+ messages in thread

* [PATCH v1 05/22] hw/misc/aspeed_hace: Introduce 64-bit digest_addr variable for AST2700
  2025-03-21  9:25 [PATCH v1 00/22] Fix incorrect hash results on AST2700 Jamin Lin via
                   ` (3 preceding siblings ...)
  2025-03-21  9:26 ` [PATCH v1 04/22] hw/misc/aspeed_hace: Update hash source address handling to 64-bit for AST2700 Jamin Lin via
@ 2025-03-21  9:26 ` Jamin Lin via
  2025-04-01 13:55   ` Cédric Le Goater
  2025-03-21  9:26 ` [PATCH v1 06/22] hw/misc/aspeed_hace: Support accumulative mode for direct access mode Jamin Lin via
                   ` (18 subsequent siblings)
  23 siblings, 1 reply; 71+ messages in thread
From: Jamin Lin via @ 2025-03-21  9:26 UTC (permalink / raw)
  To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
	Andrew Jeffery, Joel Stanley, Fabiano Rosas, Laurent Vivier,
	Paolo Bonzini, open list:ASPEED BMCs,
	open list:All patches CC here
  Cc: jamin_lin, troy_lee

The AST2700 CPU, based on the Cortex-A35, is a 64-bit processor with a 64-bit
DRAM address space. To support future AST2700 updates, a new "digest_addr"
variable is introduced with a 64-bit data type.

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

diff --git a/hw/misc/aspeed_hace.c b/hw/misc/aspeed_hace.c
index 9771d6e490..8cf3f194a5 100644
--- a/hw/misc/aspeed_hace.c
+++ b/hw/misc/aspeed_hace.c
@@ -148,6 +148,7 @@ static void do_hash_operation(AspeedHACEState *s, int algo, bool sg_mode,
     bool sg_acc_mode_final_request = false;
     g_autofree uint8_t *digest_buf = NULL;
     struct iovec iov[ASPEED_HACE_MAX_SG];
+    uint64_t digest_addr = 0;
     Error *local_err = NULL;
     uint32_t total_msg_len;
     size_t digest_len = 0;
@@ -257,7 +258,8 @@ static void do_hash_operation(AspeedHACEState *s, int algo, bool sg_mode,
         return;
     }
 
-    if (address_space_write(&s->dram_as, s->regs[R_HASH_DEST],
+    digest_addr = deposit64(digest_addr, 0, 32, s->regs[R_HASH_DEST]);
+    if (address_space_write(&s->dram_as, digest_addr,
                             MEMTXATTRS_UNSPECIFIED,
                             digest_buf, digest_len)) {
         qemu_log_mask(LOG_GUEST_ERROR,
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 71+ messages in thread

* [PATCH v1 06/22] hw/misc/aspeed_hace: Support accumulative mode for direct access mode
  2025-03-21  9:25 [PATCH v1 00/22] Fix incorrect hash results on AST2700 Jamin Lin via
                   ` (4 preceding siblings ...)
  2025-03-21  9:26 ` [PATCH v1 05/22] hw/misc/aspeed_hace: Introduce 64-bit digest_addr variable " Jamin Lin via
@ 2025-03-21  9:26 ` Jamin Lin via
  2025-04-01 13:57   ` Cédric Le Goater
  2025-03-21  9:26 ` [PATCH v1 07/22] hw/misc/aspeed_hace: Add support for source, digest, key buffer 64 bit addresses Jamin Lin via
                   ` (17 subsequent siblings)
  23 siblings, 1 reply; 71+ messages in thread
From: Jamin Lin via @ 2025-03-21  9:26 UTC (permalink / raw)
  To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
	Andrew Jeffery, Joel Stanley, Fabiano Rosas, Laurent Vivier,
	Paolo Bonzini, open list:ASPEED BMCs,
	open list:All patches CC here
  Cc: jamin_lin, troy_lee

Enable accumulative mode for direct access mode operations. In direct access
mode, only a single source buffer is used, so the "iovec" count is set to 1.
If "acc_mode" is enabled:
1. Accumulate "total_req_len" with the current request length ("plen").
2. Check for padding and determine whether this is the final request.

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

diff --git a/hw/misc/aspeed_hace.c b/hw/misc/aspeed_hace.c
index 8cf3f194a5..d06158dffd 100644
--- a/hw/misc/aspeed_hace.c
+++ b/hw/misc/aspeed_hace.c
@@ -223,8 +223,21 @@ static void do_hash_operation(AspeedHACEState *s, int algo, bool sg_mode,
             return;
         }
         iov[0].iov_base = haddr;
-        iov[0].iov_len = plen;
         i = 1;
+        if (acc_mode) {
+            s->total_req_len += plen;
+
+            if (has_padding(s, &iov[0], plen, &total_msg_len,
+                            &pad_offset)) {
+                /* Padding being present indicates the final request */
+                sg_acc_mode_final_request = true;
+                iov[0].iov_len = pad_offset;
+            } else {
+                iov[0].iov_len = plen;
+            }
+        } else {
+            iov[0].iov_len = plen;
+        }
     }
 
     if (acc_mode) {
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 71+ messages in thread

* [PATCH v1 07/22] hw/misc/aspeed_hace: Add support for source, digest, key buffer 64 bit addresses
  2025-03-21  9:25 [PATCH v1 00/22] Fix incorrect hash results on AST2700 Jamin Lin via
                   ` (5 preceding siblings ...)
  2025-03-21  9:26 ` [PATCH v1 06/22] hw/misc/aspeed_hace: Support accumulative mode for direct access mode Jamin Lin via
@ 2025-03-21  9:26 ` Jamin Lin via
  2025-04-01 16:19   ` Cédric Le Goater
  2025-03-21  9:26 ` [PATCH v1 08/22] hw/misc/aspeed_hace: Support DMA 64 bits dram address Jamin Lin via
                   ` (16 subsequent siblings)
  23 siblings, 1 reply; 71+ messages in thread
From: Jamin Lin via @ 2025-03-21  9:26 UTC (permalink / raw)
  To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
	Andrew Jeffery, Joel Stanley, Fabiano Rosas, Laurent Vivier,
	Paolo Bonzini, open list:ASPEED BMCs,
	open list:All patches CC here
  Cc: jamin_lin, troy_lee

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]. The HMAC key buffer address is also
64-bit, with R_HASH_KEY_BUFF_HI storing bits [63:32] and R_HASH_KEY_BUFF storing
bits [31:0].

The AST2700 supports a maximum DRAM size of 8 GB, with a DRAM addressable range
from 0x0_0000_0000 to 0x1_FFFF_FFFF. Since this range fits within 34 bits, only
bits [33:0] are needed to store the DRAM offset. To optimize address storage,
the high physical address bits [1:0] of the source, digest and key buffer
addresses are stored as dram_offset bits [33:32].

To achieve this, a src_hi_mask with a mask value of 0x3 is introduced, ensuring
that src_addr_hi consists of bits [1:0]. The final src_addr is computed as
(src_addr_hi[1:0] << 32) | src_addr[31:0], representing the DRAM offset within
bits [33:0].

Similarly, a dest_hi_mask with a mask value of 0x3 is introduced to ensure that
dest_addr_hi consists of bits [1:0]. The final dest_addr is calculated as
(dest_addr_hi[1:0] << 32) | dest_addr[31:0], representing the DRAM offset within
bits [33:0].

Additionally, a key_hi_mask with a mask value of 0x3 is introduced to ensure
that key_buf_addr_hi consists of bits [1:0]. The final key_buf_addr is
determined as (key_buf_addr_hi[1:0] << 32) | key_buf_addr[31:0], representing
the DRAM offset within bits [33:0].

This approach eliminates the need to reduce the high part of the DRAM physical
address for DMA operations. Previously, this was calculated as
(high physical address bits [7:0] - 4), since the DRAM start address is
0x4_00000000, making the high part address [7:0] - 4.

Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
---
 include/hw/misc/aspeed_hace.h |  5 ++++-
 hw/misc/aspeed_hace.c         | 29 +++++++++++++++++++++++++++++
 2 files changed, 33 insertions(+), 1 deletion(-)

diff --git a/include/hw/misc/aspeed_hace.h b/include/hw/misc/aspeed_hace.h
index b69a038d35..a4479bd383 100644
--- a/include/hw/misc/aspeed_hace.h
+++ b/include/hw/misc/aspeed_hace.h
@@ -22,7 +22,7 @@
 
 OBJECT_DECLARE_TYPE(AspeedHACEState, AspeedHACEClass, ASPEED_HACE)
 
-#define ASPEED_HACE_NR_REGS (0x64 >> 2)
+#define ASPEED_HACE_NR_REGS (0x9C >> 2)
 #define ASPEED_HACE_MAX_SG  256 /* max number of entries */
 
 struct AspeedHACEState {
@@ -49,6 +49,9 @@ struct AspeedHACEClass {
     uint32_t key_mask;
     uint32_t hash_mask;
     bool raise_crypt_interrupt_workaround;
+    uint32_t src_hi_mask;
+    uint32_t dest_hi_mask;
+    uint32_t key_hi_mask;
 };
 
 #endif /* ASPEED_HACE_H */
diff --git a/hw/misc/aspeed_hace.c b/hw/misc/aspeed_hace.c
index d06158dffd..51c6523fab 100644
--- a/hw/misc/aspeed_hace.c
+++ b/hw/misc/aspeed_hace.c
@@ -30,6 +30,9 @@
 #define R_HASH_DEST     (0x24 / 4)
 #define R_HASH_KEY_BUFF (0x28 / 4)
 #define R_HASH_SRC_LEN  (0x2c / 4)
+#define R_HASH_SRC_HI      (0x90 / 4)
+#define R_HASH_DEST_HI     (0x94 / 4)
+#define R_HASH_KEY_BUFF_HI (0x98 / 4)
 
 #define R_HASH_CMD      (0x30 / 4)
 /* Hash algorithm selection */
@@ -393,6 +396,15 @@ static void aspeed_hace_write(void *opaque, hwaddr addr, uint64_t data,
             }
         }
         break;
+    case R_HASH_SRC_HI:
+        data &= ahc->src_hi_mask;
+        break;
+    case R_HASH_DEST_HI:
+        data &= ahc->dest_hi_mask;
+        break;
+    case R_HASH_KEY_BUFF_HI:
+        data &= ahc->key_hi_mask;
+        break;
     default:
         break;
     }
@@ -566,6 +578,23 @@ static void aspeed_ast2700_hace_class_init(ObjectClass *klass, void *data)
     ahc->key_mask = 0x7FFFFFF8;
     ahc->hash_mask = 0x00147FFF;
 
+    /*
+     * The AST2700 supports a maximum DRAM size of 8 GB, with a DRAM
+     * addressable range from 0x0_0000_0000 to 0x1_FFFF_FFFF. Since this range
+     * fits within 34 bits, only bits [33:0] are needed to store the DRAM
+     * offset. To optimize address storage, the high physical address bits
+     * [1:0] of the source, digest and key buffer addresses are stored as
+     * dram_offset bits [33:32].
+     *
+     * This approach eliminates the need to reduce the high part of the DRAM
+     * physical address for DMA operations. Previously, this was calculated as
+     * (high physical address bits [7:0] - 4), since the DRAM start address is
+     * 0x4_00000000, making the high part address [7:0] - 4.
+     */
+    ahc->src_hi_mask = 0x00000003;
+    ahc->dest_hi_mask = 0x00000003;
+    ahc->key_hi_mask = 0x00000003;
+
     /*
      * Currently, it does not support the CRYPT command. Instead, it only
      * sends an interrupt to notify the firmware that the crypt command
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 71+ messages in thread

* [PATCH v1 08/22] hw/misc/aspeed_hace: Support DMA 64 bits dram address.
  2025-03-21  9:25 [PATCH v1 00/22] Fix incorrect hash results on AST2700 Jamin Lin via
                   ` (6 preceding siblings ...)
  2025-03-21  9:26 ` [PATCH v1 07/22] hw/misc/aspeed_hace: Add support for source, digest, key buffer 64 bit addresses Jamin Lin via
@ 2025-03-21  9:26 ` Jamin Lin via
  2025-04-02  7:41   ` Cédric Le Goater
  2025-03-21  9:26 ` [PATCH v1 09/22] hw/misc/aspeed_hace: Ensure HASH_IRQ is always set to prevent firmware hang Jamin Lin via
                   ` (15 subsequent siblings)
  23 siblings, 1 reply; 71+ messages in thread
From: Jamin Lin via @ 2025-03-21  9:26 UTC (permalink / raw)
  To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
	Andrew Jeffery, Joel Stanley, Fabiano Rosas, Laurent Vivier,
	Paolo Bonzini, open list:ASPEED BMCs,
	open list:All patches CC here
  Cc: jamin_lin, troy_lee

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;
```

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. 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.

Introduce a has_dma64 class attribute and set it to true for the AST2700.

Signed-off-by: Jamin Lin <jamin_lin@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]);
+            }
             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;
+             *
+             * 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.
+             */
 
             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 = {
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 71+ messages in thread

* [PATCH v1 09/22] hw/misc/aspeed_hace: Ensure HASH_IRQ is always set to prevent firmware hang
  2025-03-21  9:25 [PATCH v1 00/22] Fix incorrect hash results on AST2700 Jamin Lin via
                   ` (7 preceding siblings ...)
  2025-03-21  9:26 ` [PATCH v1 08/22] hw/misc/aspeed_hace: Support DMA 64 bits dram address Jamin Lin via
@ 2025-03-21  9:26 ` Jamin Lin via
  2025-04-02  9:35   ` Cédric Le Goater
  2025-03-21  9:26 ` [PATCH v1 10/22] hw/misc/aspeed_hace:: Support setting different memory size Jamin Lin via
                   ` (14 subsequent siblings)
  23 siblings, 1 reply; 71+ messages in thread
From: Jamin Lin via @ 2025-03-21  9:26 UTC (permalink / raw)
  To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
	Andrew Jeffery, Joel Stanley, Fabiano Rosas, Laurent Vivier,
	Paolo Bonzini, open list:ASPEED BMCs,
	open list:All patches CC here
  Cc: jamin_lin, troy_lee

Currently, if the program encounters an unsupported algorithm, it does not set
the HASH_IRQ bit in the status register and send an interrupt to indicate
command completion. As a result, the FW gets stuck waiting for a completion
signal from the HACE module.

Additionally, in do_hash_operation, if an error occurs within the conditional
statement, the HASH_IRQ bit is not set in the status register. This causes the
firmware to continuously send HASH commands, as it is unaware that the HACE
model has completed processing the command.

To fix this, the HASH_IRQ bit in the status register must always be set to
ensure that the firmware receives an interrupt from the HACE module, preventing
it from getting stuck or repeatedly sending HASH commands.

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

diff --git a/hw/misc/aspeed_hace.c b/hw/misc/aspeed_hace.c
index 8f333fc97e..d4f653670e 100644
--- a/hw/misc/aspeed_hace.c
+++ b/hw/misc/aspeed_hace.c
@@ -311,12 +311,6 @@ static void do_hash_operation(AspeedHACEState *s, int algo, bool sg_mode,
                             iov[i - 1].iov_len, false,
                             iov[i - 1].iov_len);
     }
-
-    /*
-     * Set status bits to indicate completion. Testing shows hardware sets
-     * these irrespective of HASH_IRQ_EN.
-     */
-    s->regs[R_STATUS] |= HASH_IRQ;
 }
 
 static uint64_t aspeed_hace_read(void *opaque, hwaddr addr, unsigned int size)
@@ -400,10 +394,16 @@ static void aspeed_hace_write(void *opaque, hwaddr addr, uint64_t data,
                 qemu_log_mask(LOG_GUEST_ERROR,
                         "%s: Invalid hash algorithm selection 0x%"PRIx64"\n",
                         __func__, data & ahc->hash_mask);
-                break;
+        } else {
+            do_hash_operation(s, algo, data & HASH_SG_EN,
+                    ((data & HASH_HMAC_MASK) == HASH_DIGEST_ACCUM));
         }
-        do_hash_operation(s, algo, data & HASH_SG_EN,
-                ((data & HASH_HMAC_MASK) == HASH_DIGEST_ACCUM));
+
+        /*
+         * Set status bits to indicate completion. Testing shows hardware sets
+         * these irrespective of HASH_IRQ_EN.
+         */
+        s->regs[R_STATUS] |= HASH_IRQ;
 
         if (data & HASH_IRQ_EN) {
             qemu_irq_raise(s->irq);
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 71+ messages in thread

* [PATCH v1 10/22] hw/misc/aspeed_hace:: Support setting different memory size
  2025-03-21  9:25 [PATCH v1 00/22] Fix incorrect hash results on AST2700 Jamin Lin via
                   ` (8 preceding siblings ...)
  2025-03-21  9:26 ` [PATCH v1 09/22] hw/misc/aspeed_hace: Ensure HASH_IRQ is always set to prevent firmware hang Jamin Lin via
@ 2025-03-21  9:26 ` Jamin Lin via
  2025-04-02  7:46   ` Cédric Le Goater
  2025-03-21  9:26 ` [PATCH v1 11/22] hw/misc/aspeed_hace: Add trace-events for better debugging Jamin Lin via
                   ` (13 subsequent siblings)
  23 siblings, 1 reply; 71+ messages in thread
From: Jamin Lin via @ 2025-03-21  9:26 UTC (permalink / raw)
  To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
	Andrew Jeffery, Joel Stanley, Fabiano Rosas, Laurent Vivier,
	Paolo Bonzini, open list:ASPEED BMCs,
	open list:All patches CC here
  Cc: jamin_lin, troy_lee

The memory size was previously hardcoded to 0x1000 (4K). However, the actual
memory size of the HACE controller varies across different models:
1. AST2400/AST2500: 0x1000 (4K)
2. AST2600/AST1030: 0x10000 (64K)
3. AST2700: 0x100 (256 bytes)

To address this, a new class attribute, mem_size, has been introduced to
dynamically set the appropriate memory size for each HACE model, ensuring
correct allocation across AST2400, AST2500, AST2600, AST1030 and AST2700.

Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
---
 include/hw/misc/aspeed_hace.h | 1 +
 hw/misc/aspeed_hace.c         | 8 +++++++-
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/include/hw/misc/aspeed_hace.h b/include/hw/misc/aspeed_hace.h
index 58fb66009a..db95f2fd4b 100644
--- a/include/hw/misc/aspeed_hace.h
+++ b/include/hw/misc/aspeed_hace.h
@@ -53,6 +53,7 @@ struct AspeedHACEClass {
     uint32_t dest_hi_mask;
     uint32_t key_hi_mask;
     bool has_dma64;
+    uint64_t mem_size;
 };
 
 #endif /* ASPEED_HACE_H */
diff --git a/hw/misc/aspeed_hace.c b/hw/misc/aspeed_hace.c
index d4f653670e..53b3b390e3 100644
--- a/hw/misc/aspeed_hace.c
+++ b/hw/misc/aspeed_hace.c
@@ -463,11 +463,12 @@ static void aspeed_hace_realize(DeviceState *dev, Error **errp)
 {
     AspeedHACEState *s = ASPEED_HACE(dev);
     SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
+    AspeedHACEClass *ahc = ASPEED_HACE_GET_CLASS(s);
 
     sysbus_init_irq(sbd, &s->irq);
 
     memory_region_init_io(&s->iomem, OBJECT(s), &aspeed_hace_ops, s,
-            TYPE_ASPEED_HACE, 0x1000);
+            TYPE_ASPEED_HACE, ahc->mem_size);
 
     if (!s->dram_mr) {
         error_setg(errp, TYPE_ASPEED_HACE ": 'dram' link not set");
@@ -521,6 +522,7 @@ static void aspeed_ast2400_hace_class_init(ObjectClass *klass, void *data)
 
     dc->desc = "AST2400 Hash and Crypto Engine";
 
+    ahc->mem_size = 0x1000;
     ahc->src_mask = 0x0FFFFFFF;
     ahc->dest_mask = 0x0FFFFFF8;
     ahc->key_mask = 0x0FFFFFC0;
@@ -540,6 +542,7 @@ static void aspeed_ast2500_hace_class_init(ObjectClass *klass, void *data)
 
     dc->desc = "AST2500 Hash and Crypto Engine";
 
+    ahc->mem_size = 0x1000;
     ahc->src_mask = 0x3fffffff;
     ahc->dest_mask = 0x3ffffff8;
     ahc->key_mask = 0x3FFFFFC0;
@@ -559,6 +562,7 @@ static void aspeed_ast2600_hace_class_init(ObjectClass *klass, void *data)
 
     dc->desc = "AST2600 Hash and Crypto Engine";
 
+    ahc->mem_size = 0x10000;
     ahc->src_mask = 0x7FFFFFFF;
     ahc->dest_mask = 0x7FFFFFF8;
     ahc->key_mask = 0x7FFFFFF8;
@@ -578,6 +582,7 @@ static void aspeed_ast1030_hace_class_init(ObjectClass *klass, void *data)
 
     dc->desc = "AST1030 Hash and Crypto Engine";
 
+    ahc->mem_size = 0x10000;
     ahc->src_mask = 0x7FFFFFFF;
     ahc->dest_mask = 0x7FFFFFF8;
     ahc->key_mask = 0x7FFFFFF8;
@@ -597,6 +602,7 @@ static void aspeed_ast2700_hace_class_init(ObjectClass *klass, void *data)
 
     dc->desc = "AST2700 Hash and Crypto Engine";
 
+    ahc->mem_size = 0x100;
     ahc->src_mask = 0x7FFFFFFF;
     ahc->dest_mask = 0x7FFFFFF8;
     ahc->key_mask = 0x7FFFFFF8;
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 71+ messages in thread

* [PATCH v1 11/22] hw/misc/aspeed_hace: Add trace-events for better debugging
  2025-03-21  9:25 [PATCH v1 00/22] Fix incorrect hash results on AST2700 Jamin Lin via
                   ` (9 preceding siblings ...)
  2025-03-21  9:26 ` [PATCH v1 10/22] hw/misc/aspeed_hace:: Support setting different memory size Jamin Lin via
@ 2025-03-21  9:26 ` Jamin Lin via
  2025-04-02  7:59   ` Cédric Le Goater
  2025-03-21  9:26 ` [PATCH v1 12/22] hw/misc/aspeed_hace Support to dump plaintext and digest " Jamin Lin via
                   ` (12 subsequent siblings)
  23 siblings, 1 reply; 71+ messages in thread
From: Jamin Lin via @ 2025-03-21  9:26 UTC (permalink / raw)
  To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
	Andrew Jeffery, Joel Stanley, Fabiano Rosas, Laurent Vivier,
	Paolo Bonzini, open list:ASPEED BMCs,
	open list:All patches CC here
  Cc: jamin_lin, troy_lee

Introduced "trace_aspeed_hace_addr", "trace_aspeed_hace_sg",
"trace_aspeed_hace_read", and "trace_aspeed_hace_write" trace events.

Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
---
 hw/misc/aspeed_hace.c | 8 ++++++++
 hw/misc/trace-events  | 6 ++++++
 2 files changed, 14 insertions(+)

diff --git a/hw/misc/aspeed_hace.c b/hw/misc/aspeed_hace.c
index 53b3b390e3..b8e473ee3f 100644
--- a/hw/misc/aspeed_hace.c
+++ b/hw/misc/aspeed_hace.c
@@ -18,6 +18,7 @@
 #include "crypto/hash.h"
 #include "hw/qdev-properties.h"
 #include "hw/irq.h"
+#include "trace.h"
 
 #define R_CRYPT_CMD     (0x10 / 4)
 
@@ -186,6 +187,7 @@ static void do_hash_operation(AspeedHACEState *s, int algo, bool sg_mode,
             if (ahc->has_dma64) {
                 src = deposit64(src, 32, 32, s->regs[R_HASH_SRC_HI]);
             }
+            trace_aspeed_hace_addr("src", src);
             src += i * SG_LIST_ENTRY_SIZE;
 
             len = address_space_ldl_le(&s->dram_as, src,
@@ -194,6 +196,7 @@ 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;
+            trace_aspeed_hace_sg(i, sg_addr, len);
             /*
              * Ideally, sg_addr should be 64-bit for the AST2700, using the
              * following program to obtain the 64-bit sg_addr and convert it
@@ -237,6 +240,7 @@ 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]);
+        trace_aspeed_hace_addr("src", src);
         if (ahc->has_dma64) {
             src = deposit64(src, 32, 32, s->regs[R_HASH_SRC_HI]);
         }
@@ -299,6 +303,7 @@ static void do_hash_operation(AspeedHACEState *s, int algo, bool sg_mode,
     if (ahc->has_dma64) {
         digest_addr = deposit64(digest_addr, 32, 32, s->regs[R_HASH_DEST_HI]);
     }
+    trace_aspeed_hace_addr("digest", digest_addr);
     if (address_space_write(&s->dram_as, digest_addr,
                             MEMTXATTRS_UNSPECIFIED,
                             digest_buf, digest_len)) {
@@ -326,6 +331,7 @@ static uint64_t aspeed_hace_read(void *opaque, hwaddr addr, unsigned int size)
         return 0;
     }
 
+    trace_aspeed_hace_read(addr << 2, s->regs[addr]);
     return s->regs[addr];
 }
 
@@ -344,6 +350,8 @@ static void aspeed_hace_write(void *opaque, hwaddr addr, uint64_t data,
         return;
     }
 
+    trace_aspeed_hace_write(addr << 2, data);
+
     switch (addr) {
     case R_STATUS:
         if (data & HASH_IRQ) {
diff --git a/hw/misc/trace-events b/hw/misc/trace-events
index 4383808d7a..cf96e68cfa 100644
--- a/hw/misc/trace-events
+++ b/hw/misc/trace-events
@@ -302,6 +302,12 @@ aspeed_peci_read(uint64_t offset, uint64_t data) "offset 0x%" PRIx64 " data 0x%"
 aspeed_peci_write(uint64_t offset, uint64_t data) "offset 0x%" PRIx64 " data 0x%" PRIx64
 aspeed_peci_raise_interrupt(uint32_t ctrl, uint32_t status) "ctrl 0x%" PRIx32 " status 0x%" PRIx32
 
+# aspeed_hace.c
+aspeed_hace_read(uint64_t offset, uint64_t data) "offset 0x%" PRIx64 " data 0x%" PRIx64
+aspeed_hace_write(uint64_t offset, uint64_t data) "offset 0x%" PRIx64 " data 0x%" PRIx64
+aspeed_hace_sg(int index, uint64_t addr, uint32_t len) "%d: addr 0x%" PRIx64 " len 0x%" PRIx32
+aspeed_hace_addr(const char *s, uint64_t addr) "%s: 0x%" PRIx64
+
 # bcm2835_property.c
 bcm2835_mbox_property(uint32_t tag, uint32_t bufsize, size_t resplen) "mbox property tag:0x%08x in_sz:%u out_sz:%zu"
 
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 71+ messages in thread

* [PATCH v1 12/22] hw/misc/aspeed_hace Support to dump plaintext and digest for better debugging
  2025-03-21  9:25 [PATCH v1 00/22] Fix incorrect hash results on AST2700 Jamin Lin via
                   ` (10 preceding siblings ...)
  2025-03-21  9:26 ` [PATCH v1 11/22] hw/misc/aspeed_hace: Add trace-events for better debugging Jamin Lin via
@ 2025-03-21  9:26 ` Jamin Lin via
  2025-04-02  8:05   ` Cédric Le Goater
  2025-03-21  9:26 ` [PATCH v1 13/22] test/qtest: Introduce a new aspeed-hace-utils.c to place common testcases Jamin Lin via
                   ` (11 subsequent siblings)
  23 siblings, 1 reply; 71+ messages in thread
From: Jamin Lin via @ 2025-03-21  9:26 UTC (permalink / raw)
  To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
	Andrew Jeffery, Joel Stanley, Fabiano Rosas, Laurent Vivier,
	Paolo Bonzini, open list:ASPEED BMCs,
	open list:All patches CC here
  Cc: jamin_lin, troy_lee

1. Disabled by default. Uncomment "#define DEBUG_HACE 1" to enable it.
2. Uses the "qemu_hexdump" API to dump the digest result.
3. Uses the "iov_hexdump" API to dump the source vector, which contains the
   source plaintext.

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

diff --git a/hw/misc/aspeed_hace.c b/hw/misc/aspeed_hace.c
index b8e473ee3f..ae4d2fa687 100644
--- a/hw/misc/aspeed_hace.c
+++ b/hw/misc/aspeed_hace.c
@@ -10,8 +10,10 @@
  */
 
 #include "qemu/osdep.h"
+#include "qemu/cutils.h"
 #include "qemu/log.h"
 #include "qemu/error-report.h"
+#include "qemu/iov.h"
 #include "hw/misc/aspeed_hace.h"
 #include "qapi/error.h"
 #include "migration/vmstate.h"
@@ -20,6 +22,8 @@
 #include "hw/irq.h"
 #include "trace.h"
 
+/* #define DEBUG_HACE 1 */
+
 #define R_CRYPT_CMD     (0x10 / 4)
 
 #define R_STATUS        (0x1c / 4)
@@ -268,6 +272,10 @@ static void do_hash_operation(AspeedHACEState *s, int algo, bool sg_mode,
         }
     }
 
+#ifdef DEBUG_HACE
+    iov_hexdump(iov, i, stdout, "plaintext", 0xa000);
+#endif
+
     if (acc_mode) {
         if (qcrypto_hash_updatev(s->hash_ctx, iov, i, &local_err) < 0) {
             qemu_log_mask(LOG_GUEST_ERROR, "qcrypto hash update failed : %s",
@@ -311,6 +319,10 @@ static void do_hash_operation(AspeedHACEState *s, int algo, bool sg_mode,
                       "aspeed_hace: address space write failed\n");
     }
 
+#ifdef DEBUG_HACE
+    qemu_hexdump(stdout, "digest", digest_buf, digest_len);
+#endif
+
     for (; i > 0; i--) {
         address_space_unmap(&s->dram_as, iov[i - 1].iov_base,
                             iov[i - 1].iov_len, false,
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 71+ messages in thread

* [PATCH v1 13/22] test/qtest: Introduce a new aspeed-hace-utils.c to place common testcases
  2025-03-21  9:25 [PATCH v1 00/22] Fix incorrect hash results on AST2700 Jamin Lin via
                   ` (11 preceding siblings ...)
  2025-03-21  9:26 ` [PATCH v1 12/22] hw/misc/aspeed_hace Support to dump plaintext and digest " Jamin Lin via
@ 2025-03-21  9:26 ` Jamin Lin via
  2025-04-02  8:54   ` Cédric Le Goater
  2025-03-21  9:26 ` [PATCH v1 14/22] test/qtest/hace: Adjust test address range for AST1030 due to SRAM limitations Jamin Lin via
                   ` (10 subsequent siblings)
  23 siblings, 1 reply; 71+ messages in thread
From: Jamin Lin via @ 2025-03-21  9:26 UTC (permalink / raw)
  To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
	Andrew Jeffery, Joel Stanley, Fabiano Rosas, Laurent Vivier,
	Paolo Bonzini, open list:ASPEED BMCs,
	open list:All patches CC here
  Cc: jamin_lin, troy_lee

The test cases for the ASPEED HACE model were originally placed in
aspeed_hace-test.c. However, this test file only supports ARM32. To enable
compatibility with all ASPEED SoCs, including the AST2700, which uses the
AArch64 architecture, this update introduces a new source file,
aspeed-hace-utils.c.

All common APIs and test cases have been moved from aspeed_hace-test.c to
aspeed-hace-utils.c to facilitate reuse across different ASPEED SoCs.
As a result, these test cases can now be reused for AST2700 and future ASPEED
SoC testing.

Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
---
 tests/qtest/aspeed-hace-utils.h |  71 +++++
 tests/qtest/aspeed-hace-utils.c | 455 ++++++++++++++++++++++++++++
 tests/qtest/aspeed_hace-test.c  | 515 ++------------------------------
 tests/qtest/meson.build         |   1 +
 4 files changed, 547 insertions(+), 495 deletions(-)
 create mode 100644 tests/qtest/aspeed-hace-utils.h
 create mode 100644 tests/qtest/aspeed-hace-utils.c

diff --git a/tests/qtest/aspeed-hace-utils.h b/tests/qtest/aspeed-hace-utils.h
new file mode 100644
index 0000000000..598577c69b
--- /dev/null
+++ b/tests/qtest/aspeed-hace-utils.h
@@ -0,0 +1,71 @@
+/*
+ * QTest testcase for the ASPEED Hash and Crypto Engine
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright 2021 IBM Corp.
+ */
+
+#ifndef TESTS_ASPEED_HACE_UTILS_H
+#define TESTS_ASPEED_HACE_UTILS_H
+
+#include "qemu/osdep.h"
+#include "libqtest.h"
+#include "qemu/bitops.h"
+
+#define HACE_CMD                 0x10
+#define  HACE_SHA_BE_EN          BIT(3)
+#define  HACE_MD5_LE_EN          BIT(2)
+#define  HACE_ALGO_MD5           0
+#define  HACE_ALGO_SHA1          BIT(5)
+#define  HACE_ALGO_SHA224        BIT(6)
+#define  HACE_ALGO_SHA256        (BIT(4) | BIT(6))
+#define  HACE_ALGO_SHA512        (BIT(5) | BIT(6))
+#define  HACE_ALGO_SHA384        (BIT(5) | BIT(6) | BIT(10))
+#define  HACE_SG_EN              BIT(18)
+#define  HACE_ACCUM_EN           BIT(8)
+
+#define HACE_STS                 0x1c
+#define  HACE_RSA_ISR            BIT(13)
+#define  HACE_CRYPTO_ISR         BIT(12)
+#define  HACE_HASH_ISR           BIT(9)
+#define  HACE_RSA_BUSY           BIT(2)
+#define  HACE_CRYPTO_BUSY        BIT(1)
+#define  HACE_HASH_BUSY          BIT(0)
+#define HACE_HASH_SRC            0x20
+#define HACE_HASH_DIGEST         0x24
+#define HACE_HASH_KEY_BUFF       0x28
+#define HACE_HASH_DATA_LEN       0x2c
+#define HACE_HASH_CMD            0x30
+
+/* Scatter-Gather Hash */
+#define SG_LIST_LEN_LAST         BIT(31)
+struct AspeedSgList {
+        uint32_t len;
+        uint32_t addr;
+} __attribute__ ((__packed__));
+
+struct AspeedMasks {
+    uint32_t src;
+    uint32_t dest;
+    uint32_t len;
+};
+
+void aspeed_test_md5(const char *machine, const uint32_t base,
+                     const uint32_t src_addr);
+void aspeed_test_sha256(const char *machine, const uint32_t base,
+                        const uint32_t src_addr);
+void aspeed_test_sha512(const char *machine, const uint32_t base,
+                        const uint32_t src_addr);
+void aspeed_test_sha256_sg(const char *machine, const uint32_t base,
+                           const uint32_t src_addr);
+void aspeed_test_sha512_sg(const char *machine, const uint32_t base,
+                           const uint32_t src_addr);
+void aspeed_test_sha256_accum(const char *machine, const uint32_t base,
+                              const uint32_t src_addr);
+void aspeed_test_sha512_accum(const char *machine, const uint32_t base,
+                              const uint32_t src_addr);
+void aspeed_test_addresses(const char *machine, const uint32_t base,
+                           const struct AspeedMasks *expected);
+
+#endif /* TESTS_ASPEED_HACE_UTILS_H */
+
diff --git a/tests/qtest/aspeed-hace-utils.c b/tests/qtest/aspeed-hace-utils.c
new file mode 100644
index 0000000000..8582847945
--- /dev/null
+++ b/tests/qtest/aspeed-hace-utils.c
@@ -0,0 +1,455 @@
+/*
+ * QTest testcase for the ASPEED Hash and Crypto Engine
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright 2021 IBM Corp.
+ */
+
+#include "qemu/osdep.h"
+#include "libqtest.h"
+#include "qemu/bitops.h"
+#include "aspeed-hace-utils.h"
+
+/*
+ * Test vector is the ascii "abc"
+ *
+ * Expected results were generated using command line utitiles:
+ *
+ *  echo -n -e 'abc' | dd of=/tmp/test
+ *  for hash in sha512sum sha256sum md5sum; do $hash /tmp/test; done
+ *
+ */
+static const uint8_t test_vector[] = {0x61, 0x62, 0x63};
+
+static const uint8_t test_result_sha512[] = {
+    0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba, 0xcc, 0x41, 0x73, 0x49,
+    0xae, 0x20, 0x41, 0x31, 0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2,
+    0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a, 0x21, 0x92, 0x99, 0x2a,
+    0x27, 0x4f, 0xc1, 0xa8, 0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd,
+    0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e, 0x2a, 0x9a, 0xc9, 0x4f,
+    0xa5, 0x4c, 0xa4, 0x9f};
+
+static const uint8_t test_result_sha256[] = {
+    0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, 0xde,
+    0x5d, 0xae, 0x22, 0x23, 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
+    0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad};
+
+static const uint8_t test_result_md5[] = {
+    0x90, 0x01, 0x50, 0x98, 0x3c, 0xd2, 0x4f, 0xb0, 0xd6, 0x96, 0x3f, 0x7d,
+    0x28, 0xe1, 0x7f, 0x72};
+
+/*
+ * The Scatter-Gather Test vector is the ascii "abc" "def" "ghi", broken
+ * into blocks of 3 characters as shown
+ *
+ * Expected results were generated using command line utitiles:
+ *
+ *  echo -n -e 'abcdefghijkl' | dd of=/tmp/test
+ *  for hash in sha512sum sha256sum; do $hash /tmp/test; done
+ *
+ */
+static const uint8_t test_vector_sg1[] = {0x61, 0x62, 0x63, 0x64, 0x65, 0x66};
+static const uint8_t test_vector_sg2[] = {0x67, 0x68, 0x69};
+static const uint8_t test_vector_sg3[] = {0x6a, 0x6b, 0x6c};
+
+static const uint8_t test_result_sg_sha512[] = {
+    0x17, 0x80, 0x7c, 0x72, 0x8e, 0xe3, 0xba, 0x35, 0xe7, 0xcf, 0x7a, 0xf8,
+    0x23, 0x11, 0x6d, 0x26, 0xe4, 0x1e, 0x5d, 0x4d, 0x6c, 0x2f, 0xf1, 0xf3,
+    0x72, 0x0d, 0x3d, 0x96, 0xaa, 0xcb, 0x6f, 0x69, 0xde, 0x64, 0x2e, 0x63,
+    0xd5, 0xb7, 0x3f, 0xc3, 0x96, 0xc1, 0x2b, 0xe3, 0x8b, 0x2b, 0xd5, 0xd8,
+    0x84, 0x25, 0x7c, 0x32, 0xc8, 0xf6, 0xd0, 0x85, 0x4a, 0xe6, 0xb5, 0x40,
+    0xf8, 0x6d, 0xda, 0x2e};
+
+static const uint8_t test_result_sg_sha256[] = {
+    0xd6, 0x82, 0xed, 0x4c, 0xa4, 0xd9, 0x89, 0xc1, 0x34, 0xec, 0x94, 0xf1,
+    0x55, 0x1e, 0x1e, 0xc5, 0x80, 0xdd, 0x6d, 0x5a, 0x6e, 0xcd, 0xe9, 0xf3,
+    0xd3, 0x5e, 0x6e, 0x4a, 0x71, 0x7f, 0xbd, 0xe4};
+
+/*
+ * The accumulative mode requires firmware to provide internal initial state
+ * and message padding (including length L at the end of padding).
+ *
+ * This test vector is a ascii text "abc" with padding message.
+ *
+ * Expected results were generated using command line utitiles:
+ *
+ *  echo -n -e 'abc' | dd of=/tmp/test
+ *  for hash in sha512sum sha256sum; do $hash /tmp/test; done
+ */
+static const uint8_t test_vector_accum_512[] = {
+    0x61, 0x62, 0x63, 0x80, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18};
+
+static const uint8_t test_vector_accum_256[] = {
+    0x61, 0x62, 0x63, 0x80, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18};
+
+static const uint8_t test_result_accum_sha512[] = {
+    0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba, 0xcc, 0x41, 0x73, 0x49,
+    0xae, 0x20, 0x41, 0x31, 0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2,
+    0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a, 0x21, 0x92, 0x99, 0x2a,
+    0x27, 0x4f, 0xc1, 0xa8, 0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd,
+    0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e, 0x2a, 0x9a, 0xc9, 0x4f,
+    0xa5, 0x4c, 0xa4, 0x9f};
+
+static const uint8_t test_result_accum_sha256[] = {
+    0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, 0xde,
+    0x5d, 0xae, 0x22, 0x23, 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
+    0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad};
+
+static void write_regs(QTestState *s, uint32_t base, uint32_t src,
+                       uint32_t length, uint32_t out, uint32_t method)
+{
+        qtest_writel(s, base + HACE_HASH_SRC, src);
+        qtest_writel(s, base + HACE_HASH_DIGEST, out);
+        qtest_writel(s, base + HACE_HASH_DATA_LEN, length);
+        qtest_writel(s, base + HACE_HASH_CMD, HACE_SHA_BE_EN | method);
+}
+
+void aspeed_test_md5(const char *machine, const uint32_t base,
+                     const uint32_t src_addr)
+
+{
+    QTestState *s = qtest_init(machine);
+
+    uint32_t digest_addr = src_addr + 0x01000000;
+    uint8_t digest[16] = {0};
+
+    /* Check engine is idle, no busy or irq bits set */
+    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
+
+    /* Write test vector into memory */
+    qtest_memwrite(s, src_addr, test_vector, sizeof(test_vector));
+
+    write_regs(s, base, src_addr, sizeof(test_vector),
+               digest_addr, HACE_ALGO_MD5);
+
+    /* Check hash IRQ status is asserted */
+    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
+
+    /* Clear IRQ status and check status is deasserted */
+    qtest_writel(s, base + HACE_STS, 0x00000200);
+    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
+
+    /* Read computed digest from memory */
+    qtest_memread(s, digest_addr, digest, sizeof(digest));
+
+    /* Check result of computation */
+    g_assert_cmpmem(digest, sizeof(digest),
+                    test_result_md5, sizeof(digest));
+
+    qtest_quit(s);
+}
+
+void aspeed_test_sha256(const char *machine, const uint32_t base,
+                        const uint32_t src_addr)
+{
+    QTestState *s = qtest_init(machine);
+
+    const uint32_t digest_addr = src_addr + 0x1000000;
+    uint8_t digest[32] = {0};
+
+    /* Check engine is idle, no busy or irq bits set */
+    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
+
+    /* Write test vector into memory */
+    qtest_memwrite(s, src_addr, test_vector, sizeof(test_vector));
+
+    write_regs(s, base, src_addr, sizeof(test_vector), digest_addr,
+               HACE_ALGO_SHA256);
+
+    /* Check hash IRQ status is asserted */
+    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
+
+    /* Clear IRQ status and check status is deasserted */
+    qtest_writel(s, base + HACE_STS, 0x00000200);
+    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
+
+    /* Read computed digest from memory */
+    qtest_memread(s, digest_addr, digest, sizeof(digest));
+
+    /* Check result of computation */
+    g_assert_cmpmem(digest, sizeof(digest),
+                    test_result_sha256, sizeof(digest));
+
+    qtest_quit(s);
+}
+
+void aspeed_test_sha512(const char *machine, const uint32_t base,
+                        const uint32_t src_addr)
+{
+    QTestState *s = qtest_init(machine);
+
+    const uint32_t digest_addr = src_addr + 0x1000000;
+    uint8_t digest[64] = {0};
+
+    /* Check engine is idle, no busy or irq bits set */
+    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
+
+    /* Write test vector into memory */
+    qtest_memwrite(s, src_addr, test_vector, sizeof(test_vector));
+
+    write_regs(s, base, src_addr, sizeof(test_vector), digest_addr,
+               HACE_ALGO_SHA512);
+
+    /* Check hash IRQ status is asserted */
+    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
+
+    /* Clear IRQ status and check status is deasserted */
+    qtest_writel(s, base + HACE_STS, 0x00000200);
+    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
+
+    /* Read computed digest from memory */
+    qtest_memread(s, digest_addr, digest, sizeof(digest));
+
+    /* Check result of computation */
+    g_assert_cmpmem(digest, sizeof(digest),
+                    test_result_sha512, sizeof(digest));
+
+    qtest_quit(s);
+}
+
+void aspeed_test_sha256_sg(const char *machine, const uint32_t base,
+                           const uint32_t src_addr)
+{
+    QTestState *s = qtest_init(machine);
+
+    const uint32_t src_addr_1 = src_addr + 0x1000000;
+    const uint32_t src_addr_2 = src_addr + 0x2000000;
+    const uint32_t src_addr_3 = src_addr + 0x3000000;
+    const uint32_t digest_addr = src_addr + 0x4000000;
+    uint8_t digest[32] = {0};
+    struct AspeedSgList array[] = {
+        {  cpu_to_le32(sizeof(test_vector_sg1)),
+           cpu_to_le32(src_addr_1) },
+        {  cpu_to_le32(sizeof(test_vector_sg2)),
+           cpu_to_le32(src_addr_2) },
+        {  cpu_to_le32(sizeof(test_vector_sg3) | SG_LIST_LEN_LAST),
+           cpu_to_le32(src_addr_3) },
+    };
+
+    /* Check engine is idle, no busy or irq bits set */
+    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
+
+    /* Write test vector into memory */
+    qtest_memwrite(s, src_addr_1, test_vector_sg1, sizeof(test_vector_sg1));
+    qtest_memwrite(s, src_addr_2, test_vector_sg2, sizeof(test_vector_sg2));
+    qtest_memwrite(s, src_addr_3, test_vector_sg3, sizeof(test_vector_sg3));
+    qtest_memwrite(s, src_addr, array, sizeof(array));
+
+    write_regs(s, base, src_addr,
+               (sizeof(test_vector_sg1)
+                + sizeof(test_vector_sg2)
+                + sizeof(test_vector_sg3)),
+               digest_addr, HACE_ALGO_SHA256 | HACE_SG_EN);
+
+    /* Check hash IRQ status is asserted */
+    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
+
+    /* Clear IRQ status and check status is deasserted */
+    qtest_writel(s, base + HACE_STS, 0x00000200);
+    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
+
+    /* Read computed digest from memory */
+    qtest_memread(s, digest_addr, digest, sizeof(digest));
+
+    /* Check result of computation */
+    g_assert_cmpmem(digest, sizeof(digest),
+                    test_result_sg_sha256, sizeof(digest));
+
+    qtest_quit(s);
+}
+
+void aspeed_test_sha512_sg(const char *machine, const uint32_t base,
+                           const uint32_t src_addr)
+{
+    QTestState *s = qtest_init(machine);
+
+    const uint32_t src_addr_1 = src_addr + 0x1000000;
+    const uint32_t src_addr_2 = src_addr + 0x2000000;
+    const uint32_t src_addr_3 = src_addr + 0x3000000;
+    const uint32_t digest_addr = src_addr + 0x4000000;
+    uint8_t digest[64] = {0};
+    struct AspeedSgList array[] = {
+        {  cpu_to_le32(sizeof(test_vector_sg1)),
+           cpu_to_le32(src_addr_1) },
+        {  cpu_to_le32(sizeof(test_vector_sg2)),
+           cpu_to_le32(src_addr_2) },
+        {  cpu_to_le32(sizeof(test_vector_sg3) | SG_LIST_LEN_LAST),
+           cpu_to_le32(src_addr_3) },
+    };
+
+    /* Check engine is idle, no busy or irq bits set */
+    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
+
+    /* Write test vector into memory */
+    qtest_memwrite(s, src_addr_1, test_vector_sg1, sizeof(test_vector_sg1));
+    qtest_memwrite(s, src_addr_2, test_vector_sg2, sizeof(test_vector_sg2));
+    qtest_memwrite(s, src_addr_3, test_vector_sg3, sizeof(test_vector_sg3));
+    qtest_memwrite(s, src_addr, array, sizeof(array));
+
+    write_regs(s, base, src_addr,
+               (sizeof(test_vector_sg1)
+                + sizeof(test_vector_sg2)
+                + sizeof(test_vector_sg3)),
+               digest_addr, HACE_ALGO_SHA512 | HACE_SG_EN);
+
+    /* Check hash IRQ status is asserted */
+    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
+
+    /* Clear IRQ status and check status is deasserted */
+    qtest_writel(s, base + HACE_STS, 0x00000200);
+    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
+
+    /* Read computed digest from memory */
+    qtest_memread(s, digest_addr, digest, sizeof(digest));
+
+    /* Check result of computation */
+    g_assert_cmpmem(digest, sizeof(digest),
+                    test_result_sg_sha512, sizeof(digest));
+
+    qtest_quit(s);
+}
+
+void aspeed_test_sha256_accum(const char *machine, const uint32_t base,
+                              const uint32_t src_addr)
+{
+    QTestState *s = qtest_init(machine);
+
+    const uint32_t buffer_addr = src_addr + 0x1000000;
+    const uint32_t digest_addr = src_addr + 0x4000000;
+    uint8_t digest[32] = {0};
+    struct AspeedSgList array[] = {
+        {  cpu_to_le32(sizeof(test_vector_accum_256) | SG_LIST_LEN_LAST),
+           cpu_to_le32(buffer_addr) },
+    };
+
+    /* Check engine is idle, no busy or irq bits set */
+    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
+
+    /* Write test vector into memory */
+    qtest_memwrite(s, buffer_addr, test_vector_accum_256,
+                   sizeof(test_vector_accum_256));
+    qtest_memwrite(s, src_addr, array, sizeof(array));
+
+    write_regs(s, base, src_addr, sizeof(test_vector_accum_256),
+               digest_addr, HACE_ALGO_SHA256 | HACE_SG_EN | HACE_ACCUM_EN);
+
+    /* Check hash IRQ status is asserted */
+    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
+
+    /* Clear IRQ status and check status is deasserted */
+    qtest_writel(s, base + HACE_STS, 0x00000200);
+    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
+
+    /* Read computed digest from memory */
+    qtest_memread(s, digest_addr, digest, sizeof(digest));
+
+    /* Check result of computation */
+    g_assert_cmpmem(digest, sizeof(digest),
+                    test_result_accum_sha256, sizeof(digest));
+
+    qtest_quit(s);
+}
+
+void aspeed_test_sha512_accum(const char *machine, const uint32_t base,
+                              const uint32_t src_addr)
+{
+    QTestState *s = qtest_init(machine);
+
+    const uint32_t buffer_addr = src_addr + 0x1000000;
+    const uint32_t digest_addr = src_addr + 0x4000000;
+    uint8_t digest[64] = {0};
+    struct AspeedSgList array[] = {
+        {  cpu_to_le32(sizeof(test_vector_accum_512) | SG_LIST_LEN_LAST),
+           cpu_to_le32(buffer_addr) },
+    };
+
+    /* Check engine is idle, no busy or irq bits set */
+    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
+
+    /* Write test vector into memory */
+    qtest_memwrite(s, buffer_addr, test_vector_accum_512,
+                   sizeof(test_vector_accum_512));
+    qtest_memwrite(s, src_addr, array, sizeof(array));
+
+    write_regs(s, base, src_addr, sizeof(test_vector_accum_512),
+               digest_addr, HACE_ALGO_SHA512 | HACE_SG_EN | HACE_ACCUM_EN);
+
+    /* Check hash IRQ status is asserted */
+    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
+
+    /* Clear IRQ status and check status is deasserted */
+    qtest_writel(s, base + HACE_STS, 0x00000200);
+    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
+
+    /* Read computed digest from memory */
+    qtest_memread(s, digest_addr, digest, sizeof(digest));
+
+    /* Check result of computation */
+    g_assert_cmpmem(digest, sizeof(digest),
+                    test_result_accum_sha512, sizeof(digest));
+
+    qtest_quit(s);
+}
+
+void aspeed_test_addresses(const char *machine, const uint32_t base,
+                           const struct AspeedMasks *expected)
+{
+    QTestState *s = qtest_init(machine);
+
+    /*
+     * Check command mode is zero, meaning engine is in direct access mode,
+     * as this affects the masking behavior of the HASH_SRC register.
+     */
+    g_assert_cmphex(qtest_readl(s, base + HACE_CMD), ==, 0);
+    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_SRC), ==, 0);
+    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DIGEST), ==, 0);
+    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DATA_LEN), ==, 0);
+
+
+    /* Check that the address masking is correct */
+    qtest_writel(s, base + HACE_HASH_SRC, 0xffffffff);
+    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_SRC), ==, expected->src);
+
+    qtest_writel(s, base + HACE_HASH_DIGEST, 0xffffffff);
+    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DIGEST), ==,
+                    expected->dest);
+
+    qtest_writel(s, base + HACE_HASH_DATA_LEN, 0xffffffff);
+    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DATA_LEN), ==,
+                    expected->len);
+
+    /* Reset to zero */
+    qtest_writel(s, base + HACE_HASH_SRC, 0);
+    qtest_writel(s, base + HACE_HASH_DIGEST, 0);
+    qtest_writel(s, base + HACE_HASH_DATA_LEN, 0);
+
+    /* Check that all bits are now zero */
+    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_SRC), ==, 0);
+    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DIGEST), ==, 0);
+    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DATA_LEN), ==, 0);
+
+    qtest_quit(s);
+}
+
diff --git a/tests/qtest/aspeed_hace-test.c b/tests/qtest/aspeed_hace-test.c
index ce86a44672..42a306af2a 100644
--- a/tests/qtest/aspeed_hace-test.c
+++ b/tests/qtest/aspeed_hace-test.c
@@ -6,584 +6,109 @@
  */
 
 #include "qemu/osdep.h"
-
 #include "libqtest.h"
 #include "qemu/bitops.h"
+#include "aspeed-hace-utils.h"
 
-#define HACE_CMD                 0x10
-#define  HACE_SHA_BE_EN          BIT(3)
-#define  HACE_MD5_LE_EN          BIT(2)
-#define  HACE_ALGO_MD5           0
-#define  HACE_ALGO_SHA1          BIT(5)
-#define  HACE_ALGO_SHA224        BIT(6)
-#define  HACE_ALGO_SHA256        (BIT(4) | BIT(6))
-#define  HACE_ALGO_SHA512        (BIT(5) | BIT(6))
-#define  HACE_ALGO_SHA384        (BIT(5) | BIT(6) | BIT(10))
-#define  HACE_SG_EN              BIT(18)
-#define  HACE_ACCUM_EN           BIT(8)
-
-#define HACE_STS                 0x1c
-#define  HACE_RSA_ISR            BIT(13)
-#define  HACE_CRYPTO_ISR         BIT(12)
-#define  HACE_HASH_ISR           BIT(9)
-#define  HACE_RSA_BUSY           BIT(2)
-#define  HACE_CRYPTO_BUSY        BIT(1)
-#define  HACE_HASH_BUSY          BIT(0)
-#define HACE_HASH_SRC            0x20
-#define HACE_HASH_DIGEST         0x24
-#define HACE_HASH_KEY_BUFF       0x28
-#define HACE_HASH_DATA_LEN       0x2c
-#define HACE_HASH_CMD            0x30
-/* Scatter-Gather Hash */
-#define SG_LIST_LEN_LAST         BIT(31)
-struct AspeedSgList {
-        uint32_t len;
-        uint32_t addr;
-} __attribute__ ((__packed__));
-
-/*
- * Test vector is the ascii "abc"
- *
- * Expected results were generated using command line utitiles:
- *
- *  echo -n -e 'abc' | dd of=/tmp/test
- *  for hash in sha512sum sha256sum md5sum; do $hash /tmp/test; done
- *
- */
-static const uint8_t test_vector[] = {0x61, 0x62, 0x63};
-
-static const uint8_t test_result_sha512[] = {
-    0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba, 0xcc, 0x41, 0x73, 0x49,
-    0xae, 0x20, 0x41, 0x31, 0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2,
-    0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a, 0x21, 0x92, 0x99, 0x2a,
-    0x27, 0x4f, 0xc1, 0xa8, 0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd,
-    0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e, 0x2a, 0x9a, 0xc9, 0x4f,
-    0xa5, 0x4c, 0xa4, 0x9f};
-
-static const uint8_t test_result_sha256[] = {
-    0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, 0xde,
-    0x5d, 0xae, 0x22, 0x23, 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
-    0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad};
-
-static const uint8_t test_result_md5[] = {
-    0x90, 0x01, 0x50, 0x98, 0x3c, 0xd2, 0x4f, 0xb0, 0xd6, 0x96, 0x3f, 0x7d,
-    0x28, 0xe1, 0x7f, 0x72};
-
-/*
- * The Scatter-Gather Test vector is the ascii "abc" "def" "ghi", broken
- * into blocks of 3 characters as shown
- *
- * Expected results were generated using command line utitiles:
- *
- *  echo -n -e 'abcdefghijkl' | dd of=/tmp/test
- *  for hash in sha512sum sha256sum; do $hash /tmp/test; done
- *
- */
-static const uint8_t test_vector_sg1[] = {0x61, 0x62, 0x63, 0x64, 0x65, 0x66};
-static const uint8_t test_vector_sg2[] = {0x67, 0x68, 0x69};
-static const uint8_t test_vector_sg3[] = {0x6a, 0x6b, 0x6c};
-
-static const uint8_t test_result_sg_sha512[] = {
-    0x17, 0x80, 0x7c, 0x72, 0x8e, 0xe3, 0xba, 0x35, 0xe7, 0xcf, 0x7a, 0xf8,
-    0x23, 0x11, 0x6d, 0x26, 0xe4, 0x1e, 0x5d, 0x4d, 0x6c, 0x2f, 0xf1, 0xf3,
-    0x72, 0x0d, 0x3d, 0x96, 0xaa, 0xcb, 0x6f, 0x69, 0xde, 0x64, 0x2e, 0x63,
-    0xd5, 0xb7, 0x3f, 0xc3, 0x96, 0xc1, 0x2b, 0xe3, 0x8b, 0x2b, 0xd5, 0xd8,
-    0x84, 0x25, 0x7c, 0x32, 0xc8, 0xf6, 0xd0, 0x85, 0x4a, 0xe6, 0xb5, 0x40,
-    0xf8, 0x6d, 0xda, 0x2e};
-
-static const uint8_t test_result_sg_sha256[] = {
-    0xd6, 0x82, 0xed, 0x4c, 0xa4, 0xd9, 0x89, 0xc1, 0x34, 0xec, 0x94, 0xf1,
-    0x55, 0x1e, 0x1e, 0xc5, 0x80, 0xdd, 0x6d, 0x5a, 0x6e, 0xcd, 0xe9, 0xf3,
-    0xd3, 0x5e, 0x6e, 0x4a, 0x71, 0x7f, 0xbd, 0xe4};
-
-/*
- * The accumulative mode requires firmware to provide internal initial state
- * and message padding (including length L at the end of padding).
- *
- * This test vector is a ascii text "abc" with padding message.
- *
- * Expected results were generated using command line utitiles:
- *
- *  echo -n -e 'abc' | dd of=/tmp/test
- *  for hash in sha512sum sha256sum; do $hash /tmp/test; done
- */
-static const uint8_t test_vector_accum_512[] = {
-    0x61, 0x62, 0x63, 0x80, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18};
-
-static const uint8_t test_vector_accum_256[] = {
-    0x61, 0x62, 0x63, 0x80, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18};
-
-static const uint8_t test_result_accum_sha512[] = {
-    0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba, 0xcc, 0x41, 0x73, 0x49,
-    0xae, 0x20, 0x41, 0x31, 0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2,
-    0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a, 0x21, 0x92, 0x99, 0x2a,
-    0x27, 0x4f, 0xc1, 0xa8, 0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd,
-    0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e, 0x2a, 0x9a, 0xc9, 0x4f,
-    0xa5, 0x4c, 0xa4, 0x9f};
-
-static const uint8_t test_result_accum_sha256[] = {
-    0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, 0xde,
-    0x5d, 0xae, 0x22, 0x23, 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
-    0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad};
-
-static void write_regs(QTestState *s, uint32_t base, uint32_t src,
-                       uint32_t length, uint32_t out, uint32_t method)
-{
-        qtest_writel(s, base + HACE_HASH_SRC, src);
-        qtest_writel(s, base + HACE_HASH_DIGEST, out);
-        qtest_writel(s, base + HACE_HASH_DATA_LEN, length);
-        qtest_writel(s, base + HACE_HASH_CMD, HACE_SHA_BE_EN | method);
-}
-
-static void test_md5(const char *machine, const uint32_t base,
-                     const uint32_t src_addr)
-
-{
-    QTestState *s = qtest_init(machine);
-
-    uint32_t digest_addr = src_addr + 0x01000000;
-    uint8_t digest[16] = {0};
-
-    /* Check engine is idle, no busy or irq bits set */
-    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
-
-    /* Write test vector into memory */
-    qtest_memwrite(s, src_addr, test_vector, sizeof(test_vector));
-
-    write_regs(s, base, src_addr, sizeof(test_vector), digest_addr, HACE_ALGO_MD5);
-
-    /* Check hash IRQ status is asserted */
-    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
-
-    /* Clear IRQ status and check status is deasserted */
-    qtest_writel(s, base + HACE_STS, 0x00000200);
-    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
-
-    /* Read computed digest from memory */
-    qtest_memread(s, digest_addr, digest, sizeof(digest));
-
-    /* Check result of computation */
-    g_assert_cmpmem(digest, sizeof(digest),
-                    test_result_md5, sizeof(digest));
-
-    qtest_quit(s);
-}
-
-static void test_sha256(const char *machine, const uint32_t base,
-                        const uint32_t src_addr)
-{
-    QTestState *s = qtest_init(machine);
-
-    const uint32_t digest_addr = src_addr + 0x1000000;
-    uint8_t digest[32] = {0};
-
-    /* Check engine is idle, no busy or irq bits set */
-    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
-
-    /* Write test vector into memory */
-    qtest_memwrite(s, src_addr, test_vector, sizeof(test_vector));
-
-    write_regs(s, base, src_addr, sizeof(test_vector), digest_addr, HACE_ALGO_SHA256);
-
-    /* Check hash IRQ status is asserted */
-    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
-
-    /* Clear IRQ status and check status is deasserted */
-    qtest_writel(s, base + HACE_STS, 0x00000200);
-    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
-
-    /* Read computed digest from memory */
-    qtest_memread(s, digest_addr, digest, sizeof(digest));
-
-    /* Check result of computation */
-    g_assert_cmpmem(digest, sizeof(digest),
-                    test_result_sha256, sizeof(digest));
-
-    qtest_quit(s);
-}
-
-static void test_sha512(const char *machine, const uint32_t base,
-                        const uint32_t src_addr)
-{
-    QTestState *s = qtest_init(machine);
-
-    const uint32_t digest_addr = src_addr + 0x1000000;
-    uint8_t digest[64] = {0};
-
-    /* Check engine is idle, no busy or irq bits set */
-    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
-
-    /* Write test vector into memory */
-    qtest_memwrite(s, src_addr, test_vector, sizeof(test_vector));
-
-    write_regs(s, base, src_addr, sizeof(test_vector), digest_addr, HACE_ALGO_SHA512);
-
-    /* Check hash IRQ status is asserted */
-    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
-
-    /* Clear IRQ status and check status is deasserted */
-    qtest_writel(s, base + HACE_STS, 0x00000200);
-    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
-
-    /* Read computed digest from memory */
-    qtest_memread(s, digest_addr, digest, sizeof(digest));
-
-    /* Check result of computation */
-    g_assert_cmpmem(digest, sizeof(digest),
-                    test_result_sha512, sizeof(digest));
-
-    qtest_quit(s);
-}
-
-static void test_sha256_sg(const char *machine, const uint32_t base,
-                        const uint32_t src_addr)
-{
-    QTestState *s = qtest_init(machine);
-
-    const uint32_t src_addr_1 = src_addr + 0x1000000;
-    const uint32_t src_addr_2 = src_addr + 0x2000000;
-    const uint32_t src_addr_3 = src_addr + 0x3000000;
-    const uint32_t digest_addr = src_addr + 0x4000000;
-    uint8_t digest[32] = {0};
-    struct AspeedSgList array[] = {
-        {  cpu_to_le32(sizeof(test_vector_sg1)),
-           cpu_to_le32(src_addr_1) },
-        {  cpu_to_le32(sizeof(test_vector_sg2)),
-           cpu_to_le32(src_addr_2) },
-        {  cpu_to_le32(sizeof(test_vector_sg3) | SG_LIST_LEN_LAST),
-           cpu_to_le32(src_addr_3) },
-    };
-
-    /* Check engine is idle, no busy or irq bits set */
-    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
-
-    /* Write test vector into memory */
-    qtest_memwrite(s, src_addr_1, test_vector_sg1, sizeof(test_vector_sg1));
-    qtest_memwrite(s, src_addr_2, test_vector_sg2, sizeof(test_vector_sg2));
-    qtest_memwrite(s, src_addr_3, test_vector_sg3, sizeof(test_vector_sg3));
-    qtest_memwrite(s, src_addr, array, sizeof(array));
-
-    write_regs(s, base, src_addr,
-               (sizeof(test_vector_sg1)
-                + sizeof(test_vector_sg2)
-                + sizeof(test_vector_sg3)),
-               digest_addr, HACE_ALGO_SHA256 | HACE_SG_EN);
-
-    /* Check hash IRQ status is asserted */
-    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
-
-    /* Clear IRQ status and check status is deasserted */
-    qtest_writel(s, base + HACE_STS, 0x00000200);
-    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
-
-    /* Read computed digest from memory */
-    qtest_memread(s, digest_addr, digest, sizeof(digest));
-
-    /* Check result of computation */
-    g_assert_cmpmem(digest, sizeof(digest),
-                    test_result_sg_sha256, sizeof(digest));
-
-    qtest_quit(s);
-}
-
-static void test_sha512_sg(const char *machine, const uint32_t base,
-                        const uint32_t src_addr)
-{
-    QTestState *s = qtest_init(machine);
-
-    const uint32_t src_addr_1 = src_addr + 0x1000000;
-    const uint32_t src_addr_2 = src_addr + 0x2000000;
-    const uint32_t src_addr_3 = src_addr + 0x3000000;
-    const uint32_t digest_addr = src_addr + 0x4000000;
-    uint8_t digest[64] = {0};
-    struct AspeedSgList array[] = {
-        {  cpu_to_le32(sizeof(test_vector_sg1)),
-           cpu_to_le32(src_addr_1) },
-        {  cpu_to_le32(sizeof(test_vector_sg2)),
-           cpu_to_le32(src_addr_2) },
-        {  cpu_to_le32(sizeof(test_vector_sg3) | SG_LIST_LEN_LAST),
-           cpu_to_le32(src_addr_3) },
-    };
-
-    /* Check engine is idle, no busy or irq bits set */
-    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
-
-    /* Write test vector into memory */
-    qtest_memwrite(s, src_addr_1, test_vector_sg1, sizeof(test_vector_sg1));
-    qtest_memwrite(s, src_addr_2, test_vector_sg2, sizeof(test_vector_sg2));
-    qtest_memwrite(s, src_addr_3, test_vector_sg3, sizeof(test_vector_sg3));
-    qtest_memwrite(s, src_addr, array, sizeof(array));
-
-    write_regs(s, base, src_addr,
-               (sizeof(test_vector_sg1)
-                + sizeof(test_vector_sg2)
-                + sizeof(test_vector_sg3)),
-               digest_addr, HACE_ALGO_SHA512 | HACE_SG_EN);
-
-    /* Check hash IRQ status is asserted */
-    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
-
-    /* Clear IRQ status and check status is deasserted */
-    qtest_writel(s, base + HACE_STS, 0x00000200);
-    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
-
-    /* Read computed digest from memory */
-    qtest_memread(s, digest_addr, digest, sizeof(digest));
-
-    /* Check result of computation */
-    g_assert_cmpmem(digest, sizeof(digest),
-                    test_result_sg_sha512, sizeof(digest));
-
-    qtest_quit(s);
-}
-
-static void test_sha256_accum(const char *machine, const uint32_t base,
-                        const uint32_t src_addr)
-{
-    QTestState *s = qtest_init(machine);
-
-    const uint32_t buffer_addr = src_addr + 0x1000000;
-    const uint32_t digest_addr = src_addr + 0x4000000;
-    uint8_t digest[32] = {0};
-    struct AspeedSgList array[] = {
-        {  cpu_to_le32(sizeof(test_vector_accum_256) | SG_LIST_LEN_LAST),
-           cpu_to_le32(buffer_addr) },
-    };
-
-    /* Check engine is idle, no busy or irq bits set */
-    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
-
-    /* Write test vector into memory */
-    qtest_memwrite(s, buffer_addr, test_vector_accum_256,
-                   sizeof(test_vector_accum_256));
-    qtest_memwrite(s, src_addr, array, sizeof(array));
-
-    write_regs(s, base, src_addr, sizeof(test_vector_accum_256),
-               digest_addr, HACE_ALGO_SHA256 | HACE_SG_EN | HACE_ACCUM_EN);
-
-    /* Check hash IRQ status is asserted */
-    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
-
-    /* Clear IRQ status and check status is deasserted */
-    qtest_writel(s, base + HACE_STS, 0x00000200);
-    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
-
-    /* Read computed digest from memory */
-    qtest_memread(s, digest_addr, digest, sizeof(digest));
-
-    /* Check result of computation */
-    g_assert_cmpmem(digest, sizeof(digest),
-                    test_result_accum_sha256, sizeof(digest));
-
-    qtest_quit(s);
-}
-
-static void test_sha512_accum(const char *machine, const uint32_t base,
-                        const uint32_t src_addr)
-{
-    QTestState *s = qtest_init(machine);
-
-    const uint32_t buffer_addr = src_addr + 0x1000000;
-    const uint32_t digest_addr = src_addr + 0x4000000;
-    uint8_t digest[64] = {0};
-    struct AspeedSgList array[] = {
-        {  cpu_to_le32(sizeof(test_vector_accum_512) | SG_LIST_LEN_LAST),
-           cpu_to_le32(buffer_addr) },
-    };
-
-    /* Check engine is idle, no busy or irq bits set */
-    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
-
-    /* Write test vector into memory */
-    qtest_memwrite(s, buffer_addr, test_vector_accum_512,
-                   sizeof(test_vector_accum_512));
-    qtest_memwrite(s, src_addr, array, sizeof(array));
-
-    write_regs(s, base, src_addr, sizeof(test_vector_accum_512),
-               digest_addr, HACE_ALGO_SHA512 | HACE_SG_EN | HACE_ACCUM_EN);
-
-    /* Check hash IRQ status is asserted */
-    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
-
-    /* Clear IRQ status and check status is deasserted */
-    qtest_writel(s, base + HACE_STS, 0x00000200);
-    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
-
-    /* Read computed digest from memory */
-    qtest_memread(s, digest_addr, digest, sizeof(digest));
-
-    /* Check result of computation */
-    g_assert_cmpmem(digest, sizeof(digest),
-                    test_result_accum_sha512, sizeof(digest));
-
-    qtest_quit(s);
-}
-
-struct masks {
-    uint32_t src;
-    uint32_t dest;
-    uint32_t len;
-};
-
-static const struct masks ast2600_masks = {
+static const struct AspeedMasks ast2600_masks = {
     .src  = 0x7fffffff,
     .dest = 0x7ffffff8,
     .len  = 0x0fffffff,
 };
 
-static const struct masks ast2500_masks = {
+static const struct AspeedMasks ast2500_masks = {
     .src  = 0x3fffffff,
     .dest = 0x3ffffff8,
     .len  = 0x0fffffff,
 };
 
-static const struct masks ast2400_masks = {
+static const struct AspeedMasks ast2400_masks = {
     .src  = 0x0fffffff,
     .dest = 0x0ffffff8,
     .len  = 0x0fffffff,
 };
 
-static void test_addresses(const char *machine, const uint32_t base,
-                           const struct masks *expected)
-{
-    QTestState *s = qtest_init(machine);
-
-    /*
-     * Check command mode is zero, meaning engine is in direct access mode,
-     * as this affects the masking behavior of the HASH_SRC register.
-     */
-    g_assert_cmphex(qtest_readl(s, base + HACE_CMD), ==, 0);
-    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_SRC), ==, 0);
-    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DIGEST), ==, 0);
-    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DATA_LEN), ==, 0);
-
-
-    /* Check that the address masking is correct */
-    qtest_writel(s, base + HACE_HASH_SRC, 0xffffffff);
-    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_SRC), ==, expected->src);
-
-    qtest_writel(s, base + HACE_HASH_DIGEST, 0xffffffff);
-    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DIGEST), ==, expected->dest);
-
-    qtest_writel(s, base + HACE_HASH_DATA_LEN, 0xffffffff);
-    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DATA_LEN), ==, expected->len);
-
-    /* Reset to zero */
-    qtest_writel(s, base + HACE_HASH_SRC, 0);
-    qtest_writel(s, base + HACE_HASH_DIGEST, 0);
-    qtest_writel(s, base + HACE_HASH_DATA_LEN, 0);
-
-    /* Check that all bits are now zero */
-    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_SRC), ==, 0);
-    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DIGEST), ==, 0);
-    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DATA_LEN), ==, 0);
-
-    qtest_quit(s);
-}
-
 /* ast2600 */
 static void test_md5_ast2600(void)
 {
-    test_md5("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
+    aspeed_test_md5("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
 }
 
 static void test_sha256_ast2600(void)
 {
-    test_sha256("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
+    aspeed_test_sha256("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
 }
 
 static void test_sha256_sg_ast2600(void)
 {
-    test_sha256_sg("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
+    aspeed_test_sha256_sg("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
 }
 
 static void test_sha512_ast2600(void)
 {
-    test_sha512("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
+    aspeed_test_sha512("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
 }
 
 static void test_sha512_sg_ast2600(void)
 {
-    test_sha512_sg("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
+    aspeed_test_sha512_sg("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
 }
 
 static void test_sha256_accum_ast2600(void)
 {
-    test_sha256_accum("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
+    aspeed_test_sha256_accum("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
 }
 
 static void test_sha512_accum_ast2600(void)
 {
-    test_sha512_accum("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
+    aspeed_test_sha512_accum("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
 }
 
 static void test_addresses_ast2600(void)
 {
-    test_addresses("-machine ast2600-evb", 0x1e6d0000, &ast2600_masks);
+    aspeed_test_addresses("-machine ast2600-evb", 0x1e6d0000, &ast2600_masks);
 }
 
 /* ast2500 */
 static void test_md5_ast2500(void)
 {
-    test_md5("-machine ast2500-evb", 0x1e6e3000, 0x80000000);
+    aspeed_test_md5("-machine ast2500-evb", 0x1e6e3000, 0x80000000);
 }
 
 static void test_sha256_ast2500(void)
 {
-    test_sha256("-machine ast2500-evb", 0x1e6e3000, 0x80000000);
+    aspeed_test_sha256("-machine ast2500-evb", 0x1e6e3000, 0x80000000);
 }
 
 static void test_sha512_ast2500(void)
 {
-    test_sha512("-machine ast2500-evb", 0x1e6e3000, 0x80000000);
+    aspeed_test_sha512("-machine ast2500-evb", 0x1e6e3000, 0x80000000);
 }
 
 static void test_addresses_ast2500(void)
 {
-    test_addresses("-machine ast2500-evb", 0x1e6e3000, &ast2500_masks);
+    aspeed_test_addresses("-machine ast2500-evb", 0x1e6e3000, &ast2500_masks);
 }
 
 /* ast2400 */
 static void test_md5_ast2400(void)
 {
-    test_md5("-machine palmetto-bmc", 0x1e6e3000, 0x40000000);
+    aspeed_test_md5("-machine palmetto-bmc", 0x1e6e3000, 0x40000000);
 }
 
 static void test_sha256_ast2400(void)
 {
-    test_sha256("-machine palmetto-bmc", 0x1e6e3000, 0x40000000);
+    aspeed_test_sha256("-machine palmetto-bmc", 0x1e6e3000, 0x40000000);
 }
 
 static void test_sha512_ast2400(void)
 {
-    test_sha512("-machine palmetto-bmc", 0x1e6e3000, 0x40000000);
+    aspeed_test_sha512("-machine palmetto-bmc", 0x1e6e3000, 0x40000000);
 }
 
 static void test_addresses_ast2400(void)
 {
-    test_addresses("-machine palmetto-bmc", 0x1e6e3000, &ast2400_masks);
+    aspeed_test_addresses("-machine palmetto-bmc", 0x1e6e3000, &ast2400_masks);
 }
 
 int main(int argc, char **argv)
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
index 8a6243382a..62fc8f9868 100644
--- a/tests/qtest/meson.build
+++ b/tests/qtest/meson.build
@@ -383,6 +383,7 @@ qtests = {
   'netdev-socket': files('netdev-socket.c', '../unit/socket-helpers.c'),
   'aspeed_smc-test': files('aspeed-smc-utils.c', 'aspeed_smc-test.c'),
   'ast2700-smc-test': files('aspeed-smc-utils.c', 'ast2700-smc-test.c'),
+  'aspeed_hace-test': files('aspeed-hace-utils.c', 'aspeed_hace-test.c'),
 }
 
 if vnc.found()
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 71+ messages in thread

* [PATCH v1 14/22] test/qtest/hace: Adjust test address range for AST1030 due to SRAM limitations
  2025-03-21  9:25 [PATCH v1 00/22] Fix incorrect hash results on AST2700 Jamin Lin via
                   ` (12 preceding siblings ...)
  2025-03-21  9:26 ` [PATCH v1 13/22] test/qtest: Introduce a new aspeed-hace-utils.c to place common testcases Jamin Lin via
@ 2025-03-21  9:26 ` Jamin Lin via
  2025-04-02  9:43   ` Cédric Le Goater
  2025-03-21  9:26 ` [PATCH v1 15/22] test/qtest/hace: Add SHA-384 test cases for ASPEED HACE model Jamin Lin via
                   ` (9 subsequent siblings)
  23 siblings, 1 reply; 71+ messages in thread
From: Jamin Lin via @ 2025-03-21  9:26 UTC (permalink / raw)
  To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
	Andrew Jeffery, Joel Stanley, Fabiano Rosas, Laurent Vivier,
	Paolo Bonzini, open list:ASPEED BMCs,
	open list:All patches CC here
  Cc: jamin_lin, troy_lee

The digest_addr is set to "src_addr + 0x1000000", where src_addr is the DRAM
base address. However, the value 0x1000000 (16MB) is too large because the
AST1030 does not support DRAM, and its SRAM size is only 768KB.

A range size of 0x1000 (64KB) is sufficient for HACE test cases, as the test
vector size does not exceed 64KB.

Updates:
1. Direct Access Mode
Update digest_addr to "src_addr + 0x1000" in the following functions:
aspeed_test_md5
aspeed_test_sha256
aspeed_test_sha512

2. Scatter-Gather (SG) Mode
Update source address for different SG buffer addresses in the following
functions:
src_addr1 = src_addr + 0x1000
src_addr2 = src_addr + 0x2000
src_addr3 = src_addr + 0x3000
digest_addr = src_addr + 0x4000

aspeed_test_sha256_sg
aspeed_test_sha512_sg

3. ACC Mode Update
Update the SG List start address: src_addr + 0x10000
Update the SG List buffer size to 0x3000 (192KB).

buffer_addr = src_addr + 0x10000
digest_addr = src_addr + 0x40000

Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
---
 tests/qtest/aspeed-hace-utils.c | 30 +++++++++++++++---------------
 1 file changed, 15 insertions(+), 15 deletions(-)

diff --git a/tests/qtest/aspeed-hace-utils.c b/tests/qtest/aspeed-hace-utils.c
index 8582847945..8fbbba49c1 100644
--- a/tests/qtest/aspeed-hace-utils.c
+++ b/tests/qtest/aspeed-hace-utils.c
@@ -132,7 +132,7 @@ void aspeed_test_md5(const char *machine, const uint32_t base,
 {
     QTestState *s = qtest_init(machine);
 
-    uint32_t digest_addr = src_addr + 0x01000000;
+    uint32_t digest_addr = src_addr + 0x010000;
     uint8_t digest[16] = {0};
 
     /* Check engine is idle, no busy or irq bits set */
@@ -166,7 +166,7 @@ void aspeed_test_sha256(const char *machine, const uint32_t base,
 {
     QTestState *s = qtest_init(machine);
 
-    const uint32_t digest_addr = src_addr + 0x1000000;
+    const uint32_t digest_addr = src_addr + 0x10000;
     uint8_t digest[32] = {0};
 
     /* Check engine is idle, no busy or irq bits set */
@@ -200,7 +200,7 @@ void aspeed_test_sha512(const char *machine, const uint32_t base,
 {
     QTestState *s = qtest_init(machine);
 
-    const uint32_t digest_addr = src_addr + 0x1000000;
+    const uint32_t digest_addr = src_addr + 0x10000;
     uint8_t digest[64] = {0};
 
     /* Check engine is idle, no busy or irq bits set */
@@ -234,10 +234,10 @@ void aspeed_test_sha256_sg(const char *machine, const uint32_t base,
 {
     QTestState *s = qtest_init(machine);
 
-    const uint32_t src_addr_1 = src_addr + 0x1000000;
-    const uint32_t src_addr_2 = src_addr + 0x2000000;
-    const uint32_t src_addr_3 = src_addr + 0x3000000;
-    const uint32_t digest_addr = src_addr + 0x4000000;
+    const uint32_t src_addr_1 = src_addr + 0x10000;
+    const uint32_t src_addr_2 = src_addr + 0x20000;
+    const uint32_t src_addr_3 = src_addr + 0x30000;
+    const uint32_t digest_addr = src_addr + 0x40000;
     uint8_t digest[32] = {0};
     struct AspeedSgList array[] = {
         {  cpu_to_le32(sizeof(test_vector_sg1)),
@@ -285,10 +285,10 @@ void aspeed_test_sha512_sg(const char *machine, const uint32_t base,
 {
     QTestState *s = qtest_init(machine);
 
-    const uint32_t src_addr_1 = src_addr + 0x1000000;
-    const uint32_t src_addr_2 = src_addr + 0x2000000;
-    const uint32_t src_addr_3 = src_addr + 0x3000000;
-    const uint32_t digest_addr = src_addr + 0x4000000;
+    const uint32_t src_addr_1 = src_addr + 0x10000;
+    const uint32_t src_addr_2 = src_addr + 0x20000;
+    const uint32_t src_addr_3 = src_addr + 0x30000;
+    const uint32_t digest_addr = src_addr + 0x40000;
     uint8_t digest[64] = {0};
     struct AspeedSgList array[] = {
         {  cpu_to_le32(sizeof(test_vector_sg1)),
@@ -336,8 +336,8 @@ void aspeed_test_sha256_accum(const char *machine, const uint32_t base,
 {
     QTestState *s = qtest_init(machine);
 
-    const uint32_t buffer_addr = src_addr + 0x1000000;
-    const uint32_t digest_addr = src_addr + 0x4000000;
+    const uint32_t buffer_addr = src_addr + 0x10000;
+    const uint32_t digest_addr = src_addr + 0x40000;
     uint8_t digest[32] = {0};
     struct AspeedSgList array[] = {
         {  cpu_to_le32(sizeof(test_vector_accum_256) | SG_LIST_LEN_LAST),
@@ -377,8 +377,8 @@ void aspeed_test_sha512_accum(const char *machine, const uint32_t base,
 {
     QTestState *s = qtest_init(machine);
 
-    const uint32_t buffer_addr = src_addr + 0x1000000;
-    const uint32_t digest_addr = src_addr + 0x4000000;
+    const uint32_t buffer_addr = src_addr + 0x10000;
+    const uint32_t digest_addr = src_addr + 0x40000;
     uint8_t digest[64] = {0};
     struct AspeedSgList array[] = {
         {  cpu_to_le32(sizeof(test_vector_accum_512) | SG_LIST_LEN_LAST),
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 71+ messages in thread

* [PATCH v1 15/22] test/qtest/hace: Add SHA-384 test cases for ASPEED HACE model
  2025-03-21  9:25 [PATCH v1 00/22] Fix incorrect hash results on AST2700 Jamin Lin via
                   ` (13 preceding siblings ...)
  2025-03-21  9:26 ` [PATCH v1 14/22] test/qtest/hace: Adjust test address range for AST1030 due to SRAM limitations Jamin Lin via
@ 2025-03-21  9:26 ` Jamin Lin via
  2025-04-02  9:02   ` Cédric Le Goater
  2025-03-21  9:26 ` [PATCH v1 16/22] test/qtest/hace: Add SHA-384 tests for AST2600 Jamin Lin via
                   ` (8 subsequent siblings)
  23 siblings, 1 reply; 71+ messages in thread
From: Jamin Lin via @ 2025-03-21  9:26 UTC (permalink / raw)
  To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
	Andrew Jeffery, Joel Stanley, Fabiano Rosas, Laurent Vivier,
	Paolo Bonzini, open list:ASPEED BMCs,
	open list:All patches CC here
  Cc: jamin_lin, troy_lee

Introduced SHA-384 test functions to verify hashing operations.
Extended support for scatter-gather (`_sg`) and accumulation (`_accum`) tests.
Updated test result vectors for SHA-384 validation.

Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
---
 tests/qtest/aspeed-hace-utils.h |   6 ++
 tests/qtest/aspeed-hace-utils.c | 168 +++++++++++++++++++++++++++++++-
 2 files changed, 171 insertions(+), 3 deletions(-)

diff --git a/tests/qtest/aspeed-hace-utils.h b/tests/qtest/aspeed-hace-utils.h
index 598577c69b..f4440561de 100644
--- a/tests/qtest/aspeed-hace-utils.h
+++ b/tests/qtest/aspeed-hace-utils.h
@@ -54,14 +54,20 @@ void aspeed_test_md5(const char *machine, const uint32_t base,
                      const uint32_t src_addr);
 void aspeed_test_sha256(const char *machine, const uint32_t base,
                         const uint32_t src_addr);
+void aspeed_test_sha384(const char *machine, const uint32_t base,
+                        const uint32_t src_addr);
 void aspeed_test_sha512(const char *machine, const uint32_t base,
                         const uint32_t src_addr);
 void aspeed_test_sha256_sg(const char *machine, const uint32_t base,
                            const uint32_t src_addr);
+void aspeed_test_sha384_sg(const char *machine, const uint32_t base,
+                           const uint32_t src_addr);
 void aspeed_test_sha512_sg(const char *machine, const uint32_t base,
                            const uint32_t src_addr);
 void aspeed_test_sha256_accum(const char *machine, const uint32_t base,
                               const uint32_t src_addr);
+void aspeed_test_sha384_accum(const char *machine, const uint32_t base,
+                              const uint32_t src_addr);
 void aspeed_test_sha512_accum(const char *machine, const uint32_t base,
                               const uint32_t src_addr);
 void aspeed_test_addresses(const char *machine, const uint32_t base,
diff --git a/tests/qtest/aspeed-hace-utils.c b/tests/qtest/aspeed-hace-utils.c
index 8fbbba49c1..d3146898c2 100644
--- a/tests/qtest/aspeed-hace-utils.c
+++ b/tests/qtest/aspeed-hace-utils.c
@@ -16,7 +16,7 @@
  * Expected results were generated using command line utitiles:
  *
  *  echo -n -e 'abc' | dd of=/tmp/test
- *  for hash in sha512sum sha256sum md5sum; do $hash /tmp/test; done
+ *  for hash in sha512sum sha384sum sha256sum md5sum; do $hash /tmp/test; done
  *
  */
 static const uint8_t test_vector[] = {0x61, 0x62, 0x63};
@@ -29,6 +29,12 @@ static const uint8_t test_result_sha512[] = {
     0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e, 0x2a, 0x9a, 0xc9, 0x4f,
     0xa5, 0x4c, 0xa4, 0x9f};
 
+static const uint8_t test_result_sha384[] = {
+    0xcb, 0x00, 0x75, 0x3f, 0x45, 0xa3, 0x5e, 0x8b, 0xb5, 0xa0, 0x3d, 0x69,
+    0x9a, 0xc6, 0x50, 0x07, 0x27, 0x2c, 0x32, 0xab, 0x0e, 0xde, 0xd1, 0x63,
+    0x1a, 0x8b, 0x60, 0x5a, 0x43, 0xff, 0x5b, 0xed, 0x80, 0x86, 0x07, 0x2b,
+    0xa1, 0xe7, 0xcc, 0x23, 0x58, 0xba, 0xec, 0xa1, 0x34, 0xc8, 0x25, 0xa7};
+
 static const uint8_t test_result_sha256[] = {
     0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, 0xde,
     0x5d, 0xae, 0x22, 0x23, 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
@@ -45,7 +51,7 @@ static const uint8_t test_result_md5[] = {
  * Expected results were generated using command line utitiles:
  *
  *  echo -n -e 'abcdefghijkl' | dd of=/tmp/test
- *  for hash in sha512sum sha256sum; do $hash /tmp/test; done
+ *  for hash in sha512sum sha384sum sha256sum; do $hash /tmp/test; done
  *
  */
 static const uint8_t test_vector_sg1[] = {0x61, 0x62, 0x63, 0x64, 0x65, 0x66};
@@ -60,6 +66,12 @@ static const uint8_t test_result_sg_sha512[] = {
     0x84, 0x25, 0x7c, 0x32, 0xc8, 0xf6, 0xd0, 0x85, 0x4a, 0xe6, 0xb5, 0x40,
     0xf8, 0x6d, 0xda, 0x2e};
 
+static const uint8_t test_result_sg_sha384[] = {
+    0x10, 0x3c, 0xa9, 0x6c, 0x06, 0xa1, 0xce, 0x79, 0x8f, 0x08, 0xf8, 0xef,
+    0xf0, 0xdf, 0xb0, 0xcc, 0xdb, 0x56, 0x7d, 0x48, 0xb2, 0x85, 0xb2, 0x3d,
+    0x0c, 0xd7, 0x73, 0x45, 0x46, 0x67, 0xa3, 0xc2, 0xfa, 0x5f, 0x1b, 0x58,
+    0xd9, 0xcd, 0xf2, 0x32, 0x9b, 0xd9, 0x97, 0x97, 0x30, 0xbf, 0xaa, 0xff};
+
 static const uint8_t test_result_sg_sha256[] = {
     0xd6, 0x82, 0xed, 0x4c, 0xa4, 0xd9, 0x89, 0xc1, 0x34, 0xec, 0x94, 0xf1,
     0x55, 0x1e, 0x1e, 0xc5, 0x80, 0xdd, 0x6d, 0x5a, 0x6e, 0xcd, 0xe9, 0xf3,
@@ -74,7 +86,7 @@ static const uint8_t test_result_sg_sha256[] = {
  * Expected results were generated using command line utitiles:
  *
  *  echo -n -e 'abc' | dd of=/tmp/test
- *  for hash in sha512sum sha256sum; do $hash /tmp/test; done
+ *  for hash in sha512sum sha384sum sha256sum; do $hash /tmp/test; done
  */
 static const uint8_t test_vector_accum_512[] = {
     0x61, 0x62, 0x63, 0x80, 0x00, 0x00, 0x00, 0x00,
@@ -94,6 +106,24 @@ static const uint8_t test_vector_accum_512[] = {
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18};
 
+static const uint8_t test_vector_accum_384[] = {
+    0x61, 0x62, 0x63, 0x80, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18};
+
 static const uint8_t test_vector_accum_256[] = {
     0x61, 0x62, 0x63, 0x80, 0x00, 0x00, 0x00, 0x00,
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -112,6 +142,12 @@ static const uint8_t test_result_accum_sha512[] = {
     0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e, 0x2a, 0x9a, 0xc9, 0x4f,
     0xa5, 0x4c, 0xa4, 0x9f};
 
+static const uint8_t test_result_accum_sha384[] = {
+    0xcb, 0x00, 0x75, 0x3f, 0x45, 0xa3, 0x5e, 0x8b, 0xb5, 0xa0, 0x3d, 0x69,
+    0x9a, 0xc6, 0x50, 0x07, 0x27, 0x2c, 0x32, 0xab, 0x0e, 0xde, 0xd1, 0x63,
+    0x1a, 0x8b, 0x60, 0x5a, 0x43, 0xff, 0x5b, 0xed, 0x80, 0x86, 0x07, 0x2b,
+    0xa1, 0xe7, 0xcc, 0x23, 0x58, 0xba, 0xec, 0xa1, 0x34, 0xc8, 0x25, 0xa7};
+
 static const uint8_t test_result_accum_sha256[] = {
     0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, 0xde,
     0x5d, 0xae, 0x22, 0x23, 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
@@ -195,6 +231,40 @@ void aspeed_test_sha256(const char *machine, const uint32_t base,
     qtest_quit(s);
 }
 
+void aspeed_test_sha384(const char *machine, const uint32_t base,
+                        const uint32_t src_addr)
+{
+    QTestState *s = qtest_init(machine);
+
+    const uint32_t digest_addr = src_addr + 0x10000;
+    uint8_t digest[32] = {0};
+
+    /* Check engine is idle, no busy or irq bits set */
+    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
+
+    /* Write test vector into memory */
+    qtest_memwrite(s, src_addr, test_vector, sizeof(test_vector));
+
+    write_regs(s, base, src_addr, sizeof(test_vector), digest_addr,
+               HACE_ALGO_SHA384);
+
+    /* Check hash IRQ status is asserted */
+    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
+
+    /* Clear IRQ status and check status is deasserted */
+    qtest_writel(s, base + HACE_STS, 0x00000200);
+    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
+
+    /* Read computed digest from memory */
+    qtest_memread(s, digest_addr, digest, sizeof(digest));
+
+    /* Check result of computation */
+    g_assert_cmpmem(digest, sizeof(digest),
+                    test_result_sha384, sizeof(digest));
+
+    qtest_quit(s);
+}
+
 void aspeed_test_sha512(const char *machine, const uint32_t base,
                         const uint32_t src_addr)
 {
@@ -280,6 +350,57 @@ void aspeed_test_sha256_sg(const char *machine, const uint32_t base,
     qtest_quit(s);
 }
 
+void aspeed_test_sha384_sg(const char *machine, const uint32_t base,
+                           const uint32_t src_addr)
+{
+    QTestState *s = qtest_init(machine);
+
+    const uint32_t src_addr_1 = src_addr + 0x10000;
+    const uint32_t src_addr_2 = src_addr + 0x20000;
+    const uint32_t src_addr_3 = src_addr + 0x30000;
+    const uint32_t digest_addr = src_addr + 0x40000;
+    uint8_t digest[64] = {0};
+    struct AspeedSgList array[] = {
+        {  cpu_to_le32(sizeof(test_vector_sg1)),
+           cpu_to_le32(src_addr_1) },
+        {  cpu_to_le32(sizeof(test_vector_sg2)),
+           cpu_to_le32(src_addr_2) },
+        {  cpu_to_le32(sizeof(test_vector_sg3) | SG_LIST_LEN_LAST),
+           cpu_to_le32(src_addr_3) },
+    };
+
+    /* Check engine is idle, no busy or irq bits set */
+    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
+
+    /* Write test vector into memory */
+    qtest_memwrite(s, src_addr_1, test_vector_sg1, sizeof(test_vector_sg1));
+    qtest_memwrite(s, src_addr_2, test_vector_sg2, sizeof(test_vector_sg2));
+    qtest_memwrite(s, src_addr_3, test_vector_sg3, sizeof(test_vector_sg3));
+    qtest_memwrite(s, src_addr, array, sizeof(array));
+
+    write_regs(s, base, src_addr,
+               (sizeof(test_vector_sg1)
+                + sizeof(test_vector_sg2)
+                + sizeof(test_vector_sg3)),
+               digest_addr, HACE_ALGO_SHA384 | HACE_SG_EN);
+
+    /* Check hash IRQ status is asserted */
+    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
+
+    /* Clear IRQ status and check status is deasserted */
+    qtest_writel(s, base + HACE_STS, 0x00000200);
+    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
+
+    /* Read computed digest from memory */
+    qtest_memread(s, digest_addr, digest, sizeof(digest));
+
+    /* Check result of computation */
+    g_assert_cmpmem(digest, sizeof(digest),
+                    test_result_sg_sha384, sizeof(digest));
+
+    qtest_quit(s);
+}
+
 void aspeed_test_sha512_sg(const char *machine, const uint32_t base,
                            const uint32_t src_addr)
 {
@@ -372,6 +493,47 @@ void aspeed_test_sha256_accum(const char *machine, const uint32_t base,
     qtest_quit(s);
 }
 
+void aspeed_test_sha384_accum(const char *machine, const uint32_t base,
+                              const uint32_t src_addr)
+{
+    QTestState *s = qtest_init(machine);
+
+    const uint32_t buffer_addr = src_addr + 0x10000;
+    const uint32_t digest_addr = src_addr + 0x40000;
+    uint8_t digest[64] = {0};
+    struct AspeedSgList array[] = {
+        {  cpu_to_le32(sizeof(test_vector_accum_384) | SG_LIST_LEN_LAST),
+           cpu_to_le32(buffer_addr) },
+    };
+
+    /* Check engine is idle, no busy or irq bits set */
+    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
+
+    /* Write test vector into memory */
+    qtest_memwrite(s, buffer_addr, test_vector_accum_384,
+                   sizeof(test_vector_accum_384));
+    qtest_memwrite(s, src_addr, array, sizeof(array));
+
+    write_regs(s, base, src_addr, sizeof(test_vector_accum_384),
+               digest_addr, HACE_ALGO_SHA384 | HACE_SG_EN | HACE_ACCUM_EN);
+
+    /* Check hash IRQ status is asserted */
+    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
+
+    /* Clear IRQ status and check status is deasserted */
+    qtest_writel(s, base + HACE_STS, 0x00000200);
+    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
+
+    /* Read computed digest from memory */
+    qtest_memread(s, digest_addr, digest, sizeof(digest));
+
+    /* Check result of computation */
+    g_assert_cmpmem(digest, sizeof(digest),
+                    test_result_accum_sha384, sizeof(digest));
+
+    qtest_quit(s);
+}
+
 void aspeed_test_sha512_accum(const char *machine, const uint32_t base,
                               const uint32_t src_addr)
 {
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 71+ messages in thread

* [PATCH v1 16/22] test/qtest/hace: Add SHA-384 tests for AST2600
  2025-03-21  9:25 [PATCH v1 00/22] Fix incorrect hash results on AST2700 Jamin Lin via
                   ` (14 preceding siblings ...)
  2025-03-21  9:26 ` [PATCH v1 15/22] test/qtest/hace: Add SHA-384 test cases for ASPEED HACE model Jamin Lin via
@ 2025-03-21  9:26 ` Jamin Lin via
  2025-04-02  9:02   ` Cédric Le Goater
  2025-03-21  9:26 ` [PATCH v1 17/22] test/qtest/hace: Add tests for AST1030 Jamin Lin via
                   ` (7 subsequent siblings)
  23 siblings, 1 reply; 71+ messages in thread
From: Jamin Lin via @ 2025-03-21  9:26 UTC (permalink / raw)
  To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
	Andrew Jeffery, Joel Stanley, Fabiano Rosas, Laurent Vivier,
	Paolo Bonzini, open list:ASPEED BMCs,
	open list:All patches CC here
  Cc: jamin_lin, troy_lee

Introduced "test_sha384_ast2600" to validate SHA-384 hashing.
Added "test_sha384_sg_ast2600" for scatter-gather SHA-384 verification.
Implemented "test_sha384_accum_ast2600" to test SHA-384 accumulation.
Registered new test cases in "main" to ensure execution.

Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
---
 tests/qtest/aspeed_hace-test.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/tests/qtest/aspeed_hace-test.c b/tests/qtest/aspeed_hace-test.c
index 42a306af2a..ab0c98330e 100644
--- a/tests/qtest/aspeed_hace-test.c
+++ b/tests/qtest/aspeed_hace-test.c
@@ -44,6 +44,16 @@ static void test_sha256_sg_ast2600(void)
     aspeed_test_sha256_sg("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
 }
 
+static void test_sha384_ast2600(void)
+{
+    aspeed_test_sha384("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
+}
+
+static void test_sha384_sg_ast2600(void)
+{
+    aspeed_test_sha384_sg("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
+}
+
 static void test_sha512_ast2600(void)
 {
     aspeed_test_sha512("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
@@ -59,6 +69,11 @@ static void test_sha256_accum_ast2600(void)
     aspeed_test_sha256_accum("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
 }
 
+static void test_sha384_accum_ast2600(void)
+{
+    aspeed_test_sha384_accum("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
+}
+
 static void test_sha512_accum_ast2600(void)
 {
     aspeed_test_sha512_accum("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
@@ -117,13 +132,16 @@ int main(int argc, char **argv)
 
     qtest_add_func("ast2600/hace/addresses", test_addresses_ast2600);
     qtest_add_func("ast2600/hace/sha512", test_sha512_ast2600);
+    qtest_add_func("ast2600/hace/sha384", test_sha384_ast2600);
     qtest_add_func("ast2600/hace/sha256", test_sha256_ast2600);
     qtest_add_func("ast2600/hace/md5", test_md5_ast2600);
 
     qtest_add_func("ast2600/hace/sha512_sg", test_sha512_sg_ast2600);
+    qtest_add_func("ast2600/hace/sha384_sg", test_sha384_sg_ast2600);
     qtest_add_func("ast2600/hace/sha256_sg", test_sha256_sg_ast2600);
 
     qtest_add_func("ast2600/hace/sha512_accum", test_sha512_accum_ast2600);
+    qtest_add_func("ast2600/hace/sha384_accum", test_sha384_accum_ast2600);
     qtest_add_func("ast2600/hace/sha256_accum", test_sha256_accum_ast2600);
 
     qtest_add_func("ast2500/hace/addresses", test_addresses_ast2500);
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 71+ messages in thread

* [PATCH v1 17/22] test/qtest/hace: Add tests for AST1030
  2025-03-21  9:25 [PATCH v1 00/22] Fix incorrect hash results on AST2700 Jamin Lin via
                   ` (15 preceding siblings ...)
  2025-03-21  9:26 ` [PATCH v1 16/22] test/qtest/hace: Add SHA-384 tests for AST2600 Jamin Lin via
@ 2025-03-21  9:26 ` Jamin Lin via
  2025-04-02  9:44   ` Cédric Le Goater
  2025-03-21  9:26 ` [PATCH v1 18/22] test/qtest/hace: Update source data and digest data type to 64-bit Jamin Lin via
                   ` (6 subsequent siblings)
  23 siblings, 1 reply; 71+ messages in thread
From: Jamin Lin via @ 2025-03-21  9:26 UTC (permalink / raw)
  To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
	Andrew Jeffery, Joel Stanley, Fabiano Rosas, Laurent Vivier,
	Paolo Bonzini, open list:ASPEED BMCs,
	open list:All patches CC here
  Cc: jamin_lin, troy_lee

The HACE model in AST2600 and AST1030 is identical. Referencing the AST2600
test cases, new tests have been created for AST1030.

Implemented test functions for SHA-256, SHA-384, SHA-512, and MD5.
Added scatter-gather and accumulation test variants.
For AST1030, the HACE controller base address starts at "0x7e6d0000", and the
SDRAM start address is "0x0".

Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
---
 tests/qtest/aspeed_hace-test.c | 76 ++++++++++++++++++++++++++++++++++
 1 file changed, 76 insertions(+)

diff --git a/tests/qtest/aspeed_hace-test.c b/tests/qtest/aspeed_hace-test.c
index ab0c98330e..31890d574e 100644
--- a/tests/qtest/aspeed_hace-test.c
+++ b/tests/qtest/aspeed_hace-test.c
@@ -10,6 +10,12 @@
 #include "qemu/bitops.h"
 #include "aspeed-hace-utils.h"
 
+static const struct AspeedMasks ast1030_masks = {
+    .src  = 0x7fffffff,
+    .dest = 0x7ffffff8,
+    .len  = 0x0fffffff,
+};
+
 static const struct AspeedMasks ast2600_masks = {
     .src  = 0x7fffffff,
     .dest = 0x7ffffff8,
@@ -28,6 +34,62 @@ static const struct AspeedMasks ast2400_masks = {
     .len  = 0x0fffffff,
 };
 
+/* ast1030 */
+static void test_md5_ast1030(void)
+{
+    aspeed_test_md5("-machine ast1030-evb", 0x7e6d0000, 0x00000000);
+}
+
+static void test_sha256_ast1030(void)
+{
+    aspeed_test_sha256("-machine ast1030-evb", 0x7e6d0000, 0x00000000);
+}
+
+static void test_sha256_sg_ast1030(void)
+{
+    aspeed_test_sha256_sg("-machine ast1030-evb", 0x7e6d0000, 0x00000000);
+}
+
+static void test_sha384_ast1030(void)
+{
+    aspeed_test_sha384("-machine ast1030-evb", 0x7e6d0000, 0x00000000);
+}
+
+static void test_sha384_sg_ast1030(void)
+{
+    aspeed_test_sha384_sg("-machine ast1030-evb", 0x7e6d0000, 0x00000000);
+}
+
+static void test_sha512_ast1030(void)
+{
+    aspeed_test_sha512("-machine ast1030-evb", 0x7e6d0000, 0x00000000);
+}
+
+static void test_sha512_sg_ast1030(void)
+{
+    aspeed_test_sha512_sg("-machine ast1030-evb", 0x7e6d0000, 0x00000000);
+}
+
+static void test_sha256_accum_ast1030(void)
+{
+    aspeed_test_sha256_accum("-machine ast1030-evb", 0x7e6d0000, 0x00000000);
+}
+
+static void test_sha384_accum_ast1030(void)
+{
+    aspeed_test_sha384_accum("-machine ast1030-evb", 0x7e6d0000, 0x00000000);
+}
+
+static void test_sha512_accum_ast1030(void)
+{
+    aspeed_test_sha512_accum("-machine ast1030-evb", 0x7e6d0000, 0x00000000);
+}
+
+static void test_addresses_ast1030(void)
+{
+    aspeed_test_addresses("-machine ast1030-evb", 0x7e6d0000, &ast1030_masks);
+}
+
 /* ast2600 */
 static void test_md5_ast2600(void)
 {
@@ -130,6 +192,20 @@ int main(int argc, char **argv)
 {
     g_test_init(&argc, &argv, NULL);
 
+    qtest_add_func("ast1030/hace/addresses", test_addresses_ast1030);
+    qtest_add_func("ast1030/hace/sha512", test_sha512_ast1030);
+    qtest_add_func("ast1030/hace/sha384", test_sha384_ast1030);
+    qtest_add_func("ast1030/hace/sha256", test_sha256_ast1030);
+    qtest_add_func("ast1030/hace/md5", test_md5_ast1030);
+
+    qtest_add_func("ast1030/hace/sha512_sg", test_sha512_sg_ast1030);
+    qtest_add_func("ast1030/hace/sha384_sg", test_sha384_sg_ast1030);
+    qtest_add_func("ast1030/hace/sha256_sg", test_sha256_sg_ast1030);
+
+    qtest_add_func("ast1030/hace/sha512_accum", test_sha512_accum_ast1030);
+    qtest_add_func("ast1030/hace/sha384_accum", test_sha384_accum_ast1030);
+    qtest_add_func("ast1030/hace/sha256_accum", test_sha256_accum_ast1030);
+
     qtest_add_func("ast2600/hace/addresses", test_addresses_ast2600);
     qtest_add_func("ast2600/hace/sha512", test_sha512_ast2600);
     qtest_add_func("ast2600/hace/sha384", test_sha384_ast2600);
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 71+ messages in thread

* [PATCH v1 18/22] test/qtest/hace: Update source data and digest data type to 64-bit
  2025-03-21  9:25 [PATCH v1 00/22] Fix incorrect hash results on AST2700 Jamin Lin via
                   ` (16 preceding siblings ...)
  2025-03-21  9:26 ` [PATCH v1 17/22] test/qtest/hace: Add tests for AST1030 Jamin Lin via
@ 2025-03-21  9:26 ` Jamin Lin via
  2025-04-02  9:05   ` Cédric Le Goater
  2025-03-21  9:26 ` [PATCH v1 19/22] test/qtest/hace: Support 64-bit source and digest addresses for AST2700 Jamin Lin via
                   ` (5 subsequent siblings)
  23 siblings, 1 reply; 71+ messages in thread
From: Jamin Lin via @ 2025-03-21  9:26 UTC (permalink / raw)
  To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
	Andrew Jeffery, Joel Stanley, Fabiano Rosas, Laurent Vivier,
	Paolo Bonzini, open list:ASPEED BMCs,
	open list:All patches CC here
  Cc: jamin_lin, troy_lee

Currently, the hash data source and digest result buffer addresses are set to
32-bit. However, the AST2700 CPU is a 64-bit Cortex-A35 architecture, and its
DRAM base address is also 64-bit.

To support AST2700, update the hash data source address and digest result buffer
address to use 64-bit addressing.

Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
---
 tests/qtest/aspeed-hace-utils.h | 20 +++----
 tests/qtest/aspeed-hace-utils.c | 96 ++++++++++++++++-----------------
 2 files changed, 58 insertions(+), 58 deletions(-)

diff --git a/tests/qtest/aspeed-hace-utils.h b/tests/qtest/aspeed-hace-utils.h
index f4440561de..0382570fa2 100644
--- a/tests/qtest/aspeed-hace-utils.h
+++ b/tests/qtest/aspeed-hace-utils.h
@@ -51,25 +51,25 @@ struct AspeedMasks {
 };
 
 void aspeed_test_md5(const char *machine, const uint32_t base,
-                     const uint32_t src_addr);
+                     const uint64_t src_addr);
 void aspeed_test_sha256(const char *machine, const uint32_t base,
-                        const uint32_t src_addr);
+                        const uint64_t src_addr);
 void aspeed_test_sha384(const char *machine, const uint32_t base,
-                        const uint32_t src_addr);
+                        const uint64_t src_addr);
 void aspeed_test_sha512(const char *machine, const uint32_t base,
-                        const uint32_t src_addr);
+                        const uint64_t src_addr);
 void aspeed_test_sha256_sg(const char *machine, const uint32_t base,
-                           const uint32_t src_addr);
+                           const uint64_t src_addr);
 void aspeed_test_sha384_sg(const char *machine, const uint32_t base,
-                           const uint32_t src_addr);
+                           const uint64_t src_addr);
 void aspeed_test_sha512_sg(const char *machine, const uint32_t base,
-                           const uint32_t src_addr);
+                           const uint64_t src_addr);
 void aspeed_test_sha256_accum(const char *machine, const uint32_t base,
-                              const uint32_t src_addr);
+                              const uint64_t src_addr);
 void aspeed_test_sha384_accum(const char *machine, const uint32_t base,
-                              const uint32_t src_addr);
+                              const uint64_t src_addr);
 void aspeed_test_sha512_accum(const char *machine, const uint32_t base,
-                              const uint32_t src_addr);
+                              const uint64_t src_addr);
 void aspeed_test_addresses(const char *machine, const uint32_t base,
                            const struct AspeedMasks *expected);
 
diff --git a/tests/qtest/aspeed-hace-utils.c b/tests/qtest/aspeed-hace-utils.c
index d3146898c2..f39bb8ea48 100644
--- a/tests/qtest/aspeed-hace-utils.c
+++ b/tests/qtest/aspeed-hace-utils.c
@@ -153,22 +153,22 @@ static const uint8_t test_result_accum_sha256[] = {
     0x5d, 0xae, 0x22, 0x23, 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
     0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad};
 
-static void write_regs(QTestState *s, uint32_t base, uint32_t src,
-                       uint32_t length, uint32_t out, uint32_t method)
+static void write_regs(QTestState *s, uint32_t base, uint64_t src,
+                       uint32_t length, uint64_t out, uint32_t method)
 {
-        qtest_writel(s, base + HACE_HASH_SRC, src);
-        qtest_writel(s, base + HACE_HASH_DIGEST, out);
+        qtest_writel(s, base + HACE_HASH_SRC, extract64(src, 0, 32));
+        qtest_writel(s, base + HACE_HASH_DIGEST, extract64(out, 0, 32));
         qtest_writel(s, base + HACE_HASH_DATA_LEN, length);
         qtest_writel(s, base + HACE_HASH_CMD, HACE_SHA_BE_EN | method);
 }
 
 void aspeed_test_md5(const char *machine, const uint32_t base,
-                     const uint32_t src_addr)
+                     const uint64_t src_addr)
 
 {
     QTestState *s = qtest_init(machine);
 
-    uint32_t digest_addr = src_addr + 0x010000;
+    uint64_t digest_addr = src_addr + 0x010000;
     uint8_t digest[16] = {0};
 
     /* Check engine is idle, no busy or irq bits set */
@@ -198,11 +198,11 @@ void aspeed_test_md5(const char *machine, const uint32_t base,
 }
 
 void aspeed_test_sha256(const char *machine, const uint32_t base,
-                        const uint32_t src_addr)
+                        const uint64_t src_addr)
 {
     QTestState *s = qtest_init(machine);
 
-    const uint32_t digest_addr = src_addr + 0x10000;
+    const uint64_t digest_addr = src_addr + 0x10000;
     uint8_t digest[32] = {0};
 
     /* Check engine is idle, no busy or irq bits set */
@@ -232,11 +232,11 @@ void aspeed_test_sha256(const char *machine, const uint32_t base,
 }
 
 void aspeed_test_sha384(const char *machine, const uint32_t base,
-                        const uint32_t src_addr)
+                        const uint64_t src_addr)
 {
     QTestState *s = qtest_init(machine);
 
-    const uint32_t digest_addr = src_addr + 0x10000;
+    const uint64_t digest_addr = src_addr + 0x10000;
     uint8_t digest[32] = {0};
 
     /* Check engine is idle, no busy or irq bits set */
@@ -266,11 +266,11 @@ void aspeed_test_sha384(const char *machine, const uint32_t base,
 }
 
 void aspeed_test_sha512(const char *machine, const uint32_t base,
-                        const uint32_t src_addr)
+                        const uint64_t src_addr)
 {
     QTestState *s = qtest_init(machine);
 
-    const uint32_t digest_addr = src_addr + 0x10000;
+    const uint64_t digest_addr = src_addr + 0x10000;
     uint8_t digest[64] = {0};
 
     /* Check engine is idle, no busy or irq bits set */
@@ -300,22 +300,22 @@ void aspeed_test_sha512(const char *machine, const uint32_t base,
 }
 
 void aspeed_test_sha256_sg(const char *machine, const uint32_t base,
-                           const uint32_t src_addr)
+                           const uint64_t src_addr)
 {
     QTestState *s = qtest_init(machine);
 
-    const uint32_t src_addr_1 = src_addr + 0x10000;
-    const uint32_t src_addr_2 = src_addr + 0x20000;
-    const uint32_t src_addr_3 = src_addr + 0x30000;
-    const uint32_t digest_addr = src_addr + 0x40000;
+    const uint64_t src_addr_1 = src_addr + 0x10000;
+    const uint64_t src_addr_2 = src_addr + 0x20000;
+    const uint64_t src_addr_3 = src_addr + 0x30000;
+    const uint64_t digest_addr = src_addr + 0x40000;
     uint8_t digest[32] = {0};
     struct AspeedSgList array[] = {
         {  cpu_to_le32(sizeof(test_vector_sg1)),
-           cpu_to_le32(src_addr_1) },
+           cpu_to_le64(src_addr_1) },
         {  cpu_to_le32(sizeof(test_vector_sg2)),
-           cpu_to_le32(src_addr_2) },
+           cpu_to_le64(src_addr_2) },
         {  cpu_to_le32(sizeof(test_vector_sg3) | SG_LIST_LEN_LAST),
-           cpu_to_le32(src_addr_3) },
+           cpu_to_le64(src_addr_3) },
     };
 
     /* Check engine is idle, no busy or irq bits set */
@@ -351,22 +351,22 @@ void aspeed_test_sha256_sg(const char *machine, const uint32_t base,
 }
 
 void aspeed_test_sha384_sg(const char *machine, const uint32_t base,
-                           const uint32_t src_addr)
+                           const uint64_t src_addr)
 {
     QTestState *s = qtest_init(machine);
 
-    const uint32_t src_addr_1 = src_addr + 0x10000;
-    const uint32_t src_addr_2 = src_addr + 0x20000;
-    const uint32_t src_addr_3 = src_addr + 0x30000;
-    const uint32_t digest_addr = src_addr + 0x40000;
+    const uint64_t src_addr_1 = src_addr + 0x10000;
+    const uint64_t src_addr_2 = src_addr + 0x20000;
+    const uint64_t src_addr_3 = src_addr + 0x30000;
+    const uint64_t digest_addr = src_addr + 0x40000;
     uint8_t digest[64] = {0};
     struct AspeedSgList array[] = {
         {  cpu_to_le32(sizeof(test_vector_sg1)),
-           cpu_to_le32(src_addr_1) },
+           cpu_to_le64(src_addr_1) },
         {  cpu_to_le32(sizeof(test_vector_sg2)),
-           cpu_to_le32(src_addr_2) },
+           cpu_to_le64(src_addr_2) },
         {  cpu_to_le32(sizeof(test_vector_sg3) | SG_LIST_LEN_LAST),
-           cpu_to_le32(src_addr_3) },
+           cpu_to_le64(src_addr_3) },
     };
 
     /* Check engine is idle, no busy or irq bits set */
@@ -402,22 +402,22 @@ void aspeed_test_sha384_sg(const char *machine, const uint32_t base,
 }
 
 void aspeed_test_sha512_sg(const char *machine, const uint32_t base,
-                           const uint32_t src_addr)
+                           const uint64_t src_addr)
 {
     QTestState *s = qtest_init(machine);
 
-    const uint32_t src_addr_1 = src_addr + 0x10000;
-    const uint32_t src_addr_2 = src_addr + 0x20000;
-    const uint32_t src_addr_3 = src_addr + 0x30000;
-    const uint32_t digest_addr = src_addr + 0x40000;
+    const uint64_t src_addr_1 = src_addr + 0x10000;
+    const uint64_t src_addr_2 = src_addr + 0x20000;
+    const uint64_t src_addr_3 = src_addr + 0x30000;
+    const uint64_t digest_addr = src_addr + 0x40000;
     uint8_t digest[64] = {0};
     struct AspeedSgList array[] = {
         {  cpu_to_le32(sizeof(test_vector_sg1)),
-           cpu_to_le32(src_addr_1) },
+           cpu_to_le64(src_addr_1) },
         {  cpu_to_le32(sizeof(test_vector_sg2)),
-           cpu_to_le32(src_addr_2) },
+           cpu_to_le64(src_addr_2) },
         {  cpu_to_le32(sizeof(test_vector_sg3) | SG_LIST_LEN_LAST),
-           cpu_to_le32(src_addr_3) },
+           cpu_to_le64(src_addr_3) },
     };
 
     /* Check engine is idle, no busy or irq bits set */
@@ -453,16 +453,16 @@ void aspeed_test_sha512_sg(const char *machine, const uint32_t base,
 }
 
 void aspeed_test_sha256_accum(const char *machine, const uint32_t base,
-                              const uint32_t src_addr)
+                              const uint64_t src_addr)
 {
     QTestState *s = qtest_init(machine);
 
-    const uint32_t buffer_addr = src_addr + 0x10000;
-    const uint32_t digest_addr = src_addr + 0x40000;
+    const uint64_t buffer_addr = src_addr + 0x10000;
+    const uint64_t digest_addr = src_addr + 0x40000;
     uint8_t digest[32] = {0};
     struct AspeedSgList array[] = {
         {  cpu_to_le32(sizeof(test_vector_accum_256) | SG_LIST_LEN_LAST),
-           cpu_to_le32(buffer_addr) },
+           cpu_to_le64(buffer_addr) },
     };
 
     /* Check engine is idle, no busy or irq bits set */
@@ -494,16 +494,16 @@ void aspeed_test_sha256_accum(const char *machine, const uint32_t base,
 }
 
 void aspeed_test_sha384_accum(const char *machine, const uint32_t base,
-                              const uint32_t src_addr)
+                              const uint64_t src_addr)
 {
     QTestState *s = qtest_init(machine);
 
-    const uint32_t buffer_addr = src_addr + 0x10000;
-    const uint32_t digest_addr = src_addr + 0x40000;
+    const uint64_t buffer_addr = src_addr + 0x10000;
+    const uint64_t digest_addr = src_addr + 0x40000;
     uint8_t digest[64] = {0};
     struct AspeedSgList array[] = {
         {  cpu_to_le32(sizeof(test_vector_accum_384) | SG_LIST_LEN_LAST),
-           cpu_to_le32(buffer_addr) },
+           cpu_to_le64(buffer_addr) },
     };
 
     /* Check engine is idle, no busy or irq bits set */
@@ -535,16 +535,16 @@ void aspeed_test_sha384_accum(const char *machine, const uint32_t base,
 }
 
 void aspeed_test_sha512_accum(const char *machine, const uint32_t base,
-                              const uint32_t src_addr)
+                              const uint64_t src_addr)
 {
     QTestState *s = qtest_init(machine);
 
-    const uint32_t buffer_addr = src_addr + 0x10000;
-    const uint32_t digest_addr = src_addr + 0x40000;
+    const uint64_t buffer_addr = src_addr + 0x10000;
+    const uint64_t digest_addr = src_addr + 0x40000;
     uint8_t digest[64] = {0};
     struct AspeedSgList array[] = {
         {  cpu_to_le32(sizeof(test_vector_accum_512) | SG_LIST_LEN_LAST),
-           cpu_to_le32(buffer_addr) },
+           cpu_to_le64(buffer_addr) },
     };
 
     /* Check engine is idle, no busy or irq bits set */
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 71+ messages in thread

* [PATCH v1 19/22] test/qtest/hace: Support 64-bit source and digest addresses for AST2700
  2025-03-21  9:25 [PATCH v1 00/22] Fix incorrect hash results on AST2700 Jamin Lin via
                   ` (17 preceding siblings ...)
  2025-03-21  9:26 ` [PATCH v1 18/22] test/qtest/hace: Update source data and digest data type to 64-bit Jamin Lin via
@ 2025-03-21  9:26 ` Jamin Lin via
  2025-04-02  9:06   ` Cédric Le Goater
  2025-03-21  9:26 ` [PATCH v1 20/22] test/qtest/hace: Support to test upper 32 bits of digest and source addresses Jamin Lin via
                   ` (4 subsequent siblings)
  23 siblings, 1 reply; 71+ messages in thread
From: Jamin Lin via @ 2025-03-21  9:26 UTC (permalink / raw)
  To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
	Andrew Jeffery, Joel Stanley, Fabiano Rosas, Laurent Vivier,
	Paolo Bonzini, open list:ASPEED BMCs,
	open list:All patches CC here
  Cc: jamin_lin, troy_lee

Added "HACE_HASH_SRC_HI" and "HACE_HASH_DIGEST_HI", "HACE_HASH_KEY_BUFF_HI"
registers to store upper 32 bits.
Updated "write_regs" to handle 64-bit source and digest addresses.

Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
---
 tests/qtest/aspeed-hace-utils.h | 3 +++
 tests/qtest/aspeed-hace-utils.c | 2 ++
 2 files changed, 5 insertions(+)

diff --git a/tests/qtest/aspeed-hace-utils.h b/tests/qtest/aspeed-hace-utils.h
index 0382570fa2..d8684d3f83 100644
--- a/tests/qtest/aspeed-hace-utils.h
+++ b/tests/qtest/aspeed-hace-utils.h
@@ -36,6 +36,9 @@
 #define HACE_HASH_KEY_BUFF       0x28
 #define HACE_HASH_DATA_LEN       0x2c
 #define HACE_HASH_CMD            0x30
+#define HACE_HASH_SRC_HI         0x90
+#define HACE_HASH_DIGEST_HI      0x94
+#define HACE_HASH_KEY_BUFF_HI    0x98
 
 /* Scatter-Gather Hash */
 #define SG_LIST_LEN_LAST         BIT(31)
diff --git a/tests/qtest/aspeed-hace-utils.c b/tests/qtest/aspeed-hace-utils.c
index f39bb8ea48..8d9c464f72 100644
--- a/tests/qtest/aspeed-hace-utils.c
+++ b/tests/qtest/aspeed-hace-utils.c
@@ -157,7 +157,9 @@ static void write_regs(QTestState *s, uint32_t base, uint64_t src,
                        uint32_t length, uint64_t out, uint32_t method)
 {
         qtest_writel(s, base + HACE_HASH_SRC, extract64(src, 0, 32));
+        qtest_writel(s, base + HACE_HASH_SRC_HI, extract64(src, 32, 32));
         qtest_writel(s, base + HACE_HASH_DIGEST, extract64(out, 0, 32));
+        qtest_writel(s, base + HACE_HASH_DIGEST_HI, extract64(out, 32, 32));
         qtest_writel(s, base + HACE_HASH_DATA_LEN, length);
         qtest_writel(s, base + HACE_HASH_CMD, HACE_SHA_BE_EN | method);
 }
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 71+ messages in thread

* [PATCH v1 20/22] test/qtest/hace: Support to test upper 32 bits of digest and source addresses
  2025-03-21  9:25 [PATCH v1 00/22] Fix incorrect hash results on AST2700 Jamin Lin via
                   ` (18 preceding siblings ...)
  2025-03-21  9:26 ` [PATCH v1 19/22] test/qtest/hace: Support 64-bit source and digest addresses for AST2700 Jamin Lin via
@ 2025-03-21  9:26 ` Jamin Lin via
  2025-04-02  9:12   ` Cédric Le Goater
  2025-03-21  9:26 ` [PATCH v1 21/22] test/qtest/hace: Support to validate 64-bit hmac key buffer addresses Jamin Lin via
                   ` (3 subsequent siblings)
  23 siblings, 1 reply; 71+ messages in thread
From: Jamin Lin via @ 2025-03-21  9:26 UTC (permalink / raw)
  To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
	Andrew Jeffery, Joel Stanley, Fabiano Rosas, Laurent Vivier,
	Paolo Bonzini, open list:ASPEED BMCs,
	open list:All patches CC here
  Cc: jamin_lin, troy_lee

Added "src_hi" and "dest_hi" fields to "AspeedMasks" for 64-bit addresses test.
Updated "aspeed_test_addresses" to validate "HACE_HASH_SRC_HI" and
"HACE_HASH_DIGEST_HI".
Ensured correct masking of 64-bit addresses by checking both lower and upper
32-bit registers.

Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
---
 tests/qtest/aspeed-hace-utils.h |  2 ++
 tests/qtest/aspeed-hace-utils.c | 15 ++++++++++++++-
 2 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/tests/qtest/aspeed-hace-utils.h b/tests/qtest/aspeed-hace-utils.h
index d8684d3f83..de8055a1db 100644
--- a/tests/qtest/aspeed-hace-utils.h
+++ b/tests/qtest/aspeed-hace-utils.h
@@ -51,6 +51,8 @@ struct AspeedMasks {
     uint32_t src;
     uint32_t dest;
     uint32_t len;
+    uint32_t src_hi;
+    uint32_t dest_hi;
 };
 
 void aspeed_test_md5(const char *machine, const uint32_t base,
diff --git a/tests/qtest/aspeed-hace-utils.c b/tests/qtest/aspeed-hace-utils.c
index 8d9c464f72..fc209353f3 100644
--- a/tests/qtest/aspeed-hace-utils.c
+++ b/tests/qtest/aspeed-hace-utils.c
@@ -588,30 +588,43 @@ void aspeed_test_addresses(const char *machine, const uint32_t base,
      */
     g_assert_cmphex(qtest_readl(s, base + HACE_CMD), ==, 0);
     g_assert_cmphex(qtest_readl(s, base + HACE_HASH_SRC), ==, 0);
+    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_SRC_HI), ==, 0);
     g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DIGEST), ==, 0);
+    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DIGEST_HI), ==, 0);
     g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DATA_LEN), ==, 0);
 
-
     /* Check that the address masking is correct */
     qtest_writel(s, base + HACE_HASH_SRC, 0xffffffff);
     g_assert_cmphex(qtest_readl(s, base + HACE_HASH_SRC), ==, expected->src);
 
+    qtest_writel(s, base + HACE_HASH_SRC_HI, 0xffffffff);
+    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_SRC_HI),
+                    ==, expected->src_hi);
+
     qtest_writel(s, base + HACE_HASH_DIGEST, 0xffffffff);
     g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DIGEST), ==,
                     expected->dest);
 
+    qtest_writel(s, base + HACE_HASH_DIGEST_HI, 0xffffffff);
+    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DIGEST_HI), ==,
+                    expected->dest_hi);
+
     qtest_writel(s, base + HACE_HASH_DATA_LEN, 0xffffffff);
     g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DATA_LEN), ==,
                     expected->len);
 
     /* Reset to zero */
     qtest_writel(s, base + HACE_HASH_SRC, 0);
+    qtest_writel(s, base + HACE_HASH_SRC_HI, 0);
     qtest_writel(s, base + HACE_HASH_DIGEST, 0);
+    qtest_writel(s, base + HACE_HASH_DIGEST_HI, 0);
     qtest_writel(s, base + HACE_HASH_DATA_LEN, 0);
 
     /* Check that all bits are now zero */
     g_assert_cmphex(qtest_readl(s, base + HACE_HASH_SRC), ==, 0);
+    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_SRC_HI), ==, 0);
     g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DIGEST), ==, 0);
+    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DIGEST_HI), ==, 0);
     g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DATA_LEN), ==, 0);
 
     qtest_quit(s);
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 71+ messages in thread

* [PATCH v1 21/22] test/qtest/hace: Support to validate 64-bit hmac key buffer addresses
  2025-03-21  9:25 [PATCH v1 00/22] Fix incorrect hash results on AST2700 Jamin Lin via
                   ` (19 preceding siblings ...)
  2025-03-21  9:26 ` [PATCH v1 20/22] test/qtest/hace: Support to test upper 32 bits of digest and source addresses Jamin Lin via
@ 2025-03-21  9:26 ` Jamin Lin via
  2025-04-02  9:12   ` Cédric Le Goater
  2025-03-21  9:26 ` [PATCH v1 22/22] test/qtest/hace: Add tests for AST2700 Jamin Lin via
                   ` (2 subsequent siblings)
  23 siblings, 1 reply; 71+ messages in thread
From: Jamin Lin via @ 2025-03-21  9:26 UTC (permalink / raw)
  To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
	Andrew Jeffery, Joel Stanley, Fabiano Rosas, Laurent Vivier,
	Paolo Bonzini, open list:ASPEED BMCs,
	open list:All patches CC here
  Cc: jamin_lin, troy_lee

Added "key" and "key_hi" fields to "AspeedMasks" for 64-bit addresses test.
Updated "aspeed_test_addresses" to validate "HACE_HASH_KEY_BUFF" and
"HACE_HASH_KEY_BUFF_HI".
Ensured correct masking of 64-bit addresses by checking both lower and upper
32-bit registers.

Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
---
 tests/qtest/aspeed-hace-utils.h |  2 ++
 tests/qtest/aspeed-hace-utils.c | 14 ++++++++++++++
 tests/qtest/aspeed_hace-test.c  |  4 ++++
 3 files changed, 20 insertions(+)

diff --git a/tests/qtest/aspeed-hace-utils.h b/tests/qtest/aspeed-hace-utils.h
index de8055a1db..c8b2ec45af 100644
--- a/tests/qtest/aspeed-hace-utils.h
+++ b/tests/qtest/aspeed-hace-utils.h
@@ -50,9 +50,11 @@ struct AspeedSgList {
 struct AspeedMasks {
     uint32_t src;
     uint32_t dest;
+    uint32_t key;
     uint32_t len;
     uint32_t src_hi;
     uint32_t dest_hi;
+    uint32_t key_hi;
 };
 
 void aspeed_test_md5(const char *machine, const uint32_t base,
diff --git a/tests/qtest/aspeed-hace-utils.c b/tests/qtest/aspeed-hace-utils.c
index fc209353f3..a5ece614ed 100644
--- a/tests/qtest/aspeed-hace-utils.c
+++ b/tests/qtest/aspeed-hace-utils.c
@@ -591,6 +591,8 @@ void aspeed_test_addresses(const char *machine, const uint32_t base,
     g_assert_cmphex(qtest_readl(s, base + HACE_HASH_SRC_HI), ==, 0);
     g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DIGEST), ==, 0);
     g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DIGEST_HI), ==, 0);
+    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_KEY_BUFF), ==, 0);
+    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_KEY_BUFF_HI), ==, 0);
     g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DATA_LEN), ==, 0);
 
     /* Check that the address masking is correct */
@@ -609,6 +611,14 @@ void aspeed_test_addresses(const char *machine, const uint32_t base,
     g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DIGEST_HI), ==,
                     expected->dest_hi);
 
+    qtest_writel(s, base + HACE_HASH_KEY_BUFF, 0xffffffff);
+    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_KEY_BUFF), ==,
+                    expected->key);
+
+    qtest_writel(s, base + HACE_HASH_KEY_BUFF_HI, 0xffffffff);
+    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_KEY_BUFF_HI), ==,
+                    expected->key_hi);
+
     qtest_writel(s, base + HACE_HASH_DATA_LEN, 0xffffffff);
     g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DATA_LEN), ==,
                     expected->len);
@@ -618,6 +628,8 @@ void aspeed_test_addresses(const char *machine, const uint32_t base,
     qtest_writel(s, base + HACE_HASH_SRC_HI, 0);
     qtest_writel(s, base + HACE_HASH_DIGEST, 0);
     qtest_writel(s, base + HACE_HASH_DIGEST_HI, 0);
+    qtest_writel(s, base + HACE_HASH_KEY_BUFF, 0);
+    qtest_writel(s, base + HACE_HASH_KEY_BUFF_HI, 0);
     qtest_writel(s, base + HACE_HASH_DATA_LEN, 0);
 
     /* Check that all bits are now zero */
@@ -625,6 +637,8 @@ void aspeed_test_addresses(const char *machine, const uint32_t base,
     g_assert_cmphex(qtest_readl(s, base + HACE_HASH_SRC_HI), ==, 0);
     g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DIGEST), ==, 0);
     g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DIGEST_HI), ==, 0);
+    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_KEY_BUFF), ==, 0);
+    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_KEY_BUFF_HI), ==, 0);
     g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DATA_LEN), ==, 0);
 
     qtest_quit(s);
diff --git a/tests/qtest/aspeed_hace-test.c b/tests/qtest/aspeed_hace-test.c
index 31890d574e..38777020ca 100644
--- a/tests/qtest/aspeed_hace-test.c
+++ b/tests/qtest/aspeed_hace-test.c
@@ -13,24 +13,28 @@
 static const struct AspeedMasks ast1030_masks = {
     .src  = 0x7fffffff,
     .dest = 0x7ffffff8,
+    .key = 0x7ffffff8,
     .len  = 0x0fffffff,
 };
 
 static const struct AspeedMasks ast2600_masks = {
     .src  = 0x7fffffff,
     .dest = 0x7ffffff8,
+    .key = 0x7ffffff8,
     .len  = 0x0fffffff,
 };
 
 static const struct AspeedMasks ast2500_masks = {
     .src  = 0x3fffffff,
     .dest = 0x3ffffff8,
+    .key = 0x3fffffc0,
     .len  = 0x0fffffff,
 };
 
 static const struct AspeedMasks ast2400_masks = {
     .src  = 0x0fffffff,
     .dest = 0x0ffffff8,
+    .key = 0x0fffffc0,
     .len  = 0x0fffffff,
 };
 
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 71+ messages in thread

* [PATCH v1 22/22] test/qtest/hace: Add tests for AST2700
  2025-03-21  9:25 [PATCH v1 00/22] Fix incorrect hash results on AST2700 Jamin Lin via
                   ` (20 preceding siblings ...)
  2025-03-21  9:26 ` [PATCH v1 21/22] test/qtest/hace: Support to validate 64-bit hmac key buffer addresses Jamin Lin via
@ 2025-03-21  9:26 ` Jamin Lin via
  2025-04-02  9:16   ` Cédric Le Goater
  2025-03-21  9:39 ` [PATCH v1 00/22] Fix incorrect hash results on AST2700 Cédric Le Goater
  2025-04-02  9:47 ` Cédric Le Goater
  23 siblings, 1 reply; 71+ messages in thread
From: Jamin Lin via @ 2025-03-21  9:26 UTC (permalink / raw)
  To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
	Andrew Jeffery, Joel Stanley, Fabiano Rosas, Laurent Vivier,
	Paolo Bonzini, open list:ASPEED BMCs,
	open list:All patches CC here
  Cc: jamin_lin, troy_lee

The HACE models in AST2600 and AST2700 are nearly identical. Based on the
AST2600 test cases, new tests have been added for AST2700.

Implemented test functions for SHA-256, SHA-384, SHA-512, and MD5.
Added scatter-gather and accumulation test variants.
For AST2700, the HACE controller base address starts at "0x12070000", and
the DRAM start address is "0x4_00000000".

Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
---
 tests/qtest/ast2700-hace-test.c | 98 +++++++++++++++++++++++++++++++++
 tests/qtest/meson.build         |  4 +-
 2 files changed, 101 insertions(+), 1 deletion(-)
 create mode 100644 tests/qtest/ast2700-hace-test.c

diff --git a/tests/qtest/ast2700-hace-test.c b/tests/qtest/ast2700-hace-test.c
new file mode 100644
index 0000000000..a400e2962b
--- /dev/null
+++ b/tests/qtest/ast2700-hace-test.c
@@ -0,0 +1,98 @@
+/*
+ * QTest testcase for the ASPEED Hash and Crypto Engine
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright (C) 2025 ASPEED Technology Inc.
+ */
+
+#include "qemu/osdep.h"
+#include "libqtest.h"
+#include "qemu/bitops.h"
+#include "aspeed-hace-utils.h"
+
+static const struct AspeedMasks as2700_masks = {
+    .src  = 0x7fffffff,
+    .dest = 0x7ffffff8,
+    .key = 0x7ffffff8,
+    .len  = 0x0fffffff,
+    .src_hi  = 0x00000003,
+    .dest_hi = 0x00000003,
+    .key_hi = 0x00000003,
+};
+
+/* ast2700 */
+static void test_md5_ast2700(void)
+{
+    aspeed_test_md5("-machine ast2700a1-evb", 0x12070000, 0x400000000);
+}
+
+static void test_sha256_ast2700(void)
+{
+    aspeed_test_sha256("-machine ast2700a1-evb", 0x12070000, 0x400000000);
+}
+
+static void test_sha256_sg_ast2700(void)
+{
+    aspeed_test_sha256_sg("-machine ast2700a1-evb", 0x12070000, 0x400000000);
+}
+
+static void test_sha384_ast2700(void)
+{
+    aspeed_test_sha384("-machine ast2700a1-evb", 0x12070000, 0x400000000);
+}
+
+static void test_sha384_sg_ast2700(void)
+{
+    aspeed_test_sha384_sg("-machine ast2700a1-evb", 0x12070000, 0x400000000);
+}
+
+static void test_sha512_ast2700(void)
+{
+    aspeed_test_sha512("-machine ast2700a1-evb", 0x12070000, 0x400000000);
+}
+
+static void test_sha512_sg_ast2700(void)
+{
+    aspeed_test_sha512_sg("-machine ast2700a1-evb", 0x12070000, 0x400000000);
+}
+
+static void test_sha256_accum_ast2700(void)
+{
+    aspeed_test_sha256_accum("-machine ast2700a1-evb", 0x12070000, 0x400000000);
+}
+
+static void test_sha384_accum_ast2700(void)
+{
+    aspeed_test_sha384_accum("-machine ast2700a1-evb", 0x12070000, 0x400000000);
+}
+
+static void test_sha512_accum_ast2700(void)
+{
+    aspeed_test_sha512_accum("-machine ast2700a1-evb", 0x12070000, 0x400000000);
+}
+
+static void test_addresses_ast2700(void)
+{
+    aspeed_test_addresses("-machine ast2700a1-evb", 0x12070000, &as2700_masks);
+}
+
+int main(int argc, char **argv)
+{
+    g_test_init(&argc, &argv, NULL);
+
+    qtest_add_func("ast2700/hace/addresses", test_addresses_ast2700);
+    qtest_add_func("ast2700/hace/sha512", test_sha512_ast2700);
+    qtest_add_func("ast2700/hace/sha384", test_sha384_ast2700);
+    qtest_add_func("ast2700/hace/sha256", test_sha256_ast2700);
+    qtest_add_func("ast2700/hace/md5", test_md5_ast2700);
+
+    qtest_add_func("ast2700/hace/sha512_sg", test_sha512_sg_ast2700);
+    qtest_add_func("ast2700/hace/sha384_sg", test_sha384_sg_ast2700);
+    qtest_add_func("ast2700/hace/sha256_sg", test_sha256_sg_ast2700);
+
+    qtest_add_func("ast2700/hace/sha512_accum", test_sha512_accum_ast2700);
+    qtest_add_func("ast2700/hace/sha384_accum", test_sha384_accum_ast2700);
+    qtest_add_func("ast2700/hace/sha256_accum", test_sha256_accum_ast2700);
+
+    return g_test_run();
+}
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
index 62fc8f9868..253d37f7bd 100644
--- a/tests/qtest/meson.build
+++ b/tests/qtest/meson.build
@@ -218,7 +218,8 @@ qtests_aspeed = \
    'aspeed_gpio-test']
 qtests_aspeed64 = \
   ['ast2700-gpio-test',
-   'ast2700-smc-test']
+   'ast2700-smc-test',
+   'ast2700-hace-test']
 
 qtests_stm32l4x5 = \
   ['stm32l4x5_exti-test',
@@ -384,6 +385,7 @@ qtests = {
   'aspeed_smc-test': files('aspeed-smc-utils.c', 'aspeed_smc-test.c'),
   'ast2700-smc-test': files('aspeed-smc-utils.c', 'ast2700-smc-test.c'),
   'aspeed_hace-test': files('aspeed-hace-utils.c', 'aspeed_hace-test.c'),
+  'ast2700-hace-test': files('aspeed-hace-utils.c', 'ast2700-hace-test.c'),
 }
 
 if vnc.found()
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 71+ messages in thread

* Re: [PATCH v1 00/22] Fix incorrect hash results on AST2700
  2025-03-21  9:25 [PATCH v1 00/22] Fix incorrect hash results on AST2700 Jamin Lin via
                   ` (21 preceding siblings ...)
  2025-03-21  9:26 ` [PATCH v1 22/22] test/qtest/hace: Add tests for AST2700 Jamin Lin via
@ 2025-03-21  9:39 ` Cédric Le Goater
  2025-04-02  9:47 ` Cédric Le Goater
  23 siblings, 0 replies; 71+ messages in thread
From: Cédric Le Goater @ 2025-03-21  9:39 UTC (permalink / raw)
  To: Jamin Lin, Peter Maydell, Steven Lee, Troy Lee, Andrew Jeffery,
	Joel Stanley, Fabiano Rosas, Laurent Vivier, Paolo Bonzini,
	open list:ASPEED BMCs, open list:All patches CC here
  Cc: troy_lee

Hello Jamin

On 3/21/25 10:25, Jamin Lin wrote:
> v1:
>   1. Added support for 64-bit DMA in the HACE model
>   2. Refactored the do_hash operation in the HACE model
>   3. Fixed a crash caused by out-of-bound memory access in HACE
>   4. Added more trace events and implemented dumping of source hash data and
>      resulting digests to improve debugging
>   5. Refactored the HACE QTest framework to support both AST1030 and AST2700
>   6. Added a test case for SHA384
> 
> This patchset resolves incorrect hash results reported on the AST2700 platform.


Thanks for taking time to address these issues.

I think it is a big change for QEMU 10.0 and I'd rather keep it
for QEMU 10.1. However, there seem to be important fixes which
would be candidates for QEMU 10.0, such as patch 2. Could you
please send a Fixes: trailer as a reply to the patch ? No need
to resend.


Thanks,

C.



> This update addresses the following kernel warnings and test failures related to
> the crypto self-test framework:
> 
> aspeed-hmac-sha512 test failed (incorrect result)
> aspeed-hmac-sha384 test failed (incorrect result)
> aspeed-sha512 test failed (incorrect result)
> aspeed-sha384 test failed (incorrect result)
> aspeed-hmac-sha256 test failed (incorrect result)
> aspeed-hmac-sha224 test failed (incorrect result)
> aspeed-hmac-sha1 test failed (incorrect result)
> aspeed-sha224 test failed (incorrect result)
> aspeed-sha256 test failed (incorrect result)
> aspeed-sha1 test failed (incorrect result)
> 
> How to test it
> 
> Use the following command to dump information about the supported digest methods
> via the afalg hardware engine:
> 
> root@ast2700-default:~# openssl engine -pre DUMP_INFO afalg
> 
> Digest SHA1, NID=64, AF_ALG info: name=sha1ALG_ERR: , driver=aspeed-sha1 (hw accelerated)
> Digest SHA224, NID=675, AF_ALG info: name=sha224ALG_ERR: , driver=aspeed-sha224 (hw accelerated)
> Digest SHA256, NID=672, AF_ALG info: name=sha256ALG_ERR: , driver=aspeed-sha256 (hw accelerated)
> Digest SHA384, NID=673, AF_ALG info: name=sha384ALG_ERR: , driver=aspeed-sha384 (hw accelerated)
> Digest SHA512, NID=674, AF_ALG info: name=sha512ALG_ERR: , driver=aspeed-sha512 (hw accelerated)
> 
> The status of SHA1, SHA224, SHA256, SHA384, and SHA512 should be marked as
> hw accelerated, indicating that these algorithms are supported by hardware
> acceleration via the aspeed drivers.
> 
> Create a test file on the host machine and compute its HASH value as the
> expected result
> 
> Create a 256MB test file
> 
> $ dd if=/dev/random of=/tmp/256M bs=1M count=256
> Generate Hash Values Using SHA1, SHA224, SHA256, SHA384, and SHA512
> 
> Use the following commands to generate HASH values for a 256MB file using
> different SHA algorithms:
> 
> $ sha1sum /tmp/256M
> 7fc628811a31ab87b0502dab3ed8d3ef07565885  /tmp/256M
> 
> $ sha224sum /tmp/256M
> 2d261c11ba05b3a62e0efeab51c307d9933426c7e18204683ef3da54  /tmp/256M
> 
> $ sha256sum /tmp/256M
> 5716d1700ee35c92ca5ca5b466639e9c36eed3f1447c1aec27f16d0fe113f94d  /tmp/256M
> 
> $ sha384sum /tmp/256M
> fb6bc62afa1096dcd3b870e7d2546b7a5a177b5f2bbd5c9759218182454709e0c504a2d9c26404e04aa8010a291b7f1c  /tmp/256M
> 
> $ sha512sum /tmp/256M
> fbceda7be34836fe857781656318ecd5b457a833a24c8736d5b8ef8d07e1950eebcdb140eebe4f12b5ff59586f7eb1c64fa95869c63dd9e4703d91261093c5c9  /tmp/256M
> 
> Generate HASH Values Using the Hardware Engine
> 
> Use the following commands to generate HASH values for a 256MB file using
> various SHA algorithms with the afalg hardware engine:
> 
> 
> root@ast2700-default:~# openssl dgst -sha1 -engine afalg /tmp/256M
> Engine "afalg" set.
> SHA1(/tmp/256M)= 7fc628811a31ab87b0502dab3ed8d3ef07565885
> 
> root@ast2700-default:~# openssl dgst -sha224 -engine ast_crypto_engine /tmp/256M
> Engine "afalg" set.
> SHA2-224(/tmp/256M)= 2d261c11ba05b3a62e0efeab51c307d9933426c7e18204683ef3da54
> 
> root@ast2700-default:~# openssl dgst -sha256 -engine afalg /tmp/256M
> Engine "afalg" set.
> SHA2-256(/tmp/256M)= 5716d1700ee35c92ca5ca5b466639e9c36eed3f1447c1aec27f16d0fe113f94d
> 
> root@ast2700-default:~# openssl dgst -sha384 -engine afalg /tmp/256M
> Engine "afalg" set.
> SHA2-384(/tmp/256M)= fb6bc62afa1096dcd3b870e7d2546b7a5a177b5f2bbd5c9759218182454709e0c504a2d9c26404e04aa8010a291b7f1c
> 
> root@ast2700-default:~# openssl dgst -sha512 -engine afalg /tmp/256M
> Engine "afalg" set.
> SHA2-512(/tmp/256M)= fbceda7be34836fe857781656318ecd5b457a833a24c8736d5b8ef8d07e1950eebcdb140eebe4f12b5ff59586f7eb1c64fa95869c63dd9e4703d91261093c5c9
> 
> 
> The HASH values generated here should exactly match those computed on the host
> machine using software-based OpenSSL, verifying both the correctness of the
> hardware-accelerated results and the functionality of the afalg.
> 
> 
> Jamin Lin (22):
>    hw/misc/aspeed_hace: Remove unused code for better readability
>    hw/misc/aspeed_hace: Fix buffer overflow in has_padding function
>    hw/misc/aspeed_hace: Improve readability and consistency in variable
>      naming
>    hw/misc/aspeed_hace: Update hash source address handling to 64-bit for
>      AST2700
>    hw/misc/aspeed_hace: Introduce 64-bit digest_addr variable for AST2700
>    hw/misc/aspeed_hace: Support accumulative mode for direct access mode
>    hw/misc/aspeed_hace: Add support for source, digest, key buffer 64 bit
>      addresses
>    hw/misc/aspeed_hace: Support DMA 64 bits dram address.
>    hw/misc/aspeed_hace: Ensure HASH_IRQ is always set to prevent firmware
>      hang
>    hw/misc/aspeed_hace:: Support setting different memory size
>    hw/misc/aspeed_hace: Add trace-events for better debugging
>    hw/misc/aspeed_hace Support to dump plaintext and digest for better
>      debugging
>    test/qtest: Introduce a new aspeed-hace-utils.c to place common
>      testcases
>    test/qtest/hace: Adjust test address range for AST1030 due to SRAM
>      limitations
>    test/qtest/hace: Add SHA-384 test cases for ASPEED HACE model
>    test/qtest/hace: Add SHA-384 tests for AST2600
>    test/qtest/hace: Add tests for AST1030
>    test/qtest/hace: Update source data and digest data type to 64-bit
>    test/qtest/hace: Support 64-bit source and digest addresses for
>      AST2700
>    test/qtest/hace: Support to test upper 32 bits of digest and source
>      addresses
>    test/qtest/hace: Support to validate 64-bit hmac key buffer addresses
>    test/qtest/hace: Add tests for AST2700
> 
>   include/hw/misc/aspeed_hace.h   |   9 +-
>   tests/qtest/aspeed-hace-utils.h |  84 +++++
>   hw/misc/aspeed_hace.c           | 194 ++++++----
>   tests/qtest/aspeed-hace-utils.c | 646 ++++++++++++++++++++++++++++++++
>   tests/qtest/aspeed_hace-test.c  | 577 +++++-----------------------
>   tests/qtest/ast2700-hace-test.c |  98 +++++
>   hw/misc/trace-events            |   6 +
>   tests/qtest/meson.build         |   5 +-
>   8 files changed, 1074 insertions(+), 545 deletions(-)
>   create mode 100644 tests/qtest/aspeed-hace-utils.h
>   create mode 100644 tests/qtest/aspeed-hace-utils.c
>   create mode 100644 tests/qtest/ast2700-hace-test.c
> 



^ permalink raw reply	[flat|nested] 71+ messages in thread

* RE: [PATCH v1 02/22] hw/misc/aspeed_hace: Fix buffer overflow in has_padding function
  2025-03-21  9:25 ` [PATCH v1 02/22] hw/misc/aspeed_hace: Fix buffer overflow in has_padding function Jamin Lin via
@ 2025-03-21  9:47   ` Jamin Lin
  2025-03-22 20:52     ` Cédric Le Goater
  0 siblings, 1 reply; 71+ messages in thread
From: Jamin Lin @ 2025-03-21  9:47 UTC (permalink / raw)
  To: Jamin Lin, Cédric Le Goater, Peter Maydell, Steven Lee,
	Troy Lee, Andrew Jeffery, Joel Stanley, Fabiano Rosas,
	Laurent Vivier, Paolo Bonzini, open list:ASPEED BMCs,
	open list:All patches CC here
  Cc: Troy Lee

Hi Cedric,

> Subject: [PATCH v1 02/22] hw/misc/aspeed_hace: Fix buffer overflow in
> has_padding function
> 
> The maximum padding size is either 64 or 128 bytes and should always be
> smaller than "req_len". If "padding_size" exceeds "req_len", then "req_len -
> padding_size" underflows due to "uint32_t" data type, leading to a large
> incorrect value (e.g., `0xFFXXXXXX`). This causes an out-of-bounds memory
> access, potentially leading to a buffer overflow.
> 
> Added a check to ensure "padding_size" does not exceed "req_len" before
> computing "pad_offset". This prevents "req_len - padding_size" from
> underflowing and avoids accessing invalid memory.
> 
> Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
> ---
>  hw/misc/aspeed_hace.c | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/hw/misc/aspeed_hace.c b/hw/misc/aspeed_hace.c index
> 8e7e8113a5..d8b5f048bb 100644
> --- a/hw/misc/aspeed_hace.c
> +++ b/hw/misc/aspeed_hace.c
> @@ -128,6 +128,11 @@ static bool has_padding(AspeedHACEState *s, struct
> iovec *iov,
>      if (*total_msg_len <= s->total_req_len) {
>          uint32_t padding_size = s->total_req_len - *total_msg_len;
>          uint8_t *padding = iov->iov_base;
> +
> +        if (padding_size > req_len) {
> +            return false;
> +        }
> +
>          *pad_offset = req_len - padding_size;
>          if (padding[*pad_offset] == 0x80) {
>              return true;
> --
> 2.43.0

Fixes: 5cd7d8564a8b563da724b9e6264c967f0a091afa ("aspeed/hace: Support AST2600 HACE ")


^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v1 02/22] hw/misc/aspeed_hace: Fix buffer overflow in has_padding function
  2025-03-21  9:47   ` Jamin Lin
@ 2025-03-22 20:52     ` Cédric Le Goater
  0 siblings, 0 replies; 71+ messages in thread
From: Cédric Le Goater @ 2025-03-22 20:52 UTC (permalink / raw)
  To: Jamin Lin, Peter Maydell, Steven Lee, Troy Lee, Andrew Jeffery,
	Joel Stanley, Fabiano Rosas, Laurent Vivier, Paolo Bonzini,
	open list:ASPEED BMCs, open list:All patches CC here
  Cc: Troy Lee

On 3/21/25 10:47, Jamin Lin wrote:
> Hi Cedric,
> 
>> Subject: [PATCH v1 02/22] hw/misc/aspeed_hace: Fix buffer overflow in
>> has_padding function
>>
>> The maximum padding size is either 64 or 128 bytes and should always be
>> smaller than "req_len". If "padding_size" exceeds "req_len", then "req_len -
>> padding_size" underflows due to "uint32_t" data type, leading to a large
>> incorrect value (e.g., `0xFFXXXXXX`). This causes an out-of-bounds memory
>> access, potentially leading to a buffer overflow.
>>
>> Added a check to ensure "padding_size" does not exceed "req_len" before
>> computing "pad_offset". This prevents "req_len - padding_size" from
>> underflowing and avoids accessing invalid memory.
>>
>> Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
>> ---
>>   hw/misc/aspeed_hace.c | 5 +++++
>>   1 file changed, 5 insertions(+)
>>
>> diff --git a/hw/misc/aspeed_hace.c b/hw/misc/aspeed_hace.c index
>> 8e7e8113a5..d8b5f048bb 100644
>> --- a/hw/misc/aspeed_hace.c
>> +++ b/hw/misc/aspeed_hace.c
>> @@ -128,6 +128,11 @@ static bool has_padding(AspeedHACEState *s, struct
>> iovec *iov,
>>       if (*total_msg_len <= s->total_req_len) {
>>           uint32_t padding_size = s->total_req_len - *total_msg_len;
>>           uint8_t *padding = iov->iov_base;
>> +
>> +        if (padding_size > req_len) {
>> +            return false;
>> +        }
>> +
>>           *pad_offset = req_len - padding_size;
>>           if (padding[*pad_offset] == 0x80) {
>>               return true;
>> --
>> 2.43.0
> 
> Fixes: 5cd7d8564a8b563da724b9e6264c967f0a091afa ("aspeed/hace: Support AST2600 HACE ")



Reviewed-by: Cédric Le Goater <clg@redhat.com>

Thanks,

C.




^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v1 01/22] hw/misc/aspeed_hace: Remove unused code for better readability
  2025-03-21  9:25 ` [PATCH v1 01/22] hw/misc/aspeed_hace: Remove unused code for better readability Jamin Lin via
@ 2025-04-01 13:08   ` Cédric Le Goater
  2025-05-05  3:28     ` Jamin Lin
  0 siblings, 1 reply; 71+ messages in thread
From: Cédric Le Goater @ 2025-04-01 13:08 UTC (permalink / raw)
  To: Jamin Lin, Peter Maydell, Steven Lee, Troy Lee, Andrew Jeffery,
	Joel Stanley, Fabiano Rosas, Laurent Vivier, Paolo Bonzini,
	open list:ASPEED BMCs, open list:All patches CC here
  Cc: troy_lee

On 3/21/25 10:25, Jamin Lin wrote:
> This cleanup follows significant changes in commit 4c1d0af4a28d, making the
> model more readable.
> 
> - Deleted "iov_cache" and "iov_count" from "AspeedHACEState".

It would be good to say why we can remove these. I think this is because
s->iov_count is always zero, right ?

> - Removed "reconstruct_iov" function and related logic.
> - Simplified "do_hash_operation" by eliminating redundant checks.
> 
> Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
> ---
>   include/hw/misc/aspeed_hace.h |  2 --
>   hw/misc/aspeed_hace.c         | 35 -----------------------------------
>   2 files changed, 37 deletions(-)
> 
> diff --git a/include/hw/misc/aspeed_hace.h b/include/hw/misc/aspeed_hace.h
> index 5d4aa19cfe..b69a038d35 100644
> --- a/include/hw/misc/aspeed_hace.h
> +++ b/include/hw/misc/aspeed_hace.h
> @@ -31,10 +31,8 @@ struct AspeedHACEState {
>       MemoryRegion iomem;
>       qemu_irq irq;
>   
> -    struct iovec iov_cache[ASPEED_HACE_MAX_SG];
>       uint32_t regs[ASPEED_HACE_NR_REGS];
>       uint32_t total_req_len;
> -    uint32_t iov_count;
>   
>       MemoryRegion *dram_mr;
>       AddressSpace dram_as;
> diff --git a/hw/misc/aspeed_hace.c b/hw/misc/aspeed_hace.c
> index 32a5dbded3..8e7e8113a5 100644
> --- a/hw/misc/aspeed_hace.c
> +++ b/hw/misc/aspeed_hace.c
> @@ -137,25 +137,6 @@ static bool has_padding(AspeedHACEState *s, struct iovec *iov,
>       return false;
>   }
>   
> -static int reconstruct_iov(AspeedHACEState *s, struct iovec *iov, int id,
> -                           uint32_t *pad_offset)
> -{
> -    int i, iov_count;
> -    if (*pad_offset != 0) {
> -        s->iov_cache[s->iov_count].iov_base = iov[id].iov_base;
> -        s->iov_cache[s->iov_count].iov_len = *pad_offset;
> -        ++s->iov_count;
> -    }
> -    for (i = 0; i < s->iov_count; i++) {
> -        iov[i].iov_base = s->iov_cache[i].iov_base;
> -        iov[i].iov_len = s->iov_cache[i].iov_len;
> -    }
> -    iov_count = s->iov_count;
> -    s->iov_count = 0;
> -    s->total_req_len = 0;
> -    return iov_count;
> -}
> -
>   static void do_hash_operation(AspeedHACEState *s, int algo, bool sg_mode,
>                                 bool acc_mode)
>   {
> @@ -237,19 +218,6 @@ static void do_hash_operation(AspeedHACEState *s, int algo, bool sg_mode,
>           iov[0].iov_base = haddr;
>           iov[0].iov_len = len;
>           i = 1;
> -
> -        if (s->iov_count) {
> -            /*
> -             * In aspeed sdk kernel driver, sg_mode is disabled in hash_final().
> -             * Thus if we received a request with sg_mode disabled, it is
> -             * required to check whether cache is empty. If no, we should
> -             * combine cached iov and the current iov.
> -             */
> -            s->total_req_len += len;
> -            if (has_padding(s, iov, len, &total_msg_len, &pad_offset)) {
> -                i = reconstruct_iov(s, iov, 0, &pad_offset);
> -            }
> -        }
>       }
>   
>       if (acc_mode) {
> @@ -273,7 +241,6 @@ static void do_hash_operation(AspeedHACEState *s, int algo, bool sg_mode,
>               qcrypto_hash_free(s->hash_ctx);
>   
>               s->hash_ctx = NULL;
> -            s->iov_count = 0;
>               s->total_req_len = 0;
>           }
>       } else if (qcrypto_hash_bytesv(algo, iov, i, &digest_buf,
> @@ -432,7 +399,6 @@ static void aspeed_hace_reset(DeviceState *dev)
>       }
>   
>       memset(s->regs, 0, sizeof(s->regs));
> -    s->iov_count = 0;
>       s->total_req_len = 0;
>   }
>   
> @@ -469,7 +435,6 @@ static const VMStateDescription vmstate_aspeed_hace = {
>       .fields = (const VMStateField[]) {
>           VMSTATE_UINT32_ARRAY(regs, AspeedHACEState, ASPEED_HACE_NR_REGS),
>           VMSTATE_UINT32(total_req_len, AspeedHACEState),
> -        VMSTATE_UINT32(iov_count, AspeedHACEState),

This is a vmstate change which is breaking migration compatibility.
We could preserve compatibility [1] but I think this is overkill.
However, we should say so. Please add a comment in the commit log.

Thanks,

C.

[1] https://qemu.readthedocs.io/en/v9.2.0/devel/migration/main.html#vmstate

>           VMSTATE_END_OF_LIST(),
>       }
>   };



^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v1 03/22] hw/misc/aspeed_hace: Improve readability and consistency in variable naming
  2025-03-21  9:25 ` [PATCH v1 03/22] hw/misc/aspeed_hace: Improve readability and consistency in variable naming Jamin Lin via
@ 2025-04-01 13:17   ` Cédric Le Goater
  2025-05-09  6:57     ` Jamin Lin
  0 siblings, 1 reply; 71+ messages in thread
From: Cédric Le Goater @ 2025-04-01 13:17 UTC (permalink / raw)
  To: Jamin Lin, Peter Maydell, Steven Lee, Troy Lee, Andrew Jeffery,
	Joel Stanley, Fabiano Rosas, Laurent Vivier, Paolo Bonzini,
	open list:ASPEED BMCs, open list:All patches CC here
  Cc: troy_lee

On 3/21/25 10:25, Jamin Lin wrote:
> Currently, users define multiple local variables within different if-statements.
> To improve readability and maintain consistency in variable naming, rename the
> variables accordingly.
> Introduced "sg_addr" to clearly indicate the scatter-gather mode buffer address.
> 
> Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>


The change look OK. do_hash_operation() is a big routine, difficult
to read. It does stuff like :

     if (sg_mode) {
	    ...
     } else {
	    ...
     }

     if (acc_mode) {
	    ...
     } else {
	    ...
     }
     ...

I think we should also split it in multiple routines to reduce the
complexity, even if some part are redundant.

Thanks,

C.



> --->   hw/misc/aspeed_hace.c | 33 ++++++++++++++++-----------------
>   1 file changed, 16 insertions(+), 17 deletions(-)
> 
> diff --git a/hw/misc/aspeed_hace.c b/hw/misc/aspeed_hace.c
> index d8b5f048bb..4bcf6ed074 100644
> --- a/hw/misc/aspeed_hace.c
> +++ b/hw/misc/aspeed_hace.c
> @@ -145,15 +145,19 @@ static bool has_padding(AspeedHACEState *s, struct iovec *iov,
>   static void do_hash_operation(AspeedHACEState *s, int algo, bool sg_mode,
>                                 bool acc_mode)
>   {
> +    bool sg_acc_mode_final_request = false;
> +    g_autofree uint8_t *digest_buf = NULL;
>       struct iovec iov[ASPEED_HACE_MAX_SG];
> +    Error *local_err = NULL;
>       uint32_t total_msg_len;
> -    uint32_t pad_offset;
> -    g_autofree uint8_t *digest_buf = NULL;
>       size_t digest_len = 0;
> -    bool sg_acc_mode_final_request = false;
> -    int i;
> +    uint32_t sg_addr = 0;
> +    uint32_t pad_offset;
> +    uint32_t len = 0;
> +    uint32_t src = 0;
>       void *haddr;
> -    Error *local_err = NULL;
> +    hwaddr plen;
> +    int i;
>   
>       if (acc_mode && s->hash_ctx == NULL) {
>           s->hash_ctx = qcrypto_hash_new(algo, &local_err);
> @@ -166,12 +170,7 @@ static void do_hash_operation(AspeedHACEState *s, int algo, bool sg_mode,
>       }
>   
>       if (sg_mode) {
> -        uint32_t len = 0;
> -
>           for (i = 0; !(len & SG_LIST_LEN_LAST); i++) {
> -            uint32_t addr, src;
> -            hwaddr plen;
> -
>               if (i == ASPEED_HACE_MAX_SG) {
>                   qemu_log_mask(LOG_GUEST_ERROR,
>                           "aspeed_hace: guest failed to set end of sg list marker\n");
> @@ -183,12 +182,12 @@ static void do_hash_operation(AspeedHACEState *s, int algo, bool sg_mode,
>               len = address_space_ldl_le(&s->dram_as, src,
>                                          MEMTXATTRS_UNSPECIFIED, NULL);
>   
> -            addr = address_space_ldl_le(&s->dram_as, src + SG_LIST_LEN_SIZE,
> -                                        MEMTXATTRS_UNSPECIFIED, NULL);
> -            addr &= SG_LIST_ADDR_MASK;
> +            sg_addr = address_space_ldl_le(&s->dram_as, src + SG_LIST_LEN_SIZE,
> +                                           MEMTXATTRS_UNSPECIFIED, NULL);
> +            sg_addr &= SG_LIST_ADDR_MASK;
>   
>               plen = len & SG_LIST_LEN_MASK;
> -            haddr = address_space_map(&s->dram_as, addr, &plen, false,
> +            haddr = address_space_map(&s->dram_as, sg_addr, &plen, false,
>                                         MEMTXATTRS_UNSPECIFIED);
>               if (haddr == NULL) {
>                   qemu_log_mask(LOG_GUEST_ERROR,
> @@ -212,16 +211,16 @@ static void do_hash_operation(AspeedHACEState *s, int algo, bool sg_mode,
>               }
>           }
>       } else {
> -        hwaddr len = s->regs[R_HASH_SRC_LEN];
> +        plen = s->regs[R_HASH_SRC_LEN];
>   
>           haddr = address_space_map(&s->dram_as, s->regs[R_HASH_SRC],
> -                                  &len, false, MEMTXATTRS_UNSPECIFIED);
> +                                  &plen, false, MEMTXATTRS_UNSPECIFIED);
>           if (haddr == NULL) {
>               qemu_log_mask(LOG_GUEST_ERROR, "%s: qcrypto failed\n", __func__);
>               return;
>           }
>           iov[0].iov_base = haddr;
> -        iov[0].iov_len = len;
> +        iov[0].iov_len = plen;
>           i = 1;
>       }
>   



^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v1 04/22] hw/misc/aspeed_hace: Update hash source address handling to 64-bit for AST2700
  2025-03-21  9:26 ` [PATCH v1 04/22] hw/misc/aspeed_hace: Update hash source address handling to 64-bit for AST2700 Jamin Lin via
@ 2025-04-01 13:52   ` Cédric Le Goater
  2025-05-09  6:49     ` Jamin Lin
  0 siblings, 1 reply; 71+ messages in thread
From: Cédric Le Goater @ 2025-04-01 13:52 UTC (permalink / raw)
  To: Jamin Lin, Peter Maydell, Steven Lee, Troy Lee, Andrew Jeffery,
	Joel Stanley, Fabiano Rosas, Laurent Vivier, Paolo Bonzini,
	open list:ASPEED BMCs, open list:All patches CC here
  Cc: troy_lee

On 3/21/25 10:26, Jamin Lin wrote:
> The AST2700 CPU, based on the Cortex-A35, is a 64-bit processor, and its DRAM
> address space is also 64-bit. To support future AST2700 updates, the source
> hash buffer address data type is being updated to 64-bit.
> 
> Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
> ---
>   hw/misc/aspeed_hace.c | 8 +++++---
>   1 file changed, 5 insertions(+), 3 deletions(-)
> 
> diff --git a/hw/misc/aspeed_hace.c b/hw/misc/aspeed_hace.c
> index 4bcf6ed074..9771d6e490 100644
> --- a/hw/misc/aspeed_hace.c
> +++ b/hw/misc/aspeed_hace.c
> @@ -154,7 +154,7 @@ static void do_hash_operation(AspeedHACEState *s, int algo, bool sg_mode,
>       uint32_t sg_addr = 0;
>       uint32_t pad_offset;
>       uint32_t len = 0;
> -    uint32_t src = 0;
> +    uint64_t src = 0;
>       void *haddr;
>       hwaddr plen;
>       int i;
> @@ -177,7 +177,8 @@ static void do_hash_operation(AspeedHACEState *s, int algo, bool sg_mode,
>                   break;
>               }
>   
> -            src = s->regs[R_HASH_SRC] + (i * SG_LIST_ENTRY_SIZE);
> +            src = deposit64(src, 0, 32, s->regs[R_HASH_SRC]);

I would introduce an helper routine to return the hash 'src' address.
More changes are expected in the following patches.

Why is the initial hash 'src' address assigned in the loop ? This
could done before looping on the scatter-gather list elements.

Also should this address be aligned to some size ?


Thanks,

C.




> +            src += i * SG_LIST_ENTRY_SIZE;
>   
>               len = address_space_ldl_le(&s->dram_as, src,
>                                          MEMTXATTRS_UNSPECIFIED, NULL);
> @@ -212,8 +213,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]);
>   
> -        haddr = address_space_map(&s->dram_as, s->regs[R_HASH_SRC],
> +        haddr = address_space_map(&s->dram_as, src,
>                                     &plen, false, MEMTXATTRS_UNSPECIFIED);
>           if (haddr == NULL) {
>               qemu_log_mask(LOG_GUEST_ERROR, "%s: qcrypto failed\n", __func__);



^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v1 05/22] hw/misc/aspeed_hace: Introduce 64-bit digest_addr variable for AST2700
  2025-03-21  9:26 ` [PATCH v1 05/22] hw/misc/aspeed_hace: Introduce 64-bit digest_addr variable " Jamin Lin via
@ 2025-04-01 13:55   ` Cédric Le Goater
  2025-05-09  4:01     ` Jamin Lin
  0 siblings, 1 reply; 71+ messages in thread
From: Cédric Le Goater @ 2025-04-01 13:55 UTC (permalink / raw)
  To: Jamin Lin, Peter Maydell, Steven Lee, Troy Lee, Andrew Jeffery,
	Joel Stanley, Fabiano Rosas, Laurent Vivier, Paolo Bonzini,
	open list:ASPEED BMCs, open list:All patches CC here
  Cc: troy_lee

On 3/21/25 10:26, Jamin Lin wrote:
> The AST2700 CPU, based on the Cortex-A35, is a 64-bit processor with a 64-bit
> DRAM address space. To support future AST2700 updates, a new "digest_addr"
> variable is introduced with a 64-bit data type.
> 
> Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
> ---
>   hw/misc/aspeed_hace.c | 4 +++-
>   1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/misc/aspeed_hace.c b/hw/misc/aspeed_hace.c
> index 9771d6e490..8cf3f194a5 100644
> --- a/hw/misc/aspeed_hace.c
> +++ b/hw/misc/aspeed_hace.c
> @@ -148,6 +148,7 @@ static void do_hash_operation(AspeedHACEState *s, int algo, bool sg_mode,
>       bool sg_acc_mode_final_request = false;
>       g_autofree uint8_t *digest_buf = NULL;
>       struct iovec iov[ASPEED_HACE_MAX_SG];
> +    uint64_t digest_addr = 0;
>       Error *local_err = NULL;
>       uint32_t total_msg_len;
>       size_t digest_len = 0;
> @@ -257,7 +258,8 @@ static void do_hash_operation(AspeedHACEState *s, int algo, bool sg_mode,
>           return;
>       }
>   
> -    if (address_space_write(&s->dram_as, s->regs[R_HASH_DEST],
> +    digest_addr = deposit64(digest_addr, 0, 32, s->regs[R_HASH_DEST]);

As on the previous patch, an helper would be useful and is there
an alignment constraint ?


Thanks,

C.



> +    if (address_space_write(&s->dram_as, digest_addr,
>                               MEMTXATTRS_UNSPECIFIED,
>                               digest_buf, digest_len)) {
>           qemu_log_mask(LOG_GUEST_ERROR,



^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v1 06/22] hw/misc/aspeed_hace: Support accumulative mode for direct access mode
  2025-03-21  9:26 ` [PATCH v1 06/22] hw/misc/aspeed_hace: Support accumulative mode for direct access mode Jamin Lin via
@ 2025-04-01 13:57   ` Cédric Le Goater
  2025-05-09  6:55     ` Jamin Lin
  0 siblings, 1 reply; 71+ messages in thread
From: Cédric Le Goater @ 2025-04-01 13:57 UTC (permalink / raw)
  To: Jamin Lin, Peter Maydell, Steven Lee, Troy Lee, Andrew Jeffery,
	Joel Stanley, Fabiano Rosas, Laurent Vivier, Paolo Bonzini,
	open list:ASPEED BMCs, open list:All patches CC here
  Cc: troy_lee

On 3/21/25 10:26, Jamin Lin wrote:
> Enable accumulative mode for direct access mode operations. In direct access
> mode, only a single source buffer is used, so the "iovec" count is set to 1.
> If "acc_mode" is enabled:
> 1. Accumulate "total_req_len" with the current request length ("plen").
> 2. Check for padding and determine whether this is the final request.
> 
> Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
> ---
>   hw/misc/aspeed_hace.c | 15 ++++++++++++++-
>   1 file changed, 14 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/misc/aspeed_hace.c b/hw/misc/aspeed_hace.c
> index 8cf3f194a5..d06158dffd 100644
> --- a/hw/misc/aspeed_hace.c
> +++ b/hw/misc/aspeed_hace.c
> @@ -223,8 +223,21 @@ static void do_hash_operation(AspeedHACEState *s, int algo, bool sg_mode,
>               return;
>           }
>           iov[0].iov_base = haddr;
> -        iov[0].iov_len = plen;
>           i = 1;
> +        if (acc_mode) {

hmm, more complexity is being added to do_hash_operation(). I would introduce
a sub routine do_hash_operation_acc() to handle accumulative mode.

Thanks,

C.



> +            s->total_req_len += plen;
> +
> +            if (has_padding(s, &iov[0], plen, &total_msg_len,
> +                            &pad_offset)) {
> +                /* Padding being present indicates the final request */
> +                sg_acc_mode_final_request = true;
> +                iov[0].iov_len = pad_offset;
> +            } else {
> +                iov[0].iov_len = plen;
> +            }
> +        } else {
> +            iov[0].iov_len = plen;
> +        }
>       }
>   
>       if (acc_mode) {



^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v1 07/22] hw/misc/aspeed_hace: Add support for source, digest, key buffer 64 bit addresses
  2025-03-21  9:26 ` [PATCH v1 07/22] hw/misc/aspeed_hace: Add support for source, digest, key buffer 64 bit addresses Jamin Lin via
@ 2025-04-01 16:19   ` Cédric Le Goater
  2025-05-12  8:06     ` Jamin Lin
  0 siblings, 1 reply; 71+ messages in thread
From: Cédric Le Goater @ 2025-04-01 16:19 UTC (permalink / raw)
  To: Jamin Lin, Peter Maydell, Steven Lee, Troy Lee, Andrew Jeffery,
	Joel Stanley, Fabiano Rosas, Laurent Vivier, Paolo Bonzini,
	open list:ASPEED BMCs, open list:All patches CC here
  Cc: troy_lee

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

R_HASH_DIGEST_HIGH would be easier to understand.

> [63:32] and R_HASH_DEST storing bits [31:0]. The HMAC key buffer address is also
> 64-bit, with R_HASH_KEY_BUFF_HI storing bits [63:32] and R_HASH_KEY_BUFF storing
> bits [31:0].
> 
> The AST2700 supports a maximum DRAM size of 8 GB, with a DRAM addressable range
> from 0x0_0000_0000 to 0x1_FFFF_FFFF. Since this range fits within 34 bits, only
> bits [33:0] are needed to store the DRAM offset. To optimize address storage,
> the high physical address bits [1:0] of the source, digest and key buffer
> addresses are stored as dram_offset bits [33:32].
> 
> To achieve this, a src_hi_mask with a mask value of 0x3 is introduced, ensuring
> that src_addr_hi consists of bits [1:0]. The final src_addr is computed as
> (src_addr_hi[1:0] << 32) | src_addr[31:0], representing the DRAM offset within
> bits [33:0].
> 
> Similarly, a dest_hi_mask with a mask value of 0x3 is introduced to ensure that
> dest_addr_hi consists of bits [1:0]. The final dest_addr is calculated as
> (dest_addr_hi[1:0] << 32) | dest_addr[31:0], representing the DRAM offset within
> bits [33:0].
> 
> Additionally, a key_hi_mask with a mask value of 0x3 is introduced to ensure
> that key_buf_addr_hi consists of bits [1:0]. The final key_buf_addr is
> determined as (key_buf_addr_hi[1:0] << 32) | key_buf_addr[31:0], representing
> the DRAM offset within bits [33:0].

What does the datasheet say regarding the High Address registers ?
Are bits [1:0] RW and [31:2] RO ?

  
> This approach eliminates the need to reduce the high part of the DRAM physical
> address for DMA operations. Previously, this was calculated as
> (high physical address bits [7:0] - 4), since the DRAM start address is
> 0x4_00000000, making the high part address [7:0] - 4.

I don't understand this part. Is there a difference between AST2700
A0 and A1  ?

> 
> Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
> ---
>   include/hw/misc/aspeed_hace.h |  5 ++++-
>   hw/misc/aspeed_hace.c         | 29 +++++++++++++++++++++++++++++
>   2 files changed, 33 insertions(+), 1 deletion(-)
> 
> diff --git a/include/hw/misc/aspeed_hace.h b/include/hw/misc/aspeed_hace.h
> index b69a038d35..a4479bd383 100644
> --- a/include/hw/misc/aspeed_hace.h
> +++ b/include/hw/misc/aspeed_hace.h
> @@ -22,7 +22,7 @@
>   
>   OBJECT_DECLARE_TYPE(AspeedHACEState, AspeedHACEClass, ASPEED_HACE)
>   
> -#define ASPEED_HACE_NR_REGS (0x64 >> 2)
> +#define ASPEED_HACE_NR_REGS (0x9C >> 2)

I think we need a class attribute.

>   #define ASPEED_HACE_MAX_SG  256 /* max number of entries */
>   
>   struct AspeedHACEState {
> @@ -49,6 +49,9 @@ struct AspeedHACEClass {
>       uint32_t key_mask;
>       uint32_t hash_mask;
>       bool raise_crypt_interrupt_workaround;
> +    uint32_t src_hi_mask;
> +    uint32_t dest_hi_mask;
> +    uint32_t key_hi_mask;
>   };
>   
>   #endif /* ASPEED_HACE_H */
> diff --git a/hw/misc/aspeed_hace.c b/hw/misc/aspeed_hace.c
> index d06158dffd..51c6523fab 100644
> --- a/hw/misc/aspeed_hace.c
> +++ b/hw/misc/aspeed_hace.c
> @@ -30,6 +30,9 @@
>   #define R_HASH_DEST     (0x24 / 4)
>   #define R_HASH_KEY_BUFF (0x28 / 4)
>   #define R_HASH_SRC_LEN  (0x2c / 4)
> +#define R_HASH_SRC_HI      (0x90 / 4)
> +#define R_HASH_DEST_HI     (0x94 / 4)
> +#define R_HASH_KEY_BUFF_HI (0x98 / 4)
>   
>   #define R_HASH_CMD      (0x30 / 4)
>   /* Hash algorithm selection */
> @@ -393,6 +396,15 @@ static void aspeed_hace_write(void *opaque, hwaddr addr, uint64_t data,
>               }
>           }
>           break;
> +    case R_HASH_SRC_HI:
> +        data &= ahc->src_hi_mask;
> +        break;
> +    case R_HASH_DEST_HI:
> +        data &= ahc->dest_hi_mask;
> +        break;
> +    case R_HASH_KEY_BUFF_HI:
> +        data &= ahc->key_hi_mask;
> +        break;

This change exposes the high address registers to all SoCs which
is unfortunate.

I would introduce a class attribute to limit the number of registers
per SoC.

You could also size the MMIO aperture with this new attribute and
remove the "Out-of-bounds" message at the beginning of the read/write
memops.

Thanks,

C.



>       default:
>           break;
>       }
> @@ -566,6 +578,23 @@ static void aspeed_ast2700_hace_class_init(ObjectClass *klass, void *data)
>       ahc->key_mask = 0x7FFFFFF8;
>       ahc->hash_mask = 0x00147FFF;
>   
> +    /*
> +     * The AST2700 supports a maximum DRAM size of 8 GB, with a DRAM
> +     * addressable range from 0x0_0000_0000 to 0x1_FFFF_FFFF. Since this range
> +     * fits within 34 bits, only bits [33:0] are needed to store the DRAM
> +     * offset. To optimize address storage, the high physical address bits
> +     * [1:0] of the source, digest and key buffer addresses are stored as
> +     * dram_offset bits [33:32].
> +     *
> +     * This approach eliminates the need to reduce the high part of the DRAM
> +     * physical address for DMA operations. Previously, this was calculated as
> +     * (high physical address bits [7:0] - 4), since the DRAM start address is
> +     * 0x4_00000000, making the high part address [7:0] - 4.
> +     */
> +    ahc->src_hi_mask = 0x00000003;
> +    ahc->dest_hi_mask = 0x00000003;
> +    ahc->key_hi_mask = 0x00000003;
> +
>       /*
>        * Currently, it does not support the CRYPT command. Instead, it only
>        * sends an interrupt to notify the firmware that the crypt command



^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v1 08/22] hw/misc/aspeed_hace: Support DMA 64 bits dram address.
  2025-03-21  9:26 ` [PATCH v1 08/22] hw/misc/aspeed_hace: Support DMA 64 bits dram address Jamin Lin via
@ 2025-04-02  7:41   ` Cédric Le Goater
  2025-05-09  7:04     ` Jamin Lin
  0 siblings, 1 reply; 71+ messages in thread
From: Cédric Le Goater @ 2025-04-02  7:41 UTC (permalink / raw)
  To: Jamin Lin, Peter Maydell, Steven Lee, Troy Lee, Andrew Jeffery,
	Joel Stanley, Fabiano Rosas, Laurent Vivier, Paolo Bonzini,
	open list:ASPEED BMCs, open list:All patches CC here
  Cc: troy_lee

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_lin@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.

>               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.
> +             */

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


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 = {



^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v1 10/22] hw/misc/aspeed_hace:: Support setting different memory size
  2025-03-21  9:26 ` [PATCH v1 10/22] hw/misc/aspeed_hace:: Support setting different memory size Jamin Lin via
@ 2025-04-02  7:46   ` Cédric Le Goater
  0 siblings, 0 replies; 71+ messages in thread
From: Cédric Le Goater @ 2025-04-02  7:46 UTC (permalink / raw)
  To: Jamin Lin, Peter Maydell, Steven Lee, Troy Lee, Andrew Jeffery,
	Joel Stanley, Fabiano Rosas, Laurent Vivier, Paolo Bonzini,
	open list:ASPEED BMCs, open list:All patches CC here
  Cc: troy_lee

On 3/21/25 10:26, Jamin Lin wrote:
> The memory size was previously hardcoded to 0x1000 (4K). However, the actual
> memory size of the HACE controller varies across different models:
> 1. AST2400/AST2500: 0x1000 (4K)
> 2. AST2600/AST1030: 0x10000 (64K)
> 3. AST2700: 0x100 (256 bytes)
> 
> To address this, a new class attribute, mem_size, has been introduced to
> dynamically set the appropriate memory size for each HACE model, ensuring
> correct allocation across AST2400, AST2500, AST2600, AST1030 and AST2700.
> 
> Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>


Reviewed-by: Cédric Le Goater <clg@redhat.com>

Thanks,

C.


> ---
>   include/hw/misc/aspeed_hace.h | 1 +
>   hw/misc/aspeed_hace.c         | 8 +++++++-
>   2 files changed, 8 insertions(+), 1 deletion(-)
> 
> diff --git a/include/hw/misc/aspeed_hace.h b/include/hw/misc/aspeed_hace.h
> index 58fb66009a..db95f2fd4b 100644
> --- a/include/hw/misc/aspeed_hace.h
> +++ b/include/hw/misc/aspeed_hace.h
> @@ -53,6 +53,7 @@ struct AspeedHACEClass {
>       uint32_t dest_hi_mask;
>       uint32_t key_hi_mask;
>       bool has_dma64;
> +    uint64_t mem_size;
>   };
>   
>   #endif /* ASPEED_HACE_H */
> diff --git a/hw/misc/aspeed_hace.c b/hw/misc/aspeed_hace.c
> index d4f653670e..53b3b390e3 100644
> --- a/hw/misc/aspeed_hace.c
> +++ b/hw/misc/aspeed_hace.c
> @@ -463,11 +463,12 @@ static void aspeed_hace_realize(DeviceState *dev, Error **errp)
>   {
>       AspeedHACEState *s = ASPEED_HACE(dev);
>       SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
> +    AspeedHACEClass *ahc = ASPEED_HACE_GET_CLASS(s);
>   
>       sysbus_init_irq(sbd, &s->irq);
>   
>       memory_region_init_io(&s->iomem, OBJECT(s), &aspeed_hace_ops, s,
> -            TYPE_ASPEED_HACE, 0x1000);
> +            TYPE_ASPEED_HACE, ahc->mem_size);
>   
>       if (!s->dram_mr) {
>           error_setg(errp, TYPE_ASPEED_HACE ": 'dram' link not set");
> @@ -521,6 +522,7 @@ static void aspeed_ast2400_hace_class_init(ObjectClass *klass, void *data)
>   
>       dc->desc = "AST2400 Hash and Crypto Engine";
>   
> +    ahc->mem_size = 0x1000;
>       ahc->src_mask = 0x0FFFFFFF;
>       ahc->dest_mask = 0x0FFFFFF8;
>       ahc->key_mask = 0x0FFFFFC0;
> @@ -540,6 +542,7 @@ static void aspeed_ast2500_hace_class_init(ObjectClass *klass, void *data)
>   
>       dc->desc = "AST2500 Hash and Crypto Engine";
>   
> +    ahc->mem_size = 0x1000;
>       ahc->src_mask = 0x3fffffff;
>       ahc->dest_mask = 0x3ffffff8;
>       ahc->key_mask = 0x3FFFFFC0;
> @@ -559,6 +562,7 @@ static void aspeed_ast2600_hace_class_init(ObjectClass *klass, void *data)
>   
>       dc->desc = "AST2600 Hash and Crypto Engine";
>   
> +    ahc->mem_size = 0x10000;
>       ahc->src_mask = 0x7FFFFFFF;
>       ahc->dest_mask = 0x7FFFFFF8;
>       ahc->key_mask = 0x7FFFFFF8;
> @@ -578,6 +582,7 @@ static void aspeed_ast1030_hace_class_init(ObjectClass *klass, void *data)
>   
>       dc->desc = "AST1030 Hash and Crypto Engine";
>   
> +    ahc->mem_size = 0x10000;
>       ahc->src_mask = 0x7FFFFFFF;
>       ahc->dest_mask = 0x7FFFFFF8;
>       ahc->key_mask = 0x7FFFFFF8;
> @@ -597,6 +602,7 @@ static void aspeed_ast2700_hace_class_init(ObjectClass *klass, void *data)
>   
>       dc->desc = "AST2700 Hash and Crypto Engine";
>   
> +    ahc->mem_size = 0x100;
>       ahc->src_mask = 0x7FFFFFFF;
>       ahc->dest_mask = 0x7FFFFFF8;
>       ahc->key_mask = 0x7FFFFFF8;



^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v1 11/22] hw/misc/aspeed_hace: Add trace-events for better debugging
  2025-03-21  9:26 ` [PATCH v1 11/22] hw/misc/aspeed_hace: Add trace-events for better debugging Jamin Lin via
@ 2025-04-02  7:59   ` Cédric Le Goater
  2025-05-12  1:34     ` Jamin Lin
  0 siblings, 1 reply; 71+ messages in thread
From: Cédric Le Goater @ 2025-04-02  7:59 UTC (permalink / raw)
  To: Jamin Lin, Peter Maydell, Steven Lee, Troy Lee, Andrew Jeffery,
	Joel Stanley, Fabiano Rosas, Laurent Vivier, Paolo Bonzini,
	open list:ASPEED BMCs, open list:All patches CC here
  Cc: troy_lee

On 3/21/25 10:26, Jamin Lin wrote:
> Introduced "trace_aspeed_hace_addr", "trace_aspeed_hace_sg",
> "trace_aspeed_hace_read", and "trace_aspeed_hace_write" trace events.
> 
> Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
> ---
>   hw/misc/aspeed_hace.c | 8 ++++++++
>   hw/misc/trace-events  | 6 ++++++
>   2 files changed, 14 insertions(+)
> 
> diff --git a/hw/misc/aspeed_hace.c b/hw/misc/aspeed_hace.c
> index 53b3b390e3..b8e473ee3f 100644
> --- a/hw/misc/aspeed_hace.c
> +++ b/hw/misc/aspeed_hace.c
> @@ -18,6 +18,7 @@
>   #include "crypto/hash.h"
>   #include "hw/qdev-properties.h"
>   #include "hw/irq.h"
> +#include "trace.h"
>   
>   #define R_CRYPT_CMD     (0x10 / 4)
>   
> @@ -186,6 +187,7 @@ static void do_hash_operation(AspeedHACEState *s, int algo, bool sg_mode,
>               if (ahc->has_dma64) {
>                   src = deposit64(src, 32, 32, s->regs[R_HASH_SRC_HI]);
>               }
> +            trace_aspeed_hace_addr("src", src);
>               src += i * SG_LIST_ENTRY_SIZE;
>   
>               len = address_space_ldl_le(&s->dram_as, src,
> @@ -194,6 +196,7 @@ 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;
> +            trace_aspeed_hace_sg(i, sg_addr, len);
>               /*
>                * Ideally, sg_addr should be 64-bit for the AST2700, using the
>                * following program to obtain the 64-bit sg_addr and convert it
> @@ -237,6 +240,7 @@ 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]);
> +        trace_aspeed_hace_addr("src", src);
>           if (ahc->has_dma64) {
>               src = deposit64(src, 32, 32, s->regs[R_HASH_SRC_HI]);
>           }
> @@ -299,6 +303,7 @@ static void do_hash_operation(AspeedHACEState *s, int algo, bool sg_mode,
>       if (ahc->has_dma64) {
>           digest_addr = deposit64(digest_addr, 32, 32, s->regs[R_HASH_DEST_HI]);
>       }
> +    trace_aspeed_hace_addr("digest", digest_addr);
>       if (address_space_write(&s->dram_as, digest_addr,
>                               MEMTXATTRS_UNSPECIFIED,
>                               digest_buf, digest_len)) {

I would use the prefix 'trace_aspeed_hace_hash_addr' since the trace
events are called from do_hash_operation()


Thanks,

C.



> @@ -326,6 +331,7 @@ static uint64_t aspeed_hace_read(void *opaque, hwaddr addr, unsigned int size)
>           return 0;
>       }
>   
> +    trace_aspeed_hace_read(addr << 2, s->regs[addr]);
>       return s->regs[addr];
>   }
>   
> @@ -344,6 +350,8 @@ static void aspeed_hace_write(void *opaque, hwaddr addr, uint64_t data,
>           return;
>       }
>   
> +    trace_aspeed_hace_write(addr << 2, data);
> +
>       switch (addr) {
>       case R_STATUS:
>           if (data & HASH_IRQ) {
> diff --git a/hw/misc/trace-events b/hw/misc/trace-events
> index 4383808d7a..cf96e68cfa 100644
> --- a/hw/misc/trace-events
> +++ b/hw/misc/trace-events
> @@ -302,6 +302,12 @@ aspeed_peci_read(uint64_t offset, uint64_t data) "offset 0x%" PRIx64 " data 0x%"
>   aspeed_peci_write(uint64_t offset, uint64_t data) "offset 0x%" PRIx64 " data 0x%" PRIx64
>   aspeed_peci_raise_interrupt(uint32_t ctrl, uint32_t status) "ctrl 0x%" PRIx32 " status 0x%" PRIx32
>   
> +# aspeed_hace.c
> +aspeed_hace_read(uint64_t offset, uint64_t data) "offset 0x%" PRIx64 " data 0x%" PRIx64
> +aspeed_hace_write(uint64_t offset, uint64_t data) "offset 0x%" PRIx64 " data 0x%" PRIx64
> +aspeed_hace_sg(int index, uint64_t addr, uint32_t len) "%d: addr 0x%" PRIx64 " len 0x%" PRIx32
> +aspeed_hace_addr(const char *s, uint64_t addr) "%s: 0x%" PRIx64
> +
>   # bcm2835_property.c
>   bcm2835_mbox_property(uint32_t tag, uint32_t bufsize, size_t resplen) "mbox property tag:0x%08x in_sz:%u out_sz:%zu"
>   



^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v1 12/22] hw/misc/aspeed_hace Support to dump plaintext and digest for better debugging
  2025-03-21  9:26 ` [PATCH v1 12/22] hw/misc/aspeed_hace Support to dump plaintext and digest " Jamin Lin via
@ 2025-04-02  8:05   ` Cédric Le Goater
  2025-05-12  5:22     ` Jamin Lin
  0 siblings, 1 reply; 71+ messages in thread
From: Cédric Le Goater @ 2025-04-02  8:05 UTC (permalink / raw)
  To: Jamin Lin, Peter Maydell, Steven Lee, Troy Lee, Andrew Jeffery,
	Joel Stanley, Fabiano Rosas, Laurent Vivier, Paolo Bonzini,
	open list:ASPEED BMCs, open list:All patches CC here
  Cc: troy_lee

On 3/21/25 10:26, Jamin Lin wrote:
> 1. Disabled by default. Uncomment "#define DEBUG_HACE 1" to enable it.
> 2. Uses the "qemu_hexdump" API to dump the digest result.
> 3. Uses the "iov_hexdump" API to dump the source vector, which contains the
>     source plaintext.
> 
> Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
> ---
>   hw/misc/aspeed_hace.c | 12 ++++++++++++
>   1 file changed, 12 insertions(+)
> 
> diff --git a/hw/misc/aspeed_hace.c b/hw/misc/aspeed_hace.c
> index b8e473ee3f..ae4d2fa687 100644
> --- a/hw/misc/aspeed_hace.c
> +++ b/hw/misc/aspeed_hace.c
> @@ -10,8 +10,10 @@
>    */
>   
>   #include "qemu/osdep.h"
> +#include "qemu/cutils.h"
>   #include "qemu/log.h"
>   #include "qemu/error-report.h"
> +#include "qemu/iov.h"
>   #include "hw/misc/aspeed_hace.h"
>   #include "qapi/error.h"
>   #include "migration/vmstate.h"
> @@ -20,6 +22,8 @@
>   #include "hw/irq.h"
>   #include "trace.h"
>   
> +/* #define DEBUG_HACE 1 */
> +
>   #define R_CRYPT_CMD     (0x10 / 4)
>   
>   #define R_STATUS        (0x1c / 4)
> @@ -268,6 +272,10 @@ static void do_hash_operation(AspeedHACEState *s, int algo, bool sg_mode,
>           }
>       }
>   
> +#ifdef DEBUG_HACE

Could we use a trace instead ? See trace_event_get_state_backends()
for complex traces and qemu_hexdump_to_buffer() ?


Thanks,

C.




> +    iov_hexdump(iov, i, stdout, "plaintext", 0xa000);
> +#endif
> +
>       if (acc_mode) {
>           if (qcrypto_hash_updatev(s->hash_ctx, iov, i, &local_err) < 0) {
>               qemu_log_mask(LOG_GUEST_ERROR, "qcrypto hash update failed : %s",
> @@ -311,6 +319,10 @@ static void do_hash_operation(AspeedHACEState *s, int algo, bool sg_mode,
>                         "aspeed_hace: address space write failed\n");
>       }
>   
> +#ifdef DEBUG_HACE
> +    qemu_hexdump(stdout, "digest", digest_buf, digest_len);
> +#endif
> +
>       for (; i > 0; i--) {
>           address_space_unmap(&s->dram_as, iov[i - 1].iov_base,
>                               iov[i - 1].iov_len, false,



^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v1 13/22] test/qtest: Introduce a new aspeed-hace-utils.c to place common testcases
  2025-03-21  9:26 ` [PATCH v1 13/22] test/qtest: Introduce a new aspeed-hace-utils.c to place common testcases Jamin Lin via
@ 2025-04-02  8:54   ` Cédric Le Goater
  2025-05-05  6:42     ` Jamin Lin
  0 siblings, 1 reply; 71+ messages in thread
From: Cédric Le Goater @ 2025-04-02  8:54 UTC (permalink / raw)
  To: Jamin Lin, Peter Maydell, Steven Lee, Troy Lee, Andrew Jeffery,
	Joel Stanley, Fabiano Rosas, Laurent Vivier, Paolo Bonzini,
	open list:ASPEED BMCs, open list:All patches CC here
  Cc: troy_lee

On 3/21/25 10:26, Jamin Lin wrote:
> The test cases for the ASPEED HACE model were originally placed in
> aspeed_hace-test.c. However, this test file only supports ARM32. To enable
> compatibility with all ASPEED SoCs, including the AST2700, which uses the
> AArch64 architecture, this update introduces a new source file,
> aspeed-hace-utils.c.
> 
> All common APIs and test cases have been moved from aspeed_hace-test.c to
> aspeed-hace-utils.c to facilitate reuse across different ASPEED SoCs.
> As a result, these test cases can now be reused for AST2700 and future ASPEED
> SoC testing.
> 
> Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>

One comment, the digest reference arrays should have fixed sizes.

Looks ok :

0000000000085fa0 l     O .rodata	0000000000000020              test_result_accum_sha256
0000000000085fc0 l     O .rodata	0000000000000040              test_result_accum_sha512
00000000000860c0 l     O .rodata	0000000000000020              test_result_sg_sha256
00000000000860e0 l     O .rodata	0000000000000040              test_result_sg_sha512
0000000000086130 l     O .rodata	0000000000000010              test_result_md5
0000000000086140 l     O .rodata	0000000000000020              test_result_sha256
0000000000086160 l     O .rodata	0000000000000040              test_result_sha512

but it would be safer add a size when the array is defined.

Anyhow, this is for another patch.


Reviewed-by: Cédric Le Goater <clg@redhat.com>

Thanks,

C.


> ---
>   tests/qtest/aspeed-hace-utils.h |  71 +++++
>   tests/qtest/aspeed-hace-utils.c | 455 ++++++++++++++++++++++++++++
>   tests/qtest/aspeed_hace-test.c  | 515 ++------------------------------
>   tests/qtest/meson.build         |   1 +
>   4 files changed, 547 insertions(+), 495 deletions(-)
>   create mode 100644 tests/qtest/aspeed-hace-utils.h
>   create mode 100644 tests/qtest/aspeed-hace-utils.c
> 
> diff --git a/tests/qtest/aspeed-hace-utils.h b/tests/qtest/aspeed-hace-utils.h
> new file mode 100644
> index 0000000000..598577c69b
> --- /dev/null
> +++ b/tests/qtest/aspeed-hace-utils.h
> @@ -0,0 +1,71 @@
> +/*
> + * QTest testcase for the ASPEED Hash and Crypto Engine
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + * Copyright 2021 IBM Corp.
> + */
> +
> +#ifndef TESTS_ASPEED_HACE_UTILS_H
> +#define TESTS_ASPEED_HACE_UTILS_H
> +
> +#include "qemu/osdep.h"
> +#include "libqtest.h"
> +#include "qemu/bitops.h"
> +
> +#define HACE_CMD                 0x10
> +#define  HACE_SHA_BE_EN          BIT(3)
> +#define  HACE_MD5_LE_EN          BIT(2)
> +#define  HACE_ALGO_MD5           0
> +#define  HACE_ALGO_SHA1          BIT(5)
> +#define  HACE_ALGO_SHA224        BIT(6)
> +#define  HACE_ALGO_SHA256        (BIT(4) | BIT(6))
> +#define  HACE_ALGO_SHA512        (BIT(5) | BIT(6))
> +#define  HACE_ALGO_SHA384        (BIT(5) | BIT(6) | BIT(10))
> +#define  HACE_SG_EN              BIT(18)
> +#define  HACE_ACCUM_EN           BIT(8)
> +
> +#define HACE_STS                 0x1c
> +#define  HACE_RSA_ISR            BIT(13)
> +#define  HACE_CRYPTO_ISR         BIT(12)
> +#define  HACE_HASH_ISR           BIT(9)
> +#define  HACE_RSA_BUSY           BIT(2)
> +#define  HACE_CRYPTO_BUSY        BIT(1)
> +#define  HACE_HASH_BUSY          BIT(0)
> +#define HACE_HASH_SRC            0x20
> +#define HACE_HASH_DIGEST         0x24
> +#define HACE_HASH_KEY_BUFF       0x28
> +#define HACE_HASH_DATA_LEN       0x2c
> +#define HACE_HASH_CMD            0x30
> +
> +/* Scatter-Gather Hash */
> +#define SG_LIST_LEN_LAST         BIT(31)
> +struct AspeedSgList {
> +        uint32_t len;
> +        uint32_t addr;
> +} __attribute__ ((__packed__));
> +
> +struct AspeedMasks {
> +    uint32_t src;
> +    uint32_t dest;
> +    uint32_t len;
> +};
> +
> +void aspeed_test_md5(const char *machine, const uint32_t base,
> +                     const uint32_t src_addr);
> +void aspeed_test_sha256(const char *machine, const uint32_t base,
> +                        const uint32_t src_addr);
> +void aspeed_test_sha512(const char *machine, const uint32_t base,
> +                        const uint32_t src_addr);
> +void aspeed_test_sha256_sg(const char *machine, const uint32_t base,
> +                           const uint32_t src_addr);
> +void aspeed_test_sha512_sg(const char *machine, const uint32_t base,
> +                           const uint32_t src_addr);
> +void aspeed_test_sha256_accum(const char *machine, const uint32_t base,
> +                              const uint32_t src_addr);
> +void aspeed_test_sha512_accum(const char *machine, const uint32_t base,
> +                              const uint32_t src_addr);
> +void aspeed_test_addresses(const char *machine, const uint32_t base,
> +                           const struct AspeedMasks *expected);
> +
> +#endif /* TESTS_ASPEED_HACE_UTILS_H */
> +
> diff --git a/tests/qtest/aspeed-hace-utils.c b/tests/qtest/aspeed-hace-utils.c
> new file mode 100644
> index 0000000000..8582847945
> --- /dev/null
> +++ b/tests/qtest/aspeed-hace-utils.c
> @@ -0,0 +1,455 @@
> +/*
> + * QTest testcase for the ASPEED Hash and Crypto Engine
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + * Copyright 2021 IBM Corp.
> + */
> +
> +#include "qemu/osdep.h"
> +#include "libqtest.h"
> +#include "qemu/bitops.h"
> +#include "aspeed-hace-utils.h"
> +
> +/*
> + * Test vector is the ascii "abc"
> + *
> + * Expected results were generated using command line utitiles:
> + *
> + *  echo -n -e 'abc' | dd of=/tmp/test
> + *  for hash in sha512sum sha256sum md5sum; do $hash /tmp/test; done
> + *
> + */
> +static const uint8_t test_vector[] = {0x61, 0x62, 0x63};
> +
> +static const uint8_t test_result_sha512[] = {
> +    0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba, 0xcc, 0x41, 0x73, 0x49,
> +    0xae, 0x20, 0x41, 0x31, 0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2,
> +    0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a, 0x21, 0x92, 0x99, 0x2a,
> +    0x27, 0x4f, 0xc1, 0xa8, 0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd,
> +    0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e, 0x2a, 0x9a, 0xc9, 0x4f,
> +    0xa5, 0x4c, 0xa4, 0x9f};
> +
> +static const uint8_t test_result_sha256[] = {
> +    0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, 0xde,
> +    0x5d, 0xae, 0x22, 0x23, 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
> +    0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad};
> +
> +static const uint8_t test_result_md5[] = {
> +    0x90, 0x01, 0x50, 0x98, 0x3c, 0xd2, 0x4f, 0xb0, 0xd6, 0x96, 0x3f, 0x7d,
> +    0x28, 0xe1, 0x7f, 0x72};
> +
> +/*
> + * The Scatter-Gather Test vector is the ascii "abc" "def" "ghi", broken
> + * into blocks of 3 characters as shown
> + *
> + * Expected results were generated using command line utitiles:
> + *
> + *  echo -n -e 'abcdefghijkl' | dd of=/tmp/test
> + *  for hash in sha512sum sha256sum; do $hash /tmp/test; done
> + *
> + */
> +static const uint8_t test_vector_sg1[] = {0x61, 0x62, 0x63, 0x64, 0x65, 0x66};
> +static const uint8_t test_vector_sg2[] = {0x67, 0x68, 0x69};
> +static const uint8_t test_vector_sg3[] = {0x6a, 0x6b, 0x6c};
> +
> +static const uint8_t test_result_sg_sha512[] = {
> +    0x17, 0x80, 0x7c, 0x72, 0x8e, 0xe3, 0xba, 0x35, 0xe7, 0xcf, 0x7a, 0xf8,
> +    0x23, 0x11, 0x6d, 0x26, 0xe4, 0x1e, 0x5d, 0x4d, 0x6c, 0x2f, 0xf1, 0xf3,
> +    0x72, 0x0d, 0x3d, 0x96, 0xaa, 0xcb, 0x6f, 0x69, 0xde, 0x64, 0x2e, 0x63,
> +    0xd5, 0xb7, 0x3f, 0xc3, 0x96, 0xc1, 0x2b, 0xe3, 0x8b, 0x2b, 0xd5, 0xd8,
> +    0x84, 0x25, 0x7c, 0x32, 0xc8, 0xf6, 0xd0, 0x85, 0x4a, 0xe6, 0xb5, 0x40,
> +    0xf8, 0x6d, 0xda, 0x2e};
> +
> +static const uint8_t test_result_sg_sha256[] = {
> +    0xd6, 0x82, 0xed, 0x4c, 0xa4, 0xd9, 0x89, 0xc1, 0x34, 0xec, 0x94, 0xf1,
> +    0x55, 0x1e, 0x1e, 0xc5, 0x80, 0xdd, 0x6d, 0x5a, 0x6e, 0xcd, 0xe9, 0xf3,
> +    0xd3, 0x5e, 0x6e, 0x4a, 0x71, 0x7f, 0xbd, 0xe4};
> +
> +/*
> + * The accumulative mode requires firmware to provide internal initial state
> + * and message padding (including length L at the end of padding).
> + *
> + * This test vector is a ascii text "abc" with padding message.
> + *
> + * Expected results were generated using command line utitiles:
> + *
> + *  echo -n -e 'abc' | dd of=/tmp/test
> + *  for hash in sha512sum sha256sum; do $hash /tmp/test; done
> + */
> +static const uint8_t test_vector_accum_512[] = {
> +    0x61, 0x62, 0x63, 0x80, 0x00, 0x00, 0x00, 0x00,
> +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18};
> +
> +static const uint8_t test_vector_accum_256[] = {
> +    0x61, 0x62, 0x63, 0x80, 0x00, 0x00, 0x00, 0x00,
> +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18};
> +
> +static const uint8_t test_result_accum_sha512[] = {
> +    0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba, 0xcc, 0x41, 0x73, 0x49,
> +    0xae, 0x20, 0x41, 0x31, 0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2,
> +    0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a, 0x21, 0x92, 0x99, 0x2a,
> +    0x27, 0x4f, 0xc1, 0xa8, 0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd,
> +    0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e, 0x2a, 0x9a, 0xc9, 0x4f,
> +    0xa5, 0x4c, 0xa4, 0x9f};
> +
> +static const uint8_t test_result_accum_sha256[] = {
> +    0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, 0xde,
> +    0x5d, 0xae, 0x22, 0x23, 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
> +    0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad};
> +
> +static void write_regs(QTestState *s, uint32_t base, uint32_t src,
> +                       uint32_t length, uint32_t out, uint32_t method)
> +{
> +        qtest_writel(s, base + HACE_HASH_SRC, src);
> +        qtest_writel(s, base + HACE_HASH_DIGEST, out);
> +        qtest_writel(s, base + HACE_HASH_DATA_LEN, length);
> +        qtest_writel(s, base + HACE_HASH_CMD, HACE_SHA_BE_EN | method);
> +}
> +
> +void aspeed_test_md5(const char *machine, const uint32_t base,
> +                     const uint32_t src_addr)
> +
> +{
> +    QTestState *s = qtest_init(machine);
> +
> +    uint32_t digest_addr = src_addr + 0x01000000;
> +    uint8_t digest[16] = {0};
> +
> +    /* Check engine is idle, no busy or irq bits set */
> +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> +
> +    /* Write test vector into memory */
> +    qtest_memwrite(s, src_addr, test_vector, sizeof(test_vector));
> +
> +    write_regs(s, base, src_addr, sizeof(test_vector),
> +               digest_addr, HACE_ALGO_MD5);
> +
> +    /* Check hash IRQ status is asserted */
> +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
> +
> +    /* Clear IRQ status and check status is deasserted */
> +    qtest_writel(s, base + HACE_STS, 0x00000200);
> +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> +
> +    /* Read computed digest from memory */
> +    qtest_memread(s, digest_addr, digest, sizeof(digest));
> +
> +    /* Check result of computation */
> +    g_assert_cmpmem(digest, sizeof(digest),
> +                    test_result_md5, sizeof(digest));
> +
> +    qtest_quit(s);
> +}
> +
> +void aspeed_test_sha256(const char *machine, const uint32_t base,
> +                        const uint32_t src_addr)
> +{
> +    QTestState *s = qtest_init(machine);
> +
> +    const uint32_t digest_addr = src_addr + 0x1000000;
> +    uint8_t digest[32] = {0};
> +
> +    /* Check engine is idle, no busy or irq bits set */
> +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> +
> +    /* Write test vector into memory */
> +    qtest_memwrite(s, src_addr, test_vector, sizeof(test_vector));
> +
> +    write_regs(s, base, src_addr, sizeof(test_vector), digest_addr,
> +               HACE_ALGO_SHA256);
> +
> +    /* Check hash IRQ status is asserted */
> +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
> +
> +    /* Clear IRQ status and check status is deasserted */
> +    qtest_writel(s, base + HACE_STS, 0x00000200);
> +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> +
> +    /* Read computed digest from memory */
> +    qtest_memread(s, digest_addr, digest, sizeof(digest));
> +
> +    /* Check result of computation */
> +    g_assert_cmpmem(digest, sizeof(digest),
> +                    test_result_sha256, sizeof(digest));
> +
> +    qtest_quit(s);
> +}
> +
> +void aspeed_test_sha512(const char *machine, const uint32_t base,
> +                        const uint32_t src_addr)
> +{
> +    QTestState *s = qtest_init(machine);
> +
> +    const uint32_t digest_addr = src_addr + 0x1000000;
> +    uint8_t digest[64] = {0};
> +
> +    /* Check engine is idle, no busy or irq bits set */
> +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> +
> +    /* Write test vector into memory */
> +    qtest_memwrite(s, src_addr, test_vector, sizeof(test_vector));
> +
> +    write_regs(s, base, src_addr, sizeof(test_vector), digest_addr,
> +               HACE_ALGO_SHA512);
> +
> +    /* Check hash IRQ status is asserted */
> +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
> +
> +    /* Clear IRQ status and check status is deasserted */
> +    qtest_writel(s, base + HACE_STS, 0x00000200);
> +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> +
> +    /* Read computed digest from memory */
> +    qtest_memread(s, digest_addr, digest, sizeof(digest));
> +
> +    /* Check result of computation */
> +    g_assert_cmpmem(digest, sizeof(digest),
> +                    test_result_sha512, sizeof(digest));
> +
> +    qtest_quit(s);
> +}
> +
> +void aspeed_test_sha256_sg(const char *machine, const uint32_t base,
> +                           const uint32_t src_addr)
> +{
> +    QTestState *s = qtest_init(machine);
> +
> +    const uint32_t src_addr_1 = src_addr + 0x1000000;
> +    const uint32_t src_addr_2 = src_addr + 0x2000000;
> +    const uint32_t src_addr_3 = src_addr + 0x3000000;
> +    const uint32_t digest_addr = src_addr + 0x4000000;
> +    uint8_t digest[32] = {0};
> +    struct AspeedSgList array[] = {
> +        {  cpu_to_le32(sizeof(test_vector_sg1)),
> +           cpu_to_le32(src_addr_1) },
> +        {  cpu_to_le32(sizeof(test_vector_sg2)),
> +           cpu_to_le32(src_addr_2) },
> +        {  cpu_to_le32(sizeof(test_vector_sg3) | SG_LIST_LEN_LAST),
> +           cpu_to_le32(src_addr_3) },
> +    };
> +
> +    /* Check engine is idle, no busy or irq bits set */
> +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> +
> +    /* Write test vector into memory */
> +    qtest_memwrite(s, src_addr_1, test_vector_sg1, sizeof(test_vector_sg1));
> +    qtest_memwrite(s, src_addr_2, test_vector_sg2, sizeof(test_vector_sg2));
> +    qtest_memwrite(s, src_addr_3, test_vector_sg3, sizeof(test_vector_sg3));
> +    qtest_memwrite(s, src_addr, array, sizeof(array));
> +
> +    write_regs(s, base, src_addr,
> +               (sizeof(test_vector_sg1)
> +                + sizeof(test_vector_sg2)
> +                + sizeof(test_vector_sg3)),
> +               digest_addr, HACE_ALGO_SHA256 | HACE_SG_EN);
> +
> +    /* Check hash IRQ status is asserted */
> +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
> +
> +    /* Clear IRQ status and check status is deasserted */
> +    qtest_writel(s, base + HACE_STS, 0x00000200);
> +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> +
> +    /* Read computed digest from memory */
> +    qtest_memread(s, digest_addr, digest, sizeof(digest));
> +
> +    /* Check result of computation */
> +    g_assert_cmpmem(digest, sizeof(digest),
> +                    test_result_sg_sha256, sizeof(digest));
> +
> +    qtest_quit(s);
> +}
> +
> +void aspeed_test_sha512_sg(const char *machine, const uint32_t base,
> +                           const uint32_t src_addr)
> +{
> +    QTestState *s = qtest_init(machine);
> +
> +    const uint32_t src_addr_1 = src_addr + 0x1000000;
> +    const uint32_t src_addr_2 = src_addr + 0x2000000;
> +    const uint32_t src_addr_3 = src_addr + 0x3000000;
> +    const uint32_t digest_addr = src_addr + 0x4000000;
> +    uint8_t digest[64] = {0};
> +    struct AspeedSgList array[] = {
> +        {  cpu_to_le32(sizeof(test_vector_sg1)),
> +           cpu_to_le32(src_addr_1) },
> +        {  cpu_to_le32(sizeof(test_vector_sg2)),
> +           cpu_to_le32(src_addr_2) },
> +        {  cpu_to_le32(sizeof(test_vector_sg3) | SG_LIST_LEN_LAST),
> +           cpu_to_le32(src_addr_3) },
> +    };
> +
> +    /* Check engine is idle, no busy or irq bits set */
> +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> +
> +    /* Write test vector into memory */
> +    qtest_memwrite(s, src_addr_1, test_vector_sg1, sizeof(test_vector_sg1));
> +    qtest_memwrite(s, src_addr_2, test_vector_sg2, sizeof(test_vector_sg2));
> +    qtest_memwrite(s, src_addr_3, test_vector_sg3, sizeof(test_vector_sg3));
> +    qtest_memwrite(s, src_addr, array, sizeof(array));
> +
> +    write_regs(s, base, src_addr,
> +               (sizeof(test_vector_sg1)
> +                + sizeof(test_vector_sg2)
> +                + sizeof(test_vector_sg3)),
> +               digest_addr, HACE_ALGO_SHA512 | HACE_SG_EN);
> +
> +    /* Check hash IRQ status is asserted */
> +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
> +
> +    /* Clear IRQ status and check status is deasserted */
> +    qtest_writel(s, base + HACE_STS, 0x00000200);
> +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> +
> +    /* Read computed digest from memory */
> +    qtest_memread(s, digest_addr, digest, sizeof(digest));
> +
> +    /* Check result of computation */
> +    g_assert_cmpmem(digest, sizeof(digest),
> +                    test_result_sg_sha512, sizeof(digest));
> +
> +    qtest_quit(s);
> +}
> +
> +void aspeed_test_sha256_accum(const char *machine, const uint32_t base,
> +                              const uint32_t src_addr)
> +{
> +    QTestState *s = qtest_init(machine);
> +
> +    const uint32_t buffer_addr = src_addr + 0x1000000;
> +    const uint32_t digest_addr = src_addr + 0x4000000;
> +    uint8_t digest[32] = {0};
> +    struct AspeedSgList array[] = {
> +        {  cpu_to_le32(sizeof(test_vector_accum_256) | SG_LIST_LEN_LAST),
> +           cpu_to_le32(buffer_addr) },
> +    };
> +
> +    /* Check engine is idle, no busy or irq bits set */
> +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> +
> +    /* Write test vector into memory */
> +    qtest_memwrite(s, buffer_addr, test_vector_accum_256,
> +                   sizeof(test_vector_accum_256));
> +    qtest_memwrite(s, src_addr, array, sizeof(array));
> +
> +    write_regs(s, base, src_addr, sizeof(test_vector_accum_256),
> +               digest_addr, HACE_ALGO_SHA256 | HACE_SG_EN | HACE_ACCUM_EN);
> +
> +    /* Check hash IRQ status is asserted */
> +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
> +
> +    /* Clear IRQ status and check status is deasserted */
> +    qtest_writel(s, base + HACE_STS, 0x00000200);
> +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> +
> +    /* Read computed digest from memory */
> +    qtest_memread(s, digest_addr, digest, sizeof(digest));
> +
> +    /* Check result of computation */
> +    g_assert_cmpmem(digest, sizeof(digest),
> +                    test_result_accum_sha256, sizeof(digest));
> +
> +    qtest_quit(s);
> +}
> +
> +void aspeed_test_sha512_accum(const char *machine, const uint32_t base,
> +                              const uint32_t src_addr)
> +{
> +    QTestState *s = qtest_init(machine);
> +
> +    const uint32_t buffer_addr = src_addr + 0x1000000;
> +    const uint32_t digest_addr = src_addr + 0x4000000;
> +    uint8_t digest[64] = {0};
> +    struct AspeedSgList array[] = {
> +        {  cpu_to_le32(sizeof(test_vector_accum_512) | SG_LIST_LEN_LAST),
> +           cpu_to_le32(buffer_addr) },
> +    };
> +
> +    /* Check engine is idle, no busy or irq bits set */
> +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> +
> +    /* Write test vector into memory */
> +    qtest_memwrite(s, buffer_addr, test_vector_accum_512,
> +                   sizeof(test_vector_accum_512));
> +    qtest_memwrite(s, src_addr, array, sizeof(array));
> +
> +    write_regs(s, base, src_addr, sizeof(test_vector_accum_512),
> +               digest_addr, HACE_ALGO_SHA512 | HACE_SG_EN | HACE_ACCUM_EN);
> +
> +    /* Check hash IRQ status is asserted */
> +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
> +
> +    /* Clear IRQ status and check status is deasserted */
> +    qtest_writel(s, base + HACE_STS, 0x00000200);
> +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> +
> +    /* Read computed digest from memory */
> +    qtest_memread(s, digest_addr, digest, sizeof(digest));
> +
> +    /* Check result of computation */
> +    g_assert_cmpmem(digest, sizeof(digest),
> +                    test_result_accum_sha512, sizeof(digest));
> +
> +    qtest_quit(s);
> +}
> +
> +void aspeed_test_addresses(const char *machine, const uint32_t base,
> +                           const struct AspeedMasks *expected)
> +{
> +    QTestState *s = qtest_init(machine);
> +
> +    /*
> +     * Check command mode is zero, meaning engine is in direct access mode,
> +     * as this affects the masking behavior of the HASH_SRC register.
> +     */
> +    g_assert_cmphex(qtest_readl(s, base + HACE_CMD), ==, 0);
> +    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_SRC), ==, 0);
> +    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DIGEST), ==, 0);
> +    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DATA_LEN), ==, 0);
> +
> +
> +    /* Check that the address masking is correct */
> +    qtest_writel(s, base + HACE_HASH_SRC, 0xffffffff);
> +    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_SRC), ==, expected->src);
> +
> +    qtest_writel(s, base + HACE_HASH_DIGEST, 0xffffffff);
> +    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DIGEST), ==,
> +                    expected->dest);
> +
> +    qtest_writel(s, base + HACE_HASH_DATA_LEN, 0xffffffff);
> +    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DATA_LEN), ==,
> +                    expected->len);
> +
> +    /* Reset to zero */
> +    qtest_writel(s, base + HACE_HASH_SRC, 0);
> +    qtest_writel(s, base + HACE_HASH_DIGEST, 0);
> +    qtest_writel(s, base + HACE_HASH_DATA_LEN, 0);
> +
> +    /* Check that all bits are now zero */
> +    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_SRC), ==, 0);
> +    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DIGEST), ==, 0);
> +    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DATA_LEN), ==, 0);
> +
> +    qtest_quit(s);
> +}
> +
> diff --git a/tests/qtest/aspeed_hace-test.c b/tests/qtest/aspeed_hace-test.c
> index ce86a44672..42a306af2a 100644
> --- a/tests/qtest/aspeed_hace-test.c
> +++ b/tests/qtest/aspeed_hace-test.c
> @@ -6,584 +6,109 @@
>    */
>   
>   #include "qemu/osdep.h"
> -
>   #include "libqtest.h"
>   #include "qemu/bitops.h"
> +#include "aspeed-hace-utils.h"
>   
> -#define HACE_CMD                 0x10
> -#define  HACE_SHA_BE_EN          BIT(3)
> -#define  HACE_MD5_LE_EN          BIT(2)
> -#define  HACE_ALGO_MD5           0
> -#define  HACE_ALGO_SHA1          BIT(5)
> -#define  HACE_ALGO_SHA224        BIT(6)
> -#define  HACE_ALGO_SHA256        (BIT(4) | BIT(6))
> -#define  HACE_ALGO_SHA512        (BIT(5) | BIT(6))
> -#define  HACE_ALGO_SHA384        (BIT(5) | BIT(6) | BIT(10))
> -#define  HACE_SG_EN              BIT(18)
> -#define  HACE_ACCUM_EN           BIT(8)
> -
> -#define HACE_STS                 0x1c
> -#define  HACE_RSA_ISR            BIT(13)
> -#define  HACE_CRYPTO_ISR         BIT(12)
> -#define  HACE_HASH_ISR           BIT(9)
> -#define  HACE_RSA_BUSY           BIT(2)
> -#define  HACE_CRYPTO_BUSY        BIT(1)
> -#define  HACE_HASH_BUSY          BIT(0)
> -#define HACE_HASH_SRC            0x20
> -#define HACE_HASH_DIGEST         0x24
> -#define HACE_HASH_KEY_BUFF       0x28
> -#define HACE_HASH_DATA_LEN       0x2c
> -#define HACE_HASH_CMD            0x30
> -/* Scatter-Gather Hash */
> -#define SG_LIST_LEN_LAST         BIT(31)
> -struct AspeedSgList {
> -        uint32_t len;
> -        uint32_t addr;
> -} __attribute__ ((__packed__));
> -
> -/*
> - * Test vector is the ascii "abc"
> - *
> - * Expected results were generated using command line utitiles:
> - *
> - *  echo -n -e 'abc' | dd of=/tmp/test
> - *  for hash in sha512sum sha256sum md5sum; do $hash /tmp/test; done
> - *
> - */
> -static const uint8_t test_vector[] = {0x61, 0x62, 0x63};
> -
> -static const uint8_t test_result_sha512[] = {
> -    0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba, 0xcc, 0x41, 0x73, 0x49,
> -    0xae, 0x20, 0x41, 0x31, 0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2,
> -    0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a, 0x21, 0x92, 0x99, 0x2a,
> -    0x27, 0x4f, 0xc1, 0xa8, 0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd,
> -    0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e, 0x2a, 0x9a, 0xc9, 0x4f,
> -    0xa5, 0x4c, 0xa4, 0x9f};
> -
> -static const uint8_t test_result_sha256[] = {
> -    0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, 0xde,
> -    0x5d, 0xae, 0x22, 0x23, 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
> -    0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad};
> -
> -static const uint8_t test_result_md5[] = {
> -    0x90, 0x01, 0x50, 0x98, 0x3c, 0xd2, 0x4f, 0xb0, 0xd6, 0x96, 0x3f, 0x7d,
> -    0x28, 0xe1, 0x7f, 0x72};
> -
> -/*
> - * The Scatter-Gather Test vector is the ascii "abc" "def" "ghi", broken
> - * into blocks of 3 characters as shown
> - *
> - * Expected results were generated using command line utitiles:
> - *
> - *  echo -n -e 'abcdefghijkl' | dd of=/tmp/test
> - *  for hash in sha512sum sha256sum; do $hash /tmp/test; done
> - *
> - */
> -static const uint8_t test_vector_sg1[] = {0x61, 0x62, 0x63, 0x64, 0x65, 0x66};
> -static const uint8_t test_vector_sg2[] = {0x67, 0x68, 0x69};
> -static const uint8_t test_vector_sg3[] = {0x6a, 0x6b, 0x6c};
> -
> -static const uint8_t test_result_sg_sha512[] = {
> -    0x17, 0x80, 0x7c, 0x72, 0x8e, 0xe3, 0xba, 0x35, 0xe7, 0xcf, 0x7a, 0xf8,
> -    0x23, 0x11, 0x6d, 0x26, 0xe4, 0x1e, 0x5d, 0x4d, 0x6c, 0x2f, 0xf1, 0xf3,
> -    0x72, 0x0d, 0x3d, 0x96, 0xaa, 0xcb, 0x6f, 0x69, 0xde, 0x64, 0x2e, 0x63,
> -    0xd5, 0xb7, 0x3f, 0xc3, 0x96, 0xc1, 0x2b, 0xe3, 0x8b, 0x2b, 0xd5, 0xd8,
> -    0x84, 0x25, 0x7c, 0x32, 0xc8, 0xf6, 0xd0, 0x85, 0x4a, 0xe6, 0xb5, 0x40,
> -    0xf8, 0x6d, 0xda, 0x2e};
> -
> -static const uint8_t test_result_sg_sha256[] = {
> -    0xd6, 0x82, 0xed, 0x4c, 0xa4, 0xd9, 0x89, 0xc1, 0x34, 0xec, 0x94, 0xf1,
> -    0x55, 0x1e, 0x1e, 0xc5, 0x80, 0xdd, 0x6d, 0x5a, 0x6e, 0xcd, 0xe9, 0xf3,
> -    0xd3, 0x5e, 0x6e, 0x4a, 0x71, 0x7f, 0xbd, 0xe4};
> -
> -/*
> - * The accumulative mode requires firmware to provide internal initial state
> - * and message padding (including length L at the end of padding).
> - *
> - * This test vector is a ascii text "abc" with padding message.
> - *
> - * Expected results were generated using command line utitiles:
> - *
> - *  echo -n -e 'abc' | dd of=/tmp/test
> - *  for hash in sha512sum sha256sum; do $hash /tmp/test; done
> - */
> -static const uint8_t test_vector_accum_512[] = {
> -    0x61, 0x62, 0x63, 0x80, 0x00, 0x00, 0x00, 0x00,
> -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18};
> -
> -static const uint8_t test_vector_accum_256[] = {
> -    0x61, 0x62, 0x63, 0x80, 0x00, 0x00, 0x00, 0x00,
> -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18};
> -
> -static const uint8_t test_result_accum_sha512[] = {
> -    0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba, 0xcc, 0x41, 0x73, 0x49,
> -    0xae, 0x20, 0x41, 0x31, 0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2,
> -    0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a, 0x21, 0x92, 0x99, 0x2a,
> -    0x27, 0x4f, 0xc1, 0xa8, 0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd,
> -    0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e, 0x2a, 0x9a, 0xc9, 0x4f,
> -    0xa5, 0x4c, 0xa4, 0x9f};
> -
> -static const uint8_t test_result_accum_sha256[] = {
> -    0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, 0xde,
> -    0x5d, 0xae, 0x22, 0x23, 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
> -    0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad};
> -
> -static void write_regs(QTestState *s, uint32_t base, uint32_t src,
> -                       uint32_t length, uint32_t out, uint32_t method)
> -{
> -        qtest_writel(s, base + HACE_HASH_SRC, src);
> -        qtest_writel(s, base + HACE_HASH_DIGEST, out);
> -        qtest_writel(s, base + HACE_HASH_DATA_LEN, length);
> -        qtest_writel(s, base + HACE_HASH_CMD, HACE_SHA_BE_EN | method);
> -}
> -
> -static void test_md5(const char *machine, const uint32_t base,
> -                     const uint32_t src_addr)
> -
> -{
> -    QTestState *s = qtest_init(machine);
> -
> -    uint32_t digest_addr = src_addr + 0x01000000;
> -    uint8_t digest[16] = {0};
> -
> -    /* Check engine is idle, no busy or irq bits set */
> -    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> -
> -    /* Write test vector into memory */
> -    qtest_memwrite(s, src_addr, test_vector, sizeof(test_vector));
> -
> -    write_regs(s, base, src_addr, sizeof(test_vector), digest_addr, HACE_ALGO_MD5);
> -
> -    /* Check hash IRQ status is asserted */
> -    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
> -
> -    /* Clear IRQ status and check status is deasserted */
> -    qtest_writel(s, base + HACE_STS, 0x00000200);
> -    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> -
> -    /* Read computed digest from memory */
> -    qtest_memread(s, digest_addr, digest, sizeof(digest));
> -
> -    /* Check result of computation */
> -    g_assert_cmpmem(digest, sizeof(digest),
> -                    test_result_md5, sizeof(digest));
> -
> -    qtest_quit(s);
> -}
> -
> -static void test_sha256(const char *machine, const uint32_t base,
> -                        const uint32_t src_addr)
> -{
> -    QTestState *s = qtest_init(machine);
> -
> -    const uint32_t digest_addr = src_addr + 0x1000000;
> -    uint8_t digest[32] = {0};
> -
> -    /* Check engine is idle, no busy or irq bits set */
> -    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> -
> -    /* Write test vector into memory */
> -    qtest_memwrite(s, src_addr, test_vector, sizeof(test_vector));
> -
> -    write_regs(s, base, src_addr, sizeof(test_vector), digest_addr, HACE_ALGO_SHA256);
> -
> -    /* Check hash IRQ status is asserted */
> -    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
> -
> -    /* Clear IRQ status and check status is deasserted */
> -    qtest_writel(s, base + HACE_STS, 0x00000200);
> -    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> -
> -    /* Read computed digest from memory */
> -    qtest_memread(s, digest_addr, digest, sizeof(digest));
> -
> -    /* Check result of computation */
> -    g_assert_cmpmem(digest, sizeof(digest),
> -                    test_result_sha256, sizeof(digest));
> -
> -    qtest_quit(s);
> -}
> -
> -static void test_sha512(const char *machine, const uint32_t base,
> -                        const uint32_t src_addr)
> -{
> -    QTestState *s = qtest_init(machine);
> -
> -    const uint32_t digest_addr = src_addr + 0x1000000;
> -    uint8_t digest[64] = {0};
> -
> -    /* Check engine is idle, no busy or irq bits set */
> -    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> -
> -    /* Write test vector into memory */
> -    qtest_memwrite(s, src_addr, test_vector, sizeof(test_vector));
> -
> -    write_regs(s, base, src_addr, sizeof(test_vector), digest_addr, HACE_ALGO_SHA512);
> -
> -    /* Check hash IRQ status is asserted */
> -    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
> -
> -    /* Clear IRQ status and check status is deasserted */
> -    qtest_writel(s, base + HACE_STS, 0x00000200);
> -    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> -
> -    /* Read computed digest from memory */
> -    qtest_memread(s, digest_addr, digest, sizeof(digest));
> -
> -    /* Check result of computation */
> -    g_assert_cmpmem(digest, sizeof(digest),
> -                    test_result_sha512, sizeof(digest));
> -
> -    qtest_quit(s);
> -}
> -
> -static void test_sha256_sg(const char *machine, const uint32_t base,
> -                        const uint32_t src_addr)
> -{
> -    QTestState *s = qtest_init(machine);
> -
> -    const uint32_t src_addr_1 = src_addr + 0x1000000;
> -    const uint32_t src_addr_2 = src_addr + 0x2000000;
> -    const uint32_t src_addr_3 = src_addr + 0x3000000;
> -    const uint32_t digest_addr = src_addr + 0x4000000;
> -    uint8_t digest[32] = {0};
> -    struct AspeedSgList array[] = {
> -        {  cpu_to_le32(sizeof(test_vector_sg1)),
> -           cpu_to_le32(src_addr_1) },
> -        {  cpu_to_le32(sizeof(test_vector_sg2)),
> -           cpu_to_le32(src_addr_2) },
> -        {  cpu_to_le32(sizeof(test_vector_sg3) | SG_LIST_LEN_LAST),
> -           cpu_to_le32(src_addr_3) },
> -    };
> -
> -    /* Check engine is idle, no busy or irq bits set */
> -    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> -
> -    /* Write test vector into memory */
> -    qtest_memwrite(s, src_addr_1, test_vector_sg1, sizeof(test_vector_sg1));
> -    qtest_memwrite(s, src_addr_2, test_vector_sg2, sizeof(test_vector_sg2));
> -    qtest_memwrite(s, src_addr_3, test_vector_sg3, sizeof(test_vector_sg3));
> -    qtest_memwrite(s, src_addr, array, sizeof(array));
> -
> -    write_regs(s, base, src_addr,
> -               (sizeof(test_vector_sg1)
> -                + sizeof(test_vector_sg2)
> -                + sizeof(test_vector_sg3)),
> -               digest_addr, HACE_ALGO_SHA256 | HACE_SG_EN);
> -
> -    /* Check hash IRQ status is asserted */
> -    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
> -
> -    /* Clear IRQ status and check status is deasserted */
> -    qtest_writel(s, base + HACE_STS, 0x00000200);
> -    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> -
> -    /* Read computed digest from memory */
> -    qtest_memread(s, digest_addr, digest, sizeof(digest));
> -
> -    /* Check result of computation */
> -    g_assert_cmpmem(digest, sizeof(digest),
> -                    test_result_sg_sha256, sizeof(digest));
> -
> -    qtest_quit(s);
> -}
> -
> -static void test_sha512_sg(const char *machine, const uint32_t base,
> -                        const uint32_t src_addr)
> -{
> -    QTestState *s = qtest_init(machine);
> -
> -    const uint32_t src_addr_1 = src_addr + 0x1000000;
> -    const uint32_t src_addr_2 = src_addr + 0x2000000;
> -    const uint32_t src_addr_3 = src_addr + 0x3000000;
> -    const uint32_t digest_addr = src_addr + 0x4000000;
> -    uint8_t digest[64] = {0};
> -    struct AspeedSgList array[] = {
> -        {  cpu_to_le32(sizeof(test_vector_sg1)),
> -           cpu_to_le32(src_addr_1) },
> -        {  cpu_to_le32(sizeof(test_vector_sg2)),
> -           cpu_to_le32(src_addr_2) },
> -        {  cpu_to_le32(sizeof(test_vector_sg3) | SG_LIST_LEN_LAST),
> -           cpu_to_le32(src_addr_3) },
> -    };
> -
> -    /* Check engine is idle, no busy or irq bits set */
> -    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> -
> -    /* Write test vector into memory */
> -    qtest_memwrite(s, src_addr_1, test_vector_sg1, sizeof(test_vector_sg1));
> -    qtest_memwrite(s, src_addr_2, test_vector_sg2, sizeof(test_vector_sg2));
> -    qtest_memwrite(s, src_addr_3, test_vector_sg3, sizeof(test_vector_sg3));
> -    qtest_memwrite(s, src_addr, array, sizeof(array));
> -
> -    write_regs(s, base, src_addr,
> -               (sizeof(test_vector_sg1)
> -                + sizeof(test_vector_sg2)
> -                + sizeof(test_vector_sg3)),
> -               digest_addr, HACE_ALGO_SHA512 | HACE_SG_EN);
> -
> -    /* Check hash IRQ status is asserted */
> -    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
> -
> -    /* Clear IRQ status and check status is deasserted */
> -    qtest_writel(s, base + HACE_STS, 0x00000200);
> -    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> -
> -    /* Read computed digest from memory */
> -    qtest_memread(s, digest_addr, digest, sizeof(digest));
> -
> -    /* Check result of computation */
> -    g_assert_cmpmem(digest, sizeof(digest),
> -                    test_result_sg_sha512, sizeof(digest));
> -
> -    qtest_quit(s);
> -}
> -
> -static void test_sha256_accum(const char *machine, const uint32_t base,
> -                        const uint32_t src_addr)
> -{
> -    QTestState *s = qtest_init(machine);
> -
> -    const uint32_t buffer_addr = src_addr + 0x1000000;
> -    const uint32_t digest_addr = src_addr + 0x4000000;
> -    uint8_t digest[32] = {0};
> -    struct AspeedSgList array[] = {
> -        {  cpu_to_le32(sizeof(test_vector_accum_256) | SG_LIST_LEN_LAST),
> -           cpu_to_le32(buffer_addr) },
> -    };
> -
> -    /* Check engine is idle, no busy or irq bits set */
> -    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> -
> -    /* Write test vector into memory */
> -    qtest_memwrite(s, buffer_addr, test_vector_accum_256,
> -                   sizeof(test_vector_accum_256));
> -    qtest_memwrite(s, src_addr, array, sizeof(array));
> -
> -    write_regs(s, base, src_addr, sizeof(test_vector_accum_256),
> -               digest_addr, HACE_ALGO_SHA256 | HACE_SG_EN | HACE_ACCUM_EN);
> -
> -    /* Check hash IRQ status is asserted */
> -    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
> -
> -    /* Clear IRQ status and check status is deasserted */
> -    qtest_writel(s, base + HACE_STS, 0x00000200);
> -    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> -
> -    /* Read computed digest from memory */
> -    qtest_memread(s, digest_addr, digest, sizeof(digest));
> -
> -    /* Check result of computation */
> -    g_assert_cmpmem(digest, sizeof(digest),
> -                    test_result_accum_sha256, sizeof(digest));
> -
> -    qtest_quit(s);
> -}
> -
> -static void test_sha512_accum(const char *machine, const uint32_t base,
> -                        const uint32_t src_addr)
> -{
> -    QTestState *s = qtest_init(machine);
> -
> -    const uint32_t buffer_addr = src_addr + 0x1000000;
> -    const uint32_t digest_addr = src_addr + 0x4000000;
> -    uint8_t digest[64] = {0};
> -    struct AspeedSgList array[] = {
> -        {  cpu_to_le32(sizeof(test_vector_accum_512) | SG_LIST_LEN_LAST),
> -           cpu_to_le32(buffer_addr) },
> -    };
> -
> -    /* Check engine is idle, no busy or irq bits set */
> -    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> -
> -    /* Write test vector into memory */
> -    qtest_memwrite(s, buffer_addr, test_vector_accum_512,
> -                   sizeof(test_vector_accum_512));
> -    qtest_memwrite(s, src_addr, array, sizeof(array));
> -
> -    write_regs(s, base, src_addr, sizeof(test_vector_accum_512),
> -               digest_addr, HACE_ALGO_SHA512 | HACE_SG_EN | HACE_ACCUM_EN);
> -
> -    /* Check hash IRQ status is asserted */
> -    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
> -
> -    /* Clear IRQ status and check status is deasserted */
> -    qtest_writel(s, base + HACE_STS, 0x00000200);
> -    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> -
> -    /* Read computed digest from memory */
> -    qtest_memread(s, digest_addr, digest, sizeof(digest));
> -
> -    /* Check result of computation */
> -    g_assert_cmpmem(digest, sizeof(digest),
> -                    test_result_accum_sha512, sizeof(digest));
> -
> -    qtest_quit(s);
> -}
> -
> -struct masks {
> -    uint32_t src;
> -    uint32_t dest;
> -    uint32_t len;
> -};
> -
> -static const struct masks ast2600_masks = {
> +static const struct AspeedMasks ast2600_masks = {
>       .src  = 0x7fffffff,
>       .dest = 0x7ffffff8,
>       .len  = 0x0fffffff,
>   };
>   
> -static const struct masks ast2500_masks = {
> +static const struct AspeedMasks ast2500_masks = {
>       .src  = 0x3fffffff,
>       .dest = 0x3ffffff8,
>       .len  = 0x0fffffff,
>   };
>   
> -static const struct masks ast2400_masks = {
> +static const struct AspeedMasks ast2400_masks = {
>       .src  = 0x0fffffff,
>       .dest = 0x0ffffff8,
>       .len  = 0x0fffffff,
>   };
>   
> -static void test_addresses(const char *machine, const uint32_t base,
> -                           const struct masks *expected)
> -{
> -    QTestState *s = qtest_init(machine);
> -
> -    /*
> -     * Check command mode is zero, meaning engine is in direct access mode,
> -     * as this affects the masking behavior of the HASH_SRC register.
> -     */
> -    g_assert_cmphex(qtest_readl(s, base + HACE_CMD), ==, 0);
> -    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_SRC), ==, 0);
> -    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DIGEST), ==, 0);
> -    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DATA_LEN), ==, 0);
> -
> -
> -    /* Check that the address masking is correct */
> -    qtest_writel(s, base + HACE_HASH_SRC, 0xffffffff);
> -    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_SRC), ==, expected->src);
> -
> -    qtest_writel(s, base + HACE_HASH_DIGEST, 0xffffffff);
> -    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DIGEST), ==, expected->dest);
> -
> -    qtest_writel(s, base + HACE_HASH_DATA_LEN, 0xffffffff);
> -    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DATA_LEN), ==, expected->len);
> -
> -    /* Reset to zero */
> -    qtest_writel(s, base + HACE_HASH_SRC, 0);
> -    qtest_writel(s, base + HACE_HASH_DIGEST, 0);
> -    qtest_writel(s, base + HACE_HASH_DATA_LEN, 0);
> -
> -    /* Check that all bits are now zero */
> -    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_SRC), ==, 0);
> -    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DIGEST), ==, 0);
> -    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DATA_LEN), ==, 0);
> -
> -    qtest_quit(s);
> -}
> -
>   /* ast2600 */
>   static void test_md5_ast2600(void)
>   {
> -    test_md5("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
> +    aspeed_test_md5("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
>   }
>   
>   static void test_sha256_ast2600(void)
>   {
> -    test_sha256("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
> +    aspeed_test_sha256("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
>   }
>   
>   static void test_sha256_sg_ast2600(void)
>   {
> -    test_sha256_sg("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
> +    aspeed_test_sha256_sg("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
>   }
>   
>   static void test_sha512_ast2600(void)
>   {
> -    test_sha512("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
> +    aspeed_test_sha512("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
>   }
>   
>   static void test_sha512_sg_ast2600(void)
>   {
> -    test_sha512_sg("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
> +    aspeed_test_sha512_sg("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
>   }
>   
>   static void test_sha256_accum_ast2600(void)
>   {
> -    test_sha256_accum("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
> +    aspeed_test_sha256_accum("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
>   }
>   
>   static void test_sha512_accum_ast2600(void)
>   {
> -    test_sha512_accum("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
> +    aspeed_test_sha512_accum("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
>   }
>   
>   static void test_addresses_ast2600(void)
>   {
> -    test_addresses("-machine ast2600-evb", 0x1e6d0000, &ast2600_masks);
> +    aspeed_test_addresses("-machine ast2600-evb", 0x1e6d0000, &ast2600_masks);
>   }
>   
>   /* ast2500 */
>   static void test_md5_ast2500(void)
>   {
> -    test_md5("-machine ast2500-evb", 0x1e6e3000, 0x80000000);
> +    aspeed_test_md5("-machine ast2500-evb", 0x1e6e3000, 0x80000000);
>   }
>   
>   static void test_sha256_ast2500(void)
>   {
> -    test_sha256("-machine ast2500-evb", 0x1e6e3000, 0x80000000);
> +    aspeed_test_sha256("-machine ast2500-evb", 0x1e6e3000, 0x80000000);
>   }
>   
>   static void test_sha512_ast2500(void)
>   {
> -    test_sha512("-machine ast2500-evb", 0x1e6e3000, 0x80000000);
> +    aspeed_test_sha512("-machine ast2500-evb", 0x1e6e3000, 0x80000000);
>   }
>   
>   static void test_addresses_ast2500(void)
>   {
> -    test_addresses("-machine ast2500-evb", 0x1e6e3000, &ast2500_masks);
> +    aspeed_test_addresses("-machine ast2500-evb", 0x1e6e3000, &ast2500_masks);
>   }
>   
>   /* ast2400 */
>   static void test_md5_ast2400(void)
>   {
> -    test_md5("-machine palmetto-bmc", 0x1e6e3000, 0x40000000);
> +    aspeed_test_md5("-machine palmetto-bmc", 0x1e6e3000, 0x40000000);
>   }
>   
>   static void test_sha256_ast2400(void)
>   {
> -    test_sha256("-machine palmetto-bmc", 0x1e6e3000, 0x40000000);
> +    aspeed_test_sha256("-machine palmetto-bmc", 0x1e6e3000, 0x40000000);
>   }
>   
>   static void test_sha512_ast2400(void)
>   {
> -    test_sha512("-machine palmetto-bmc", 0x1e6e3000, 0x40000000);
> +    aspeed_test_sha512("-machine palmetto-bmc", 0x1e6e3000, 0x40000000);
>   }
>   
>   static void test_addresses_ast2400(void)
>   {
> -    test_addresses("-machine palmetto-bmc", 0x1e6e3000, &ast2400_masks);
> +    aspeed_test_addresses("-machine palmetto-bmc", 0x1e6e3000, &ast2400_masks);
>   }
>   
>   int main(int argc, char **argv)
> diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
> index 8a6243382a..62fc8f9868 100644
> --- a/tests/qtest/meson.build
> +++ b/tests/qtest/meson.build
> @@ -383,6 +383,7 @@ qtests = {
>     'netdev-socket': files('netdev-socket.c', '../unit/socket-helpers.c'),
>     'aspeed_smc-test': files('aspeed-smc-utils.c', 'aspeed_smc-test.c'),
>     'ast2700-smc-test': files('aspeed-smc-utils.c', 'ast2700-smc-test.c'),
> +  'aspeed_hace-test': files('aspeed-hace-utils.c', 'aspeed_hace-test.c'),
>   }
>   
>   if vnc.found()



^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v1 15/22] test/qtest/hace: Add SHA-384 test cases for ASPEED HACE model
  2025-03-21  9:26 ` [PATCH v1 15/22] test/qtest/hace: Add SHA-384 test cases for ASPEED HACE model Jamin Lin via
@ 2025-04-02  9:02   ` Cédric Le Goater
  2025-05-05  6:36     ` Jamin Lin
  0 siblings, 1 reply; 71+ messages in thread
From: Cédric Le Goater @ 2025-04-02  9:02 UTC (permalink / raw)
  To: Jamin Lin, Peter Maydell, Steven Lee, Troy Lee, Andrew Jeffery,
	Joel Stanley, Fabiano Rosas, Laurent Vivier, Paolo Bonzini,
	open list:ASPEED BMCs, open list:All patches CC here
  Cc: troy_lee

On 3/21/25 10:26, Jamin Lin wrote:
> Introduced SHA-384 test functions to verify hashing operations.
> Extended support for scatter-gather (`_sg`) and accumulation (`_accum`) tests.
> Updated test result vectors for SHA-384 validation.
> 
> Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
> ---
>   tests/qtest/aspeed-hace-utils.h |   6 ++
>   tests/qtest/aspeed-hace-utils.c | 168 +++++++++++++++++++++++++++++++-
>   2 files changed, 171 insertions(+), 3 deletions(-)
> 
> diff --git a/tests/qtest/aspeed-hace-utils.h b/tests/qtest/aspeed-hace-utils.h
> index 598577c69b..f4440561de 100644
> --- a/tests/qtest/aspeed-hace-utils.h
> +++ b/tests/qtest/aspeed-hace-utils.h
> @@ -54,14 +54,20 @@ void aspeed_test_md5(const char *machine, const uint32_t base,
>                        const uint32_t src_addr);
>   void aspeed_test_sha256(const char *machine, const uint32_t base,
>                           const uint32_t src_addr);
> +void aspeed_test_sha384(const char *machine, const uint32_t base,
> +                        const uint32_t src_addr);
>   void aspeed_test_sha512(const char *machine, const uint32_t base,
>                           const uint32_t src_addr);
>   void aspeed_test_sha256_sg(const char *machine, const uint32_t base,
>                              const uint32_t src_addr);
> +void aspeed_test_sha384_sg(const char *machine, const uint32_t base,
> +                           const uint32_t src_addr);
>   void aspeed_test_sha512_sg(const char *machine, const uint32_t base,
>                              const uint32_t src_addr);
>   void aspeed_test_sha256_accum(const char *machine, const uint32_t base,
>                                 const uint32_t src_addr);
> +void aspeed_test_sha384_accum(const char *machine, const uint32_t base,
> +                              const uint32_t src_addr);
>   void aspeed_test_sha512_accum(const char *machine, const uint32_t base,
>                                 const uint32_t src_addr);
>   void aspeed_test_addresses(const char *machine, const uint32_t base,
> diff --git a/tests/qtest/aspeed-hace-utils.c b/tests/qtest/aspeed-hace-utils.c
> index 8fbbba49c1..d3146898c2 100644
> --- a/tests/qtest/aspeed-hace-utils.c
> +++ b/tests/qtest/aspeed-hace-utils.c
> @@ -16,7 +16,7 @@
>    * Expected results were generated using command line utitiles:
>    *
>    *  echo -n -e 'abc' | dd of=/tmp/test
> - *  for hash in sha512sum sha256sum md5sum; do $hash /tmp/test; done
> + *  for hash in sha512sum sha384sum sha256sum md5sum; do $hash /tmp/test; done
>    *
>    */
>   static const uint8_t test_vector[] = {0x61, 0x62, 0x63};
> @@ -29,6 +29,12 @@ static const uint8_t test_result_sha512[] = {
>       0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e, 0x2a, 0x9a, 0xc9, 0x4f,
>       0xa5, 0x4c, 0xa4, 0x9f};
>   
> +static const uint8_t test_result_sha384[] = {
> +    0xcb, 0x00, 0x75, 0x3f, 0x45, 0xa3, 0x5e, 0x8b, 0xb5, 0xa0, 0x3d, 0x69,
> +    0x9a, 0xc6, 0x50, 0x07, 0x27, 0x2c, 0x32, 0xab, 0x0e, 0xde, 0xd1, 0x63,
> +    0x1a, 0x8b, 0x60, 0x5a, 0x43, 0xff, 0x5b, 0xed, 0x80, 0x86, 0x07, 0x2b,
> +    0xa1, 0xe7, 0xcc, 0x23, 0x58, 0xba, 0xec, 0xa1, 0x34, 0xc8, 0x25, 0xa7};
> +
>   static const uint8_t test_result_sha256[] = {
>       0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, 0xde,
>       0x5d, 0xae, 0x22, 0x23, 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
> @@ -45,7 +51,7 @@ static const uint8_t test_result_md5[] = {
>    * Expected results were generated using command line utitiles:
>    *
>    *  echo -n -e 'abcdefghijkl' | dd of=/tmp/test
> - *  for hash in sha512sum sha256sum; do $hash /tmp/test; done
> + *  for hash in sha512sum sha384sum sha256sum; do $hash /tmp/test; done
>    *
>    */
>   static const uint8_t test_vector_sg1[] = {0x61, 0x62, 0x63, 0x64, 0x65, 0x66};
> @@ -60,6 +66,12 @@ static const uint8_t test_result_sg_sha512[] = {
>       0x84, 0x25, 0x7c, 0x32, 0xc8, 0xf6, 0xd0, 0x85, 0x4a, 0xe6, 0xb5, 0x40,
>       0xf8, 0x6d, 0xda, 0x2e};
>   
> +static const uint8_t test_result_sg_sha384[] = {
> +    0x10, 0x3c, 0xa9, 0x6c, 0x06, 0xa1, 0xce, 0x79, 0x8f, 0x08, 0xf8, 0xef,
> +    0xf0, 0xdf, 0xb0, 0xcc, 0xdb, 0x56, 0x7d, 0x48, 0xb2, 0x85, 0xb2, 0x3d,
> +    0x0c, 0xd7, 0x73, 0x45, 0x46, 0x67, 0xa3, 0xc2, 0xfa, 0x5f, 0x1b, 0x58,
> +    0xd9, 0xcd, 0xf2, 0x32, 0x9b, 0xd9, 0x97, 0x97, 0x30, 0xbf, 0xaa, 0xff};
> +
>   static const uint8_t test_result_sg_sha256[] = {
>       0xd6, 0x82, 0xed, 0x4c, 0xa4, 0xd9, 0x89, 0xc1, 0x34, 0xec, 0x94, 0xf1,
>       0x55, 0x1e, 0x1e, 0xc5, 0x80, 0xdd, 0x6d, 0x5a, 0x6e, 0xcd, 0xe9, 0xf3,
> @@ -74,7 +86,7 @@ static const uint8_t test_result_sg_sha256[] = {
>    * Expected results were generated using command line utitiles:
>    *
>    *  echo -n -e 'abc' | dd of=/tmp/test
> - *  for hash in sha512sum sha256sum; do $hash /tmp/test; done
> + *  for hash in sha512sum sha384sum sha256sum; do $hash /tmp/test; done
>    */
>   static const uint8_t test_vector_accum_512[] = {
>       0x61, 0x62, 0x63, 0x80, 0x00, 0x00, 0x00, 0x00,
> @@ -94,6 +106,24 @@ static const uint8_t test_vector_accum_512[] = {
>       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
>       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18};
>   
> +static const uint8_t test_vector_accum_384[] = {
> +    0x61, 0x62, 0x63, 0x80, 0x00, 0x00, 0x00, 0x00,
> +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18};
> +
>   static const uint8_t test_vector_accum_256[] = {
>       0x61, 0x62, 0x63, 0x80, 0x00, 0x00, 0x00, 0x00,
>       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> @@ -112,6 +142,12 @@ static const uint8_t test_result_accum_sha512[] = {
>       0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e, 0x2a, 0x9a, 0xc9, 0x4f,
>       0xa5, 0x4c, 0xa4, 0x9f};
>   
> +static const uint8_t test_result_accum_sha384[] = {
> +    0xcb, 0x00, 0x75, 0x3f, 0x45, 0xa3, 0x5e, 0x8b, 0xb5, 0xa0, 0x3d, 0x69,
> +    0x9a, 0xc6, 0x50, 0x07, 0x27, 0x2c, 0x32, 0xab, 0x0e, 0xde, 0xd1, 0x63,
> +    0x1a, 0x8b, 0x60, 0x5a, 0x43, 0xff, 0x5b, 0xed, 0x80, 0x86, 0x07, 0x2b,
> +    0xa1, 0xe7, 0xcc, 0x23, 0x58, 0xba, 0xec, 0xa1, 0x34, 0xc8, 0x25, 0xa7};
> +
>   static const uint8_t test_result_accum_sha256[] = {
>       0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, 0xde,
>       0x5d, 0xae, 0x22, 0x23, 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
> @@ -195,6 +231,40 @@ void aspeed_test_sha256(const char *machine, const uint32_t base,
>       qtest_quit(s);
>   }
>   
> +void aspeed_test_sha384(const char *machine, const uint32_t base,
> +                        const uint32_t src_addr)
> +{
> +    QTestState *s = qtest_init(machine);
> +
> +    const uint32_t digest_addr = src_addr + 0x10000;
> +    uint8_t digest[32] = {0};
> +
> +    /* Check engine is idle, no busy or irq bits set */
> +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> +
> +    /* Write test vector into memory */
> +    qtest_memwrite(s, src_addr, test_vector, sizeof(test_vector));
> +
> +    write_regs(s, base, src_addr, sizeof(test_vector), digest_addr,
> +               HACE_ALGO_SHA384);
> +
> +    /* Check hash IRQ status is asserted */
> +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
> +
> +    /* Clear IRQ status and check status is deasserted */
> +    qtest_writel(s, base + HACE_STS, 0x00000200);
> +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> +
> +    /* Read computed digest from memory */
> +    qtest_memread(s, digest_addr, digest, sizeof(digest));
> +
> +    /* Check result of computation */
> +    g_assert_cmpmem(digest, sizeof(digest),
> +                    test_result_sha384, sizeof(digest));
> +
> +    qtest_quit(s);
> +}
> +
>   void aspeed_test_sha512(const char *machine, const uint32_t base,
>                           const uint32_t src_addr)
>   {
> @@ -280,6 +350,57 @@ void aspeed_test_sha256_sg(const char *machine, const uint32_t base,
>       qtest_quit(s);
>   }
>   
> +void aspeed_test_sha384_sg(const char *machine, const uint32_t base,
> +                           const uint32_t src_addr)
> +{
> +    QTestState *s = qtest_init(machine);
> +
> +    const uint32_t src_addr_1 = src_addr + 0x10000;
> +    const uint32_t src_addr_2 = src_addr + 0x20000;
> +    const uint32_t src_addr_3 = src_addr + 0x30000;
> +    const uint32_t digest_addr = src_addr + 0x40000;
> +    uint8_t digest[64] = {0};

This does not compile (gcc version 14.2.1)


../tests/qtest/aspeed-hace-utils.c: In function ‘aspeed_test_sha384_sg’:
/usr/include/glib-2.0/glib/gtestutils.h:93:84: error: ‘__builtin_memcmp_eq’ specified bound 64 exceeds the size 48 of unterminated array [-Werror=stringop-overread]
    93 |                                              else if (__l1 != 0 && __m2 != NULL && memcmp (__m1, __m2, __l1) != 0) \
       |                                                                                    ^~~~~~~~~~~~~~~~~~~~~~~~~
../tests/qtest/aspeed-hace-utils.c:399:5: note: in expansion of macro ‘g_assert_cmpmem’
   399 |     g_assert_cmpmem(digest, sizeof(digest),
       |     ^~~~~~~~~~~~~~~
../tests/qtest/aspeed-hace-utils.c:69:22: note: referenced argument declared here
    69 | static const uint8_t test_result_sg_sha384[] = {
       |                      ^~~~~~~~~~~~~~~~~~~~~




> +    struct AspeedSgList array[] = {
> +        {  cpu_to_le32(sizeof(test_vector_sg1)),
> +           cpu_to_le32(src_addr_1) },
> +        {  cpu_to_le32(sizeof(test_vector_sg2)),
> +           cpu_to_le32(src_addr_2) },
> +        {  cpu_to_le32(sizeof(test_vector_sg3) | SG_LIST_LEN_LAST),
> +           cpu_to_le32(src_addr_3) },
> +    };
> +
> +    /* Check engine is idle, no busy or irq bits set */
> +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> +
> +    /* Write test vector into memory */
> +    qtest_memwrite(s, src_addr_1, test_vector_sg1, sizeof(test_vector_sg1));
> +    qtest_memwrite(s, src_addr_2, test_vector_sg2, sizeof(test_vector_sg2));
> +    qtest_memwrite(s, src_addr_3, test_vector_sg3, sizeof(test_vector_sg3));
> +    qtest_memwrite(s, src_addr, array, sizeof(array));
> +
> +    write_regs(s, base, src_addr,
> +               (sizeof(test_vector_sg1)
> +                + sizeof(test_vector_sg2)
> +                + sizeof(test_vector_sg3)),
> +               digest_addr, HACE_ALGO_SHA384 | HACE_SG_EN);
> +
> +    /* Check hash IRQ status is asserted */
> +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
> +
> +    /* Clear IRQ status and check status is deasserted */
> +    qtest_writel(s, base + HACE_STS, 0x00000200);
> +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> +
> +    /* Read computed digest from memory */
> +    qtest_memread(s, digest_addr, digest, sizeof(digest));
> +
> +    /* Check result of computation */
> +    g_assert_cmpmem(digest, sizeof(digest),
> +                    test_result_sg_sha384, sizeof(digest));
> +
> +    qtest_quit(s);
> +}
> +
>   void aspeed_test_sha512_sg(const char *machine, const uint32_t base,
>                              const uint32_t src_addr)
>   {
> @@ -372,6 +493,47 @@ void aspeed_test_sha256_accum(const char *machine, const uint32_t base,
>       qtest_quit(s);
>   }
>   
> +void aspeed_test_sha384_accum(const char *machine, const uint32_t base,
> +                              const uint32_t src_addr)
> +{
> +    QTestState *s = qtest_init(machine);
> +
> +    const uint32_t buffer_addr = src_addr + 0x10000;
> +    const uint32_t digest_addr = src_addr + 0x40000;
> +    uint8_t digest[64] = {0};

../tests/qtest/aspeed-hace-utils.c: In function ‘aspeed_test_sha384_accum’:
/usr/include/glib-2.0/glib/gtestutils.h:93:84: error: ‘__builtin_memcmp_eq’ specified bound 64 exceeds source size 48 [-Werror=stringop-overread]
    93 |                                              else if (__l1 != 0 && __m2 != NULL && memcmp (__m1, __m2, __l1) != 0) \
       |                                                                                    ^~~~~~~~~~~~~~~~~~~~~~~~~
../tests/qtest/aspeed-hace-utils.c:533:5: note: in expansion of macro ‘g_assert_cmpmem’
   533 |     g_assert_cmpmem(digest, sizeof(digest),
       |     ^~~~~~~~~~~~~~~
../tests/qtest/aspeed-hace-utils.c:145:22: note: source object declared here
   145 | static const uint8_t test_result_accum_sha384[] = {
       |                      ^~~~~~~~~~~~~~~~~~~~~~~~


Thanks,

C.



> +    struct AspeedSgList array[] = {
> +        {  cpu_to_le32(sizeof(test_vector_accum_384) | SG_LIST_LEN_LAST),
> +           cpu_to_le32(buffer_addr) },
> +    };
> +
> +    /* Check engine is idle, no busy or irq bits set */
> +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> +
> +    /* Write test vector into memory */
> +    qtest_memwrite(s, buffer_addr, test_vector_accum_384,
> +                   sizeof(test_vector_accum_384));
> +    qtest_memwrite(s, src_addr, array, sizeof(array));
> +
> +    write_regs(s, base, src_addr, sizeof(test_vector_accum_384),
> +               digest_addr, HACE_ALGO_SHA384 | HACE_SG_EN | HACE_ACCUM_EN);
> +
> +    /* Check hash IRQ status is asserted */
> +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
> +
> +    /* Clear IRQ status and check status is deasserted */
> +    qtest_writel(s, base + HACE_STS, 0x00000200);
> +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> +
> +    /* Read computed digest from memory */
> +    qtest_memread(s, digest_addr, digest, sizeof(digest));
> +
> +    /* Check result of computation */
> +    g_assert_cmpmem(digest, sizeof(digest),
> +                    test_result_accum_sha384, sizeof(digest));
> +
> +    qtest_quit(s);
> +}
> +
>   void aspeed_test_sha512_accum(const char *machine, const uint32_t base,
>                                 const uint32_t src_addr)
>   {



^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v1 16/22] test/qtest/hace: Add SHA-384 tests for AST2600
  2025-03-21  9:26 ` [PATCH v1 16/22] test/qtest/hace: Add SHA-384 tests for AST2600 Jamin Lin via
@ 2025-04-02  9:02   ` Cédric Le Goater
  0 siblings, 0 replies; 71+ messages in thread
From: Cédric Le Goater @ 2025-04-02  9:02 UTC (permalink / raw)
  To: Jamin Lin, Peter Maydell, Steven Lee, Troy Lee, Andrew Jeffery,
	Joel Stanley, Fabiano Rosas, Laurent Vivier, Paolo Bonzini,
	open list:ASPEED BMCs, open list:All patches CC here
  Cc: troy_lee

On 3/21/25 10:26, Jamin Lin wrote:
> Introduced "test_sha384_ast2600" to validate SHA-384 hashing.
> Added "test_sha384_sg_ast2600" for scatter-gather SHA-384 verification.
> Implemented "test_sha384_accum_ast2600" to test SHA-384 accumulation.
> Registered new test cases in "main" to ensure execution.
> 
> Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>


Reviewed-by: Cédric Le Goater <clg@redhat.com>

Thanks,

C.


> ---
>   tests/qtest/aspeed_hace-test.c | 18 ++++++++++++++++++
>   1 file changed, 18 insertions(+)
> 
> diff --git a/tests/qtest/aspeed_hace-test.c b/tests/qtest/aspeed_hace-test.c
> index 42a306af2a..ab0c98330e 100644
> --- a/tests/qtest/aspeed_hace-test.c
> +++ b/tests/qtest/aspeed_hace-test.c
> @@ -44,6 +44,16 @@ static void test_sha256_sg_ast2600(void)
>       aspeed_test_sha256_sg("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
>   }
>   
> +static void test_sha384_ast2600(void)
> +{
> +    aspeed_test_sha384("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
> +}
> +
> +static void test_sha384_sg_ast2600(void)
> +{
> +    aspeed_test_sha384_sg("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
> +}
> +
>   static void test_sha512_ast2600(void)
>   {
>       aspeed_test_sha512("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
> @@ -59,6 +69,11 @@ static void test_sha256_accum_ast2600(void)
>       aspeed_test_sha256_accum("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
>   }
>   
> +static void test_sha384_accum_ast2600(void)
> +{
> +    aspeed_test_sha384_accum("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
> +}
> +
>   static void test_sha512_accum_ast2600(void)
>   {
>       aspeed_test_sha512_accum("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
> @@ -117,13 +132,16 @@ int main(int argc, char **argv)
>   
>       qtest_add_func("ast2600/hace/addresses", test_addresses_ast2600);
>       qtest_add_func("ast2600/hace/sha512", test_sha512_ast2600);
> +    qtest_add_func("ast2600/hace/sha384", test_sha384_ast2600);
>       qtest_add_func("ast2600/hace/sha256", test_sha256_ast2600);
>       qtest_add_func("ast2600/hace/md5", test_md5_ast2600);
>   
>       qtest_add_func("ast2600/hace/sha512_sg", test_sha512_sg_ast2600);
> +    qtest_add_func("ast2600/hace/sha384_sg", test_sha384_sg_ast2600);
>       qtest_add_func("ast2600/hace/sha256_sg", test_sha256_sg_ast2600);
>   
>       qtest_add_func("ast2600/hace/sha512_accum", test_sha512_accum_ast2600);
> +    qtest_add_func("ast2600/hace/sha384_accum", test_sha384_accum_ast2600);
>       qtest_add_func("ast2600/hace/sha256_accum", test_sha256_accum_ast2600);
>   
>       qtest_add_func("ast2500/hace/addresses", test_addresses_ast2500);



^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v1 18/22] test/qtest/hace: Update source data and digest data type to 64-bit
  2025-03-21  9:26 ` [PATCH v1 18/22] test/qtest/hace: Update source data and digest data type to 64-bit Jamin Lin via
@ 2025-04-02  9:05   ` Cédric Le Goater
  2025-05-12  7:14     ` Jamin Lin
  0 siblings, 1 reply; 71+ messages in thread
From: Cédric Le Goater @ 2025-04-02  9:05 UTC (permalink / raw)
  To: Jamin Lin, Peter Maydell, Steven Lee, Troy Lee, Andrew Jeffery,
	Joel Stanley, Fabiano Rosas, Laurent Vivier, Paolo Bonzini,
	open list:ASPEED BMCs, open list:All patches CC here
  Cc: troy_lee

On 3/21/25 10:26, Jamin Lin wrote:
> Currently, the hash data source and digest result buffer addresses are set to
> 32-bit. However, the AST2700 CPU is a 64-bit Cortex-A35 architecture, and its
> DRAM base address is also 64-bit.
> 
> To support AST2700, update the hash data source address and digest result buffer
> address to use 64-bit addressing.
> 
> Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
> ---
>   tests/qtest/aspeed-hace-utils.h | 20 +++----
>   tests/qtest/aspeed-hace-utils.c | 96 ++++++++++++++++-----------------
>   2 files changed, 58 insertions(+), 58 deletions(-)
> 
> diff --git a/tests/qtest/aspeed-hace-utils.h b/tests/qtest/aspeed-hace-utils.h
> index f4440561de..0382570fa2 100644
> --- a/tests/qtest/aspeed-hace-utils.h
> +++ b/tests/qtest/aspeed-hace-utils.h
> @@ -51,25 +51,25 @@ struct AspeedMasks {
>   };
>   
>   void aspeed_test_md5(const char *machine, const uint32_t base,
> -                     const uint32_t src_addr);
> +                     const uint64_t src_addr);
>   void aspeed_test_sha256(const char *machine, const uint32_t base,
> -                        const uint32_t src_addr);
> +                        const uint64_t src_addr);
>   void aspeed_test_sha384(const char *machine, const uint32_t base,
> -                        const uint32_t src_addr);
> +                        const uint64_t src_addr);
>   void aspeed_test_sha512(const char *machine, const uint32_t base,
> -                        const uint32_t src_addr);
> +                        const uint64_t src_addr);
>   void aspeed_test_sha256_sg(const char *machine, const uint32_t base,
> -                           const uint32_t src_addr);
> +                           const uint64_t src_addr);
>   void aspeed_test_sha384_sg(const char *machine, const uint32_t base,
> -                           const uint32_t src_addr);
> +                           const uint64_t src_addr);
>   void aspeed_test_sha512_sg(const char *machine, const uint32_t base,
> -                           const uint32_t src_addr);
> +                           const uint64_t src_addr);
>   void aspeed_test_sha256_accum(const char *machine, const uint32_t base,
> -                              const uint32_t src_addr);
> +                              const uint64_t src_addr);
>   void aspeed_test_sha384_accum(const char *machine, const uint32_t base,
> -                              const uint32_t src_addr);
> +                              const uint64_t src_addr);
>   void aspeed_test_sha512_accum(const char *machine, const uint32_t base,
> -                              const uint32_t src_addr);
> +                              const uint64_t src_addr);
>   void aspeed_test_addresses(const char *machine, const uint32_t base,
>                              const struct AspeedMasks *expected);
>   
> diff --git a/tests/qtest/aspeed-hace-utils.c b/tests/qtest/aspeed-hace-utils.c
> index d3146898c2..f39bb8ea48 100644
> --- a/tests/qtest/aspeed-hace-utils.c
> +++ b/tests/qtest/aspeed-hace-utils.c
> @@ -153,22 +153,22 @@ static const uint8_t test_result_accum_sha256[] = {
>       0x5d, 0xae, 0x22, 0x23, 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
>       0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad};
>   
> -static void write_regs(QTestState *s, uint32_t base, uint32_t src,
> -                       uint32_t length, uint32_t out, uint32_t method)
> +static void write_regs(QTestState *s, uint32_t base, uint64_t src,
> +                       uint32_t length, uint64_t out, uint32_t method)
>   {
> -        qtest_writel(s, base + HACE_HASH_SRC, src);
> -        qtest_writel(s, base + HACE_HASH_DIGEST, out);
> +        qtest_writel(s, base + HACE_HASH_SRC, extract64(src, 0, 32));
> +        qtest_writel(s, base + HACE_HASH_DIGEST, extract64(out, 0, 32));
>           qtest_writel(s, base + HACE_HASH_DATA_LEN, length);
>           qtest_writel(s, base + HACE_HASH_CMD, HACE_SHA_BE_EN | method);
>   }
>   
>   void aspeed_test_md5(const char *machine, const uint32_t base,
> -                     const uint32_t src_addr)
> +                     const uint64_t src_addr)
>   
>   {
>       QTestState *s = qtest_init(machine);
>   
> -    uint32_t digest_addr = src_addr + 0x010000;
> +    uint64_t digest_addr = src_addr + 0x010000;
>       uint8_t digest[16] = {0};
>   
>       /* Check engine is idle, no busy or irq bits set */
> @@ -198,11 +198,11 @@ void aspeed_test_md5(const char *machine, const uint32_t base,
>   }
>   
>   void aspeed_test_sha256(const char *machine, const uint32_t base,
> -                        const uint32_t src_addr)
> +                        const uint64_t src_addr)
>   {
>       QTestState *s = qtest_init(machine);
>   
> -    const uint32_t digest_addr = src_addr + 0x10000;
> +    const uint64_t digest_addr = src_addr + 0x10000;
>       uint8_t digest[32] = {0};
>   
>       /* Check engine is idle, no busy or irq bits set */
> @@ -232,11 +232,11 @@ void aspeed_test_sha256(const char *machine, const uint32_t base,
>   }
>   
>   void aspeed_test_sha384(const char *machine, const uint32_t base,
> -                        const uint32_t src_addr)
> +                        const uint64_t src_addr)
>   {
>       QTestState *s = qtest_init(machine);
>   
> -    const uint32_t digest_addr = src_addr + 0x10000;
> +    const uint64_t digest_addr = src_addr + 0x10000;
>       uint8_t digest[32] = {0};
>   
>       /* Check engine is idle, no busy or irq bits set */
> @@ -266,11 +266,11 @@ void aspeed_test_sha384(const char *machine, const uint32_t base,
>   }
>   
>   void aspeed_test_sha512(const char *machine, const uint32_t base,
> -                        const uint32_t src_addr)
> +                        const uint64_t src_addr)
>   {
>       QTestState *s = qtest_init(machine);
>   
> -    const uint32_t digest_addr = src_addr + 0x10000;
> +    const uint64_t digest_addr = src_addr + 0x10000;
>       uint8_t digest[64] = {0};
>   
>       /* Check engine is idle, no busy or irq bits set */
> @@ -300,22 +300,22 @@ void aspeed_test_sha512(const char *machine, const uint32_t base,
>   }
>   
>   void aspeed_test_sha256_sg(const char *machine, const uint32_t base,
> -                           const uint32_t src_addr)
> +                           const uint64_t src_addr)
>   {
>       QTestState *s = qtest_init(machine);
>   
> -    const uint32_t src_addr_1 = src_addr + 0x10000;
> -    const uint32_t src_addr_2 = src_addr + 0x20000;
> -    const uint32_t src_addr_3 = src_addr + 0x30000;
> -    const uint32_t digest_addr = src_addr + 0x40000;
> +    const uint64_t src_addr_1 = src_addr + 0x10000;
> +    const uint64_t src_addr_2 = src_addr + 0x20000;
> +    const uint64_t src_addr_3 = src_addr + 0x30000;
> +    const uint64_t digest_addr = src_addr + 0x40000;
>       uint8_t digest[32] = {0};
>       struct AspeedSgList array[] = {
>           {  cpu_to_le32(sizeof(test_vector_sg1)),
> -           cpu_to_le32(src_addr_1) },
> +           cpu_to_le64(src_addr_1) },


This looks broken to me. The addr field is in the scatter-gather list entry
is 32bit :

   struct AspeedSgList {
           uint32_t len;
           uint32_t addr;
   } __attribute__ ((__packed__));



Thanks,

C.


>           {  cpu_to_le32(sizeof(test_vector_sg2)),
> -           cpu_to_le32(src_addr_2) },
> +           cpu_to_le64(src_addr_2) },
>           {  cpu_to_le32(sizeof(test_vector_sg3) | SG_LIST_LEN_LAST),
> -           cpu_to_le32(src_addr_3) },
> +           cpu_to_le64(src_addr_3) },
>       };
>   
>       /* Check engine is idle, no busy or irq bits set */
> @@ -351,22 +351,22 @@ void aspeed_test_sha256_sg(const char *machine, const uint32_t base,
>   }
>   
>   void aspeed_test_sha384_sg(const char *machine, const uint32_t base,
> -                           const uint32_t src_addr)
> +                           const uint64_t src_addr)
>   {
>       QTestState *s = qtest_init(machine);
>   
> -    const uint32_t src_addr_1 = src_addr + 0x10000;
> -    const uint32_t src_addr_2 = src_addr + 0x20000;
> -    const uint32_t src_addr_3 = src_addr + 0x30000;
> -    const uint32_t digest_addr = src_addr + 0x40000;
> +    const uint64_t src_addr_1 = src_addr + 0x10000;
> +    const uint64_t src_addr_2 = src_addr + 0x20000;
> +    const uint64_t src_addr_3 = src_addr + 0x30000;
> +    const uint64_t digest_addr = src_addr + 0x40000;
>       uint8_t digest[64] = {0};
>       struct AspeedSgList array[] = {
>           {  cpu_to_le32(sizeof(test_vector_sg1)),
> -           cpu_to_le32(src_addr_1) },
> +           cpu_to_le64(src_addr_1) },
>           {  cpu_to_le32(sizeof(test_vector_sg2)),
> -           cpu_to_le32(src_addr_2) },
> +           cpu_to_le64(src_addr_2) },
>           {  cpu_to_le32(sizeof(test_vector_sg3) | SG_LIST_LEN_LAST),
> -           cpu_to_le32(src_addr_3) },
> +           cpu_to_le64(src_addr_3) },
>       };
>   
>       /* Check engine is idle, no busy or irq bits set */
> @@ -402,22 +402,22 @@ void aspeed_test_sha384_sg(const char *machine, const uint32_t base,
>   }
>   
>   void aspeed_test_sha512_sg(const char *machine, const uint32_t base,
> -                           const uint32_t src_addr)
> +                           const uint64_t src_addr)
>   {
>       QTestState *s = qtest_init(machine);
>   
> -    const uint32_t src_addr_1 = src_addr + 0x10000;
> -    const uint32_t src_addr_2 = src_addr + 0x20000;
> -    const uint32_t src_addr_3 = src_addr + 0x30000;
> -    const uint32_t digest_addr = src_addr + 0x40000;
> +    const uint64_t src_addr_1 = src_addr + 0x10000;
> +    const uint64_t src_addr_2 = src_addr + 0x20000;
> +    const uint64_t src_addr_3 = src_addr + 0x30000;
> +    const uint64_t digest_addr = src_addr + 0x40000;
>       uint8_t digest[64] = {0};
>       struct AspeedSgList array[] = {
>           {  cpu_to_le32(sizeof(test_vector_sg1)),
> -           cpu_to_le32(src_addr_1) },
> +           cpu_to_le64(src_addr_1) },
>           {  cpu_to_le32(sizeof(test_vector_sg2)),
> -           cpu_to_le32(src_addr_2) },
> +           cpu_to_le64(src_addr_2) },
>           {  cpu_to_le32(sizeof(test_vector_sg3) | SG_LIST_LEN_LAST),
> -           cpu_to_le32(src_addr_3) },
> +           cpu_to_le64(src_addr_3) },
>       };
>   
>       /* Check engine is idle, no busy or irq bits set */
> @@ -453,16 +453,16 @@ void aspeed_test_sha512_sg(const char *machine, const uint32_t base,
>   }
>   
>   void aspeed_test_sha256_accum(const char *machine, const uint32_t base,
> -                              const uint32_t src_addr)
> +                              const uint64_t src_addr)
>   {
>       QTestState *s = qtest_init(machine);
>   
> -    const uint32_t buffer_addr = src_addr + 0x10000;
> -    const uint32_t digest_addr = src_addr + 0x40000;
> +    const uint64_t buffer_addr = src_addr + 0x10000;
> +    const uint64_t digest_addr = src_addr + 0x40000;
>       uint8_t digest[32] = {0};
>       struct AspeedSgList array[] = {
>           {  cpu_to_le32(sizeof(test_vector_accum_256) | SG_LIST_LEN_LAST),
> -           cpu_to_le32(buffer_addr) },
> +           cpu_to_le64(buffer_addr) },
>       };
>   
>       /* Check engine is idle, no busy or irq bits set */
> @@ -494,16 +494,16 @@ void aspeed_test_sha256_accum(const char *machine, const uint32_t base,
>   }
>   
>   void aspeed_test_sha384_accum(const char *machine, const uint32_t base,
> -                              const uint32_t src_addr)
> +                              const uint64_t src_addr)
>   {
>       QTestState *s = qtest_init(machine);
>   
> -    const uint32_t buffer_addr = src_addr + 0x10000;
> -    const uint32_t digest_addr = src_addr + 0x40000;
> +    const uint64_t buffer_addr = src_addr + 0x10000;
> +    const uint64_t digest_addr = src_addr + 0x40000;
>       uint8_t digest[64] = {0};
>       struct AspeedSgList array[] = {
>           {  cpu_to_le32(sizeof(test_vector_accum_384) | SG_LIST_LEN_LAST),
> -           cpu_to_le32(buffer_addr) },
> +           cpu_to_le64(buffer_addr) },
>       };
>   
>       /* Check engine is idle, no busy or irq bits set */
> @@ -535,16 +535,16 @@ void aspeed_test_sha384_accum(const char *machine, const uint32_t base,
>   }
>   
>   void aspeed_test_sha512_accum(const char *machine, const uint32_t base,
> -                              const uint32_t src_addr)
> +                              const uint64_t src_addr)
>   {
>       QTestState *s = qtest_init(machine);
>   
> -    const uint32_t buffer_addr = src_addr + 0x10000;
> -    const uint32_t digest_addr = src_addr + 0x40000;
> +    const uint64_t buffer_addr = src_addr + 0x10000;
> +    const uint64_t digest_addr = src_addr + 0x40000;
>       uint8_t digest[64] = {0};
>       struct AspeedSgList array[] = {
>           {  cpu_to_le32(sizeof(test_vector_accum_512) | SG_LIST_LEN_LAST),
> -           cpu_to_le32(buffer_addr) },
> +           cpu_to_le64(buffer_addr) },
>       };
>   
>       /* Check engine is idle, no busy or irq bits set */



^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v1 19/22] test/qtest/hace: Support 64-bit source and digest addresses for AST2700
  2025-03-21  9:26 ` [PATCH v1 19/22] test/qtest/hace: Support 64-bit source and digest addresses for AST2700 Jamin Lin via
@ 2025-04-02  9:06   ` Cédric Le Goater
  0 siblings, 0 replies; 71+ messages in thread
From: Cédric Le Goater @ 2025-04-02  9:06 UTC (permalink / raw)
  To: Jamin Lin, Peter Maydell, Steven Lee, Troy Lee, Andrew Jeffery,
	Joel Stanley, Fabiano Rosas, Laurent Vivier, Paolo Bonzini,
	open list:ASPEED BMCs, open list:All patches CC here
  Cc: troy_lee

On 3/21/25 10:26, Jamin Lin wrote:
> Added "HACE_HASH_SRC_HI" and "HACE_HASH_DIGEST_HI", "HACE_HASH_KEY_BUFF_HI"
> registers to store upper 32 bits.
> Updated "write_regs" to handle 64-bit source and digest addresses.
> 
> Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>


Reviewed-by: Cédric Le Goater <clg@redhat.com>

Thanks,

C.


> ---
>   tests/qtest/aspeed-hace-utils.h | 3 +++
>   tests/qtest/aspeed-hace-utils.c | 2 ++
>   2 files changed, 5 insertions(+)
> 
> diff --git a/tests/qtest/aspeed-hace-utils.h b/tests/qtest/aspeed-hace-utils.h
> index 0382570fa2..d8684d3f83 100644
> --- a/tests/qtest/aspeed-hace-utils.h
> +++ b/tests/qtest/aspeed-hace-utils.h
> @@ -36,6 +36,9 @@
>   #define HACE_HASH_KEY_BUFF       0x28
>   #define HACE_HASH_DATA_LEN       0x2c
>   #define HACE_HASH_CMD            0x30
> +#define HACE_HASH_SRC_HI         0x90
> +#define HACE_HASH_DIGEST_HI      0x94
> +#define HACE_HASH_KEY_BUFF_HI    0x98
>   
>   /* Scatter-Gather Hash */
>   #define SG_LIST_LEN_LAST         BIT(31)
> diff --git a/tests/qtest/aspeed-hace-utils.c b/tests/qtest/aspeed-hace-utils.c
> index f39bb8ea48..8d9c464f72 100644
> --- a/tests/qtest/aspeed-hace-utils.c
> +++ b/tests/qtest/aspeed-hace-utils.c
> @@ -157,7 +157,9 @@ static void write_regs(QTestState *s, uint32_t base, uint64_t src,
>                          uint32_t length, uint64_t out, uint32_t method)
>   {
>           qtest_writel(s, base + HACE_HASH_SRC, extract64(src, 0, 32));
> +        qtest_writel(s, base + HACE_HASH_SRC_HI, extract64(src, 32, 32));
>           qtest_writel(s, base + HACE_HASH_DIGEST, extract64(out, 0, 32));
> +        qtest_writel(s, base + HACE_HASH_DIGEST_HI, extract64(out, 32, 32));
>           qtest_writel(s, base + HACE_HASH_DATA_LEN, length);
>           qtest_writel(s, base + HACE_HASH_CMD, HACE_SHA_BE_EN | method);
>   }



^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v1 20/22] test/qtest/hace: Support to test upper 32 bits of digest and source addresses
  2025-03-21  9:26 ` [PATCH v1 20/22] test/qtest/hace: Support to test upper 32 bits of digest and source addresses Jamin Lin via
@ 2025-04-02  9:12   ` Cédric Le Goater
  0 siblings, 0 replies; 71+ messages in thread
From: Cédric Le Goater @ 2025-04-02  9:12 UTC (permalink / raw)
  To: Jamin Lin, Peter Maydell, Steven Lee, Troy Lee, Andrew Jeffery,
	Joel Stanley, Fabiano Rosas, Laurent Vivier, Paolo Bonzini,
	open list:ASPEED BMCs, open list:All patches CC here
  Cc: troy_lee

On 3/21/25 10:26, Jamin Lin wrote:
> Added "src_hi" and "dest_hi" fields to "AspeedMasks" for 64-bit addresses test.
> Updated "aspeed_test_addresses" to validate "HACE_HASH_SRC_HI" and
> "HACE_HASH_DIGEST_HI".
> Ensured correct masking of 64-bit addresses by checking both lower and upper
> 32-bit registers.
> 
> Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>


Reviewed-by: Cédric Le Goater <clg@redhat.com>

Thanks,

C.


> ---
>   tests/qtest/aspeed-hace-utils.h |  2 ++
>   tests/qtest/aspeed-hace-utils.c | 15 ++++++++++++++-
>   2 files changed, 16 insertions(+), 1 deletion(-)
> 
> diff --git a/tests/qtest/aspeed-hace-utils.h b/tests/qtest/aspeed-hace-utils.h
> index d8684d3f83..de8055a1db 100644
> --- a/tests/qtest/aspeed-hace-utils.h
> +++ b/tests/qtest/aspeed-hace-utils.h
> @@ -51,6 +51,8 @@ struct AspeedMasks {
>       uint32_t src;
>       uint32_t dest;
>       uint32_t len;
> +    uint32_t src_hi;
> +    uint32_t dest_hi;
>   };
>   
>   void aspeed_test_md5(const char *machine, const uint32_t base,
> diff --git a/tests/qtest/aspeed-hace-utils.c b/tests/qtest/aspeed-hace-utils.c
> index 8d9c464f72..fc209353f3 100644
> --- a/tests/qtest/aspeed-hace-utils.c
> +++ b/tests/qtest/aspeed-hace-utils.c
> @@ -588,30 +588,43 @@ void aspeed_test_addresses(const char *machine, const uint32_t base,
>        */
>       g_assert_cmphex(qtest_readl(s, base + HACE_CMD), ==, 0);
>       g_assert_cmphex(qtest_readl(s, base + HACE_HASH_SRC), ==, 0);
> +    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_SRC_HI), ==, 0);
>       g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DIGEST), ==, 0);
> +    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DIGEST_HI), ==, 0);
>       g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DATA_LEN), ==, 0);
>   
> -
>       /* Check that the address masking is correct */
>       qtest_writel(s, base + HACE_HASH_SRC, 0xffffffff);
>       g_assert_cmphex(qtest_readl(s, base + HACE_HASH_SRC), ==, expected->src);
>   
> +    qtest_writel(s, base + HACE_HASH_SRC_HI, 0xffffffff);
> +    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_SRC_HI),
> +                    ==, expected->src_hi);
> +
>       qtest_writel(s, base + HACE_HASH_DIGEST, 0xffffffff);
>       g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DIGEST), ==,
>                       expected->dest);
>   
> +    qtest_writel(s, base + HACE_HASH_DIGEST_HI, 0xffffffff);
> +    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DIGEST_HI), ==,
> +                    expected->dest_hi);
> +
>       qtest_writel(s, base + HACE_HASH_DATA_LEN, 0xffffffff);
>       g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DATA_LEN), ==,
>                       expected->len);
>   
>       /* Reset to zero */
>       qtest_writel(s, base + HACE_HASH_SRC, 0);
> +    qtest_writel(s, base + HACE_HASH_SRC_HI, 0);
>       qtest_writel(s, base + HACE_HASH_DIGEST, 0);
> +    qtest_writel(s, base + HACE_HASH_DIGEST_HI, 0);
>       qtest_writel(s, base + HACE_HASH_DATA_LEN, 0);
>   
>       /* Check that all bits are now zero */
>       g_assert_cmphex(qtest_readl(s, base + HACE_HASH_SRC), ==, 0);
> +    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_SRC_HI), ==, 0);
>       g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DIGEST), ==, 0);
> +    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DIGEST_HI), ==, 0);
>       g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DATA_LEN), ==, 0);
>   
>       qtest_quit(s);



^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v1 21/22] test/qtest/hace: Support to validate 64-bit hmac key buffer addresses
  2025-03-21  9:26 ` [PATCH v1 21/22] test/qtest/hace: Support to validate 64-bit hmac key buffer addresses Jamin Lin via
@ 2025-04-02  9:12   ` Cédric Le Goater
  0 siblings, 0 replies; 71+ messages in thread
From: Cédric Le Goater @ 2025-04-02  9:12 UTC (permalink / raw)
  To: Jamin Lin, Peter Maydell, Steven Lee, Troy Lee, Andrew Jeffery,
	Joel Stanley, Fabiano Rosas, Laurent Vivier, Paolo Bonzini,
	open list:ASPEED BMCs, open list:All patches CC here
  Cc: troy_lee

On 3/21/25 10:26, Jamin Lin wrote:
> Added "key" and "key_hi" fields to "AspeedMasks" for 64-bit addresses test.
> Updated "aspeed_test_addresses" to validate "HACE_HASH_KEY_BUFF" and
> "HACE_HASH_KEY_BUFF_HI".
> Ensured correct masking of 64-bit addresses by checking both lower and upper
> 32-bit registers.
> 
> Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>


Reviewed-by: Cédric Le Goater <clg@redhat.com>

Thanks,

C.


> ---
>   tests/qtest/aspeed-hace-utils.h |  2 ++
>   tests/qtest/aspeed-hace-utils.c | 14 ++++++++++++++
>   tests/qtest/aspeed_hace-test.c  |  4 ++++
>   3 files changed, 20 insertions(+)
> 
> diff --git a/tests/qtest/aspeed-hace-utils.h b/tests/qtest/aspeed-hace-utils.h
> index de8055a1db..c8b2ec45af 100644
> --- a/tests/qtest/aspeed-hace-utils.h
> +++ b/tests/qtest/aspeed-hace-utils.h
> @@ -50,9 +50,11 @@ struct AspeedSgList {
>   struct AspeedMasks {
>       uint32_t src;
>       uint32_t dest;
> +    uint32_t key;
>       uint32_t len;
>       uint32_t src_hi;
>       uint32_t dest_hi;
> +    uint32_t key_hi;
>   };
>   
>   void aspeed_test_md5(const char *machine, const uint32_t base,
> diff --git a/tests/qtest/aspeed-hace-utils.c b/tests/qtest/aspeed-hace-utils.c
> index fc209353f3..a5ece614ed 100644
> --- a/tests/qtest/aspeed-hace-utils.c
> +++ b/tests/qtest/aspeed-hace-utils.c
> @@ -591,6 +591,8 @@ void aspeed_test_addresses(const char *machine, const uint32_t base,
>       g_assert_cmphex(qtest_readl(s, base + HACE_HASH_SRC_HI), ==, 0);
>       g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DIGEST), ==, 0);
>       g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DIGEST_HI), ==, 0);
> +    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_KEY_BUFF), ==, 0);
> +    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_KEY_BUFF_HI), ==, 0);
>       g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DATA_LEN), ==, 0);
>   
>       /* Check that the address masking is correct */
> @@ -609,6 +611,14 @@ void aspeed_test_addresses(const char *machine, const uint32_t base,
>       g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DIGEST_HI), ==,
>                       expected->dest_hi);
>   
> +    qtest_writel(s, base + HACE_HASH_KEY_BUFF, 0xffffffff);
> +    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_KEY_BUFF), ==,
> +                    expected->key);
> +
> +    qtest_writel(s, base + HACE_HASH_KEY_BUFF_HI, 0xffffffff);
> +    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_KEY_BUFF_HI), ==,
> +                    expected->key_hi);
> +
>       qtest_writel(s, base + HACE_HASH_DATA_LEN, 0xffffffff);
>       g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DATA_LEN), ==,
>                       expected->len);
> @@ -618,6 +628,8 @@ void aspeed_test_addresses(const char *machine, const uint32_t base,
>       qtest_writel(s, base + HACE_HASH_SRC_HI, 0);
>       qtest_writel(s, base + HACE_HASH_DIGEST, 0);
>       qtest_writel(s, base + HACE_HASH_DIGEST_HI, 0);
> +    qtest_writel(s, base + HACE_HASH_KEY_BUFF, 0);
> +    qtest_writel(s, base + HACE_HASH_KEY_BUFF_HI, 0);
>       qtest_writel(s, base + HACE_HASH_DATA_LEN, 0);
>   
>       /* Check that all bits are now zero */
> @@ -625,6 +637,8 @@ void aspeed_test_addresses(const char *machine, const uint32_t base,
>       g_assert_cmphex(qtest_readl(s, base + HACE_HASH_SRC_HI), ==, 0);
>       g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DIGEST), ==, 0);
>       g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DIGEST_HI), ==, 0);
> +    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_KEY_BUFF), ==, 0);
> +    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_KEY_BUFF_HI), ==, 0);
>       g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DATA_LEN), ==, 0);
>   
>       qtest_quit(s);
> diff --git a/tests/qtest/aspeed_hace-test.c b/tests/qtest/aspeed_hace-test.c
> index 31890d574e..38777020ca 100644
> --- a/tests/qtest/aspeed_hace-test.c
> +++ b/tests/qtest/aspeed_hace-test.c
> @@ -13,24 +13,28 @@
>   static const struct AspeedMasks ast1030_masks = {
>       .src  = 0x7fffffff,
>       .dest = 0x7ffffff8,
> +    .key = 0x7ffffff8,
>       .len  = 0x0fffffff,
>   };
>   
>   static const struct AspeedMasks ast2600_masks = {
>       .src  = 0x7fffffff,
>       .dest = 0x7ffffff8,
> +    .key = 0x7ffffff8,
>       .len  = 0x0fffffff,
>   };
>   
>   static const struct AspeedMasks ast2500_masks = {
>       .src  = 0x3fffffff,
>       .dest = 0x3ffffff8,
> +    .key = 0x3fffffc0,
>       .len  = 0x0fffffff,
>   };
>   
>   static const struct AspeedMasks ast2400_masks = {
>       .src  = 0x0fffffff,
>       .dest = 0x0ffffff8,
> +    .key = 0x0fffffc0,
>       .len  = 0x0fffffff,
>   };
>   



^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v1 22/22] test/qtest/hace: Add tests for AST2700
  2025-03-21  9:26 ` [PATCH v1 22/22] test/qtest/hace: Add tests for AST2700 Jamin Lin via
@ 2025-04-02  9:16   ` Cédric Le Goater
  0 siblings, 0 replies; 71+ messages in thread
From: Cédric Le Goater @ 2025-04-02  9:16 UTC (permalink / raw)
  To: Jamin Lin, Peter Maydell, Steven Lee, Troy Lee, Andrew Jeffery,
	Joel Stanley, Fabiano Rosas, Laurent Vivier, Paolo Bonzini,
	open list:ASPEED BMCs, open list:All patches CC here
  Cc: troy_lee

On 3/21/25 10:26, Jamin Lin wrote:
> The HACE models in AST2600 and AST2700 are nearly identical. Based on the
> AST2600 test cases, new tests have been added for AST2700.
> 
> Implemented test functions for SHA-256, SHA-384, SHA-512, and MD5.
> Added scatter-gather and accumulation test variants.
> For AST2700, the HACE controller base address starts at "0x12070000", and
> the DRAM start address is "0x4_00000000".
> 
> Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
> ---
>   tests/qtest/ast2700-hace-test.c | 98 +++++++++++++++++++++++++++++++++
>   tests/qtest/meson.build         |  4 +-
>   2 files changed, 101 insertions(+), 1 deletion(-)
>   create mode 100644 tests/qtest/ast2700-hace-test.c
> 
> diff --git a/tests/qtest/ast2700-hace-test.c b/tests/qtest/ast2700-hace-test.c
> new file mode 100644
> index 0000000000..a400e2962b
> --- /dev/null
> +++ b/tests/qtest/ast2700-hace-test.c
> @@ -0,0 +1,98 @@
> +/*
> + * QTest testcase for the ASPEED Hash and Crypto Engine
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + * Copyright (C) 2025 ASPEED Technology Inc.
> + */
> +
> +#include "qemu/osdep.h"
> +#include "libqtest.h"
> +#include "qemu/bitops.h"
> +#include "aspeed-hace-utils.h"
> +
> +static const struct AspeedMasks as2700_masks = {
> +    .src  = 0x7fffffff,
> +    .dest = 0x7ffffff8,
> +    .key = 0x7ffffff8,
> +    .len  = 0x0fffffff,
> +    .src_hi  = 0x00000003,
> +    .dest_hi = 0x00000003,
> +    .key_hi = 0x00000003,
> +};
> +
> +/* ast2700 */
> +static void test_md5_ast2700(void)
> +{
> +    aspeed_test_md5("-machine ast2700a1-evb", 0x12070000, 0x400000000);
> +}
> +
> +static void test_sha256_ast2700(void)
> +{
> +    aspeed_test_sha256("-machine ast2700a1-evb", 0x12070000, 0x400000000);
> +}
> +
> +static void test_sha256_sg_ast2700(void)
> +{
> +    aspeed_test_sha256_sg("-machine ast2700a1-evb", 0x12070000, 0x400000000);
> +}
> +
> +static void test_sha384_ast2700(void)
> +{
> +    aspeed_test_sha384("-machine ast2700a1-evb", 0x12070000, 0x400000000);
> +}
> +
> +static void test_sha384_sg_ast2700(void)
> +{
> +    aspeed_test_sha384_sg("-machine ast2700a1-evb", 0x12070000, 0x400000000);
> +}
> +
> +static void test_sha512_ast2700(void)
> +{
> +    aspeed_test_sha512("-machine ast2700a1-evb", 0x12070000, 0x400000000);
> +}
> +
> +static void test_sha512_sg_ast2700(void)
> +{
> +    aspeed_test_sha512_sg("-machine ast2700a1-evb", 0x12070000, 0x400000000);
> +}
> +
> +static void test_sha256_accum_ast2700(void)
> +{
> +    aspeed_test_sha256_accum("-machine ast2700a1-evb", 0x12070000, 0x400000000);
> +}
> +
> +static void test_sha384_accum_ast2700(void)
> +{
> +    aspeed_test_sha384_accum("-machine ast2700a1-evb", 0x12070000, 0x400000000);
> +}
> +
> +static void test_sha512_accum_ast2700(void)
> +{
> +    aspeed_test_sha512_accum("-machine ast2700a1-evb", 0x12070000, 0x400000000);
> +}
> +
> +static void test_addresses_ast2700(void)
> +{
> +    aspeed_test_addresses("-machine ast2700a1-evb", 0x12070000, &as2700_masks);
> +}
> +
> +int main(int argc, char **argv)
> +{
> +    g_test_init(&argc, &argv, NULL);
> +
> +    qtest_add_func("ast2700/hace/addresses", test_addresses_ast2700);
> +    qtest_add_func("ast2700/hace/sha512", test_sha512_ast2700);
> +    qtest_add_func("ast2700/hace/sha384", test_sha384_ast2700);
> +    qtest_add_func("ast2700/hace/sha256", test_sha256_ast2700);
> +    qtest_add_func("ast2700/hace/md5", test_md5_ast2700);
> +
> +    qtest_add_func("ast2700/hace/sha512_sg", test_sha512_sg_ast2700);
> +    qtest_add_func("ast2700/hace/sha384_sg", test_sha384_sg_ast2700);
> +    qtest_add_func("ast2700/hace/sha256_sg", test_sha256_sg_ast2700);
> +
> +    qtest_add_func("ast2700/hace/sha512_accum", test_sha512_accum_ast2700);
> +    qtest_add_func("ast2700/hace/sha384_accum", test_sha384_accum_ast2700);
> +    qtest_add_func("ast2700/hace/sha256_accum", test_sha256_accum_ast2700);
> +
> +    return g_test_run();
> +}
> diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
> index 62fc8f9868..253d37f7bd 100644
> --- a/tests/qtest/meson.build
> +++ b/tests/qtest/meson.build
> @@ -218,7 +218,8 @@ qtests_aspeed = \
>      'aspeed_gpio-test']
>   qtests_aspeed64 = \
>     ['ast2700-gpio-test',
> -   'ast2700-smc-test']
> +   'ast2700-smc-test',
> +   'ast2700-hace-test']

I would keep the alphabetical order.

Anyhow,


Reviewed-by: Cédric Le Goater <clg@redhat.com>

Thanks,

C.



>   
>   qtests_stm32l4x5 = \
>     ['stm32l4x5_exti-test',
> @@ -384,6 +385,7 @@ qtests = {
>     'aspeed_smc-test': files('aspeed-smc-utils.c', 'aspeed_smc-test.c'),
>     'ast2700-smc-test': files('aspeed-smc-utils.c', 'ast2700-smc-test.c'),
>     'aspeed_hace-test': files('aspeed-hace-utils.c', 'aspeed_hace-test.c'),
> +  'ast2700-hace-test': files('aspeed-hace-utils.c', 'ast2700-hace-test.c'),
>   }
>   
>   if vnc.found()



^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v1 09/22] hw/misc/aspeed_hace: Ensure HASH_IRQ is always set to prevent firmware hang
  2025-03-21  9:26 ` [PATCH v1 09/22] hw/misc/aspeed_hace: Ensure HASH_IRQ is always set to prevent firmware hang Jamin Lin via
@ 2025-04-02  9:35   ` Cédric Le Goater
  2025-05-06  5:08     ` Jamin Lin
  0 siblings, 1 reply; 71+ messages in thread
From: Cédric Le Goater @ 2025-04-02  9:35 UTC (permalink / raw)
  To: Jamin Lin, Peter Maydell, Steven Lee, Troy Lee, Andrew Jeffery,
	Joel Stanley, Fabiano Rosas, Laurent Vivier, Paolo Bonzini,
	open list:ASPEED BMCs, open list:All patches CC here
  Cc: troy_lee

On 3/21/25 10:26, Jamin Lin wrote:
> Currently, if the program encounters an unsupported algorithm, it does not set
> the HASH_IRQ bit in the status register and send an interrupt to indicate
> command completion. As a result, the FW gets stuck waiting for a completion
> signal from the HACE module.
> 
> Additionally, in do_hash_operation, if an error occurs within the conditional
> statement, the HASH_IRQ bit is not set in the status register. This causes the
> firmware to continuously send HASH commands, as it is unaware that the HACE
> model has completed processing the command.
> 
> To fix this, the HASH_IRQ bit in the status register must always be set to
> ensure that the firmware receives an interrupt from the HACE module, preventing
> it from getting stuck or repeatedly sending HASH commands.
> 
> Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>

Should we add a 'Fixes' trailer ?

> ---
>   hw/misc/aspeed_hace.c | 18 +++++++++---------
>   1 file changed, 9 insertions(+), 9 deletions(-)
> 
> diff --git a/hw/misc/aspeed_hace.c b/hw/misc/aspeed_hace.c
> index 8f333fc97e..d4f653670e 100644
> --- a/hw/misc/aspeed_hace.c
> +++ b/hw/misc/aspeed_hace.c
> @@ -311,12 +311,6 @@ static void do_hash_operation(AspeedHACEState *s, int algo, bool sg_mode,
>                               iov[i - 1].iov_len, false,
>                               iov[i - 1].iov_len);
>       }
> -
> -    /*
> -     * Set status bits to indicate completion. Testing shows hardware sets
> -     * these irrespective of HASH_IRQ_EN.
> -     */
> -    s->regs[R_STATUS] |= HASH_IRQ;
>   }
>   
>   static uint64_t aspeed_hace_read(void *opaque, hwaddr addr, unsigned int size)
> @@ -400,10 +394,16 @@ static void aspeed_hace_write(void *opaque, hwaddr addr, uint64_t data,
>                   qemu_log_mask(LOG_GUEST_ERROR,
>                           "%s: Invalid hash algorithm selection 0x%"PRIx64"\n",
>                           __func__, data & ahc->hash_mask);
> -                break;
> +        } else {
> +            do_hash_operation(s, algo, data & HASH_SG_EN,
> +                    ((data & HASH_HMAC_MASK) == HASH_DIGEST_ACCUM));
>           }
> -        do_hash_operation(s, algo, data & HASH_SG_EN,
> -                ((data & HASH_HMAC_MASK) == HASH_DIGEST_ACCUM));
> +
> +        /*
> +         * Set status bits to indicate completion. Testing shows hardware sets
> +         * these irrespective of HASH_IRQ_EN.

is that still true on the AST2700 SoC ?

> +         */
> +        s->regs[R_STATUS] |= HASH_IRQ;
>   >           if (data & HASH_IRQ_EN) {
>               qemu_irq_raise(s->irq);



Reviewed-by: Cédric Le Goater <clg@redhat.com>

Thanks,

C.




^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v1 14/22] test/qtest/hace: Adjust test address range for AST1030 due to SRAM limitations
  2025-03-21  9:26 ` [PATCH v1 14/22] test/qtest/hace: Adjust test address range for AST1030 due to SRAM limitations Jamin Lin via
@ 2025-04-02  9:43   ` Cédric Le Goater
  2025-05-05  3:44     ` Jamin Lin
  0 siblings, 1 reply; 71+ messages in thread
From: Cédric Le Goater @ 2025-04-02  9:43 UTC (permalink / raw)
  To: Jamin Lin, Peter Maydell, Steven Lee, Troy Lee, Andrew Jeffery,
	Joel Stanley, Fabiano Rosas, Laurent Vivier, Paolo Bonzini,
	open list:ASPEED BMCs, open list:All patches CC here
  Cc: troy_lee

On 3/21/25 10:26, Jamin Lin wrote:
> The digest_addr is set to "src_addr + 0x1000000", where src_addr is the DRAM
> base address. However, the value 0x1000000 (16MB) is too large because the
> AST1030 does not support DRAM, and its SRAM size is only 768KB.
> 
> A range size of 0x1000 (64KB) is sufficient for HACE test cases, as the test
> vector size does not exceed 64KB.
> 
> Updates:
> 1. Direct Access Mode
> Update digest_addr to "src_addr + 0x1000" in the following functions:

The change does src_addr + 0x10000. Can you please adjust the commit log
or the code ?


Thanks,

C.



> aspeed_test_md5
> aspeed_test_sha256
> aspeed_test_sha512
> 
> 2. Scatter-Gather (SG) Mode
> Update source address for different SG buffer addresses in the following
> functions:
> src_addr1 = src_addr + 0x1000
> src_addr2 = src_addr + 0x2000
> src_addr3 = src_addr + 0x3000
> digest_addr = src_addr + 0x4000
> 
> aspeed_test_sha256_sg
> aspeed_test_sha512_sg
> 
> 3. ACC Mode Update
> Update the SG List start address: src_addr + 0x10000
> Update the SG List buffer size to 0x3000 (192KB).
> 
> buffer_addr = src_addr + 0x10000
> digest_addr = src_addr + 0x40000
> 
> Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
> ---
>   tests/qtest/aspeed-hace-utils.c | 30 +++++++++++++++---------------
>   1 file changed, 15 insertions(+), 15 deletions(-)
> 
> diff --git a/tests/qtest/aspeed-hace-utils.c b/tests/qtest/aspeed-hace-utils.c
> index 8582847945..8fbbba49c1 100644
> --- a/tests/qtest/aspeed-hace-utils.c
> +++ b/tests/qtest/aspeed-hace-utils.c
> @@ -132,7 +132,7 @@ void aspeed_test_md5(const char *machine, const uint32_t base,
>   {
>       QTestState *s = qtest_init(machine);
>   
> -    uint32_t digest_addr = src_addr + 0x01000000;
> +    uint32_t digest_addr = src_addr + 0x010000;
>       uint8_t digest[16] = {0};
>   
>       /* Check engine is idle, no busy or irq bits set */
> @@ -166,7 +166,7 @@ void aspeed_test_sha256(const char *machine, const uint32_t base,
>   {
>       QTestState *s = qtest_init(machine);
>   
> -    const uint32_t digest_addr = src_addr + 0x1000000;
> +    const uint32_t digest_addr = src_addr + 0x10000;
>       uint8_t digest[32] = {0};
>   
>       /* Check engine is idle, no busy or irq bits set */
> @@ -200,7 +200,7 @@ void aspeed_test_sha512(const char *machine, const uint32_t base,
>   {
>       QTestState *s = qtest_init(machine);
>   
> -    const uint32_t digest_addr = src_addr + 0x1000000;
> +    const uint32_t digest_addr = src_addr + 0x10000;
>       uint8_t digest[64] = {0};
>   
>       /* Check engine is idle, no busy or irq bits set */
> @@ -234,10 +234,10 @@ void aspeed_test_sha256_sg(const char *machine, const uint32_t base,
>   {
>       QTestState *s = qtest_init(machine);
>   
> -    const uint32_t src_addr_1 = src_addr + 0x1000000;
> -    const uint32_t src_addr_2 = src_addr + 0x2000000;
> -    const uint32_t src_addr_3 = src_addr + 0x3000000;
> -    const uint32_t digest_addr = src_addr + 0x4000000;
> +    const uint32_t src_addr_1 = src_addr + 0x10000;
> +    const uint32_t src_addr_2 = src_addr + 0x20000;
> +    const uint32_t src_addr_3 = src_addr + 0x30000;
> +    const uint32_t digest_addr = src_addr + 0x40000;
>       uint8_t digest[32] = {0};
>       struct AspeedSgList array[] = {
>           {  cpu_to_le32(sizeof(test_vector_sg1)),
> @@ -285,10 +285,10 @@ void aspeed_test_sha512_sg(const char *machine, const uint32_t base,
>   {
>       QTestState *s = qtest_init(machine);
>   
> -    const uint32_t src_addr_1 = src_addr + 0x1000000;
> -    const uint32_t src_addr_2 = src_addr + 0x2000000;
> -    const uint32_t src_addr_3 = src_addr + 0x3000000;
> -    const uint32_t digest_addr = src_addr + 0x4000000;
> +    const uint32_t src_addr_1 = src_addr + 0x10000;
> +    const uint32_t src_addr_2 = src_addr + 0x20000;
> +    const uint32_t src_addr_3 = src_addr + 0x30000;
> +    const uint32_t digest_addr = src_addr + 0x40000;
>       uint8_t digest[64] = {0};
>       struct AspeedSgList array[] = {
>           {  cpu_to_le32(sizeof(test_vector_sg1)),
> @@ -336,8 +336,8 @@ void aspeed_test_sha256_accum(const char *machine, const uint32_t base,
>   {
>       QTestState *s = qtest_init(machine);
>   
> -    const uint32_t buffer_addr = src_addr + 0x1000000;
> -    const uint32_t digest_addr = src_addr + 0x4000000;
> +    const uint32_t buffer_addr = src_addr + 0x10000;
> +    const uint32_t digest_addr = src_addr + 0x40000;
>       uint8_t digest[32] = {0};
>       struct AspeedSgList array[] = {
>           {  cpu_to_le32(sizeof(test_vector_accum_256) | SG_LIST_LEN_LAST),
> @@ -377,8 +377,8 @@ void aspeed_test_sha512_accum(const char *machine, const uint32_t base,
>   {
>       QTestState *s = qtest_init(machine);
>   
> -    const uint32_t buffer_addr = src_addr + 0x1000000;
> -    const uint32_t digest_addr = src_addr + 0x4000000;
> +    const uint32_t buffer_addr = src_addr + 0x10000;
> +    const uint32_t digest_addr = src_addr + 0x40000;
>       uint8_t digest[64] = {0};
>       struct AspeedSgList array[] = {
>           {  cpu_to_le32(sizeof(test_vector_accum_512) | SG_LIST_LEN_LAST),



^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v1 17/22] test/qtest/hace: Add tests for AST1030
  2025-03-21  9:26 ` [PATCH v1 17/22] test/qtest/hace: Add tests for AST1030 Jamin Lin via
@ 2025-04-02  9:44   ` Cédric Le Goater
  0 siblings, 0 replies; 71+ messages in thread
From: Cédric Le Goater @ 2025-04-02  9:44 UTC (permalink / raw)
  To: Jamin Lin, Peter Maydell, Steven Lee, Troy Lee, Andrew Jeffery,
	Joel Stanley, Fabiano Rosas, Laurent Vivier, Paolo Bonzini,
	open list:ASPEED BMCs, open list:All patches CC here
  Cc: troy_lee

On 3/21/25 10:26, Jamin Lin wrote:
> The HACE model in AST2600 and AST1030 is identical. Referencing the AST2600
> test cases, new tests have been created for AST1030.
> 
> Implemented test functions for SHA-256, SHA-384, SHA-512, and MD5.
> Added scatter-gather and accumulation test variants.
> For AST1030, the HACE controller base address starts at "0x7e6d0000", and the
> SDRAM start address is "0x0".
> 
> Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>


Reviewed-by: Cédric Le Goater <clg@redhat.com>

Thanks,

C.


> ---
>   tests/qtest/aspeed_hace-test.c | 76 ++++++++++++++++++++++++++++++++++
>   1 file changed, 76 insertions(+)
> 
> diff --git a/tests/qtest/aspeed_hace-test.c b/tests/qtest/aspeed_hace-test.c
> index ab0c98330e..31890d574e 100644
> --- a/tests/qtest/aspeed_hace-test.c
> +++ b/tests/qtest/aspeed_hace-test.c
> @@ -10,6 +10,12 @@
>   #include "qemu/bitops.h"
>   #include "aspeed-hace-utils.h"
>   
> +static const struct AspeedMasks ast1030_masks = {
> +    .src  = 0x7fffffff,
> +    .dest = 0x7ffffff8,
> +    .len  = 0x0fffffff,
> +};
> +
>   static const struct AspeedMasks ast2600_masks = {
>       .src  = 0x7fffffff,
>       .dest = 0x7ffffff8,
> @@ -28,6 +34,62 @@ static const struct AspeedMasks ast2400_masks = {
>       .len  = 0x0fffffff,
>   };
>   
> +/* ast1030 */
> +static void test_md5_ast1030(void)
> +{
> +    aspeed_test_md5("-machine ast1030-evb", 0x7e6d0000, 0x00000000);
> +}
> +
> +static void test_sha256_ast1030(void)
> +{
> +    aspeed_test_sha256("-machine ast1030-evb", 0x7e6d0000, 0x00000000);
> +}
> +
> +static void test_sha256_sg_ast1030(void)
> +{
> +    aspeed_test_sha256_sg("-machine ast1030-evb", 0x7e6d0000, 0x00000000);
> +}
> +
> +static void test_sha384_ast1030(void)
> +{
> +    aspeed_test_sha384("-machine ast1030-evb", 0x7e6d0000, 0x00000000);
> +}
> +
> +static void test_sha384_sg_ast1030(void)
> +{
> +    aspeed_test_sha384_sg("-machine ast1030-evb", 0x7e6d0000, 0x00000000);
> +}
> +
> +static void test_sha512_ast1030(void)
> +{
> +    aspeed_test_sha512("-machine ast1030-evb", 0x7e6d0000, 0x00000000);
> +}
> +
> +static void test_sha512_sg_ast1030(void)
> +{
> +    aspeed_test_sha512_sg("-machine ast1030-evb", 0x7e6d0000, 0x00000000);
> +}
> +
> +static void test_sha256_accum_ast1030(void)
> +{
> +    aspeed_test_sha256_accum("-machine ast1030-evb", 0x7e6d0000, 0x00000000);
> +}
> +
> +static void test_sha384_accum_ast1030(void)
> +{
> +    aspeed_test_sha384_accum("-machine ast1030-evb", 0x7e6d0000, 0x00000000);
> +}
> +
> +static void test_sha512_accum_ast1030(void)
> +{
> +    aspeed_test_sha512_accum("-machine ast1030-evb", 0x7e6d0000, 0x00000000);
> +}
> +
> +static void test_addresses_ast1030(void)
> +{
> +    aspeed_test_addresses("-machine ast1030-evb", 0x7e6d0000, &ast1030_masks);
> +}
> +
>   /* ast2600 */
>   static void test_md5_ast2600(void)
>   {
> @@ -130,6 +192,20 @@ int main(int argc, char **argv)
>   {
>       g_test_init(&argc, &argv, NULL);
>   
> +    qtest_add_func("ast1030/hace/addresses", test_addresses_ast1030);
> +    qtest_add_func("ast1030/hace/sha512", test_sha512_ast1030);
> +    qtest_add_func("ast1030/hace/sha384", test_sha384_ast1030);
> +    qtest_add_func("ast1030/hace/sha256", test_sha256_ast1030);
> +    qtest_add_func("ast1030/hace/md5", test_md5_ast1030);
> +
> +    qtest_add_func("ast1030/hace/sha512_sg", test_sha512_sg_ast1030);
> +    qtest_add_func("ast1030/hace/sha384_sg", test_sha384_sg_ast1030);
> +    qtest_add_func("ast1030/hace/sha256_sg", test_sha256_sg_ast1030);
> +
> +    qtest_add_func("ast1030/hace/sha512_accum", test_sha512_accum_ast1030);
> +    qtest_add_func("ast1030/hace/sha384_accum", test_sha384_accum_ast1030);
> +    qtest_add_func("ast1030/hace/sha256_accum", test_sha256_accum_ast1030);
> +
>       qtest_add_func("ast2600/hace/addresses", test_addresses_ast2600);
>       qtest_add_func("ast2600/hace/sha512", test_sha512_ast2600);
>       qtest_add_func("ast2600/hace/sha384", test_sha384_ast2600);



^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v1 00/22] Fix incorrect hash results on AST2700
  2025-03-21  9:25 [PATCH v1 00/22] Fix incorrect hash results on AST2700 Jamin Lin via
                   ` (22 preceding siblings ...)
  2025-03-21  9:39 ` [PATCH v1 00/22] Fix incorrect hash results on AST2700 Cédric Le Goater
@ 2025-04-02  9:47 ` Cédric Le Goater
  2025-04-02  9:54   ` Jamin Lin
  23 siblings, 1 reply; 71+ messages in thread
From: Cédric Le Goater @ 2025-04-02  9:47 UTC (permalink / raw)
  To: Jamin Lin, Peter Maydell, Steven Lee, Troy Lee, Andrew Jeffery,
	Joel Stanley, Fabiano Rosas, Laurent Vivier, Paolo Bonzini,
	open list:ASPEED BMCs, open list:All patches CC here
  Cc: troy_lee

Hello Jamin,

On 3/21/25 10:25, Jamin Lin wrote:
> v1:
>   1. Added support for 64-bit DMA in the HACE model
>   2. Refactored the do_hash operation in the HACE model
>   3. Fixed a crash caused by out-of-bound memory access in HACE
>   4. Added more trace events and implemented dumping of source hash data and
>      resulting digests to improve debugging
>   5. Refactored the HACE QTest framework to support both AST1030 and AST2700
>   6. Added a test case for SHA384
> 
> This patchset resolves incorrect hash results reported on the AST2700 platform.
> This update addresses the following kernel warnings and test failures related to
> the crypto self-test framework:
> 
> aspeed-hmac-sha512 test failed (incorrect result)
> aspeed-hmac-sha384 test failed (incorrect result)
> aspeed-sha512 test failed (incorrect result)
> aspeed-sha384 test failed (incorrect result)
> aspeed-hmac-sha256 test failed (incorrect result)
> aspeed-hmac-sha224 test failed (incorrect result)
> aspeed-hmac-sha1 test failed (incorrect result)
> aspeed-sha224 test failed (incorrect result)
> aspeed-sha256 test failed (incorrect result)
> aspeed-sha1 test failed (incorrect result)
> 
> How to test it
> 
> Use the following command to dump information about the supported digest methods
> via the afalg hardware engine:
> 
> root@ast2700-default:~# openssl engine -pre DUMP_INFO afalg
> 
> Digest SHA1, NID=64, AF_ALG info: name=sha1ALG_ERR: , driver=aspeed-sha1 (hw accelerated)
> Digest SHA224, NID=675, AF_ALG info: name=sha224ALG_ERR: , driver=aspeed-sha224 (hw accelerated)
> Digest SHA256, NID=672, AF_ALG info: name=sha256ALG_ERR: , driver=aspeed-sha256 (hw accelerated)
> Digest SHA384, NID=673, AF_ALG info: name=sha384ALG_ERR: , driver=aspeed-sha384 (hw accelerated)
> Digest SHA512, NID=674, AF_ALG info: name=sha512ALG_ERR: , driver=aspeed-sha512 (hw accelerated)
> 
> The status of SHA1, SHA224, SHA256, SHA384, and SHA512 should be marked as
> hw accelerated, indicating that these algorithms are supported by hardware
> acceleration via the aspeed drivers.
> 
> Create a test file on the host machine and compute its HASH value as the
> expected result
> 
> Create a 256MB test file
> 
> $ dd if=/dev/random of=/tmp/256M bs=1M count=256
> Generate Hash Values Using SHA1, SHA224, SHA256, SHA384, and SHA512
> 
> Use the following commands to generate HASH values for a 256MB file using
> different SHA algorithms:
> 
> $ sha1sum /tmp/256M
> 7fc628811a31ab87b0502dab3ed8d3ef07565885  /tmp/256M
> 
> $ sha224sum /tmp/256M
> 2d261c11ba05b3a62e0efeab51c307d9933426c7e18204683ef3da54  /tmp/256M
> 
> $ sha256sum /tmp/256M
> 5716d1700ee35c92ca5ca5b466639e9c36eed3f1447c1aec27f16d0fe113f94d  /tmp/256M
> 
> $ sha384sum /tmp/256M
> fb6bc62afa1096dcd3b870e7d2546b7a5a177b5f2bbd5c9759218182454709e0c504a2d9c26404e04aa8010a291b7f1c  /tmp/256M
> 
> $ sha512sum /tmp/256M
> fbceda7be34836fe857781656318ecd5b457a833a24c8736d5b8ef8d07e1950eebcdb140eebe4f12b5ff59586f7eb1c64fa95869c63dd9e4703d91261093c5c9  /tmp/256M
> 
> Generate HASH Values Using the Hardware Engine
> 
> Use the following commands to generate HASH values for a 256MB file using
> various SHA algorithms with the afalg hardware engine:
> 
> 
> root@ast2700-default:~# openssl dgst -sha1 -engine afalg /tmp/256M
> Engine "afalg" set.
> SHA1(/tmp/256M)= 7fc628811a31ab87b0502dab3ed8d3ef07565885
> 
> root@ast2700-default:~# openssl dgst -sha224 -engine ast_crypto_engine /tmp/256M
> Engine "afalg" set.
> SHA2-224(/tmp/256M)= 2d261c11ba05b3a62e0efeab51c307d9933426c7e18204683ef3da54
> 
> root@ast2700-default:~# openssl dgst -sha256 -engine afalg /tmp/256M
> Engine "afalg" set.
> SHA2-256(/tmp/256M)= 5716d1700ee35c92ca5ca5b466639e9c36eed3f1447c1aec27f16d0fe113f94d
> 
> root@ast2700-default:~# openssl dgst -sha384 -engine afalg /tmp/256M
> Engine "afalg" set.
> SHA2-384(/tmp/256M)= fb6bc62afa1096dcd3b870e7d2546b7a5a177b5f2bbd5c9759218182454709e0c504a2d9c26404e04aa8010a291b7f1c
> 
> root@ast2700-default:~# openssl dgst -sha512 -engine afalg /tmp/256M
> Engine "afalg" set.
> SHA2-512(/tmp/256M)= fbceda7be34836fe857781656318ecd5b457a833a24c8736d5b8ef8d07e1950eebcdb140eebe4f12b5ff59586f7eb1c64fa95869c63dd9e4703d91261093c5c9
> 
> 
> The HASH values generated here should exactly match those computed on the host
> machine using software-based OpenSSL, verifying both the correctness of the
> hardware-accelerated results and the functionality of the afalg.
> 
> 
> Jamin Lin (22):
>    hw/misc/aspeed_hace: Remove unused code for better readability
>    hw/misc/aspeed_hace: Fix buffer overflow in has_padding function
>    hw/misc/aspeed_hace: Improve readability and consistency in variable
>      naming
>    hw/misc/aspeed_hace: Update hash source address handling to 64-bit for
>      AST2700
>    hw/misc/aspeed_hace: Introduce 64-bit digest_addr variable for AST2700
>    hw/misc/aspeed_hace: Support accumulative mode for direct access mode
>    hw/misc/aspeed_hace: Add support for source, digest, key buffer 64 bit
>      addresses
>    hw/misc/aspeed_hace: Support DMA 64 bits dram address.
>    hw/misc/aspeed_hace: Ensure HASH_IRQ is always set to prevent firmware
>      hang
>    hw/misc/aspeed_hace:: Support setting different memory size
>    hw/misc/aspeed_hace: Add trace-events for better debugging
>    hw/misc/aspeed_hace Support to dump plaintext and digest for better
>      debugging
>    test/qtest: Introduce a new aspeed-hace-utils.c to place common
>      testcases
>    test/qtest/hace: Adjust test address range for AST1030 due to SRAM
>      limitations
>    test/qtest/hace: Add SHA-384 test cases for ASPEED HACE model
>    test/qtest/hace: Add SHA-384 tests for AST2600
>    test/qtest/hace: Add tests for AST1030
>    test/qtest/hace: Update source data and digest data type to 64-bit
>    test/qtest/hace: Support 64-bit source and digest addresses for
>      AST2700
>    test/qtest/hace: Support to test upper 32 bits of digest and source
>      addresses
>    test/qtest/hace: Support to validate 64-bit hmac key buffer addresses
>    test/qtest/hace: Add tests for AST2700
> 
>   include/hw/misc/aspeed_hace.h   |   9 +-
>   tests/qtest/aspeed-hace-utils.h |  84 +++++
>   hw/misc/aspeed_hace.c           | 194 ++++++----
>   tests/qtest/aspeed-hace-utils.c | 646 ++++++++++++++++++++++++++++++++
>   tests/qtest/aspeed_hace-test.c  | 577 +++++-----------------------
>   tests/qtest/ast2700-hace-test.c |  98 +++++
>   hw/misc/trace-events            |   6 +
>   tests/qtest/meson.build         |   5 +-
>   8 files changed, 1074 insertions(+), 545 deletions(-)
>   create mode 100644 tests/qtest/aspeed-hace-utils.h
>   create mode 100644 tests/qtest/aspeed-hace-utils.c
>   create mode 100644 tests/qtest/ast2700-hace-test.c
> 

It looks good overall. There are a couple of issues in the tests to fix
and I think we should take this opportunity to rework do_hash_operation()
and make it simpler by cutting it in smaller pieces, one for each mode.


Thanks,

C.




^ permalink raw reply	[flat|nested] 71+ messages in thread

* RE: [PATCH v1 00/22] Fix incorrect hash results on AST2700
  2025-04-02  9:47 ` Cédric Le Goater
@ 2025-04-02  9:54   ` Jamin Lin
  0 siblings, 0 replies; 71+ messages in thread
From: Jamin Lin @ 2025-04-02  9:54 UTC (permalink / raw)
  To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
	Andrew Jeffery, Joel Stanley, Fabiano Rosas, Laurent Vivier,
	Paolo Bonzini, open list:ASPEED BMCs,
	open list:All patches CC here
  Cc: Troy Lee

Hi Cedric,

> Subject: Re: [PATCH v1 00/22] Fix incorrect hash results on AST2700
> 
> Hello Jamin,
> 
> On 3/21/25 10:25, Jamin Lin wrote:
> > v1:
> >   1. Added support for 64-bit DMA in the HACE model
> >   2. Refactored the do_hash operation in the HACE model
> >   3. Fixed a crash caused by out-of-bound memory access in HACE
> >   4. Added more trace events and implemented dumping of source hash
> data and
> >      resulting digests to improve debugging
> >   5. Refactored the HACE QTest framework to support both AST1030 and
> AST2700
> >   6. Added a test case for SHA384
> >
> > This patchset resolves incorrect hash results reported on the AST2700
> platform.
> > This update addresses the following kernel warnings and test failures
> > related to the crypto self-test framework:
> >
> > aspeed-hmac-sha512 test failed (incorrect result)
> > aspeed-hmac-sha384 test failed (incorrect result)
> > aspeed-sha512 test failed (incorrect result)
> > aspeed-sha384 test failed (incorrect result)
> > aspeed-hmac-sha256 test failed (incorrect result)
> > aspeed-hmac-sha224 test failed (incorrect result)
> > aspeed-hmac-sha1 test failed (incorrect result)
> > aspeed-sha224 test failed (incorrect result)
> > aspeed-sha256 test failed (incorrect result)
> > aspeed-sha1 test failed (incorrect result)
> >
> > How to test it
> >
> > Use the following command to dump information about the supported
> > digest methods via the afalg hardware engine:
> >
> > root@ast2700-default:~# openssl engine -pre DUMP_INFO afalg
> >
> > Digest SHA1, NID=64, AF_ALG info: name=sha1ALG_ERR: ,
> > driver=aspeed-sha1 (hw accelerated) Digest SHA224, NID=675, AF_ALG
> > info: name=sha224ALG_ERR: , driver=aspeed-sha224 (hw accelerated)
> > Digest SHA256, NID=672, AF_ALG info: name=sha256ALG_ERR: ,
> > driver=aspeed-sha256 (hw accelerated) Digest SHA384, NID=673, AF_ALG
> > info: name=sha384ALG_ERR: , driver=aspeed-sha384 (hw accelerated)
> > Digest SHA512, NID=674, AF_ALG info: name=sha512ALG_ERR: ,
> > driver=aspeed-sha512 (hw accelerated)
> >
> > The status of SHA1, SHA224, SHA256, SHA384, and SHA512 should be
> > marked as hw accelerated, indicating that these algorithms are
> > supported by hardware acceleration via the aspeed drivers.
> >
> > Create a test file on the host machine and compute its HASH value as
> > the expected result
> >
> > Create a 256MB test file
> >
> > $ dd if=/dev/random of=/tmp/256M bs=1M count=256 Generate Hash Values
> > Using SHA1, SHA224, SHA256, SHA384, and SHA512
> >
> > Use the following commands to generate HASH values for a 256MB file
> > using different SHA algorithms:
> >
> > $ sha1sum /tmp/256M
> > 7fc628811a31ab87b0502dab3ed8d3ef07565885  /tmp/256M
> >
> > $ sha224sum /tmp/256M
> > 2d261c11ba05b3a62e0efeab51c307d9933426c7e18204683ef3da54
> /tmp/256M
> >
> > $ sha256sum /tmp/256M
> > 5716d1700ee35c92ca5ca5b466639e9c36eed3f1447c1aec27f16d0fe113f94d
> > /tmp/256M
> >
> > $ sha384sum /tmp/256M
> >
> fb6bc62afa1096dcd3b870e7d2546b7a5a177b5f2bbd5c9759218182454709e0c
> 504a2
> > d9c26404e04aa8010a291b7f1c  /tmp/256M
> >
> > $ sha512sum /tmp/256M
> >
> fbceda7be34836fe857781656318ecd5b457a833a24c8736d5b8ef8d07e1950ee
> bcdb1
> > 40eebe4f12b5ff59586f7eb1c64fa95869c63dd9e4703d91261093c5c9
> /tmp/256M
> >
> > Generate HASH Values Using the Hardware Engine
> >
> > Use the following commands to generate HASH values for a 256MB file
> > using various SHA algorithms with the afalg hardware engine:
> >
> >
> > root@ast2700-default:~# openssl dgst -sha1 -engine afalg /tmp/256M
> > Engine "afalg" set.
> > SHA1(/tmp/256M)= 7fc628811a31ab87b0502dab3ed8d3ef07565885
> >
> > root@ast2700-default:~# openssl dgst -sha224 -engine ast_crypto_engine
> > /tmp/256M Engine "afalg" set.
> > SHA2-224(/tmp/256M)=
> > 2d261c11ba05b3a62e0efeab51c307d9933426c7e18204683ef3da54
> >
> > root@ast2700-default:~# openssl dgst -sha256 -engine afalg /tmp/256M
> > Engine "afalg" set.
> > SHA2-256(/tmp/256M)=
> > 5716d1700ee35c92ca5ca5b466639e9c36eed3f1447c1aec27f16d0fe113f94d
> >
> > root@ast2700-default:~# openssl dgst -sha384 -engine afalg /tmp/256M
> > Engine "afalg" set.
> > SHA2-384(/tmp/256M)=
> >
> fb6bc62afa1096dcd3b870e7d2546b7a5a177b5f2bbd5c9759218182454709e0c
> 504a2
> > d9c26404e04aa8010a291b7f1c
> >
> > root@ast2700-default:~# openssl dgst -sha512 -engine afalg /tmp/256M
> > Engine "afalg" set.
> > SHA2-512(/tmp/256M)=
> >
> fbceda7be34836fe857781656318ecd5b457a833a24c8736d5b8ef8d07e1950ee
> bcdb1
> > 40eebe4f12b5ff59586f7eb1c64fa95869c63dd9e4703d91261093c5c9
> >
> >
> > The HASH values generated here should exactly match those computed on
> > the host machine using software-based OpenSSL, verifying both the
> > correctness of the hardware-accelerated results and the functionality of the
> afalg.
> >
> >
> > Jamin Lin (22):
> >    hw/misc/aspeed_hace: Remove unused code for better readability
> >    hw/misc/aspeed_hace: Fix buffer overflow in has_padding function
> >    hw/misc/aspeed_hace: Improve readability and consistency in variable
> >      naming
> >    hw/misc/aspeed_hace: Update hash source address handling to 64-bit
> for
> >      AST2700
> >    hw/misc/aspeed_hace: Introduce 64-bit digest_addr variable for
> AST2700
> >    hw/misc/aspeed_hace: Support accumulative mode for direct access
> mode
> >    hw/misc/aspeed_hace: Add support for source, digest, key buffer 64 bit
> >      addresses
> >    hw/misc/aspeed_hace: Support DMA 64 bits dram address.
> >    hw/misc/aspeed_hace: Ensure HASH_IRQ is always set to prevent
> firmware
> >      hang
> >    hw/misc/aspeed_hace:: Support setting different memory size
> >    hw/misc/aspeed_hace: Add trace-events for better debugging
> >    hw/misc/aspeed_hace Support to dump plaintext and digest for better
> >      debugging
> >    test/qtest: Introduce a new aspeed-hace-utils.c to place common
> >      testcases
> >    test/qtest/hace: Adjust test address range for AST1030 due to SRAM
> >      limitations
> >    test/qtest/hace: Add SHA-384 test cases for ASPEED HACE model
> >    test/qtest/hace: Add SHA-384 tests for AST2600
> >    test/qtest/hace: Add tests for AST1030
> >    test/qtest/hace: Update source data and digest data type to 64-bit
> >    test/qtest/hace: Support 64-bit source and digest addresses for
> >      AST2700
> >    test/qtest/hace: Support to test upper 32 bits of digest and source
> >      addresses
> >    test/qtest/hace: Support to validate 64-bit hmac key buffer addresses
> >    test/qtest/hace: Add tests for AST2700
> >
> >   include/hw/misc/aspeed_hace.h   |   9 +-
> >   tests/qtest/aspeed-hace-utils.h |  84 +++++
> >   hw/misc/aspeed_hace.c           | 194 ++++++----
> >   tests/qtest/aspeed-hace-utils.c | 646
> ++++++++++++++++++++++++++++++++
> >   tests/qtest/aspeed_hace-test.c  | 577 +++++-----------------------
> >   tests/qtest/ast2700-hace-test.c |  98 +++++
> >   hw/misc/trace-events            |   6 +
> >   tests/qtest/meson.build         |   5 +-
> >   8 files changed, 1074 insertions(+), 545 deletions(-)
> >   create mode 100644 tests/qtest/aspeed-hace-utils.h
> >   create mode 100644 tests/qtest/aspeed-hace-utils.c
> >   create mode 100644 tests/qtest/ast2700-hace-test.c
> >
> 
> It looks good overall. There are a couple of issues in the tests to fix and I think
> we should take this opportunity to rework do_hash_operation() and make it
> simpler by cutting it in smaller pieces, one for each mode.
> 
Thank you for your review and suggestions.
I'll go through your comments and incorporate your suggestions.
I'll update you once it's done.
Thanks-Jamin
> 
> Thanks,
> 
> C.
> 


^ permalink raw reply	[flat|nested] 71+ messages in thread

* RE: [PATCH v1 01/22] hw/misc/aspeed_hace: Remove unused code for better readability
  2025-04-01 13:08   ` Cédric Le Goater
@ 2025-05-05  3:28     ` Jamin Lin
  2025-05-06  9:01       ` Cédric Le Goater
  0 siblings, 1 reply; 71+ messages in thread
From: Jamin Lin @ 2025-05-05  3:28 UTC (permalink / raw)
  To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
	Andrew Jeffery, Joel Stanley, Fabiano Rosas, Laurent Vivier,
	Paolo Bonzini, open list:ASPEED BMCs,
	open list:All patches CC here
  Cc: Troy Lee

Hi Cédric

> Subject: Re: [PATCH v1 01/22] hw/misc/aspeed_hace: Remove unused code for
> better readability
> 
> On 3/21/25 10:25, Jamin Lin wrote:
> > This cleanup follows significant changes in commit 4c1d0af4a28d,
> > making the model more readable.
> >
> > - Deleted "iov_cache" and "iov_count" from "AspeedHACEState".
> 
> It would be good to say why we can remove these. I think this is because
> s->iov_count is always zero, right ?
> 
> > - Removed "reconstruct_iov" function and related logic.
> > - Simplified "do_hash_operation" by eliminating redundant checks.
> >
> > Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
> > ---
> >   include/hw/misc/aspeed_hace.h |  2 --
> >   hw/misc/aspeed_hace.c         | 35 -----------------------------------
> >   2 files changed, 37 deletions(-)
> >
> > diff --git a/include/hw/misc/aspeed_hace.h
> > b/include/hw/misc/aspeed_hace.h index 5d4aa19cfe..b69a038d35 100644
> > --- a/include/hw/misc/aspeed_hace.h
> > +++ b/include/hw/misc/aspeed_hace.h
> > @@ -31,10 +31,8 @@ struct AspeedHACEState {
> >       MemoryRegion iomem;
> >       qemu_irq irq;
> >
> > -    struct iovec iov_cache[ASPEED_HACE_MAX_SG];
> >       uint32_t regs[ASPEED_HACE_NR_REGS];
> >       uint32_t total_req_len;
> > -    uint32_t iov_count;
> >
> >       MemoryRegion *dram_mr;
> >       AddressSpace dram_as;
> > diff --git a/hw/misc/aspeed_hace.c b/hw/misc/aspeed_hace.c index
> > 32a5dbded3..8e7e8113a5 100644
> > --- a/hw/misc/aspeed_hace.c
> > +++ b/hw/misc/aspeed_hace.c
> > @@ -137,25 +137,6 @@ static bool has_padding(AspeedHACEState *s,
> struct iovec *iov,
> >       return false;
> >   }
> >
> > -static int reconstruct_iov(AspeedHACEState *s, struct iovec *iov, int id,
> > -                           uint32_t *pad_offset)
> > -{
> > -    int i, iov_count;
> > -    if (*pad_offset != 0) {
> > -        s->iov_cache[s->iov_count].iov_base = iov[id].iov_base;
> > -        s->iov_cache[s->iov_count].iov_len = *pad_offset;
> > -        ++s->iov_count;
> > -    }
> > -    for (i = 0; i < s->iov_count; i++) {
> > -        iov[i].iov_base = s->iov_cache[i].iov_base;
> > -        iov[i].iov_len = s->iov_cache[i].iov_len;
> > -    }
> > -    iov_count = s->iov_count;
> > -    s->iov_count = 0;
> > -    s->total_req_len = 0;
> > -    return iov_count;
> > -}
> > -
> >   static void do_hash_operation(AspeedHACEState *s, int algo, bool
> sg_mode,
> >                                 bool acc_mode)
> >   {
> > @@ -237,19 +218,6 @@ static void do_hash_operation(AspeedHACEState *s,
> int algo, bool sg_mode,
> >           iov[0].iov_base = haddr;
> >           iov[0].iov_len = len;
> >           i = 1;
> > -
> > -        if (s->iov_count) {
> > -            /*
> > -             * In aspeed sdk kernel driver, sg_mode is disabled in
> hash_final().
> > -             * Thus if we received a request with sg_mode disabled, it is
> > -             * required to check whether cache is empty. If no, we should
> > -             * combine cached iov and the current iov.
> > -             */
> > -            s->total_req_len += len;
> > -            if (has_padding(s, iov, len, &total_msg_len, &pad_offset)) {
> > -                i = reconstruct_iov(s, iov, 0, &pad_offset);
> > -            }
> > -        }
> >       }
> >
> >       if (acc_mode) {
> > @@ -273,7 +241,6 @@ static void do_hash_operation(AspeedHACEState *s,
> int algo, bool sg_mode,
> >               qcrypto_hash_free(s->hash_ctx);
> >
> >               s->hash_ctx = NULL;
> > -            s->iov_count = 0;
> >               s->total_req_len = 0;
> >           }
> >       } else if (qcrypto_hash_bytesv(algo, iov, i, &digest_buf, @@
> > -432,7 +399,6 @@ static void aspeed_hace_reset(DeviceState *dev)
> >       }
> >
> >       memset(s->regs, 0, sizeof(s->regs));
> > -    s->iov_count = 0;
> >       s->total_req_len = 0;
> >   }
> >
> > @@ -469,7 +435,6 @@ static const VMStateDescription
> vmstate_aspeed_hace = {
> >       .fields = (const VMStateField[]) {
> >           VMSTATE_UINT32_ARRAY(regs, AspeedHACEState,
> ASPEED_HACE_NR_REGS),
> >           VMSTATE_UINT32(total_req_len, AspeedHACEState),
> > -        VMSTATE_UINT32(iov_count, AspeedHACEState),
> 
> This is a vmstate change which is breaking migration compatibility.
> We could preserve compatibility [1] but I think this is overkill.
> However, we should say so. Please add a comment in the commit log.
> 

How about the following commit log:

```
hw/misc/aspeed_hace: Remove unused code for better readability

In the previous design of the hash framework, accumulative hashing was not
supported. To work around this limitation, commit 5cd7d85 introduced an
iov_cache array to store all the hash data from firmware.
Once the ASPEED HACE model collected all the data, it passed the iov_cache to
the hash API to calculate the final digest.

However, with commit e3c0752, the hash framework now supports accumulative
hashing. This allows us to refactor the ASPEED HACE model, removing redundant
logic and simplifying the implementation for better readability and
maintainability.

As a result, the iov_count variable is no longer needed—it was previously used
to track how many cached entries were used for hashing.
To maintain VMSTATE compatibility after removing this field, the VMSTATE_VERSION
is bumped to 2

This cleanup follows significant changes in commit 4c1d0af4a28d, making the
model more readable.

- Deleted "iov_cache" and "iov_count" from "AspeedHACEState".
- Removed "reconstruct_iov" function and related logic.
- Simplified "do_hash_operation" by eliminating redundant checks.
```

Thans-Jamin

> Thanks,
> 
> C.
> 
> [1]
> https://qemu.readthedocs.io/en/v9.2.0/devel/migration/main.html#vmstate
> 
> >           VMSTATE_END_OF_LIST(),
> >       }
> >   };


^ permalink raw reply	[flat|nested] 71+ messages in thread

* RE: [PATCH v1 14/22] test/qtest/hace: Adjust test address range for AST1030 due to SRAM limitations
  2025-04-02  9:43   ` Cédric Le Goater
@ 2025-05-05  3:44     ` Jamin Lin
  0 siblings, 0 replies; 71+ messages in thread
From: Jamin Lin @ 2025-05-05  3:44 UTC (permalink / raw)
  To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
	Andrew Jeffery, Joel Stanley, Fabiano Rosas, Laurent Vivier,
	Paolo Bonzini, open list:ASPEED BMCs,
	open list:All patches CC here
  Cc: Troy Lee

Hi Cédric
> Subject: Re: [PATCH v1 14/22] test/qtest/hace: Adjust test address range for
> AST1030 due to SRAM limitations
> 
> On 3/21/25 10:26, Jamin Lin wrote:
> > The digest_addr is set to "src_addr + 0x1000000", where src_addr is
> > the DRAM base address. However, the value 0x1000000 (16MB) is too
> > large because the
> > AST1030 does not support DRAM, and its SRAM size is only 768KB.
> >
> > A range size of 0x1000 (64KB) is sufficient for HACE test cases, as
> > the test vector size does not exceed 64KB.
> >
> > Updates:
> > 1. Direct Access Mode
> > Update digest_addr to "src_addr + 0x1000" in the following functions:
> 
> The change does src_addr + 0x10000. Can you please adjust the commit log or
> the code ?
> 
Thanks for review. It should be 0x10000(64KB).
I will adjust the commit log.
Thanks-Jamin
> 
> Thanks,
> 
> C.
> 
> 
> 
> > aspeed_test_md5
> > aspeed_test_sha256
> > aspeed_test_sha512
> >
> > 2. Scatter-Gather (SG) Mode
> > Update source address for different SG buffer addresses in the
> > following
> > functions:
> > src_addr1 = src_addr + 0x1000
> > src_addr2 = src_addr + 0x2000
> > src_addr3 = src_addr + 0x3000
> > digest_addr = src_addr + 0x4000
> >
> > aspeed_test_sha256_sg
> > aspeed_test_sha512_sg
> >
> > 3. ACC Mode Update
> > Update the SG List start address: src_addr + 0x10000 Update the SG
> > List buffer size to 0x3000 (192KB).
> >
> > buffer_addr = src_addr + 0x10000
> > digest_addr = src_addr + 0x40000
> >
> > Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
> > ---
> >   tests/qtest/aspeed-hace-utils.c | 30 +++++++++++++++---------------
> >   1 file changed, 15 insertions(+), 15 deletions(-)
> >
> > diff --git a/tests/qtest/aspeed-hace-utils.c
> > b/tests/qtest/aspeed-hace-utils.c index 8582847945..8fbbba49c1 100644
> > --- a/tests/qtest/aspeed-hace-utils.c
> > +++ b/tests/qtest/aspeed-hace-utils.c
> > @@ -132,7 +132,7 @@ void aspeed_test_md5(const char *machine, const
> uint32_t base,
> >   {
> >       QTestState *s = qtest_init(machine);
> >
> > -    uint32_t digest_addr = src_addr + 0x01000000;
> > +    uint32_t digest_addr = src_addr + 0x010000;
> >       uint8_t digest[16] = {0};
> >
> >       /* Check engine is idle, no busy or irq bits set */ @@ -166,7
> > +166,7 @@ void aspeed_test_sha256(const char *machine, const uint32_t
> base,
> >   {
> >       QTestState *s = qtest_init(machine);
> >
> > -    const uint32_t digest_addr = src_addr + 0x1000000;
> > +    const uint32_t digest_addr = src_addr + 0x10000;
> >       uint8_t digest[32] = {0};
> >
> >       /* Check engine is idle, no busy or irq bits set */ @@ -200,7
> > +200,7 @@ void aspeed_test_sha512(const char *machine, const uint32_t
> base,
> >   {
> >       QTestState *s = qtest_init(machine);
> >
> > -    const uint32_t digest_addr = src_addr + 0x1000000;
> > +    const uint32_t digest_addr = src_addr + 0x10000;
> >       uint8_t digest[64] = {0};
> >
> >       /* Check engine is idle, no busy or irq bits set */ @@ -234,10
> > +234,10 @@ void aspeed_test_sha256_sg(const char *machine, const
> uint32_t base,
> >   {
> >       QTestState *s = qtest_init(machine);
> >
> > -    const uint32_t src_addr_1 = src_addr + 0x1000000;
> > -    const uint32_t src_addr_2 = src_addr + 0x2000000;
> > -    const uint32_t src_addr_3 = src_addr + 0x3000000;
> > -    const uint32_t digest_addr = src_addr + 0x4000000;
> > +    const uint32_t src_addr_1 = src_addr + 0x10000;
> > +    const uint32_t src_addr_2 = src_addr + 0x20000;
> > +    const uint32_t src_addr_3 = src_addr + 0x30000;
> > +    const uint32_t digest_addr = src_addr + 0x40000;
> >       uint8_t digest[32] = {0};
> >       struct AspeedSgList array[] = {
> >           {  cpu_to_le32(sizeof(test_vector_sg1)),
> > @@ -285,10 +285,10 @@ void aspeed_test_sha512_sg(const char *machine,
> const uint32_t base,
> >   {
> >       QTestState *s = qtest_init(machine);
> >
> > -    const uint32_t src_addr_1 = src_addr + 0x1000000;
> > -    const uint32_t src_addr_2 = src_addr + 0x2000000;
> > -    const uint32_t src_addr_3 = src_addr + 0x3000000;
> > -    const uint32_t digest_addr = src_addr + 0x4000000;
> > +    const uint32_t src_addr_1 = src_addr + 0x10000;
> > +    const uint32_t src_addr_2 = src_addr + 0x20000;
> > +    const uint32_t src_addr_3 = src_addr + 0x30000;
> > +    const uint32_t digest_addr = src_addr + 0x40000;
> >       uint8_t digest[64] = {0};
> >       struct AspeedSgList array[] = {
> >           {  cpu_to_le32(sizeof(test_vector_sg1)),
> > @@ -336,8 +336,8 @@ void aspeed_test_sha256_accum(const char
> *machine, const uint32_t base,
> >   {
> >       QTestState *s = qtest_init(machine);
> >
> > -    const uint32_t buffer_addr = src_addr + 0x1000000;
> > -    const uint32_t digest_addr = src_addr + 0x4000000;
> > +    const uint32_t buffer_addr = src_addr + 0x10000;
> > +    const uint32_t digest_addr = src_addr + 0x40000;
> >       uint8_t digest[32] = {0};
> >       struct AspeedSgList array[] = {
> >           {  cpu_to_le32(sizeof(test_vector_accum_256) |
> > SG_LIST_LEN_LAST), @@ -377,8 +377,8 @@ void
> aspeed_test_sha512_accum(const char *machine, const uint32_t base,
> >   {
> >       QTestState *s = qtest_init(machine);
> >
> > -    const uint32_t buffer_addr = src_addr + 0x1000000;
> > -    const uint32_t digest_addr = src_addr + 0x4000000;
> > +    const uint32_t buffer_addr = src_addr + 0x10000;
> > +    const uint32_t digest_addr = src_addr + 0x40000;
> >       uint8_t digest[64] = {0};
> >       struct AspeedSgList array[] = {
> >           {  cpu_to_le32(sizeof(test_vector_accum_512) |
> > SG_LIST_LEN_LAST),


^ permalink raw reply	[flat|nested] 71+ messages in thread

* RE: [PATCH v1 15/22] test/qtest/hace: Add SHA-384 test cases for ASPEED HACE model
  2025-04-02  9:02   ` Cédric Le Goater
@ 2025-05-05  6:36     ` Jamin Lin
  2025-05-05  6:51       ` Jamin Lin
  0 siblings, 1 reply; 71+ messages in thread
From: Jamin Lin @ 2025-05-05  6:36 UTC (permalink / raw)
  To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
	Andrew Jeffery, Joel Stanley, Fabiano Rosas, Laurent Vivier,
	Paolo Bonzini, open list:ASPEED BMCs,
	open list:All patches CC here
  Cc: Troy Lee

Hi Cédric,

> Subject: Re: [PATCH v1 15/22] test/qtest/hace: Add SHA-384 test cases for
> ASPEED HACE model
> 
> On 3/21/25 10:26, Jamin Lin wrote:
> > Introduced SHA-384 test functions to verify hashing operations.
> > Extended support for scatter-gather (`_sg`) and accumulation (`_accum`)
> tests.
> > Updated test result vectors for SHA-384 validation.
> >
> > Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
> > ---
> >   tests/qtest/aspeed-hace-utils.h |   6 ++
> >   tests/qtest/aspeed-hace-utils.c | 168
> +++++++++++++++++++++++++++++++-
> >   2 files changed, 171 insertions(+), 3 deletions(-)
> >
> > diff --git a/tests/qtest/aspeed-hace-utils.h
> > b/tests/qtest/aspeed-hace-utils.h index 598577c69b..f4440561de 100644
> > --- a/tests/qtest/aspeed-hace-utils.h
> > +++ b/tests/qtest/aspeed-hace-utils.h
> > @@ -54,14 +54,20 @@ void aspeed_test_md5(const char *machine, const
> uint32_t base,
> >                        const uint32_t src_addr);
> >   void aspeed_test_sha256(const char *machine, const uint32_t base,
> >                           const uint32_t src_addr);
> > +void aspeed_test_sha384(const char *machine, const uint32_t base,
> > +                        const uint32_t src_addr);
> >   void aspeed_test_sha512(const char *machine, const uint32_t base,
> >                           const uint32_t src_addr);
> >   void aspeed_test_sha256_sg(const char *machine, const uint32_t base,
> >                              const uint32_t src_addr);
> > +void aspeed_test_sha384_sg(const char *machine, const uint32_t base,
> > +                           const uint32_t src_addr);
> >   void aspeed_test_sha512_sg(const char *machine, const uint32_t base,
> >                              const uint32_t src_addr);
> >   void aspeed_test_sha256_accum(const char *machine, const uint32_t
> base,
> >                                 const uint32_t src_addr);
> > +void aspeed_test_sha384_accum(const char *machine, const uint32_t base,
> > +                              const uint32_t src_addr);
> >   void aspeed_test_sha512_accum(const char *machine, const uint32_t
> base,
> >                                 const uint32_t src_addr);
> >   void aspeed_test_addresses(const char *machine, const uint32_t base,
> > diff --git a/tests/qtest/aspeed-hace-utils.c
> > b/tests/qtest/aspeed-hace-utils.c index 8fbbba49c1..d3146898c2 100644
> > --- a/tests/qtest/aspeed-hace-utils.c
> > +++ b/tests/qtest/aspeed-hace-utils.c
> > @@ -16,7 +16,7 @@
> >    * Expected results were generated using command line utitiles:
> >    *
> >    *  echo -n -e 'abc' | dd of=/tmp/test
> > - *  for hash in sha512sum sha256sum md5sum; do $hash /tmp/test; done
> > + *  for hash in sha512sum sha384sum sha256sum md5sum; do $hash
> > + /tmp/test; done
> >    *
> >    */
> >   static const uint8_t test_vector[] = {0x61, 0x62, 0x63}; @@ -29,6
> > +29,12 @@ static const uint8_t test_result_sha512[] = {
> >       0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e, 0x2a, 0x9a, 0xc9,
> 0x4f,
> >       0xa5, 0x4c, 0xa4, 0x9f};
> >
> > +static const uint8_t test_result_sha384[] = {
> > +    0xcb, 0x00, 0x75, 0x3f, 0x45, 0xa3, 0x5e, 0x8b, 0xb5, 0xa0, 0x3d, 0x69,
> > +    0x9a, 0xc6, 0x50, 0x07, 0x27, 0x2c, 0x32, 0xab, 0x0e, 0xde, 0xd1,
> 0x63,
> > +    0x1a, 0x8b, 0x60, 0x5a, 0x43, 0xff, 0x5b, 0xed, 0x80, 0x86, 0x07, 0x2b,
> > +    0xa1, 0xe7, 0xcc, 0x23, 0x58, 0xba, 0xec, 0xa1, 0x34, 0xc8, 0x25,
> > +0xa7};
> > +
> >   static const uint8_t test_result_sha256[] = {
> >       0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40,
> 0xde,
> >       0x5d, 0xae, 0x22, 0x23, 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17,
> > 0x7a, 0x9c, @@ -45,7 +51,7 @@ static const uint8_t test_result_md5[] = {
> >    * Expected results were generated using command line utitiles:
> >    *
> >    *  echo -n -e 'abcdefghijkl' | dd of=/tmp/test
> > - *  for hash in sha512sum sha256sum; do $hash /tmp/test; done
> > + *  for hash in sha512sum sha384sum sha256sum; do $hash /tmp/test;
> > + done
> >    *
> >    */
> >   static const uint8_t test_vector_sg1[] = {0x61, 0x62, 0x63, 0x64,
> > 0x65, 0x66}; @@ -60,6 +66,12 @@ static const uint8_t
> test_result_sg_sha512[] = {
> >       0x84, 0x25, 0x7c, 0x32, 0xc8, 0xf6, 0xd0, 0x85, 0x4a, 0xe6, 0xb5,
> 0x40,
> >       0xf8, 0x6d, 0xda, 0x2e};
> >
> > +static const uint8_t test_result_sg_sha384[] = {
> > +    0x10, 0x3c, 0xa9, 0x6c, 0x06, 0xa1, 0xce, 0x79, 0x8f, 0x08, 0xf8, 0xef,
> > +    0xf0, 0xdf, 0xb0, 0xcc, 0xdb, 0x56, 0x7d, 0x48, 0xb2, 0x85, 0xb2, 0x3d,
> > +    0x0c, 0xd7, 0x73, 0x45, 0x46, 0x67, 0xa3, 0xc2, 0xfa, 0x5f, 0x1b, 0x58,
> > +    0xd9, 0xcd, 0xf2, 0x32, 0x9b, 0xd9, 0x97, 0x97, 0x30, 0xbf, 0xaa,
> > +0xff};
> > +
> >   static const uint8_t test_result_sg_sha256[] = {
> >       0xd6, 0x82, 0xed, 0x4c, 0xa4, 0xd9, 0x89, 0xc1, 0x34, 0xec, 0x94,
> 0xf1,
> >       0x55, 0x1e, 0x1e, 0xc5, 0x80, 0xdd, 0x6d, 0x5a, 0x6e, 0xcd,
> > 0xe9, 0xf3, @@ -74,7 +86,7 @@ static const uint8_t test_result_sg_sha256[]
> = {
> >    * Expected results were generated using command line utitiles:
> >    *
> >    *  echo -n -e 'abc' | dd of=/tmp/test
> > - *  for hash in sha512sum sha256sum; do $hash /tmp/test; done
> > + *  for hash in sha512sum sha384sum sha256sum; do $hash /tmp/test;
> > + done
> >    */
> >   static const uint8_t test_vector_accum_512[] = {
> >       0x61, 0x62, 0x63, 0x80, 0x00, 0x00, 0x00, 0x00, @@ -94,6 +106,24
> > @@ static const uint8_t test_vector_accum_512[] = {
> >       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> >       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18};
> >
> > +static const uint8_t test_vector_accum_384[] = {
> > +    0x61, 0x62, 0x63, 0x80, 0x00, 0x00, 0x00, 0x00,
> > +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18};
> > +
> >   static const uint8_t test_vector_accum_256[] = {
> >       0x61, 0x62, 0x63, 0x80, 0x00, 0x00, 0x00, 0x00,
> >       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -112,6
> > +142,12 @@ static const uint8_t test_result_accum_sha512[] = {
> >       0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e, 0x2a, 0x9a, 0xc9,
> 0x4f,
> >       0xa5, 0x4c, 0xa4, 0x9f};
> >
> > +static const uint8_t test_result_accum_sha384[] = {
> > +    0xcb, 0x00, 0x75, 0x3f, 0x45, 0xa3, 0x5e, 0x8b, 0xb5, 0xa0, 0x3d, 0x69,
> > +    0x9a, 0xc6, 0x50, 0x07, 0x27, 0x2c, 0x32, 0xab, 0x0e, 0xde, 0xd1,
> 0x63,
> > +    0x1a, 0x8b, 0x60, 0x5a, 0x43, 0xff, 0x5b, 0xed, 0x80, 0x86, 0x07, 0x2b,
> > +    0xa1, 0xe7, 0xcc, 0x23, 0x58, 0xba, 0xec, 0xa1, 0x34, 0xc8, 0x25,
> > +0xa7};
> > +
> >   static const uint8_t test_result_accum_sha256[] = {
> >       0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40,
> 0xde,
> >       0x5d, 0xae, 0x22, 0x23, 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17,
> > 0x7a, 0x9c, @@ -195,6 +231,40 @@ void aspeed_test_sha256(const char
> *machine, const uint32_t base,
> >       qtest_quit(s);
> >   }
> >
> > +void aspeed_test_sha384(const char *machine, const uint32_t base,
> > +                        const uint32_t src_addr) {
> > +    QTestState *s = qtest_init(machine);
> > +
> > +    const uint32_t digest_addr = src_addr + 0x10000;
> > +    uint8_t digest[32] = {0};
> > +
> > +    /* Check engine is idle, no busy or irq bits set */
> > +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> > +
> > +    /* Write test vector into memory */
> > +    qtest_memwrite(s, src_addr, test_vector, sizeof(test_vector));
> > +
> > +    write_regs(s, base, src_addr, sizeof(test_vector), digest_addr,
> > +               HACE_ALGO_SHA384);
> > +
> > +    /* Check hash IRQ status is asserted */
> > +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
> > +
> > +    /* Clear IRQ status and check status is deasserted */
> > +    qtest_writel(s, base + HACE_STS, 0x00000200);
> > +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> > +
> > +    /* Read computed digest from memory */
> > +    qtest_memread(s, digest_addr, digest, sizeof(digest));
> > +
> > +    /* Check result of computation */
> > +    g_assert_cmpmem(digest, sizeof(digest),
> > +                    test_result_sha384, sizeof(digest));
> > +
> > +    qtest_quit(s);
> > +}
> > +
> >   void aspeed_test_sha512(const char *machine, const uint32_t base,
> >                           const uint32_t src_addr)
> >   {
> > @@ -280,6 +350,57 @@ void aspeed_test_sha256_sg(const char *machine,
> const uint32_t base,
> >       qtest_quit(s);
> >   }
> >
> > +void aspeed_test_sha384_sg(const char *machine, const uint32_t base,
> > +                           const uint32_t src_addr) {
> > +    QTestState *s = qtest_init(machine);
> > +
> > +    const uint32_t src_addr_1 = src_addr + 0x10000;
> > +    const uint32_t src_addr_2 = src_addr + 0x20000;
> > +    const uint32_t src_addr_3 = src_addr + 0x30000;
> > +    const uint32_t digest_addr = src_addr + 0x40000;
> > +    uint8_t digest[64] = {0};
> 
> This does not compile (gcc version 14.2.1)
> 
> 
> ../tests/qtest/aspeed-hace-utils.c: In function ‘aspeed_test_sha384_sg’:
> /usr/include/glib-2.0/glib/gtestutils.h:93:84: error: ‘__builtin_memcmp_eq’
> specified bound 64 exceeds the size 48 of unterminated array
> [-Werror=stringop-overread]
>     93 |                                              else if
> (__l1 != 0 && __m2 != NULL && memcmp (__m1, __m2, __l1) != 0) \
>        |
> ^~~~~~~~~~~~~~~~~~~~~~~~~
> ../tests/qtest/aspeed-hace-utils.c:399:5: note: in expansion of macro
> ‘g_assert_cmpmem’
>    399 |     g_assert_cmpmem(digest, sizeof(digest),
>        |     ^~~~~~~~~~~~~~~
> ../tests/qtest/aspeed-hace-utils.c:69:22: note: referenced argument declared
> here
>     69 | static const uint8_t test_result_sg_sha384[] = {
>        |                      ^~~~~~~~~~~~~~~~~~~~~
> 


I didn't explicitly set the array size for "test_result_sg_sha384", and the compiler seems to have inferred a size of 64 bytes—likely due to 32-byte alignment.
However, the actual SHA384 digest is 48 bytes, which is why your compiler reported an error: it detected a possible buffer overread.

There are two possible ways to fix this issue:

Solution 1:
Define a constant MAX_SIZE_LENGTH (e.g., 64 bytes), and use it for all test result arrays:

test_result_sha512[MAX_SIZE_LENGTH];
test_result_sha384[MAX_SIZE_LENGTH];
However, in this case, we cannot use "sizeof(test_result_sha384)" or "sizeof(test_result_sha256)" in the test code, because the compiler will evaluate them as 128 bytes.
Therefore, we should use hardcoded digest lengths (48 for SHA384, 32 for SHA256) when comparing results in the tests.

Solution 2:
Set the actual digest size explicitly in the array definition:
test_result_sha512[64];
test_result_sha384[48];
This ensures "sizeof()" will return the correct digest size, and we can safely use it in assertions.

I prefer solution 2.
Let me know which solution you'd prefer to go with.

Thanks-Jamin
> 
> 
> 
> > +    struct AspeedSgList array[] = {
> > +        {  cpu_to_le32(sizeof(test_vector_sg1)),
> > +           cpu_to_le32(src_addr_1) },
> > +        {  cpu_to_le32(sizeof(test_vector_sg2)),
> > +           cpu_to_le32(src_addr_2) },
> > +        {  cpu_to_le32(sizeof(test_vector_sg3) | SG_LIST_LEN_LAST),
> > +           cpu_to_le32(src_addr_3) },
> > +    };
> > +
> > +    /* Check engine is idle, no busy or irq bits set */
> > +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> > +
> > +    /* Write test vector into memory */
> > +    qtest_memwrite(s, src_addr_1, test_vector_sg1,
> sizeof(test_vector_sg1));
> > +    qtest_memwrite(s, src_addr_2, test_vector_sg2,
> sizeof(test_vector_sg2));
> > +    qtest_memwrite(s, src_addr_3, test_vector_sg3,
> sizeof(test_vector_sg3));
> > +    qtest_memwrite(s, src_addr, array, sizeof(array));
> > +
> > +    write_regs(s, base, src_addr,
> > +               (sizeof(test_vector_sg1)
> > +                + sizeof(test_vector_sg2)
> > +                + sizeof(test_vector_sg3)),
> > +               digest_addr, HACE_ALGO_SHA384 | HACE_SG_EN);
> > +
> > +    /* Check hash IRQ status is asserted */
> > +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
> > +
> > +    /* Clear IRQ status and check status is deasserted */
> > +    qtest_writel(s, base + HACE_STS, 0x00000200);
> > +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> > +
> > +    /* Read computed digest from memory */
> > +    qtest_memread(s, digest_addr, digest, sizeof(digest));
> > +
> > +    /* Check result of computation */
> > +    g_assert_cmpmem(digest, sizeof(digest),
> > +                    test_result_sg_sha384, sizeof(digest));
> > +
> > +    qtest_quit(s);
> > +}
> > +
> >   void aspeed_test_sha512_sg(const char *machine, const uint32_t base,
> >                              const uint32_t src_addr)
> >   {
> > @@ -372,6 +493,47 @@ void aspeed_test_sha256_accum(const char
> *machine, const uint32_t base,
> >       qtest_quit(s);
> >   }
> >
> > +void aspeed_test_sha384_accum(const char *machine, const uint32_t base,
> > +                              const uint32_t src_addr) {
> > +    QTestState *s = qtest_init(machine);
> > +
> > +    const uint32_t buffer_addr = src_addr + 0x10000;
> > +    const uint32_t digest_addr = src_addr + 0x40000;
> > +    uint8_t digest[64] = {0};
> 
> ../tests/qtest/aspeed-hace-utils.c: In function ‘aspeed_test_sha384_accum’:
> /usr/include/glib-2.0/glib/gtestutils.h:93:84: error: ‘__builtin_memcmp_eq’
> specified bound 64 exceeds source size 48 [-Werror=stringop-overread]
>     93 |                                              else if
> (__l1 != 0 && __m2 != NULL && memcmp (__m1, __m2, __l1) != 0) \
>        |
> ^~~~~~~~~~~~~~~~~~~~~~~~~
> ../tests/qtest/aspeed-hace-utils.c:533:5: note: in expansion of macro
> ‘g_assert_cmpmem’
>    533 |     g_assert_cmpmem(digest, sizeof(digest),
>        |     ^~~~~~~~~~~~~~~
> ../tests/qtest/aspeed-hace-utils.c:145:22: note: source object declared here
>    145 | static const uint8_t test_result_accum_sha384[] = {
>        |                      ^~~~~~~~~~~~~~~~~~~~~~~~
> 
> 
> Thanks,
> 
> C.
> 
> 
> 
> > +    struct AspeedSgList array[] = {
> > +        {  cpu_to_le32(sizeof(test_vector_accum_384) |
> SG_LIST_LEN_LAST),
> > +           cpu_to_le32(buffer_addr) },
> > +    };
> > +
> > +    /* Check engine is idle, no busy or irq bits set */
> > +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> > +
> > +    /* Write test vector into memory */
> > +    qtest_memwrite(s, buffer_addr, test_vector_accum_384,
> > +                   sizeof(test_vector_accum_384));
> > +    qtest_memwrite(s, src_addr, array, sizeof(array));
> > +
> > +    write_regs(s, base, src_addr, sizeof(test_vector_accum_384),
> > +               digest_addr, HACE_ALGO_SHA384 | HACE_SG_EN |
> > + HACE_ACCUM_EN);
> > +
> > +    /* Check hash IRQ status is asserted */
> > +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
> > +
> > +    /* Clear IRQ status and check status is deasserted */
> > +    qtest_writel(s, base + HACE_STS, 0x00000200);
> > +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> > +
> > +    /* Read computed digest from memory */
> > +    qtest_memread(s, digest_addr, digest, sizeof(digest));
> > +
> > +    /* Check result of computation */
> > +    g_assert_cmpmem(digest, sizeof(digest),
> > +                    test_result_accum_sha384, sizeof(digest));
> > +
> > +    qtest_quit(s);
> > +}
> > +
> >   void aspeed_test_sha512_accum(const char *machine, const uint32_t
> base,
> >                                 const uint32_t src_addr)
> >   {


^ permalink raw reply	[flat|nested] 71+ messages in thread

* RE: [PATCH v1 13/22] test/qtest: Introduce a new aspeed-hace-utils.c to place common testcases
  2025-04-02  8:54   ` Cédric Le Goater
@ 2025-05-05  6:42     ` Jamin Lin
  0 siblings, 0 replies; 71+ messages in thread
From: Jamin Lin @ 2025-05-05  6:42 UTC (permalink / raw)
  To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
	Andrew Jeffery, Joel Stanley, Fabiano Rosas, Laurent Vivier,
	Paolo Bonzini, open list:ASPEED BMCs,
	open list:All patches CC here
  Cc: Troy Lee

Hi Cédric

> Subject: Re: [PATCH v1 13/22] test/qtest: Introduce a new aspeed-hace-utils.c
> to place common testcases
> 
> On 3/21/25 10:26, Jamin Lin wrote:
> > The test cases for the ASPEED HACE model were originally placed in
> > aspeed_hace-test.c. However, this test file only supports ARM32. To
> > enable compatibility with all ASPEED SoCs, including the AST2700,
> > which uses the
> > AArch64 architecture, this update introduces a new source file,
> > aspeed-hace-utils.c.
> >
> > All common APIs and test cases have been moved from aspeed_hace-test.c
> > to aspeed-hace-utils.c to facilitate reuse across different ASPEED SoCs.
> > As a result, these test cases can now be reused for AST2700 and future
> > ASPEED SoC testing.
> >
> > Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
> 
> One comment, the digest reference arrays should have fixed sizes.
> 
> Looks ok :
> 
> 0000000000085fa0 l     O .rodata	0000000000000020
> test_result_accum_sha256
> 0000000000085fc0 l     O .rodata	0000000000000040
> test_result_accum_sha512
> 00000000000860c0 l     O .rodata	0000000000000020
> test_result_sg_sha256
> 00000000000860e0 l     O .rodata	0000000000000040
> test_result_sg_sha512
> 0000000000086130 l     O .rodata	0000000000000010
> test_result_md5
> 0000000000086140 l     O .rodata	0000000000000020
> test_result_sha256
> 0000000000086160 l     O .rodata	0000000000000040
> test_result_sha512
> 
> but it would be safer add a size when the array is defined.
> 
> Anyhow, this is for another patch.
> 

Please see the comments on patch 15 — the array size should be explicitly defined to avoid unexpected compiler issues.
I will submit a new patch in the v2 series to set the size for all global arrays accordingly.

Thanks-Jamin 

> 
> Reviewed-by: Cédric Le Goater <clg@redhat.com>
> 
> Thanks,
> 
> C.
> 
> 
> > ---
> >   tests/qtest/aspeed-hace-utils.h |  71 +++++
> >   tests/qtest/aspeed-hace-utils.c | 455 ++++++++++++++++++++++++++++
> >   tests/qtest/aspeed_hace-test.c  | 515 ++------------------------------
> >   tests/qtest/meson.build         |   1 +
> >   4 files changed, 547 insertions(+), 495 deletions(-)
> >   create mode 100644 tests/qtest/aspeed-hace-utils.h
> >   create mode 100644 tests/qtest/aspeed-hace-utils.c
> >
> > diff --git a/tests/qtest/aspeed-hace-utils.h
> > b/tests/qtest/aspeed-hace-utils.h new file mode 100644 index
> > 0000000000..598577c69b
> > --- /dev/null
> > +++ b/tests/qtest/aspeed-hace-utils.h
> > @@ -0,0 +1,71 @@
> > +/*
> > + * QTest testcase for the ASPEED Hash and Crypto Engine
> > + *
> > + * SPDX-License-Identifier: GPL-2.0-or-later
> > + * Copyright 2021 IBM Corp.
> > + */
> > +
> > +#ifndef TESTS_ASPEED_HACE_UTILS_H
> > +#define TESTS_ASPEED_HACE_UTILS_H
> > +
> > +#include "qemu/osdep.h"
> > +#include "libqtest.h"
> > +#include "qemu/bitops.h"
> > +
> > +#define HACE_CMD                 0x10
> > +#define  HACE_SHA_BE_EN          BIT(3)
> > +#define  HACE_MD5_LE_EN          BIT(2)
> > +#define  HACE_ALGO_MD5           0
> > +#define  HACE_ALGO_SHA1          BIT(5)
> > +#define  HACE_ALGO_SHA224        BIT(6)
> > +#define  HACE_ALGO_SHA256        (BIT(4) | BIT(6))
> > +#define  HACE_ALGO_SHA512        (BIT(5) | BIT(6))
> > +#define  HACE_ALGO_SHA384        (BIT(5) | BIT(6) | BIT(10))
> > +#define  HACE_SG_EN              BIT(18)
> > +#define  HACE_ACCUM_EN           BIT(8)
> > +
> > +#define HACE_STS                 0x1c
> > +#define  HACE_RSA_ISR            BIT(13)
> > +#define  HACE_CRYPTO_ISR         BIT(12)
> > +#define  HACE_HASH_ISR           BIT(9)
> > +#define  HACE_RSA_BUSY           BIT(2)
> > +#define  HACE_CRYPTO_BUSY        BIT(1)
> > +#define  HACE_HASH_BUSY          BIT(0)
> > +#define HACE_HASH_SRC            0x20
> > +#define HACE_HASH_DIGEST         0x24
> > +#define HACE_HASH_KEY_BUFF       0x28
> > +#define HACE_HASH_DATA_LEN       0x2c
> > +#define HACE_HASH_CMD            0x30
> > +
> > +/* Scatter-Gather Hash */
> > +#define SG_LIST_LEN_LAST         BIT(31)
> > +struct AspeedSgList {
> > +        uint32_t len;
> > +        uint32_t addr;
> > +} __attribute__ ((__packed__));
> > +
> > +struct AspeedMasks {
> > +    uint32_t src;
> > +    uint32_t dest;
> > +    uint32_t len;
> > +};
> > +
> > +void aspeed_test_md5(const char *machine, const uint32_t base,
> > +                     const uint32_t src_addr); void
> > +aspeed_test_sha256(const char *machine, const uint32_t base,
> > +                        const uint32_t src_addr); void
> > +aspeed_test_sha512(const char *machine, const uint32_t base,
> > +                        const uint32_t src_addr); void
> > +aspeed_test_sha256_sg(const char *machine, const uint32_t base,
> > +                           const uint32_t src_addr); void
> > +aspeed_test_sha512_sg(const char *machine, const uint32_t base,
> > +                           const uint32_t src_addr); void
> > +aspeed_test_sha256_accum(const char *machine, const uint32_t base,
> > +                              const uint32_t src_addr); void
> > +aspeed_test_sha512_accum(const char *machine, const uint32_t base,
> > +                              const uint32_t src_addr); void
> > +aspeed_test_addresses(const char *machine, const uint32_t base,
> > +                           const struct AspeedMasks *expected);
> > +
> > +#endif /* TESTS_ASPEED_HACE_UTILS_H */
> > +
> > diff --git a/tests/qtest/aspeed-hace-utils.c
> > b/tests/qtest/aspeed-hace-utils.c new file mode 100644 index
> > 0000000000..8582847945
> > --- /dev/null
> > +++ b/tests/qtest/aspeed-hace-utils.c
> > @@ -0,0 +1,455 @@
> > +/*
> > + * QTest testcase for the ASPEED Hash and Crypto Engine
> > + *
> > + * SPDX-License-Identifier: GPL-2.0-or-later
> > + * Copyright 2021 IBM Corp.
> > + */
> > +
> > +#include "qemu/osdep.h"
> > +#include "libqtest.h"
> > +#include "qemu/bitops.h"
> > +#include "aspeed-hace-utils.h"
> > +
> > +/*
> > + * Test vector is the ascii "abc"
> > + *
> > + * Expected results were generated using command line utitiles:
> > + *
> > + *  echo -n -e 'abc' | dd of=/tmp/test
> > + *  for hash in sha512sum sha256sum md5sum; do $hash /tmp/test; done
> > + *
> > + */
> > +static const uint8_t test_vector[] = {0x61, 0x62, 0x63};
> > +
> > +static const uint8_t test_result_sha512[] = {
> > +    0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba, 0xcc, 0x41, 0x73, 0x49,
> > +    0xae, 0x20, 0x41, 0x31, 0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2,
> > +    0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a, 0x21, 0x92, 0x99,
> 0x2a,
> > +    0x27, 0x4f, 0xc1, 0xa8, 0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd,
> > +    0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e, 0x2a, 0x9a, 0xc9, 0x4f,
> > +    0xa5, 0x4c, 0xa4, 0x9f};
> > +
> > +static const uint8_t test_result_sha256[] = {
> > +    0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, 0xde,
> > +    0x5d, 0xae, 0x22, 0x23, 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a,
> 0x9c,
> > +    0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad};
> > +
> > +static const uint8_t test_result_md5[] = {
> > +    0x90, 0x01, 0x50, 0x98, 0x3c, 0xd2, 0x4f, 0xb0, 0xd6, 0x96, 0x3f, 0x7d,
> > +    0x28, 0xe1, 0x7f, 0x72};
> > +
> > +/*
> > + * The Scatter-Gather Test vector is the ascii "abc" "def" "ghi",
> > +broken
> > + * into blocks of 3 characters as shown
> > + *
> > + * Expected results were generated using command line utitiles:
> > + *
> > + *  echo -n -e 'abcdefghijkl' | dd of=/tmp/test
> > + *  for hash in sha512sum sha256sum; do $hash /tmp/test; done
> > + *
> > + */
> > +static const uint8_t test_vector_sg1[] = {0x61, 0x62, 0x63, 0x64,
> > +0x65, 0x66}; static const uint8_t test_vector_sg2[] = {0x67, 0x68,
> > +0x69}; static const uint8_t test_vector_sg3[] = {0x6a, 0x6b, 0x6c};
> > +
> > +static const uint8_t test_result_sg_sha512[] = {
> > +    0x17, 0x80, 0x7c, 0x72, 0x8e, 0xe3, 0xba, 0x35, 0xe7, 0xcf, 0x7a, 0xf8,
> > +    0x23, 0x11, 0x6d, 0x26, 0xe4, 0x1e, 0x5d, 0x4d, 0x6c, 0x2f, 0xf1, 0xf3,
> > +    0x72, 0x0d, 0x3d, 0x96, 0xaa, 0xcb, 0x6f, 0x69, 0xde, 0x64, 0x2e, 0x63,
> > +    0xd5, 0xb7, 0x3f, 0xc3, 0x96, 0xc1, 0x2b, 0xe3, 0x8b, 0x2b, 0xd5, 0xd8,
> > +    0x84, 0x25, 0x7c, 0x32, 0xc8, 0xf6, 0xd0, 0x85, 0x4a, 0xe6, 0xb5, 0x40,
> > +    0xf8, 0x6d, 0xda, 0x2e};
> > +
> > +static const uint8_t test_result_sg_sha256[] = {
> > +    0xd6, 0x82, 0xed, 0x4c, 0xa4, 0xd9, 0x89, 0xc1, 0x34, 0xec, 0x94, 0xf1,
> > +    0x55, 0x1e, 0x1e, 0xc5, 0x80, 0xdd, 0x6d, 0x5a, 0x6e, 0xcd, 0xe9, 0xf3,
> > +    0xd3, 0x5e, 0x6e, 0x4a, 0x71, 0x7f, 0xbd, 0xe4};
> > +
> > +/*
> > + * The accumulative mode requires firmware to provide internal
> > +initial state
> > + * and message padding (including length L at the end of padding).
> > + *
> > + * This test vector is a ascii text "abc" with padding message.
> > + *
> > + * Expected results were generated using command line utitiles:
> > + *
> > + *  echo -n -e 'abc' | dd of=/tmp/test
> > + *  for hash in sha512sum sha256sum; do $hash /tmp/test; done  */
> > +static const uint8_t test_vector_accum_512[] = {
> > +    0x61, 0x62, 0x63, 0x80, 0x00, 0x00, 0x00, 0x00,
> > +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18};
> > +
> > +static const uint8_t test_vector_accum_256[] = {
> > +    0x61, 0x62, 0x63, 0x80, 0x00, 0x00, 0x00, 0x00,
> > +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18};
> > +
> > +static const uint8_t test_result_accum_sha512[] = {
> > +    0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba, 0xcc, 0x41, 0x73, 0x49,
> > +    0xae, 0x20, 0x41, 0x31, 0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2,
> > +    0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a, 0x21, 0x92, 0x99,
> 0x2a,
> > +    0x27, 0x4f, 0xc1, 0xa8, 0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd,
> > +    0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e, 0x2a, 0x9a, 0xc9, 0x4f,
> > +    0xa5, 0x4c, 0xa4, 0x9f};
> > +
> > +static const uint8_t test_result_accum_sha256[] = {
> > +    0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, 0xde,
> > +    0x5d, 0xae, 0x22, 0x23, 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a,
> 0x9c,
> > +    0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad};
> > +
> > +static void write_regs(QTestState *s, uint32_t base, uint32_t src,
> > +                       uint32_t length, uint32_t out, uint32_t
> > +method) {
> > +        qtest_writel(s, base + HACE_HASH_SRC, src);
> > +        qtest_writel(s, base + HACE_HASH_DIGEST, out);
> > +        qtest_writel(s, base + HACE_HASH_DATA_LEN, length);
> > +        qtest_writel(s, base + HACE_HASH_CMD, HACE_SHA_BE_EN |
> > +method); }
> > +
> > +void aspeed_test_md5(const char *machine, const uint32_t base,
> > +                     const uint32_t src_addr)
> > +
> > +{
> > +    QTestState *s = qtest_init(machine);
> > +
> > +    uint32_t digest_addr = src_addr + 0x01000000;
> > +    uint8_t digest[16] = {0};
> > +
> > +    /* Check engine is idle, no busy or irq bits set */
> > +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> > +
> > +    /* Write test vector into memory */
> > +    qtest_memwrite(s, src_addr, test_vector, sizeof(test_vector));
> > +
> > +    write_regs(s, base, src_addr, sizeof(test_vector),
> > +               digest_addr, HACE_ALGO_MD5);
> > +
> > +    /* Check hash IRQ status is asserted */
> > +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
> > +
> > +    /* Clear IRQ status and check status is deasserted */
> > +    qtest_writel(s, base + HACE_STS, 0x00000200);
> > +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> > +
> > +    /* Read computed digest from memory */
> > +    qtest_memread(s, digest_addr, digest, sizeof(digest));
> > +
> > +    /* Check result of computation */
> > +    g_assert_cmpmem(digest, sizeof(digest),
> > +                    test_result_md5, sizeof(digest));
> > +
> > +    qtest_quit(s);
> > +}
> > +
> > +void aspeed_test_sha256(const char *machine, const uint32_t base,
> > +                        const uint32_t src_addr) {
> > +    QTestState *s = qtest_init(machine);
> > +
> > +    const uint32_t digest_addr = src_addr + 0x1000000;
> > +    uint8_t digest[32] = {0};
> > +
> > +    /* Check engine is idle, no busy or irq bits set */
> > +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> > +
> > +    /* Write test vector into memory */
> > +    qtest_memwrite(s, src_addr, test_vector, sizeof(test_vector));
> > +
> > +    write_regs(s, base, src_addr, sizeof(test_vector), digest_addr,
> > +               HACE_ALGO_SHA256);
> > +
> > +    /* Check hash IRQ status is asserted */
> > +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
> > +
> > +    /* Clear IRQ status and check status is deasserted */
> > +    qtest_writel(s, base + HACE_STS, 0x00000200);
> > +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> > +
> > +    /* Read computed digest from memory */
> > +    qtest_memread(s, digest_addr, digest, sizeof(digest));
> > +
> > +    /* Check result of computation */
> > +    g_assert_cmpmem(digest, sizeof(digest),
> > +                    test_result_sha256, sizeof(digest));
> > +
> > +    qtest_quit(s);
> > +}
> > +
> > +void aspeed_test_sha512(const char *machine, const uint32_t base,
> > +                        const uint32_t src_addr) {
> > +    QTestState *s = qtest_init(machine);
> > +
> > +    const uint32_t digest_addr = src_addr + 0x1000000;
> > +    uint8_t digest[64] = {0};
> > +
> > +    /* Check engine is idle, no busy or irq bits set */
> > +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> > +
> > +    /* Write test vector into memory */
> > +    qtest_memwrite(s, src_addr, test_vector, sizeof(test_vector));
> > +
> > +    write_regs(s, base, src_addr, sizeof(test_vector), digest_addr,
> > +               HACE_ALGO_SHA512);
> > +
> > +    /* Check hash IRQ status is asserted */
> > +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
> > +
> > +    /* Clear IRQ status and check status is deasserted */
> > +    qtest_writel(s, base + HACE_STS, 0x00000200);
> > +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> > +
> > +    /* Read computed digest from memory */
> > +    qtest_memread(s, digest_addr, digest, sizeof(digest));
> > +
> > +    /* Check result of computation */
> > +    g_assert_cmpmem(digest, sizeof(digest),
> > +                    test_result_sha512, sizeof(digest));
> > +
> > +    qtest_quit(s);
> > +}
> > +
> > +void aspeed_test_sha256_sg(const char *machine, const uint32_t base,
> > +                           const uint32_t src_addr) {
> > +    QTestState *s = qtest_init(machine);
> > +
> > +    const uint32_t src_addr_1 = src_addr + 0x1000000;
> > +    const uint32_t src_addr_2 = src_addr + 0x2000000;
> > +    const uint32_t src_addr_3 = src_addr + 0x3000000;
> > +    const uint32_t digest_addr = src_addr + 0x4000000;
> > +    uint8_t digest[32] = {0};
> > +    struct AspeedSgList array[] = {
> > +        {  cpu_to_le32(sizeof(test_vector_sg1)),
> > +           cpu_to_le32(src_addr_1) },
> > +        {  cpu_to_le32(sizeof(test_vector_sg2)),
> > +           cpu_to_le32(src_addr_2) },
> > +        {  cpu_to_le32(sizeof(test_vector_sg3) | SG_LIST_LEN_LAST),
> > +           cpu_to_le32(src_addr_3) },
> > +    };
> > +
> > +    /* Check engine is idle, no busy or irq bits set */
> > +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> > +
> > +    /* Write test vector into memory */
> > +    qtest_memwrite(s, src_addr_1, test_vector_sg1,
> sizeof(test_vector_sg1));
> > +    qtest_memwrite(s, src_addr_2, test_vector_sg2,
> sizeof(test_vector_sg2));
> > +    qtest_memwrite(s, src_addr_3, test_vector_sg3,
> sizeof(test_vector_sg3));
> > +    qtest_memwrite(s, src_addr, array, sizeof(array));
> > +
> > +    write_regs(s, base, src_addr,
> > +               (sizeof(test_vector_sg1)
> > +                + sizeof(test_vector_sg2)
> > +                + sizeof(test_vector_sg3)),
> > +               digest_addr, HACE_ALGO_SHA256 | HACE_SG_EN);
> > +
> > +    /* Check hash IRQ status is asserted */
> > +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
> > +
> > +    /* Clear IRQ status and check status is deasserted */
> > +    qtest_writel(s, base + HACE_STS, 0x00000200);
> > +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> > +
> > +    /* Read computed digest from memory */
> > +    qtest_memread(s, digest_addr, digest, sizeof(digest));
> > +
> > +    /* Check result of computation */
> > +    g_assert_cmpmem(digest, sizeof(digest),
> > +                    test_result_sg_sha256, sizeof(digest));
> > +
> > +    qtest_quit(s);
> > +}
> > +
> > +void aspeed_test_sha512_sg(const char *machine, const uint32_t base,
> > +                           const uint32_t src_addr) {
> > +    QTestState *s = qtest_init(machine);
> > +
> > +    const uint32_t src_addr_1 = src_addr + 0x1000000;
> > +    const uint32_t src_addr_2 = src_addr + 0x2000000;
> > +    const uint32_t src_addr_3 = src_addr + 0x3000000;
> > +    const uint32_t digest_addr = src_addr + 0x4000000;
> > +    uint8_t digest[64] = {0};
> > +    struct AspeedSgList array[] = {
> > +        {  cpu_to_le32(sizeof(test_vector_sg1)),
> > +           cpu_to_le32(src_addr_1) },
> > +        {  cpu_to_le32(sizeof(test_vector_sg2)),
> > +           cpu_to_le32(src_addr_2) },
> > +        {  cpu_to_le32(sizeof(test_vector_sg3) | SG_LIST_LEN_LAST),
> > +           cpu_to_le32(src_addr_3) },
> > +    };
> > +
> > +    /* Check engine is idle, no busy or irq bits set */
> > +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> > +
> > +    /* Write test vector into memory */
> > +    qtest_memwrite(s, src_addr_1, test_vector_sg1,
> sizeof(test_vector_sg1));
> > +    qtest_memwrite(s, src_addr_2, test_vector_sg2,
> sizeof(test_vector_sg2));
> > +    qtest_memwrite(s, src_addr_3, test_vector_sg3,
> sizeof(test_vector_sg3));
> > +    qtest_memwrite(s, src_addr, array, sizeof(array));
> > +
> > +    write_regs(s, base, src_addr,
> > +               (sizeof(test_vector_sg1)
> > +                + sizeof(test_vector_sg2)
> > +                + sizeof(test_vector_sg3)),
> > +               digest_addr, HACE_ALGO_SHA512 | HACE_SG_EN);
> > +
> > +    /* Check hash IRQ status is asserted */
> > +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
> > +
> > +    /* Clear IRQ status and check status is deasserted */
> > +    qtest_writel(s, base + HACE_STS, 0x00000200);
> > +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> > +
> > +    /* Read computed digest from memory */
> > +    qtest_memread(s, digest_addr, digest, sizeof(digest));
> > +
> > +    /* Check result of computation */
> > +    g_assert_cmpmem(digest, sizeof(digest),
> > +                    test_result_sg_sha512, sizeof(digest));
> > +
> > +    qtest_quit(s);
> > +}
> > +
> > +void aspeed_test_sha256_accum(const char *machine, const uint32_t base,
> > +                              const uint32_t src_addr) {
> > +    QTestState *s = qtest_init(machine);
> > +
> > +    const uint32_t buffer_addr = src_addr + 0x1000000;
> > +    const uint32_t digest_addr = src_addr + 0x4000000;
> > +    uint8_t digest[32] = {0};
> > +    struct AspeedSgList array[] = {
> > +        {  cpu_to_le32(sizeof(test_vector_accum_256) |
> SG_LIST_LEN_LAST),
> > +           cpu_to_le32(buffer_addr) },
> > +    };
> > +
> > +    /* Check engine is idle, no busy or irq bits set */
> > +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> > +
> > +    /* Write test vector into memory */
> > +    qtest_memwrite(s, buffer_addr, test_vector_accum_256,
> > +                   sizeof(test_vector_accum_256));
> > +    qtest_memwrite(s, src_addr, array, sizeof(array));
> > +
> > +    write_regs(s, base, src_addr, sizeof(test_vector_accum_256),
> > +               digest_addr, HACE_ALGO_SHA256 | HACE_SG_EN |
> > + HACE_ACCUM_EN);
> > +
> > +    /* Check hash IRQ status is asserted */
> > +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
> > +
> > +    /* Clear IRQ status and check status is deasserted */
> > +    qtest_writel(s, base + HACE_STS, 0x00000200);
> > +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> > +
> > +    /* Read computed digest from memory */
> > +    qtest_memread(s, digest_addr, digest, sizeof(digest));
> > +
> > +    /* Check result of computation */
> > +    g_assert_cmpmem(digest, sizeof(digest),
> > +                    test_result_accum_sha256, sizeof(digest));
> > +
> > +    qtest_quit(s);
> > +}
> > +
> > +void aspeed_test_sha512_accum(const char *machine, const uint32_t base,
> > +                              const uint32_t src_addr) {
> > +    QTestState *s = qtest_init(machine);
> > +
> > +    const uint32_t buffer_addr = src_addr + 0x1000000;
> > +    const uint32_t digest_addr = src_addr + 0x4000000;
> > +    uint8_t digest[64] = {0};
> > +    struct AspeedSgList array[] = {
> > +        {  cpu_to_le32(sizeof(test_vector_accum_512) |
> SG_LIST_LEN_LAST),
> > +           cpu_to_le32(buffer_addr) },
> > +    };
> > +
> > +    /* Check engine is idle, no busy or irq bits set */
> > +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> > +
> > +    /* Write test vector into memory */
> > +    qtest_memwrite(s, buffer_addr, test_vector_accum_512,
> > +                   sizeof(test_vector_accum_512));
> > +    qtest_memwrite(s, src_addr, array, sizeof(array));
> > +
> > +    write_regs(s, base, src_addr, sizeof(test_vector_accum_512),
> > +               digest_addr, HACE_ALGO_SHA512 | HACE_SG_EN |
> > + HACE_ACCUM_EN);
> > +
> > +    /* Check hash IRQ status is asserted */
> > +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
> > +
> > +    /* Clear IRQ status and check status is deasserted */
> > +    qtest_writel(s, base + HACE_STS, 0x00000200);
> > +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> > +
> > +    /* Read computed digest from memory */
> > +    qtest_memread(s, digest_addr, digest, sizeof(digest));
> > +
> > +    /* Check result of computation */
> > +    g_assert_cmpmem(digest, sizeof(digest),
> > +                    test_result_accum_sha512, sizeof(digest));
> > +
> > +    qtest_quit(s);
> > +}
> > +
> > +void aspeed_test_addresses(const char *machine, const uint32_t base,
> > +                           const struct AspeedMasks *expected) {
> > +    QTestState *s = qtest_init(machine);
> > +
> > +    /*
> > +     * Check command mode is zero, meaning engine is in direct access
> mode,
> > +     * as this affects the masking behavior of the HASH_SRC register.
> > +     */
> > +    g_assert_cmphex(qtest_readl(s, base + HACE_CMD), ==, 0);
> > +    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_SRC), ==, 0);
> > +    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DIGEST), ==, 0);
> > +    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DATA_LEN), ==,
> > + 0);
> > +
> > +
> > +    /* Check that the address masking is correct */
> > +    qtest_writel(s, base + HACE_HASH_SRC, 0xffffffff);
> > +    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_SRC), ==,
> > + expected->src);
> > +
> > +    qtest_writel(s, base + HACE_HASH_DIGEST, 0xffffffff);
> > +    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DIGEST), ==,
> > +                    expected->dest);
> > +
> > +    qtest_writel(s, base + HACE_HASH_DATA_LEN, 0xffffffff);
> > +    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DATA_LEN), ==,
> > +                    expected->len);
> > +
> > +    /* Reset to zero */
> > +    qtest_writel(s, base + HACE_HASH_SRC, 0);
> > +    qtest_writel(s, base + HACE_HASH_DIGEST, 0);
> > +    qtest_writel(s, base + HACE_HASH_DATA_LEN, 0);
> > +
> > +    /* Check that all bits are now zero */
> > +    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_SRC), ==, 0);
> > +    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DIGEST), ==, 0);
> > +    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DATA_LEN), ==,
> > + 0);
> > +
> > +    qtest_quit(s);
> > +}
> > +
> > diff --git a/tests/qtest/aspeed_hace-test.c
> > b/tests/qtest/aspeed_hace-test.c index ce86a44672..42a306af2a 100644
> > --- a/tests/qtest/aspeed_hace-test.c
> > +++ b/tests/qtest/aspeed_hace-test.c
> > @@ -6,584 +6,109 @@
> >    */
> >
> >   #include "qemu/osdep.h"
> > -
> >   #include "libqtest.h"
> >   #include "qemu/bitops.h"
> > +#include "aspeed-hace-utils.h"
> >
> > -#define HACE_CMD                 0x10
> > -#define  HACE_SHA_BE_EN          BIT(3)
> > -#define  HACE_MD5_LE_EN          BIT(2)
> > -#define  HACE_ALGO_MD5           0
> > -#define  HACE_ALGO_SHA1          BIT(5)
> > -#define  HACE_ALGO_SHA224        BIT(6)
> > -#define  HACE_ALGO_SHA256        (BIT(4) | BIT(6))
> > -#define  HACE_ALGO_SHA512        (BIT(5) | BIT(6))
> > -#define  HACE_ALGO_SHA384        (BIT(5) | BIT(6) | BIT(10))
> > -#define  HACE_SG_EN              BIT(18)
> > -#define  HACE_ACCUM_EN           BIT(8)
> > -
> > -#define HACE_STS                 0x1c
> > -#define  HACE_RSA_ISR            BIT(13)
> > -#define  HACE_CRYPTO_ISR         BIT(12)
> > -#define  HACE_HASH_ISR           BIT(9)
> > -#define  HACE_RSA_BUSY           BIT(2)
> > -#define  HACE_CRYPTO_BUSY        BIT(1)
> > -#define  HACE_HASH_BUSY          BIT(0)
> > -#define HACE_HASH_SRC            0x20
> > -#define HACE_HASH_DIGEST         0x24
> > -#define HACE_HASH_KEY_BUFF       0x28
> > -#define HACE_HASH_DATA_LEN       0x2c
> > -#define HACE_HASH_CMD            0x30
> > -/* Scatter-Gather Hash */
> > -#define SG_LIST_LEN_LAST         BIT(31)
> > -struct AspeedSgList {
> > -        uint32_t len;
> > -        uint32_t addr;
> > -} __attribute__ ((__packed__));
> > -
> > -/*
> > - * Test vector is the ascii "abc"
> > - *
> > - * Expected results were generated using command line utitiles:
> > - *
> > - *  echo -n -e 'abc' | dd of=/tmp/test
> > - *  for hash in sha512sum sha256sum md5sum; do $hash /tmp/test; done
> > - *
> > - */
> > -static const uint8_t test_vector[] = {0x61, 0x62, 0x63};
> > -
> > -static const uint8_t test_result_sha512[] = {
> > -    0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba, 0xcc, 0x41, 0x73, 0x49,
> > -    0xae, 0x20, 0x41, 0x31, 0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2,
> > -    0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a, 0x21, 0x92, 0x99, 0x2a,
> > -    0x27, 0x4f, 0xc1, 0xa8, 0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd,
> > -    0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e, 0x2a, 0x9a, 0xc9, 0x4f,
> > -    0xa5, 0x4c, 0xa4, 0x9f};
> > -
> > -static const uint8_t test_result_sha256[] = {
> > -    0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, 0xde,
> > -    0x5d, 0xae, 0x22, 0x23, 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
> > -    0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad};
> > -
> > -static const uint8_t test_result_md5[] = {
> > -    0x90, 0x01, 0x50, 0x98, 0x3c, 0xd2, 0x4f, 0xb0, 0xd6, 0x96, 0x3f, 0x7d,
> > -    0x28, 0xe1, 0x7f, 0x72};
> > -
> > -/*
> > - * The Scatter-Gather Test vector is the ascii "abc" "def" "ghi",
> > broken
> > - * into blocks of 3 characters as shown
> > - *
> > - * Expected results were generated using command line utitiles:
> > - *
> > - *  echo -n -e 'abcdefghijkl' | dd of=/tmp/test
> > - *  for hash in sha512sum sha256sum; do $hash /tmp/test; done
> > - *
> > - */
> > -static const uint8_t test_vector_sg1[] = {0x61, 0x62, 0x63, 0x64,
> > 0x65, 0x66}; -static const uint8_t test_vector_sg2[] = {0x67, 0x68,
> > 0x69}; -static const uint8_t test_vector_sg3[] = {0x6a, 0x6b, 0x6c};
> > -
> > -static const uint8_t test_result_sg_sha512[] = {
> > -    0x17, 0x80, 0x7c, 0x72, 0x8e, 0xe3, 0xba, 0x35, 0xe7, 0xcf, 0x7a, 0xf8,
> > -    0x23, 0x11, 0x6d, 0x26, 0xe4, 0x1e, 0x5d, 0x4d, 0x6c, 0x2f, 0xf1, 0xf3,
> > -    0x72, 0x0d, 0x3d, 0x96, 0xaa, 0xcb, 0x6f, 0x69, 0xde, 0x64, 0x2e, 0x63,
> > -    0xd5, 0xb7, 0x3f, 0xc3, 0x96, 0xc1, 0x2b, 0xe3, 0x8b, 0x2b, 0xd5, 0xd8,
> > -    0x84, 0x25, 0x7c, 0x32, 0xc8, 0xf6, 0xd0, 0x85, 0x4a, 0xe6, 0xb5, 0x40,
> > -    0xf8, 0x6d, 0xda, 0x2e};
> > -
> > -static const uint8_t test_result_sg_sha256[] = {
> > -    0xd6, 0x82, 0xed, 0x4c, 0xa4, 0xd9, 0x89, 0xc1, 0x34, 0xec, 0x94, 0xf1,
> > -    0x55, 0x1e, 0x1e, 0xc5, 0x80, 0xdd, 0x6d, 0x5a, 0x6e, 0xcd, 0xe9, 0xf3,
> > -    0xd3, 0x5e, 0x6e, 0x4a, 0x71, 0x7f, 0xbd, 0xe4};
> > -
> > -/*
> > - * The accumulative mode requires firmware to provide internal
> > initial state
> > - * and message padding (including length L at the end of padding).
> > - *
> > - * This test vector is a ascii text "abc" with padding message.
> > - *
> > - * Expected results were generated using command line utitiles:
> > - *
> > - *  echo -n -e 'abc' | dd of=/tmp/test
> > - *  for hash in sha512sum sha256sum; do $hash /tmp/test; done
> > - */
> > -static const uint8_t test_vector_accum_512[] = {
> > -    0x61, 0x62, 0x63, 0x80, 0x00, 0x00, 0x00, 0x00,
> > -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18};
> > -
> > -static const uint8_t test_vector_accum_256[] = {
> > -    0x61, 0x62, 0x63, 0x80, 0x00, 0x00, 0x00, 0x00,
> > -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18};
> > -
> > -static const uint8_t test_result_accum_sha512[] = {
> > -    0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba, 0xcc, 0x41, 0x73, 0x49,
> > -    0xae, 0x20, 0x41, 0x31, 0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2,
> > -    0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a, 0x21, 0x92, 0x99, 0x2a,
> > -    0x27, 0x4f, 0xc1, 0xa8, 0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd,
> > -    0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e, 0x2a, 0x9a, 0xc9, 0x4f,
> > -    0xa5, 0x4c, 0xa4, 0x9f};
> > -
> > -static const uint8_t test_result_accum_sha256[] = {
> > -    0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, 0xde,
> > -    0x5d, 0xae, 0x22, 0x23, 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
> > -    0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad};
> > -
> > -static void write_regs(QTestState *s, uint32_t base, uint32_t src,
> > -                       uint32_t length, uint32_t out, uint32_t method)
> > -{
> > -        qtest_writel(s, base + HACE_HASH_SRC, src);
> > -        qtest_writel(s, base + HACE_HASH_DIGEST, out);
> > -        qtest_writel(s, base + HACE_HASH_DATA_LEN, length);
> > -        qtest_writel(s, base + HACE_HASH_CMD, HACE_SHA_BE_EN |
> method);
> > -}
> > -
> > -static void test_md5(const char *machine, const uint32_t base,
> > -                     const uint32_t src_addr)
> > -
> > -{
> > -    QTestState *s = qtest_init(machine);
> > -
> > -    uint32_t digest_addr = src_addr + 0x01000000;
> > -    uint8_t digest[16] = {0};
> > -
> > -    /* Check engine is idle, no busy or irq bits set */
> > -    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> > -
> > -    /* Write test vector into memory */
> > -    qtest_memwrite(s, src_addr, test_vector, sizeof(test_vector));
> > -
> > -    write_regs(s, base, src_addr, sizeof(test_vector), digest_addr,
> HACE_ALGO_MD5);
> > -
> > -    /* Check hash IRQ status is asserted */
> > -    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
> > -
> > -    /* Clear IRQ status and check status is deasserted */
> > -    qtest_writel(s, base + HACE_STS, 0x00000200);
> > -    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> > -
> > -    /* Read computed digest from memory */
> > -    qtest_memread(s, digest_addr, digest, sizeof(digest));
> > -
> > -    /* Check result of computation */
> > -    g_assert_cmpmem(digest, sizeof(digest),
> > -                    test_result_md5, sizeof(digest));
> > -
> > -    qtest_quit(s);
> > -}
> > -
> > -static void test_sha256(const char *machine, const uint32_t base,
> > -                        const uint32_t src_addr)
> > -{
> > -    QTestState *s = qtest_init(machine);
> > -
> > -    const uint32_t digest_addr = src_addr + 0x1000000;
> > -    uint8_t digest[32] = {0};
> > -
> > -    /* Check engine is idle, no busy or irq bits set */
> > -    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> > -
> > -    /* Write test vector into memory */
> > -    qtest_memwrite(s, src_addr, test_vector, sizeof(test_vector));
> > -
> > -    write_regs(s, base, src_addr, sizeof(test_vector), digest_addr,
> HACE_ALGO_SHA256);
> > -
> > -    /* Check hash IRQ status is asserted */
> > -    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
> > -
> > -    /* Clear IRQ status and check status is deasserted */
> > -    qtest_writel(s, base + HACE_STS, 0x00000200);
> > -    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> > -
> > -    /* Read computed digest from memory */
> > -    qtest_memread(s, digest_addr, digest, sizeof(digest));
> > -
> > -    /* Check result of computation */
> > -    g_assert_cmpmem(digest, sizeof(digest),
> > -                    test_result_sha256, sizeof(digest));
> > -
> > -    qtest_quit(s);
> > -}
> > -
> > -static void test_sha512(const char *machine, const uint32_t base,
> > -                        const uint32_t src_addr)
> > -{
> > -    QTestState *s = qtest_init(machine);
> > -
> > -    const uint32_t digest_addr = src_addr + 0x1000000;
> > -    uint8_t digest[64] = {0};
> > -
> > -    /* Check engine is idle, no busy or irq bits set */
> > -    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> > -
> > -    /* Write test vector into memory */
> > -    qtest_memwrite(s, src_addr, test_vector, sizeof(test_vector));
> > -
> > -    write_regs(s, base, src_addr, sizeof(test_vector), digest_addr,
> HACE_ALGO_SHA512);
> > -
> > -    /* Check hash IRQ status is asserted */
> > -    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
> > -
> > -    /* Clear IRQ status and check status is deasserted */
> > -    qtest_writel(s, base + HACE_STS, 0x00000200);
> > -    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> > -
> > -    /* Read computed digest from memory */
> > -    qtest_memread(s, digest_addr, digest, sizeof(digest));
> > -
> > -    /* Check result of computation */
> > -    g_assert_cmpmem(digest, sizeof(digest),
> > -                    test_result_sha512, sizeof(digest));
> > -
> > -    qtest_quit(s);
> > -}
> > -
> > -static void test_sha256_sg(const char *machine, const uint32_t base,
> > -                        const uint32_t src_addr)
> > -{
> > -    QTestState *s = qtest_init(machine);
> > -
> > -    const uint32_t src_addr_1 = src_addr + 0x1000000;
> > -    const uint32_t src_addr_2 = src_addr + 0x2000000;
> > -    const uint32_t src_addr_3 = src_addr + 0x3000000;
> > -    const uint32_t digest_addr = src_addr + 0x4000000;
> > -    uint8_t digest[32] = {0};
> > -    struct AspeedSgList array[] = {
> > -        {  cpu_to_le32(sizeof(test_vector_sg1)),
> > -           cpu_to_le32(src_addr_1) },
> > -        {  cpu_to_le32(sizeof(test_vector_sg2)),
> > -           cpu_to_le32(src_addr_2) },
> > -        {  cpu_to_le32(sizeof(test_vector_sg3) | SG_LIST_LEN_LAST),
> > -           cpu_to_le32(src_addr_3) },
> > -    };
> > -
> > -    /* Check engine is idle, no busy or irq bits set */
> > -    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> > -
> > -    /* Write test vector into memory */
> > -    qtest_memwrite(s, src_addr_1, test_vector_sg1,
> sizeof(test_vector_sg1));
> > -    qtest_memwrite(s, src_addr_2, test_vector_sg2,
> sizeof(test_vector_sg2));
> > -    qtest_memwrite(s, src_addr_3, test_vector_sg3,
> sizeof(test_vector_sg3));
> > -    qtest_memwrite(s, src_addr, array, sizeof(array));
> > -
> > -    write_regs(s, base, src_addr,
> > -               (sizeof(test_vector_sg1)
> > -                + sizeof(test_vector_sg2)
> > -                + sizeof(test_vector_sg3)),
> > -               digest_addr, HACE_ALGO_SHA256 | HACE_SG_EN);
> > -
> > -    /* Check hash IRQ status is asserted */
> > -    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
> > -
> > -    /* Clear IRQ status and check status is deasserted */
> > -    qtest_writel(s, base + HACE_STS, 0x00000200);
> > -    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> > -
> > -    /* Read computed digest from memory */
> > -    qtest_memread(s, digest_addr, digest, sizeof(digest));
> > -
> > -    /* Check result of computation */
> > -    g_assert_cmpmem(digest, sizeof(digest),
> > -                    test_result_sg_sha256, sizeof(digest));
> > -
> > -    qtest_quit(s);
> > -}
> > -
> > -static void test_sha512_sg(const char *machine, const uint32_t base,
> > -                        const uint32_t src_addr)
> > -{
> > -    QTestState *s = qtest_init(machine);
> > -
> > -    const uint32_t src_addr_1 = src_addr + 0x1000000;
> > -    const uint32_t src_addr_2 = src_addr + 0x2000000;
> > -    const uint32_t src_addr_3 = src_addr + 0x3000000;
> > -    const uint32_t digest_addr = src_addr + 0x4000000;
> > -    uint8_t digest[64] = {0};
> > -    struct AspeedSgList array[] = {
> > -        {  cpu_to_le32(sizeof(test_vector_sg1)),
> > -           cpu_to_le32(src_addr_1) },
> > -        {  cpu_to_le32(sizeof(test_vector_sg2)),
> > -           cpu_to_le32(src_addr_2) },
> > -        {  cpu_to_le32(sizeof(test_vector_sg3) | SG_LIST_LEN_LAST),
> > -           cpu_to_le32(src_addr_3) },
> > -    };
> > -
> > -    /* Check engine is idle, no busy or irq bits set */
> > -    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> > -
> > -    /* Write test vector into memory */
> > -    qtest_memwrite(s, src_addr_1, test_vector_sg1,
> sizeof(test_vector_sg1));
> > -    qtest_memwrite(s, src_addr_2, test_vector_sg2,
> sizeof(test_vector_sg2));
> > -    qtest_memwrite(s, src_addr_3, test_vector_sg3,
> sizeof(test_vector_sg3));
> > -    qtest_memwrite(s, src_addr, array, sizeof(array));
> > -
> > -    write_regs(s, base, src_addr,
> > -               (sizeof(test_vector_sg1)
> > -                + sizeof(test_vector_sg2)
> > -                + sizeof(test_vector_sg3)),
> > -               digest_addr, HACE_ALGO_SHA512 | HACE_SG_EN);
> > -
> > -    /* Check hash IRQ status is asserted */
> > -    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
> > -
> > -    /* Clear IRQ status and check status is deasserted */
> > -    qtest_writel(s, base + HACE_STS, 0x00000200);
> > -    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> > -
> > -    /* Read computed digest from memory */
> > -    qtest_memread(s, digest_addr, digest, sizeof(digest));
> > -
> > -    /* Check result of computation */
> > -    g_assert_cmpmem(digest, sizeof(digest),
> > -                    test_result_sg_sha512, sizeof(digest));
> > -
> > -    qtest_quit(s);
> > -}
> > -
> > -static void test_sha256_accum(const char *machine, const uint32_t base,
> > -                        const uint32_t src_addr)
> > -{
> > -    QTestState *s = qtest_init(machine);
> > -
> > -    const uint32_t buffer_addr = src_addr + 0x1000000;
> > -    const uint32_t digest_addr = src_addr + 0x4000000;
> > -    uint8_t digest[32] = {0};
> > -    struct AspeedSgList array[] = {
> > -        {  cpu_to_le32(sizeof(test_vector_accum_256) |
> SG_LIST_LEN_LAST),
> > -           cpu_to_le32(buffer_addr) },
> > -    };
> > -
> > -    /* Check engine is idle, no busy or irq bits set */
> > -    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> > -
> > -    /* Write test vector into memory */
> > -    qtest_memwrite(s, buffer_addr, test_vector_accum_256,
> > -                   sizeof(test_vector_accum_256));
> > -    qtest_memwrite(s, src_addr, array, sizeof(array));
> > -
> > -    write_regs(s, base, src_addr, sizeof(test_vector_accum_256),
> > -               digest_addr, HACE_ALGO_SHA256 | HACE_SG_EN |
> HACE_ACCUM_EN);
> > -
> > -    /* Check hash IRQ status is asserted */
> > -    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
> > -
> > -    /* Clear IRQ status and check status is deasserted */
> > -    qtest_writel(s, base + HACE_STS, 0x00000200);
> > -    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> > -
> > -    /* Read computed digest from memory */
> > -    qtest_memread(s, digest_addr, digest, sizeof(digest));
> > -
> > -    /* Check result of computation */
> > -    g_assert_cmpmem(digest, sizeof(digest),
> > -                    test_result_accum_sha256, sizeof(digest));
> > -
> > -    qtest_quit(s);
> > -}
> > -
> > -static void test_sha512_accum(const char *machine, const uint32_t base,
> > -                        const uint32_t src_addr)
> > -{
> > -    QTestState *s = qtest_init(machine);
> > -
> > -    const uint32_t buffer_addr = src_addr + 0x1000000;
> > -    const uint32_t digest_addr = src_addr + 0x4000000;
> > -    uint8_t digest[64] = {0};
> > -    struct AspeedSgList array[] = {
> > -        {  cpu_to_le32(sizeof(test_vector_accum_512) |
> SG_LIST_LEN_LAST),
> > -           cpu_to_le32(buffer_addr) },
> > -    };
> > -
> > -    /* Check engine is idle, no busy or irq bits set */
> > -    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> > -
> > -    /* Write test vector into memory */
> > -    qtest_memwrite(s, buffer_addr, test_vector_accum_512,
> > -                   sizeof(test_vector_accum_512));
> > -    qtest_memwrite(s, src_addr, array, sizeof(array));
> > -
> > -    write_regs(s, base, src_addr, sizeof(test_vector_accum_512),
> > -               digest_addr, HACE_ALGO_SHA512 | HACE_SG_EN |
> HACE_ACCUM_EN);
> > -
> > -    /* Check hash IRQ status is asserted */
> > -    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
> > -
> > -    /* Clear IRQ status and check status is deasserted */
> > -    qtest_writel(s, base + HACE_STS, 0x00000200);
> > -    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> > -
> > -    /* Read computed digest from memory */
> > -    qtest_memread(s, digest_addr, digest, sizeof(digest));
> > -
> > -    /* Check result of computation */
> > -    g_assert_cmpmem(digest, sizeof(digest),
> > -                    test_result_accum_sha512, sizeof(digest));
> > -
> > -    qtest_quit(s);
> > -}
> > -
> > -struct masks {
> > -    uint32_t src;
> > -    uint32_t dest;
> > -    uint32_t len;
> > -};
> > -
> > -static const struct masks ast2600_masks = {
> > +static const struct AspeedMasks ast2600_masks = {
> >       .src  = 0x7fffffff,
> >       .dest = 0x7ffffff8,
> >       .len  = 0x0fffffff,
> >   };
> >
> > -static const struct masks ast2500_masks = {
> > +static const struct AspeedMasks ast2500_masks = {
> >       .src  = 0x3fffffff,
> >       .dest = 0x3ffffff8,
> >       .len  = 0x0fffffff,
> >   };
> >
> > -static const struct masks ast2400_masks = {
> > +static const struct AspeedMasks ast2400_masks = {
> >       .src  = 0x0fffffff,
> >       .dest = 0x0ffffff8,
> >       .len  = 0x0fffffff,
> >   };
> >
> > -static void test_addresses(const char *machine, const uint32_t base,
> > -                           const struct masks *expected)
> > -{
> > -    QTestState *s = qtest_init(machine);
> > -
> > -    /*
> > -     * Check command mode is zero, meaning engine is in direct access
> mode,
> > -     * as this affects the masking behavior of the HASH_SRC register.
> > -     */
> > -    g_assert_cmphex(qtest_readl(s, base + HACE_CMD), ==, 0);
> > -    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_SRC), ==, 0);
> > -    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DIGEST), ==, 0);
> > -    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DATA_LEN), ==,
> 0);
> > -
> > -
> > -    /* Check that the address masking is correct */
> > -    qtest_writel(s, base + HACE_HASH_SRC, 0xffffffff);
> > -    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_SRC), ==,
> expected->src);
> > -
> > -    qtest_writel(s, base + HACE_HASH_DIGEST, 0xffffffff);
> > -    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DIGEST), ==,
> expected->dest);
> > -
> > -    qtest_writel(s, base + HACE_HASH_DATA_LEN, 0xffffffff);
> > -    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DATA_LEN), ==,
> expected->len);
> > -
> > -    /* Reset to zero */
> > -    qtest_writel(s, base + HACE_HASH_SRC, 0);
> > -    qtest_writel(s, base + HACE_HASH_DIGEST, 0);
> > -    qtest_writel(s, base + HACE_HASH_DATA_LEN, 0);
> > -
> > -    /* Check that all bits are now zero */
> > -    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_SRC), ==, 0);
> > -    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DIGEST), ==, 0);
> > -    g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DATA_LEN), ==,
> 0);
> > -
> > -    qtest_quit(s);
> > -}
> > -
> >   /* ast2600 */
> >   static void test_md5_ast2600(void)
> >   {
> > -    test_md5("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
> > +    aspeed_test_md5("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
> >   }
> >
> >   static void test_sha256_ast2600(void)
> >   {
> > -    test_sha256("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
> > +    aspeed_test_sha256("-machine ast2600-evb", 0x1e6d0000,
> > + 0x80000000);
> >   }
> >
> >   static void test_sha256_sg_ast2600(void)
> >   {
> > -    test_sha256_sg("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
> > +    aspeed_test_sha256_sg("-machine ast2600-evb", 0x1e6d0000,
> > + 0x80000000);
> >   }
> >
> >   static void test_sha512_ast2600(void)
> >   {
> > -    test_sha512("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
> > +    aspeed_test_sha512("-machine ast2600-evb", 0x1e6d0000,
> > + 0x80000000);
> >   }
> >
> >   static void test_sha512_sg_ast2600(void)
> >   {
> > -    test_sha512_sg("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
> > +    aspeed_test_sha512_sg("-machine ast2600-evb", 0x1e6d0000,
> > + 0x80000000);
> >   }
> >
> >   static void test_sha256_accum_ast2600(void)
> >   {
> > -    test_sha256_accum("-machine ast2600-evb", 0x1e6d0000,
> 0x80000000);
> > +    aspeed_test_sha256_accum("-machine ast2600-evb", 0x1e6d0000,
> > + 0x80000000);
> >   }
> >
> >   static void test_sha512_accum_ast2600(void)
> >   {
> > -    test_sha512_accum("-machine ast2600-evb", 0x1e6d0000,
> 0x80000000);
> > +    aspeed_test_sha512_accum("-machine ast2600-evb", 0x1e6d0000,
> > + 0x80000000);
> >   }
> >
> >   static void test_addresses_ast2600(void)
> >   {
> > -    test_addresses("-machine ast2600-evb", 0x1e6d0000,
> &ast2600_masks);
> > +    aspeed_test_addresses("-machine ast2600-evb", 0x1e6d0000,
> > + &ast2600_masks);
> >   }
> >
> >   /* ast2500 */
> >   static void test_md5_ast2500(void)
> >   {
> > -    test_md5("-machine ast2500-evb", 0x1e6e3000, 0x80000000);
> > +    aspeed_test_md5("-machine ast2500-evb", 0x1e6e3000, 0x80000000);
> >   }
> >
> >   static void test_sha256_ast2500(void)
> >   {
> > -    test_sha256("-machine ast2500-evb", 0x1e6e3000, 0x80000000);
> > +    aspeed_test_sha256("-machine ast2500-evb", 0x1e6e3000,
> > + 0x80000000);
> >   }
> >
> >   static void test_sha512_ast2500(void)
> >   {
> > -    test_sha512("-machine ast2500-evb", 0x1e6e3000, 0x80000000);
> > +    aspeed_test_sha512("-machine ast2500-evb", 0x1e6e3000,
> > + 0x80000000);
> >   }
> >
> >   static void test_addresses_ast2500(void)
> >   {
> > -    test_addresses("-machine ast2500-evb", 0x1e6e3000,
> &ast2500_masks);
> > +    aspeed_test_addresses("-machine ast2500-evb", 0x1e6e3000,
> > + &ast2500_masks);
> >   }
> >
> >   /* ast2400 */
> >   static void test_md5_ast2400(void)
> >   {
> > -    test_md5("-machine palmetto-bmc", 0x1e6e3000, 0x40000000);
> > +    aspeed_test_md5("-machine palmetto-bmc", 0x1e6e3000,
> 0x40000000);
> >   }
> >
> >   static void test_sha256_ast2400(void)
> >   {
> > -    test_sha256("-machine palmetto-bmc", 0x1e6e3000, 0x40000000);
> > +    aspeed_test_sha256("-machine palmetto-bmc", 0x1e6e3000,
> > + 0x40000000);
> >   }
> >
> >   static void test_sha512_ast2400(void)
> >   {
> > -    test_sha512("-machine palmetto-bmc", 0x1e6e3000, 0x40000000);
> > +    aspeed_test_sha512("-machine palmetto-bmc", 0x1e6e3000,
> > + 0x40000000);
> >   }
> >
> >   static void test_addresses_ast2400(void)
> >   {
> > -    test_addresses("-machine palmetto-bmc", 0x1e6e3000,
> &ast2400_masks);
> > +    aspeed_test_addresses("-machine palmetto-bmc", 0x1e6e3000,
> > + &ast2400_masks);
> >   }
> >
> >   int main(int argc, char **argv)
> > diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build index
> > 8a6243382a..62fc8f9868 100644
> > --- a/tests/qtest/meson.build
> > +++ b/tests/qtest/meson.build
> > @@ -383,6 +383,7 @@ qtests = {
> >     'netdev-socket': files('netdev-socket.c', '../unit/socket-helpers.c'),
> >     'aspeed_smc-test': files('aspeed-smc-utils.c', 'aspeed_smc-test.c'),
> >     'ast2700-smc-test': files('aspeed-smc-utils.c',
> > 'ast2700-smc-test.c'),
> > +  'aspeed_hace-test': files('aspeed-hace-utils.c',
> > + 'aspeed_hace-test.c'),
> >   }
> >
> >   if vnc.found()


^ permalink raw reply	[flat|nested] 71+ messages in thread

* RE: [PATCH v1 15/22] test/qtest/hace: Add SHA-384 test cases for ASPEED HACE model
  2025-05-05  6:36     ` Jamin Lin
@ 2025-05-05  6:51       ` Jamin Lin
  2025-05-06  8:59         ` Cédric Le Goater
  0 siblings, 1 reply; 71+ messages in thread
From: Jamin Lin @ 2025-05-05  6:51 UTC (permalink / raw)
  To: Jamin Lin, Cédric Le Goater, Peter Maydell, Steven Lee,
	Troy Lee, Andrew Jeffery, Joel Stanley, Fabiano Rosas,
	Laurent Vivier, Paolo Bonzini, open list:ASPEED BMCs,
	open list:All patches CC here
  Cc: Troy Lee

Hi Cédric

> Subject: RE: [PATCH v1 15/22] test/qtest/hace: Add SHA-384 test cases for
> ASPEED HACE model
> 
> Hi Cédric,
> 
> > Subject: Re: [PATCH v1 15/22] test/qtest/hace: Add SHA-384 test cases
> > for ASPEED HACE model
> >
> > On 3/21/25 10:26, Jamin Lin wrote:
> > > Introduced SHA-384 test functions to verify hashing operations.
> > > Extended support for scatter-gather (`_sg`) and accumulation
> > > (`_accum`)
> > tests.
> > > Updated test result vectors for SHA-384 validation.
> > >
> > > Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
> > > ---
> > >   tests/qtest/aspeed-hace-utils.h |   6 ++
> > >   tests/qtest/aspeed-hace-utils.c | 168
> > +++++++++++++++++++++++++++++++-
> > >   2 files changed, 171 insertions(+), 3 deletions(-)
> > >
> > > diff --git a/tests/qtest/aspeed-hace-utils.h
> > > b/tests/qtest/aspeed-hace-utils.h index 598577c69b..f4440561de
> > > 100644
> > > --- a/tests/qtest/aspeed-hace-utils.h
> > > +++ b/tests/qtest/aspeed-hace-utils.h
> > > @@ -54,14 +54,20 @@ void aspeed_test_md5(const char *machine, const
> > uint32_t base,
> > >                        const uint32_t src_addr);
> > >   void aspeed_test_sha256(const char *machine, const uint32_t base,
> > >                           const uint32_t src_addr);
> > > +void aspeed_test_sha384(const char *machine, const uint32_t base,
> > > +                        const uint32_t src_addr);
> > >   void aspeed_test_sha512(const char *machine, const uint32_t base,
> > >                           const uint32_t src_addr);
> > >   void aspeed_test_sha256_sg(const char *machine, const uint32_t base,
> > >                              const uint32_t src_addr);
> > > +void aspeed_test_sha384_sg(const char *machine, const uint32_t base,
> > > +                           const uint32_t src_addr);
> > >   void aspeed_test_sha512_sg(const char *machine, const uint32_t base,
> > >                              const uint32_t src_addr);
> > >   void aspeed_test_sha256_accum(const char *machine, const uint32_t
> > base,
> > >                                 const uint32_t src_addr);
> > > +void aspeed_test_sha384_accum(const char *machine, const uint32_t
> base,
> > > +                              const uint32_t src_addr);
> > >   void aspeed_test_sha512_accum(const char *machine, const uint32_t
> > base,
> > >                                 const uint32_t src_addr);
> > >   void aspeed_test_addresses(const char *machine, const uint32_t
> > > base, diff --git a/tests/qtest/aspeed-hace-utils.c
> > > b/tests/qtest/aspeed-hace-utils.c index 8fbbba49c1..d3146898c2
> > > 100644
> > > --- a/tests/qtest/aspeed-hace-utils.c
> > > +++ b/tests/qtest/aspeed-hace-utils.c
> > > @@ -16,7 +16,7 @@
> > >    * Expected results were generated using command line utitiles:
> > >    *
> > >    *  echo -n -e 'abc' | dd of=/tmp/test
> > > - *  for hash in sha512sum sha256sum md5sum; do $hash /tmp/test;
> > > done
> > > + *  for hash in sha512sum sha384sum sha256sum md5sum; do $hash
> > > + /tmp/test; done
> > >    *
> > >    */
> > >   static const uint8_t test_vector[] = {0x61, 0x62, 0x63}; @@ -29,6
> > > +29,12 @@ static const uint8_t test_result_sha512[] = {
> > >       0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e, 0x2a, 0x9a,
> > > 0xc9,
> > 0x4f,
> > >       0xa5, 0x4c, 0xa4, 0x9f};
> > >
> > > +static const uint8_t test_result_sha384[] = {
> > > +    0xcb, 0x00, 0x75, 0x3f, 0x45, 0xa3, 0x5e, 0x8b, 0xb5, 0xa0, 0x3d,
> 0x69,
> > > +    0x9a, 0xc6, 0x50, 0x07, 0x27, 0x2c, 0x32, 0xab, 0x0e, 0xde,
> > > +0xd1,
> > 0x63,
> > > +    0x1a, 0x8b, 0x60, 0x5a, 0x43, 0xff, 0x5b, 0xed, 0x80, 0x86, 0x07,
> 0x2b,
> > > +    0xa1, 0xe7, 0xcc, 0x23, 0x58, 0xba, 0xec, 0xa1, 0x34, 0xc8,
> > > +0x25, 0xa7};
> > > +
> > >   static const uint8_t test_result_sha256[] = {
> > >       0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41,
> > > 0x40,
> > 0xde,
> > >       0x5d, 0xae, 0x22, 0x23, 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17,
> > > 0x7a, 0x9c, @@ -45,7 +51,7 @@ static const uint8_t test_result_md5[] = {
> > >    * Expected results were generated using command line utitiles:
> > >    *
> > >    *  echo -n -e 'abcdefghijkl' | dd of=/tmp/test
> > > - *  for hash in sha512sum sha256sum; do $hash /tmp/test; done
> > > + *  for hash in sha512sum sha384sum sha256sum; do $hash /tmp/test;
> > > + done
> > >    *
> > >    */
> > >   static const uint8_t test_vector_sg1[] = {0x61, 0x62, 0x63, 0x64,
> > > 0x65, 0x66}; @@ -60,6 +66,12 @@ static const uint8_t
> > test_result_sg_sha512[] = {
> > >       0x84, 0x25, 0x7c, 0x32, 0xc8, 0xf6, 0xd0, 0x85, 0x4a, 0xe6,
> > > 0xb5,
> > 0x40,
> > >       0xf8, 0x6d, 0xda, 0x2e};
> > >
> > > +static const uint8_t test_result_sg_sha384[] = {
> > > +    0x10, 0x3c, 0xa9, 0x6c, 0x06, 0xa1, 0xce, 0x79, 0x8f, 0x08, 0xf8,
> 0xef,
> > > +    0xf0, 0xdf, 0xb0, 0xcc, 0xdb, 0x56, 0x7d, 0x48, 0xb2, 0x85, 0xb2,
> 0x3d,
> > > +    0x0c, 0xd7, 0x73, 0x45, 0x46, 0x67, 0xa3, 0xc2, 0xfa, 0x5f, 0x1b,
> 0x58,
> > > +    0xd9, 0xcd, 0xf2, 0x32, 0x9b, 0xd9, 0x97, 0x97, 0x30, 0xbf,
> > > +0xaa, 0xff};
> > > +
> > >   static const uint8_t test_result_sg_sha256[] = {
> > >       0xd6, 0x82, 0xed, 0x4c, 0xa4, 0xd9, 0x89, 0xc1, 0x34, 0xec,
> > > 0x94,
> > 0xf1,
> > >       0x55, 0x1e, 0x1e, 0xc5, 0x80, 0xdd, 0x6d, 0x5a, 0x6e, 0xcd,
> > > 0xe9, 0xf3, @@ -74,7 +86,7 @@ static const uint8_t
> > > test_result_sg_sha256[]
> > = {
> > >    * Expected results were generated using command line utitiles:
> > >    *
> > >    *  echo -n -e 'abc' | dd of=/tmp/test
> > > - *  for hash in sha512sum sha256sum; do $hash /tmp/test; done
> > > + *  for hash in sha512sum sha384sum sha256sum; do $hash /tmp/test;
> > > + done
> > >    */
> > >   static const uint8_t test_vector_accum_512[] = {
> > >       0x61, 0x62, 0x63, 0x80, 0x00, 0x00, 0x00, 0x00, @@ -94,6
> > > +106,24 @@ static const uint8_t test_vector_accum_512[] = {
> > >       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > >       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18};
> > >
> > > +static const uint8_t test_vector_accum_384[] = {
> > > +    0x61, 0x62, 0x63, 0x80, 0x00, 0x00, 0x00, 0x00,
> > > +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > > +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > > +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > > +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > > +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > > +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > > +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > > +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > > +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > > +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > > +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > > +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > > +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > > +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > > +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18};
> > > +
> > >   static const uint8_t test_vector_accum_256[] = {
> > >       0x61, 0x62, 0x63, 0x80, 0x00, 0x00, 0x00, 0x00,
> > >       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -112,6
> > > +142,12 @@ static const uint8_t test_result_accum_sha512[] = {
> > >       0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e, 0x2a, 0x9a,
> > > 0xc9,
> > 0x4f,
> > >       0xa5, 0x4c, 0xa4, 0x9f};
> > >
> > > +static const uint8_t test_result_accum_sha384[] = {
> > > +    0xcb, 0x00, 0x75, 0x3f, 0x45, 0xa3, 0x5e, 0x8b, 0xb5, 0xa0, 0x3d,
> 0x69,
> > > +    0x9a, 0xc6, 0x50, 0x07, 0x27, 0x2c, 0x32, 0xab, 0x0e, 0xde,
> > > +0xd1,
> > 0x63,
> > > +    0x1a, 0x8b, 0x60, 0x5a, 0x43, 0xff, 0x5b, 0xed, 0x80, 0x86, 0x07,
> 0x2b,
> > > +    0xa1, 0xe7, 0xcc, 0x23, 0x58, 0xba, 0xec, 0xa1, 0x34, 0xc8,
> > > +0x25, 0xa7};
> > > +
> > >   static const uint8_t test_result_accum_sha256[] = {
> > >       0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41,
> > > 0x40,
> > 0xde,
> > >       0x5d, 0xae, 0x22, 0x23, 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17,
> > > 0x7a, 0x9c, @@ -195,6 +231,40 @@ void aspeed_test_sha256(const char
> > *machine, const uint32_t base,
> > >       qtest_quit(s);
> > >   }
> > >
> > > +void aspeed_test_sha384(const char *machine, const uint32_t base,
> > > +                        const uint32_t src_addr) {
> > > +    QTestState *s = qtest_init(machine);
> > > +
> > > +    const uint32_t digest_addr = src_addr + 0x10000;
> > > +    uint8_t digest[32] = {0};
> > > +
> > > +    /* Check engine is idle, no busy or irq bits set */
> > > +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> > > +
> > > +    /* Write test vector into memory */
> > > +    qtest_memwrite(s, src_addr, test_vector, sizeof(test_vector));
> > > +
> > > +    write_regs(s, base, src_addr, sizeof(test_vector), digest_addr,
> > > +               HACE_ALGO_SHA384);
> > > +
> > > +    /* Check hash IRQ status is asserted */
> > > +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==,
> > > + 0x00000200);
> > > +
> > > +    /* Clear IRQ status and check status is deasserted */
> > > +    qtest_writel(s, base + HACE_STS, 0x00000200);
> > > +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> > > +
> > > +    /* Read computed digest from memory */
> > > +    qtest_memread(s, digest_addr, digest, sizeof(digest));
> > > +
> > > +    /* Check result of computation */
> > > +    g_assert_cmpmem(digest, sizeof(digest),
> > > +                    test_result_sha384, sizeof(digest));
> > > +
> > > +    qtest_quit(s);
> > > +}
> > > +
> > >   void aspeed_test_sha512(const char *machine, const uint32_t base,
> > >                           const uint32_t src_addr)
> > >   {
> > > @@ -280,6 +350,57 @@ void aspeed_test_sha256_sg(const char
> *machine,
> > const uint32_t base,
> > >       qtest_quit(s);
> > >   }
> > >
> > > +void aspeed_test_sha384_sg(const char *machine, const uint32_t base,
> > > +                           const uint32_t src_addr) {
> > > +    QTestState *s = qtest_init(machine);
> > > +
> > > +    const uint32_t src_addr_1 = src_addr + 0x10000;
> > > +    const uint32_t src_addr_2 = src_addr + 0x20000;
> > > +    const uint32_t src_addr_3 = src_addr + 0x30000;
> > > +    const uint32_t digest_addr = src_addr + 0x40000;
> > > +    uint8_t digest[64] = {0};
> >
> > This does not compile (gcc version 14.2.1)
> >
> >
> > ../tests/qtest/aspeed-hace-utils.c: In function ‘aspeed_test_sha384_sg’:
> > /usr/include/glib-2.0/glib/gtestutils.h:93:84: error: ‘__builtin_memcmp_eq’
> > specified bound 64 exceeds the size 48 of unterminated array
> > [-Werror=stringop-overread]
> >     93 |                                              else if
> > (__l1 != 0 && __m2 != NULL && memcmp (__m1, __m2, __l1) != 0) \
> >        |
> > ^~~~~~~~~~~~~~~~~~~~~~~~~
> > ../tests/qtest/aspeed-hace-utils.c:399:5: note: in expansion of macro
> > ‘g_assert_cmpmem’
> >    399 |     g_assert_cmpmem(digest, sizeof(digest),
> >        |     ^~~~~~~~~~~~~~~
> > ../tests/qtest/aspeed-hace-utils.c:69:22: note: referenced argument
> > declared here
> >     69 | static const uint8_t test_result_sg_sha384[] = {
> >        |                      ^~~~~~~~~~~~~~~~~~~~~
> >
> 

Sorry, the root cause is that I mistakenly set the digest size to 64 bytes. I will fix it.

uint8_t digest[64] = {0};
static const uint8_t test_result_sg_sha384[] = {
    0x10, 0x3c, 0xa9, 0x6c, 0x06, 0xa1, 0xce, 0x79, 0x8f, 0x08, 0xf8, 0xef,
    0xf0, 0xdf, 0xb0, 0xcc, 0xdb, 0x56, 0x7d, 0x48, 0xb2, 0x85, 0xb2, 0x3d,
    0x0c, 0xd7, 0x73, 0x45, 0x46, 0x67, 0xa3, 0xc2, 0xfa, 0x5f, 0x1b, 0x58,
    0xd9, 0xcd, 0xf2, 0x32, 0x9b, 0xd9, 0x97, 0x97, 0x30, 0xbf, 0xaa, 0xff};
/* Check result of computation */
    g_assert_cmpmem(digest, sizeof(digest), ====> 64bytes
                    test_result_sg_sha384 ===>only 48bytes , sizeof(digest));

However, I believe explicitly setting the array size is the right approach.
I’d appreciate your thoughts or suggestions on this.

Thanks-Jamin

> 
> I didn't explicitly set the array size for "test_result_sg_sha384", and the
> compiler seems to have inferred a size of 64 bytes—likely due to 32-byte
> alignment.
> However, the actual SHA384 digest is 48 bytes, which is why your compiler
> reported an error: it detected a possible buffer overread.
> 
> There are two possible ways to fix this issue:
> 
> Solution 1:
> Define a constant MAX_SIZE_LENGTH (e.g., 64 bytes), and use it for all test
> result arrays:
> 
> test_result_sha512[MAX_SIZE_LENGTH];
> test_result_sha384[MAX_SIZE_LENGTH];
> However, in this case, we cannot use "sizeof(test_result_sha384)" or
> "sizeof(test_result_sha256)" in the test code, because the compiler will
> evaluate them as 128 bytes.
> Therefore, we should use hardcoded digest lengths (48 for SHA384, 32 for
> SHA256) when comparing results in the tests.
> 
> Solution 2:
> Set the actual digest size explicitly in the array definition:
> test_result_sha512[64];
> test_result_sha384[48];
> This ensures "sizeof()" will return the correct digest size, and we can safely use
> it in assertions.
> 
> I prefer solution 2.
> Let me know which solution you'd prefer to go with.
> 
> Thanks-Jamin
> >
> >
> >
> > > +    struct AspeedSgList array[] = {
> > > +        {  cpu_to_le32(sizeof(test_vector_sg1)),
> > > +           cpu_to_le32(src_addr_1) },
> > > +        {  cpu_to_le32(sizeof(test_vector_sg2)),
> > > +           cpu_to_le32(src_addr_2) },
> > > +        {  cpu_to_le32(sizeof(test_vector_sg3) | SG_LIST_LEN_LAST),
> > > +           cpu_to_le32(src_addr_3) },
> > > +    };
> > > +
> > > +    /* Check engine is idle, no busy or irq bits set */
> > > +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> > > +
> > > +    /* Write test vector into memory */
> > > +    qtest_memwrite(s, src_addr_1, test_vector_sg1,
> > sizeof(test_vector_sg1));
> > > +    qtest_memwrite(s, src_addr_2, test_vector_sg2,
> > sizeof(test_vector_sg2));
> > > +    qtest_memwrite(s, src_addr_3, test_vector_sg3,
> > sizeof(test_vector_sg3));
> > > +    qtest_memwrite(s, src_addr, array, sizeof(array));
> > > +
> > > +    write_regs(s, base, src_addr,
> > > +               (sizeof(test_vector_sg1)
> > > +                + sizeof(test_vector_sg2)
> > > +                + sizeof(test_vector_sg3)),
> > > +               digest_addr, HACE_ALGO_SHA384 | HACE_SG_EN);
> > > +
> > > +    /* Check hash IRQ status is asserted */
> > > +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==,
> > > + 0x00000200);
> > > +
> > > +    /* Clear IRQ status and check status is deasserted */
> > > +    qtest_writel(s, base + HACE_STS, 0x00000200);
> > > +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> > > +
> > > +    /* Read computed digest from memory */
> > > +    qtest_memread(s, digest_addr, digest, sizeof(digest));
> > > +
> > > +    /* Check result of computation */
> > > +    g_assert_cmpmem(digest, sizeof(digest),
> > > +                    test_result_sg_sha384, sizeof(digest));
> > > +
> > > +    qtest_quit(s);
> > > +}
> > > +
> > >   void aspeed_test_sha512_sg(const char *machine, const uint32_t base,
> > >                              const uint32_t src_addr)
> > >   {
> > > @@ -372,6 +493,47 @@ void aspeed_test_sha256_accum(const char
> > *machine, const uint32_t base,
> > >       qtest_quit(s);
> > >   }
> > >
> > > +void aspeed_test_sha384_accum(const char *machine, const uint32_t
> base,
> > > +                              const uint32_t src_addr) {
> > > +    QTestState *s = qtest_init(machine);
> > > +
> > > +    const uint32_t buffer_addr = src_addr + 0x10000;
> > > +    const uint32_t digest_addr = src_addr + 0x40000;
> > > +    uint8_t digest[64] = {0};
> >
> > ../tests/qtest/aspeed-hace-utils.c: In function ‘aspeed_test_sha384_accum’:
> > /usr/include/glib-2.0/glib/gtestutils.h:93:84: error: ‘__builtin_memcmp_eq’
> > specified bound 64 exceeds source size 48 [-Werror=stringop-overread]
> >     93 |                                              else if
> > (__l1 != 0 && __m2 != NULL && memcmp (__m1, __m2, __l1) != 0) \
> >        |
> > ^~~~~~~~~~~~~~~~~~~~~~~~~
> > ../tests/qtest/aspeed-hace-utils.c:533:5: note: in expansion of macro
> > ‘g_assert_cmpmem’
> >    533 |     g_assert_cmpmem(digest, sizeof(digest),
> >        |     ^~~~~~~~~~~~~~~
> > ../tests/qtest/aspeed-hace-utils.c:145:22: note: source object declared here
> >    145 | static const uint8_t test_result_accum_sha384[] = {
> >        |                      ^~~~~~~~~~~~~~~~~~~~~~~~
> >
> >
> > Thanks,
> >
> > C.
> >
> >
> >
> > > +    struct AspeedSgList array[] = {
> > > +        {  cpu_to_le32(sizeof(test_vector_accum_384) |
> > SG_LIST_LEN_LAST),
> > > +           cpu_to_le32(buffer_addr) },
> > > +    };
> > > +
> > > +    /* Check engine is idle, no busy or irq bits set */
> > > +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> > > +
> > > +    /* Write test vector into memory */
> > > +    qtest_memwrite(s, buffer_addr, test_vector_accum_384,
> > > +                   sizeof(test_vector_accum_384));
> > > +    qtest_memwrite(s, src_addr, array, sizeof(array));
> > > +
> > > +    write_regs(s, base, src_addr, sizeof(test_vector_accum_384),
> > > +               digest_addr, HACE_ALGO_SHA384 | HACE_SG_EN |
> > > + HACE_ACCUM_EN);
> > > +
> > > +    /* Check hash IRQ status is asserted */
> > > +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==,
> > > + 0x00000200);
> > > +
> > > +    /* Clear IRQ status and check status is deasserted */
> > > +    qtest_writel(s, base + HACE_STS, 0x00000200);
> > > +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
> > > +
> > > +    /* Read computed digest from memory */
> > > +    qtest_memread(s, digest_addr, digest, sizeof(digest));
> > > +
> > > +    /* Check result of computation */
> > > +    g_assert_cmpmem(digest, sizeof(digest),
> > > +                    test_result_accum_sha384, sizeof(digest));
> > > +
> > > +    qtest_quit(s);
> > > +}
> > > +
> > >   void aspeed_test_sha512_accum(const char *machine, const uint32_t
> > base,
> > >                                 const uint32_t src_addr)
> > >   {


^ permalink raw reply	[flat|nested] 71+ messages in thread

* RE: [PATCH v1 09/22] hw/misc/aspeed_hace: Ensure HASH_IRQ is always set to prevent firmware hang
  2025-04-02  9:35   ` Cédric Le Goater
@ 2025-05-06  5:08     ` Jamin Lin
  0 siblings, 0 replies; 71+ messages in thread
From: Jamin Lin @ 2025-05-06  5:08 UTC (permalink / raw)
  To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
	Andrew Jeffery, Joel Stanley, Fabiano Rosas, Laurent Vivier,
	Paolo Bonzini, open list:ASPEED BMCs,
	open list:All patches CC here
  Cc: Troy Lee

Hi Cédric

> Subject: Re: [PATCH v1 09/22] hw/misc/aspeed_hace: Ensure HASH_IRQ is
> always set to prevent firmware hang
> 
> On 3/21/25 10:26, Jamin Lin wrote:
> > Currently, if the program encounters an unsupported algorithm, it does
> > not set the HASH_IRQ bit in the status register and send an interrupt
> > to indicate command completion. As a result, the FW gets stuck waiting
> > for a completion signal from the HACE module.
> >
> > Additionally, in do_hash_operation, if an error occurs within the
> > conditional statement, the HASH_IRQ bit is not set in the status
> > register. This causes the firmware to continuously send HASH commands,
> > as it is unaware that the HACE model has completed processing the
> command.
> >
> > To fix this, the HASH_IRQ bit in the status register must always be
> > set to ensure that the firmware receives an interrupt from the HACE
> > module, preventing it from getting stuck or repeatedly sending HASH
> commands.
> >
> > Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
> 
> Should we add a 'Fixes' trailer ?
Thanks for review and suggestion.
Will add
Jamin

> 
> > ---
> >   hw/misc/aspeed_hace.c | 18 +++++++++---------
> >   1 file changed, 9 insertions(+), 9 deletions(-)
> >
> > diff --git a/hw/misc/aspeed_hace.c b/hw/misc/aspeed_hace.c index
> > 8f333fc97e..d4f653670e 100644
> > --- a/hw/misc/aspeed_hace.c
> > +++ b/hw/misc/aspeed_hace.c
> > @@ -311,12 +311,6 @@ static void do_hash_operation(AspeedHACEState *s,
> int algo, bool sg_mode,
> >                               iov[i - 1].iov_len, false,
> >                               iov[i - 1].iov_len);
> >       }
> > -
> > -    /*
> > -     * Set status bits to indicate completion. Testing shows hardware sets
> > -     * these irrespective of HASH_IRQ_EN.
> > -     */
> > -    s->regs[R_STATUS] |= HASH_IRQ;
> >   }
> >
> >   static uint64_t aspeed_hace_read(void *opaque, hwaddr addr, unsigned
> > int size) @@ -400,10 +394,16 @@ static void aspeed_hace_write(void
> *opaque, hwaddr addr, uint64_t data,
> >                   qemu_log_mask(LOG_GUEST_ERROR,
> >                           "%s: Invalid hash algorithm selection
> 0x%"PRIx64"\n",
> >                           __func__, data & ahc->hash_mask);
> > -                break;
> > +        } else {
> > +            do_hash_operation(s, algo, data & HASH_SG_EN,
> > +                    ((data & HASH_HMAC_MASK) ==
> HASH_DIGEST_ACCUM));
> >           }
> > -        do_hash_operation(s, algo, data & HASH_SG_EN,
> > -                ((data & HASH_HMAC_MASK) ==
> HASH_DIGEST_ACCUM));
> > +
> > +        /*
> > +         * Set status bits to indicate completion. Testing shows hardware
> sets
> > +         * these irrespective of HASH_IRQ_EN.
> 
> is that still true on the AST2700 SoC ?
> 
> > +         */
> > +        s->regs[R_STATUS] |= HASH_IRQ;
> >   >           if (data & HASH_IRQ_EN) {
> >               qemu_irq_raise(s->irq);
> 
> 
> 
> Reviewed-by: Cédric Le Goater <clg@redhat.com>
> 
> Thanks,
> 
> C.
> 


^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v1 15/22] test/qtest/hace: Add SHA-384 test cases for ASPEED HACE model
  2025-05-05  6:51       ` Jamin Lin
@ 2025-05-06  8:59         ` Cédric Le Goater
  0 siblings, 0 replies; 71+ messages in thread
From: Cédric Le Goater @ 2025-05-06  8:59 UTC (permalink / raw)
  To: Jamin Lin, Peter Maydell, Steven Lee, Troy Lee, Andrew Jeffery,
	Joel Stanley, Fabiano Rosas, Laurent Vivier, Paolo Bonzini,
	open list:ASPEED BMCs, open list:All patches CC here
  Cc: Troy Lee

On 5/5/25 08:51, Jamin Lin wrote:
> Hi Cédric
> 
>> Subject: RE: [PATCH v1 15/22] test/qtest/hace: Add SHA-384 test cases for
>> ASPEED HACE model
>>
>> Hi Cédric,
>>
>>> Subject: Re: [PATCH v1 15/22] test/qtest/hace: Add SHA-384 test cases
>>> for ASPEED HACE model
>>>
>>> On 3/21/25 10:26, Jamin Lin wrote:
>>>> Introduced SHA-384 test functions to verify hashing operations.
>>>> Extended support for scatter-gather (`_sg`) and accumulation
>>>> (`_accum`)
>>> tests.
>>>> Updated test result vectors for SHA-384 validation.
>>>>
>>>> Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
>>>> ---
>>>>    tests/qtest/aspeed-hace-utils.h |   6 ++
>>>>    tests/qtest/aspeed-hace-utils.c | 168
>>> +++++++++++++++++++++++++++++++-
>>>>    2 files changed, 171 insertions(+), 3 deletions(-)
>>>>
>>>> diff --git a/tests/qtest/aspeed-hace-utils.h
>>>> b/tests/qtest/aspeed-hace-utils.h index 598577c69b..f4440561de
>>>> 100644
>>>> --- a/tests/qtest/aspeed-hace-utils.h
>>>> +++ b/tests/qtest/aspeed-hace-utils.h
>>>> @@ -54,14 +54,20 @@ void aspeed_test_md5(const char *machine, const
>>> uint32_t base,
>>>>                         const uint32_t src_addr);
>>>>    void aspeed_test_sha256(const char *machine, const uint32_t base,
>>>>                            const uint32_t src_addr);
>>>> +void aspeed_test_sha384(const char *machine, const uint32_t base,
>>>> +                        const uint32_t src_addr);
>>>>    void aspeed_test_sha512(const char *machine, const uint32_t base,
>>>>                            const uint32_t src_addr);
>>>>    void aspeed_test_sha256_sg(const char *machine, const uint32_t base,
>>>>                               const uint32_t src_addr);
>>>> +void aspeed_test_sha384_sg(const char *machine, const uint32_t base,
>>>> +                           const uint32_t src_addr);
>>>>    void aspeed_test_sha512_sg(const char *machine, const uint32_t base,
>>>>                               const uint32_t src_addr);
>>>>    void aspeed_test_sha256_accum(const char *machine, const uint32_t
>>> base,
>>>>                                  const uint32_t src_addr);
>>>> +void aspeed_test_sha384_accum(const char *machine, const uint32_t
>> base,
>>>> +                              const uint32_t src_addr);
>>>>    void aspeed_test_sha512_accum(const char *machine, const uint32_t
>>> base,
>>>>                                  const uint32_t src_addr);
>>>>    void aspeed_test_addresses(const char *machine, const uint32_t
>>>> base, diff --git a/tests/qtest/aspeed-hace-utils.c
>>>> b/tests/qtest/aspeed-hace-utils.c index 8fbbba49c1..d3146898c2
>>>> 100644
>>>> --- a/tests/qtest/aspeed-hace-utils.c
>>>> +++ b/tests/qtest/aspeed-hace-utils.c
>>>> @@ -16,7 +16,7 @@
>>>>     * Expected results were generated using command line utitiles:
>>>>     *
>>>>     *  echo -n -e 'abc' | dd of=/tmp/test
>>>> - *  for hash in sha512sum sha256sum md5sum; do $hash /tmp/test;
>>>> done
>>>> + *  for hash in sha512sum sha384sum sha256sum md5sum; do $hash
>>>> + /tmp/test; done
>>>>     *
>>>>     */
>>>>    static const uint8_t test_vector[] = {0x61, 0x62, 0x63}; @@ -29,6
>>>> +29,12 @@ static const uint8_t test_result_sha512[] = {
>>>>        0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e, 0x2a, 0x9a,
>>>> 0xc9,
>>> 0x4f,
>>>>        0xa5, 0x4c, 0xa4, 0x9f};
>>>>
>>>> +static const uint8_t test_result_sha384[] = {
>>>> +    0xcb, 0x00, 0x75, 0x3f, 0x45, 0xa3, 0x5e, 0x8b, 0xb5, 0xa0, 0x3d,
>> 0x69,
>>>> +    0x9a, 0xc6, 0x50, 0x07, 0x27, 0x2c, 0x32, 0xab, 0x0e, 0xde,
>>>> +0xd1,
>>> 0x63,
>>>> +    0x1a, 0x8b, 0x60, 0x5a, 0x43, 0xff, 0x5b, 0xed, 0x80, 0x86, 0x07,
>> 0x2b,
>>>> +    0xa1, 0xe7, 0xcc, 0x23, 0x58, 0xba, 0xec, 0xa1, 0x34, 0xc8,
>>>> +0x25, 0xa7};
>>>> +
>>>>    static const uint8_t test_result_sha256[] = {
>>>>        0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41,
>>>> 0x40,
>>> 0xde,
>>>>        0x5d, 0xae, 0x22, 0x23, 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17,
>>>> 0x7a, 0x9c, @@ -45,7 +51,7 @@ static const uint8_t test_result_md5[] = {
>>>>     * Expected results were generated using command line utitiles:
>>>>     *
>>>>     *  echo -n -e 'abcdefghijkl' | dd of=/tmp/test
>>>> - *  for hash in sha512sum sha256sum; do $hash /tmp/test; done
>>>> + *  for hash in sha512sum sha384sum sha256sum; do $hash /tmp/test;
>>>> + done
>>>>     *
>>>>     */
>>>>    static const uint8_t test_vector_sg1[] = {0x61, 0x62, 0x63, 0x64,
>>>> 0x65, 0x66}; @@ -60,6 +66,12 @@ static const uint8_t
>>> test_result_sg_sha512[] = {
>>>>        0x84, 0x25, 0x7c, 0x32, 0xc8, 0xf6, 0xd0, 0x85, 0x4a, 0xe6,
>>>> 0xb5,
>>> 0x40,
>>>>        0xf8, 0x6d, 0xda, 0x2e};
>>>>
>>>> +static const uint8_t test_result_sg_sha384[] = {
>>>> +    0x10, 0x3c, 0xa9, 0x6c, 0x06, 0xa1, 0xce, 0x79, 0x8f, 0x08, 0xf8,
>> 0xef,
>>>> +    0xf0, 0xdf, 0xb0, 0xcc, 0xdb, 0x56, 0x7d, 0x48, 0xb2, 0x85, 0xb2,
>> 0x3d,
>>>> +    0x0c, 0xd7, 0x73, 0x45, 0x46, 0x67, 0xa3, 0xc2, 0xfa, 0x5f, 0x1b,
>> 0x58,
>>>> +    0xd9, 0xcd, 0xf2, 0x32, 0x9b, 0xd9, 0x97, 0x97, 0x30, 0xbf,
>>>> +0xaa, 0xff};
>>>> +
>>>>    static const uint8_t test_result_sg_sha256[] = {
>>>>        0xd6, 0x82, 0xed, 0x4c, 0xa4, 0xd9, 0x89, 0xc1, 0x34, 0xec,
>>>> 0x94,
>>> 0xf1,
>>>>        0x55, 0x1e, 0x1e, 0xc5, 0x80, 0xdd, 0x6d, 0x5a, 0x6e, 0xcd,
>>>> 0xe9, 0xf3, @@ -74,7 +86,7 @@ static const uint8_t
>>>> test_result_sg_sha256[]
>>> = {
>>>>     * Expected results were generated using command line utitiles:
>>>>     *
>>>>     *  echo -n -e 'abc' | dd of=/tmp/test
>>>> - *  for hash in sha512sum sha256sum; do $hash /tmp/test; done
>>>> + *  for hash in sha512sum sha384sum sha256sum; do $hash /tmp/test;
>>>> + done
>>>>     */
>>>>    static const uint8_t test_vector_accum_512[] = {
>>>>        0x61, 0x62, 0x63, 0x80, 0x00, 0x00, 0x00, 0x00, @@ -94,6
>>>> +106,24 @@ static const uint8_t test_vector_accum_512[] = {
>>>>        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
>>>>        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18};
>>>>
>>>> +static const uint8_t test_vector_accum_384[] = {
>>>> +    0x61, 0x62, 0x63, 0x80, 0x00, 0x00, 0x00, 0x00,
>>>> +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
>>>> +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
>>>> +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
>>>> +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
>>>> +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
>>>> +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
>>>> +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
>>>> +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
>>>> +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
>>>> +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
>>>> +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
>>>> +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
>>>> +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
>>>> +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
>>>> +    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18};
>>>> +
>>>>    static const uint8_t test_vector_accum_256[] = {
>>>>        0x61, 0x62, 0x63, 0x80, 0x00, 0x00, 0x00, 0x00,
>>>>        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -112,6
>>>> +142,12 @@ static const uint8_t test_result_accum_sha512[] = {
>>>>        0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e, 0x2a, 0x9a,
>>>> 0xc9,
>>> 0x4f,
>>>>        0xa5, 0x4c, 0xa4, 0x9f};
>>>>
>>>> +static const uint8_t test_result_accum_sha384[] = {
>>>> +    0xcb, 0x00, 0x75, 0x3f, 0x45, 0xa3, 0x5e, 0x8b, 0xb5, 0xa0, 0x3d,
>> 0x69,
>>>> +    0x9a, 0xc6, 0x50, 0x07, 0x27, 0x2c, 0x32, 0xab, 0x0e, 0xde,
>>>> +0xd1,
>>> 0x63,
>>>> +    0x1a, 0x8b, 0x60, 0x5a, 0x43, 0xff, 0x5b, 0xed, 0x80, 0x86, 0x07,
>> 0x2b,
>>>> +    0xa1, 0xe7, 0xcc, 0x23, 0x58, 0xba, 0xec, 0xa1, 0x34, 0xc8,
>>>> +0x25, 0xa7};
>>>> +
>>>>    static const uint8_t test_result_accum_sha256[] = {
>>>>        0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41,
>>>> 0x40,
>>> 0xde,
>>>>        0x5d, 0xae, 0x22, 0x23, 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17,
>>>> 0x7a, 0x9c, @@ -195,6 +231,40 @@ void aspeed_test_sha256(const char
>>> *machine, const uint32_t base,
>>>>        qtest_quit(s);
>>>>    }
>>>>
>>>> +void aspeed_test_sha384(const char *machine, const uint32_t base,
>>>> +                        const uint32_t src_addr) {
>>>> +    QTestState *s = qtest_init(machine);
>>>> +
>>>> +    const uint32_t digest_addr = src_addr + 0x10000;
>>>> +    uint8_t digest[32] = {0};
>>>> +
>>>> +    /* Check engine is idle, no busy or irq bits set */
>>>> +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
>>>> +
>>>> +    /* Write test vector into memory */
>>>> +    qtest_memwrite(s, src_addr, test_vector, sizeof(test_vector));
>>>> +
>>>> +    write_regs(s, base, src_addr, sizeof(test_vector), digest_addr,
>>>> +               HACE_ALGO_SHA384);
>>>> +
>>>> +    /* Check hash IRQ status is asserted */
>>>> +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==,
>>>> + 0x00000200);
>>>> +
>>>> +    /* Clear IRQ status and check status is deasserted */
>>>> +    qtest_writel(s, base + HACE_STS, 0x00000200);
>>>> +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
>>>> +
>>>> +    /* Read computed digest from memory */
>>>> +    qtest_memread(s, digest_addr, digest, sizeof(digest));
>>>> +
>>>> +    /* Check result of computation */
>>>> +    g_assert_cmpmem(digest, sizeof(digest),
>>>> +                    test_result_sha384, sizeof(digest));
>>>> +
>>>> +    qtest_quit(s);
>>>> +}
>>>> +
>>>>    void aspeed_test_sha512(const char *machine, const uint32_t base,
>>>>                            const uint32_t src_addr)
>>>>    {
>>>> @@ -280,6 +350,57 @@ void aspeed_test_sha256_sg(const char
>> *machine,
>>> const uint32_t base,
>>>>        qtest_quit(s);
>>>>    }
>>>>
>>>> +void aspeed_test_sha384_sg(const char *machine, const uint32_t base,
>>>> +                           const uint32_t src_addr) {
>>>> +    QTestState *s = qtest_init(machine);
>>>> +
>>>> +    const uint32_t src_addr_1 = src_addr + 0x10000;
>>>> +    const uint32_t src_addr_2 = src_addr + 0x20000;
>>>> +    const uint32_t src_addr_3 = src_addr + 0x30000;
>>>> +    const uint32_t digest_addr = src_addr + 0x40000;
>>>> +    uint8_t digest[64] = {0};
>>>
>>> This does not compile (gcc version 14.2.1)
>>>
>>>
>>> ../tests/qtest/aspeed-hace-utils.c: In function ‘aspeed_test_sha384_sg’:
>>> /usr/include/glib-2.0/glib/gtestutils.h:93:84: error: ‘__builtin_memcmp_eq’
>>> specified bound 64 exceeds the size 48 of unterminated array
>>> [-Werror=stringop-overread]
>>>      93 |                                              else if
>>> (__l1 != 0 && __m2 != NULL && memcmp (__m1, __m2, __l1) != 0) \
>>>         |
>>> ^~~~~~~~~~~~~~~~~~~~~~~~~
>>> ../tests/qtest/aspeed-hace-utils.c:399:5: note: in expansion of macro
>>> ‘g_assert_cmpmem’
>>>     399 |     g_assert_cmpmem(digest, sizeof(digest),
>>>         |     ^~~~~~~~~~~~~~~
>>> ../tests/qtest/aspeed-hace-utils.c:69:22: note: referenced argument
>>> declared here
>>>      69 | static const uint8_t test_result_sg_sha384[] = {
>>>         |                      ^~~~~~~~~~~~~~~~~~~~~
>>>
>>
> 
> Sorry, the root cause is that I mistakenly set the digest size to 64 bytes. I will fix it.
> 
> uint8_t digest[64] = {0};
> static const uint8_t test_result_sg_sha384[] = {
>      0x10, 0x3c, 0xa9, 0x6c, 0x06, 0xa1, 0xce, 0x79, 0x8f, 0x08, 0xf8, 0xef,
>      0xf0, 0xdf, 0xb0, 0xcc, 0xdb, 0x56, 0x7d, 0x48, 0xb2, 0x85, 0xb2, 0x3d,
>      0x0c, 0xd7, 0x73, 0x45, 0x46, 0x67, 0xa3, 0xc2, 0xfa, 0x5f, 0x1b, 0x58,
>      0xd9, 0xcd, 0xf2, 0x32, 0x9b, 0xd9, 0x97, 0x97, 0x30, 0xbf, 0xaa, 0xff};
> /* Check result of computation */
>      g_assert_cmpmem(digest, sizeof(digest), ====> 64bytes
>                      test_result_sg_sha384 ===>only 48bytes , sizeof(digest));
> 
> However, I believe explicitly setting the array size is the right approach.
> I’d appreciate your thoughts or suggestions on this.

Yes. Please do that. Since this is an architecture requirement.


Thanks,

C.



> 
> Thanks-Jamin
> 
>>
>> I didn't explicitly set the array size for "test_result_sg_sha384", and the
>> compiler seems to have inferred a size of 64 bytes—likely due to 32-byte
>> alignment.
>> However, the actual SHA384 digest is 48 bytes, which is why your compiler
>> reported an error: it detected a possible buffer overread.
>>
>> There are two possible ways to fix this issue:
>>
>> Solution 1:
>> Define a constant MAX_SIZE_LENGTH (e.g., 64 bytes), and use it for all test
>> result arrays:
>>
>> test_result_sha512[MAX_SIZE_LENGTH];
>> test_result_sha384[MAX_SIZE_LENGTH];
>> However, in this case, we cannot use "sizeof(test_result_sha384)" or
>> "sizeof(test_result_sha256)" in the test code, because the compiler will
>> evaluate them as 128 bytes.
>> Therefore, we should use hardcoded digest lengths (48 for SHA384, 32 for
>> SHA256) when comparing results in the tests.
>>
>> Solution 2:
>> Set the actual digest size explicitly in the array definition:
>> test_result_sha512[64];
>> test_result_sha384[48];
>> This ensures "sizeof()" will return the correct digest size, and we can safely use
>> it in assertions.
>>
>> I prefer solution 2.
>> Let me know which solution you'd prefer to go with.
>>
>> Thanks-Jamin
>>>
>>>
>>>
>>>> +    struct AspeedSgList array[] = {
>>>> +        {  cpu_to_le32(sizeof(test_vector_sg1)),
>>>> +           cpu_to_le32(src_addr_1) },
>>>> +        {  cpu_to_le32(sizeof(test_vector_sg2)),
>>>> +           cpu_to_le32(src_addr_2) },
>>>> +        {  cpu_to_le32(sizeof(test_vector_sg3) | SG_LIST_LEN_LAST),
>>>> +           cpu_to_le32(src_addr_3) },
>>>> +    };
>>>> +
>>>> +    /* Check engine is idle, no busy or irq bits set */
>>>> +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
>>>> +
>>>> +    /* Write test vector into memory */
>>>> +    qtest_memwrite(s, src_addr_1, test_vector_sg1,
>>> sizeof(test_vector_sg1));
>>>> +    qtest_memwrite(s, src_addr_2, test_vector_sg2,
>>> sizeof(test_vector_sg2));
>>>> +    qtest_memwrite(s, src_addr_3, test_vector_sg3,
>>> sizeof(test_vector_sg3));
>>>> +    qtest_memwrite(s, src_addr, array, sizeof(array));
>>>> +
>>>> +    write_regs(s, base, src_addr,
>>>> +               (sizeof(test_vector_sg1)
>>>> +                + sizeof(test_vector_sg2)
>>>> +                + sizeof(test_vector_sg3)),
>>>> +               digest_addr, HACE_ALGO_SHA384 | HACE_SG_EN);
>>>> +
>>>> +    /* Check hash IRQ status is asserted */
>>>> +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==,
>>>> + 0x00000200);
>>>> +
>>>> +    /* Clear IRQ status and check status is deasserted */
>>>> +    qtest_writel(s, base + HACE_STS, 0x00000200);
>>>> +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
>>>> +
>>>> +    /* Read computed digest from memory */
>>>> +    qtest_memread(s, digest_addr, digest, sizeof(digest));
>>>> +
>>>> +    /* Check result of computation */
>>>> +    g_assert_cmpmem(digest, sizeof(digest),
>>>> +                    test_result_sg_sha384, sizeof(digest));
>>>> +
>>>> +    qtest_quit(s);
>>>> +}
>>>> +
>>>>    void aspeed_test_sha512_sg(const char *machine, const uint32_t base,
>>>>                               const uint32_t src_addr)
>>>>    {
>>>> @@ -372,6 +493,47 @@ void aspeed_test_sha256_accum(const char
>>> *machine, const uint32_t base,
>>>>        qtest_quit(s);
>>>>    }
>>>>
>>>> +void aspeed_test_sha384_accum(const char *machine, const uint32_t
>> base,
>>>> +                              const uint32_t src_addr) {
>>>> +    QTestState *s = qtest_init(machine);
>>>> +
>>>> +    const uint32_t buffer_addr = src_addr + 0x10000;
>>>> +    const uint32_t digest_addr = src_addr + 0x40000;
>>>> +    uint8_t digest[64] = {0};
>>>
>>> ../tests/qtest/aspeed-hace-utils.c: In function ‘aspeed_test_sha384_accum’:
>>> /usr/include/glib-2.0/glib/gtestutils.h:93:84: error: ‘__builtin_memcmp_eq’
>>> specified bound 64 exceeds source size 48 [-Werror=stringop-overread]
>>>      93 |                                              else if
>>> (__l1 != 0 && __m2 != NULL && memcmp (__m1, __m2, __l1) != 0) \
>>>         |
>>> ^~~~~~~~~~~~~~~~~~~~~~~~~
>>> ../tests/qtest/aspeed-hace-utils.c:533:5: note: in expansion of macro
>>> ‘g_assert_cmpmem’
>>>     533 |     g_assert_cmpmem(digest, sizeof(digest),
>>>         |     ^~~~~~~~~~~~~~~
>>> ../tests/qtest/aspeed-hace-utils.c:145:22: note: source object declared here
>>>     145 | static const uint8_t test_result_accum_sha384[] = {
>>>         |                      ^~~~~~~~~~~~~~~~~~~~~~~~
>>>
>>>
>>> Thanks,
>>>
>>> C.
>>>
>>>
>>>
>>>> +    struct AspeedSgList array[] = {
>>>> +        {  cpu_to_le32(sizeof(test_vector_accum_384) |
>>> SG_LIST_LEN_LAST),
>>>> +           cpu_to_le32(buffer_addr) },
>>>> +    };
>>>> +
>>>> +    /* Check engine is idle, no busy or irq bits set */
>>>> +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
>>>> +
>>>> +    /* Write test vector into memory */
>>>> +    qtest_memwrite(s, buffer_addr, test_vector_accum_384,
>>>> +                   sizeof(test_vector_accum_384));
>>>> +    qtest_memwrite(s, src_addr, array, sizeof(array));
>>>> +
>>>> +    write_regs(s, base, src_addr, sizeof(test_vector_accum_384),
>>>> +               digest_addr, HACE_ALGO_SHA384 | HACE_SG_EN |
>>>> + HACE_ACCUM_EN);
>>>> +
>>>> +    /* Check hash IRQ status is asserted */
>>>> +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==,
>>>> + 0x00000200);
>>>> +
>>>> +    /* Clear IRQ status and check status is deasserted */
>>>> +    qtest_writel(s, base + HACE_STS, 0x00000200);
>>>> +    g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
>>>> +
>>>> +    /* Read computed digest from memory */
>>>> +    qtest_memread(s, digest_addr, digest, sizeof(digest));
>>>> +
>>>> +    /* Check result of computation */
>>>> +    g_assert_cmpmem(digest, sizeof(digest),
>>>> +                    test_result_accum_sha384, sizeof(digest));
>>>> +
>>>> +    qtest_quit(s);
>>>> +}
>>>> +
>>>>    void aspeed_test_sha512_accum(const char *machine, const uint32_t
>>> base,
>>>>                                  const uint32_t src_addr)
>>>>    {
> 



^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v1 01/22] hw/misc/aspeed_hace: Remove unused code for better readability
  2025-05-05  3:28     ` Jamin Lin
@ 2025-05-06  9:01       ` Cédric Le Goater
  0 siblings, 0 replies; 71+ messages in thread
From: Cédric Le Goater @ 2025-05-06  9:01 UTC (permalink / raw)
  To: Jamin Lin, Peter Maydell, Steven Lee, Troy Lee, Andrew Jeffery,
	Joel Stanley, Fabiano Rosas, Laurent Vivier, Paolo Bonzini,
	open list:ASPEED BMCs, open list:All patches CC here
  Cc: Troy Lee

On 5/5/25 05:28, Jamin Lin wrote:
> Hi Cédric
> 
>> Subject: Re: [PATCH v1 01/22] hw/misc/aspeed_hace: Remove unused code for
>> better readability
>>
>> On 3/21/25 10:25, Jamin Lin wrote:
>>> This cleanup follows significant changes in commit 4c1d0af4a28d,
>>> making the model more readable.
>>>
>>> - Deleted "iov_cache" and "iov_count" from "AspeedHACEState".
>>
>> It would be good to say why we can remove these. I think this is because
>> s->iov_count is always zero, right ?
>>
>>> - Removed "reconstruct_iov" function and related logic.
>>> - Simplified "do_hash_operation" by eliminating redundant checks.
>>>
>>> Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
>>> ---
>>>    include/hw/misc/aspeed_hace.h |  2 --
>>>    hw/misc/aspeed_hace.c         | 35 -----------------------------------
>>>    2 files changed, 37 deletions(-)
>>>
>>> diff --git a/include/hw/misc/aspeed_hace.h
>>> b/include/hw/misc/aspeed_hace.h index 5d4aa19cfe..b69a038d35 100644
>>> --- a/include/hw/misc/aspeed_hace.h
>>> +++ b/include/hw/misc/aspeed_hace.h
>>> @@ -31,10 +31,8 @@ struct AspeedHACEState {
>>>        MemoryRegion iomem;
>>>        qemu_irq irq;
>>>
>>> -    struct iovec iov_cache[ASPEED_HACE_MAX_SG];
>>>        uint32_t regs[ASPEED_HACE_NR_REGS];
>>>        uint32_t total_req_len;
>>> -    uint32_t iov_count;
>>>
>>>        MemoryRegion *dram_mr;
>>>        AddressSpace dram_as;
>>> diff --git a/hw/misc/aspeed_hace.c b/hw/misc/aspeed_hace.c index
>>> 32a5dbded3..8e7e8113a5 100644
>>> --- a/hw/misc/aspeed_hace.c
>>> +++ b/hw/misc/aspeed_hace.c
>>> @@ -137,25 +137,6 @@ static bool has_padding(AspeedHACEState *s,
>> struct iovec *iov,
>>>        return false;
>>>    }
>>>
>>> -static int reconstruct_iov(AspeedHACEState *s, struct iovec *iov, int id,
>>> -                           uint32_t *pad_offset)
>>> -{
>>> -    int i, iov_count;
>>> -    if (*pad_offset != 0) {
>>> -        s->iov_cache[s->iov_count].iov_base = iov[id].iov_base;
>>> -        s->iov_cache[s->iov_count].iov_len = *pad_offset;
>>> -        ++s->iov_count;
>>> -    }
>>> -    for (i = 0; i < s->iov_count; i++) {
>>> -        iov[i].iov_base = s->iov_cache[i].iov_base;
>>> -        iov[i].iov_len = s->iov_cache[i].iov_len;
>>> -    }
>>> -    iov_count = s->iov_count;
>>> -    s->iov_count = 0;
>>> -    s->total_req_len = 0;
>>> -    return iov_count;
>>> -}
>>> -
>>>    static void do_hash_operation(AspeedHACEState *s, int algo, bool
>> sg_mode,
>>>                                  bool acc_mode)
>>>    {
>>> @@ -237,19 +218,6 @@ static void do_hash_operation(AspeedHACEState *s,
>> int algo, bool sg_mode,
>>>            iov[0].iov_base = haddr;
>>>            iov[0].iov_len = len;
>>>            i = 1;
>>> -
>>> -        if (s->iov_count) {
>>> -            /*
>>> -             * In aspeed sdk kernel driver, sg_mode is disabled in
>> hash_final().
>>> -             * Thus if we received a request with sg_mode disabled, it is
>>> -             * required to check whether cache is empty. If no, we should
>>> -             * combine cached iov and the current iov.
>>> -             */
>>> -            s->total_req_len += len;
>>> -            if (has_padding(s, iov, len, &total_msg_len, &pad_offset)) {
>>> -                i = reconstruct_iov(s, iov, 0, &pad_offset);
>>> -            }
>>> -        }
>>>        }
>>>
>>>        if (acc_mode) {
>>> @@ -273,7 +241,6 @@ static void do_hash_operation(AspeedHACEState *s,
>> int algo, bool sg_mode,
>>>                qcrypto_hash_free(s->hash_ctx);
>>>
>>>                s->hash_ctx = NULL;
>>> -            s->iov_count = 0;
>>>                s->total_req_len = 0;
>>>            }
>>>        } else if (qcrypto_hash_bytesv(algo, iov, i, &digest_buf, @@
>>> -432,7 +399,6 @@ static void aspeed_hace_reset(DeviceState *dev)
>>>        }
>>>
>>>        memset(s->regs, 0, sizeof(s->regs));
>>> -    s->iov_count = 0;
>>>        s->total_req_len = 0;
>>>    }
>>>
>>> @@ -469,7 +435,6 @@ static const VMStateDescription
>> vmstate_aspeed_hace = {
>>>        .fields = (const VMStateField[]) {
>>>            VMSTATE_UINT32_ARRAY(regs, AspeedHACEState,
>> ASPEED_HACE_NR_REGS),
>>>            VMSTATE_UINT32(total_req_len, AspeedHACEState),
>>> -        VMSTATE_UINT32(iov_count, AspeedHACEState),
>>
>> This is a vmstate change which is breaking migration compatibility.
>> We could preserve compatibility [1] but I think this is overkill.
>> However, we should say so. Please add a comment in the commit log.
>>
> 
> How about the following commit log:
> 
> ```
> hw/misc/aspeed_hace: Remove unused code for better readability
> 
> In the previous design of the hash framework, accumulative hashing was not
> supported. To work around this limitation, commit 5cd7d85 introduced an
> iov_cache array to store all the hash data from firmware.
> Once the ASPEED HACE model collected all the data, it passed the iov_cache to
> the hash API to calculate the final digest.
> 
> However, with commit e3c0752, the hash framework now supports accumulative
> hashing. This allows us to refactor the ASPEED HACE model, removing redundant
> logic and simplifying the implementation for better readability and
> maintainability.
> 
> As a result, the iov_count variable is no longer needed—it was previously used
> to track how many cached entries were used for hashing.
> To maintain VMSTATE compatibility after removing this field, the VMSTATE_VERSION
> is bumped to 2
> 
> This cleanup follows significant changes in commit 4c1d0af4a28d, making the
> model more readable.
> 
> - Deleted "iov_cache" and "iov_count" from "AspeedHACEState".
> - Removed "reconstruct_iov" function and related logic.
> - Simplified "do_hash_operation" by eliminating redundant checks.
> ```


OK Let's see in v2.


Thanks,

C.


> Thans-Jamin
> 
>> Thanks,
>>
>> C.
>>
>> [1]
>> https://qemu.readthedocs.io/en/v9.2.0/devel/migration/main.html#vmstate
>>
>>>            VMSTATE_END_OF_LIST(),
>>>        }
>>>    };
> 



^ permalink raw reply	[flat|nested] 71+ messages in thread

* RE: [PATCH v1 05/22] hw/misc/aspeed_hace: Introduce 64-bit digest_addr variable for AST2700
  2025-04-01 13:55   ` Cédric Le Goater
@ 2025-05-09  4:01     ` Jamin Lin
  0 siblings, 0 replies; 71+ messages in thread
From: Jamin Lin @ 2025-05-09  4:01 UTC (permalink / raw)
  To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
	Andrew Jeffery, Joel Stanley, Fabiano Rosas, Laurent Vivier,
	Paolo Bonzini, open list:ASPEED BMCs,
	open list:All patches CC here
  Cc: Troy Lee

Hi Cédric

> Subject: Re: [PATCH v1 05/22] hw/misc/aspeed_hace: Introduce 64-bit
> digest_addr variable for AST2700
> 
> On 3/21/25 10:26, Jamin Lin wrote:
> > The AST2700 CPU, based on the Cortex-A35, is a 64-bit processor with a
> > 64-bit DRAM address space. To support future AST2700 updates, a new
> "digest_addr"
> > variable is introduced with a 64-bit data type.
> >
> > Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
> > ---
> >   hw/misc/aspeed_hace.c | 4 +++-
> >   1 file changed, 3 insertions(+), 1 deletion(-)
> >
> > diff --git a/hw/misc/aspeed_hace.c b/hw/misc/aspeed_hace.c index
> > 9771d6e490..8cf3f194a5 100644
> > --- a/hw/misc/aspeed_hace.c
> > +++ b/hw/misc/aspeed_hace.c
> > @@ -148,6 +148,7 @@ static void do_hash_operation(AspeedHACEState *s,
> int algo, bool sg_mode,
> >       bool sg_acc_mode_final_request = false;
> >       g_autofree uint8_t *digest_buf = NULL;
> >       struct iovec iov[ASPEED_HACE_MAX_SG];
> > +    uint64_t digest_addr = 0;
> >       Error *local_err = NULL;
> >       uint32_t total_msg_len;
> >       size_t digest_len = 0;
> > @@ -257,7 +258,8 @@ static void do_hash_operation(AspeedHACEState *s,
> int algo, bool sg_mode,
> >           return;
> >       }
> >
> > -    if (address_space_write(&s->dram_as, s->regs[R_HASH_DEST],
> > +    digest_addr = deposit64(digest_addr, 0, 32,
> > + s->regs[R_HASH_DEST]);
> 
> As on the previous patch, an helper would be useful and is there an alignment
> constraint ?
> 
Thanks for the review and suggestion.
I will add the hash_get_digest_addr helper function to retrieve the hash digest address.
The digest address must be 8-byte aligned.
To enforce this, we already define a "dest_mask" class attribute and set it to 0x7FFFFFF8, which ensures proper 8-byte alignment of digest_addr.

Reference
https://github.com/qemu/qemu/blob/master/hw/misc/aspeed_hace.c#L365
case R_HASH_DEST:
        data &= ahc->dest_mask;
https://github.com/qemu/qemu/blob/master/hw/misc/aspeed_hace.c#L584
    ahc->dest_mask = 0x7FFFFFF8;

For more details, please refer to the Hash & Crypto Engine section(HACE24) in the datasheet.
Thanks-Jamin

> 
> Thanks,
> 
> C.
> 
> 
> 
> > +    if (address_space_write(&s->dram_as, digest_addr,
> >                               MEMTXATTRS_UNSPECIFIED,
> >                               digest_buf, digest_len)) {
> >           qemu_log_mask(LOG_GUEST_ERROR,


^ permalink raw reply	[flat|nested] 71+ messages in thread

* RE: [PATCH v1 04/22] hw/misc/aspeed_hace: Update hash source address handling to 64-bit for AST2700
  2025-04-01 13:52   ` Cédric Le Goater
@ 2025-05-09  6:49     ` Jamin Lin
  0 siblings, 0 replies; 71+ messages in thread
From: Jamin Lin @ 2025-05-09  6:49 UTC (permalink / raw)
  To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
	Andrew Jeffery, Joel Stanley, Fabiano Rosas, Laurent Vivier,
	Paolo Bonzini, open list:ASPEED BMCs,
	open list:All patches CC here
  Cc: Troy Lee

Hi Cédric

> Subject: Re: [PATCH v1 04/22] hw/misc/aspeed_hace: Update hash source
> address handling to 64-bit for AST2700
> 
> On 3/21/25 10:26, Jamin Lin wrote:
> > The AST2700 CPU, based on the Cortex-A35, is a 64-bit processor, and
> > its DRAM address space is also 64-bit. To support future AST2700
> > updates, the source hash buffer address data type is being updated to 64-bit.
> >
> > Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
> > ---
> >   hw/misc/aspeed_hace.c | 8 +++++---
> >   1 file changed, 5 insertions(+), 3 deletions(-)
> >
> > diff --git a/hw/misc/aspeed_hace.c b/hw/misc/aspeed_hace.c index
> > 4bcf6ed074..9771d6e490 100644
> > --- a/hw/misc/aspeed_hace.c
> > +++ b/hw/misc/aspeed_hace.c
> > @@ -154,7 +154,7 @@ static void do_hash_operation(AspeedHACEState *s,
> int algo, bool sg_mode,
> >       uint32_t sg_addr = 0;
> >       uint32_t pad_offset;
> >       uint32_t len = 0;
> > -    uint32_t src = 0;
> > +    uint64_t src = 0;
> >       void *haddr;
> >       hwaddr plen;
> >       int i;
> > @@ -177,7 +177,8 @@ static void do_hash_operation(AspeedHACEState *s,
> int algo, bool sg_mode,
> >                   break;
> >               }
> >
> > -            src = s->regs[R_HASH_SRC] + (i * SG_LIST_ENTRY_SIZE);
> > +            src = deposit64(src, 0, 32, s->regs[R_HASH_SRC]);
> 
> I would introduce an helper routine to return the hash 'src' address.
> More changes are expected in the following patches.
> 

Thanks for the review and suggestion.
I will add "hash_get_source_addr" helper function to get the source address.

> Why is the initial hash 'src' address assigned in the loop ? This could done
> before looping on the scatter-gather list elements.

Yes, it can be moved before the "for loop" and only need to assign one time.

> 
> Also should this address be aligned to some size ?
The HACE hash engine supports two modes for the source buffer:

1. Direct Mode
Byte-aligned source data
Bit 31: Reserved
Bit 30:0 Base address of the hash source data buffer

To ensure byte alignment, the "src_mask" is set to 0x7FFFFFFF

Reference:
https://github.com/qemu/qemu/blob/master/hw/misc/aspeed_hace.c#L583 
ahc->src_mask = 0x7FFFFFFF;

https://github.com/qemu/qemu/blob/master/hw/misc/aspeed_hace.c#L362
case R_HASH_SRC:
        data &= ahc->src_mask;

2. Scatter-Gather (SG) Mode
Bit 31: Reserved
Bit 30:3 Base address of the SG list (must be 8-byte aligned)
Bit 2:0 Reserved
 
In SG mode:

The R_HASH_SRC value is first masked using ahc->src_mask as in Direct Mode.
Then, while parsing SG entries, each SG list entry's address is additionally masked using SG_LIST_ADDR_MASK. 

https://github.com/qemu/qemu/blob/master/hw/misc/aspeed_hace.c#L207

```
src = s->regs[R_HASH_SRC] + (i * SG_LIST_ENTRY_SIZE);

            len = address_space_ldl_le(&s->dram_as, src,
                                       MEMTXATTRS_UNSPECIFIED, NULL);

            addr = address_space_ldl_le(&s->dram_as, src + SG_LIST_LEN_SIZE,
                                        MEMTXATTRS_UNSPECIFIED, NULL);
            addr &= SG_LIST_ADDR_MASK;
```

However, the value of SG_LIST_ADDR_MASK is incorrect.
It should be updated to "0x7FFFFFF8" to correctly enforce the 8-byte alignment requirement.
Please refer to the HACE and CRYPTO chapters in the datasheet for more details.

The SG mode address format (HACE24) is identical between the AST2600 and AST2700.
Thanks-Jamin

> 
> 
> Thanks,
> 
> C.
> 
> 
> 
> 
> > +            src += i * SG_LIST_ENTRY_SIZE;
> >
> >               len = address_space_ldl_le(&s->dram_as, src,
> >
> MEMTXATTRS_UNSPECIFIED,
> > NULL); @@ -212,8 +213,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]);
> >
> > -        haddr = address_space_map(&s->dram_as, s->regs[R_HASH_SRC],
> > +        haddr = address_space_map(&s->dram_as, src,
> >                                     &plen, false,
> MEMTXATTRS_UNSPECIFIED);
> >           if (haddr == NULL) {
> >               qemu_log_mask(LOG_GUEST_ERROR, "%s: qcrypto
> failed\n",
> > __func__);


^ permalink raw reply	[flat|nested] 71+ messages in thread

* RE: [PATCH v1 06/22] hw/misc/aspeed_hace: Support accumulative mode for direct access mode
  2025-04-01 13:57   ` Cédric Le Goater
@ 2025-05-09  6:55     ` Jamin Lin
  2025-05-10  6:12       ` Cédric Le Goater
  0 siblings, 1 reply; 71+ messages in thread
From: Jamin Lin @ 2025-05-09  6:55 UTC (permalink / raw)
  To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
	Andrew Jeffery, Joel Stanley, Fabiano Rosas, Laurent Vivier,
	Paolo Bonzini, open list:ASPEED BMCs,
	open list:All patches CC here
  Cc: Troy Lee

Hi Cédric

> Subject: Re: [PATCH v1 06/22] hw/misc/aspeed_hace: Support accumulative
> mode for direct access mode
> 
> On 3/21/25 10:26, Jamin Lin wrote:
> > Enable accumulative mode for direct access mode operations. In direct
> > access mode, only a single source buffer is used, so the "iovec" count is set to
> 1.
> > If "acc_mode" is enabled:
> > 1. Accumulate "total_req_len" with the current request length ("plen").
> > 2. Check for padding and determine whether this is the final request.
> >
> > Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
> > ---
> >   hw/misc/aspeed_hace.c | 15 ++++++++++++++-
> >   1 file changed, 14 insertions(+), 1 deletion(-)
> >
> > diff --git a/hw/misc/aspeed_hace.c b/hw/misc/aspeed_hace.c index
> > 8cf3f194a5..d06158dffd 100644
> > --- a/hw/misc/aspeed_hace.c
> > +++ b/hw/misc/aspeed_hace.c
> > @@ -223,8 +223,21 @@ static void do_hash_operation(AspeedHACEState *s,
> int algo, bool sg_mode,
> >               return;
> >           }
> >           iov[0].iov_base = haddr;
> > -        iov[0].iov_len = plen;
> >           i = 1;
> > +        if (acc_mode) {
> 
> hmm, more complexity is being added to do_hash_operation(). I would
> introduce a sub routine do_hash_operation_acc() to handle accumulative
> mode.
> 
Thanks for the review and suggestion.
I refactor "do_hash_operation" and changes looks like as following

New Helper functions:

hash_get_source_addr
hash_prepare_direct_iov
hash_prepare_sg_iov
hash_get_digest_addr
hash_write_digest_and_unmap_iov
hash_execute_non_acc_mode
hash_execute_acc_mode

```
static void do_hash_operation(AspeedHACEState *s, int algo, bool sg_mode,
                              bool acc_mode)
{
    struct iovec iov[ASPEED_HACE_MAX_SG];
    bool acc_final_request = false;
    int iov_idx = -1;

    /* Prepares the iov for hashing operations based on the selected mode */
    if (sg_mode) {
        iov_idx = hash_prepare_sg_iov(s, iov, acc_mode, &acc_final_request);
    } else {
        iov_idx = hash_prepare_direct_iov(s, iov);
    }

    if (iov_idx <= 0) {
        qemu_log_mask(LOG_GUEST_ERROR,
                      "%s: Failed to prepare iov\n", __func__);
         return;
    }

    /* Executes the hash operation */
    if (acc_mode) {
        hash_execute_acc_mode(s, algo, iov, iov_idx, acc_final_request);
    } else {
        hash_execute_non_acc_mode(s, algo, iov, iov_idx);
    }
}
```
Thanks-Jamin

> Thanks,
> 
> C.
> 
> 
> 
> > +            s->total_req_len += plen;
> > +
> > +            if (has_padding(s, &iov[0], plen, &total_msg_len,
> > +                            &pad_offset)) {
> > +                /* Padding being present indicates the final request */
> > +                sg_acc_mode_final_request = true;
> > +                iov[0].iov_len = pad_offset;
> > +            } else {
> > +                iov[0].iov_len = plen;
> > +            }
> > +        } else {
> > +            iov[0].iov_len = plen;
> > +        }
> >       }
> >
> >       if (acc_mode) {


^ permalink raw reply	[flat|nested] 71+ messages in thread

* RE: [PATCH v1 03/22] hw/misc/aspeed_hace: Improve readability and consistency in variable naming
  2025-04-01 13:17   ` Cédric Le Goater
@ 2025-05-09  6:57     ` Jamin Lin
  0 siblings, 0 replies; 71+ messages in thread
From: Jamin Lin @ 2025-05-09  6:57 UTC (permalink / raw)
  To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
	Andrew Jeffery, Joel Stanley, Fabiano Rosas, Laurent Vivier,
	Paolo Bonzini, open list:ASPEED BMCs,
	open list:All patches CC here
  Cc: Troy Lee

Hi Cédric

> Subject: Re: [PATCH v1 03/22] hw/misc/aspeed_hace: Improve readability and
> consistency in variable naming
> 
> On 3/21/25 10:25, Jamin Lin wrote:
> > Currently, users define multiple local variables within different if-statements.
> > To improve readability and maintain consistency in variable naming,
> > rename the variables accordingly.
> > Introduced "sg_addr" to clearly indicate the scatter-gather mode buffer
> address.
> >
> > Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
> 
> 
> The change look OK. do_hash_operation() is a big routine, difficult to read. It
> does stuff like :
> 
>      if (sg_mode) {
> 	    ...
>      } else {
> 	    ...
>      }
> 
>      if (acc_mode) {
> 	    ...
>      } else {
> 	    ...
>      }
>      ...
> 
> I think we should also split it in multiple routines to reduce the complexity,
> even if some part are redundant.
> 
Thanks for the review and suggestion.
I refactor "do_hash_operation". Please see patch 6 comments.
Thanks-Jamin

> Thanks,
> 
> C.
> 
> 
> 
> > --->   hw/misc/aspeed_hace.c | 33 ++++++++++++++++-----------------
> >   1 file changed, 16 insertions(+), 17 deletions(-)
> >
> > diff --git a/hw/misc/aspeed_hace.c b/hw/misc/aspeed_hace.c index
> > d8b5f048bb..4bcf6ed074 100644
> > --- a/hw/misc/aspeed_hace.c
> > +++ b/hw/misc/aspeed_hace.c
> > @@ -145,15 +145,19 @@ static bool has_padding(AspeedHACEState *s,
> struct iovec *iov,
> >   static void do_hash_operation(AspeedHACEState *s, int algo, bool
> sg_mode,
> >                                 bool acc_mode)
> >   {
> > +    bool sg_acc_mode_final_request = false;
> > +    g_autofree uint8_t *digest_buf = NULL;
> >       struct iovec iov[ASPEED_HACE_MAX_SG];
> > +    Error *local_err = NULL;
> >       uint32_t total_msg_len;
> > -    uint32_t pad_offset;
> > -    g_autofree uint8_t *digest_buf = NULL;
> >       size_t digest_len = 0;
> > -    bool sg_acc_mode_final_request = false;
> > -    int i;
> > +    uint32_t sg_addr = 0;
> > +    uint32_t pad_offset;
> > +    uint32_t len = 0;
> > +    uint32_t src = 0;
> >       void *haddr;
> > -    Error *local_err = NULL;
> > +    hwaddr plen;
> > +    int i;
> >
> >       if (acc_mode && s->hash_ctx == NULL) {
> >           s->hash_ctx = qcrypto_hash_new(algo, &local_err); @@
> -166,12
> > +170,7 @@ static void do_hash_operation(AspeedHACEState *s, int algo,
> bool sg_mode,
> >       }
> >
> >       if (sg_mode) {
> > -        uint32_t len = 0;
> > -
> >           for (i = 0; !(len & SG_LIST_LEN_LAST); i++) {
> > -            uint32_t addr, src;
> > -            hwaddr plen;
> > -
> >               if (i == ASPEED_HACE_MAX_SG) {
> >                   qemu_log_mask(LOG_GUEST_ERROR,
> >                           "aspeed_hace: guest failed to set end of sg
> > list marker\n"); @@ -183,12 +182,12 @@ static void
> do_hash_operation(AspeedHACEState *s, int algo, bool sg_mode,
> >               len = address_space_ldl_le(&s->dram_as, src,
> >
> MEMTXATTRS_UNSPECIFIED,
> > NULL);
> >
> > -            addr = address_space_ldl_le(&s->dram_as, src +
> SG_LIST_LEN_SIZE,
> > -
> MEMTXATTRS_UNSPECIFIED, NULL);
> > -            addr &= SG_LIST_ADDR_MASK;
> > +            sg_addr = address_space_ldl_le(&s->dram_as, src +
> SG_LIST_LEN_SIZE,
> > +
> MEMTXATTRS_UNSPECIFIED, NULL);
> > +            sg_addr &= SG_LIST_ADDR_MASK;
> >
> >               plen = len & SG_LIST_LEN_MASK;
> > -            haddr = address_space_map(&s->dram_as, addr, &plen,
> false,
> > +            haddr = address_space_map(&s->dram_as, sg_addr, &plen,
> > + false,
> >
> MEMTXATTRS_UNSPECIFIED);
> >               if (haddr == NULL) {
> >                   qemu_log_mask(LOG_GUEST_ERROR, @@ -212,16
> +211,16 @@
> > static void do_hash_operation(AspeedHACEState *s, int algo, bool sg_mode,
> >               }
> >           }
> >       } else {
> > -        hwaddr len = s->regs[R_HASH_SRC_LEN];
> > +        plen = s->regs[R_HASH_SRC_LEN];
> >
> >           haddr = address_space_map(&s->dram_as,
> s->regs[R_HASH_SRC],
> > -                                  &len, false,
> MEMTXATTRS_UNSPECIFIED);
> > +                                  &plen, false,
> > + MEMTXATTRS_UNSPECIFIED);
> >           if (haddr == NULL) {
> >               qemu_log_mask(LOG_GUEST_ERROR, "%s: qcrypto
> failed\n", __func__);
> >               return;
> >           }
> >           iov[0].iov_base = haddr;
> > -        iov[0].iov_len = len;
> > +        iov[0].iov_len = plen;
> >           i = 1;
> >       }
> >


^ permalink raw reply	[flat|nested] 71+ messages in thread

* RE: [PATCH v1 08/22] hw/misc/aspeed_hace: Support DMA 64 bits dram address.
  2025-04-02  7:41   ` Cédric Le Goater
@ 2025-05-09  7:04     ` Jamin Lin
  2025-05-10  6:15       ` Cédric Le Goater
  0 siblings, 1 reply; 71+ messages in thread
From: Jamin Lin @ 2025-05-09  7:04 UTC (permalink / raw)
  To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
	Andrew Jeffery, Joel Stanley, Fabiano Rosas, Laurent Vivier,
	Paolo Bonzini, open list:ASPEED BMCs,
	open list:All patches CC here
  Cc: Troy Lee

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_lin@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 = {


^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v1 06/22] hw/misc/aspeed_hace: Support accumulative mode for direct access mode
  2025-05-09  6:55     ` Jamin Lin
@ 2025-05-10  6:12       ` Cédric Le Goater
  0 siblings, 0 replies; 71+ messages in thread
From: Cédric Le Goater @ 2025-05-10  6:12 UTC (permalink / raw)
  To: Jamin Lin, Peter Maydell, Steven Lee, Troy Lee, Andrew Jeffery,
	Joel Stanley, Fabiano Rosas, Laurent Vivier, Paolo Bonzini,
	open list:ASPEED BMCs, open list:All patches CC here
  Cc: Troy Lee

On 5/9/25 08:55, Jamin Lin wrote:
> Hi Cédric
> 
>> Subject: Re: [PATCH v1 06/22] hw/misc/aspeed_hace: Support accumulative
>> mode for direct access mode
>>
>> On 3/21/25 10:26, Jamin Lin wrote:
>>> Enable accumulative mode for direct access mode operations. In direct
>>> access mode, only a single source buffer is used, so the "iovec" count is set to
>> 1.
>>> If "acc_mode" is enabled:
>>> 1. Accumulate "total_req_len" with the current request length ("plen").
>>> 2. Check for padding and determine whether this is the final request.
>>>
>>> Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
>>> ---
>>>    hw/misc/aspeed_hace.c | 15 ++++++++++++++-
>>>    1 file changed, 14 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/hw/misc/aspeed_hace.c b/hw/misc/aspeed_hace.c index
>>> 8cf3f194a5..d06158dffd 100644
>>> --- a/hw/misc/aspeed_hace.c
>>> +++ b/hw/misc/aspeed_hace.c
>>> @@ -223,8 +223,21 @@ static void do_hash_operation(AspeedHACEState *s,
>> int algo, bool sg_mode,
>>>                return;
>>>            }
>>>            iov[0].iov_base = haddr;
>>> -        iov[0].iov_len = plen;
>>>            i = 1;
>>> +        if (acc_mode) {
>>
>> hmm, more complexity is being added to do_hash_operation(). I would
>> introduce a sub routine do_hash_operation_acc() to handle accumulative
>> mode.
>>
> Thanks for the review and suggestion.
> I refactor "do_hash_operation" and changes looks like as following
> 
> New Helper functions:
> 
> hash_get_source_addr
> hash_prepare_direct_iov
> hash_prepare_sg_iov
> hash_get_digest_addr
> hash_write_digest_and_unmap_iov
> hash_execute_non_acc_mode
> hash_execute_acc_mode
> 
> ```
> static void do_hash_operation(AspeedHACEState *s, int algo, bool sg_mode,
>                                bool acc_mode)
> {
>      struct iovec iov[ASPEED_HACE_MAX_SG];
>      bool acc_final_request = false;
>      int iov_idx = -1;
> 
>      /* Prepares the iov for hashing operations based on the selected mode */
>      if (sg_mode) {
>          iov_idx = hash_prepare_sg_iov(s, iov, acc_mode, &acc_final_request);
>      } else {
>          iov_idx = hash_prepare_direct_iov(s, iov);
>      }
> 
>      if (iov_idx <= 0) {
>          qemu_log_mask(LOG_GUEST_ERROR,
>                        "%s: Failed to prepare iov\n", __func__);
>           return;
>      }
> 
>      /* Executes the hash operation */
>      if (acc_mode) {
>          hash_execute_acc_mode(s, algo, iov, iov_idx, acc_final_request);
>      } else {
>          hash_execute_non_acc_mode(s, algo, iov, iov_idx);
>      }
> }

This looks better.

Thanks !

C.



^ permalink raw reply	[flat|nested] 71+ messages in thread

* Re: [PATCH v1 08/22] hw/misc/aspeed_hace: Support DMA 64 bits dram address.
  2025-05-09  7:04     ` Jamin Lin
@ 2025-05-10  6:15       ` Cédric Le Goater
  2025-05-12  8:41         ` Jamin Lin
  0 siblings, 1 reply; 71+ messages in thread
From: Cédric Le Goater @ 2025-05-10  6:15 UTC (permalink / raw)
  To: Jamin Lin, Peter Maydell, Steven Lee, Troy Lee, Andrew Jeffery,
	Joel Stanley, Fabiano Rosas, Laurent Vivier, Paolo Bonzini,
	open list:ASPEED BMCs, open list:All patches CC here
  Cc: Troy Lee

On 5/9/25 09:04, Jamin Lin wrote:
> 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_lin@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.

Should we introduce a class attribute then ?

Thanks,

C.


^ permalink raw reply	[flat|nested] 71+ messages in thread

* RE: [PATCH v1 11/22] hw/misc/aspeed_hace: Add trace-events for better debugging
  2025-04-02  7:59   ` Cédric Le Goater
@ 2025-05-12  1:34     ` Jamin Lin
  0 siblings, 0 replies; 71+ messages in thread
From: Jamin Lin @ 2025-05-12  1:34 UTC (permalink / raw)
  To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
	Andrew Jeffery, Joel Stanley, Fabiano Rosas, Laurent Vivier,
	Paolo Bonzini, open list:ASPEED BMCs,
	open list:All patches CC here
  Cc: Troy Lee

Hi Cédric

> From: Cédric Le Goater <clg@kaod.org>
>
> Subject: Re: [PATCH v1 11/22] hw/misc/aspeed_hace: Add trace-events for
> better debugging
> 
> On 3/21/25 10:26, Jamin Lin wrote:
> > Introduced "trace_aspeed_hace_addr", "trace_aspeed_hace_sg",
> > "trace_aspeed_hace_read", and "trace_aspeed_hace_write" trace events.
> >
> > Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
> > ---
> >   hw/misc/aspeed_hace.c | 8 ++++++++
> >   hw/misc/trace-events  | 6 ++++++
> >   2 files changed, 14 insertions(+)
> >
> > diff --git a/hw/misc/aspeed_hace.c b/hw/misc/aspeed_hace.c index
> > 53b3b390e3..b8e473ee3f 100644
> > --- a/hw/misc/aspeed_hace.c
> > +++ b/hw/misc/aspeed_hace.c
> > @@ -18,6 +18,7 @@
> >   #include "crypto/hash.h"
> >   #include "hw/qdev-properties.h"
> >   #include "hw/irq.h"
> > +#include "trace.h"
> >
> >   #define R_CRYPT_CMD     (0x10 / 4)
> >
> > @@ -186,6 +187,7 @@ static void do_hash_operation(AspeedHACEState *s,
> int algo, bool sg_mode,
> >               if (ahc->has_dma64) {
> >                   src = deposit64(src, 32, 32, s->regs[R_HASH_SRC_HI]);
> >               }
> > +            trace_aspeed_hace_addr("src", src);
> >               src += i * SG_LIST_ENTRY_SIZE;
> >
> >               len = address_space_ldl_le(&s->dram_as, src, @@ -194,6
> > +196,7 @@ 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;
> > +            trace_aspeed_hace_sg(i, sg_addr, len);
> >               /*
> >                * Ideally, sg_addr should be 64-bit for the AST2700, using
> the
> >                * following program to obtain the 64-bit sg_addr and
> > convert it @@ -237,6 +240,7 @@ 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]);
> > +        trace_aspeed_hace_addr("src", src);
> >           if (ahc->has_dma64) {
> >               src = deposit64(src, 32, 32, s->regs[R_HASH_SRC_HI]);
> >           }
> > @@ -299,6 +303,7 @@ static void do_hash_operation(AspeedHACEState *s,
> int algo, bool sg_mode,
> >       if (ahc->has_dma64) {
> >           digest_addr = deposit64(digest_addr, 32, 32,
> s->regs[R_HASH_DEST_HI]);
> >       }
> > +    trace_aspeed_hace_addr("digest", digest_addr);
> >       if (address_space_write(&s->dram_as, digest_addr,
> >                               MEMTXATTRS_UNSPECIFIED,
> >                               digest_buf, digest_len)) {
> 
> I would use the prefix 'trace_aspeed_hace_hash_addr' since the trace events
> are called from do_hash_operation()
> 
> 
Will add "aspeed_hace_hash" prefix to make user know trace event for hash command.
Thanks-Jamin
> Thanks,
> 
> C.
> 
> 
> 
> > @@ -326,6 +331,7 @@ static uint64_t aspeed_hace_read(void *opaque,
> hwaddr addr, unsigned int size)
> >           return 0;
> >       }
> >
> > +    trace_aspeed_hace_read(addr << 2, s->regs[addr]);
> >       return s->regs[addr];
> >   }
> >
> > @@ -344,6 +350,8 @@ static void aspeed_hace_write(void *opaque,
> hwaddr addr, uint64_t data,
> >           return;
> >       }
> >
> > +    trace_aspeed_hace_write(addr << 2, data);
> > +
> >       switch (addr) {
> >       case R_STATUS:
> >           if (data & HASH_IRQ) {
> > diff --git a/hw/misc/trace-events b/hw/misc/trace-events index
> > 4383808d7a..cf96e68cfa 100644
> > --- a/hw/misc/trace-events
> > +++ b/hw/misc/trace-events
> > @@ -302,6 +302,12 @@ aspeed_peci_read(uint64_t offset, uint64_t data)
> "offset 0x%" PRIx64 " data 0x%"
> >   aspeed_peci_write(uint64_t offset, uint64_t data) "offset 0x%" PRIx64 "
> data 0x%" PRIx64
> >   aspeed_peci_raise_interrupt(uint32_t ctrl, uint32_t status) "ctrl
> > 0x%" PRIx32 " status 0x%" PRIx32
> >
> > +# aspeed_hace.c
> > +aspeed_hace_read(uint64_t offset, uint64_t data) "offset 0x%" PRIx64
> > +" data 0x%" PRIx64 aspeed_hace_write(uint64_t offset, uint64_t data)
> > +"offset 0x%" PRIx64 " data 0x%" PRIx64 aspeed_hace_sg(int index,
> > +uint64_t addr, uint32_t len) "%d: addr 0x%" PRIx64 " len 0x%" PRIx32
> > +aspeed_hace_addr(const char *s, uint64_t addr) "%s: 0x%" PRIx64
> > +
> >   # bcm2835_property.c
> >   bcm2835_mbox_property(uint32_t tag, uint32_t bufsize, size_t resplen)
> "mbox property tag:0x%08x in_sz:%u out_sz:%zu"
> >


^ permalink raw reply	[flat|nested] 71+ messages in thread

* RE: [PATCH v1 12/22] hw/misc/aspeed_hace Support to dump plaintext and digest for better debugging
  2025-04-02  8:05   ` Cédric Le Goater
@ 2025-05-12  5:22     ` Jamin Lin
  0 siblings, 0 replies; 71+ messages in thread
From: Jamin Lin @ 2025-05-12  5:22 UTC (permalink / raw)
  To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
	Andrew Jeffery, Joel Stanley, Fabiano Rosas, Laurent Vivier,
	Paolo Bonzini, open list:ASPEED BMCs,
	open list:All patches CC here
  Cc: Troy Lee

Hi Cédric

> Subject: Re: [PATCH v1 12/22] hw/misc/aspeed_hace Support to dump
> plaintext and digest for better debugging
> 
> On 3/21/25 10:26, Jamin Lin wrote:
> > 1. Disabled by default. Uncomment "#define DEBUG_HACE 1" to enable it.
> > 2. Uses the "qemu_hexdump" API to dump the digest result.
> > 3. Uses the "iov_hexdump" API to dump the source vector, which contains the
> >     source plaintext.
> >
> > Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
> > ---
> >   hw/misc/aspeed_hace.c | 12 ++++++++++++
> >   1 file changed, 12 insertions(+)
> >
> > diff --git a/hw/misc/aspeed_hace.c b/hw/misc/aspeed_hace.c index
> > b8e473ee3f..ae4d2fa687 100644
> > --- a/hw/misc/aspeed_hace.c
> > +++ b/hw/misc/aspeed_hace.c
> > @@ -10,8 +10,10 @@
> >    */
> >
> >   #include "qemu/osdep.h"
> > +#include "qemu/cutils.h"
> >   #include "qemu/log.h"
> >   #include "qemu/error-report.h"
> > +#include "qemu/iov.h"
> >   #include "hw/misc/aspeed_hace.h"
> >   #include "qapi/error.h"
> >   #include "migration/vmstate.h"
> > @@ -20,6 +22,8 @@
> >   #include "hw/irq.h"
> >   #include "trace.h"
> >
> > +/* #define DEBUG_HACE 1 */
> > +
> >   #define R_CRYPT_CMD     (0x10 / 4)
> >
> >   #define R_STATUS        (0x1c / 4)
> > @@ -268,6 +272,10 @@ static void do_hash_operation(AspeedHACEState *s,
> int algo, bool sg_mode,
> >           }
> >       }
> >
> > +#ifdef DEBUG_HACE
> 
> Could we use a trace instead ? See trace_event_get_state_backends() for
> complex traces and qemu_hexdump_to_buffer() ?
> 
Thanks for the review and suggestion.
Will add "hexdump data" in trace event.
Thanks-Jamin
> 
> Thanks,
> 
> C.
> 
> 
> 
> 
> > +    iov_hexdump(iov, i, stdout, "plaintext", 0xa000); #endif
> > +
> >       if (acc_mode) {
> >           if (qcrypto_hash_updatev(s->hash_ctx, iov, i, &local_err) < 0) {
> >               qemu_log_mask(LOG_GUEST_ERROR, "qcrypto hash
> update
> > failed : %s", @@ -311,6 +319,10 @@ static void
> do_hash_operation(AspeedHACEState *s, int algo, bool sg_mode,
> >                         "aspeed_hace: address space write failed\n");
> >       }
> >
> > +#ifdef DEBUG_HACE
> > +    qemu_hexdump(stdout, "digest", digest_buf, digest_len); #endif
> > +
> >       for (; i > 0; i--) {
> >           address_space_unmap(&s->dram_as, iov[i - 1].iov_base,
> >                               iov[i - 1].iov_len, false,


^ permalink raw reply	[flat|nested] 71+ messages in thread

* RE: [PATCH v1 18/22] test/qtest/hace: Update source data and digest data type to 64-bit
  2025-04-02  9:05   ` Cédric Le Goater
@ 2025-05-12  7:14     ` Jamin Lin
  0 siblings, 0 replies; 71+ messages in thread
From: Jamin Lin @ 2025-05-12  7:14 UTC (permalink / raw)
  To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
	Andrew Jeffery, Joel Stanley, Fabiano Rosas, Laurent Vivier,
	Paolo Bonzini, open list:ASPEED BMCs,
	open list:All patches CC here
  Cc: Troy Lee

Hi Cédric,

> Subject: Re: [PATCH v1 18/22] test/qtest/hace: Update source data and digest
> data type to 64-bit
> 
> On 3/21/25 10:26, Jamin Lin wrote:
> > Currently, the hash data source and digest result buffer addresses are
> > set to 32-bit. However, the AST2700 CPU is a 64-bit Cortex-A35
> > architecture, and its DRAM base address is also 64-bit.
> >
> > To support AST2700, update the hash data source address and digest
> > result buffer address to use 64-bit addressing.
> >
> > Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
> > ---
> >   tests/qtest/aspeed-hace-utils.h | 20 +++----
> >   tests/qtest/aspeed-hace-utils.c | 96 ++++++++++++++++-----------------
> >   2 files changed, 58 insertions(+), 58 deletions(-)
> >
> > diff --git a/tests/qtest/aspeed-hace-utils.h
> > b/tests/qtest/aspeed-hace-utils.h index f4440561de..0382570fa2 100644
> > --- a/tests/qtest/aspeed-hace-utils.h
> > +++ b/tests/qtest/aspeed-hace-utils.h
> > @@ -51,25 +51,25 @@ struct AspeedMasks {
> >   };
> >
> >   void aspeed_test_md5(const char *machine, const uint32_t base,
> > -                     const uint32_t src_addr);
> > +                     const uint64_t src_addr);
> >   void aspeed_test_sha256(const char *machine, const uint32_t base,
> > -                        const uint32_t src_addr);
> > +                        const uint64_t src_addr);
> >   void aspeed_test_sha384(const char *machine, const uint32_t base,
> > -                        const uint32_t src_addr);
> > +                        const uint64_t src_addr);
> >   void aspeed_test_sha512(const char *machine, const uint32_t base,
> > -                        const uint32_t src_addr);
> > +                        const uint64_t src_addr);
> >   void aspeed_test_sha256_sg(const char *machine, const uint32_t base,
> > -                           const uint32_t src_addr);
> > +                           const uint64_t src_addr);
> >   void aspeed_test_sha384_sg(const char *machine, const uint32_t base,
> > -                           const uint32_t src_addr);
> > +                           const uint64_t src_addr);
> >   void aspeed_test_sha512_sg(const char *machine, const uint32_t base,
> > -                           const uint32_t src_addr);
> > +                           const uint64_t src_addr);
> >   void aspeed_test_sha256_accum(const char *machine, const uint32_t
> base,
> > -                              const uint32_t src_addr);
> > +                              const uint64_t src_addr);
> >   void aspeed_test_sha384_accum(const char *machine, const uint32_t
> base,
> > -                              const uint32_t src_addr);
> > +                              const uint64_t src_addr);
> >   void aspeed_test_sha512_accum(const char *machine, const uint32_t
> base,
> > -                              const uint32_t src_addr);
> > +                              const uint64_t src_addr);
> >   void aspeed_test_addresses(const char *machine, const uint32_t base,
> >                              const struct AspeedMasks *expected);
> >
> > diff --git a/tests/qtest/aspeed-hace-utils.c
> > b/tests/qtest/aspeed-hace-utils.c index d3146898c2..f39bb8ea48 100644
> > --- a/tests/qtest/aspeed-hace-utils.c
> > +++ b/tests/qtest/aspeed-hace-utils.c
> > @@ -153,22 +153,22 @@ static const uint8_t test_result_accum_sha256[] =
> {
> >       0x5d, 0xae, 0x22, 0x23, 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a,
> 0x9c,
> >       0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad};
> >
> > -static void write_regs(QTestState *s, uint32_t base, uint32_t src,
> > -                       uint32_t length, uint32_t out, uint32_t method)
> > +static void write_regs(QTestState *s, uint32_t base, uint64_t src,
> > +                       uint32_t length, uint64_t out, uint32_t
> > +method)
> >   {
> > -        qtest_writel(s, base + HACE_HASH_SRC, src);
> > -        qtest_writel(s, base + HACE_HASH_DIGEST, out);
> > +        qtest_writel(s, base + HACE_HASH_SRC, extract64(src, 0, 32));
> > +        qtest_writel(s, base + HACE_HASH_DIGEST, extract64(out, 0,
> > + 32));
> >           qtest_writel(s, base + HACE_HASH_DATA_LEN, length);
> >           qtest_writel(s, base + HACE_HASH_CMD, HACE_SHA_BE_EN |
> method);
> >   }
> >
> >   void aspeed_test_md5(const char *machine, const uint32_t base,
> > -                     const uint32_t src_addr)
> > +                     const uint64_t src_addr)
> >
> >   {
> >       QTestState *s = qtest_init(machine);
> >
> > -    uint32_t digest_addr = src_addr + 0x010000;
> > +    uint64_t digest_addr = src_addr + 0x010000;
> >       uint8_t digest[16] = {0};
> >
> >       /* Check engine is idle, no busy or irq bits set */ @@ -198,11
> > +198,11 @@ void aspeed_test_md5(const char *machine, const uint32_t
> base,
> >   }
> >
> >   void aspeed_test_sha256(const char *machine, const uint32_t base,
> > -                        const uint32_t src_addr)
> > +                        const uint64_t src_addr)
> >   {
> >       QTestState *s = qtest_init(machine);
> >
> > -    const uint32_t digest_addr = src_addr + 0x10000;
> > +    const uint64_t digest_addr = src_addr + 0x10000;
> >       uint8_t digest[32] = {0};
> >
> >       /* Check engine is idle, no busy or irq bits set */ @@ -232,11
> > +232,11 @@ void aspeed_test_sha256(const char *machine, const uint32_t
> base,
> >   }
> >
> >   void aspeed_test_sha384(const char *machine, const uint32_t base,
> > -                        const uint32_t src_addr)
> > +                        const uint64_t src_addr)
> >   {
> >       QTestState *s = qtest_init(machine);
> >
> > -    const uint32_t digest_addr = src_addr + 0x10000;
> > +    const uint64_t digest_addr = src_addr + 0x10000;
> >       uint8_t digest[32] = {0};
> >
> >       /* Check engine is idle, no busy or irq bits set */ @@ -266,11
> > +266,11 @@ void aspeed_test_sha384(const char *machine, const uint32_t
> base,
> >   }
> >
> >   void aspeed_test_sha512(const char *machine, const uint32_t base,
> > -                        const uint32_t src_addr)
> > +                        const uint64_t src_addr)
> >   {
> >       QTestState *s = qtest_init(machine);
> >
> > -    const uint32_t digest_addr = src_addr + 0x10000;
> > +    const uint64_t digest_addr = src_addr + 0x10000;
> >       uint8_t digest[64] = {0};
> >
> >       /* Check engine is idle, no busy or irq bits set */ @@ -300,22
> > +300,22 @@ void aspeed_test_sha512(const char *machine, const uint32_t
> base,
> >   }
> >
> >   void aspeed_test_sha256_sg(const char *machine, const uint32_t base,
> > -                           const uint32_t src_addr)
> > +                           const uint64_t src_addr)
> >   {
> >       QTestState *s = qtest_init(machine);
> >
> > -    const uint32_t src_addr_1 = src_addr + 0x10000;
> > -    const uint32_t src_addr_2 = src_addr + 0x20000;
> > -    const uint32_t src_addr_3 = src_addr + 0x30000;
> > -    const uint32_t digest_addr = src_addr + 0x40000;
> > +    const uint64_t src_addr_1 = src_addr + 0x10000;
> > +    const uint64_t src_addr_2 = src_addr + 0x20000;
> > +    const uint64_t src_addr_3 = src_addr + 0x30000;
> > +    const uint64_t digest_addr = src_addr + 0x40000;
> >       uint8_t digest[32] = {0};
> >       struct AspeedSgList array[] = {
> >           {  cpu_to_le32(sizeof(test_vector_sg1)),
> > -           cpu_to_le32(src_addr_1) },
> > +           cpu_to_le64(src_addr_1) },
> 
> 
> This looks broken to me. The addr field is in the scatter-gather list entry is
> 32bit :
> 
>    struct AspeedSgList {
>            uint32_t len;
>            uint32_t addr;
>    } __attribute__ ((__packed__));
> 
> 
Thanks for the review.
Will fix it.
Jamin
> 
> Thanks,
> 
> C.
> 
> 
> >           {  cpu_to_le32(sizeof(test_vector_sg2)),
> > -           cpu_to_le32(src_addr_2) },
> > +           cpu_to_le64(src_addr_2) },
> >           {  cpu_to_le32(sizeof(test_vector_sg3) | SG_LIST_LEN_LAST),
> > -           cpu_to_le32(src_addr_3) },
> > +           cpu_to_le64(src_addr_3) },
> >       };
> >
> >       /* Check engine is idle, no busy or irq bits set */ @@ -351,22
> > +351,22 @@ void aspeed_test_sha256_sg(const char *machine, const
> uint32_t base,
> >   }
> >
> >   void aspeed_test_sha384_sg(const char *machine, const uint32_t base,
> > -                           const uint32_t src_addr)
> > +                           const uint64_t src_addr)
> >   {
> >       QTestState *s = qtest_init(machine);
> >
> > -    const uint32_t src_addr_1 = src_addr + 0x10000;
> > -    const uint32_t src_addr_2 = src_addr + 0x20000;
> > -    const uint32_t src_addr_3 = src_addr + 0x30000;
> > -    const uint32_t digest_addr = src_addr + 0x40000;
> > +    const uint64_t src_addr_1 = src_addr + 0x10000;
> > +    const uint64_t src_addr_2 = src_addr + 0x20000;
> > +    const uint64_t src_addr_3 = src_addr + 0x30000;
> > +    const uint64_t digest_addr = src_addr + 0x40000;
> >       uint8_t digest[64] = {0};
> >       struct AspeedSgList array[] = {
> >           {  cpu_to_le32(sizeof(test_vector_sg1)),
> > -           cpu_to_le32(src_addr_1) },
> > +           cpu_to_le64(src_addr_1) },
> >           {  cpu_to_le32(sizeof(test_vector_sg2)),
> > -           cpu_to_le32(src_addr_2) },
> > +           cpu_to_le64(src_addr_2) },
> >           {  cpu_to_le32(sizeof(test_vector_sg3) | SG_LIST_LEN_LAST),
> > -           cpu_to_le32(src_addr_3) },
> > +           cpu_to_le64(src_addr_3) },
> >       };
> >
> >       /* Check engine is idle, no busy or irq bits set */ @@ -402,22
> > +402,22 @@ void aspeed_test_sha384_sg(const char *machine, const
> uint32_t base,
> >   }
> >
> >   void aspeed_test_sha512_sg(const char *machine, const uint32_t base,
> > -                           const uint32_t src_addr)
> > +                           const uint64_t src_addr)
> >   {
> >       QTestState *s = qtest_init(machine);
> >
> > -    const uint32_t src_addr_1 = src_addr + 0x10000;
> > -    const uint32_t src_addr_2 = src_addr + 0x20000;
> > -    const uint32_t src_addr_3 = src_addr + 0x30000;
> > -    const uint32_t digest_addr = src_addr + 0x40000;
> > +    const uint64_t src_addr_1 = src_addr + 0x10000;
> > +    const uint64_t src_addr_2 = src_addr + 0x20000;
> > +    const uint64_t src_addr_3 = src_addr + 0x30000;
> > +    const uint64_t digest_addr = src_addr + 0x40000;
> >       uint8_t digest[64] = {0};
> >       struct AspeedSgList array[] = {
> >           {  cpu_to_le32(sizeof(test_vector_sg1)),
> > -           cpu_to_le32(src_addr_1) },
> > +           cpu_to_le64(src_addr_1) },
> >           {  cpu_to_le32(sizeof(test_vector_sg2)),
> > -           cpu_to_le32(src_addr_2) },
> > +           cpu_to_le64(src_addr_2) },
> >           {  cpu_to_le32(sizeof(test_vector_sg3) | SG_LIST_LEN_LAST),
> > -           cpu_to_le32(src_addr_3) },
> > +           cpu_to_le64(src_addr_3) },
> >       };
> >
> >       /* Check engine is idle, no busy or irq bits set */ @@ -453,16
> > +453,16 @@ void aspeed_test_sha512_sg(const char *machine, const
> uint32_t base,
> >   }
> >
> >   void aspeed_test_sha256_accum(const char *machine, const uint32_t
> base,
> > -                              const uint32_t src_addr)
> > +                              const uint64_t src_addr)
> >   {
> >       QTestState *s = qtest_init(machine);
> >
> > -    const uint32_t buffer_addr = src_addr + 0x10000;
> > -    const uint32_t digest_addr = src_addr + 0x40000;
> > +    const uint64_t buffer_addr = src_addr + 0x10000;
> > +    const uint64_t digest_addr = src_addr + 0x40000;
> >       uint8_t digest[32] = {0};
> >       struct AspeedSgList array[] = {
> >           {  cpu_to_le32(sizeof(test_vector_accum_256) |
> SG_LIST_LEN_LAST),
> > -           cpu_to_le32(buffer_addr) },
> > +           cpu_to_le64(buffer_addr) },
> >       };
> >
> >       /* Check engine is idle, no busy or irq bits set */ @@ -494,16
> > +494,16 @@ void aspeed_test_sha256_accum(const char *machine, const
> uint32_t base,
> >   }
> >
> >   void aspeed_test_sha384_accum(const char *machine, const uint32_t
> base,
> > -                              const uint32_t src_addr)
> > +                              const uint64_t src_addr)
> >   {
> >       QTestState *s = qtest_init(machine);
> >
> > -    const uint32_t buffer_addr = src_addr + 0x10000;
> > -    const uint32_t digest_addr = src_addr + 0x40000;
> > +    const uint64_t buffer_addr = src_addr + 0x10000;
> > +    const uint64_t digest_addr = src_addr + 0x40000;
> >       uint8_t digest[64] = {0};
> >       struct AspeedSgList array[] = {
> >           {  cpu_to_le32(sizeof(test_vector_accum_384) |
> SG_LIST_LEN_LAST),
> > -           cpu_to_le32(buffer_addr) },
> > +           cpu_to_le64(buffer_addr) },
> >       };
> >
> >       /* Check engine is idle, no busy or irq bits set */ @@ -535,16
> > +535,16 @@ void aspeed_test_sha384_accum(const char *machine, const
> uint32_t base,
> >   }
> >
> >   void aspeed_test_sha512_accum(const char *machine, const uint32_t
> base,
> > -                              const uint32_t src_addr)
> > +                              const uint64_t src_addr)
> >   {
> >       QTestState *s = qtest_init(machine);
> >
> > -    const uint32_t buffer_addr = src_addr + 0x10000;
> > -    const uint32_t digest_addr = src_addr + 0x40000;
> > +    const uint64_t buffer_addr = src_addr + 0x10000;
> > +    const uint64_t digest_addr = src_addr + 0x40000;
> >       uint8_t digest[64] = {0};
> >       struct AspeedSgList array[] = {
> >           {  cpu_to_le32(sizeof(test_vector_accum_512) |
> SG_LIST_LEN_LAST),
> > -           cpu_to_le32(buffer_addr) },
> > +           cpu_to_le64(buffer_addr) },
> >       };
> >
> >       /* Check engine is idle, no busy or irq bits set */


^ permalink raw reply	[flat|nested] 71+ messages in thread

* RE: [PATCH v1 07/22] hw/misc/aspeed_hace: Add support for source, digest, key buffer 64 bit addresses
  2025-04-01 16:19   ` Cédric Le Goater
@ 2025-05-12  8:06     ` Jamin Lin
  0 siblings, 0 replies; 71+ messages in thread
From: Jamin Lin @ 2025-05-12  8:06 UTC (permalink / raw)
  To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
	Andrew Jeffery, Joel Stanley, Fabiano Rosas, Laurent Vivier,
	Paolo Bonzini, open list:ASPEED BMCs,
	open list:All patches CC here
  Cc: Troy Lee

Hi Cédric,

> Subject: Re: [PATCH v1 07/22] hw/misc/aspeed_hace: Add support for source,
> digest, key buffer 64 bit addresses
> 
> 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
> 
> R_HASH_DIGEST_HIGH would be easier to understand.
> 
Will update it.

> > [63:32] and R_HASH_DEST storing bits [31:0]. The HMAC key buffer
> > address is also 64-bit, with R_HASH_KEY_BUFF_HI storing bits [63:32]
> > and R_HASH_KEY_BUFF storing bits [31:0].
> >
> > The AST2700 supports a maximum DRAM size of 8 GB, with a DRAM
> > addressable range from 0x0_0000_0000 to 0x1_FFFF_FFFF. Since this
> > range fits within 34 bits, only bits [33:0] are needed to store the
> > DRAM offset. To optimize address storage, the high physical address
> > bits [1:0] of the source, digest and key buffer addresses are stored as
> dram_offset bits [33:32].
> >
> > To achieve this, a src_hi_mask with a mask value of 0x3 is introduced,
> > ensuring that src_addr_hi consists of bits [1:0]. The final src_addr
> > is computed as (src_addr_hi[1:0] << 32) | src_addr[31:0], representing
> > the DRAM offset within bits [33:0].
> >
> > Similarly, a dest_hi_mask with a mask value of 0x3 is introduced to
> > ensure that dest_addr_hi consists of bits [1:0]. The final dest_addr
> > is calculated as (dest_addr_hi[1:0] << 32) | dest_addr[31:0],
> > representing the DRAM offset within bits [33:0].
> >
> > Additionally, a key_hi_mask with a mask value of 0x3 is introduced to
> > ensure that key_buf_addr_hi consists of bits [1:0]. The final
> > key_buf_addr is determined as (key_buf_addr_hi[1:0] << 32) |
> > key_buf_addr[31:0], representing the DRAM offset within bits [33:0].
> 
> What does the datasheet say regarding the High Address registers ?
> Are bits [1:0] RW and [31:2] RO ?
> 
> 
> > This approach eliminates the need to reduce the high part of the DRAM
> > physical address for DMA operations. Previously, this was calculated
> > as (high physical address bits [7:0] - 4), since the DRAM start
> > address is 0x4_00000000, making the high part address [7:0] - 4.
> 
> I don't understand this part. Is there a difference between AST2700
> A0 and A1  ?
> 

A0 and A1 designs are identical.

For example: 
The HACE model sets its DRAM memory region to the SoC’s dram_mr memory region.
The SoC’s dram_mr represents the DRAM region starting at address 0x4_0000_0000.

https://github.com/qemu/qemu/blob/master/hw/arm/aspeed_ast27x0.c#L926 
/* HACE */
    object_property_set_link(OBJECT(&s->hace), "dram", OBJECT(s->dram_mr),
                             &error_abort);

When FW sets the source buffer address to 0x4_XXXX_XXXX, the HACE model must convert this to a DRAM offset using:
offset = 0x4_XXXX_XXXX - 0x4_0000_0000

This ensures compatibility with QEMU memory access APIs like:
address_space_write (&s->dram_as....)
address_space_ldl_le(&s->dram_as...)

There are two approaches to convert the source address into a DRAM offset

1. This method subtracts the DRAM base address explicitly. The SPI controller model (SMC/FMC) uses this approach.
https://github.com/qemu/qemu/commit/ee48fef06c034ff245db9e553dcf0f1262f97bd2 
https://github.com/qemu/qemu/commit/6330be8da44cf11e429197187e814299eff881cd 
Reference:
https://github.com/qemu/qemu/blob/master/hw/arm/aspeed_ast27x0.c#L725C4-L728C43

/* FMC, The number of CS is set at the board level */
    object_property_set_int(OBJECT(&s->fmc), "dram-base",
                            sc->memmap[ASPEED_DEV_SDRAM],
                            &error_abort);
https://github.com/qemu/qemu/blob/master/hw/ssi/aspeed_smc.c#L948
 
if (aspeed_smc_has_dma64(asc)) {
        dma_dram_offset = dma_dram_addr - s->dram_base;
    } else {
        dma_dram_offset = dma_dram_addr;
    }


2. Using this solution in HACE model
The AST2700 supports a maximum DRAM size of 8 GB, with a DRAM
addressable range from 0x0_0000_0000 to 0x1_FFFF_FFFF. Since this
range fits within 34 bits, only bits [33:0] are needed to store the
DRAM offset. Therefore, I set the high mark address to 0x03.
In this solution we don’t need to create a new property.

I2c model use this solution, too
https://github.com/qemu/qemu/commit/be8c15118a24491ccb2e7451f74f8efca1dd149c

> >
> > Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
> > ---
> >   include/hw/misc/aspeed_hace.h |  5 ++++-
> >   hw/misc/aspeed_hace.c         | 29
> +++++++++++++++++++++++++++++
> >   2 files changed, 33 insertions(+), 1 deletion(-)
> >
> > diff --git a/include/hw/misc/aspeed_hace.h
> > b/include/hw/misc/aspeed_hace.h index b69a038d35..a4479bd383 100644
> > --- a/include/hw/misc/aspeed_hace.h
> > +++ b/include/hw/misc/aspeed_hace.h
> > @@ -22,7 +22,7 @@
> >
> >   OBJECT_DECLARE_TYPE(AspeedHACEState, AspeedHACEClass,
> ASPEED_HACE)
> >
> > -#define ASPEED_HACE_NR_REGS (0x64 >> 2)
> > +#define ASPEED_HACE_NR_REGS (0x9C >> 2)
> 
> I think we need a class attribute.
> 
> >   #define ASPEED_HACE_MAX_SG  256 /* max number of entries */
> >
> >   struct AspeedHACEState {
> > @@ -49,6 +49,9 @@ struct AspeedHACEClass {
> >       uint32_t key_mask;
> >       uint32_t hash_mask;
> >       bool raise_crypt_interrupt_workaround;
> > +    uint32_t src_hi_mask;
> > +    uint32_t dest_hi_mask;
> > +    uint32_t key_hi_mask;
> >   };
> >
> >   #endif /* ASPEED_HACE_H */
> > diff --git a/hw/misc/aspeed_hace.c b/hw/misc/aspeed_hace.c index
> > d06158dffd..51c6523fab 100644
> > --- a/hw/misc/aspeed_hace.c
> > +++ b/hw/misc/aspeed_hace.c
> > @@ -30,6 +30,9 @@
> >   #define R_HASH_DEST     (0x24 / 4)
> >   #define R_HASH_KEY_BUFF (0x28 / 4)
> >   #define R_HASH_SRC_LEN  (0x2c / 4)
> > +#define R_HASH_SRC_HI      (0x90 / 4)
> > +#define R_HASH_DEST_HI     (0x94 / 4)
> > +#define R_HASH_KEY_BUFF_HI (0x98 / 4)
> >
> >   #define R_HASH_CMD      (0x30 / 4)
> >   /* Hash algorithm selection */
> > @@ -393,6 +396,15 @@ static void aspeed_hace_write(void *opaque,
> hwaddr addr, uint64_t data,
> >               }
> >           }
> >           break;
> > +    case R_HASH_SRC_HI:
> > +        data &= ahc->src_hi_mask;
> > +        break;
> > +    case R_HASH_DEST_HI:
> > +        data &= ahc->dest_hi_mask;
> > +        break;
> > +    case R_HASH_KEY_BUFF_HI:
> > +        data &= ahc->key_hi_mask;
> > +        break;
> 
> This change exposes the high address registers to all SoCs which is unfortunate.
> 
> I would introduce a class attribute to limit the number of registers per SoC.
> 
> You could also size the MMIO aperture with this new attribute and remove the
> "Out-of-bounds" message at the beginning of the read/write memops.
Will do.

I introduce a new mem_size class attribute to set the different memory size for different SOCs in patch 10. 
https://patchwork.kernel.org/project/qemu-devel/patch/20250321092623.2097234-11-jamin_lin@aspeedtech.com/

Solution 1:
Should I use this mem_size class attribute to set it to register spaces instead of memory size and rename it to reg_szie?
ahc->reg_size = 0x64 >> 2 for AST2500, AST2600, AST1030
ahc->reg_size = 0x9C >> 2 for AST2700

Solution2:
Keep patch 10. And Introduce a new subregion for register size

2700
Container ----> mem_szie    0x100)
  Sub region ---> reg_size  (0x9C >> 2)

2600
Container --> mem_size 0x10000
  Sub region --> reg_size (0x64 >> 2)

Could you please tell me which solution you prefer?

Thanks-Jamin

> Thanks,
> 
> C.
> 
> 
> 
> >       default:
> >           break;
> >       }
> > @@ -566,6 +578,23 @@ static void
> aspeed_ast2700_hace_class_init(ObjectClass *klass, void *data)
> >       ahc->key_mask = 0x7FFFFFF8;
> >       ahc->hash_mask = 0x00147FFF;
> >
> > +    /*
> > +     * The AST2700 supports a maximum DRAM size of 8 GB, with a
> DRAM
> > +     * addressable range from 0x0_0000_0000 to 0x1_FFFF_FFFF. Since
> this range
> > +     * fits within 34 bits, only bits [33:0] are needed to store the DRAM
> > +     * offset. To optimize address storage, the high physical address bits
> > +     * [1:0] of the source, digest and key buffer addresses are stored as
> > +     * dram_offset bits [33:32].
> > +     *
> > +     * This approach eliminates the need to reduce the high part of the
> DRAM
> > +     * physical address for DMA operations. Previously, this was calculated
> as
> > +     * (high physical address bits [7:0] - 4), since the DRAM start address
> is
> > +     * 0x4_00000000, making the high part address [7:0] - 4.
> > +     */
> > +    ahc->src_hi_mask = 0x00000003;
> > +    ahc->dest_hi_mask = 0x00000003;
> > +    ahc->key_hi_mask = 0x00000003;
> > +
> >       /*
> >        * Currently, it does not support the CRYPT command. Instead, it
> only
> >        * sends an interrupt to notify the firmware that the crypt
> > command


^ permalink raw reply	[flat|nested] 71+ messages in thread

* RE: [PATCH v1 08/22] hw/misc/aspeed_hace: Support DMA 64 bits dram address.
  2025-05-10  6:15       ` Cédric Le Goater
@ 2025-05-12  8:41         ` Jamin Lin
  2025-05-15  7:11           ` Jamin Lin
  0 siblings, 1 reply; 71+ messages in thread
From: Jamin Lin @ 2025-05-12  8:41 UTC (permalink / raw)
  To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
	Andrew Jeffery, Joel Stanley, Fabiano Rosas, Laurent Vivier,
	Paolo Bonzini, open list:ASPEED BMCs,
	open list:All patches CC here
  Cc: Troy Lee

Hi Cédric

> Subject: Re: [PATCH v1 08/22] hw/misc/aspeed_hace: Support DMA 64 bits
> dram address.
> 
> On 5/9/25 09:04, Jamin Lin wrote:
> > 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_lin@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.
> 
> Should we introduce a class attribute then ?
> 
Can I modify SG_LIST_ADDR_MASK directly?

In this model, hash_mask is set to 0x000003ff for AST2500, which disables support for SG mode and SHA512:
As a result, the model does not handle SG mode for AST2500.

https://github.com/qemu/qemu/blob/master/hw/misc/aspeed_hace.c#L529
ahc->hash_mask = 0x000003ff; /* No SG or SHA512 modes */

Thanks-Jamin
> Thanks,
> 
> C.

^ permalink raw reply	[flat|nested] 71+ messages in thread

* RE: [PATCH v1 08/22] hw/misc/aspeed_hace: Support DMA 64 bits dram address.
  2025-05-12  8:41         ` Jamin Lin
@ 2025-05-15  7:11           ` Jamin Lin
  2025-05-15  7:19             ` Jamin Lin
  0 siblings, 1 reply; 71+ messages in thread
From: Jamin Lin @ 2025-05-15  7:11 UTC (permalink / raw)
  To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
	Andrew Jeffery, Joel Stanley, Fabiano Rosas, Laurent Vivier,
	Paolo Bonzini, open list:ASPEED BMCs,
	open list:All patches CC here
  Cc: Troy Lee

Hi Cédric

> > >
> > >> 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.
> >
> > Should we introduce a class attribute then ?
> >
> Can I modify SG_LIST_ADDR_MASK directly?
> 
> In this model, hash_mask is set to 0x000003ff for AST2500, which disables
> support for SG mode and SHA512:
> As a result, the model does not handle SG mode for AST2500.
> 
> https://github.com/qemu/qemu/blob/master/hw/misc/aspeed_hace.c#L529
> ahc->hash_mask = 0x000003ff; /* No SG or SHA512 modes */
> 

I would like to correct my previous investigation.

According to the datasheet, the source buffer address list must be 8-byte aligned. Therefore, the definition of HACE20 should be as follows:
Bit 31: Reserved 0
Bit 30:3 base address of sg list
Bit 2:0 Reserved 0

In the current implementation of SG mode, the "local src" variable represents the buffer address, and each scatter-gather entry has a size of 8 bytes (SG_LIST_ENTRY_SIZE).
As a result, we only need to ensure that the "local src variable itself is 8-byte aligned".
The actual buffer addresses referenced by the SG list entries do not need to be 8-byte aligned.

```
src = s->regs[R_HASH_SRC] + (i * SG_LIST_ENTRY_SIZE);
```

We only need to ensure that the starting src address is aligned to 8 bytes.

```
  len = address_space_ldl_le(&s->dram_as, src,
                                       MEMTXATTRS_UNSPECIFIED, NULL);

   addr = address_space_ldl_le(&s->dram_as, src + SG_LIST_LEN_SIZE,
                                        MEMTXATTRS_UNSPECIFIED, NULL);
   addr &= SG_LIST_ADDR_MASK;
```

The local addr variable represents the buffer address and does not need to be 8-byte aligned.
I tried removing this line(addr &= SG_LIST_ADDR_MASK), but encountered a failure in the AST2600 test.
This is because the AST2600 DRAM base address is 0x80000000, and the original code applies "addr & 0x7FFFFFFF" to convert the buffer address to 0x0, which corresponds to the
"DRAM offset 0". In this case, there is no need to perform (addr - 0x80000000) to compute the DRAM offset on AST2600. 

As a result, I will not modify SG_LIST_ADDR_MASK in this patch.
If you still wish to improve this part, I can create a separate patch series to address it, since the current patch set has already become quite large (29 patches will be re-sent in v3).

Thanks-Jamin

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

^ permalink raw reply	[flat|nested] 71+ messages in thread

* RE: [PATCH v1 08/22] hw/misc/aspeed_hace: Support DMA 64 bits dram address.
  2025-05-15  7:11           ` Jamin Lin
@ 2025-05-15  7:19             ` Jamin Lin
  0 siblings, 0 replies; 71+ messages in thread
From: Jamin Lin @ 2025-05-15  7:19 UTC (permalink / raw)
  To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
	Andrew Jeffery, Joel Stanley, Fabiano Rosas, Laurent Vivier,
	Paolo Bonzini, open list:ASPEED BMCs,
	open list:All patches CC here
  Cc: Troy Lee


> Subject: RE: [PATCH v1 08/22] hw/misc/aspeed_hace: Support DMA 64 bits
> dram address.
> 
> Hi Cédric
> 
> > > >
> > > >> 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.
> > >
> > > Should we introduce a class attribute then ?
> > >
> > Can I modify SG_LIST_ADDR_MASK directly?
> >
> > In this model, hash_mask is set to 0x000003ff for AST2500, which
> > disables support for SG mode and SHA512:
> > As a result, the model does not handle SG mode for AST2500.
> >
> > https://github.com/qemu/qemu/blob/master/hw/misc/aspeed_hace.c#L529
> > ahc->hash_mask = 0x000003ff; /* No SG or SHA512 modes */
> >
> 
> I would like to correct my previous investigation.
> 
> According to the datasheet, the source buffer address list must be 8-byte
> aligned. Therefore, the definition of HACE20 should be as follows:
> Bit 31: Reserved 0
> Bit 30:3 base address of sg list
> Bit 2:0 Reserved 0
> 
> In the current implementation of SG mode, the "local src" variable represents
> the buffer address, and each scatter-gather entry has a size of 8 bytes

Sorry typo --> the "local src" variable represents the buffer list address

buffer list address1 addr --> 8-byte aligned".
  len
  buf_addr A --> do not need to be 8-byte aligned.
buffer list address2 addr 
  len
  buf_addr B --> do not need to be 8-byte aligned.

Addr A: Data
Addr B: Data 

Thanks-Jamin

> (SG_LIST_ENTRY_SIZE).
> As a result, we only need to ensure that the "local src variable itself is 8-byte
> aligned".
> The actual buffer addresses referenced by the SG list entries do not need to be
> 8-byte aligned.
> 
> ```
> src = s->regs[R_HASH_SRC] + (i * SG_LIST_ENTRY_SIZE); ```
> 
> We only need to ensure that the starting src address is aligned to 8 bytes.
> 
> ```
>   len = address_space_ldl_le(&s->dram_as, src,
>                                        MEMTXATTRS_UNSPECIFIED,
> NULL);
> 
>    addr = address_space_ldl_le(&s->dram_as, src + SG_LIST_LEN_SIZE,
>                                         MEMTXATTRS_UNSPECIFIED,
> NULL);
>    addr &= SG_LIST_ADDR_MASK;
> ```
> 
> The local addr variable represents the buffer address and does not need to be
> 8-byte aligned.
> I tried removing this line(addr &= SG_LIST_ADDR_MASK), but encountered a
> failure in the AST2600 test.
> This is because the AST2600 DRAM base address is 0x80000000, and the
> original code applies "addr & 0x7FFFFFFF" to convert the buffer address to 0x0,
> which corresponds to the "DRAM offset 0". In this case, there is no need to
> perform (addr - 0x80000000) to compute the DRAM offset on AST2600.
> 
> As a result, I will not modify SG_LIST_ADDR_MASK in this patch.
> If you still wish to improve this part, I can create a separate patch series to
> address it, since the current patch set has already become quite large (29
> patches will be re-sent in v3).
> 
> Thanks-Jamin
> 
> > Thanks-Jamin
> > > Thanks,
> > >
> > > C.

^ permalink raw reply	[flat|nested] 71+ messages in thread

end of thread, other threads:[~2025-05-15  7:20 UTC | newest]

Thread overview: 71+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-03-21  9:25 [PATCH v1 00/22] Fix incorrect hash results on AST2700 Jamin Lin via
2025-03-21  9:25 ` [PATCH v1 01/22] hw/misc/aspeed_hace: Remove unused code for better readability Jamin Lin via
2025-04-01 13:08   ` Cédric Le Goater
2025-05-05  3:28     ` Jamin Lin
2025-05-06  9:01       ` Cédric Le Goater
2025-03-21  9:25 ` [PATCH v1 02/22] hw/misc/aspeed_hace: Fix buffer overflow in has_padding function Jamin Lin via
2025-03-21  9:47   ` Jamin Lin
2025-03-22 20:52     ` Cédric Le Goater
2025-03-21  9:25 ` [PATCH v1 03/22] hw/misc/aspeed_hace: Improve readability and consistency in variable naming Jamin Lin via
2025-04-01 13:17   ` Cédric Le Goater
2025-05-09  6:57     ` Jamin Lin
2025-03-21  9:26 ` [PATCH v1 04/22] hw/misc/aspeed_hace: Update hash source address handling to 64-bit for AST2700 Jamin Lin via
2025-04-01 13:52   ` Cédric Le Goater
2025-05-09  6:49     ` Jamin Lin
2025-03-21  9:26 ` [PATCH v1 05/22] hw/misc/aspeed_hace: Introduce 64-bit digest_addr variable " Jamin Lin via
2025-04-01 13:55   ` Cédric Le Goater
2025-05-09  4:01     ` Jamin Lin
2025-03-21  9:26 ` [PATCH v1 06/22] hw/misc/aspeed_hace: Support accumulative mode for direct access mode Jamin Lin via
2025-04-01 13:57   ` Cédric Le Goater
2025-05-09  6:55     ` Jamin Lin
2025-05-10  6:12       ` Cédric Le Goater
2025-03-21  9:26 ` [PATCH v1 07/22] hw/misc/aspeed_hace: Add support for source, digest, key buffer 64 bit addresses Jamin Lin via
2025-04-01 16:19   ` Cédric Le Goater
2025-05-12  8:06     ` Jamin Lin
2025-03-21  9:26 ` [PATCH v1 08/22] hw/misc/aspeed_hace: Support DMA 64 bits dram address Jamin Lin via
2025-04-02  7:41   ` Cédric Le Goater
2025-05-09  7:04     ` Jamin Lin
2025-05-10  6:15       ` Cédric Le Goater
2025-05-12  8:41         ` Jamin Lin
2025-05-15  7:11           ` Jamin Lin
2025-05-15  7:19             ` Jamin Lin
2025-03-21  9:26 ` [PATCH v1 09/22] hw/misc/aspeed_hace: Ensure HASH_IRQ is always set to prevent firmware hang Jamin Lin via
2025-04-02  9:35   ` Cédric Le Goater
2025-05-06  5:08     ` Jamin Lin
2025-03-21  9:26 ` [PATCH v1 10/22] hw/misc/aspeed_hace:: Support setting different memory size Jamin Lin via
2025-04-02  7:46   ` Cédric Le Goater
2025-03-21  9:26 ` [PATCH v1 11/22] hw/misc/aspeed_hace: Add trace-events for better debugging Jamin Lin via
2025-04-02  7:59   ` Cédric Le Goater
2025-05-12  1:34     ` Jamin Lin
2025-03-21  9:26 ` [PATCH v1 12/22] hw/misc/aspeed_hace Support to dump plaintext and digest " Jamin Lin via
2025-04-02  8:05   ` Cédric Le Goater
2025-05-12  5:22     ` Jamin Lin
2025-03-21  9:26 ` [PATCH v1 13/22] test/qtest: Introduce a new aspeed-hace-utils.c to place common testcases Jamin Lin via
2025-04-02  8:54   ` Cédric Le Goater
2025-05-05  6:42     ` Jamin Lin
2025-03-21  9:26 ` [PATCH v1 14/22] test/qtest/hace: Adjust test address range for AST1030 due to SRAM limitations Jamin Lin via
2025-04-02  9:43   ` Cédric Le Goater
2025-05-05  3:44     ` Jamin Lin
2025-03-21  9:26 ` [PATCH v1 15/22] test/qtest/hace: Add SHA-384 test cases for ASPEED HACE model Jamin Lin via
2025-04-02  9:02   ` Cédric Le Goater
2025-05-05  6:36     ` Jamin Lin
2025-05-05  6:51       ` Jamin Lin
2025-05-06  8:59         ` Cédric Le Goater
2025-03-21  9:26 ` [PATCH v1 16/22] test/qtest/hace: Add SHA-384 tests for AST2600 Jamin Lin via
2025-04-02  9:02   ` Cédric Le Goater
2025-03-21  9:26 ` [PATCH v1 17/22] test/qtest/hace: Add tests for AST1030 Jamin Lin via
2025-04-02  9:44   ` Cédric Le Goater
2025-03-21  9:26 ` [PATCH v1 18/22] test/qtest/hace: Update source data and digest data type to 64-bit Jamin Lin via
2025-04-02  9:05   ` Cédric Le Goater
2025-05-12  7:14     ` Jamin Lin
2025-03-21  9:26 ` [PATCH v1 19/22] test/qtest/hace: Support 64-bit source and digest addresses for AST2700 Jamin Lin via
2025-04-02  9:06   ` Cédric Le Goater
2025-03-21  9:26 ` [PATCH v1 20/22] test/qtest/hace: Support to test upper 32 bits of digest and source addresses Jamin Lin via
2025-04-02  9:12   ` Cédric Le Goater
2025-03-21  9:26 ` [PATCH v1 21/22] test/qtest/hace: Support to validate 64-bit hmac key buffer addresses Jamin Lin via
2025-04-02  9:12   ` Cédric Le Goater
2025-03-21  9:26 ` [PATCH v1 22/22] test/qtest/hace: Add tests for AST2700 Jamin Lin via
2025-04-02  9:16   ` Cédric Le Goater
2025-03-21  9:39 ` [PATCH v1 00/22] Fix incorrect hash results on AST2700 Cédric Le Goater
2025-04-02  9:47 ` Cédric Le Goater
2025-04-02  9:54   ` Jamin Lin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).