123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186 |
- /*
- * Copyright 2021 NXP
- *
- * SPDX-License-Identifier: BSD-3-Clause
- *
- */
- #include <stdint.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <snvs.h>
- static uintptr_t g_nxp_snvs_addr;
- void snvs_init(uintptr_t nxp_snvs_addr)
- {
- g_nxp_snvs_addr = nxp_snvs_addr;
- }
- uint32_t get_snvs_state(void)
- {
- struct snvs_regs *snvs = (struct snvs_regs *) (g_nxp_snvs_addr);
- return (snvs_read32(&snvs->hp_stat) & HPSTS_MASK_SSM_ST);
- }
- static uint32_t do_snvs_state_transition(uint32_t state_transtion_bit,
- uint32_t target_state)
- {
- struct snvs_regs *snvs = (struct snvs_regs *) (g_nxp_snvs_addr);
- uint32_t sts = get_snvs_state();
- uint32_t fetch_cnt = 16U;
- uint32_t val = snvs_read32(&snvs->hp_com) | state_transtion_bit;
- snvs_write32(&snvs->hp_com, val);
- /* polling loop till SNVS is in target state */
- do {
- sts = get_snvs_state();
- } while ((sts != target_state) && ((--fetch_cnt) != 0));
- return sts;
- }
- void transition_snvs_non_secure(void)
- {
- struct snvs_regs *snvs = (struct snvs_regs *) (g_nxp_snvs_addr);
- uint32_t sts = get_snvs_state();
- switch (sts) {
- /* If initial state is check or Non-Secure, then
- * set the Software Security Violation Bit and
- * transition to Non-Secure State.
- */
- case HPSTS_CHECK_SSM_ST:
- sts = do_snvs_state_transition(HPCOM_SW_SV, HPSTS_NON_SECURE_SSM_ST);
- break;
- /* If initial state is Trusted, Secure or Soft-Fail, then
- * first set the Software Security Violation Bit and
- * transition to Soft-Fail State.
- */
- case HPSTS_TRUST_SSM_ST:
- case HPSTS_SECURE_SSM_ST:
- case HPSTS_SOFT_FAIL_SSM_ST:
- sts = do_snvs_state_transition(HPCOM_SW_SV, HPSTS_NON_SECURE_SSM_ST);
- /* If SSM Soft Fail to Non-Secure State Transition
- * Disable is not set, then set SSM_ST bit and
- * transition to Non-Secure State.
- */
- if ((snvs_read32(&snvs->hp_com) & HPCOM_SSM_SFNS_DIS) == 0) {
- sts = do_snvs_state_transition(HPCOM_SSM_ST, HPSTS_NON_SECURE_SSM_ST);
- }
- break;
- default:
- break;
- }
- }
- void transition_snvs_soft_fail(void)
- {
- do_snvs_state_transition(HPCOM_SW_FSV, HPSTS_SOFT_FAIL_SSM_ST);
- }
- uint32_t transition_snvs_trusted(void)
- {
- struct snvs_regs *snvs = (struct snvs_regs *) (g_nxp_snvs_addr);
- uint32_t sts = get_snvs_state();
- switch (sts) {
- /* If initial state is check, set the SSM_ST bit to
- * change the state to trusted.
- */
- case HPSTS_CHECK_SSM_ST:
- sts = do_snvs_state_transition(HPCOM_SSM_ST, HPSTS_TRUST_SSM_ST);
- break;
- /* If SSM Secure to Trusted State Transition Disable
- * is not set, then set SSM_ST bit and
- * transition to Trusted State.
- */
- case HPSTS_SECURE_SSM_ST:
- if ((snvs_read32(&snvs->hp_com) & HPCOM_SSM_ST_DIS) == 0) {
- sts = do_snvs_state_transition(HPCOM_SSM_ST, HPSTS_TRUST_SSM_ST);
- }
- break;
- /* If initial state is Soft-Fail or Non-Secure, then
- * transition to Trusted is not Possible.
- */
- default:
- break;
- }
- return sts;
- }
- uint32_t transition_snvs_secure(void)
- {
- uint32_t sts = get_snvs_state();
- if (sts == HPSTS_SECURE_SSM_ST) {
- return sts;
- }
- if (sts != HPSTS_TRUST_SSM_ST) {
- sts = transition_snvs_trusted();
- if (sts != HPSTS_TRUST_SSM_ST) {
- return sts;
- }
- }
- sts = do_snvs_state_transition(HPCOM_SSM_ST, HPSTS_TRUST_SSM_ST);
- return sts;
- }
- void snvs_write_lp_gpr_bit(uint32_t offset, uint32_t bit_pos, bool flag_val)
- {
- if (flag_val) {
- snvs_write32(g_nxp_snvs_addr + offset,
- (snvs_read32(g_nxp_snvs_addr + offset))
- | (1 << bit_pos));
- } else {
- snvs_write32(g_nxp_snvs_addr + offset,
- (snvs_read32(g_nxp_snvs_addr + offset))
- & ~(1 << bit_pos));
- }
- }
- uint32_t snvs_read_lp_gpr_bit(uint32_t offset, uint32_t bit_pos)
- {
- return (snvs_read32(g_nxp_snvs_addr + offset) & (1 << bit_pos));
- }
- void snvs_disable_zeroize_lp_gpr(void)
- {
- snvs_write_lp_gpr_bit(NXP_LPCR_OFFSET,
- NXP_GPR_Z_DIS_BIT,
- true);
- }
- #if defined(NXP_NV_SW_MAINT_LAST_EXEC_DATA) && defined(NXP_COINED_BB)
- void snvs_write_app_data_bit(uint32_t bit_pos)
- {
- snvs_write_lp_gpr_bit(NXP_APP_DATA_LP_GPR_OFFSET,
- bit_pos,
- true);
- }
- uint32_t snvs_read_app_data(void)
- {
- return snvs_read32(g_nxp_snvs_addr + NXP_APP_DATA_LP_GPR_OFFSET);
- }
- uint32_t snvs_read_app_data_bit(uint32_t bit_pos)
- {
- uint8_t ret = snvs_read_lp_gpr_bit(NXP_APP_DATA_LP_GPR_OFFSET, bit_pos);
- return ((ret != 0U) ? 1U : 0U);
- }
- void snvs_clear_app_data(void)
- {
- snvs_write32(g_nxp_snvs_addr + NXP_APP_DATA_LP_GPR_OFFSET, 0x0);
- }
- #endif
|