1 /**
2 * \file sbl_qspi.c
3 *
4 * \brief This file contains functions for QSPI read/write operations for SBL
5 *
6 */
8 /*
9 * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 *
15 * Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 *
18 * Redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the
21 * distribution.
22 *
23 * Neither the name of Texas Instruments Incorporated nor the names of
24 * its contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
30 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
31 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
32 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
33 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
34 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
35 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
36 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
37 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 *
39 */
41 /* ========================================================================== */
42 /* Include Files */
43 /* ========================================================================== */
44 #include <stdint.h>
45 #include "string.h"
47 /* TI-RTOS Header files */
48 #include <ti/drv/spi/SPI.h>
49 #include <ti/drv/spi/src/SPI_osal.h>
50 #include <ti/drv/uart/UART_stdio.h>
52 /* SBL Header files. */
53 #include "sbl_rprc_parse.h"
54 #include "sbl_soc.h"
56 #ifdef SECURE_BOOT
57 #include "sbl_sec.h"
58 #endif
60 /* Macro representing the offset where the App Image has to be written/Read from
61 the QSPI Flash.
62 */
63 #define QSPI_OFFSET_SI (0x80000)
65 /* QSPI Flash Read Sector API. */
66 int32_t SBL_QSPI_ReadSectors(void *dstAddr,
67 void *srcOffsetAddr,
68 uint32_t length);
70 /* Initialize the QSPI driver and the controller. */
71 void SBL_QSPI_Initialize();
73 /* Sets the src address to the given offset address. */
74 void SBL_QSPI_seek(void *srcAddr, uint32_t location);
76 int32_t SBL_QSPI_ReadSectors(void *dstAddr,
77 void *srcOffsetAddr,
78 uint32_t length);
80 void *boardHandle;
82 #ifdef SECURE_BOOT
83 extern SBL_incomingBootData_S sblInBootData;
85 int32_t SBL_loadQSPIBootData(void);
86 #endif
88 int32_t SBL_QSPIBootImage(sblEntryPoint_t *pEntry)
89 {
90 int32_t retVal;
92 #ifdef SECURE_BOOT
93 uint32_t authenticated = 0;
94 uint32_t srcAddr = 0;
95 uint32_t imgOffset = 0;
96 #else
97 uint32_t offset = QSPI_OFFSET_SI;
98 #endif
100 /* Initialization of the driver. */
101 SBL_QSPI_Initialize();
103 #ifndef SECURE_BOOT
104 retVal = SBL_MulticoreImageParse((void *) &offset, QSPI_OFFSET_SI, pEntry);
105 #else
106 retVal = SBL_loadQSPIBootData();
108 if (retVal == E_PASS)
109 {
110 /* authentiate it */
111 authenticated = SBL_authentication(sblInBootData.sbl_boot_buff);
112 if (authenticated == 0)
113 {
114 /* fails authentiation */
115 UART_printf("\n QSPI Boot - fail authentication\n");
117 retVal = E_FAIL;
118 }
119 else
120 {
121 /* need to skip the TOC headers */
122 imgOffset = ((uint32_t*)sblInBootData.sbl_boot_buff)[0];
123 srcAddr = (uint32_t)(sblInBootData.sbl_boot_buff) + imgOffset;
124 retVal = SBL_MulticoreImageParse((void *)srcAddr, 0, pEntry);
125 }
126 }
127 else
128 {
129 retVal = E_FAIL;
130 UART_printf("\n QSPI Boot - problem processing image \n");
131 }
133 /* install RAM Secure Kernel and overwrite DSP secure server*/
134 UART_printf("\n Starting Secure Kernel on DSP...\n");
135 SBL_startSK();
137 #endif
139 /* Close the QSPI driver */
140 SBL_qspiClose(&boardHandle);
142 return retVal;
143 }
145 void SBL_QSPI_Initialize()
146 {
147 SBL_qspiInit(&boardHandle);
149 /* Initialize the function pointers to parse through the RPRC format. */
151 #ifndef SECURE_BOOT
152 fp_readData = &SBL_QSPI_ReadSectors;
153 fp_seek = &SBL_QSPI_seek;
154 #else
155 fp_readData = &SBL_MemRead;
156 fp_seek = &SBL_MemSeek;
157 #endif
159 }
162 #ifndef SECURE_BOOT
164 int32_t SBL_QSPI_ReadSectors(void *dstAddr,
165 void *srcOffsetAddr,
166 uint32_t length)
167 {
168 int32_t ret;
169 ret = SBL_qspiFlashRead(&boardHandle, (uint8_t *) dstAddr, length,
170 *((uint32_t *) srcOffsetAddr));
171 *((uint32_t *) srcOffsetAddr) += length;
172 return ret;
173 }
175 void SBL_QSPI_seek(void *srcAddr, uint32_t location)
176 {
177 *((uint32_t *) srcAddr) = location;
178 }
180 #else
182 /* load signed boot data from QSPI */
183 int32_t SBL_loadQSPIBootData()
184 {
185 int32_t retVal = E_PASS;
186 uint32_t key_size = 0;
187 uint32_t load_size = 0;
188 uint32_t total_size = 0;
189 uint8_t *u8Ptr = 0;
191 sblInBootData.sbl_boot_size = 0;
192 sblInBootData.sbl_boot_buff_idx = 0; /* reset the read pointer */
194 u8Ptr = sblInBootData.sbl_boot_buff;
196 /* first read a block to figure out the max size */
197 retVal = SBL_qspiFlashRead(&boardHandle, sblInBootData.sbl_boot_buff,
198 READ_BUFF_SIZE, QSPI_OFFSET_SI);
200 if (retVal == E_PASS)
201 {
202 if (strcmp((char *)&u8Ptr[TOC_HDR_SIZE + TOC_FILE_NAME_OFFSET], "KEYS")==0)
203 {
204 /* first TOC HDR is IMG. Second TOC HDR is image */
205 key_size = *(uint32_t*)(&u8Ptr[TOC_HDR_SIZE + TOC_DAT_SIZE_OFFSET]);
207 if (strcmp((char *)&u8Ptr[TOC_FILE_NAME_OFFSET], "2ND")==0)
208 {
209 load_size = *(uint32_t*)(&u8Ptr[TOC_DAT_SIZE_OFFSET]);
211 total_size = key_size + load_size + 0x60;
212 sblInBootData.sbl_boot_size = total_size;
214 if (total_size < SBL_MAX_BOOT_BUFF_SIZE)
215 {
216 /* read the entire boot data in */
217 retVal = SBL_qspiFlashRead(&boardHandle,
218 sblInBootData.sbl_boot_buff,
219 total_size,
220 QSPI_OFFSET_SI);
221 }
222 else
223 {
224 /* not enough buffer to read entire boot data */
225 retVal = E_FAIL;
226 }
227 }
228 else
229 {
230 /* bad or unsupported image type */
231 retVal = E_FAIL;
232 }
233 }
234 else
235 {
236 /* Keys not found */
237 retVal = E_FAIL;
238 }
239 }
240 else
241 {
242 /* Fail to read the QSPI flash */
243 retVal = E_FAIL;
244 }
247 return retVal;
248 }
249 #endif