snvs.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. /*
  2. * Copyright 2021 NXP
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. *
  6. */
  7. #include <stdint.h>
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <snvs.h>
  11. static uintptr_t g_nxp_snvs_addr;
  12. void snvs_init(uintptr_t nxp_snvs_addr)
  13. {
  14. g_nxp_snvs_addr = nxp_snvs_addr;
  15. }
  16. uint32_t get_snvs_state(void)
  17. {
  18. struct snvs_regs *snvs = (struct snvs_regs *) (g_nxp_snvs_addr);
  19. return (snvs_read32(&snvs->hp_stat) & HPSTS_MASK_SSM_ST);
  20. }
  21. static uint32_t do_snvs_state_transition(uint32_t state_transtion_bit,
  22. uint32_t target_state)
  23. {
  24. struct snvs_regs *snvs = (struct snvs_regs *) (g_nxp_snvs_addr);
  25. uint32_t sts = get_snvs_state();
  26. uint32_t fetch_cnt = 16U;
  27. uint32_t val = snvs_read32(&snvs->hp_com) | state_transtion_bit;
  28. snvs_write32(&snvs->hp_com, val);
  29. /* polling loop till SNVS is in target state */
  30. do {
  31. sts = get_snvs_state();
  32. } while ((sts != target_state) && ((--fetch_cnt) != 0));
  33. return sts;
  34. }
  35. void transition_snvs_non_secure(void)
  36. {
  37. struct snvs_regs *snvs = (struct snvs_regs *) (g_nxp_snvs_addr);
  38. uint32_t sts = get_snvs_state();
  39. switch (sts) {
  40. /* If initial state is check or Non-Secure, then
  41. * set the Software Security Violation Bit and
  42. * transition to Non-Secure State.
  43. */
  44. case HPSTS_CHECK_SSM_ST:
  45. sts = do_snvs_state_transition(HPCOM_SW_SV, HPSTS_NON_SECURE_SSM_ST);
  46. break;
  47. /* If initial state is Trusted, Secure or Soft-Fail, then
  48. * first set the Software Security Violation Bit and
  49. * transition to Soft-Fail State.
  50. */
  51. case HPSTS_TRUST_SSM_ST:
  52. case HPSTS_SECURE_SSM_ST:
  53. case HPSTS_SOFT_FAIL_SSM_ST:
  54. sts = do_snvs_state_transition(HPCOM_SW_SV, HPSTS_NON_SECURE_SSM_ST);
  55. /* If SSM Soft Fail to Non-Secure State Transition
  56. * Disable is not set, then set SSM_ST bit and
  57. * transition to Non-Secure State.
  58. */
  59. if ((snvs_read32(&snvs->hp_com) & HPCOM_SSM_SFNS_DIS) == 0) {
  60. sts = do_snvs_state_transition(HPCOM_SSM_ST, HPSTS_NON_SECURE_SSM_ST);
  61. }
  62. break;
  63. default:
  64. break;
  65. }
  66. }
  67. void transition_snvs_soft_fail(void)
  68. {
  69. do_snvs_state_transition(HPCOM_SW_FSV, HPSTS_SOFT_FAIL_SSM_ST);
  70. }
  71. uint32_t transition_snvs_trusted(void)
  72. {
  73. struct snvs_regs *snvs = (struct snvs_regs *) (g_nxp_snvs_addr);
  74. uint32_t sts = get_snvs_state();
  75. switch (sts) {
  76. /* If initial state is check, set the SSM_ST bit to
  77. * change the state to trusted.
  78. */
  79. case HPSTS_CHECK_SSM_ST:
  80. sts = do_snvs_state_transition(HPCOM_SSM_ST, HPSTS_TRUST_SSM_ST);
  81. break;
  82. /* If SSM Secure to Trusted State Transition Disable
  83. * is not set, then set SSM_ST bit and
  84. * transition to Trusted State.
  85. */
  86. case HPSTS_SECURE_SSM_ST:
  87. if ((snvs_read32(&snvs->hp_com) & HPCOM_SSM_ST_DIS) == 0) {
  88. sts = do_snvs_state_transition(HPCOM_SSM_ST, HPSTS_TRUST_SSM_ST);
  89. }
  90. break;
  91. /* If initial state is Soft-Fail or Non-Secure, then
  92. * transition to Trusted is not Possible.
  93. */
  94. default:
  95. break;
  96. }
  97. return sts;
  98. }
  99. uint32_t transition_snvs_secure(void)
  100. {
  101. uint32_t sts = get_snvs_state();
  102. if (sts == HPSTS_SECURE_SSM_ST) {
  103. return sts;
  104. }
  105. if (sts != HPSTS_TRUST_SSM_ST) {
  106. sts = transition_snvs_trusted();
  107. if (sts != HPSTS_TRUST_SSM_ST) {
  108. return sts;
  109. }
  110. }
  111. sts = do_snvs_state_transition(HPCOM_SSM_ST, HPSTS_TRUST_SSM_ST);
  112. return sts;
  113. }
  114. void snvs_write_lp_gpr_bit(uint32_t offset, uint32_t bit_pos, bool flag_val)
  115. {
  116. if (flag_val) {
  117. snvs_write32(g_nxp_snvs_addr + offset,
  118. (snvs_read32(g_nxp_snvs_addr + offset))
  119. | (1 << bit_pos));
  120. } else {
  121. snvs_write32(g_nxp_snvs_addr + offset,
  122. (snvs_read32(g_nxp_snvs_addr + offset))
  123. & ~(1 << bit_pos));
  124. }
  125. }
  126. uint32_t snvs_read_lp_gpr_bit(uint32_t offset, uint32_t bit_pos)
  127. {
  128. return (snvs_read32(g_nxp_snvs_addr + offset) & (1 << bit_pos));
  129. }
  130. void snvs_disable_zeroize_lp_gpr(void)
  131. {
  132. snvs_write_lp_gpr_bit(NXP_LPCR_OFFSET,
  133. NXP_GPR_Z_DIS_BIT,
  134. true);
  135. }
  136. #if defined(NXP_NV_SW_MAINT_LAST_EXEC_DATA) && defined(NXP_COINED_BB)
  137. void snvs_write_app_data_bit(uint32_t bit_pos)
  138. {
  139. snvs_write_lp_gpr_bit(NXP_APP_DATA_LP_GPR_OFFSET,
  140. bit_pos,
  141. true);
  142. }
  143. uint32_t snvs_read_app_data(void)
  144. {
  145. return snvs_read32(g_nxp_snvs_addr + NXP_APP_DATA_LP_GPR_OFFSET);
  146. }
  147. uint32_t snvs_read_app_data_bit(uint32_t bit_pos)
  148. {
  149. uint8_t ret = snvs_read_lp_gpr_bit(NXP_APP_DATA_LP_GPR_OFFSET, bit_pos);
  150. return ((ret != 0U) ? 1U : 0U);
  151. }
  152. void snvs_clear_app_data(void)
  153. {
  154. snvs_write32(g_nxp_snvs_addr + NXP_APP_DATA_LP_GPR_OFFSET, 0x0);
  155. }
  156. #endif