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.

DM6437 my own bootloader not quite right!

Other Parts Discussed in Thread: CCSTUDIO

Because hexAIS does not work for me (http://e2e.ti.com/support/dsp/davinci_digital_media_processors/f/99/t/118523.aspx) I have written a 2 stage bootloader. However, on the second stage when the main software image runs some time between BIOS_init call and the board init function the software calls back to flash and starts running its own loader.

Details are:

I am using Direct EMIFA boot 0100b (fastboot = 0) on a DM6437.

My POR bootloader at 0x42000000 disables L1D then copies a primary bootloader to 0x10800000 which is L2 RAM area.

The primary bootloader is a C program that initialises PLL1/2 and the DDR2 and is basically a rip-off of the DM6437 GEL file. The primary bootloader C code then obtains the address in flash of the main image bootloader (the bootloader that copies the main software from flash to DDR2), casts the address to a function pointer and calls it.

The main bootloader disables L1D, invalidates L1P (not sure if I need to), invalidates L2 (I should not need to) and copies the main software image into DDR2 then jumps to its c_int00.

The main software runs from c_int00, reaches BIOS_init (the start of it anyway) and sometime before it reaches the user initialisation function somehow calls back to the flash memory and starts executing the main bootloader (which of course copies again the main software image to DDR2). This repeats continually.

 

I wondered if the problem is one of caching: The only way I can think that the main bootloader is being run again is if the code that originally called it from the primary bootloader is being executed again, perhaps from L1P. That's why my main bootloader invalidates L1P but I am not sure that I need to because the main software image code is running from DDR2 and the primary bootloader was run from L2 when it was set to all RAM so there should be no confusion.

I am not running self modifying code as mentioned in the cache manual in the sense that I am not modifying previously run instructions, so L1P should not be affected. However, I am careful to disable L1D so that the image DATA as it is copied is not cached in L1D before it is actually run as code.

 

Ideas?

  • My only idea is to make sure that you have actually jumped to your main program's init routine in ddr2 and haven't accidentally jumped right back to the image bootloader init.

    Have you confirmed that it is jumping back to the image loader and hasn't actually done a reset and executed all the loaders?

  • When I reach the c_int00 of the main software it looks like the EFR (exception flag register) is 2 (internal exception) and the IERR is 0x89 (I do not know what this means).

    As soon as the software reaches "_auto_init" whithin a few instructions it jumps to 10810400 which is the ISTP (interrupt service table pointer)

    As this point the main software has not set up the ISTP and looks like it is the ISTP from the primary bootloader written in C.

    I'm thinking the DSP is objecting to something I am doing.

    Anybody know what 0x89 in the IERR means? I have the 64x+ megamodule manual, DM6437 manual and a few others and cannot find a list of definitions.

     

    Also, in the primary bootloader written in C I set up PLL1/2 and DDR2, disable software and hardware interrupts and then create a C function pointer that points to the image loader bootloader located in flash which I then jump to.

    I still get an EFR = 2 if I load the primary bootloader in EMUL boot mode, allow it to initialise PLL1/2/DDR2 then vector to the image bootloader in flash. It runs this then comes back to C_int00 in DDR2. When it reaches _auto_init the EFR register is 2 with an IERR of 0x18 and then goes to 10810400 which is the ISTP from the primary bootloader.

  • The IERR register bits are defined in spru732.

  • Thanks. Never thought to look there ... (Was looking at megamodule manual)

  • IERR codes I was getting seemed to all revolve around 'opcode exception' (OPX) but also saw instruction fetch exception (FPX) and resource conflict exception (RCX) and SPLOOP buffer exception (LBX).

    When I got to auto_init in the main load and stepped though (after having loaded symbols only) I noticed that the instructions were changing before my eyes:

    In fact, this:

    879AC560          _auto_init:
    879AC560 25F7                STW.D2T1      A11,*B15--[2]
    879AC562 9577                STDW.D2T2     B11:B10,*B15--[1]
    879AC564 65C7     ||         MV.L2         B3,B11
    879AC566 2577                STW.D2T1      A10,*B15--[2]
    879AC568 5647                MV.L2X        A4,B10
    879AC56A 764E     ||         MV.S1X        B4,A11
    879AC56C 0013EA58 ||         CMPEQ.L1      -1,A4,A0
    879AC570 C0686121     [ A0]  BNOP.S1       C$L8 (PC+208 = 0x879ac630),3
    879AC574 D02802E7 ||  [!A0]  LDW.D2T2      *+B10[0],B0
    879AC578 C26FA02B ||  [ A0]  MVK.S2        0xffffdf40,B4
    879AC57C E0E00032            .fphead       n, l, W, BU, nobr, nosat, 0000111
    879AC580 C004A35A ||  [ A0]  MVK.L2        1,B0
    879AC584 C243CFEA     [ A0]  MVKH.S2       0x879f0000,B4
    879AC588 30001511     [!B0]  B.S1          C$L7 (PC+168 = 0x879ac628)
    879AC58C D5001FD8 ||  [!A0]  OR.L1X        0,B0,A10
    879AC590 2528805A     [ B0]  ADD.L2        4,B10,B10
    879AC594 202818DA     [ B0]  CMPGT.L2X     0,A10,B0
    879AC598 4C6E                NOP           3
    879AC59A 0C6E     ||         NOP           1
    879AC59C E8001000            .fphead       n, l, W, BU, nobr, nosat, 1000000

    was changing to this:

    879AC560          _auto_init:
    879AC560 00000000            NOP          
    879AC564 D02802E7     [!A0]  LDW.D2T2      *+B10[0],B0
    879AC568 C0686121 ||  [ A0]  BNOP.S1       0x879AC700 (PC+416 = 0x879ac700),3
    879AC56C E0E00032 ||         .word         0xe0e00032
    879AC570 C26FA02B ||  [ A0]  MVK.S2        0xffffdf40,B4
    879AC574 257765C7 ||         .word         0x257765c7
    879AC578 957725F7 ||         .word         0x957725f7
    879AC57C 0013EA58 ||         CMPEQ.L1      -1,A4,A0
    879AC580 764E5647     [!B2]  LDH.D1T2      *A19++[18],B12
    879AC584 202818DA ||  [ B0]  CMPGT.L2X     0,A10,B0
    879AC588 2528805A     [ B0]  ADD.L2        4,B10,B10
    879AC58C E8001000            .word         0xe8001000
    879AC590 0C6E4C6E            LDW.D2T2      *+B14[28236],B24
    879AC594 C243CFEA     [ A0]  MVKH.S2       0x879f0000,B4
    879AC598 C004A35A     [ A0]  MVK.L2        1,B0
    879AC59C D5001FD8     [!A0]  OR.L1X        0,B0,A10

    DDR2 setup became the immediate suspect. In my primary bootloader I had copied the DDR2 setup direct from the DM6437 GEL file. Specifically the timing values were as follows (for 162Mhz):

            DDR_SDTIMR   = 0x16492148;  // DDR Timing
            DDR_SDTIMR2  = 0x000cc702;  // DDR Timing

    However, when I changed the timing to those as below

            DDR_SDTIMR   = 0x22923209;  // DDR Timing
            DDR_SDTIMR2  = 0x0012c722;  // DDR Timing

    then the bootloader came to life and booted the software OK.

    The timings that worked I obtained from reading the actual SDTIM registers using CCS memory view after I used the full GEL file to connect and run the software in EMUL boot mode.

    Then I realised .... there are 2 directories for the DM6437 in my CCStudio boards area: evmdv6437 and evmdv6437_v2: The GEL from the evmdv6437 has the timings that 'work' and the evmdv6437_v2 has timings that do not work. Not sure why I have 2 directories.

     

    I wonder if the dm6437 directory that has the timings that work comes with CCS 3.3 Platinum which I have (or updates thereof) but the dm6437_v2 directory which has timings that do not work arrived on CD with my DM6437 boards: I've been running CCS 3.3 for a while but only recently purchased a DM6437.

     

    Part of the 'good' GEL:

       /*
         *  Step 3 - DDR2 Initialization
         */
        DDR_DDRPHYCR = 0x50006405;      // DLL powered, ReadLatency=5
        DDR_SDBCR    = 0x00138822;      // DDR Bank: 32-bit bus, CAS=4,
                                        // 4 banks, 1024-word pg
        DDR_SDTIMR   = 0x22923209;      // DDR Timing
        DDR_SDTIMR2  = 0x0012c722;      // DDR Timing
        DDR_SDBCR    = 0x00130822;      // DDR Bank: cannot modify
        DDR_SDRCR    = freq * 7.8;      // Refresh Control [ 7.8 usec * freq ]

    Part of the 'bad' GEL:

        /*
         *  Step 3 - DDR2 Initialization
         */
        DDR_DDRPHYCR = 0x50006405;      // DLL powered, ReadLatency=5
        DDR_SDBCR    = 0x00138822;      // DDR Bank: 32-bit bus, CAS=4,
                                        // 4 banks, 1024-word pg
        if ( freq == 135 )
        {
            DDR_SDTIMR   = 0x14492148;  // DDR Timing
            DDR_SDTIMR2  = 0x000bc702;  // DDR Timing
        }
        else /* Default to 162 MHz */
        {
            DDR_SDTIMR   = 0x16492148;  // DDR Timing
            DDR_SDTIMR2  = 0x000cc702;  // DDR Timing
        }
        DDR_SDBCR    = 0x00130822;      // DDR Bank: cannot modify
        DDR_SDRCR    = freq * 7.8;      // Refresh Control [ 7.8 usec * freq ]

    The INI file that came with flashburn directory in the dvsdk for thd DM6437 board I have also has the following (which does not work):

    [DDR]
    DDRPLLM = 23
    DDRCLKDIV = 1
    VPFECLKDIV = 11
    CLK_SRC = 0
    DDRPHYCR = 0x50006405
    SDBCR = 0x00138822
    SDTIMR = 0x16492148
    SDTIMR2 = 0x000CC702
    SDRCR = 0x000004EF

    Are there 2 versions of the DM6437 board with different DDR2 timings?