AM2634-Q1: AM2634 mpu_init failure Core 2

Part Number: AM2634-Q1
Other Parts Discussed in Thread: AM2634

 

 

I have a question regarding the mpu_init() function. Basically this function is called by c_init(), but is called before ti_auto_init. I get stuck in the assert for Mpu region size, this is because I see the gMpuCongif which is generated by the syscfg is not initialised before calling mpu_init. What am I missing here?

 

  • I already looked at this TI thread:

     AM2432: Do we need to use "--ram_model" option as an initialization model in linker runtime environment? 

    However even if I use rom_model the issue is the same since ti_auto_init is called after mpu_init(). Was there a fix made for Am2634 for this issue?

  • Hi Royston,

    There seems to be something strange with the code. I can see that the mpu related functions are lying in a different addres than it should be. I was running a the hello world example from the SDK and I can see that these functions lie in RAM but looking at the images, it is not so.

    Have you made any changes to the memory configurations for this to happen ?

    Regards,

    Aswin

  • Hi Aswin,

    The code is running for AM2634, AM2634 is a ROMless part and all code runs from RAM. This code is executed by Core 2 (i.e. cluster 1, core 0). The SBL loads TCMA, TCMB, Vectors for Core 2 and release core 2 from reset. Please find linker file attached

  • --retain="*(.intvecs)"
    --retain="*(.irqStack)"
    --retain="*(.fiqStack)"
    --retain="*(.abortStack)"
    --retain="*(.undefinedstack)"
    --retain="*(.svcStack)"
    /* This is the stack that is used by code running within main()
     * In case of NORTOS,
     * - This means all the code outside of ISR uses this stack
     * In case of FreeRTOS
     * - This means all the code until vTaskStartScheduler() is called in main()
     *   uses this stack.
     * - After vTaskStartScheduler() each task created in FreeRTOS has its own stack
     */
    --stack_size=16384
    /* This is the heap size for malloc() API in NORTOS and FreeRTOS
     * This is also the heap used by pvPortMalloc in FreeRTOS
     */
    --heap_size=256
    -e_vectors  /* This is the entry of the application, _vector MUST be plabed starting address 0x0 */
    
    /* This is the size of stack when R5 is in IRQ mode
     * In NORTOS,
     * - Here interrupt nesting is disabled as of now
     * - This is the stack used by ISRs registered as type IRQ
     * In FreeRTOS,
     * - Here interrupt nesting is enabled
     * - This is stack that is used initally when a IRQ is received
     * - But then the mode is switched to SVC mode and SVC stack is used for all user ISR callbacks
     * - Hence in FreeRTOS, IRQ stack size is less and SVC stack size is more
     */
    __IRQ_STACK_SIZE = 256;
    /* This is the size of stack when R5 is in IRQ mode
     * - In both NORTOS and FreeRTOS nesting is disabled for FIQ
     */
    __FIQ_STACK_SIZE = 256;
    __SVC_STACK_SIZE = 4096; /* This is the size of stack when R5 is in SVC mode */
    __ABORT_STACK_SIZE = 256;  /* This is the size of stack when R5 is in ABORT mode */
    __UNDEFINED_STACK_SIZE = 256;  /* This is the size of stack when R5 is in UNDEF mode */
    
    SECTIONS
    {
        /* This has the R5F entry point and vector table, this MUST be at 0x0 */
        .vectors:{} palign(8) > R5F_VECS
    
        /*Code changes*/
        .intvecs 	 : {} palign(8) 		> R5F_TCMA
        .controlfnc  : {} palign(8) 		> R5F_TCMA
        .controldata : {} palign(8)		    > R5F_TCMB
    
        /* This has the R5F boot code until MPU is enabled,  this MUST be at a address < 0x80000000
         * i.e this cannot be placed in DDR
         */
        GROUP {
            .text.hwi: palign(8)
            .text.cache: palign(8)
            .text.mpu: palign(8)
            .text.boot: palign(8)
            .text:abort: palign(8) /* this helps in loading symbols when using XIP mode */
            .textTrig: palign(8)
        } > R5F_TCMA/*R5F_TCMA*/
    
        /* This is rest of code. This can be placed in DDR if DDR is available and needed */
        GROUP {
            .text:   {} palign(8)   /* This is where code resides */
            .rodata: {} palign(8)   /* This is where const's go */
        } > OCRAM
    
        /* This is rest of initialized data. This can be placed in DDR if DDR is available and needed */
        GROUP {
            .data:   {} palign(8)/*(128)*/   /* This is where initialized globals and static go */
        } > OCRAM
    
    
        GROUP {
            .cinit: {} palign(8)
        } > OCRAM
    
    
    
        /* This is rest of uninitialized data. This can be placed in DDR if DDR is available and needed */
        GROUP {
            .bss:    {} palign(8)   /* This is where uninitialized globals go */
            RUN_START(__BSS_START)
            RUN_END(__BSS_END)
            .sysmem: {} palign(8)   /* This is where the malloc heap goes */
            .stack:  {} palign(8)   /* This is where the main() stack goes */
        } > OCRAM
    
        /* This is where the stacks for different R5F modes go */
        //.bss     	: {} align(4)  		> R5F_TCMB
        //.sysmem  	: {} align(8)		> R5F_TCMB
        //.stack  	: {} align(4)		> OCRAM
        .irqStack  	: {. = . + __IRQ_STACK_SIZE;} align(4)		> R5F_TCMA
        RUN_START(__IRQ_STACK_START)
        RUN_END(__IRQ_STACK_END)
        .fiqStack  	: {. = . + __FIQ_STACK_SIZE;} align(4)		> R5F_TCMB
        RUN_START(__FIQ_STACK_START)
        RUN_END(__FIQ_STACK_END)
        .abortStack  	: {. = . + __ABORT_STACK_SIZE;} align(4)		> R5F_TCMB
        RUN_START(__ABORT_STACK_START)
        RUN_END(__ABORT_STACK_END)
        .undefinedstack  	: {. = . + __UNDEFINED_STACK_SIZE;} align(4)		> R5F_TCMB
        RUN_START(__UNDEFINED_STACK_START)
        RUN_END(__UNDEFINED_STACK_END)
        .svcStack  	: {. = . + __SVC_STACK_SIZE;} align(4)		> R5F_TCMB
        RUN_START(__SVC_STACK_START)
        RUN_END(__SVC_STACK_END)
    
        /*GROUP {
            .irqstack: {. = . + __IRQ_STACK_SIZE;} align(8)
            RUN_START(__IRQ_STACK_START)
            RUN_END(__IRQ_STACK_END)
            .fiqstack: {. = . + __FIQ_STACK_SIZE;} align(8)
            RUN_START(__FIQ_STACK_START)
            RUN_END(__FIQ_STACK_END)
            .svcstack: {. = . + __SVC_STACK_SIZE;} align(8)
            RUN_START(__SVC_STACK_START)
            RUN_END(__SVC_STACK_END)
            .abortstack: {. = . + __ABORT_STACK_SIZE;} align(8)
            RUN_START(__ABORT_STACK_START)
            RUN_END(__ABORT_STACK_END)
            .undefinedstack: {. = . + __UNDEFINED_STACK_SIZE;} align(8)
            RUN_START(__UNDEFINED_STACK_START)
            RUN_END(__UNDEFINED_STACK_END)
        } > OCRAM*/
    
        /* Sections needed for C++ projects */
        GROUP {
            .ARM.exidx:  {} palign(8)   /* Needed for C++ exception handling */
            .init_array: {} palign(8)   /* Contains function pointers called before main */
            .fini_array: {} palign(8)   /* Contains function pointers called after main */
        } > OCRAM
    
        /* General purpose user shared memory, used in some examples */
        .bss.user_shared_mem (NOLOAD) : {} > USER_SHM_MEM
        /* this is used when Debug log's to shared memory are enabled, else this is not used */
        .bss.log_shared_mem  (NOLOAD) : {} > LOG_SHM_MEM
        /* this is used only when IPC RPMessage is enabled, else this is not used */
        .bss.ipc_vring_mem   (NOLOAD) : {} > RTOS_NORTOS_IPC_SHM_MEM
    }
    
    MEMORY
    {
        R5F_VECS  : ORIGIN = 0x00000000 , LENGTH = 0x00000040
        R5F_TCMA  : ORIGIN = 0x00000040 , LENGTH = 0x00007FC0
        R5F_TCMB  : ORIGIN = 0x00080000 , LENGTH = 0x00008000
    
        /* when using multi-core application's i.e more than one R5F/M4F active, make sure
         * this memory does not overlap with other R5F's
         */
        OCRAM     : ORIGIN = 0x70190000 , LENGTH = 0x30000
    
        /* This section can be used to put XIP section of the application in flash, make sure this does not overlap with
         * other CPUs. Also make sure to add a MPU entry for this section and mark it as cached and code executable
         */
        FLASH     : ORIGIN = 0x60200000 , LENGTH = 0x80000
    
    
        /* shared memories that are used by RTOS/NORTOS cores */
        /* On R5F,
         * - make sure there is a MPU entry which maps below regions as non-cache
         */
        USER_SHM_MEM            : ORIGIN = 0x701D0000, LENGTH = 0x00004000
        LOG_SHM_MEM             : ORIGIN = 0x701D4000, LENGTH = 0x00004000
        /* MSS mailbox memory is used as shared memory, we dont use bottom 32*12 bytes, since its used as SW queue by ipc_notify */
        RTOS_NORTOS_IPC_SHM_MEM : ORIGIN = 0x72000000, LENGTH = 0x3E80
        MAILBOX_HSM:    ORIGIN = 0x44000000 , LENGTH = 0x000003CE
        MAILBOX_R5F:    ORIGIN = 0x44000400 , LENGTH = 0x000003CE
    }
    
    

  • Hi Aswin,

    I realized that SBL is responsible for initializing or loading the gMpuConfig from ROM to RAM as ti_auto_init happens at a later stage. I did this and then the code worked fine. Not sure if this is a workaround or recommended process for the SBL to load gMpuConfi

  • Hi Royston,

    The SBL copies the application to RAM. MPU configs that are a part of application are also copied in this process. May I know what change was done as this is the default behaviour ?

    Regards,

    Aswin

  • Hi Aswin,

    I am using Boot Manager from Autosar vendor and Autosar as well. Can share more details over an email. Thank you for confirming this was default behavior that MPU configs for application needed to be loaded by SBL. 

  • Thank you for the details and confirmation.