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