FAQ: Preload code customization

Document created by Kader.M Employee on Jun 15, 2017Last modified by Kader.M Employee on Jun 15, 2017
Version 2Show Document
  • View in full screen mode


 This document explains how to create/modify the preload program and .ld file for the custom target on ADSP-SC5XX.

 The following topics are discussed:

     Pre-load Files

     Default Preload and Initialization Code

     Default linker files for ARM

     Preload code, .ld file for any custom board                                

                Modifying preload code

                Modifying .ld file

     MMU Configuration




Pre-load Files

External memory needs to be configured appropriately before applications can be loaded. When the application boots, this is done through initcodes; when the application is loaded to target using the debugger, this can be done by the IDE automatically for simple processors.

For heterogeneous processors such as the ADSP-SC58x processors, more flexibility is required.


The main purpose of these pre-load files is to set up clocks and DMC settings so that the debugger is able to load the user’s application to external memory.


Preload programs or scripts are automatically set-up in a Debug configuration as illustrated below.





Default Preload and Initialization Code

The CCES installation provides the DXE files produced by the default preload and initialization code for each of the ADSP-SC589,ADSP-SC584,and ADSP-SC573 evaluation platforms in the directory:

[CCES_Install]/CrossCore Embedded Studio 2.x.x/SHARC/ldr


The corresponding source code and project files can be found in the /init_code subdirectory.

The default CGU configuration which the DMC initialization code is designed for is as follows:


  1. ADSP-SC589 EZ-Board Micron MT41K128M16-125DDR3 device with:
  • PLLCLK = CCLK = DCLK = 450MHz
  • SYSCLK = 225MHz
  • SCLK0 = SCLK1 = 112.5 MHz


  1. ADSP-SC584 EZ-Board Micron MT47H128M16RT-25E XIT:CDDR2 device with:
  • PLLCLK = CCLK = DCLK = 400MHz
  • SYSCLK = 200MHz
  • SCLK0 = SCLK1=100MHz


  1. ADSP-SC573 EZ-Board Micron MT41K128M16-125DDR3 device with:
  • SYSCLK=225MHz
  • SCLK0=SCLK1 =112.5 MHz


Default linker files for ARM

For ADI parts, typically two .ld files are used. The first provides the memory map of the specific part, and the second provides mappings of code and data sections to the previously defined memory map.

The default linker files for each multi-lib are located in the kit. For example, the ADSP-SC589, silicon revision "any" .ld files are located as follows:



The former file containing the memory map of the ADSP-SC589 part, and the latter file the section mappings.


Preload code, .ld file for any custom board

The CGU and DMC settings in the default preload and initialization source code may need to be modified for the following conditions:


  1. When using the EZ-Board(or a custom board with the same DDR memory device as

that populated on the EZ-Board) with non-default CGU settings.

  1. When using a custom board with a different memory device.

Modifying preload code:

The dynamic memory controller (DMC) provides a glueless interface between DDR3/DDR2/LPDDR SDRAMs and the system crossbar interface (SCB). The DMC enables execution of instructions from, as well as transfer of data to and from, DDR3, DDR2 SDRAM or LPDDR SDRAM respectively.

The DMC supports access to the external memory by core and DMA accesses.

By default there are two Dynamic Memory Controllers (DMC) on the ADSP-SC589 processor and one DMC on the ADSP-SC584 processor.

  1. Open the preload code for the necessary part from the latest CCES installation.

[CCES_Install]/CrossCore Embedded Studio 2.X.X/SHARC/ldr/init_code

  1. For the part which are not on the EZ-KIT, choose the one closest in terms of number of DMCs available or use the macro CONFIG_DMC0 /CONFIG_DMC1 respectively.
  2. Change the project setting from "C/C++ Build > Settings > Processor Settings" to match the processor on the custom board.
  3. By default DMC register values are for the Memory on EZ-KIT. For different memory, use "DMC_Registers_List.xlsx" sheet to provide input memory parameters and generate DDR register values. Update the sc58x_init.c with the new values.
  4. Now build the code and customized preload .dxe is generated.
  1. In main application, Core 0 first loads the default preload program from Session Tab. To modify the path, select the default preload program and Click edit to choose the custom preload file path.

Note: Unlike preload code, initialization code is actually a part of the application. Pre-load files should be used only during emulation. Do not use pre-load files when building bootable LDR files. To run from flash, the corresponding initcode file (created from the same source files as the pre-load file) ought to be selected in the initialization section while creating the loader file.

Modifying .ld file:

  1. Choose the closest part of .ld files from the below path:


         If Custom board have only one DMC, refer "adsp-sc584.ld" file for memory mappings and for two DMC, refer "adsp-sc589.ld".
         If custom board have one SHARC and one DMC, refer "adsp-sc582.ld"

  1. For ease, merge the 2 .ld files(adsp-sc5xx.ld & adsp-sc58x-common.ld) into a single file and alter it to re-map the data and code sections into respective memory region.
  2. Add the customized .ld file into ARM project by selecting Tool Settings -> Linker -> General and then adding a "Custom linker script".
  3. For ADSP-SC5xx parts, if the share of cached vs uncached memory, or the amount of memory assigned to the ARM vs the SHARC cores, is being altered then the MMU configuration may need to be altered to reflect this. Please refer to the MMU Configuration.

