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.

Boot Basics on OMAP-L138 with DSP/BIOS Application

Guru 15580 points

This is a continuation of previous threads dealing with booting an OMAP-L138 from SPI Flash.

I am now trying to add my DSP/BIO application to the boot image, but the DSP application does not run. The ARM initialization runs properly and releases the DSP from reset. It also properly programs HOST1CFG. Here's the ARM initialization code (uses Logic BSL).

void AMX_init( )
{
    PSC_All_On_Full_EVM();
    Core_300MHz_mDDR_150MHz();
 DEVICE_kickUnlock();   
    HOST1CFG = (0xC0000000 & 0xFFFFFC00);   
    Wake_DSP();
}

I can see the code properly loaded in DDR memory, but the DSP/BIO application does not run properly

 However, I am confused about the location of the DSP/BIO startup code. Based on a suggestion by another member, I created a memory section called "Vectors" at the beginning of DDR memory (0xc0000000). Using the DSP/BIO Graphic Config tool, in the DSP/BIO Memory Manager I allocated the "startup code section (.sysinit) to the Vectors memory section. Here's a snapshot of the Memory Manager window.

After compiling, the .map file shows this allocation.

******************************************************************************
               TMS320C6x Linker PC v7.0.3                     
******************************************************************************
>> Linked Sun Jan 23 10:53:00 2011

OUTPUT FILE NAME:   <DSP_BIOS.out>
ENTRY POINT SYMBOL: "_c_int00"  address: c0000380


MEMORY CONFIGURATION

         name            origin    length      used     unused   attr    fill
----------------------  --------  ---------  --------  --------  ----  --------
  IRAM                  11800000   00030000  00012a54  0001d5ac  RWIX
  CACHE_L2              11830000   00010000  00000000  00010000  RWIX
  CACHE_L1P             11e00000   00008000  00000000  00008000  RWIX
  CACHE_L1D             11f00000   00008000  00000000  00008000  RWIX
  L3_CBA_RAM            80000000   00020000  00008000  00018000  RWIX
  Vectors               c0000000   00008000  00000580  00007a80  RWIX
  DDR                   c0008000   04000000  001acadc  03e53524  RWIX

But, notice that c_int00 is not at 0xc0000000, but 0xc0000380. I assume this is because there is some additional DSP/BIOS initialization code that runs before c_int00.

Looking at the code actually loaded into memory at 0xc000000, I see this:

            BIOS_init, BIOS_init, $DSP_BIOS_dspcfg.s62:2442:2480$:
0xC0000000:   02410106            PLD.D2         *-A16(8),4
0xC0000004:   018D0040            MVK.D1        8,A3
0xC0000008:   11202088            .word         0x11202088
0xC000000C:   008C0040            MVK.D1        0,A1
0xC0000010:   02400008            EXTU.S1       A16,0,0,A4
0xC0000014:   00000008            EXTU.S1       A0,0,0,A0
0xC0000018:   00800000            NOP
            versret$291$:
0xC000001C:   02443218            ADDSP.L1X     A1,B17,A4

which clearly shows BIOS init code located at 0xc0000000.

However, if I set the DSP program counter to 0xc0000000 and try to run the application from this location, the program bombs (usually with a ccs debug error) and does not run properly.

QUESTION:

1. Have I properly allocated the correct BIOS startup code (.sysinit) to my entry point (0xc0000000)?

2. Should the DSP program run properly with the above initialization? Perhaps something else is contributing to the program not running?

Guidance is appreciated.

Thx,

