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