Note: Modification of  SHARC ldf is also required, if ARM uses the SHARC memory regions.


MMU Configuration

For ARM parts (or parts with an ARM core) with an MMU, the application start up code will automatically configure the MMU to match the default memory layout, as defined in the default linker scripts.

  1. However, the memory map has been customised for the application, then the MMU's configuration may need to be updated to match. In order to simplify this process, an abstract page table mechanism has been created to allow for easy alteration of the MMU's translation tables.
  2. To replace the default abstract page table, the user simply needs to define their own version of the abstract page table _adi_mmu_absPageTable (and associated _adi_mmu_absPageTableSize), to override the default weak definition.
  3. The easiest way to do this is to copy the MMU configuration "abstract page table" file into the application and then edit it. The default abstract page table can be found in the CCES installation directory:


     Each abstract page table entry is in the form: { StartAddress, EndAddress, Descriptor Value }

  1. Blocks of memory in the abstract page table should be no smaller than 4KB. For more details on ARM translation table descriptors, please refer to the Cortex-A Programmer's Guide.
  2. During application start up, the CRT will automatically call a function to parse the abstract page table, turn them into real page tables and then enable the MMU.


Question: What modifications have to be done, If the SC589 based custom board has one DMC.

Answer: Follow the below steps

  1. Open the copy of preload code from the CCES installation directory: [CCES_Install]/SHARC/ldr/init_code/SC58x_Init/sc589_preload_Core0
  2. Comment the below lines in sc58x_init.h, since custom board has only one DMC.

    #if !defined(CONFIG_DMC1)

   #define CONFIG_DMC1 (DMCMEM)


 Note: Update the sc58x_init.c file, if custom board has a different memory device.

  1. Change the processor and silicon Revision from "C/C++ Build > Settings > Processor Settings" to match the processor on the custom board. Build the preload project.
  2. Merge the 2 .ld files(adsp-sc589.ld & adsp-sc58x-common.ld) into a single file and remove the DMC1 memory region. Alter the memory section range(MEM_L3_CORE1_DATA2 & MEM_L3_CORE1_DATA2) to occupy ARM data and code. Likewise adsp-sc584.ld file

      MEM_L3_CORE1_DATA2 (r) : ORIGIN = 0x81000000, LENGTH = 62M /* SHARC CORE1 Data, DMC0 */ 

      MEM_L3_CORE2_DATA2 (r) : ORIGIN = 0x84E00000, LENGTH = 66M /* SHARC CORE2 Data, DMC0 */ 

      MEM_L3 : ORIGIN = 0x89000000, LENGTH = 112M /* ARM CORE 0 L3, DMC0 */

  1. Open the copy of MMU configuration "apt-sc589.c" file. Use the " 2 SHARC cores, 1 Dynamic Memory Controller " table entry.
  1. Open the main application, copy the modified .ld and apt-sc589.c file into source directory of the ARM project.
  2. In ARM project, under tool settings->linker settings -> Custom linker script file-> choose the ld file.
  3. In SHARC0 & SHARC1 project set DMC1 memory size to 0,under system.svc -> Startup Code/LDF tab -> LDF page as illustrated below.


  1. Build the code and load. In debug configuration, add the custom preload file instead of default one from session tab and choose application .dxe to reset the core before load


Below are the changes made in MMU configuration file, .ld file and LDF files for the above example (SC589 based custom board with one DMC):

L3 memory Configuration - DMC0:

0x80000000u to 0x802FFFFFu   /*   3MB DDR-A : SHARC0 NW code   */

0x80300000u to 0x805FFFFFu   /*   3MB DDR-A : SHARC1 NW code   */

0x80600000u to 0x809FFFFFu   /*   4MB DDR-A : SHARC0 data      */

0x80A00000u to 0x80CFFFFFu   /*   3MB DDR-A : SHARC0 VISA code */

0x80D00000u to 0x80FFFFFFu   /*   3MB DDR-A : SHARC1 VISA code */

0x81000000u to 0x84DFFFFFu   /*  62MB DDR-A : SHARC0 data2     */

0x84E00000u to 0x88FFFFFFu   /*  66MB DDR-A : SHARC1 data2     */

0x89000000u to 0x8FFFFFFFu   /* 112MB DDR-A : ARM    code & data */


MMU configuration - DMC0:

{ 0x80000000u, 0x802FFFFFu, ADI_MMU_RO_UNCACHED         }, /*   3MB DDR-A : SHARC0 NW code   */

{ 0x80300000u, 0x805FFFFFu, ADI_MMU_RO_UNCACHED         }, /*   3MB DDR-A : SHARC1 NW code   */

