soc_se_trng.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. /*
  2. * Copyright (c) 2020 Actions Semiconductor Co., Ltd
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. /**
  7. * @file security engine trng for Actions SoC
  8. */
  9. #include <kernel.h>
  10. #include <device.h>
  11. #include <soc.h>
  12. #include <sys/printk.h>
  13. #include <drivers/se/se.h>
  14. static void se_init(void)
  15. {
  16. /* SE CLK = HOSC/1 */
  17. sys_write32((0 << 8) | (0 << 0), CMU_SECCLK);
  18. acts_clock_peripheral_enable(CLOCK_ID_SE);
  19. acts_reset_peripheral(RESET_ID_SE);
  20. }
  21. static int se_deinit(void)
  22. {
  23. uint32_t regval;
  24. /* rng/aes/crc/sha are all released, then SE module can be shut down */
  25. /* rng clk released or not */
  26. regval = sys_read32(TRNG_CTRL);
  27. if (regval & TRNG_CTRL_CLK_EN)
  28. return -EAGAIN;
  29. /* aes clk released or not */
  30. regval = sys_read32(AES_CTRL);
  31. if (regval & AES_CTRL_CLK_EN)
  32. return -EAGAIN;
  33. /* crc clk released or not */
  34. regval = sys_read32(CRC_CTRL);
  35. if (regval & CRC_CTRL_CLK_EN)
  36. return -EAGAIN;
  37. /* sha clk released or not */
  38. regval = sys_read32(SHA_CTRL);
  39. if (regval & SHA_CTRL_CLK_EN)
  40. return -EAGAIN;
  41. acts_clock_peripheral_disable(CLOCK_ID_SE);
  42. return 0;
  43. }
  44. /**
  45. * \brief IC inner true random number generator module init
  46. */
  47. int se_trng_init(void)
  48. {
  49. se_init();
  50. sys_write32((1 << 3), TRNG_CTRL);
  51. return 0;
  52. }
  53. /**
  54. * \brief IC inner true random number generator module deinit
  55. */
  56. int se_trng_deinit(void)
  57. {
  58. sys_write32(sys_read32(TRNG_CTRL) & ~(1 << 3), TRNG_CTRL);
  59. return se_deinit();
  60. }
  61. /**
  62. * \brief true random number generator use IC inner crc module
  63. *
  64. * \param trng_low true random number low 32bit
  65. * \param trng_high true random number high 32bit
  66. *
  67. * \return 0
  68. */
  69. uint32_t se_trng_process(uint32_t *trng_low, uint32_t *trng_high)
  70. {
  71. uint32_t trng_ctrl_value;
  72. trng_ctrl_value = sys_read32(TRNG_CTRL);
  73. trng_ctrl_value = (trng_ctrl_value & ~(0x03<<1)) | (0x0<<1); //TRNG Mode : OSC+LFSR
  74. trng_ctrl_value |= (1<<8)|(1<<9)|(1<<10); //OSC XOR mode, SAMPLE CLK MODE
  75. trng_ctrl_value = (trng_ctrl_value & ~(0x03<<6)) | (0x02<<6); //OSC Sample Low
  76. sys_write32(trng_ctrl_value, TRNG_CTRL);
  77. trng_ctrl_value |= (1<<0); //TRNG enable
  78. sys_write32(trng_ctrl_value, TRNG_CTRL);
  79. while ((sys_read32(TRNG_CTRL) & (1<<31)) == 0); //wait trng ready
  80. *trng_low = sys_read32(TRNG_LR);
  81. *trng_high = sys_read32(TRNG_MR);
  82. trng_ctrl_value = sys_read32(TRNG_CTRL);
  83. trng_ctrl_value &= ~(1<<0); //clear trng ready and finish trng
  84. sys_write32(trng_ctrl_value, TRNG_CTRL);
  85. return 0;
  86. }
  87. /* sample code, trng 64bit, 150us general one ramdom
  88. uint32_t trng_low, trng_high;
  89. int i;
  90. se_trng_init();
  91. for (i = 0; i < 8; i++) {
  92. se_trng_process(&trng_low, &trng_high);
  93. printk("ramdom %d : [0x%08x, 0x%08x] @ %d us\n", i + 1, trng_low, trng_high, BROM_TIMESTAMP_GET_US());
  94. }
  95. se_trng_deinit();
  96. */