fsl_sec_mon.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright 2015 Freescale Semiconductor, Inc.
  4. */
  5. #include <common.h>
  6. #include <fsl_sec_mon.h>
  7. #include <linux/delay.h>
  8. static u32 get_sec_mon_state(void)
  9. {
  10. struct ccsr_sec_mon_regs *sec_mon_regs = (void *)
  11. (CONFIG_SYS_SEC_MON_ADDR);
  12. return sec_mon_in32(&sec_mon_regs->hp_stat) & HPSR_SSM_ST_MASK;
  13. }
  14. static int set_sec_mon_state_non_sec(void)
  15. {
  16. u32 sts;
  17. int timeout = 10;
  18. struct ccsr_sec_mon_regs *sec_mon_regs = (void *)
  19. (CONFIG_SYS_SEC_MON_ADDR);
  20. sts = get_sec_mon_state();
  21. switch (sts) {
  22. /*
  23. * If initial state is check or Non-Secure, then set the Software
  24. * Security Violation Bit and transition to Non-Secure State.
  25. */
  26. case HPSR_SSM_ST_CHECK:
  27. printf("SEC_MON state transitioning to Non Secure.\n");
  28. sec_mon_setbits32(&sec_mon_regs->hp_com, HPCOMR_SW_SV);
  29. /* polling loop till SEC_MON is in Non Secure state */
  30. while (timeout) {
  31. sts = get_sec_mon_state();
  32. if ((sts & HPSR_SSM_ST_MASK) ==
  33. HPSR_SSM_ST_NON_SECURE)
  34. break;
  35. udelay(10);
  36. timeout--;
  37. }
  38. if (timeout == 0) {
  39. printf("SEC_MON state transition timeout.\n");
  40. return -1;
  41. }
  42. break;
  43. /*
  44. * If initial state is Trusted, Secure or Soft-Fail, then first set
  45. * the Software Security Violation Bit and transition to Soft-Fail
  46. * State.
  47. */
  48. case HPSR_SSM_ST_TRUST:
  49. case HPSR_SSM_ST_SECURE:
  50. case HPSR_SSM_ST_SOFT_FAIL:
  51. printf("SEC_MON state transitioning to Soft Fail.\n");
  52. sec_mon_setbits32(&sec_mon_regs->hp_com, HPCOMR_SW_SV);
  53. /* polling loop till SEC_MON is in Soft-Fail state */
  54. while (timeout) {
  55. sts = get_sec_mon_state();
  56. if ((sts & HPSR_SSM_ST_MASK) ==
  57. HPSR_SSM_ST_SOFT_FAIL)
  58. break;
  59. udelay(10);
  60. timeout--;
  61. }
  62. if (timeout == 0) {
  63. printf("SEC_MON state transition timeout.\n");
  64. return -1;
  65. }
  66. timeout = 10;
  67. /*
  68. * If SSM Soft Fail to Non-Secure State Transition
  69. * disable is not set, then set SSM_ST bit and
  70. * transition to Non-Secure State.
  71. */
  72. if ((sec_mon_in32(&sec_mon_regs->hp_com) &
  73. HPCOMR_SSM_SFNS_DIS) == 0) {
  74. printf("SEC_MON state transitioning to Non Secure.\n");
  75. sec_mon_setbits32(&sec_mon_regs->hp_com, HPCOMR_SSM_ST);
  76. /* polling loop till SEC_MON is in Non Secure*/
  77. while (timeout) {
  78. sts = get_sec_mon_state();
  79. if ((sts & HPSR_SSM_ST_MASK) ==
  80. HPSR_SSM_ST_NON_SECURE)
  81. break;
  82. udelay(10);
  83. timeout--;
  84. }
  85. if (timeout == 0) {
  86. printf("SEC_MON state transition timeout.\n");
  87. return -1;
  88. }
  89. }
  90. break;
  91. default:
  92. printf("SEC_MON already in Non Secure state.\n");
  93. return 0;
  94. }
  95. return 0;
  96. }
  97. static int set_sec_mon_state_soft_fail(void)
  98. {
  99. u32 sts;
  100. int timeout = 10;
  101. struct ccsr_sec_mon_regs *sec_mon_regs = (void *)
  102. (CONFIG_SYS_SEC_MON_ADDR);
  103. printf("SEC_MON state transitioning to Soft Fail.\n");
  104. sec_mon_setbits32(&sec_mon_regs->hp_com, HPCOMR_SW_FSV);
  105. /* polling loop till SEC_MON is in Soft-Fail state */
  106. while (timeout) {
  107. sts = get_sec_mon_state();
  108. if ((sts & HPSR_SSM_ST_MASK) ==
  109. HPSR_SSM_ST_SOFT_FAIL)
  110. break;
  111. udelay(10);
  112. timeout--;
  113. }
  114. if (timeout == 0) {
  115. printf("SEC_MON state transition timeout.\n");
  116. return -1;
  117. }
  118. return 0;
  119. }
  120. int set_sec_mon_state(u32 state)
  121. {
  122. int ret = -1;
  123. switch (state) {
  124. case HPSR_SSM_ST_NON_SECURE:
  125. ret = set_sec_mon_state_non_sec();
  126. break;
  127. case HPSR_SSM_ST_SOFT_FAIL:
  128. ret = set_sec_mon_state_soft_fail();
  129. break;
  130. default:
  131. printf("SEC_MON state transition not supported.\n");
  132. return 0;
  133. }
  134. return ret;
  135. }