MikeH

 

  • Progress! I have created a RESET vector in the DSP/BIOS Hardware Interrup Service Routine Manager which places a RESET vector address at 0xc0000000. The RESET vector points to c_int00 and the boot process seems to work if I manually load my DSP application .out file into DDR memory then set the PC=0xc0000000 and run from there.

    HOWEVER, if I try to run from the code loaded during the boot from SPI flash, the program gets hung in the auto_init loop at the following code:

                C$L2:
    0xC01B1376:   4DE7                SPLOOPD       12
    0xC01B1378:   E507     ||         MV.L2         B10,B7
    0xC01B137A:   DA6F     ||         MVC.S2        B4,ILC
    0xC01B137C:   EC001800            .fphead       n, l, W, BU, nobr, nosat, 1100000
    0xC01B1380:   1DDD                LDW.D2T2      *B7++[1],B5
    0xC01B1382:   6C6E                NOP           4
    0xC01B1384:   10CD                LDW.D2T2      *B5[0],B4
    0xC01B1386:   4C6E                NOP           3
    0xC01B1388:   2CE6                SPMASK        L2
    0xC01B138A:   D587     || ^       MV.L2X        A11,B6
    0xC01B138C:   C241                ADD.L2        B6,B4,B4
    0xC01B138E:   10C5                STW.D2T2      B4,*B5[0]
    0xC01B1390:   1CE6                SPKERNEL      0,1
    0xC01B1392:   E7C1                ADD.L2        B7,7,B4
    0xC01B1394:   05116F7A            AND.L2        B11,B4,B10
    0xC01B1398:   022836E6            LDW.D2T2      *B10++[1],B4
    0xC01B139C:   E3E00010            .fphead       n, l, W, BU, nobr, nosat, 0011111
    0xC01B13A0:   7746                MV.L1X        B6,A11
    0xC01B13A2:   0C6E                NOP           1

    Can somebody help explain why the code loaded from SPI flash will not run past this point, while the code manually loaded from the .out file will run?

    Thx,

    MikeH

     

     

  • Do you have any GEL files loaded in CCS that perform some initialization automatically when you connect? If so try removing the GEL file and seeing if it still works.

    Jeff

  • Hello again Jeff. You get around....:)

    jc said:
    Do you have any GEL files loaded in CCS that perform some initialization automatically when you connect?

    No. All GEL files have been converted to C and run as part of my ARM AMX_init() routine. However, I have enabled PLL and DDR initialization in AIS. The DDR init is needed since this is where I am loading my DSP code, which happens before the ARM starts running.

    Again, I am able to load the DSP code manually from ccs, start the PC at 0xc0000000 and run successfully. It's just when I load the DSP code from SPI flash with the bootloader (which happens after the ARM code is loaded), the program gets stuck in the loop shown above.

    Thx,

    MIkeH

     

  • Why do you have to manually set the PC to 0xC0000000 after you load your program in CCS? It should automatically set the PC to the entrypoint after loading the program. Where does it set the PC after loading?

    If you put a breakpoint at 0xC0000000 and reset the CPU, it should then immediately halt there after it loads from the SPI flash.  Does this happen?

    When it gets stuck after booting, does setting the PC back to 0xC0000000 fix the issue, even if you don't reload the program? If it doesn't that would indicate the image loaded through SPI is not identical to the one loaded through CCS.

    Jeff

  • jc said:
    Why do you have to manually set the PC to 0xC0000000 after you load your program in CCS?

    Just to clarify, I have two test cases:

    1. After booting from SPI flash, the ARM initializes all of my perhiperals  then releases the DSP from reset. Since the DSP does not run, I connect to it and examine its state. I find its PC in autoinit hung in a loop. I examine my reset vector value at 0xc0000000 and its value is correct. In fact, I can manually set the PC=0xc0000000 and step throught the program until it reaches the autoinit routine, where it hangs in a loop.

    2. Second test case is to manually load the known-good DSP code using ccs. After loading the code, I set the PC=0xc000000 to simulate where the DSP will start after the ARM releases it from reset. After setting PC=0xc0000000 and running the program, it runs correctly. This tells me that the code is correct, but in the process of loading from SPI flash something is not getting initialzed properly, causing the program to hang in autoinit.

    To further test the code loaded from SPI flash vs the manually loaded code from ccs, I did a compare in a hex editor and the only difference I found was a few bytes in the un-initialized heap space. All other code matched exactly.

    jc said:

    If you put a breakpoint at 0xC0000000 and reset the CPU, it should then immediately halt there after it loads from the SPI flash.  Does this happen?

    Yes, I can insert a break point at 0xc0000000 and start the program from there, but it ends up stuck in the same autoinit loop.

    jc said:

    When it gets stuck after booting, does setting the PC back to 0xC0000000 fix the issue, even if you don't reload the program? If it doesn't that would indicate the image loaded through SPI is not identical to the one loaded through CCS.

    No, as mentioned above, after booting from SPI flash then resetting the PC=0xc0000000 the program gets hung in autoinit.

    This has me baffled. If you can suggest something else to look at, I would greatly appreciate it.

    Is there some way to figure out what is going on with autoinit?

    Thx,

    MikeH

     

  • Can you clarify what state the device is in before you "Load Program" in CCS which works successfully? Do you do this immediately after it is hung in the autoinit function, or are you resetting the device and loading it before any of the code in the SPI flash is loaded or executed? If it works by doing "Load Program" after it is hung and jumping to 0xC0000000, that strongly indicates your images are different.

    Jeff

  • jc said:
    Can you clarify what state the device is in before you "Load Program" in CCS which works successfully?

    The device has been cold booted (power off the power on) from SPI flash. The ARM is running (LED blinking). DSP hung.

    jc said:
    Do you do this immediately after it is hung in the autoinit function, or are you resetting the device and loading it before any of the code in the SPI flash is loaded or executed?

    Once the device has cold booted and the DSP is hung, I connect to the DSP with ccs, then manually load the DSP .out file without first resetting the device. The debugger stops at "main". I hit "run" and the DSP code operates properly. I can then halt the DSP, restart the program, and the DSP continues to run properly.

    jc said:
    If it works by doing "Load Program" after it is hung and jumping to 0xC0000000, that strongly indicates your images are different.

     I totally agree. But as far as I can tell, they are identical except for 8 bytes at the begining of my heap space.

  • And the location of "main" where you start to run after "Load Program" is address 0xC0000000? If it is something other than that, what happens if you set the PC to that "main" location instead of doing "Load Program"?

    Jeff

  • Hang on....there are differences. I was comparing the wrong areas of ram. Let me discect this for a bit.

     

  • Sorry for giving you wrong infomation before. There are significant number of 4-byte differences between the manually loaded, and SPI flash loaded ram contents. The differences all appear to be 4 bytes long and seperated by a random number of correct bytes. This almost sounds like a SPI flash timing problem, either writing or reading. However, it is strange that the ARM program is not having a problem running.

    It looks like it's going to take some time tracking down why there are differences. I'll put this thread on hold til then.

    thx

    MikeH

     

  • Try enabling CRC checkign in AISGen when creating the AIS image you are loading. That will verify the memory contents vs what is in the flash itself.

    Jeff

  • I tried enabling CRC in AISgen and the ARM will not boot. From what I can tell this indicates CRC errors are present:

    For master boot modes, the bootloader calculates the CRC over each section of the application data and
    checks it against the expected value from AIS. In case of an error, the bootloader loads the section again,
    re-calculates the CRC and checks again with the expected value. If a CRC error is found in three
    successive attempts, the boot process is aborted.

     

  • Interesting. Load the debug GEL file below and reconnect to the target and it will show any ROM status errors, including CRC errors.

    http://processors.wiki.ti.com/index.php/OMAP-L1x_Debug_Gel_Files

    Jeff

  • Jeff,

    After further investigation, I have now verified that the post-boot memory contents, and the manually loaded memory contents are identical.

    In the above image the memory contents between 0xc0018000 and 0xc001b1200 (a total of 0x29200, or 168k bytes) are matched. I have looked at each initialized DDR memoery section and it matches between the post boot and manual load.

    I am trying to step through the auto_init routine to see what's going on but am having trouble getting the source .asm file to show up in the debugger so that I can see the source. I have added the source file (autoinit.asm) to my project and have provided a path to the bios source location (C:\Users\Mike\TI Workspaces\Documentation\ARM\rtssrc) in the debug properties source path window, but the source does not appear while single stepping through the code. Any idas?

    Mike

     

  • Can you attach the entire ARM map file and DSP map file? It seems most likely that they are sharing some memory regions, and that the ARM program may be overwriting some of the DSP instructions. That would explain why reloading the code after the ARM code has run fixes the issue.

    Jeff

  • Jeff,

    I have fixed the overlap in shared memory between ARM and DSP and the boot problem persists.

    However, I hav managed to get the debugger to find the source code for auto_init and allow me to watch the code as I step through. The problem lies in the incoming value of "length" in the memcopy function.


    void _auto_init(const void *cinit, const unsigned int dp)
    {
       const unsigned int *recptr = cinit;
       int length;

       if ((int)recptr != -1)
          while ((length = *recptr++) != 0)
          {
             if (length < 0)
             {
                int i;

                for (i = -length; i != 0; i-=4)
                {
                    unsigned int *to  = (unsigned int *) *recptr++;
                    *to += dp;
                }
                recptr = ALIGN_PTR(recptr);
             }
             else
             {
                char *to   = (void*) *recptr++;
                char *from = (void*) recptr;

                memcpy(to, from, length);

                from   += length;
                recptr  = ALIGN_PTR(from);
             }
          }

    Upon entry the value of length gets set to 1417693276, which causes the memcopy to hang. Here are the local variable values upon entry.

    cinit = 0x1180CB88
     *(cinit) = cannot load from non-primitive location
    dp = 293678840
    from = 0x1180CB90 "\030\026\035\016+\373\377e7\205"
     *(from) = 0x18
    length = 1417693276
    recptr = 0x1180CB8C
     *(recptr) = 2281788208
    to = 0x88015330
     *(to) = 0x00

    CAn you see anything obvious here?

     

  • Jeff,

    I managed to get the ARM to halt after loading so that I could examine memory after booting from SPI and before releasing the DSP from reset. I found that the .cinit area of DSP ram was all zeroes before releasing the DSP from reset. But immediately after releasing the DSP I could see the .cinit area fill with non-zero values. Shouldn't .cinit be filled by AIS with the initialized variable values?

    I then manually loaded the DSP .out file and saw different non-zero values in .cinit.

    Any ideas?

    MikeH

     

  • Can you privately send the AIS file created? We can look to see what data is supposed to be loaded to that section. Thanks

    Jeff

     

  • Jeff,

    Any progress on the data I sent?

    MikeH

  • Mike, when the DSP is not powered up through the PSC, the ARM will not be able to write to the DSP L2 RAM. If you are loading any sections to that memory space, the ARM will first have to enable the DSP power domain. After everything has been loaded, then the DSP can be taken out of reset. Is this what you are doing?

    Jeff

  • Jeff,

    jc said:
    . After everything has been loaded, then the DSP can be taken out of reset. Is this what you are doing?

    I am not using DSP L2 RAM for any of  the ARM memory sections.

    I am using AIS to initialize DDR. I copied this config from one of your posts. This may be where one of the problems lies. Can you take a look at the config file I sent ealier>

    Currently the ARM is initializing DDR, other peripherals, then releasing the DSP from reset.

     

    void main()

    {

    AMX_init();

    USTIMER_init();

    I2C_init(I2C1, I2C_CLK_400K);

    GPIO_init();

    GPIO_read_devID();

    SPIPort_init();

    RF_init();

    // aic3204_init_stereo();

    aic3204_init_mono();

    // aic3204_beep(1);

    LED_allON();

    USTIMER_delay(DELAY_HALF_SEC);

    LED_allOFF();

    LCD_bklt_enable();

    LCD_init();

    LCD_test();

    USTIMER_delay(DELAY_HALF_SEC);

    LCD_bklt_disable();

    SW_status = GPIO_read_joystick();

    DEVICE_kickUnlock();    

       HOST1CFG = (0xC0000000 & 0xFFFFFC00);

       Wake_DSP();

    while(1)LED_flash(1);

    }

    The init section looks like this:

     

    void AMX_init( )

    {

        PSC_All_On_Full_EVM();

        Core_300MHz_mDDR_150MHz();

    // DEVICE_kickUnlock();    

    //   HOST1CFG = (0xC0000000 & 0xFFFFFC00);    

    //    Wake_DSP();

    }

     

    void Wake_DSP()

    {

        PSC0_LPSC_enableCore(1, LPSC_DSP);

    }

     

     

  • Your AIS file is loading both the ARM and DSP files. For the DSP out file, one of the section loads is to address 0x1180CB88, which is the DSP L2 RAM. In you AIS config file, I dont see you turning on the PSC to the DSP. If you are going to have the ARM boot loader load the DSP code as well then you must power the DSP first.

    Jeff

  • WOOOOHOOOOOOO!!!!! That did it!!

    Now booting both ARM and DSP from SPI Flash !!!

    Thanks so much Jeff. I appreciate your perseverance!

    MikeH

     

  • No I dont have any GEL files.