1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Copyright ASPEED Technology Inc. 4 */ 5 #include <config.h> 6 #include <common.h> 7 #include <clk.h> 8 #include <dm.h> 9 #include <asm/types.h> 10 #include <asm/io.h> 11 #include <dm/device.h> 12 #include <dm/fdtaddr.h> 13 #include <linux/delay.h> 14 #include <u-boot/rsa-mod-exp.h> 15 16 /* ACRY register offsets */ 17 #define ACRY_CTRL1 0x00 18 #define ACRY_CTRL1_RSA_DMA BIT(1) 19 #define ACRY_CTRL1_RSA_START BIT(0) 20 #define ACRY_CTRL2 0x44 21 #define ACRY_CTRL3 0x48 22 #define ACRY_CTRL3_SRAM_AHB_ACCESS BIT(8) 23 #define ACRY_CTRL3_ECC_RSA_MODE_MASK GENMASK(5, 4) 24 #define ACRY_CTRL3_ECC_RSA_MODE_SHIFT 4 25 #define ACRY_DMA_DRAM_SADDR 0x4c 26 #define ACRY_DMA_DMEM_TADDR 0x50 27 #define ACRY_DMA_DMEM_TADDR_LEN_MASK GENMASK(15, 0) 28 #define ACRY_DMA_DMEM_TADDR_LEN_SHIFT 0 29 #define ACRY_RSA_PARAM 0x58 30 #define ACRY_RSA_PARAM_EXP_MASK GENMASK(31, 16) 31 #define ACRY_RSA_PARAM_EXP_SHIFT 16 32 #define ACRY_RSA_PARAM_MOD_MASK GENMASK(15, 0) 33 #define ACRY_RSA_PARAM_MOD_SHIFT 0 34 #define ACRY_RSA_INT_EN 0x3f8 35 #define ACRY_RSA_INT_EN_RSA_READY BIT(2) 36 #define ACRY_RSA_INT_EN_RSA_CMPLT BIT(1) 37 #define ACRY_RSA_INT_STS 0x3fc 38 #define ACRY_RSA_INT_STS_RSA_READY BIT(2) 39 #define ACRY_RSA_INT_STS_RSA_CMPLT BIT(1) 40 41 /* misc. constant */ 42 #define ACRY_ECC_MODE 2 43 #define ACRY_RSA_MODE 3 44 #define ACRY_CTX_BUFSZ 0x600 45 46 struct aspeed_acry { 47 phys_addr_t base; 48 phys_addr_t sram_base; /* internal sram */ 49 struct clk clk; 50 }; 51 52 static int aspeed_acry_mod_exp(struct udevice *dev, const uint8_t *sig, uint32_t sig_len, 53 struct key_prop *prop, uint8_t *out) 54 { 55 int i, j; 56 u8 *ctx; 57 u8 *ptr; 58 u32 reg; 59 struct aspeed_acry *acry = dev_get_priv(dev); 60 61 ctx = memalign(16, ACRY_CTX_BUFSZ); 62 if (!ctx) 63 return -ENOMEM; 64 65 memset(ctx, 0, ACRY_CTX_BUFSZ); 66 67 ptr = (u8 *)prop->public_exponent; 68 for (i = prop->exp_len - 1, j = 0; i >= 0; --i) { 69 ctx[j] = ptr[i]; 70 j++; 71 j = (j % 16) ? j : j + 32; 72 } 73 74 ptr = (u8 *)prop->modulus; 75 for (i = (prop->num_bits >> 3) - 1, j = 0; i >= 0; --i) { 76 ctx[j + 16] = ptr[i]; 77 j++; 78 j = (j % 16) ? j : j + 32; 79 } 80 81 ptr = (u8 *)sig; 82 for (i = sig_len - 1, j = 0; i >= 0; --i) { 83 ctx[j + 32] = ptr[i]; 84 j++; 85 j = (j % 16) ? j : j + 32; 86 } 87 88 writel((u32)ctx, acry->base + ACRY_DMA_DRAM_SADDR); 89 90 reg = (((prop->exp_len << 3) << ACRY_RSA_PARAM_EXP_SHIFT) & ACRY_RSA_PARAM_EXP_MASK) | 91 ((prop->num_bits << ACRY_RSA_PARAM_MOD_SHIFT) & ACRY_RSA_PARAM_MOD_MASK); 92 writel(reg, acry->base + ACRY_RSA_PARAM); 93 94 reg = (ACRY_CTX_BUFSZ << ACRY_DMA_DMEM_TADDR_LEN_SHIFT) & ACRY_DMA_DMEM_TADDR_LEN_MASK; 95 writel(reg, acry->base + ACRY_DMA_DMEM_TADDR); 96 97 reg = (ACRY_RSA_MODE << ACRY_CTRL3_ECC_RSA_MODE_SHIFT) & ACRY_CTRL3_ECC_RSA_MODE_MASK; 98 writel(reg, acry->base + ACRY_CTRL3); 99 100 writel(ACRY_CTRL1_RSA_DMA | ACRY_CTRL1_RSA_START, acry->base + ACRY_CTRL1); 101 102 /* polling RSA status */ 103 while (1) { 104 reg = readl(acry->base + ACRY_RSA_INT_STS); 105 if ((reg & ACRY_RSA_INT_STS_RSA_READY) && (reg & ACRY_RSA_INT_STS_RSA_CMPLT)) { 106 writel(reg, acry->base + ACRY_RSA_INT_STS); 107 break; 108 } 109 udelay(20); 110 } 111 112 /* grant SRAM access permission to CPU */ 113 writel(0x0, acry->base + ACRY_CTRL1); 114 writel(ACRY_CTRL3_SRAM_AHB_ACCESS, acry->base + ACRY_CTRL3); 115 udelay(20); 116 117 for (i = (prop->num_bits / 8) - 1, j = 0; i >= 0; --i) { 118 out[i] = readb(acry->sram_base + (j + 32)); 119 j++; 120 j = (j % 16) ? j : j + 32; 121 } 122 123 free(ctx); 124 125 return 0; 126 } 127 128 static int aspeed_acry_probe(struct udevice *dev) 129 { 130 struct aspeed_acry *acry = dev_get_priv(dev); 131 int ret; 132 133 ret = clk_get_by_index(dev, 0, &acry->clk); 134 if (ret < 0) { 135 debug("Can't get clock for %s: %d\n", dev->name, ret); 136 return ret; 137 } 138 139 ret = clk_enable(&acry->clk); 140 if (ret) { 141 debug("Failed to enable acry clock (%d)\n", ret); 142 return ret; 143 } 144 145 acry->base = devfdt_get_addr_index(dev, 0); 146 if (acry->base == FDT_ADDR_T_NONE) { 147 debug("Failed to get acry base\n"); 148 return acry->base; 149 } 150 151 acry->sram_base = devfdt_get_addr_index(dev, 1); 152 if (acry->sram_base == FDT_ADDR_T_NONE) { 153 debug("Failed to get acry SRAM base\n"); 154 return acry->sram_base; 155 } 156 157 /* grant SRAM access permission to CPU */ 158 writel(ACRY_CTRL3_SRAM_AHB_ACCESS, acry->base + ACRY_CTRL3); 159 160 return ret; 161 } 162 163 static int aspeed_acry_remove(struct udevice *dev) 164 { 165 struct aspeed_acry *acry = dev_get_priv(dev); 166 167 clk_disable(&acry->clk); 168 169 return 0; 170 } 171 172 static const struct mod_exp_ops aspeed_acry_ops = { 173 .mod_exp = aspeed_acry_mod_exp, 174 }; 175 176 static const struct udevice_id aspeed_acry_ids[] = { 177 { .compatible = "aspeed,ast2600-acry" }, 178 { } 179 }; 180 181 U_BOOT_DRIVER(aspeed_acry) = { 182 .name = "aspeed_acry", 183 .id = UCLASS_MOD_EXP, 184 .of_match = aspeed_acry_ids, 185 .probe = aspeed_acry_probe, 186 .remove = aspeed_acry_remove, 187 .priv_auto_alloc_size = sizeof(struct aspeed_acry), 188 .ops = &aspeed_acry_ops, 189 .flags = DM_FLAG_PRE_RELOC, 190 }; 191