]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - processor-sdk/performance-audio-sr.git/blob - pdk_k2g_1_0_1_0_eng/packages/ti/boot/sbl/src/rprc/sbl_rprc.c
Change pdk_k2g_1_0_1 directory name in preparation for updating RSTC plugin
[processor-sdk/performance-audio-sr.git] / pdk_k2g_1_0_1_0_eng / packages / ti / boot / sbl / src / rprc / sbl_rprc.c
1 /**
2  *  \file   sbl_rprc.c
3  *
4  *  \brief  This file contains functions to parse the multi-core
5  *          image file & loads into CPU internal memory & external memory.
6  *
7  */
9 /*
10  * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  *
16  * Redistributions of source code must retain the above copyright
17  * notice, this list of conditions and the following disclaimer.
18  *
19  * Redistributions in binary form must reproduce the above copyright
20  * notice, this list of conditions and the following disclaimer in the
21  * documentation and/or other materials provided with the
22  * distribution.
23  *
24  * Neither the name of Texas Instruments Incorporated nor the names of
25  * its contributors may be used to endorse or promote products derived
26  * from this software without specific prior written permission.
27  *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39  *
40  */
42 #include "sbl_rprc_parse.h"
44 /* TI-RTOS Header files */
45 #include <ti/drv/uart/UART_stdio.h>
46 #include <ti/csl/cslr_device.h>
48 #include <stdio.h>
49 #include "sbl_image_copy.h"
51 /* ========================================================================== */
52 /*                         Structures and Enums                               */
53 /* ========================================================================== */
55 /*
56 **    Enumerates the different cores present on AM57x device.
57 */
58 typedef enum cpu_core_id
59 {
60     MPU_CPU0_ID = 0,
61     MPU_CPU1_ID,
62     IPU1_CPU0_ID,
63     IPU1_CPU1_ID,
64     IPU1_CPU_SMP_ID,
65     IPU2_CPU0_ID,
66     IPU2_CPU1_ID,
67     IPU2_CPU_SMP_ID,
68     DSP1_ID,
69     DSP2_ID,
70 }cpu_core_id_t;
72 typedef struct rprcFileHeader {
73     uint32_t magic;
74     uint32_t entry;
75     uint32_t rsvd_addr;
76     uint32_t SectionCount;
77     uint32_t version;
78 } rprcFileHeader_t;
80 typedef struct rprcSectionHeader {
81     uint32_t addr;
82     uint32_t rsvd_addr;
83     uint32_t size;
84     uint32_t rsvdCrc;
85     uint32_t rsvd;
86 } rprcSectionHeader_t;
88 typedef struct meta_header_start
89 {
90     uint32_t magic_str;
91     uint32_t num_files;
92     uint32_t dev_id;
93     uint32_t rsvd;
94 }meta_header_start_t;
96 typedef struct meta_header_core
97 {
98     uint32_t core_id;
99     uint32_t image_offset;
100 }meta_header_core_t;
102 typedef struct meta_header_end
104     uint32_t rsvd;
105     uint32_t magic_string_end;
106 }meta_header_end_t;
108 /* Magic numbers for gforge and sourceforge */
109 #define MAGIC_NUM_GF          (0xA1ACED00)
110 #define MAGIC_NUM_SF          (0x55424CBB)
112 /* Magic number and tokens for RPRC format */
113 #define RPRC_MAGIC_NUMBER   0x43525052
114 #define RPRC_RESOURCE       0
115 #define RPRC_BOOTADDR       5
117 #define MAX_INPUT_FILES 10
118 #define META_HDR_MAGIC_STR 0x5254534D /* MSTR in ascii */
119 #define META_HDR_MAGIC_END 0x444E454D /* MEND in ascii */
121 #define SOC_OCMC_RAM1_SIZE          ((uint32_t) 0x80000)     /*OCMC1 512KB*/
122 #define SOC_OCMC_RAM2_SIZE          ((uint32_t) 0x100000)    /*OCMC2 1MB   */
123 #define SOC_OCMC_RAM3_SIZE          ((uint32_t) 0x100000)    /*OCMC3  1MB   */
125 #define MPU_IPU1_ROM                    (CSL_IPU_IPU1_TARGET_REGS)
127 #define MPU_IPU1_RAM                    (CSL_IPU_IPU1_TARGET_REGS + \
128                                             (uint32_t) 0x20000)
130 #define MPU_IPU2_ROM                    (CSL_IPU_IPU1_ROM_REGS)
132 #define MPU_IPU2_RAM                    (CSL_IPU_IPU1_ROM_REGS + \
133                                             (uint32_t) 0x20000)
135 #define MPU_DSP1_L2_RAM                 (0x40800000)
136 #define MPU_DSP1_L1P_CACHE              (0x40E00000)
137 #define MPU_DSP1_L1D_CACHE              (0x40F00000)
138 #define MPU_DSP2_L2_RAM                 (0x41000000)
139 #define MPU_DSP2_L1P_CACHE              (0x41600000)
140 #define MPU_DSP2_L1D_CACHE              (0x41700000)
142 #define SOC_DSP_L2_BASE                 (0x800000)
143 #define SOC_DSP_L1P_BASE                (0xe00000)
144 #define SOC_DSP_L1D_BASE                (0xf00000)
146 /* Function Pointer used while reading data from the storage. */
147 int32_t (*fp_readData)(void *dstAddr, void *srcAddr,
148                         uint32_t length);
150 /* Function Pointer used while reading data from the storage. */
151 void  (*fp_seek)(void *srcAddr, uint32_t location);
153 /**
154  * \brief           SBL_RprcImageParse function parse the RPRC executable image.
155  *                  Copies individual section into destination location
156  *
157  * \param[in]    srcAddr - Pointer RPRC image
158  * \param[out] entryPoint - CPU entry point address
159  * \param[in]    CoreId - CPU ID to identify the CPU core
160  *
161  *
162  * \return uint32_t: Status (success or failure)
163  */
164 static int32_t SBL_RprcImageParse(void *srcAddr, uint32_t *entryPoint,
165                               int32_t CoreId);
167 /**
168  * \brief        SBL_BootCore function stores the CPU entry location into
169  *               global pointer.
170  *
171  * \param[in]    entry - CPU Entry location
172  * \param[in]    entryPoint - CPU ID
173  *
174  * \return   none
175  */
176 void SBL_BootCore(uint32_t entry, uint32_t CoreID, sblEntryPoint_t *pAppEntry);
178 int32_t GetDeviceId(void);
180 /**
181  * \brief           QSPIBootRprc function parses the multi-core app image
182  *                  stored in the QSPI serial flash.
183  *                  It Parses the AppImage & copies the section into CPU
184  *                  internal memory & external memory.
185  *                  CPUs entry loctions are stored into entry point
186  *                  global pointers.
187  *
188  *
189  * \param               none
190  *
191  *
192  * \return          error status.If error has occured it returns a non zero
193  *                  value.
194  *                  If no error has occured then return status will be
195  *                  zero.
196  */
198 /******************************************************************************
199 **                       SBL Multicore RPRC parse functions
200 *******************************************************************************/
202 int32_t SBL_MulticoreImageParse(void *srcAddr,
203                                 uint32_t ImageOffset,
204                                 sblEntryPoint_t *pAppEntry)
206     uint32_t            i;
207     uint32_t            entryPoint = 0;
208     meta_header_start_t mHdrStr;
209     meta_header_core_t  mHdrCore[MAX_INPUT_FILES];
210     meta_header_end_t   mHdrEnd;
211     int32_t magic_str = META_HDR_MAGIC_STR;
212     int32_t retVal    = E_PASS;
214     if ((fp_readData == NULL) || (fp_seek == NULL))
215     {
216         retVal = E_FAIL;
217     }
218     else
219     {
220         /* Read Meta Header Start and get the Number of Input RPRC Files */
221         fp_readData(&mHdrStr, srcAddr, sizeof (meta_header_start_t));
222         if (mHdrStr.magic_str != (uint32_t) magic_str)
223         {
224             UART_printf("Invalid magic number in Single image header\r\n");
225             retVal = E_FAIL;
226         }
227         else
228         {
229             if (mHdrStr.dev_id != GetDeviceId())
230             {
231                 UART_printf("\nWARNING: Device Id Doesnot match\r\n");
232             }
234             /* Read all the Core offset addresses */
235             for (i = 0; i < mHdrStr.num_files; i++)
236             {
237                 fp_readData(&mHdrCore[i], srcAddr, sizeof (meta_header_core_t));
238             }
240             /* Add Base Offset address for All core Image start offset */
241             for (i = 0; i < mHdrStr.num_files; i++)
242             {
243                 mHdrCore[i].image_offset += ImageOffset;
244             }
246             /* Read Meta Header End */
247             fp_readData(&mHdrEnd, srcAddr, sizeof (meta_header_end_t));
249             /* Now Parse Individual RPRC files */
251             for (i = 0; i < mHdrStr.num_files; i++)
252             {
253                 if (mHdrCore[i].core_id != (0xFFFFFFFFU))
254                 {
255                     fp_seek(srcAddr, mHdrCore[i].image_offset);
256                     if (SBL_RprcImageParse(srcAddr, &entryPoint,
257                                        mHdrCore[i].core_id) != E_PASS)
258                     {
259                         /* Error occurred parsing the RPRC file continue to
260                          * parsing next
261                          * image and skip booting the particular core */
262                         UART_printf("RPRC parse error\n");
263                         retVal = E_FAIL;
264                     }
265                     else
266                     {
267                         SBL_BootCore(entryPoint, mHdrCore[i].core_id, pAppEntry);
268                     }
269                 }
270             }
271         }
272     }
273     return retVal;
276 void SBL_BootCore(uint32_t entry, uint32_t CoreID, sblEntryPoint_t *pAppEntry)
278     switch (CoreID)
279     {
280         case MPU_CPU0_ID:
281             /* CSL_MPU CPU0*/
282             UART_printf("\n MPU CPU0 image load completed \n");
283             pAppEntry->entryPoint_MPU_CPU0 = entry;
284             break;
286 #if defined (AM572x_BUILD)
287         case MPU_CPU1_ID:
288             /* CSL_MPU CPU1 */
289             UART_printf("\n MPU CPU1 image load completed \n");
290             pAppEntry->entryPoint_MPU_CPU1 = entry;
291             break;
292 #endif
294         case IPU1_CPU0_ID:
295             /*IPU1 CPU0*/
296             UART_printf("\n IPU1 CPU0 image load completed \n");
297             pAppEntry->entryPoint_IPU1_CPU0 = entry;
298             break;
300         case IPU1_CPU1_ID:
301             /*IPU1 CPU1*/
302             UART_printf("\n IPU1 CPU1 image load completed \n");
303             pAppEntry->entryPoint_IPU1_CPU1 = entry;
304             break;
306         case IPU1_CPU_SMP_ID:
307             /*IPU1 CPU0 & CPU1*/
308             UART_printf(
309                        "\n IPU1 CPU0 & CPU1 image load completed \n");
310             pAppEntry->entryPoint_IPU1_CPU0 = entry;
311             pAppEntry->entryPoint_IPU1_CPU1 = entry;
312             break;
314 #if defined (AM572x_BUILD)
315         case IPU2_CPU0_ID:
316             /*IPU2 CPU0*/
317             UART_printf("\n IPU2 CPU0 image load completed \n");
318             pAppEntry->entryPoint_IPU2_CPU0 = entry;
319             break;
321         case IPU2_CPU1_ID:
322             /*IPU2 CPU1*/
323             UART_printf("\n IPU2 CPU1 image load completed \n");
324             pAppEntry->entryPoint_IPU2_CPU1 = entry;
325             break;
327         case IPU2_CPU_SMP_ID:
328             /*IPU2 CPU0 & CPU1*/
329             UART_printf(
330                        "\n IPU2 CPU0 & CPU1  image load completed \n");
331             pAppEntry->entryPoint_IPU2_CPU0 = entry;
332             pAppEntry->entryPoint_IPU2_CPU1 = entry;
333             break;
334 #endif
335         case DSP1_ID:
336             /* DSP1*/
337             UART_printf("\n DSP1 image load completed \n");
338             pAppEntry->entryPoint_DSP1 = entry;
339             break;
341 #if defined (AM572x_BUILD)
342         case DSP2_ID:
343             /* DSP2*/
344             UART_printf("\n DSP2 image load completed \n");
345             pAppEntry->entryPoint_DSP2 = entry;
346             break;
347 #endif
348             default:
349             /* Wrong CPU ID */
350             UART_printf("\n Tried to boot Unknown Core \n");
351             break;
352     }
355 static int32_t SBL_RprcImageParse(void *srcAddr,
356                                   uint32_t *entryPoint,
357                                   int32_t CoreId)
359     rprcFileHeader_t    header;
360     rprcSectionHeader_t section;
361     int32_t i;
362     int32_t retVal = E_PASS;
364     /*read application image header*/
365     fp_readData(&header, srcAddr, sizeof (rprcFileHeader_t));
367     /*check magic number*/
368     if (header.magic != RPRC_MAGIC_NUMBER)
369     {
370         UART_printf("Invalid magic number in boot image. Expected: %x, received: %x\n", RPRC_MAGIC_NUMBER, header.magic);
371         retVal = E_FAIL;
372     }
373     else
374     {
375         /* Set the Entry Point */
376         *entryPoint = header.entry;
378         /*read entrypoint and copy sections to memory*/
379         for (i = 0; i < header.SectionCount; i++)
380         {
381             /*read new section header*/
382             fp_readData(&section, srcAddr, sizeof (rprcSectionHeader_t));
384 #if defined(K2G_BUILD)
385             if ((section.addr >= CSL_MSMC_SRAM_REGS) &&
386                 (section.addr < CSL_MSMC_SRAM_REGS + CSL_MSMC_SRAM_REGS_SIZE))
387             {
389             }
390             else if (section.addr >= CSL_DDR_0_DATA)
391             {
393             }
394             else if ((section.addr >= CSL_C66X_COREPAC_LOCAL_L2_SRAM_REGS) &&
395                 (section.addr < CSL_C66X_COREPAC_LOCAL_L2_SRAM_REGS + CSL_C66X_COREPAC_LOCAL_L2_SRAM_REGS_SIZE))
396             {
397                 section.addr |= 0x10000000;
398             }
399             else
400             {
401                 
402             }
403 #else
404 #if defined (AM572x_BUILD)
405             if (((section.addr >= CSL_MPU_OCMC_RAM1_REGS) &&
406                  (section.addr < (CSL_MPU_OCMC_RAM1_REGS + SOC_OCMC_RAM1_SIZE))) ||
407                 ((section.addr >= CSL_MPU_OCMC_RAM2_REGS) &&
408                  (section.addr < (CSL_MPU_OCMC_RAM2_REGS + SOC_OCMC_RAM2_SIZE))) ||
409                 ((section.addr >= CSL_MPU_OCMC_RAM3_REGS) &&
410                  (section.addr < (CSL_MPU_OCMC_RAM3_REGS + SOC_OCMC_RAM3_SIZE))))
411 #elif defined (AM571x_BUILD)
412             if ((section.addr >= CSL_MPU_OCMC_RAM1_REGS) &&
413                  (section.addr < (CSL_MPU_OCMC_RAM1_REGS + SOC_OCMC_RAM1_SIZE)))
414 #endif
415             {
416                 /* Internal OCMC RAM Space for all the cores */
417             }
418             /*copy section to memory*/
419             /*check for section mapped into CPU internal memories*/
420             else if (section.addr < 0x80000000U)
421             {
422                 switch (CoreId)
423                 {
424                     case MPU_CPU0_ID:
425                         /*No action*/
426                         break;
427 #if defined (AM572x_BUILD)
428                     case MPU_CPU1_ID:
429                         /*No action*/
430                         break;
431 #endif
432                     case IPU1_CPU0_ID:
433                     case IPU1_CPU1_ID:
434                     case IPU1_CPU_SMP_ID:
436                         if (((section.addr >= CSL_IPU_IPU1_BOOT_SPACE_REGS) &&
437                              (section.addr <
438                               (CSL_IPU_IPU1_BOOT_SPACE_REGS + 0x10000U))) ||
439                             ((section.addr >= CSL_IPU_IPU1_RAM_REGS) &&
440                              (section.addr < (CSL_IPU_IPU1_RAM_REGS + 0x10000))))
441                         {
442                             section.addr = section.addr & 0x000FFFFFU;
443                             section.addr = MPU_IPU1_RAM + section.addr;
444                         }
445                         else
446                         {
447                             UART_puts("IPU1 - Invalid Memory section", -1);
448                         }
450                         break;
451 #if defined (AM572x_BUILD)
452                     case IPU2_CPU0_ID:
453                     case IPU2_CPU1_ID:
454                     case IPU2_CPU_SMP_ID:
455                         if (((section.addr >= CSL_IPU_IPU1_BOOT_SPACE_REGS) &&
456                              (section.addr <
457                               (CSL_IPU_IPU1_BOOT_SPACE_REGS + 0x10000U)))
458                             ||
459                             ((section.addr >= CSL_IPU_IPU1_RAM_REGS) &&
460                              (section.addr < (CSL_IPU_IPU1_RAM_REGS + 0x10000))))
461                         {
462                             section.addr = section.addr & 0x000FFFFFU;
463                             section.addr = MPU_IPU2_RAM + section.addr;
464                         }
465                         else
466                         {
467                             UART_puts("IPU2  - Invalid Memory section", -1);
468                         }
470                         break;
471 #endif
472                     case DSP1_ID:
474                         if ((section.addr >= SOC_DSP_L2_BASE) &&
475                             (section.addr < (SOC_DSP_L2_BASE + 0x48000)))
476                         {
477                             /* L2 RAM Read the offset */
478                             section.addr = section.addr - SOC_DSP_L2_BASE;
479                             section.addr = MPU_DSP1_L2_RAM + section.addr;
480                         }
481                         else if ((section.addr >= SOC_DSP_L1P_BASE) &&
482                                  (section.addr < (SOC_DSP_L1P_BASE + 0x8000)))
483                         {
484                             /* CSL_MPU_DSP1_L1P_CACHE Read the offset */
485                             section.addr = section.addr - SOC_DSP_L1P_BASE;
486                             section.addr = MPU_DSP1_L1P_CACHE + section.addr;
487                         }
488                         else if ((section.addr >= SOC_DSP_L2_BASE) &&
489                                  (section.addr < (SOC_DSP_L2_BASE + 0x8000)))
490                         {
491                             /* CSL_MPU_DSP1_L1D_CACHE */
492                             section.addr = section.addr - SOC_DSP_L2_BASE;
493                             section.addr = MPU_DSP1_L1D_CACHE + section.addr;
494                         }
495                         else
496                         {
497                             UART_puts("DSP1 - Invalid Memory section", -1);
498                         }
500                         break;
501 #if defined (AM572x_BUILD)
502                     case DSP2_ID:
504                         if ((section.addr >= SOC_DSP_L2_BASE) &&
505                             (section.addr < (SOC_DSP_L2_BASE + 0x48000)))
506                         {
507                             /* DSP2 L2 RAM Read the offset */
508                             section.addr = section.addr - SOC_DSP_L2_BASE;
509                             section.addr = MPU_DSP2_L2_RAM + section.addr;
510                         }
511                         else if ((section.addr >= SOC_DSP_L1P_BASE) &&
512                                  (section.addr < (SOC_DSP_L1P_BASE + 0x8000)))
513                         {
514                             /* CSL_MPU_DSP2_L1P_CACHE Read the offset */
515                             section.addr = section.addr - SOC_DSP_L1P_BASE;
516                             section.addr = MPU_DSP2_L1P_CACHE + section.addr;
517                         }
518                         else if ((section.addr >= SOC_DSP_L1D_BASE) &&
519                                  (section.addr < (SOC_DSP_L1D_BASE + 0x8000)))
520                         {
521                             /* CSL_MPU_DSP2_L1D_CACHE */
522                             section.addr = section.addr - SOC_DSP_L1D_BASE;
523                             section.addr = MPU_DSP2_L1D_CACHE + section.addr;
524                         }
525                         else
526                         {
527                             UART_puts("DSP2 - Invalid Memory section", -1);
528                         }
530                         break;
531 #endif
532                     default:
533                         break;
534                 }
535             }
536             else
537             {
538                 /* To remove MISRA C error */
539             }
540 #endif
541             fp_readData((void *) section.addr, srcAddr, section.size);
542         }
543     }
544     return retVal;
547 /**
548  * \brief  Function to read the device ID
549  *
550  *
551  * \param   None.
552  *
553  * \return   Return the device id
554  *
555  **/
556 int32_t GetDeviceId(void)
558     int32_t deviceId = 55;
559     return (deviceId);