From: Klaus Heinrich Kiwi <klaus@linux.vnet.ibm.com>
To: Joel Stanley <joel@jms.id.au>,
openbmc@lists.ozlabs.org, Andrew Jeffery <andrew@aj.id.au>
Cc: "Cédric Le Goater" <clg@kaod.org>
Subject: Re: [PATCH u-boot v2019.04-aspeed-openbmc 10/11] crypto: Add driver for Aspeed HACE
Date: Tue, 13 Apr 2021 17:41:03 -0300 [thread overview]
Message-ID: <cacf13c1-91b2-ad51-606e-bb208d13ec36@linux.vnet.ibm.com> (raw)
In-Reply-To: <20210413080755.73572-11-joel@jms.id.au>
Hi Joel,
On 4/13/2021 5:07 AM, Joel Stanley wrote:
> The HACE supports MD5, SHA1 and SHA2 family hash functions. This driver
> uses it in a polling mode to perform hash calculations over buffers
> placed in DRAM.
>
> Co-developed-by: Klaus Heinrich Kiwi <klaus@linux.vnet.ibm.com>
> Signed-off-by: Joel Stanley <joel@jms.id.au>
> ---
> drivers/crypto/Kconfig | 16 +++
> drivers/crypto/Makefile | 1 +
> drivers/crypto/aspeed_hace.c | 250 +++++++++++++++++++++++++++++++++++
> 3 files changed, 267 insertions(+)
> create mode 100644 drivers/crypto/aspeed_hace.c
>
> diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
> index 1ea116be7503..f78e41e0e9e7 100644
> --- a/drivers/crypto/Kconfig
> +++ b/drivers/crypto/Kconfig
> @@ -2,4 +2,20 @@ menu "Hardware crypto devices"
>
> source drivers/crypto/fsl/Kconfig
>
> +config ASPEED_HACE
> + bool "ASPEED Hash and Crypto Engine"
> + select SHA_HW_ACCEL
> + select SHA_PROG_HW_ACCEL
> + depends on ASPEED_AST2600
> + help
> + Select this option to enable a driver for using the SHA engine in
> + the ASPEED BMC SoCs.
> +
> + Enabling this allows the use of SHA operations in hardware without requiring the
> + SHA software implementations, saving code size.
> +
> + Due to hardware limitations it cannot be used with a FIT placed in SPI
> + FLASH. Data can only be hashed if it is in SDRAM, making this relevant
> + for MMC and network boot only.
> +
> endmenu
> diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile
> index efbd1d3fca05..ac93b1295954 100644
> --- a/drivers/crypto/Makefile
> +++ b/drivers/crypto/Makefile
> @@ -4,5 +4,6 @@
> # http://www.samsung.com
>
> obj-$(CONFIG_EXYNOS_ACE_SHA) += ace_sha.o
> +obj-$(CONFIG_ASPEED_HACE) += aspeed_hace.o
> obj-y += rsa_mod_exp/
> obj-y += fsl/
> diff --git a/drivers/crypto/aspeed_hace.c b/drivers/crypto/aspeed_hace.c
> new file mode 100644
> index 000000000000..473d4d7391b7
> --- /dev/null
> +++ b/drivers/crypto/aspeed_hace.c
> @@ -0,0 +1,250 @@
> +/*
> + * (C) Copyright ASPEED Technology Inc.
> + * Copyright 2021 IBM Corp.
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +
> +#include <common.h>
> +#include <clk.h>
> +
> +#include <log.h>
> +#include <asm/io.h>
> +#include <malloc.h>
> +#include <hash.h>
> +
> +#include <dm/device.h>
> +#include <dm/fdtaddr.h>
> +
> +#include <linux/bitops.h>
> +#include <linux/delay.h>
> +#include <linux/kernel.h>
> +#include <linux/iopoll.h>
> +
> +#define ASPEED_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 ASPEED_HACE_HASH_SRC 0x20
> +#define ASPEED_HACE_HASH_DIGEST_BUFF 0x24
> +#define ASPEED_HACE_HASH_KEY_BUFF 0x28
> +#define ASPEED_HACE_HASH_DATA_LEN 0x2C
> +#define HACE_SG_LAST BIT(31)
> +#define ASPEED_HACE_HASH_CMD 0x30
> +#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 ASPEED_MAX_SG 32
> +
> +struct aspeed_sg {
> + u32 len;
> + u32 addr;
> +};
> +
> +struct aspeed_hash_ctx {
> + u32 method;
> + u32 digest_size;
> + u32 len;
> + u32 count;
> + struct aspeed_sg list[ASPEED_MAX_SG] __attribute__((aligned(8)));
> +};
> +
> +struct aspeed_hace {
> + struct clk clk;
> +};
> +
> +static phys_addr_t base;
> +
> +static int aspeed_hace_wait_completion(u32 reg, u32 flag, int timeout_us)
> +{
> + u32 val;
> +
> + return readl_poll_timeout(reg, val, (val & flag) == flag, timeout_us);
> +}
> +
> +static int digest_object(const void *src, unsigned int length, void *digest,
> + u32 method)
> +{
> + if (!((u32)src & BIT(31))) {
> + debug("HACE src out of bounds: can only copy from SDRAM\n");
> + return -EINVAL;
> + }
> +
> + if ((u32)digest & 0x7) {
> + debug("HACE dest alignment incorrect: %p\n", digest);
> + return -EINVAL;
> + }
> +
> + writel((u32)src, base + ASPEED_HACE_HASH_SRC);
> + writel((u32)digest, base + ASPEED_HACE_HASH_DIGEST_BUFF);
> + writel(length, base + ASPEED_HACE_HASH_DATA_LEN);
> + writel(HACE_SHA_BE_EN | method, base + ASPEED_HACE_HASH_CMD);
> +
> + /* SHA512 hashing appears to have a througput of about 12MB/s */
> + return aspeed_hace_wait_completion(base + ASPEED_HACE_STS,
> + HACE_HASH_ISR,
> + 1000 + (length >> 3));
In some of my previous testing with the un-cleaned patchset
(https://github.com/klauskiwi/u-boot/tree/hace_sg_work), the
Qemu implementation (Cedric's Aspeed-6.0 branch) worked fine,
but on hardware I was getting errors until I explicitly
cleared the HACE_HASH_ISR before attemptinga new command..
It makes sense since the readl_poll_timeout() would return
immediately, without completing the command, if the HASH_ISR bit
is set.
> +}
> +
> +void hw_sha1(const unsigned char *pbuf, unsigned int buf_len,
> + unsigned char *pout, unsigned int chunk_size)
> +{
> + int rc;
> +
> + rc = digest_object(pbuf, buf_len, pout, HACE_ALGO_SHA1);
> + if (rc)
> + debug("HACE failure: %d\n", rc);
> +}
> +
> +void hw_sha256(const unsigned char *pbuf, unsigned int buf_len,
> + unsigned char *pout, unsigned int chunk_size)
> +{
> + int rc;
> +
> + rc = digest_object(pbuf, buf_len, pout, HACE_ALGO_SHA256);
> + if (rc)
> + debug("HACE failure: %d\n", rc);
> +}
> +
> +void hw_sha512(const unsigned char *pbuf, unsigned int buf_len,
> + unsigned char *pout, unsigned int chunk_size)
> +{
> + int rc;
> +
> + rc = digest_object(pbuf, buf_len, pout, HACE_ALGO_SHA512);
> + if (rc)
> + debug("HACE failure: %d\n", rc);
> +}
> +
> +#if IS_ENABLED(CONFIG_SHA_PROG_HW_ACCEL)
> +int hw_sha_init(struct hash_algo *algo, void **ctxp)
> +{
> + struct aspeed_hash_ctx *ctx;
> + u32 method;
> +
> + if (!strcmp(algo->name, "sha1")) {
> + method = HACE_ALGO_SHA1;
> + }
> + else if (!strcmp(algo->name, "sha256")) {
> + method = HACE_ALGO_SHA256;
> + }
> + else if (!strcmp(algo->name, "sha512")) {
> + method = HACE_ALGO_SHA512;
> + }
> + else {
> + return -ENOTSUPP;
> + }
> +
> + ctx = calloc(1, sizeof(*ctx));
> +
> + if (ctx == NULL) {
> + debug("Cannot allocate memory for context\n");
> + return -ENOMEM;
> + }
> + ctx->method = method | HACE_SG_EN;
> + ctx->digest_size = algo->digest_size;
> + *ctxp = ctx;
> +
> + return 0;
> +}
> +
> +int hw_sha_update(struct hash_algo *algo, void *hash_ctx, const void *buf,
> + unsigned int size, int is_last)
> +{
> + struct aspeed_hash_ctx *ctx = hash_ctx;
> + struct aspeed_sg *sg = &ctx->list[ctx->count];
> +
> + if (ctx->count >= ARRAY_SIZE(ctx->list)) {
> + debug("HACE error: Reached maximum number of hash segments\n");
> + free(ctx);
> + return -EINVAL;
> + }
> +
> + sg->addr = (u32)buf;
> + sg->len = size;
> + if (is_last)
> + sg->len |= HACE_SG_LAST;
> +
> + ctx->count++;
> + ctx->len += size;
> +
> + return 0;
> +}
> +
> +int hw_sha_finish(struct hash_algo *algo, void *hash_ctx, void *dest_buf, int size)
> +{
> + struct aspeed_hash_ctx *ctx = hash_ctx;
> + int rc;
> +
> + if (size < ctx->digest_size) {
> + debug("HACE error: insufficient size on destination buffer\n");
> + free(ctx);
> + return -EINVAL;
> + }
> +
> + rc = digest_object(ctx->list, ctx->len, dest_buf, ctx->method);
> + if (rc)
> + debug("HACE Scatter-Gather failure\n");
> +
> + free(ctx);
> +
> + return rc;
> +}
> +#endif
> +
> +static int aspeed_hace_probe(struct udevice *dev)
> +{
> + struct aspeed_hace *hace = dev_get_priv(dev);
> + int ret;
> +
> + ret = clk_get_by_index(dev, 0, &hace->clk);
> + if (ret < 0) {
> + debug("Can't get clock for %s: %d\n", dev->name, ret);
> + return ret;
> + }
> +
> + ret = clk_enable(&hace->clk);
> + if (ret) {
> + debug("Failed to enable fsi clock (%d)\n", ret);
> + return ret;
> + }
> +
> + /* As the crypto code does not pass us any driver state */
> + base = devfdt_get_addr(dev);
> +
> + return ret;
> +}
> +
> +static int aspeed_hace_remove(struct udevice *dev)
> +{
> + struct aspeed_hace *hace = dev_get_priv(dev);
> +
> + clk_disable(&hace->clk);
> +
> + return 0;
> +}
> +
> +static const struct udevice_id aspeed_hace_ids[] = {
> + { .compatible = "aspeed,ast2600-hace" },
> + { }
> +};
> +
> +U_BOOT_DRIVER(aspeed_hace) = {
> + .name = "aspeed_hace",
> + .id = UCLASS_MISC,
> + .of_match = aspeed_hace_ids,
> + .probe = aspeed_hace_probe,
> + .remove = aspeed_hace_remove,
> + .priv_auto_alloc_size = sizeof(struct aspeed_hace),
> + .flags = DM_FLAG_PRE_RELOC,
> +};
>
I've tested your patchset with Cedric's Aspeed-6.0 but looks
like the probe function is never called. Reading through the code
a bit more, looks like you need to explicitly probe this device
somewhere in board_init_r (that is, after sdram was initialized),
since functions like dm_scan_fdt() and dm_extended_scan_fdt() will
only scan subnodes of the top level, and the clocks node.
This is what I get (with some added printfs of mine):
qemu-system-arm: warning: Aspeed iBT has no chardev backend
qemu-system-arm: warning: nic ftgmac100.0 has no peer
qemu-system-arm: warning: nic ftgmac100.1 has no peer
qemu-system-arm: warning: nic ftgmac100.2 has no peer
qemu-system-arm: warning: nic ftgmac100.3 has no peer
aspeed_timer_ctrl_pulse_enable: Timer does not support pulse mode
aspeed_timer_ctrl_pulse_enable: Timer does not support pulse mode
aspeed_timer_ctrl_pulse_enable: Timer does not support pulse mode
aspeed_timer_ctrl_pulse_enable: Timer does not support pulse mode
aspeed_ast2600_scu_write: SCU is locked!
aspeed_ast2600_scu_write: SCU is locked!
aspeed_smc_write: not implemented: 0x18
U-Boot SPL 2019.04 (Apr 13 2021 - 17:57:20 +0000)
aspeed_soc.io: unimplemented device read (size 4, offset 0x0f500c)
aspeed_soc.io: unimplemented device write (size 4, offset 0x0f500c, value 0x00000000)
Trying to boot from MMC1
SD: CMD8 in a wrong state
## Checking hash(es) for Image uboot ... sha512,rsa4096:autogenerated-uboot-4096-key
digest_object: ASPEED_HACE_STS='0xe59ff03c'
digest_object: SCU080h='0xf7ff7f8a'
digest_object: writing '0x90200104' to ASPEED_HACE_HASH_SRC
digest_object: writing '0x902ffa50' to ASPEED_HACE_HASH_DIGEST_BUFF
digest_object: writing '0x0005ccd4' to ASPEED_HACE_HASH_DATA_LEN
digest_object: writing '0x00040068' to ASPEED_HACE_HASH_CMD
HACE Scatter-Gather failure
rsa_verify: Error in checksum calculation
- Failed to verify required signature 'key-autogenerated-uboot-4096-key'
error!
Unable to verify required signature for '' hash node in 'uboot' image node
mmc_load_image_raw_sector: mmc block read error
Trying to boot from UART
CCQEMU: Terminated
--
Klaus Heinrich Kiwi <klaus@linux.vnet.ibm.com>
next prev parent reply other threads:[~2021-04-13 20:41 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-04-13 8:07 [PATCH u-boot v2019.04-aspeed-openbmc 00/11] Use HACE to Joel Stanley
2021-04-13 8:07 ` [PATCH u-boot v2019.04-aspeed-openbmc 01/11] aspeed: Build secboot only when enabled Joel Stanley
2021-04-13 12:28 ` Klaus Heinrich Kiwi
2021-04-13 8:07 ` [PATCH u-boot v2019.04-aspeed-openbmc 02/11] ast2600: Specify boot order Joel Stanley
2021-04-14 11:17 ` Klaus Heinrich Kiwi
2021-04-13 8:07 ` [PATCH u-boot v2019.04-aspeed-openbmc 03/11] ast2600: Configure emmc boot options Joel Stanley
2021-04-13 8:07 ` [PATCH u-boot v2019.04-aspeed-openbmc 04/11] ast2600: spl: Support common boot devices Joel Stanley
2021-04-13 12:31 ` Klaus Heinrich Kiwi
2021-04-13 8:07 ` [PATCH u-boot v2019.04-aspeed-openbmc 05/11] config: ast2600: Enable common eMMC SPL loader Joel Stanley
2021-04-13 20:47 ` Klaus Heinrich Kiwi
2021-04-13 23:48 ` Joel Stanley
2021-04-13 8:07 ` [PATCH u-boot v2019.04-aspeed-openbmc 06/11] image-fit: use hashing infra Joel Stanley
2021-04-13 12:38 ` Klaus Heinrich Kiwi
2021-04-13 23:49 ` Joel Stanley
2021-04-13 8:07 ` [PATCH u-boot v2019.04-aspeed-openbmc 07/11] hash: Allow for SHA512 hardware implementations Joel Stanley
2021-04-13 12:51 ` Klaus Heinrich Kiwi
2021-04-13 8:07 ` [PATCH u-boot v2019.04-aspeed-openbmc 08/11] ast2600: Add HACE to device tree Joel Stanley
2021-04-13 20:43 ` Klaus Heinrich Kiwi
2021-04-13 8:07 ` [PATCH u-boot v2019.04-aspeed-openbmc 09/11] clk: aspeed: Add HACE yclk to ast2600 Joel Stanley
2021-04-13 20:42 ` Klaus Heinrich Kiwi
2021-04-13 8:07 ` [PATCH u-boot v2019.04-aspeed-openbmc 10/11] crypto: Add driver for Aspeed HACE Joel Stanley
2021-04-13 20:41 ` Klaus Heinrich Kiwi [this message]
2021-04-14 20:28 ` Klaus Heinrich Kiwi
2021-04-15 2:32 ` Joel Stanley
2021-04-15 21:37 ` Klaus Heinrich Kiwi
2021-04-19 12:49 ` Joel Stanley
2021-04-19 12:58 ` Klaus Heinrich Kiwi
2021-04-13 8:07 ` [PATCH u-boot v2019.04-aspeed-openbmc 11/11] configs/openbmc: Enable hw accelerated sha Joel Stanley
2021-04-13 20:42 ` Klaus Heinrich Kiwi
2021-04-14 21:03 ` Klaus Heinrich Kiwi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=cacf13c1-91b2-ad51-606e-bb208d13ec36@linux.vnet.ibm.com \
--to=klaus@linux.vnet.ibm.com \
--cc=andrew@aj.id.au \
--cc=clg@kaod.org \
--cc=joel@jms.id.au \
--cc=openbmc@lists.ozlabs.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).