aspeed_acry.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * Copyright 2021 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. /* 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. /* misc. constant */
  40. #define ACRY_ECC_MODE 2
  41. #define ACRY_RSA_MODE 3
  42. #define ACRY_CTX_BUFSZ 0x600
  43. struct aspeed_acry {
  44. phys_addr_t base;
  45. phys_addr_t sram_base; /* internal sram */
  46. struct clk clk;
  47. };
  48. static int aspeed_acry_mod_exp(struct udevice *dev, const uint8_t *sig, uint32_t sig_len,
  49. struct key_prop *prop, uint8_t *out)
  50. {
  51. int i, j;
  52. u8 *ctx;
  53. u8 *ptr;
  54. u32 reg;
  55. struct aspeed_acry *acry = dev_get_priv(dev);
  56. ctx = memalign(16, ACRY_CTX_BUFSZ);
  57. if (!ctx)
  58. return -ENOMEM;
  59. memset(ctx, 0, ACRY_CTX_BUFSZ);
  60. ptr = (u8 *)prop->public_exponent;
  61. for (i = prop->exp_len - 1, j = 0; i >= 0; --i) {
  62. ctx[j] = ptr[i];
  63. j++;
  64. j = (j % 16) ? j : j + 32;
  65. }
  66. ptr = (u8 *)prop->modulus;
  67. for (i = (prop->num_bits >> 3) - 1, j = 0; i >= 0; --i) {
  68. ctx[j + 16] = ptr[i];
  69. j++;
  70. j = (j % 16) ? j : j + 32;
  71. }
  72. ptr = (u8 *)sig;
  73. for (i = sig_len - 1, j = 0; i >= 0; --i) {
  74. ctx[j + 32] = ptr[i];
  75. j++;
  76. j = (j % 16) ? j : j + 32;
  77. }
  78. writel((u32)ctx, acry->base + ACRY_DMA_DRAM_SADDR);
  79. reg = (((prop->exp_len << 3) << ACRY_RSA_PARAM_EXP_SHIFT) & ACRY_RSA_PARAM_EXP_MASK) |
  80. ((prop->num_bits << ACRY_RSA_PARAM_MOD_SHIFT) & ACRY_RSA_PARAM_MOD_MASK);
  81. writel(reg, acry->base + ACRY_RSA_PARAM);
  82. reg = (ACRY_CTX_BUFSZ << ACRY_DMA_DMEM_TADDR_LEN_SHIFT) & ACRY_DMA_DMEM_TADDR_LEN_MASK;
  83. writel(reg, acry->base + ACRY_DMA_DMEM_TADDR);
  84. reg = (ACRY_RSA_MODE << ACRY_CTRL3_ECC_RSA_MODE_SHIFT) & ACRY_CTRL3_ECC_RSA_MODE_MASK;
  85. writel(reg, acry->base + ACRY_CTRL3);
  86. writel(ACRY_CTRL1_RSA_DMA | ACRY_CTRL1_RSA_START, acry->base + ACRY_CTRL1);
  87. /* polling RSA status */
  88. while (1) {
  89. reg = readl(acry->base + ACRY_RSA_INT_STS);
  90. if ((reg & ACRY_RSA_INT_STS_RSA_READY) && (reg & ACRY_RSA_INT_STS_RSA_CMPLT)) {
  91. writel(reg, acry->base + ACRY_RSA_INT_STS);
  92. break;
  93. }
  94. udelay(20);
  95. }
  96. /* grant SRAM access permission to CPU */
  97. writel(0x0, acry->base + ACRY_CTRL1);
  98. writel(ACRY_CTRL3_SRAM_AHB_ACCESS, acry->base + ACRY_CTRL3);
  99. udelay(20);
  100. for (i = (prop->num_bits / 8) - 1, j = 0; i >= 0; --i) {
  101. out[i] = readb(acry->sram_base + (j + 32));
  102. j++;
  103. j = (j % 16) ? j : j + 32;
  104. }
  105. /* return SRAM access permission to ACRY */
  106. writel(0, acry->base + ACRY_CTRL3);
  107. free(ctx);
  108. return 0;
  109. }
  110. static int aspeed_acry_probe(struct udevice *dev)
  111. {
  112. struct aspeed_acry *acry = dev_get_priv(dev);
  113. int ret;
  114. ret = clk_get_by_index(dev, 0, &acry->clk);
  115. if (ret < 0) {
  116. debug("Can't get clock for %s: %d\n", dev->name, ret);
  117. return ret;
  118. }
  119. ret = clk_enable(&acry->clk);
  120. if (ret) {
  121. debug("Failed to enable acry clock (%d)\n", ret);
  122. return ret;
  123. }
  124. acry->base = devfdt_get_addr_index(dev, 0);
  125. if (acry->base == FDT_ADDR_T_NONE) {
  126. debug("Failed to get acry base\n");
  127. return acry->base;
  128. }
  129. acry->sram_base = devfdt_get_addr_index(dev, 1);
  130. if (acry->sram_base == FDT_ADDR_T_NONE) {
  131. debug("Failed to get acry SRAM base\n");
  132. return acry->sram_base;
  133. }
  134. return ret;
  135. }
  136. static int aspeed_acry_remove(struct udevice *dev)
  137. {
  138. struct aspeed_acry *acry = dev_get_priv(dev);
  139. clk_disable(&acry->clk);
  140. return 0;
  141. }
  142. static const struct mod_exp_ops aspeed_acry_ops = {
  143. .mod_exp = aspeed_acry_mod_exp,
  144. };
  145. static const struct udevice_id aspeed_acry_ids[] = {
  146. { .compatible = "aspeed,ast2600-acry" },
  147. { }
  148. };
  149. U_BOOT_DRIVER(aspeed_acry) = {
  150. .name = "aspeed_acry",
  151. .id = UCLASS_MOD_EXP,
  152. .of_match = aspeed_acry_ids,
  153. .probe = aspeed_acry_probe,
  154. .remove = aspeed_acry_remove,
  155. .priv_auto = sizeof(struct aspeed_acry),
  156. .ops = &aspeed_acry_ops,
  157. .flags = DM_FLAG_PRE_RELOC,
  158. };