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.

AM335x boot using TI starterware_02_00_01_01 boot loader

Hi,

I am working on AM335x based product development where the boot time of the system is very stringent. We expect the system to boot and stabilize in 500 msec. we need 150 msec to stabilize the control loop once the main code runs and left with 350 msec for system boot. We are also targeting to boot using SD card (This is also one of the critical requirement).

I tried the starterware boot loader, and figured out that, it takes around 800 msec to copy a application binary of size 84 KB from SD card to DDR3. So in the existing boot loader code in starteware the  through put is around 100KB/sec. This is very slow and it doesn't match our requirement. I studied the TI Technical reference manual where it is mentioned that the SD card data transfer rate is 24MB/sec and also tried the example code /beaglebone/hs_mmcsd/. I am able to get very good SD card through put here, it just took 10msec to copy 100KB binary from SD card to DDR3.

I tried to understand the difference between the boot loader SD card copy and hs_mmcsd example SD card copy to DDR3 and found the following differences.

1.In the boot loader code, the data is read from SD card into IRAM in chunks of 512 bytes and memory copied to DDR3 from IRAM, where as in hs_mmscd example, the data is read from SD card directly into DDR3 of buffer size 64k.

2. The boot loader uses polling mode  where as the hs_mmcsd code  use EDMA for data read from SD card to DDR

3. MMU/cache not enabled in boot loader but enabled in hs_mmcsd example.

Because of the above differences, the boot loader SD card read to copy application image to DDR3 was very slow.

I tried to port the hs_mmscsd code into boot loader and tried to run and at this point, it the boot loader hangs/stops working in the EDMA transfer code.The same code works fine in hs_mmcsd example but fails in EDMA transfer code in the boot loader. I also tried /example/beaglebone/edma example code to run in the boot loader but it doesn't work (Again hangs in EDMA transfer)

1.Now my question is why EDMA data transfer ( from SD card to IRAM or IRAM to IRAM or UART to IRAM ) doesn't work in the boot loader? Can EDMA be used in boot loader or not? please suggest

2.If i enable MMU/Cache in the boot loader, it hangs? Why can't i enable MMU/Cache in boot loader?

3. How much time does the  ROM boot code takes to run till the point  MLO code starts running?

4. Finally is it possible to have 350 msec boot time using TI starterware boot loader booting from SD card ? if yes, how to achieve this?

Please give your inputs?

Regards,

