This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[DRA829]About Xip questions and confirmation

Hi,Experts

On the development board, I am using SDK7.0 to try to start the app in xip mode. The demo app in SDK7.0 can be started successfully. But I have a few questions to ask.

1.When using xip to start, the sbl_cust_img file is used, but in the code I see that the xip mode of OSPI is not turned on, as shown in the figure below. The SBL_HLOS_OWNS_FLASH compile option has be defined, so the ospi_cfg.xipEnable = false. Why can disable xip and demo start successfully??

2.The startup process of the demo is sbl_cust_img->sbl_baremetal_boot_xip_entry_j721e_evm_mcu1_0TestApp_release.appimage->can_profile_xip_app_mcu1_0_release.xer5f.bin.

At the same time, I also analyzed the role of each file. I think the role of the sbl_baremetal_boot_xip_entry_j721e_evm_mcu1_0TestApp_release.appimage file is just to make the PC pointer jump to the 0x500e0000 address to run can_profile_xip_app_mcu1_0_release.xer5f.bin. So I was wondering whether we can remove the sbl_baremetal_boot_xip_entry_j721e_evm_mcu1_0TestApp_release.appimage file, and then do a PC jump at the last step of the sbl_cust_img file?

3.Of course I tried it, but unfortunately I can jump to can_profile_xip_app_mcu1_0_release.xer5f.bin, but in the end the core died. Did I do something wrong? Or is this method not working? Please give me some support, thank you!The jump method and log information are shown in the figure below:

Please reply as soon as possible!

Regards,

