1 /*
2 * Copyright (C) 2018-2019 Texas Instruments Incorporated - http://www.ti.com/
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the
14 * distribution.
15 *
16 * Neither the name of Texas Instruments Incorporated nor the names of
17 * its contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 */
33 #include <ti/csl/tistdtypes.h>
34 #include <ti/csl/soc.h>
35 #include <ti/csl/arch/csl_arch.h>
36 #include <ti/csl/hw_types.h>
37 #include <ti/drv/uart/UART_stdio.h>
38 #include <ti/drv/uart/soc/UART_soc.h>
39 #include <ti/board/board.h>
40 #include <sbl_soc.h>
41 #include <sbl_soc_cfg.h>
42 #include <sbl_err_trap.h>
43 #include <sbl_sci_client.h>
45 #ifdef __cplusplus
46 #pragma DATA_SECTION(".firmware")
47 #else
48 #pragma WEAK (SBL_ReadSysfwImage)
49 #pragma DATA_SECTION(gSciclient_firmware, ".firmware")
50 #endif
51 uint32_t gSciclient_firmware[1];
53 #if BINARY_FILE_SIZE_IN_BYTES > SBL_SYSFW_MAX_SIZE
54 #error "SYSFW too large...update SBL_SYSFW_MAX_SIZE"
55 #endif
57 uint32_t SBL_IsSysfwEnc(uint8_t *x509_cert_ptr)
58 {
59 static uint32_t retVal = SBL_SYSFW_NOT_PROCESSED;
60 uint8_t *encSeqPtr = NULL;
61 uint32_t outer_cert_len = 0;
62 uint8_t *innerCertStart = NULL;
63 uint32_t inner_cert_len = 0;
64 /* oid encoding of encryption seq extension for RBL - 1.3.6.1.4.1.294.1.4 */
65 uint8_t enc_seq_oid[] = {0x06, 0x09, 0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0x26, 0x01, 0x04};
67 SBL_ADD_PROFILE_POINT;
69 if (x509_cert_ptr)
70 {
71 uint32_t SBL_GetCertLen(uint8_t *x509_cert_ptr);
73 outer_cert_len = SBL_GetCertLen(x509_cert_ptr);
74 innerCertStart = x509_cert_ptr + outer_cert_len;
75 inner_cert_len = SBL_GetCertLen(innerCertStart);
76 }
78 if (inner_cert_len)
79 {
80 uint8_t *SBL_FindSeq(uint8_t *x509_cert_ptr, uint32_t x509_cert_size, uint8_t *seq_oid, uint8_t seq_len);
82 encSeqPtr = SBL_FindSeq(innerCertStart, inner_cert_len, enc_seq_oid, sizeof(enc_seq_oid));
83 if (encSeqPtr)
84 {
85 /* SYSFW is double signed and encrypted */
86 retVal = SBL_SYSFW_ENCRYPTED;
87 }
88 else
89 {
90 /* SYSFW is double signed but not encrypted */
91 SBL_log(SBL_LOG_ERR,"invalid SYSFW signature \n");
92 SblErrLoop(__FILE__, __LINE__);
93 }
94 }
95 else if ((x509_cert_ptr) && (retVal == SBL_SYSFW_NOT_PROCESSED))
96 {
97 /* SYSFW is single signed */
98 retVal = SBL_SYSFW_CLEAR_TEXT;
99 }
101 SBL_ADD_PROFILE_POINT;
103 return retVal;
104 }
106 void SBL_SciClientInit(void)
107 {
108 int32_t status = CSL_EFAIL;
109 void *sysfw_ptr = gSciclient_firmware;
111 #ifndef SBL_SKIP_SYSFW_INIT
112 /* Point to the constant global structure because we need to modify it */
113 struct tisci_boardcfg *pBoardConfigLow = (struct tisci_boardcfg *)&gBoardConfigLow;
115 /* SYSFW board configurations */
116 Sciclient_BoardCfgPrms_t sblBoardCfgPrms =
117 {
118 .boardConfigLow = (uint32_t)&gBoardConfigLow,
119 .boardConfigHigh = 0,
120 .boardConfigSize = sizeof(gBoardConfigLow),
121 .devGrp = SBL_DEVGRP
122 };
124 Sciclient_BoardCfgPrms_t sblBoardCfgPmPrms =
125 {
126 .boardConfigLow = (uint32_t)NULL,
127 .boardConfigHigh = 0,
128 .boardConfigSize = 0,
129 .devGrp = SBL_DEVGRP
130 };
132 Sciclient_BoardCfgPrms_t sblBoardCfgRmPrms =
133 {
134 .boardConfigLow = (uint32_t)&gBoardConfigLow_rm,
135 .boardConfigHigh = 0,
136 .boardConfigSize = sizeof(gBoardConfigLow_rm),
137 .devGrp = SBL_DEVGRP
138 };
140 Sciclient_BoardCfgPrms_t sblBoardCfgSecPrms =
141 {
142 .boardConfigLow = (uint32_t)&gBoardConfigLow_security,
143 .boardConfigHigh = 0,
144 .boardConfigSize = sizeof(gBoardConfigLow_security),
145 .devGrp = SBL_DEVGRP
146 };
148 Sciclient_ConfigPrms_t config =
149 {
150 SCICLIENT_SERVICE_OPERATION_MODE_POLLED,
151 };
152 #endif
154 SBL_ADD_PROFILE_POINT;
156 status = SBL_ReadSysfwImage(&sysfw_ptr, SBL_SYSFW_MAX_SIZE);
157 if (status != CSL_PASS)
158 {
159 SBL_log(SBL_LOG_ERR,"SYSFW read...FAILED \n");
160 SblErrLoop(__FILE__, __LINE__);
161 }
162 else
163 {
164 SBL_ADD_PROFILE_POINT;
165 SBL_IsSysfwEnc((uint8_t *) sysfw_ptr);
166 }
168 #ifndef SBL_SKIP_SYSFW_INIT
170 SBL_ADD_PROFILE_POINT;
171 status = Sciclient_loadFirmware((const uint32_t *) sysfw_ptr);
172 if (status != CSL_PASS)
173 {
174 SBL_log(SBL_LOG_ERR,"SYSFW load...FAILED \n");
175 SblErrLoop(__FILE__, __LINE__);
176 }
178 SBL_ADD_PROFILE_POINT;
179 status = Sciclient_init(&config);
180 if (status != CSL_PASS)
181 {
182 SBL_log(SBL_LOG_ERR,"SYSFW init ...FAILED \n");
183 SblErrLoop(__FILE__, __LINE__);
184 }
186 #ifndef SBL_SKIP_BRD_CFG_BOARD
187 if (SBL_LOG_LEVEL < SBL_LOG_MIN)
188 {
189 /* Redirect DMSC logs to memory */
190 pBoardConfigLow->debug_cfg.trace_dst_enables = TISCI_BOARDCFG_TRACE_DST_MEM;
192 /* Enable no logs */
193 pBoardConfigLow->debug_cfg.trace_src_enables = 0;
194 }
195 else if (SBL_LOG_LEVEL > SBL_LOG_MIN)
196 {
197 /* Redirect DMSC logs to WKUP UART */
198 pBoardConfigLow->debug_cfg.trace_dst_enables = TISCI_BOARDCFG_TRACE_DST_UART0;
200 /* Enable full logs */
201 pBoardConfigLow->debug_cfg.trace_src_enables = TISCI_BOARDCFG_TRACE_SRC_PM |
202 TISCI_BOARDCFG_TRACE_SRC_RM |
203 TISCI_BOARDCFG_TRACE_SRC_SEC |
204 TISCI_BOARDCFG_TRACE_SRC_BASE |
205 TISCI_BOARDCFG_TRACE_SRC_USER |
206 TISCI_BOARDCFG_TRACE_SRC_SUPR ;
207 }
209 SBL_ADD_PROFILE_POINT;
210 status = Sciclient_boardCfg(&sblBoardCfgPrms);
211 if (status != CSL_PASS)
212 {
213 SBL_log(SBL_LOG_ERR,"SYSFW board config ...FAILED \n");
214 SblErrLoop(__FILE__, __LINE__);
215 }
216 #endif
218 #ifndef SBL_SKIP_BRD_CFG_PM
219 if (SBL_LOG_LEVEL > SBL_LOG_NONE)
220 {
221 SBL_ADD_PROFILE_POINT;
222 UART_stdioDeInit();
223 }
224 SBL_ADD_PROFILE_POINT;
225 status = Sciclient_boardCfgPm(&sblBoardCfgPmPrms);
226 if (status != CSL_PASS)
227 {
228 SBL_log(SBL_LOG_ERR,"SYSFW board config pm...FAILED \n")
229 SblErrLoop(__FILE__, __LINE__);
230 }
232 if (SBL_LOG_LEVEL > SBL_LOG_NONE)
233 {
234 /* Re-init UART for logging */
235 UART_HwAttrs uart_cfg;
237 SBL_ADD_PROFILE_POINT;
238 UART_socGetInitCfg(BOARD_UART_INSTANCE, &uart_cfg);
239 uart_cfg.frequency = SBL_SYSFW_UART_MODULE_INPUT_CLK;
240 UART_socSetInitCfg(BOARD_UART_INSTANCE, &uart_cfg);
241 UART_stdioInit(BOARD_UART_INSTANCE);
242 }
243 #endif
245 #ifndef SBL_SKIP_BRD_CFG_RM
246 SBL_ADD_PROFILE_POINT;
247 status = Sciclient_boardCfgRm(&sblBoardCfgRmPrms);
248 if (status != CSL_PASS)
249 {
250 SBL_log(SBL_LOG_ERR,"SYSFW board config rm...FAILED \n");
251 SblErrLoop(__FILE__, __LINE__);
252 }
253 #endif
255 #ifndef SBL_SKIP_BRD_CFG_SEC
256 SBL_ADD_PROFILE_POINT;
257 status = Sciclient_boardCfgSec(&sblBoardCfgSecPrms);
258 if (status != CSL_PASS)
259 {
260 SBL_log(SBL_LOG_ERR,"SYSFW board config sec...FAILED \n");
261 SblErrLoop(__FILE__, __LINE__);
262 }
263 #endif
265 /* Get SYSFW version */
266 SBL_ADD_PROFILE_POINT;
268 if (SBL_LOG_LEVEL > SBL_LOG_ERR)
269 {
270 const Sciclient_ReqPrm_t reqPrm =
271 {
272 TISCI_MSG_VERSION,
273 TISCI_MSG_FLAG_AOP,
274 (uint8_t *)NULL,
275 0,
276 SCICLIENT_SERVICE_WAIT_FOREVER
277 };
279 struct tisci_msg_version_resp response;
280 Sciclient_RespPrm_t respPrm =
281 {
282 0,
283 (uint8_t *) &response,
284 (uint32_t)sizeof (response)
285 };
287 status = Sciclient_service(&reqPrm, &respPrm);
288 if (CSL_PASS == status)
289 {
290 if (respPrm.flags == (uint32_t)TISCI_MSG_FLAG_ACK)
291 {
292 SBL_ADD_PROFILE_POINT;
293 SBL_log(SBL_LOG_MIN,"SYSFW ver: %s\n", (char *) response.str);
294 }
295 else
296 {
297 SBL_log(SBL_LOG_ERR,"SYSFW Get Version failed \n");
298 SblErrLoop(__FILE__, __LINE__);
299 }
300 }
301 }
303 /* RTI seems to be turned on by ROM. Turning it off so that Power domain can transition */
304 Sciclient_pmSetModuleState(SBL_DEV_ID_RTI0, TISCI_MSG_VALUE_DEVICE_SW_STATE_AUTO_OFF, TISCI_MSG_FLAG_AOP, SCICLIENT_SERVICE_WAIT_FOREVER);
305 Sciclient_pmSetModuleState(SBL_DEV_ID_RTI1, TISCI_MSG_VALUE_DEVICE_SW_STATE_AUTO_OFF, TISCI_MSG_FLAG_AOP, SCICLIENT_SERVICE_WAIT_FOREVER);
306 #endif
308 SBL_ADD_PROFILE_POINT;
309 }