{ 0x80600000u, 0x809FFFFFu, SHARC_L3                                        },  /*   4MB DDR-A : SHARC0 data      */

{ 0x80A00000u, 0x80CFFFFFu, ADI_MMU_RO_UNCACHED         },  /*   3MB DDR-A : SHARC0 VISA code */

{ 0x80D00000u, 0x80FFFFFFu, ADI_MMU_RO_UNCACHED         },  /*   3MB DDR-A : SHARC1 VISA code */

{ 0x81000000u, 0x84DFFFFFu, SHARC_L3                                        },   /*  62MB DDR-A : SHARC0 data2     */

{ 0x84E00000u, 0x88FFFFFFu, SHARC_L3                                         },   /*  66MB DDR-A : SHARC1 data2     */

{ 0x89000000u, 0x8FFFFFFFu, ADI_MMU_WB_CACHED               },   /* 112MB DDR-A : ARM    code&data */


.ld file - DMC0:

  /* SHARC CORE 1 NW Code 3MB, DMC0 */

  MEM_L3_CORE1_NW_CODE (r) : ORIGIN = 0x80000000, LENGTH = 3M

  /* SHARC CORE2 NW Code 3MB, DMC0 */

  MEM_L3_CORE2_NW_CODE (r) : ORIGIN = 0x80300000, LENGTH = 3M



  MEM_L3_CORE1_DATA (r) : ORIGIN = 0x80600000, LENGTH = 4M


  /* SHARC CORE1 VISA Code 3MB, DMC0 */

  MEM_L3_CORE1_VISA_CODE (r) : ORIGIN = 0x80A00000, LENGTH = 3M


  /* SHARC CORE2 VISA Code 3MB, DMC0 */

  MEM_L3_CORE2_VISA_CODE (r) : ORIGIN = 0x80D00000, LENGTH = 3M



  MEM_L3_CORE1_DATA2 (r) : ORIGIN = 0x81000000, LENGTH = 62M



  MEM_L3_CORE2_DATA2 (r) : ORIGIN = 0x84E00000, LENGTH = 66M


  /* ARM CORE 0 L3 112MB, DMC0 */

  MEM_L3 : ORIGIN = 0x89000000, LENGTH = 112M




  //   DDR-A bank1 : SHARC0 NW code, 3MB

   //   DDR-A bank2 : SHARC1 NW code, 3MB

   //   DDR-A bank3 : SHARC0 data, 4MB

   //   DDR-A bank4 : SHARC0 VISA code, 3MB (reduced for 20000019 workaround)

   //   DDR-A bank5 : SHARC1 VISA code, 3MB (reduced for 20000019 workaround)

   //   DDR-A bank6 : SHARC0 data, 62MB

   //   DDR-A bank7 : SHARC1 data, 66MB

   //   DDR-A bank8 : ARM 112MB

   mem_DMC0_SDRAM_A1       { TYPE(BW RAM) START(0x80000000) END(0x802fffff) WIDTH(8) }

   mem_DMC0_SDRAM_A2       { TYPE(BW RAM) START(0x80300000) END(0x805fffff) WIDTH(8) }

   mem_DMC0_SDRAM_A3       { TYPE(BW RAM) START(0x80600000) END(0x809fffff) WIDTH(8) }

   #if defined(__WORKAROUND_20000019)

   mem_DMC0_SDRAM_A4       { TYPE(BW RAM) START(0x80a00000) END(0x80bfffff) WIDTH(8) }

   mem_DMC0_SDRAM_A5       { TYPE(BW RAM) START(0x80e00000) END(0x80ffffff) WIDTH(8) }


   mem_DMC0_SDRAM_A4       { TYPE(BW RAM) START(0x80a00000) END(0x80cfffff) WIDTH(8) }

   mem_DMC0_SDRAM_A5       { TYPE(BW RAM) START(0x80d00000) END(0x80ffffff) WIDTH(8) }


   mem_DMC0_SDRAM_A6       { TYPE(BW RAM) START(0x81000000) END(0x84dfffff) WIDTH(8) }

   mem_DMC0_SDRAM_A7       { TYPE(BW RAM) START(0x84e00000) END(0x88ffffff) WIDTH(8) }

   mem_DMC0_SDRAM_A8       { TYPE(BW RAM) START(0x89000000) END(0x8fffffff) WIDTH(8) }


Below is the Summary of changes for the above example (SC589 based custom board with one DMC):

  1. Define the shared memory configuration
  2. Change the MMU table entry configuration to access all three cores .
  3. Change .ld file and it needs to be exactly matched with MMU table entry.
  4. Change the SHARC LDF files as required.

Following files are attached with this FAQ for the above example (SC589 based custom board with one DMC):



     Contains modified preload code example for ADSP-SC589 processor.


     Contains modified linker description file for ADSP-SC589 processors.               


     Contains modified MMU configuration file.

2 people found this helpful