]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - processor-sdk/pdk.git/blob - packages/ti/boot/sbl/soc/k3/sbl_sci_client.c
Fixes for Sciclient to not globally disable interrupts
[processor-sdk/pdk.git] / packages / ti / boot / sbl / soc / k3 / sbl_sci_client.c
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;
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 #ifndef SBL_SKIP_BRD_CFG_RM
118 uint16_t gCertLength = 0;
119 #endif
120 static uint16_t boardcfgRmFindCertSize(uint32_t *msg_recv)
122     uint16_t cert_len = 0;
123     uint8_t *cert_len_ptr = (uint8_t *)&cert_len;
124     uint8_t *x509_cert_ptr;
126     x509_cert_ptr = (uint8_t *)msg_recv;
129     if (*x509_cert_ptr != 0x30)
130     {
131         /* The data does not contain a certificate - return */
132         return 0;
133     }
135     cert_len = *(x509_cert_ptr + 1);
137     /* If you need more than 2 bytes to store the cert length  */
138     /* it means that the cert length is greater than 64 Kbytes */
139     /* and we do not support it                                */
140     if ((cert_len > 0x80) &&
141         (cert_len != 0x82))
142     {
143         return 0;
144     }
146     if (cert_len == 0x82)
147     {
148         *cert_len_ptr = *(x509_cert_ptr + 3);
149         *(cert_len_ptr + 1) = *(x509_cert_ptr + 2);
151         /* add current offset from start of x509 cert */
152         cert_len += 3;
153     }
154     else
155     {
156         /* add current offset from start of x509 cert  */
157         /* if cert len was obtained from 2nd byte i.e. */
158         /* cert size is 127 bytes or less              */
159         cert_len += 1;
160     }
162     /* cert_len now contains the offset of the last byte */
163     /* of the cert from the ccert_start. To get the size */
164     /* of certificate, add 1                             */
166     return cert_len + 1;
169 void SBL_SciClientInit(void)
171     int32_t status = CSL_EFAIL;
172     void *sysfw_ptr = gSciclient_firmware;
174 #ifndef SBL_SKIP_SYSFW_INIT
175     /* SYSFW board configurations */
176     Sciclient_DefaultBoardCfgInfo_t boardCfgInfo;
177     Sciclient_ConfigPrms_t config;
178     Sciclient_configPrmsInit(&config);
179     config.opModeFlag               =   SCICLIENT_SERVICE_OPERATION_MODE_POLLED;
180     config.pBoardCfgPrms            =   NULL;
181     config.isSecureMode             =   1;
182     config.c66xRatRegion            =   0;
183     config.skipLocalBoardCfgProcess =   TRUE;
185 #if defined(SOC_AM65XX)
186     config.isSecureMode = 0U;
187 #endif /* AM65xx the default board cfg is for non-secure mode */
189 #endif
191     SBL_ADD_PROFILE_POINT;
193     status = SBL_ReadSysfwImage(&sysfw_ptr, SBL_SYSFW_MAX_SIZE);
194     if (status != CSL_PASS)
195     {
196 #if defined(SOC_J721E) || defined(SOC_J7200)
197         SBL_log(SBL_LOG_ERR,"TIFS read...FAILED \n");
198 #else
199         SBL_log(SBL_LOG_ERR,"SYSFW read...FAILED \n");
200 #endif
201         SblErrLoop(__FILE__, __LINE__);
202     }
204 #ifndef SBL_SKIP_SYSFW_INIT
205     SBL_ADD_PROFILE_POINT;
207     status = Sciclient_getDefaultBoardCfgInfo(&boardCfgInfo);
209 #if defined(SBL_ENABLE_HLOS_BOOT) && defined(SOC_AM65XX)
210     /* Replace default Sciclient boardCfgLowRm with alternate version for HLOS boot */
211         boardCfgInfo.boardCfgLowRm     = &gSciclient_boardCfgLow_hlos_rm[0U];
212         boardCfgInfo.boardCfgLowRmSize = SCICLIENT_BOARDCFG_RM_LINUX_SIZE_IN_BYTES;
213 #endif
215     if (status != CSL_PASS)
216     {
217         SBL_log(SBL_LOG_ERR,"Sciclient get default board config...FAILED \n");
218         SblErrLoop(__FILE__, __LINE__);
219     }
221     status = Sciclient_loadFirmware((const uint32_t *) sysfw_ptr);
222     if (status != CSL_PASS)
223     {
224 #if defined(SOC_J721E) || defined(SOC_J7200)
225         SBL_log(SBL_LOG_ERR,"TIFS load...FAILED \n");
226 #else
227         SBL_log(SBL_LOG_ERR,"SYSFW load...FAILED \n");
228 #endif
229         SblErrLoop(__FILE__, __LINE__);
230     }
232     SBL_ADD_PROFILE_POINT;
233     status = Sciclient_init(&config);
234     if (status != CSL_PASS)
235     {
236         SBL_log(SBL_LOG_ERR,"Sciclient init ...FAILED \n");
237         SblErrLoop(__FILE__, __LINE__);
238     }
240 #ifndef SBL_SKIP_BRD_CFG_BOARD
241     SBL_ADD_PROFILE_POINT;
242     sblBoardCfgPrms.boardConfigLow = (uint32_t)boardCfgInfo.boardCfgLow;
243     sblBoardCfgPrms.boardConfigHigh = 0;
244     sblBoardCfgPrms.boardConfigSize = boardCfgInfo.boardCfgLowSize;
245     sblBoardCfgPrms.devGrp = SBL_DEVGRP;
246     status = Sciclient_boardCfg(&sblBoardCfgPrms);
247     if (status != CSL_PASS)
248     {
249         SBL_log(SBL_LOG_ERR,"Sciclient board config ...FAILED \n");
250         SblErrLoop(__FILE__, __LINE__);
251     }
252 #endif
254 #ifndef SBL_SKIP_BRD_CFG_PM
255     if (SBL_LOG_LEVEL > SBL_LOG_NONE)
256     {
257         SBL_ADD_PROFILE_POINT;
258         UART_stdioDeInit();
259     }
260     SBL_ADD_PROFILE_POINT;
261     sblBoardCfgPmPrms.boardConfigLow = (uint32_t)boardCfgInfo.boardCfgLowPm;
262     sblBoardCfgPmPrms.boardConfigHigh = 0;
263     sblBoardCfgPmPrms.boardConfigSize = boardCfgInfo.boardCfgLowPmSize;
264     sblBoardCfgPmPrms.devGrp = SBL_DEVGRP;
265     status = Sciclient_boardCfgPm(&sblBoardCfgPmPrms);
266     if (status != CSL_PASS)
267     {
268         SBL_log(SBL_LOG_ERR,"Sciclient board config pm...FAILED \n")
269         SblErrLoop(__FILE__, __LINE__);
270     }
272     if (SBL_LOG_LEVEL > SBL_LOG_NONE)
273     {
274         /* Re-init UART for logging */
275         UART_HwAttrs uart_cfg;
277         SBL_ADD_PROFILE_POINT;
278         UART_socGetInitCfg(BOARD_UART_INSTANCE, &uart_cfg);
279         uart_cfg.frequency = SBL_SYSFW_UART_MODULE_INPUT_CLK;
280         UART_socSetInitCfg(BOARD_UART_INSTANCE, &uart_cfg);
281         UART_stdioInit(BOARD_UART_INSTANCE);
282     }
283 #endif
285 #ifndef SBL_SKIP_BRD_CFG_SEC
286     SBL_ADD_PROFILE_POINT;
287     sblBoardCfgSecPrms.boardConfigLow = (uint32_t)boardCfgInfo.boardCfgLowSec;
288     sblBoardCfgSecPrms.boardConfigHigh = 0;
289     sblBoardCfgSecPrms.boardConfigSize = boardCfgInfo.boardCfgLowSecSize;
290     sblBoardCfgSecPrms.devGrp = SBL_DEVGRP;
291     status = Sciclient_boardCfgSec(&sblBoardCfgSecPrms);
292     if (status != CSL_PASS)
293     {
294         SBL_log(SBL_LOG_ERR,"Sciclient board config sec...FAILED \n");
295         SblErrLoop(__FILE__, __LINE__);
296     }
297 #if defined(SOC_AM65XX) || defined(SOC_J721E) || defined(SOC_J7200)
298     /* Secure ROM has left firewall regions for FSS DAT0 set.  Disable them for DMA usage. */
299     uint16_t i;
300     struct tisci_msg_fwl_set_firewall_region_resp respFwCtrl = {0};
301     struct tisci_msg_fwl_set_firewall_region_req reqFwCtrl =
302     {
303         .fwl_id = (uint16_t) MCU_FSS0_S0_FWID,
304         .region = (uint16_t) 0,
305         .n_permission_regs = (uint32_t) 3,
306         /* Set .control to zero to disable the firewall region */
307         .control = (uint32_t) 0,
308         .permissions[0] = (uint32_t) 0,
309         .permissions[1] = (uint32_t) 0,
310         .permissions[2] = (uint32_t) 0,
311         .start_address = 0,
312         .end_address = 0
313     };
315     for (i = 0; i < MCU_FSS0_S0_FW_REGIONS; i++)
316     {
317         reqFwCtrl.region = i;
318         status = Sciclient_firewallSetRegion(&reqFwCtrl, &respFwCtrl, SCICLIENT_SERVICE_WAIT_FOREVER);
319         if (status != CSL_PASS)
320         {
321             SBL_log(SBL_LOG_ERR,"MCU FSS0_S0 firewall region # %d disable...FAILED \n", i);
322         }
323     }
324 #endif
325 #endif
327 #ifndef SBL_SKIP_BRD_CFG_RM
328     SBL_ADD_PROFILE_POINT;
329     sblBoardCfgRmPrms.boardConfigLow = (uint32_t)boardCfgInfo.boardCfgLowRm;
330     sblBoardCfgRmPrms.boardConfigHigh = 0;
331     sblBoardCfgRmPrms.boardConfigSize = boardCfgInfo.boardCfgLowRmSize;
332     sblBoardCfgRmPrms.devGrp = SBL_DEVGRP;
333     gCertLength = boardcfgRmFindCertSize((uint32_t*)boardCfgInfo.boardCfgLowRm);
334     status = Sciclient_boardCfgRm(&sblBoardCfgRmPrms);
335     if (status != CSL_PASS)
336     {
337         SBL_log(SBL_LOG_ERR,"Sciclient board config rm...FAILED \n");
338         SblErrLoop(__FILE__, __LINE__);
339     }
340 #endif
342     /* Get SYSFW/TIFS version */
343     SBL_ADD_PROFILE_POINT;
345     if (SBL_LOG_LEVEL > SBL_LOG_ERR)
346     {
347         struct tisci_msg_version_req req = {0};
348         const Sciclient_ReqPrm_t      reqPrm =
349         {
350             TISCI_MSG_VERSION,
351             TISCI_MSG_FLAG_AOP,
352             (const uint8_t *)&req,
353             sizeof(req),
354             SCICLIENT_SERVICE_WAIT_FOREVER
355         };
357         struct tisci_msg_version_resp response;
358         Sciclient_RespPrm_t           respPrm =
359         {
360             0,
361             (uint8_t *) &response,
362             (uint32_t)sizeof (response)
363         };
365         status = Sciclient_service(&reqPrm, &respPrm);
366         if (CSL_PASS == status)
367         {
368             if (respPrm.flags == (uint32_t)TISCI_MSG_FLAG_ACK)
369             {
370                 SBL_ADD_PROFILE_POINT;
371 #if defined(SOC_J721E) || defined(SOC_J7200)
372                 SBL_log(SBL_LOG_MIN,"TIFS  ver: %s\n", (char *) response.str);
373 #else
374                 SBL_log(SBL_LOG_MIN,"SYSFW  ver: %s\n", (char *) response.str);
375 #endif
376             }
377             else
378             {
379 #if defined(SOC_J721E) || defined(SOC_J7200)
380                 SBL_log(SBL_LOG_ERR,"TIFS Get Version failed \n");
381 #else
382                 SBL_log(SBL_LOG_ERR,"SYSFW Get Version failed \n");
383 #endif
384                 SblErrLoop(__FILE__, __LINE__);
385             }
386         }
387     }
390 #if (!defined(SBL_SKIP_BRD_CFG_PM)) || (!defined(SBL_SKIP_BRD_CFG_RM))
391     status = Sciclient_setBoardConfigHeader();
392     if (CSL_PASS == status)
393     {
394         SBL_log(SBL_LOG_MAX,"Sciclient_setBoardConfigHeader... PASSED\n");
395     }
396     else
397     {
398         SBL_log(SBL_LOG_ERR,"Sciclient_setBoardConfigHeader... FAILED\n");
399         SblErrLoop(__FILE__, __LINE__);
400     }
401 #endif
404 #if !defined(SBL_SKIP_MCU_RESET)
405     /* RTI seems to be turned on by ROM. Turning it off so that Power domain can transition */
406     Sciclient_pmSetModuleState(SBL_DEV_ID_RTI0, TISCI_MSG_VALUE_DEVICE_SW_STATE_AUTO_OFF, TISCI_MSG_FLAG_AOP, SCICLIENT_SERVICE_WAIT_FOREVER);
407     Sciclient_pmSetModuleState(SBL_DEV_ID_RTI1, TISCI_MSG_VALUE_DEVICE_SW_STATE_AUTO_OFF, TISCI_MSG_FLAG_AOP, SCICLIENT_SERVICE_WAIT_FOREVER);
408 #if defined(SOC_AM64X)
409     Sciclient_pmSetModuleState(SBL_DEV_ID_RTI8, TISCI_MSG_VALUE_DEVICE_SW_STATE_AUTO_OFF, TISCI_MSG_FLAG_AOP, SCICLIENT_SERVICE_WAIT_FOREVER);
410     Sciclient_pmSetModuleState(SBL_DEV_ID_RTI9, TISCI_MSG_VALUE_DEVICE_SW_STATE_AUTO_OFF, TISCI_MSG_FLAG_AOP, SCICLIENT_SERVICE_WAIT_FOREVER);
411     Sciclient_pmSetModuleState(SBL_DEV_ID_RTI10, TISCI_MSG_VALUE_DEVICE_SW_STATE_AUTO_OFF, TISCI_MSG_FLAG_AOP, SCICLIENT_SERVICE_WAIT_FOREVER);
412     Sciclient_pmSetModuleState(SBL_DEV_ID_RTI11, TISCI_MSG_VALUE_DEVICE_SW_STATE_AUTO_OFF, TISCI_MSG_FLAG_AOP, SCICLIENT_SERVICE_WAIT_FOREVER);
413     Sciclient_pmSetModuleState(SBL_DEV_ID_MCU_RTI0, TISCI_MSG_VALUE_DEVICE_SW_STATE_AUTO_OFF, TISCI_MSG_FLAG_AOP, SCICLIENT_SERVICE_WAIT_FOREVER);
414 #endif
415 #endif
418 #endif
420     SBL_ADD_PROFILE_POINT;
423 #if (!defined(SBL_SKIP_BRD_CFG_PM)) || (!defined(SBL_SKIP_BRD_CFG_RM))
424 static int32_t Sciclient_setBoardConfigHeader ()
426     int32_t status = CSL_PASS;
427 #if defined (SOC_J7200) || defined (SOC_J721E)
428     //uint32_t alignedOffset = ((SCICLIENT_BOARDCFG_PM_SIZE_IN_BYTES + 128U)/128U)*128U;
429     uint32_t alignedOffset = SCICLIENT_BOARDCFG_PM_SIZE_IN_BYTES;
430     Sciclient_BoardCfgPrms_t boardCfgPrms_pm =
431     {
432         .boardConfigLow = (uint32_t)SCISERVER_BOARDCONFIG_DATA_ADDR,
433         .boardConfigHigh = 0,
434         .boardConfigSize = SCICLIENT_BOARDCFG_PM_SIZE_IN_BYTES,
435         .devGrp = DEVGRP_ALL
436     };
437     Sciclient_BoardCfgPrms_t boardCfgPrms_rm =
438     {
439         .boardConfigLow =
440             (uint32_t) SCISERVER_BOARDCONFIG_DATA_ADDR + alignedOffset,
441         .boardConfigHigh = 0,
442         .boardConfigSize = SCICLIENT_BOARDCFG_RM_SIZE_IN_BYTES - gCertLength,
443         .devGrp = DEVGRP_ALL
444     };
445     status = Sciclient_boardCfgPrepHeader (
446         (uint8_t *) SCISERVER_COMMON_X509_HEADER_ADDR,
447         (uint8_t *) SCISERVER_BOARDCONFIG_HEADER_ADDR,
448         &boardCfgPrms_pm, &boardCfgPrms_rm);
449     if (CSL_PASS == status)
450     {
451         SBL_log(SBL_LOG_MAX,"SCISERVER Board Configuration header population... ");
452         SBL_log(SBL_LOG_MAX,"PASSED\n");
453     }
454     else
455     {
456         SBL_log(SBL_LOG_MIN,"SCISERVER Board Configuration header population... ");
457         SBL_log(SBL_LOG_MIN,"FAILED\n");
458     }
459     memcpy((void *)boardCfgPrms_pm.boardConfigLow, (void *) sblBoardCfgPmPrms.boardConfigLow, SCICLIENT_BOARDCFG_PM_SIZE_IN_BYTES);
460     memcpy((void *)boardCfgPrms_rm.boardConfigLow, (void *) sblBoardCfgRmPrms.boardConfigLow, SCICLIENT_BOARDCFG_RM_SIZE_IN_BYTES - gCertLength);
461 #endif
462     return status;
464 #endif