soc_se_trng.c 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  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. static void se_init(void)
  14. {
  15. /* SE CLK = HOSC/1 */
  16. sys_write32((0 << 8) | (0 << 0), CMU_SECCLK);
  17. acts_clock_peripheral_enable(CLOCK_ID_SE);
  18. acts_reset_peripheral(RESET_ID_SE);
  19. sys_write32((1 << 3), TRNG_CTRL);
  20. }
  21. static void se_deinit(void)
  22. {
  23. sys_write32(sys_read32(TRNG_CTRL) & ~(1 << 3), TRNG_CTRL);
  24. acts_clock_peripheral_disable(CLOCK_ID_SE);
  25. }
  26. /**
  27. * \brief IC inner true random number generator module init
  28. */
  29. int se_trng_init(void)
  30. {
  31. se_init();
  32. return 0;
  33. }
  34. /**
  35. * \brief IC inner true random number generator module deinit
  36. */
  37. int se_trng_deinit(void)
  38. {
  39. se_deinit();
  40. return 0;
  41. }
  42. /**
  43. * \brief true random number generator use IC inner crc module
  44. *
  45. * \param trng_low true random number low 32bit
  46. * \param trng_high true random number high 32bit
  47. *
  48. * \return 0
  49. */
  50. uint32_t se_trng_process(uint32_t *trng_low, uint32_t *trng_high)
  51. {
  52. uint32_t trng_ctrl_value;
  53. trng_ctrl_value = sys_read32(TRNG_CTRL);
  54. trng_ctrl_value = (trng_ctrl_value & ~(0x03<<1)) | (0x0<<1); //TRNG Mode : OSC+LFSR
  55. trng_ctrl_value |= (1<<8)|(1<<9)|(1<<10); //OSC XOR mode, SAMPLE CLK MODE
  56. trng_ctrl_value = (trng_ctrl_value & ~(0x03<<6)) | (0x02<<6); //OSC Sample Low
  57. sys_write32(trng_ctrl_value, TRNG_CTRL);
  58. trng_ctrl_value |= (1<<0); //TRNG enable
  59. sys_write32(trng_ctrl_value, TRNG_CTRL);
  60. while ((sys_read32(TRNG_CTRL) & (1<<31)) == 0); //wait trng ready
  61. *trng_low = sys_read32(TRNG_LR);
  62. *trng_high = sys_read32(TRNG_MR);
  63. trng_ctrl_value = sys_read32(TRNG_CTRL);
  64. trng_ctrl_value &= ~(1<<0); //clear trng ready and finish trng
  65. sys_write32(trng_ctrl_value, TRNG_CTRL);
  66. return 0;
  67. }
  68. /* sample code, trng 64bit, 150us general one ramdom
  69. uint32_t trng_low, trng_high;
  70. int i;
  71. se_trng_init();
  72. for (i = 0; i < 8; i++) {
  73. se_trng_process(&trng_low, &trng_high);
  74. printk("ramdom %d : [0x%08x, 0x%08x] @ %d us\n", i + 1, trng_low, trng_high, BROM_TIMESTAMP_GET_US());
  75. }
  76. se_trng_deinit();
  77. */