1 /* 2 * (C) Copyright ASPEED Technology Inc. 3 * Copyright 2021 IBM Corp. 4 * 5 * SPDX-License-Identifier: GPL-2.0-or-later 6 */ 7 8 #include <common.h> 9 #include <clk.h> 10 11 #include <log.h> 12 #include <asm/io.h> 13 #include <malloc.h> 14 #include <hash.h> 15 16 #include <dm/device.h> 17 #include <dm/fdtaddr.h> 18 19 #include <linux/bitops.h> 20 #include <linux/delay.h> 21 #include <linux/kernel.h> 22 #include <linux/iopoll.h> 23 24 #define ASPEED_HACE_STS 0x1C 25 #define HACE_RSA_ISR BIT(13) 26 #define HACE_CRYPTO_ISR BIT(12) 27 #define HACE_HASH_ISR BIT(9) 28 #define HACE_RSA_BUSY BIT(2) 29 #define HACE_CRYPTO_BUSY BIT(1) 30 #define HACE_HASH_BUSY BIT(0) 31 #define ASPEED_HACE_HASH_SRC 0x20 32 #define ASPEED_HACE_HASH_DIGEST_BUFF 0x24 33 #define ASPEED_HACE_HASH_KEY_BUFF 0x28 34 #define ASPEED_HACE_HASH_DATA_LEN 0x2C 35 #define HACE_SG_LAST BIT(31) 36 #define ASPEED_HACE_HASH_CMD 0x30 37 #define HACE_SHA_BE_EN BIT(3) 38 #define HACE_MD5_LE_EN BIT(2) 39 #define HACE_ALGO_MD5 0 40 #define HACE_ALGO_SHA1 BIT(5) 41 #define HACE_ALGO_SHA224 BIT(6) 42 #define HACE_ALGO_SHA256 (BIT(4) | BIT(6)) 43 #define HACE_ALGO_SHA512 (BIT(5) | BIT(6)) 44 #define HACE_ALGO_SHA384 (BIT(5) | BIT(6) | BIT(10)) 45 #define HACE_SG_EN BIT(18) 46 47 #define ASPEED_MAX_SG 32 48 49 struct aspeed_sg { 50 u32 len; 51 u32 addr; 52 }; 53 54 struct aspeed_hash_ctx { 55 u32 method; 56 u32 digest_size; 57 u32 len; 58 u32 count; 59 struct aspeed_sg list[ASPEED_MAX_SG]; /* Must be 8 byte aligned */ 60 }; 61 62 struct aspeed_hace { 63 struct clk clk; 64 }; 65 66 static phys_addr_t base; 67 68 static int aspeed_hace_wait_completion(u32 reg, u32 flag, int timeout_us) 69 { 70 u32 val; 71 72 return readl_poll_timeout(reg, val, (val & flag) == flag, timeout_us); 73 } 74 75 static int digest_object(const void *src, unsigned int length, void *digest, 76 u32 method) 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 89 if (readl(base + ASPEED_HACE_STS) & HACE_HASH_BUSY) { 90 debug("HACE error: engine busy\n"); 91 return -EBUSY; 92 } 93 94 /* Clear pending completion status */ 95 writel(HACE_HASH_ISR, base + ASPEED_HACE_STS); 96 97 writel((u32)src, base + ASPEED_HACE_HASH_SRC); 98 writel((u32)digest, base + ASPEED_HACE_HASH_DIGEST_BUFF); 99 writel(length, base + ASPEED_HACE_HASH_DATA_LEN); 100 writel(HACE_SHA_BE_EN | method, base + ASPEED_HACE_HASH_CMD); 101 102 /* SHA512 hashing appears to have a througput of about 12MB/s */ 103 aspeed_hace_wait_completion(base + ASPEED_HACE_STS, 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 0; 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 } 166 else if (!strcmp(algo->name, "sha256")) { 167 method = HACE_ALGO_SHA256; 168 } 169 else if (!strcmp(algo->name, "sha512")) { 170 method = HACE_ALGO_SHA512; 171 } 172 else { 173 return -ENOTSUPP; 174 } 175 176 ctx = memalign(8, sizeof(*ctx)); 177 memset(ctx, '\0', sizeof(*ctx)); 178 179 if (ctx == NULL) { 180 debug("HACE error: Cannot allocate memory for context\n"); 181 return -ENOMEM; 182 } 183 184 if (((uintptr_t)ctx->list & 0x3) != 0) { 185 printf("HACE error: Invalid alignment for input data\n"); 186 return -EINVAL; 187 } 188 189 ctx->method = method | HACE_SG_EN; 190 ctx->digest_size = algo->digest_size; 191 *ctxp = ctx; 192 193 return 0; 194 } 195 196 int hw_sha_update(struct hash_algo *algo, void *hash_ctx, const void *buf, 197 unsigned int size, int is_last) 198 { 199 struct aspeed_hash_ctx *ctx = hash_ctx; 200 struct aspeed_sg *sg = &ctx->list[ctx->count]; 201 202 if (ctx->count >= ARRAY_SIZE(ctx->list)) { 203 debug("HACE error: Reached maximum number of hash segments\n"); 204 free(ctx); 205 return -EINVAL; 206 } 207 208 sg->addr = (u32)buf; 209 sg->len = size; 210 if (is_last) 211 sg->len |= HACE_SG_LAST; 212 213 ctx->count++; 214 ctx->len += size; 215 216 return 0; 217 } 218 219 int hw_sha_finish(struct hash_algo *algo, void *hash_ctx, void *dest_buf, int size) 220 { 221 struct aspeed_hash_ctx *ctx = hash_ctx; 222 int rc; 223 224 if (size < ctx->digest_size) { 225 debug("HACE error: insufficient size on destination buffer\n"); 226 free(ctx); 227 return -EINVAL; 228 } 229 230 rc = digest_object(ctx->list, ctx->len, dest_buf, ctx->method); 231 if (rc) 232 debug("HACE Scatter-Gather failure\n"); 233 234 free(ctx); 235 236 return rc; 237 } 238 #endif 239 240 static int aspeed_hace_probe(struct udevice *dev) 241 { 242 struct aspeed_hace *hace = dev_get_priv(dev); 243 int ret; 244 245 ret = clk_get_by_index(dev, 0, &hace->clk); 246 if (ret < 0) { 247 debug("Can't get clock for %s: %d\n", dev->name, ret); 248 return ret; 249 } 250 251 ret = clk_enable(&hace->clk); 252 if (ret) { 253 debug("Failed to enable fsi clock (%d)\n", ret); 254 return ret; 255 } 256 257 /* As the crypto code does not pass us any driver state */ 258 base = devfdt_get_addr(dev); 259 260 return ret; 261 } 262 263 static int aspeed_hace_remove(struct udevice *dev) 264 { 265 struct aspeed_hace *hace = dev_get_priv(dev); 266 267 clk_disable(&hace->clk); 268 269 return 0; 270 } 271 272 static const struct udevice_id aspeed_hace_ids[] = { 273 { .compatible = "aspeed,ast2600-hace" }, 274 { } 275 }; 276 277 U_BOOT_DRIVER(aspeed_hace) = { 278 .name = "aspeed_hace", 279 .id = UCLASS_MISC, 280 .of_match = aspeed_hace_ids, 281 .probe = aspeed_hace_probe, 282 .remove = aspeed_hace_remove, 283 .priv_auto_alloc_size = sizeof(struct aspeed_hace), 284 .flags = DM_FLAG_PRE_RELOC, 285 }; 286