1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * (C) Copyright ASPEED Technology Inc. 4 * Copyright 2021 IBM Corp. 5 */ 6 #include <common.h> 7 #include <clk.h> 8 9 #include <log.h> 10 #include <asm/io.h> 11 #include <malloc.h> 12 #include <hash.h> 13 14 #include <dm/device.h> 15 #include <dm/fdtaddr.h> 16 17 #include <linux/bitops.h> 18 #include <linux/delay.h> 19 #include <linux/kernel.h> 20 #include <linux/iopoll.h> 21 22 #define ASPEED_HACE_STS 0x1C 23 #define HACE_RSA_ISR BIT(13) 24 #define HACE_CRYPTO_ISR BIT(12) 25 #define HACE_HASH_ISR BIT(9) 26 #define HACE_RSA_BUSY BIT(2) 27 #define HACE_CRYPTO_BUSY BIT(1) 28 #define HACE_HASH_BUSY BIT(0) 29 #define ASPEED_HACE_HASH_SRC 0x20 30 #define ASPEED_HACE_HASH_DIGEST_BUFF 0x24 31 #define ASPEED_HACE_HASH_KEY_BUFF 0x28 32 #define ASPEED_HACE_HASH_DATA_LEN 0x2C 33 #define HACE_SG_LAST BIT(31) 34 #define ASPEED_HACE_HASH_CMD 0x30 35 #define HACE_SHA_BE_EN BIT(3) 36 #define HACE_MD5_LE_EN BIT(2) 37 #define HACE_ALGO_MD5 0 38 #define HACE_ALGO_SHA1 BIT(5) 39 #define HACE_ALGO_SHA224 BIT(6) 40 #define HACE_ALGO_SHA256 (BIT(4) | BIT(6)) 41 #define HACE_ALGO_SHA512 (BIT(5) | BIT(6)) 42 #define HACE_ALGO_SHA384 (BIT(5) | BIT(6) | BIT(10)) 43 #define HACE_SG_EN BIT(18) 44 45 #define ASPEED_MAX_SG 32 46 47 struct aspeed_sg { 48 u32 len; 49 u32 addr; 50 }; 51 52 struct aspeed_hash_ctx { 53 u32 method; 54 u32 digest_size; 55 u32 len; 56 u32 count; 57 struct aspeed_sg list[ASPEED_MAX_SG]; /* Must be 8 byte aligned */ 58 }; 59 60 struct aspeed_hace { 61 struct clk clk; 62 }; 63 64 static phys_addr_t base; 65 66 static int aspeed_hace_wait_completion(u32 reg, u32 flag, int timeout_us) 67 { 68 u32 val; 69 70 return readl_poll_timeout(reg, val, (val & flag) == flag, timeout_us); 71 } 72 73 static int digest_object(const void *src, unsigned int length, void *digest, 74 u32 method) 75 { 76 int rc; 77 78 if (!((u32)src & BIT(31))) { 79 debug("HACE src out of bounds: can only copy from SDRAM\n"); 80 return -EINVAL; 81 } 82 83 if ((u32)digest & 0x7) { 84 debug("HACE dest alignment incorrect: %p\n", digest); 85 return -EINVAL; 86 } 87 88 if (readl(base + ASPEED_HACE_STS) & HACE_HASH_BUSY) { 89 debug("HACE error: engine busy\n"); 90 return -EBUSY; 91 } 92 93 /* Clear pending completion status */ 94 writel(HACE_HASH_ISR, base + ASPEED_HACE_STS); 95 96 writel((u32)src, base + ASPEED_HACE_HASH_SRC); 97 writel((u32)digest, base + ASPEED_HACE_HASH_DIGEST_BUFF); 98 writel(length, base + ASPEED_HACE_HASH_DATA_LEN); 99 writel(HACE_SHA_BE_EN | method, base + ASPEED_HACE_HASH_CMD); 100 101 /* SHA512 hashing appears to have a througput of about 12MB/s */ 102 rc = aspeed_hace_wait_completion(base + ASPEED_HACE_STS, 103 HACE_HASH_ISR, 104 1000 + (length >> 3)); 105 106 if (readl(base + ASPEED_HACE_STS)) { 107 debug("\nHACE error 0x%08x, resetting\n", readl(base + 0x1c)); 108 109 writel(0x10, 0x1e6e2040); 110 mdelay(5); 111 writel(0x10, 0x1e6e2044); 112 } 113 114 return rc; 115 } 116 117 void hw_sha1(const unsigned char *pbuf, unsigned int buf_len, 118 unsigned char *pout, unsigned int chunk_size) 119 { 120 int rc; 121 122 rc = digest_object(pbuf, buf_len, pout, HACE_ALGO_SHA1); 123 if (rc) 124 debug("HACE failure: %d\n", rc); 125 } 126 127 void hw_sha256(const unsigned char *pbuf, unsigned int buf_len, 128 unsigned char *pout, unsigned int chunk_size) 129 { 130 int rc; 131 132 rc = digest_object(pbuf, buf_len, pout, HACE_ALGO_SHA256); 133 if (rc) 134 debug("HACE failure: %d\n", rc); 135 } 136 137 void hw_sha384(const unsigned char *pbuf, unsigned int buf_len, 138 unsigned char *pout, unsigned int chunk_size) 139 { 140 int rc; 141 142 rc = digest_object(pbuf, buf_len, pout, HACE_ALGO_SHA384); 143 if (rc) 144 debug("HACE failure: %d\n", rc); 145 } 146 147 void hw_sha512(const unsigned char *pbuf, unsigned int buf_len, 148 unsigned char *pout, unsigned int chunk_size) 149 { 150 int rc; 151 152 rc = digest_object(pbuf, buf_len, pout, HACE_ALGO_SHA512); 153 if (rc) 154 debug("HACE failure: %d\n", rc); 155 } 156 157 #if IS_ENABLED(CONFIG_SHA_PROG_HW_ACCEL) 158 int hw_sha_init(struct hash_algo *algo, void **ctxp) 159 { 160 struct aspeed_hash_ctx *ctx; 161 u32 method; 162 163 if (!strcmp(algo->name, "sha1")) 164 method = HACE_ALGO_SHA1; 165 else if (!strcmp(algo->name, "sha256")) 166 method = HACE_ALGO_SHA256; 167 else if (!strcmp(algo->name, "sha384")) 168 method = HACE_ALGO_SHA384; 169 else if (!strcmp(algo->name, "sha512")) 170 method = HACE_ALGO_SHA512; 171 else 172 return -ENOTSUPP; 173 174 ctx = memalign(8, sizeof(*ctx)); 175 memset(ctx, '\0', sizeof(*ctx)); 176 177 if (!ctx) { 178 debug("HACE error: Cannot allocate memory for context\n"); 179 return -ENOMEM; 180 } 181 182 if (((uintptr_t)ctx->list & 0x3) != 0) { 183 printf("HACE error: Invalid alignment for input data\n"); 184 return -EINVAL; 185 } 186 187 ctx->method = method | HACE_SG_EN; 188 ctx->digest_size = algo->digest_size; 189 *ctxp = ctx; 190 191 return 0; 192 } 193 194 int hw_sha_update(struct hash_algo *algo, void *hash_ctx, const void *buf, 195 unsigned int size, int is_last) 196 { 197 struct aspeed_hash_ctx *ctx = hash_ctx; 198 struct aspeed_sg *sg = &ctx->list[ctx->count]; 199 200 if (ctx->count >= ARRAY_SIZE(ctx->list)) { 201 debug("HACE error: Reached maximum number of hash segments\n"); 202 free(ctx); 203 return -EINVAL; 204 } 205 206 sg->addr = (u32)buf; 207 sg->len = size; 208 if (is_last) 209 sg->len |= HACE_SG_LAST; 210 211 ctx->count++; 212 ctx->len += size; 213 214 return 0; 215 } 216 217 int hw_sha_finish(struct hash_algo *algo, void *hash_ctx, void *dest_buf, int size) 218 { 219 struct aspeed_hash_ctx *ctx = hash_ctx; 220 int rc; 221 222 if (size < ctx->digest_size) { 223 debug("HACE error: insufficient size on destination buffer\n"); 224 free(ctx); 225 return -EINVAL; 226 } 227 228 rc = digest_object(ctx->list, ctx->len, dest_buf, ctx->method); 229 if (rc) 230 debug("HACE Scatter-Gather failure\n"); 231 232 free(ctx); 233 234 return rc; 235 } 236 #endif 237 238 static int aspeed_hace_probe(struct udevice *dev) 239 { 240 struct aspeed_hace *hace = dev_get_priv(dev); 241 int ret; 242 243 ret = clk_get_by_index(dev, 0, &hace->clk); 244 if (ret < 0) { 245 debug("Can't get clock for %s: %d\n", dev->name, ret); 246 return ret; 247 } 248 249 ret = clk_enable(&hace->clk); 250 if (ret) { 251 debug("Failed to enable fsi clock (%d)\n", ret); 252 return ret; 253 } 254 255 /* As the crypto code does not pass us any driver state */ 256 base = devfdt_get_addr(dev); 257 258 return ret; 259 } 260 261 static int aspeed_hace_remove(struct udevice *dev) 262 { 263 struct aspeed_hace *hace = dev_get_priv(dev); 264 265 clk_disable(&hace->clk); 266 267 return 0; 268 } 269 270 static const struct udevice_id aspeed_hace_ids[] = { 271 { .compatible = "aspeed,ast2600-hace" }, 272 { } 273 }; 274 275 U_BOOT_DRIVER(aspeed_hace) = { 276 .name = "aspeed_hace", 277 .id = UCLASS_MISC, 278 .of_match = aspeed_hace_ids, 279 .probe = aspeed_hace_probe, 280 .remove = aspeed_hace_remove, 281 .priv_auto_alloc_size = sizeof(struct aspeed_hace), 282 .flags = DM_FLAG_PRE_RELOC, 283 }; 284