This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

remapping of ddr

Hi again

I am still struggling with debugging my code in DDR3 memory using the Keil uLink2. I have created a .ini file for the uLink2 to execute which initializes the DDR3 for use, load my code to DDR3, and attempts to change the pc and sp to that memory. The last thing is not working. the code definitely is in the DDR3 memory OK. Below is the the script function.

The code was linked to 0xA0000000

This is a microsemi cortex m3 FPGA arm.

Can anyone see a reason why this would not work? or why the uLink2 jumps away to undefined memory space? I assume people have debugged out of external RAM before

Thanks :-)


FUNC void SetupPC_SP (void) {
       // Stack pointer and vector table offset
       // registers are set to 0x00000000
       // Setup Stack Pointer

    SP = _RDWORD(0xA0000000);          // Setup Stack Pointer

       // Program Counter is set to (0x00000004 -1)
    PC = _RDWORD(0xA0000004-1);        // Setup Program Counter

       // change vector table address to 0
    _WDWORD(0xE000ED08, 0x0);          // 0xE000ED08 SCB->VTOR = readonly_region_base;

}

Parents
  • Hi

    I just wanted to follow up on getting the bootloader to work out of esram. Because of your great help, I was able to implement the critical part of the code out of the line of fire in nvm by putting it into esram.

    I did it somewhat differently so that I could pass the base address of the registers by a simple call to esram. The assembly code in esram is in a table which I located at the start of esram. I had to NOP the return assembly code for the function in esram so it would not immediately jump back (return) so the processor would instead execute through it into the table and execute the remapping and pc/sp loading code. It work find although its not a elegant solution. Straightforward though.

    thanks again for you help and Microsemi if your out there you need to fix your app notes to make it clear that you cannot be executing out of nvm when you remap on top of yourself!

    // code located in nvm memory before remapping ddr on top of it
    void Jump_to_executable(void)
    {
    
        SCB->VTOR = 0x00000000;      // set the vector table base address to 0
    
       int * test = (int*)BootJump1; // get the address of the code table in esram
       test[-1] = 0xBF00BF00;        // back up 1 assembly instruction to NOP the
                                     // return address of BootJump
                                     // we do not want it to return.
    
       BootJump((INT32U)0x40038000);
    
    ////////////////////////////////////////////////////////////
    
    // code located at address 0x20000000 (esram)
    // BootJump() MUST be located just before the table in the scatter
    // file so that execution will fall thought to the table of code
    
    void BootJump(INT32U firmwareStartAddress)
    {
         return; // BX LR changed to NOp NOP
    }
    
    char BootJump1[18] = {
     00,  0x21,    //MOVS     r1,#0x00       ; R0 contains base address 0x40038000
     01,  0x60,    //STR      r1,[r0,#0x00]  ; SYSREG->ESRAM_CR = 0u
     01,  0x61,    //STR      r1,[r0,#0x10]  ; SYSREG->ENVM_REMAP_BASE_CR = 0u
     01,  0x22,    //MOVS     r2,#0x01       ; SYSREG->DDR_CR = 1u
     0x82,  0x60,  //STR      r2,[r0,#0x08]  ; Remap to address 0
     0xD1,0xF8,    //LDR      sp,[r1,#0x00]  ; Load new stack pointer address
     00,  0xD0,
     0xD1,0xF8,    //LDR      pc,[r1,#0x04]  ; Load new program counter address
     04,  0xF0
     };
    

Reply
  • Hi

    I just wanted to follow up on getting the bootloader to work out of esram. Because of your great help, I was able to implement the critical part of the code out of the line of fire in nvm by putting it into esram.

    I did it somewhat differently so that I could pass the base address of the registers by a simple call to esram. The assembly code in esram is in a table which I located at the start of esram. I had to NOP the return assembly code for the function in esram so it would not immediately jump back (return) so the processor would instead execute through it into the table and execute the remapping and pc/sp loading code. It work find although its not a elegant solution. Straightforward though.

    thanks again for you help and Microsemi if your out there you need to fix your app notes to make it clear that you cannot be executing out of nvm when you remap on top of yourself!

    // code located in nvm memory before remapping ddr on top of it
    void Jump_to_executable(void)
    {
    
        SCB->VTOR = 0x00000000;      // set the vector table base address to 0
    
       int * test = (int*)BootJump1; // get the address of the code table in esram
       test[-1] = 0xBF00BF00;        // back up 1 assembly instruction to NOP the
                                     // return address of BootJump
                                     // we do not want it to return.
    
       BootJump((INT32U)0x40038000);
    
    ////////////////////////////////////////////////////////////
    
    // code located at address 0x20000000 (esram)
    // BootJump() MUST be located just before the table in the scatter
    // file so that execution will fall thought to the table of code
    
    void BootJump(INT32U firmwareStartAddress)
    {
         return; // BX LR changed to NOp NOP
    }
    
    char BootJump1[18] = {
     00,  0x21,    //MOVS     r1,#0x00       ; R0 contains base address 0x40038000
     01,  0x60,    //STR      r1,[r0,#0x00]  ; SYSREG->ESRAM_CR = 0u
     01,  0x61,    //STR      r1,[r0,#0x10]  ; SYSREG->ENVM_REMAP_BASE_CR = 0u
     01,  0x22,    //MOVS     r2,#0x01       ; SYSREG->DDR_CR = 1u
     0x82,  0x60,  //STR      r2,[r0,#0x08]  ; Remap to address 0
     0xD1,0xF8,    //LDR      sp,[r1,#0x00]  ; Load new stack pointer address
     00,  0xD0,
     0xD1,0xF8,    //LDR      pc,[r1,#0x04]  ; Load new program counter address
     04,  0xF0
     };
    

Children
No data