Seetaram

  • Hi Seetaram,

    This forum is for linux & hw related questions. Could you please ask your question in the StarterWare Forum: e2e.ti.com/.../790

    Best Regards,
    Yordan
  • sram said:
    1.Now my question is why EDMA data transfer ( from SD card to IRAM or IRAM to IRAM or UART to IRAM ) doesn't work in the boot loader? Can EDMA be used in boot loader or not? please suggest

    Definitely EDMA can be used in the bootloader.  I think this will be your best method of improving your boot speed.  We would need to debug this in depth.

    1. Has the EDMA clock been properly enabled such that its registers are visible and its Parameter RAM is writeable?
    2. What parameters are you using to service the MMC?
    3. If I recall correctly, you also need to enable the DMA event from within the MMC configuration.

    We'll need to work our way through all these items to get things setup properly.

    sram said:
    2.If i enable MMU/Cache in the boot loader, it hangs? Why can't i enable MMU/Cache in boot loader?

    I don't recommend proceeding down this path.  Even major bootloaders like u-boot do not enable the MMU as it substantially increases the complexity of things.  I think you can get 90% of the speed improvement by utilizing EDMA and without all the additional complexity.

    sram said:
    3. How much time does the  ROM boot code takes to run till the point  MLO code starts running?

    This varies depending on the speed of your SD card as well as the size of your MLO.  You would need to measure this on a scope.

    sram said:
    4. Finally is it possible to have 350 msec boot time using TI starterware boot loader booting from SD card ? if yes, how to achieve this?

    I think for starters we would need to know how much time has already been consumed in booting your MLO.  I believe it should be feasible, though it's hard to say for sure given all the variables.

  • To give some more specific guidance, let's start with validating the clocks...  Please check the following registers.   They're all 32-bit registers so you can use the "md.l" command from u-boot.  That last character is a lower case 'L' for "long" since it is 32-bit.  You can do "md.l <address> 1" to do a single register read.  That's a "one" as the very last item (after the address).  Here are the registers of interest:

    • CM_PER_TPCC_CLKCTRL at address 0x44E000BC.
    • CM_PER_TPTC0_CLKCTRL at address 0x44E00024.
    • CM_PER_TPTC1_CLKCTRL at address 0x44E000FC.
    • CM_PER_TPTC2_CLKCTRL at address 0x44E00100.

    All of these registers should contain a value of 2 if their associated clock is enabled.  Finally, once you're at a point where all of those are enabled you should be able to perform a read of the EDMA CCCFG register at address 0x49000004 and it should have a value of 0x03224445.

    Once you get to a point where the EDMA clocks are all alive then we can start programming a transfer.

  • Sorry, I forgot you're not using u-boot. You're using starterware! In any case, use your method of choice (JTAG, etc.) to interrogate the registers I mentioned.
  • Hi Brad,
    Thanks much for your inputs.

    You are right that, EDMA in boot loader can improve the speed drastically.

    Keeping aside the boot loader, i tried a starterware example which demonstrates EDMA transfer from one buffer to other.
    The example code is available in TI starterware in the path ti/AM335X_StarterWare_02_00_01_01/examples/beaglebone/edma.

    The source code is as follows.
    main()
    {
    /* Configure EDMA module clock */
    EDMAModuleClkConfig();

    /* Initialize EDMA */
    EDMA3Init(EDMAAPP_EDMACC_BASE_ADDRESS, EDMAAPP_DMA_EVTQ);

    _EDMAAppRegisterEdma3Interrupts();

    EDMAAppEDMA3Test(); // Here the actual EDMA transfer is enabled.

    EDMA3Deinit(EDMAAPP_EDMACC_BASE_ADDRESS, EDMAAPP_DMA_EVTQ);

    return 0;
    }

    This example code works fine if the source and destination buffers are allocated memory in the DDR. (By default this application has .bss allocated in DDR).

    Following is the log i generated running this application.

    StarterWare AM335x Boot Loader
    Copying application image from MMC/SD card to RAM
    Jumping to StarterWare Application...

    EDMA_CCCFG value=3224445

    Source and Destination buffer initial values
    SrcBuff[0]=0: DstBuff[0]=0
    SrcBuff[1]=1: DstBuff[1]=0
    SrcBuff[2]=2: DstBuff[2]=0
    SrcBuff[3]=3: DstBuff[3]=0
    SrcBuff[4]=4: DstBuff[4]=0
    SrcBuff[5]=5: DstBuff[5]=0
    SrcBuff[6]=6: DstBuff[6]=0
    SrcBuff[7]=7: DstBuff[7]=0
    SrcBuff[8]=8: DstBuff[8]=0
    SrcBuff[9]=9: DstBuff[9]=0

    paramSet.srcAddr=80003540:
    paramSet.destAddr=80003680:
    paramSet.aCnt=a:
    paramSet.bCnt=1:
    paramSet.cCnt=1:
    paramSet.srcBIdx=a:
    paramSet.destBIdx=a:
    paramSet.linkAddr=ffff:
    paramSet.opt=8033f000

    numEnabled=1
    In TX completed ISR isIntrPending=0: isHighIntrPending=80000000
    in else pendingIrqs =80000000
    in second while pendingIrqs =1
    in else isIntrPending Clear Pending interrupt=0
    in else pendingIrqs =0
    EDMA enable functionretval=1

    After EDMA transfer complete

    Print the Sourec bytes..
    SrcBuff[0]=0
    SrcBuff[1]=1
    SrcBuff[2]=2
    SrcBuff[3]=3
    SrcBuff[4]=4
    SrcBuff[5]=5
    SrcBuff[6]=6
    SrcBuff[7]=7
    SrcBuff[8]=8
    SrcBuff[9]=9

    Print the Destination bytes..
    DstBuff[0]=0
    DstBuff[1]=1
    DstBuff[2]=2
    DstBuff[3]=3
    DstBuff[4]=4
    DstBuff[5]=5
    DstBuff[6]=6
    DstBuff[7]=7
    DstBuff[8]=8
    DstBuff[9]=9
    EDMA3Test: Data write-read matching PASSED.
    EDMA3Test PASSED.

    Now i just tried a small change to this example that, instead of allocating memory for source and destination buffers in DDR, i changed it to IRAM (This i did by changing linker command file .bss section to IRAM_MEM). This is because when i implement the EDMA transfer in boot code, the source buffer is in SD card and destination is in IRAM. I wanted to verify if the EDMA works when the buffers are in IRAM.

    The new linked command file looks something like this.
    MEMORY
    {
    DDR0 : o = 0x80000000, l = 0x20000000 /* 512MB external DDR Bank 0 */

    #I added this new section in the original file
    IRAM_MEM : o = 0x402F0400, l = 0x1FBFF /* 127k internal Memory */

    }

    .bss :
    {
    . = ALIGN(4);
    _bss_start = .;
    *(.bss*)
    *(COMMON)
    _bss_end = .;
    } >IRAM_MEM

    Once i do this change and rebuild and run the code, it runs without any error but if i compare the source and destination buffer data after EDMA, the destination will have the default values but not the new values EDMA transferred from Source. I have captured the log as shown below.

    StarterWare AM335x Boot Loader
    Copying application image from MMC/SD card to RAM
    Jumping to StarterWare Application...

    EDMA_CCCFG value=3224445

    Source and Destination buffer initial values
    SrcBuff[0]=0: DstBuff[0]=0
    SrcBuff[1]=1: DstBuff[1]=0
    SrcBuff[2]=2: DstBuff[2]=0
    SrcBuff[3]=3: DstBuff[3]=0
    SrcBuff[4]=4: DstBuff[4]=0
    SrcBuff[5]=5: DstBuff[5]=0
    SrcBuff[6]=6: DstBuff[6]=0
    SrcBuff[7]=7: DstBuff[7]=0
    SrcBuff[8]=8: DstBuff[8]=0
    SrcBuff[9]=9: DstBuff[9]=0

    paramSet.srcAddr=402f0440:
    paramSet.destAddr=402f0580:
    paramSet.aCnt=a:
    paramSet.bCnt=1:
    paramSet.cCnt=1:
    paramSet.srcBIdx=a:
    paramSet.destBIdx=a:
    paramSet.linkAddr=ffff:
    paramSet.opt=8033f000
    numEnabled=1
    In TX completed ISR isIntrPending=0: isHighIntrPending=80000000
    in else pendingIrqs =80000000
    in second while pendingIrqs =1
    in else isIntrPending Clear Pending interrupt=0
    in else pendingIrqs =0
    EDMA enable functionretval=1

    After EDMA transfer complete

    Print the Sourec bytes..
    SrcBuff[0]=0
    SrcBuff[1]=1
    SrcBuff[2]=2
    SrcBuff[3]=3
    SrcBuff[4]=4
    SrcBuff[5]=5
    SrcBuff[6]=6
    SrcBuff[7]=7
    SrcBuff[8]=8
    SrcBuff[9]=9
    Print the Destination bytes..
    DstBuff[0]=0
    DstBuff[1]=0
    DstBuff[2]=0
    DstBuff[3]=0
    DstBuff[4]=0
    DstBuff[5]=0
    DstBuff[6]=0
    DstBuff[7]=0
    DstBuff[8]=0
    DstBuff[9]=0
    EDMA3Test: Data write-read matching FAILED.
    The mismatch happened at index : 2
    EDMA3Test FAILED

    So in both the cases we can see that, the clock configuration, ISR config, Param config is all correct except that the source and destination buffers are allocated in DDR and IRAM respectively.

    Based on this observation , the EDMA data transfer is not working if i use source and/or destination buffer in IRAM. This is also the reason why the boot loader SD card copy using EDMA to IRAM buffer is not working.

    Can you please review this and suggest me what is the issue here?
    Surprisingly there is no error in EDMA but the destination buffer will not have the EDMA transferred data. Not sure what is wrong.
    Please suggest.

    Thanks
    Seetaram
  • Hi Brad,

    I figured out the root cause of this problem.

    The source and destination buffer were allocated in IRAM memory in the address range 0x402F_0000 0x402F_03FF 64KB which is Reserved. I changed this to 0x402F_0400 0x402F_FFFF in linker command file, it started working.

    May be this Could be the reason why the SD card EDMA not working in boot loader! I need to check this and figure out.

    Can you please suggest how to allocate .bss section in the address range 0x402F_0000 0x402F_03FF using the linker command file?

    Thanks a lot
    Regards,
    Seetaram
  • Sorry just a correction here.
    The buffers are allocated in the address: paramSet.srcAddr=402f0440: paramSet.destAddr=402f0580:

    This address range is reserved for loading the boot loader image as per TI AM335 Technical reference manual section 26.1.3.2. So i changed the starting address of IRAM to 0x402F-FFFF it worked. ( 0x402F-FFFF is end address of SRAM internal)

    If i make IRAM start adress as 0x4030_0000 it doesn't work!
  • Hi Brad,

    I tried to run the same code in boot loader with .bss memory allocated in address 0x402F-FFFF, the EDMA works.
    However the boot loader code having SD card (file copy from SD card to DDR using EDMA ) code ported from beaglebone/hs_mmscd application is still not working.with the DMA buffer memory address changes which i figured out in the above exercise.

    Any pointers will be helpful.

    Regards,
    Seetaram
  • Can you explain in more detail why you are using the EDMA to copy from MMC to internal SRAM?  Isn't your end goal to load your application to DDR?  Why not copy it there directly?

    Can you please provide a memory map for both your bootloader and application?  In particular, I need a breakdown of code, uninitialized (or zero initialized) data, and initialized/const data for both the bootloader and application.

  • sram said:
    This address range is reserved for loading the boot loader image as per TI AM335 Technical reference manual section 26.1.3.2. So i changed the starting address of IRAM to 0x402F-FFFF it worked. ( 0x402F-FFFF is end address of SRAM internal)

    I don't think I would use the word "reserved" to describe the range 0x402F0400 - 0x4030B7FF.  I would describe this as "available" for your downloaded image.  The range from 0x4030B800 - 0x4030FFFF is what I would consider "reserved" in that you can NOT put code or initialized data in these areas or else you will cause the boot ROM to corrupt its own stack.  It would however be ok to put an uninitialized section like bss in that range because nothing would actually touch those memory addresses until after control had transferred from the boot ROM to your bootloader.

    This is why in my previous post I asked you to please provide a complete memory map for your bootloader and your application.  We need to make sure that at each stage of the boot process that we are not shooting ourselves in the foot by copying something from the next stage of the boot over something required for the current stage.