Xie

  • Hi Xie,

    Linda Xie said:
    1.When using xip to start, the sbl_cust_img file is used, but in the code I see that the xip mode of OSPI is not turned on, as shown in the figure below. The SBL_HLOS_OWNS_FLASH compile option has be defined, so the ospi_cfg.xipEnable = false. Why can disable xip and demo start successfully??

    SBL_HLOS_OWNS_FLASH: 

    # If enabled, SBL will not leave the OSPI
    # flash in XIP mode, so that the MAIN
    # domain Cortex-A code (HLOS) can reset
    # the flash and take control of it, if
    # needed.

    This flag is used when we want to pass control to the HLOS. In case when this is ON, which is the default in CUST SBL build then the xipEnable flag is off.

    Now the question is how can we still run in XIP?

    xipEnable is used to turn on some additional optimizations when running in XIP. So if xipEnable is true then there will be somewhat better performance in the application. That being said, even when this flag is off the flash is in DAC mode. The flash in DAC mode gets memory mapped to the core's memory space and hence executing from it in DAC mode is also possible. 

    That is the reason why it works even when that flag is off. I would expect it to work even if you remove the SBL_HLOS_OWNS_FLASH flag from the CUST SBL and hence turning this flag on.

    Linda Xie said:

    2.The startup process of the demo is sbl_cust_img->sbl_baremetal_boot_xip_entry_j721e_evm_mcu1_0TestApp_release.appimage->can_profile_xip_app_mcu1_0_release.xer5f.bin.

    At the same time, I also analyzed the role of each file. I think the role of the sbl_baremetal_boot_xip_entry_j721e_evm_mcu1_0TestApp_release.appimage file is just to make the PC pointer jump to the 0x500e0000 address to run can_profile_xip_app_mcu1_0_release.xer5f.bin. So I was wondering whether we can remove the sbl_baremetal_boot_xip_entry_j721e_evm_mcu1_0TestApp_release.appimage file, and then do a PC jump at the last step of the sbl_cust_img file?

    Due to the nature of the SBL, it always copies the application to the core's memory and then brings the core out of reset. On in case of XIP, jumps to it. But in all cases - it copies. So just to have a trampoline sort of application which does nothing but sets the entry point to the actual application is used.

    I would believe that there would be a way to directly jump to the application too, but there could be things which might be needed to be modified and there is always a risk of some corner case which might be overlooked. The  sbl_baremetal_boot_xip_entry_j721e_evm_mcu1_0TestApp_release.appimage is tested and I would recommend that.

    Regards,

    Karan

  • Hi,Karan

    Karan Saxena said:
    I would believe that there would be a way to directly jump to the application too, but there could be things which might be needed to be modified and there is always a risk of some corner case which might be overlooked. The  sbl_baremetal_boot_xip_entry_j721e_evm_mcu1_0TestApp_release.appimage is tested and I would recommend that.

    Can you tell me about the risks? Then what should we do to avoid these risks?

    1.Then I have another question. When xip is running, it will jump to the address 0x500e0000 to run, and the .rstvectors is also at the address 0x500e0000; but the arm core will run from the address 0x0 after each reset, then do we need to copy a copy of the .rstvectors To address 0x0?

    2.Is the app file required for xip running in *.bin format (such as can_profile_xip_app_mcu1_0_release.xer5f.bin)? Can it be in other formats? Such as *.HEX?

    3.We compiled in the windows environment, and then used armobjcopy.exe to convert *.out to *.bin file, but the generated bin file is much larger than the out file. We think this is because of the problem of address discontinuity. How to avoid it What about this problem? I will attach our lds file later to help you troubleshoot problems

    lds file:

    map file:

    Regards,

    Xie

  • Hi,Karan

    Can you explain in detail how to implement data cection relocation in xip mode?
    At what stage is relocation implemented? Which piece of code does this function? I did not find it in the SDK package

    Regards,

    Xie

  • Hi Xie,

    The code relocation is only needed in case your application has a section which is Read-Write and is also initialized. Does you application has a section like this?

    Linda Xie said:
    Can you explain in detail how to implement data cection relocation in xip mode?

    The SDK application which run in XIP do not have this as there is no RW initialized section.

    I will send you a sample code for the same.

    Linda Xie said:
    At what stage is relocation implemented?

    The copy happens as the first instruction in main(). So in case the section you want to copy is being accessed before main() then this method won't work..

    Linda Xie said:
    Which piece of code does this function?

    So what can be done here is, you can specify different Load and Run address for that particular RW init section. The load address will be Flash (this will make the BIN small) and then the Run address will be in RAM (or any internal memory).

    The copy then needs to happen manually using a copy_in(&table_name) function. This will copy the section from the Load address to Run address. And the let us say that there was a variable X which was in that section - the program when referencing X, will always look at its run address. So you need to copy before you access X.

    Some documentation: 

    http://downloads.ti.com/docs/esd/SPRU513/the-table-operator-stdz0750717.html#STDZ0750717 

    http://downloads.ti.com/docs/esd/SPRU513/load-and-run-addresses-slau1317366.html

    https://downloads.ti.com/docs/esd/SPNU118N/Content/SPNU118N_HTML/linker_description.html

    I will also try to put together a sample code for the same. I will post it in a day.

    Regards,

    Karan

  • Hi,Karan

    Karan Saxena said:
    The code relocation is only needed in case your application has a section which is Read-Write and is also initialized. Does you application has a section like this?

    yeah,this is a very common feature。

    I have understood the role of load address and run address, and also learned that AT (load address) is used for relocation in lds files (for example, .data 0x41c300000 : AT(0x500e0200)), but we are using ti under ccs ti-cgt-arm_20.2.0. LTS compiler, the lds file he used does not seem to support AT keywords, so can you tell me how to relocate in the lds file?

    Looking forward to your quick reply

    Regards,

    Xie

  • Hi Xie,

    Below is snippet for the main.c file where the copy happens and also the linker file where we mention different load and run sections.

    Snippet for the Linker file:

    MEMORY
    {
        ...
        ...
     
        XIP_FLASH               : origin=0x500E0100 length=0x400000 - 0x100
        MSMC3_H (RWIX)          : origin=0x70100000 length=0xE2000               /* 1MB -56K */
        OCMRAM  (RWIX)          : origin=0x41C60000 length=0x20000 - 0x1000      /* ~124KB */
     
        ...
        ...
    }
     
    SECTIONS
    {
        ...
        ...
     
        .text_fast  : {
                        *ti.board*aer5f(.text)
                        *ti.csl*aer5f(.text)
                        *ti.drv*aer5f(.text)
                        *ti.osal.aer5f(.text)
                        *ti.transport*aer5f(.text)
                        *sciclient.aer5f*(.text)
                        *(.text:ti_sysbios_family_arm_v7r_keystone3_Hwi*)
                      } palign(8)  load = XIP_FLASH, run = OCMRAM, table(_text_fast_section)
     
        .text_fast2  : {
                        *profinet_slave_stack_RT_MRP_AM65xx_r5f.lib*(.text)
                      } palign(8)  load = XIP_FLASH , run = MSMC3_H, table(_text_fast2_section)
     
        .text_fast3  : {
                        iPNDrv.obj(.text)
                        iPNLegacy.obj(.text)
                        iPNOs.obj(.text)
                        iPtcpDrv.obj(.text)
                        iRtcDrv.obj(.text)
                        iRtcDrv2.obj(.text)
                        *P_tirtos.obj(.text)
                      } palign(8)  load = XIP_FLASH , run = OCMRAM_LOW, table(_text_fast3_section)
     
        /* This is the region which will have all the copy tables */
        .ovly       : {} palign(128)  load = XIP_FLASH
     
        ...
        ...
    }

    Snippet for main.c

    /* Needed for copy_in() function */
    #include <cpy_tbl.h>
     
    /* extern all the table sections */
    extern COPY_TABLE _text_fast_section;
    extern COPY_TABLE _text_fast2_section;
    extern COPY_TABLE _text_fast3_section;
     
    int main(void)
    {
        /* First thing in main - copies by looking at entries from the table _text_fast_section */
        copy_in(&_text_fast_section);
        /* First thing in main - copies by looking at entries from the table _text_fast2_section */
        copy_in(&_text_fast2_section);
        /* First thing in main - copies by looking at entries from the table _text_fast3_section */
        copy_in(&_text_fast3_section);
     
        :
        :
        /* Rest of the body */
    }

    Please let me know if this helps.

    Regards,

    Karan

  • Hi,karan

    Thank you very much, these things are very useful!

    But I used a different method, which may be cumbersome. Fan Zhang will send it to you by email later.

    I can use my method to start and run the app normally without opening the cache, but the app cannot be started normally after opening the cache. How to debug the cache and determine the cause? Do you have a good way?

    Regards,

    Xie

  • Hi Xie,

    When you say without opening the cache, does that mean your cache is always disabled?

    EDIT:

    I would assume the xip execution to crash in that case as when running in XIP any instruction or data access which is less than 32 bits causes a wrong interpretation. 

    So in an application the startup code is where the cache is disabled and then re-enabled. So there is a small window where the cache is disabled.

    One peculiar thing about XIP execution is that the cache needs to be always on. Any instruction or data access which is less than 32 bits causes a wrong interpretation. So in the in the time window of the application startup code, where the cache is disabled and re-enabled In between this there are couple of ASM instructions which lead to < 32 bit access to OSPI in XIP mode. This will cause the code to behave strangely.

    For this, in the application startup code - either Baremetal or BIOS, we do not want to have such a window.

    BIOS - there is a flag skipEarlyCacheStartup, which we can set. See bios config file for can_profile_xip application is the SDK. With this flag set, the disable and re-enable doesn't happen.

    Baremetal - see this e2e https://e2e.ti.com/support/processors/f/791/t/885969 , this has some details. You essentially need to override the mpu_init() - this function is used in the baremetal startup code. See _enable_cache() in psdk_rtos_auto_j7_07_00_00_11/pdk_jacinto_07_00_00/packages/ti/csl/arch/r5/src/startup/startup.c

    Regards,

    Karan

  • Hi,Karan

    I’m not sure whether cache is disabled consistently. I have enabled cache in startup.c in sbl, but there is no enableCache again in my app, and there is no disablecache in the middle, so I want to ask if it only needs to be in sbl Is it enough to enable the cache once?

    Regards,

    Xie

  • Hi Xie,

    Is this a BIOS application or a baremetal application?

    Regards,

    Karan

  • Hi,Karan

    Neither,We are using AUTOSAR OS(vector support).

    Regards,

    Xie

  • Hi Xie,

    I have edited one of my older response https://e2e.ti.com/support/processors/f/791/p/948438/3507512#3507512 

    In the AUTOSAR OS, try to look at the cache startup / mpu_init type functions. I have added some details. Let me know if they work for you.

    Regards,

    Karan

  • Hi,Karan

    I'm sure I have commented out _enable_mpu and _enable_cache in mpu_init, but my code can run normally, does it mean that the cache is always on?

    Can I judge whether the cache is open by the status of some registers?

    Regards,

    Xie

  • Hi Xie,

    The XIP application should not be having __mpu_init() redone after the program jumps to resetVectors address.

    It is standard for XIP applications to not do CPU reset, as they expect the Cache to be on to run.

    So, you should be branching to resetVectors and have a stubbed out implementation for mpu_init () (It should not re-enable cache and have another MPU settings for XIP).

    You can override the while __mpu_init() function - not just the _enable_mpu and _enable_cache.

    Linda Xie said:
    I'm sure I have commented out _enable_mpu and _enable_cache in mpu_init, but my code can run normally, does it mean that the cache is always on?

    If the application is working fine, I am sure the cache would be ON. I'm thinking this is done in the SBL.

    Linda Xie said:
    Can I judge whether the cache is open by the status of some registers?

    There should be something I believe, but I don't remember it from the top of my head. Need to check this.

    Regards,

    Karan

  • Hi,Karan

    The picture below is my system resgiter, please help to see if the cache is on,

    Regards,

    Xie

  • Hi Xie,

    I am checking this. Will get back to you.

    Regards,

    Karan

  • Karan Saxena said:

    Below is snippet for the main.c file where the copy happens and also the linker file where we mention different load and run sections.

    Snippet for the Linker file:

    I tried to use the method you mentioned (using table and copy_in), but the generated bin file is very large, and it is the same as without relocation, and the one generated by my own method is very small, so I would like to ask the next one. Is the method incorrect?

    .data :
    {
        .=align(4);
        *(.data)
        .=align(4)
    }RUN = MSMC_COMMON_DATA, LOAD = MSMC_COMMON_CODE, ,align(4),table(_data_table)

    Regards,

    Xie

  • Hi Xie,

    Linda Xie said:
    }RUN = MSMC_COMMON_DATA, LOAD = MSMC_COMMON_CODE, ,align(4),table(_data_table)

    This is telling the linker that the Load address is MSMC_COMMON_CODE and the RUN address is MSMC_COMMON_DATA.

    Assuming based on the name, that both these regions are MSMC addresses and that this is a RW init section - there is still a loadable section in MSMC and that will increase the BIN size.

    The size will be small only when you BIN is compact i.e. you do not have any Loadable sections in any other memory than the Flash (0x5000_0000).

    You need to change the LOAD = MSMC_COMMOM_CODE to LOAD = FLASH_ADDRESS and in case this needs to be running from the MSMC then you can have the RUN = MSMC.

    Can you try this?

    Regards,

    Karan

  • Hi,Karan

    Sorry, this is just a problem with my variable naming. In fact, the address of MSMC_COMMOM_CODE is 0x500e0100 length = 0x200000, and the address of MSMC_COMMON_DATA is 0x41cbf4df, length = 0x9000, which is the same as the lds sent to you by Fan Zhang.

    Regards,

    Xie

  • Hi Xie,

    Can you also add the below line in the linker file:

        /* This is the region which will have all the copy tables */
        .ovly       : {} palign(128)  load = XIP_FLASH
    I have edited my old response to have this too. This is the region where the tables are stored. I'm not sure if this will change the BIN size, but this is needed.
    Regards,
    Karan
  • Hi Xie,

    Linda Xie said:
    The picture below is my system resgiter, please help to see if the cache is on,

    Created a new thread for this https://e2e.ti.com/support/processors/f/791/t/949471 

    Regards,

    Karan

  • Hi,Karan

    Karan Saxena said:

    Can you also add the below line in the linker file:

        /* This is the region which will have all the copy tables */
        .ovly       : {} palign(128)  load = XIP_FLASH
    I have edited my old response to have this too. This is the region where the tables are stored. I'm not sure if this will change the BIN size, but this is needed.

    The .ovly instruction helped me solve the problem, and the generated bin file is of normal size. thank you very much! Then I did not find the specific meaning of the .ovly instruction in the ARM Assembly Language Tools manual. There is still a big difference between adding and not adding the generated bin file. Anyway, my question is over, thanks again!

    Regards,

    Xie

  • Hi,Karan

    Karan Saxena said:
    You can override the while __mpu_init() function - not just the _enable_mpu and _enable_cache.

    I tried to override the while __mpu_init() function, my code could not run normally, and then I saw I&F bit = 0 in the CPSR register, which means that the interrupt was not turned on. Then at the end of the __mpu_init() function, CSL_armR5StartupIntrEnableFiq(1) and CSL_armR5StartupIntrEnableIrq(1) will be called to enable the I&F bit, can’t the entire __mpu_init() function override? Just override _enable_cache & _enable_mpu?

    Regards,

    Xie

  • Hi,Karan

    We only run one core in the current XIP mode. If we want to use the multi-core xip mode, how should we adapt it?
    Two situations:
    1. We are using multiple cores using the same code (SMP), and then do we only need to jump from SBL to the entry address of the main core?
    2. If we use different codes for multiple cores (NO SMP), how should we jump? How to deal with it in SBL?
    The two cores we are currently using, MCU1_0 and MCU1_1.

    Regards,

    Xie

  • Hi Xie,

    -1-

    On the ovly section. This is the overlay section which has the tables. I believe that when we were not specifying it in any section, then it could have been placed somewhere other than the flash and that might be causing the increase in the size of the BIN.

    Good to know this worked for you.

    -2-

    Linda Xie said:
    I tried to override the while __mpu_init() function, my code could not run normally, and then I saw I&F bit = 0 in the CPSR register, which means that the interrupt was not turned on. Then at the end of the __mpu_init() function, CSL_armR5StartupIntrEnableFiq(1) and CSL_armR5StartupIntrEnableIrq(1) will be called to enable the I&F bit, can’t the entire __mpu_init() function override? Just override _enable_cache & _enable_mpu?

    So when you override the whole __mpu_init() i.e. have nothing in that function, then the code doesn't work as expected / or doesn't run at all. And when you just remove the _enable_mpu() and _enable_cache() then it works? Is that correct understanding?

    -3-

    Linda Xie said:
    We only run one core in the current XIP mode. If we want to use the multi-core xip mode, how should we adapt it?
    Two situations:
    1. We are using multiple cores using the same code (SMP), and then do we only need to jump from SBL to the entry address of the main core?
    2. If we use different codes for multiple cores (NO SMP), how should we jump? How to deal with it in SBL?
    The two cores we are currently using, MCU1_0 and MCU1_1.

    For this, can you create a new thread. This can be dealt with separately - I will pick it up.

    Regards,

    Karan

  • Hi,Karan

    Karan Saxena said:
    So when you override the whole __mpu_init() i.e. have nothing in that function, then the code doesn't work as expected / or doesn't run at all. And when you just remove the _enable_mpu() and _enable_cache() then it works? Is that correct understanding?

    Yes, your understanding is correct。

    Karan Saxena said:
    For this, can you create a new thread. This can be dealt with separately - I will pick it up.

    The new thread is https://e2e.ti.com/support/processors/f/791/t/949614 

  • Hi Xie,

    So the intent behind overriding the __mpu_init() is that the R5F core is not undergoing a reset. So we do not want to re-do the configuration. I'm just thinking if there is something missing from the SBL which might be needed to be done here.

    Is enabling the IRQs and FIQs the only thing that, if you add to the overridden __mpu_init() then it works?

    I see the following happening in the default __mpu_init() - were you able to pin point what is needed and what isn't? I will check the SBL code to see what is happening there.

    1. CSL_armR5SetDLFOBit()

    2. _enable_mpu()

    3. _enable_cache()

    4. CSL_armR5StartupFpuEnable()

    5. CSL_armR5StartupIntrEnableVic()

    6. CSL_startupVimSetIntrEnable() and  CSL_startupVimClrIntrPending()

    7. CSL_armR5StartupIntrEnableFiq() and CSL_armR5StartupIntrEnableIrq()

    Regards,

    Karan

  • Hi,Karan,

    Karan Saxena said:

    1. CSL_armR5SetDLFOBit()

    2. _enable_mpu()

    3. _enable_cache()

    4. CSL_armR5StartupFpuEnable()

    5. CSL_armR5StartupIntrEnableVic()

    6. CSL_startupVimSetIntrEnable() and  CSL_startupVimClrIntrPending()

    7. CSL_armR5StartupIntrEnableFiq() and CSL_armR5StartupIntrEnableIrq()


    2 and 3 are not needed, all others are needed.I wonder if it is the reason why I did not use BIOS?

    Regards,

    Xie

  • Hi Xie,

    I assume as things are working now, this is not such a high priority. I will try to get some more insight on why this is happening - will get back to you in a day or two. 

    Regards,

    Karan

  • Hi,Karan

    ok,Can you help me solve the problem in this post https://e2e.ti.com/support/processors/f/791/t/949614