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