blob: e9f351dc3aa468424cebb34d5a11aeb4438f4dee [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
gaurav rana9aaea442015-02-27 09:44:22 +05302/*
3 * Copyright 2015 Freescale Semiconductor, Inc.
gaurav rana9aaea442015-02-27 09:44:22 +05304 */
5
6#include <common.h>
7#include <fsl_sec_mon.h>
8
Sumit Gargbc17f982016-08-31 08:54:15 -04009static u32 get_sec_mon_state(void)
gaurav rana9aaea442015-02-27 09:44:22 +053010{
11 struct ccsr_sec_mon_regs *sec_mon_regs = (void *)
12 (CONFIG_SYS_SEC_MON_ADDR);
Sumit Gargbc17f982016-08-31 08:54:15 -040013 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;
gaurav rana9aaea442015-02-27 09:44:22 +053019 int timeout = 10;
Sumit Gargbc17f982016-08-31 08:54:15 -040020 struct ccsr_sec_mon_regs *sec_mon_regs = (void *)
21 (CONFIG_SYS_SEC_MON_ADDR);
gaurav rana9aaea442015-02-27 09:44:22 +053022
Sumit Gargbc17f982016-08-31 08:54:15 -040023 sts = get_sec_mon_state();
gaurav rana9aaea442015-02-27 09:44:22 +053024
Sumit Gargbc17f982016-08-31 08:54:15 -040025 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);
gaurav rana9aaea442015-02-27 09:44:22 +053033
Sumit Gargbc17f982016-08-31 08:54:15 -040034 /* polling loop till SEC_MON is in Non Secure state */
35 while (timeout) {
36 sts = get_sec_mon_state();
gaurav rana9aaea442015-02-27 09:44:22 +053037
Sumit Gargbc17f982016-08-31 08:54:15 -040038 if ((sts & HPSR_SSM_ST_MASK) ==
39 HPSR_SSM_ST_NON_SECURE)
40 break;
gaurav rana9aaea442015-02-27 09:44:22 +053041
Sumit Gargbc17f982016-08-31 08:54:15 -040042 udelay(10);
43 timeout--;
44 }
gaurav rana9aaea442015-02-27 09:44:22 +053045
Sumit Gargbc17f982016-08-31 08:54:15 -040046 if (timeout == 0) {
47 printf("SEC_MON state transition timeout.\n");
48 return -1;
49 }
50 break;
gaurav rana9aaea442015-02-27 09:44:22 +053051
Sumit Gargbc17f982016-08-31 08:54:15 -040052 /*
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);
gaurav rana9aaea442015-02-27 09:44:22 +053062
Sumit Gargbc17f982016-08-31 08:54:15 -040063 /* polling loop till SEC_MON is in Soft-Fail state */
64 while (timeout) {
65 sts = get_sec_mon_state();
gaurav rana9aaea442015-02-27 09:44:22 +053066
Sumit Gargbc17f982016-08-31 08:54:15 -040067 if ((sts & HPSR_SSM_ST_MASK) ==
68 HPSR_SSM_ST_SOFT_FAIL)
69 break;
gaurav rana9aaea442015-02-27 09:44:22 +053070
Sumit Gargbc17f982016-08-31 08:54:15 -040071 udelay(10);
72 timeout--;
73 }
gaurav rana9aaea442015-02-27 09:44:22 +053074
Sumit Gargbc17f982016-08-31 08:54:15 -040075 if (timeout == 0) {
76 printf("SEC_MON state transition timeout.\n");
77 return -1;
78 }
gaurav rana9aaea442015-02-27 09:44:22 +053079
Sumit Gargbc17f982016-08-31 08:54:15 -040080 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);
gaurav rana9aaea442015-02-27 09:44:22 +053091
Sumit Gargbc17f982016-08-31 08:54:15 -040092 /* polling loop till SEC_MON is in Non Secure*/
93 while (timeout) {
94 sts = get_sec_mon_state();
gaurav rana9aaea442015-02-27 09:44:22 +053095
Sumit Gargbc17f982016-08-31 08:54:15 -040096 if ((sts & HPSR_SSM_ST_MASK) ==
97 HPSR_SSM_ST_NON_SECURE)
98 break;
gaurav rana9aaea442015-02-27 09:44:22 +053099
Sumit Gargbc17f982016-08-31 08:54:15 -0400100 udelay(10);
101 timeout--;
gaurav rana9aaea442015-02-27 09:44:22 +0530102 }
103
104 if (timeout == 0) {
105 printf("SEC_MON state transition timeout.\n");
106 return -1;
107 }
gaurav rana9aaea442015-02-27 09:44:22 +0530108 }
Sumit Gargbc17f982016-08-31 08:54:15 -0400109 break;
110 default:
111 printf("SEC_MON already in Non Secure state.\n");
112 return 0;
113 }
114 return 0;
115}
gaurav rana9aaea442015-02-27 09:44:22 +0530116
Sumit Gargbc17f982016-08-31 08:54:15 -0400117static 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);
gaurav rana9aaea442015-02-27 09:44:22 +0530123
Sumit Gargbc17f982016-08-31 08:54:15 -0400124 printf("SEC_MON state transitioning to Soft Fail.\n");
125 sec_mon_setbits32(&sec_mon_regs->hp_com, HPCOMR_SW_FSV);
gaurav rana9aaea442015-02-27 09:44:22 +0530126
Sumit Gargbc17f982016-08-31 08:54:15 -0400127 /* polling loop till SEC_MON is in Soft-Fail state */
128 while (timeout) {
129 sts = get_sec_mon_state();
gaurav rana9aaea442015-02-27 09:44:22 +0530130
Sumit Gargbc17f982016-08-31 08:54:15 -0400131 if ((sts & HPSR_SSM_ST_MASK) ==
132 HPSR_SSM_ST_SOFT_FAIL)
gaurav rana9aaea442015-02-27 09:44:22 +0530133 break;
Sumit Gargbc17f982016-08-31 08:54:15 -0400134
135 udelay(10);
136 timeout--;
gaurav rana9aaea442015-02-27 09:44:22 +0530137 }
138
Sumit Gargbc17f982016-08-31 08:54:15 -0400139 if (timeout == 0) {
140 printf("SEC_MON state transition timeout.\n");
141 return -1;
142 }
gaurav rana9aaea442015-02-27 09:44:22 +0530143 return 0;
144}
Sumit Gargbc17f982016-08-31 08:54:15 -0400145
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}