1 /*
2 * Copyright (C) 2018-2020 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 #if defined(SBL_ENABLE_HLOS_BOOT) && defined(SOC_AM65XX)
46 const uint32_t gSciclient_boardCfgLow_hlos_rm[(SCICLIENT_BOARDCFG_RM_LINUX_SIZE_IN_BYTES+3U)/4U]
47 __attribute__(( aligned(128), section(".boardcfg_data") ))
48 = SCICLIENT_BOARDCFG_RM_LINUX;
49 #endif
51 #ifdef __cplusplus
52 #pragma DATA_SECTION(".firmware")
53 #else
54 #pragma WEAK (SBL_ReadSysfwImage)
55 #pragma DATA_SECTION(gSciclient_firmware, ".firmware")
56 #endif
57 uint32_t gSciclient_firmware[1];
59 #if SCICLIENT_FIRMWARE_SIZE_IN_BYTES > SBL_SYSFW_MAX_SIZE
60 #error "SYSFW too large...update SBL_SYSFW_MAX_SIZE"
61 #endif
63 #if (!defined(SBL_SKIP_BRD_CFG_PM)) || (!defined(SBL_SKIP_BRD_CFG_RM))
64 static int32_t Sciclient_setBoardConfigHeader ();
65 #endif
66 #if defined(SOC_AM65XX) || defined(SOC_J721E) || defined(SOC_J7200)
67 /* Firewall ID for MCU_FSS0_S0 */
68 #define MCU_FSS0_S0_FWID (1036)
69 #define MCU_FSS0_S0_FW_REGIONS (8)
71 #if defined (SOC_J721E) || defined (SOC_J7200)
72 /** \brief Aligned address at which the X509 header is placed. */
73 #define SCISERVER_COMMON_X509_HEADER_ADDR (0x41cffb00U)
75 /** \brief Aligned address at which the Board Config header is placed. */
76 #define SCISERVER_BOARDCONFIG_HEADER_ADDR (0x41c80000U)
78 /** \brief Aligned address at which the Board Config is placed. */
79 #define SCISERVER_BOARDCONFIG_DATA_ADDR (0x41c80040U)
81 #endif
82 #endif
84 uint32_t SBL_IsAuthReq(void)
85 {
86 uint32_t retVal = SBL_ALWAYS_AUTH_APP;
87 uint32_t dev_type;
88 uint32_t dev_subtype;
90 SBL_ADD_PROFILE_POINT;
92 dev_type = CSL_REG32_RD(SBL_SYS_STATUS_REG) & SBL_SYS_STATUS_DEV_TYPE_MASK;
93 dev_subtype = CSL_REG32_RD(SBL_SYS_STATUS_REG) & SBL_SYS_STATUS_DEV_SUBTYPE_MASK;
95 /* No auth possible, if valid SMPK/BMPK is not present */
96 if ((dev_subtype == SBL_SYS_STATUS_DEV_SUBTYPE_FS) ||
97 (dev_type == SBL_SYS_STATUS_DEV_TYPE_GP) ||
98 (dev_type == SBL_SYS_STATUS_DEV_TYPE_TEST))
99 {
100 retVal = SBL_NEVER_AUTH_APP;
101 }
103 SBL_ADD_PROFILE_POINT;
105 return retVal;
106 }
108 #ifndef SBL_SKIP_SYSFW_INIT
109 Sciclient_BoardCfgPrms_t sblBoardCfgPrms = {0};
110 Sciclient_BoardCfgPrms_t sblBoardCfgPmPrms = {0};
111 Sciclient_BoardCfgPrms_t sblBoardCfgRmPrms = {0};
112 #ifndef SBL_SKIP_BRD_CFG_SEC
113 Sciclient_BoardCfgPrms_t sblBoardCfgSecPrms = {0};
114 #endif
115 #endif
117 void SBL_SciClientInit(void)
118 {
119 int32_t status = CSL_EFAIL;
120 void *sysfw_ptr = gSciclient_firmware;
122 #ifndef SBL_SKIP_SYSFW_INIT
123 /* SYSFW board configurations */
124 Sciclient_DefaultBoardCfgInfo_t boardCfgInfo;
125 Sciclient_ConfigPrms_t config =
126 {
127 SCICLIENT_SERVICE_OPERATION_MODE_POLLED,
128 NULL,
129 1,
130 0,
131 TRUE
132 };
133 #endif
135 SBL_ADD_PROFILE_POINT;
137 status = SBL_ReadSysfwImage(&sysfw_ptr, SBL_SYSFW_MAX_SIZE);
138 if (status != CSL_PASS)
139 {
140 SBL_log(SBL_LOG_ERR,"SYSFW read...FAILED \n");
141 SblErrLoop(__FILE__, __LINE__);
142 }
144 #ifndef SBL_SKIP_SYSFW_INIT
145 SBL_ADD_PROFILE_POINT;
147 status = Sciclient_getDefaultBoardCfgInfo(&boardCfgInfo);
149 #if defined(SBL_ENABLE_HLOS_BOOT) && defined(SOC_AM65XX)
150 /* Replace default Sciclient boardCfgLowRm with alternate version for HLOS boot */
151 boardCfgInfo.boardCfgLowRm = &gSciclient_boardCfgLow_hlos_rm[0U];
152 boardCfgInfo.boardCfgLowRmSize = SCICLIENT_BOARDCFG_RM_LINUX_SIZE_IN_BYTES;
153 #endif
155 if (status != CSL_PASS)
156 {
157 SBL_log(SBL_LOG_ERR,"SYSFW get default board config...FAILED \n");
158 SblErrLoop(__FILE__, __LINE__);
159 }
161 status = Sciclient_loadFirmware((const uint32_t *) sysfw_ptr);
162 if (status != CSL_PASS)
163 {
164 SBL_log(SBL_LOG_ERR,"SYSFW load...FAILED \n");
165 SblErrLoop(__FILE__, __LINE__);
166 }
168 SBL_ADD_PROFILE_POINT;
169 status = Sciclient_init(&config);
170 if (status != CSL_PASS)
171 {
172 SBL_log(SBL_LOG_ERR,"SYSFW init ...FAILED \n");
173 SblErrLoop(__FILE__, __LINE__);
174 }
176 #ifndef SBL_SKIP_BRD_CFG_BOARD
177 SBL_ADD_PROFILE_POINT;
178 sblBoardCfgPrms.boardConfigLow = (uint32_t)boardCfgInfo.boardCfgLow;
179 sblBoardCfgPrms.boardConfigHigh = 0;
180 sblBoardCfgPrms.boardConfigSize = boardCfgInfo.boardCfgLowSize;
181 sblBoardCfgPrms.devGrp = SBL_DEVGRP;
182 status = Sciclient_boardCfg(&sblBoardCfgPrms);
183 if (status != CSL_PASS)
184 {
185 SBL_log(SBL_LOG_ERR,"SYSFW board config ...FAILED \n");
186 SblErrLoop(__FILE__, __LINE__);
187 }
188 #endif
190 #ifndef SBL_SKIP_BRD_CFG_PM
191 if (SBL_LOG_LEVEL > SBL_LOG_NONE)
192 {
193 SBL_ADD_PROFILE_POINT;
194 UART_stdioDeInit();
195 }
196 SBL_ADD_PROFILE_POINT;
197 sblBoardCfgPmPrms.boardConfigLow = (uint32_t)boardCfgInfo.boardCfgLowPm;
198 sblBoardCfgPmPrms.boardConfigHigh = 0;
199 sblBoardCfgPmPrms.boardConfigSize = boardCfgInfo.boardCfgLowPmSize;
200 sblBoardCfgPmPrms.devGrp = SBL_DEVGRP;
201 status = Sciclient_boardCfgPm(&sblBoardCfgPmPrms);
202 if (status != CSL_PASS)
203 {
204 SBL_log(SBL_LOG_ERR,"SYSFW board config pm...FAILED \n")
205 SblErrLoop(__FILE__, __LINE__);
206 }
208 if (SBL_LOG_LEVEL > SBL_LOG_NONE)
209 {
210 /* Re-init UART for logging */
211 UART_HwAttrs uart_cfg;
213 SBL_ADD_PROFILE_POINT;
214 UART_socGetInitCfg(BOARD_UART_INSTANCE, &uart_cfg);
215 uart_cfg.frequency = SBL_SYSFW_UART_MODULE_INPUT_CLK;
216 UART_socSetInitCfg(BOARD_UART_INSTANCE, &uart_cfg);
217 UART_stdioInit(BOARD_UART_INSTANCE);
218 }
219 #endif
221 #ifndef SBL_SKIP_BRD_CFG_RM
222 SBL_ADD_PROFILE_POINT;
223 sblBoardCfgRmPrms.boardConfigLow = (uint32_t)boardCfgInfo.boardCfgLowRm;
224 sblBoardCfgRmPrms.boardConfigHigh = 0;
225 sblBoardCfgRmPrms.boardConfigSize = boardCfgInfo.boardCfgLowRmSize;
226 sblBoardCfgRmPrms.devGrp = SBL_DEVGRP;
227 status = Sciclient_boardCfgRm(&sblBoardCfgRmPrms);
228 if (status != CSL_PASS)
229 {
230 SBL_log(SBL_LOG_ERR,"SYSFW board config rm...FAILED \n");
231 SblErrLoop(__FILE__, __LINE__);
232 }
233 #endif
235 #ifndef SBL_SKIP_BRD_CFG_SEC
236 SBL_ADD_PROFILE_POINT;
237 sblBoardCfgSecPrms.boardConfigLow = (uint32_t)boardCfgInfo.boardCfgLowSec;
238 sblBoardCfgSecPrms.boardConfigHigh = 0;
239 sblBoardCfgSecPrms.boardConfigSize = boardCfgInfo.boardCfgLowSecSize;
240 sblBoardCfgSecPrms.devGrp = SBL_DEVGRP;
241 status = Sciclient_boardCfgSec(&sblBoardCfgSecPrms);
242 if (status != CSL_PASS)
243 {
244 SBL_log(SBL_LOG_ERR,"SYSFW board config sec...FAILED \n");
245 SblErrLoop(__FILE__, __LINE__);
246 }
247 #if defined(SOC_AM65XX) || defined(SOC_J721E) || defined(SOC_J7200)
248 /* Secure ROM has left firewall regions for FSS DAT0 set. Disable them for DMA usage. */
249 uint16_t i;
250 struct tisci_msg_fwl_set_firewall_region_resp respFwCtrl = {0};
251 struct tisci_msg_fwl_set_firewall_region_req reqFwCtrl =
252 {
253 .fwl_id = (uint16_t) MCU_FSS0_S0_FWID,
254 .region = (uint16_t) 0,
255 .n_permission_regs = (uint32_t) 3,
256 /* Set .control to zero to disable the firewall region */
257 .control = (uint32_t) 0,
258 .permissions[0] = (uint32_t) 0,
259 .permissions[1] = (uint32_t) 0,
260 .permissions[2] = (uint32_t) 0,
261 .start_address = 0,
262 .end_address = 0
263 };
265 for (i = 0; i < MCU_FSS0_S0_FW_REGIONS; i++)
266 {
267 reqFwCtrl.region = i;
268 status = Sciclient_firewallSetRegion(&reqFwCtrl, &respFwCtrl, SCICLIENT_SERVICE_WAIT_FOREVER);
269 if (status != CSL_PASS)
270 {
271 SBL_log(SBL_LOG_ERR,"MCU FSS0_S0 firewall region # %d disable...FAILED \n", i);
272 }
273 }
274 #endif
275 #endif
277 /* Get SYSFW version */
278 SBL_ADD_PROFILE_POINT;
280 if (SBL_LOG_LEVEL > SBL_LOG_ERR)
281 {
282 struct tisci_msg_version_req req = {0};
283 const Sciclient_ReqPrm_t reqPrm =
284 {
285 TISCI_MSG_VERSION,
286 TISCI_MSG_FLAG_AOP,
287 (const uint8_t *)&req,
288 sizeof(req),
289 SCICLIENT_SERVICE_WAIT_FOREVER
290 };
292 struct tisci_msg_version_resp response;
293 Sciclient_RespPrm_t respPrm =
294 {
295 0,
296 (uint8_t *) &response,
297 (uint32_t)sizeof (response)
298 };
300 status = Sciclient_service(&reqPrm, &respPrm);
301 if (CSL_PASS == status)
302 {
303 if (respPrm.flags == (uint32_t)TISCI_MSG_FLAG_ACK)
304 {
305 SBL_ADD_PROFILE_POINT;
306 SBL_log(SBL_LOG_MIN,"SYSFW ver: %s\n", (char *) response.str);
307 }
308 else
309 {
310 SBL_log(SBL_LOG_ERR,"SYSFW Get Version failed \n");
311 SblErrLoop(__FILE__, __LINE__);
312 }
313 }
314 }
317 #if (!defined(SBL_SKIP_BRD_CFG_PM)) || (!defined(SBL_SKIP_BRD_CFG_RM))
318 status = Sciclient_setBoardConfigHeader();
319 if (CSL_PASS == status)
320 {
321 SBL_log(SBL_LOG_MAX,"Sciclient_setBoardConfigHeader... PASSED\n");
322 }
323 else
324 {
325 SBL_log(SBL_LOG_ERR,"Sciclient_setBoardConfigHeader... FAILED\n");
326 SblErrLoop(__FILE__, __LINE__);
327 }
328 #endif
331 #if !defined(SBL_SKIP_MCU_RESET)
332 /* RTI seems to be turned on by ROM. Turning it off so that Power domain can transition */
333 Sciclient_pmSetModuleState(SBL_DEV_ID_RTI0, TISCI_MSG_VALUE_DEVICE_SW_STATE_AUTO_OFF, TISCI_MSG_FLAG_AOP, SCICLIENT_SERVICE_WAIT_FOREVER);
334 Sciclient_pmSetModuleState(SBL_DEV_ID_RTI1, TISCI_MSG_VALUE_DEVICE_SW_STATE_AUTO_OFF, TISCI_MSG_FLAG_AOP, SCICLIENT_SERVICE_WAIT_FOREVER);
335 #if defined(SOC_AM64X)
336 Sciclient_pmSetModuleState(SBL_DEV_ID_RTI8, TISCI_MSG_VALUE_DEVICE_SW_STATE_AUTO_OFF, TISCI_MSG_FLAG_AOP, SCICLIENT_SERVICE_WAIT_FOREVER);
337 Sciclient_pmSetModuleState(SBL_DEV_ID_RTI9, TISCI_MSG_VALUE_DEVICE_SW_STATE_AUTO_OFF, TISCI_MSG_FLAG_AOP, SCICLIENT_SERVICE_WAIT_FOREVER);
338 Sciclient_pmSetModuleState(SBL_DEV_ID_RTI10, TISCI_MSG_VALUE_DEVICE_SW_STATE_AUTO_OFF, TISCI_MSG_FLAG_AOP, SCICLIENT_SERVICE_WAIT_FOREVER);
339 Sciclient_pmSetModuleState(SBL_DEV_ID_RTI11, TISCI_MSG_VALUE_DEVICE_SW_STATE_AUTO_OFF, TISCI_MSG_FLAG_AOP, SCICLIENT_SERVICE_WAIT_FOREVER);
340 Sciclient_pmSetModuleState(SBL_DEV_ID_MCU_RTI0, TISCI_MSG_VALUE_DEVICE_SW_STATE_AUTO_OFF, TISCI_MSG_FLAG_AOP, SCICLIENT_SERVICE_WAIT_FOREVER);
341 #endif
342 #endif
345 #endif
347 SBL_ADD_PROFILE_POINT;
348 }
350 #if (!defined(SBL_SKIP_BRD_CFG_PM)) || (!defined(SBL_SKIP_BRD_CFG_RM))
351 static int32_t Sciclient_setBoardConfigHeader ()
352 {
353 int32_t status = CSL_PASS;
354 #if defined (SOC_J7200) || defined (SOC_J721E)
355 //uint32_t alignedOffset = ((SCICLIENT_BOARDCFG_PM_SIZE_IN_BYTES + 128U)/128U)*128U;
356 uint32_t alignedOffset = SCICLIENT_BOARDCFG_PM_SIZE_IN_BYTES;
357 Sciclient_BoardCfgPrms_t boardCfgPrms_pm =
358 {
359 .boardConfigLow = (uint32_t)SCISERVER_BOARDCONFIG_DATA_ADDR,
360 .boardConfigHigh = 0,
361 .boardConfigSize = SCICLIENT_BOARDCFG_PM_SIZE_IN_BYTES,
362 .devGrp = DEVGRP_ALL
363 };
364 Sciclient_BoardCfgPrms_t boardCfgPrms_rm =
365 {
366 .boardConfigLow =
367 (uint32_t) SCISERVER_BOARDCONFIG_DATA_ADDR + alignedOffset,
368 .boardConfigHigh = 0,
369 .boardConfigSize = SCICLIENT_BOARDCFG_RM_SIZE_IN_BYTES,
370 .devGrp = DEVGRP_ALL
371 };
372 status = Sciclient_boardCfgPrepHeader (
373 (uint8_t *) SCISERVER_COMMON_X509_HEADER_ADDR,
374 (uint8_t *) SCISERVER_BOARDCONFIG_HEADER_ADDR,
375 &boardCfgPrms_pm, &boardCfgPrms_rm);
376 if (CSL_PASS == status)
377 {
378 SBL_log(SBL_LOG_MAX,"SCISERVER Board Configuration header population... ");
379 SBL_log(SBL_LOG_MAX,"PASSED\n");
380 }
381 else
382 {
383 SBL_log(SBL_LOG_MIN,"SCISERVER Board Configuration header population... ");
384 SBL_log(SBL_LOG_MIN,"FAILED\n");
385 }
386 memcpy((void *)boardCfgPrms_pm.boardConfigLow, (void *) sblBoardCfgPmPrms.boardConfigLow, SCICLIENT_BOARDCFG_PM_SIZE_IN_BYTES);
387 memcpy((void *)boardCfgPrms_rm.boardConfigLow, (void *) sblBoardCfgRmPrms.boardConfigLow, SCICLIENT_BOARDCFG_RM_SIZE_IN_BYTES);
388 #endif
389 return status;
390 }
391 #endif