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.

L1P L1D invalidate operation on DM642

Hi

I am working with DM642 DSP

 I want to invalidate entire L1D and L1P caches , for that

 I am writing value of 1 to bits 8 and 9 of CCFG register

How do I know that the invalidate operation is completed ? I am trying to make polling on bites 8 and 9 , and wait  while they going to 0

But , it’s never happens I stall in while loop forever.

 What I did wrong ?

 See below my code:

 //invalidate L1D

*(int *)0x01840000 = *(int *)0x01840000 | 0X100;

 while(*(int *)0x01840000 & 0X100 ) != 0)

{

}

 

//invalidate L1P

 *(int *)0x01840000 = *(int *)0x01840000 | 0X200;

 while(*(int *)0x01840000 & 0X200 ) != 0)

{

}

 I also have 128 cache from  L2 memory , to complete the cache invalidation I need to invalidate the L2 too ?  

Thanks

  

 

  • Genady,

    There are 3 documents that help you understand the operation of the cache, and the third is the primary source for coherence operations:

    - the DM642 datasheet
    - Cache User's Guide
    - SPRU610C TMS320C64x Two-Level Internal Memory

    In particular, you will want to refer to the Two-Level Internal Memory document in Section 7.3.1 "Global Cache Operations". Please note the description of the operation of the global coherence bits and how to use the CCFG register. Also, please note the highlighted Caution Note in this section..

    For your question on L2 interaction with L1 coherence, there is much to read on this in the documents that will be very helpful for you to fully understand the operation of cache and the DM642's cache in particular. SPecific to your question, please see Table 29 "Summary of Program-Initiated Cache Operations".

    In what document or example did you determine to read the IP and ID bits as status bits? I do not find this recommendation, and would like to understand where this idea came from.

    Regards,
    RandyP

  • Hi Genady,

    Moving your post to Davinci Video processor forum.

     

    Regards,

    Shankari

  • Hi

    Thanks for fast response

    I am writing third boot loader for DM642 , this boot loader supposed to fill  program memory with another  program

    Before jumping to c_init of new program , I want to invalidate the program cache

    the  L2 memory is configured as 128k  4 way  cache

    The spru610 says (on page 65) 

    “A global

    writeback-invalidate of L2 (L2WBINV) triggers a complete invalidation of L1P”

      

    See below my code

    //write bit C (bit 0) to L2WBINV - L2 write back invalidate all register

    *(int *)0x01845004 =  *(int *)0x01845004 | 1

     

    environment["ti.bios.oldMemoryNames"] = true;
    
    /* loading the generic platform */
    var params = {};
    params.clockRate = 720.000000;
    params.deviceName = "DM642";
    params.catalogName = "ti.catalog.c6000";
    params.regs = {};
    params.regs.l2Mode = "4-way cache (0k)";
    utils.loadPlatform("ti.platforms.generic", params);
    
    
    /* enabling DSP/BIOS components */
    bios.GBL.ENABLEINST = true;
    bios.MEM.NOMEMORYHEAPS = false;
    bios.RTDX.ENABLERTDX = true;
    bios.HST.HOSTLINKTYPE = "RTDX";
    bios.TSK.ENABLETSK = true;
    bios.GBL.ENABLEALLTRC = true;
    
    bios.GBL.ENDIANMODE = "little";
    
    bios.GBL.C641XCONFIGUREL2 = true;
    bios.ISRAM.createHeap = true;
    bios.ISRAM.heapSize = 0x8000;
    
    bios.MEM.BIOSOBJSEG = prog.get("ISRAM");
    bios.MEM.MALLOCSEG = prog.get("ISRAM");
    bios.TSK.STACKSEG = prog.get("ISRAM");
    
    
    /* applying user changes */
    bios.SDRAM = bios.MEM.create("SDRAM");
    
    bios.SDRAM.comment = "This object defines space for the DSP's off-chip memory";
    
    bios.SDRAM.base = 0x80000000;
    
    bios.SDRAM.len = 0x3000000;
    
    bios.SDRAM.heapSize = 0xa00000;
    
    bios.SDRAM.space = "code/data";
    
    bios.BOOT = bios.MEM.create("BOOT");
    
    bios.BOOT.comment = "Boot";
    
    bios.BOOT.len = 0x400;
    
    bios.BOOT.createHeap = 0;
    
    bios.BOOT.space = "code/data";
    
    bios.NC_SDRAM = bios.MEM.create("NC_SDRAM");
    
    bios.NC_SDRAM.base = 0x83000000;
    
    bios.NC_SDRAM.len = 0xb00000;
    
    bios.NC_SDRAM.createHeap = 0;
    
    bios.LOADER = bios.MEM.create("LOADER");
    
    bios.LOADER.base = 0x83b00000;
    
    bios.LOADER.len = 0x500000;
    
    bios.LOADER.createHeap = 0;
    
    bios.LOADER.space = "code/data";
    
    bios.PRD_NDK = bios.PRD.create("PRD_NDK");
    
    bios.TSK_NetInit = bios.TSK.create("TSK_NetInit");
    
    bios.TSK_NetComm = bios.TSK.create("TSK_NetComm");
    
    bios.TSK_MessageParser = bios.TSK.create("TSK_MessageParser");
    
    bios.TSK_NetTxComm = bios.TSK.create("TSK_NetTxComm");
    
    bios.trace = bios.LOG.create("trace");
    
    bios.HOOK_NDK = bios.HOOK.create("HOOK_NDK");
    
    bios.RTA_fromHost.bufSeg = prog.get("SDRAM");
    
    bios.RTA_toHost.bufSeg = prog.get("SDRAM");
    
    bios.LOG_system.bufSeg = prog.get("SDRAM");
    
    bios.LOG_system.bufLen = 0x400;
    
    bios.MEM.STACKSIZE = 0x9000;
    
    bios.MEM.GBLINITSEG = prog.get("SDRAM");
    
    bios.MEM.BIOSOBJSEG = prog.get("SDRAM");
    
    bios.MEM.MALLOCSEG = prog.get("SDRAM");
    
    bios.MEM.TEXTSEG = prog.get("SDRAM");
    
    bios.MEM.FARSEG = prog.get("SDRAM");
    
    bios.MEM.CINITSEG = prog.get("SDRAM");
    
    bios.MEM.CIOSEG = prog.get("SDRAM");
    
    bios.MEM.SYSMEMSEG = prog.get("SDRAM");
    
    bios.MEM.RTDXTEXTSEG = prog.get("SDRAM");
    
    bios.GBL.C641XSETL2ALLOC = 1;
    
    bios.GBL.C641XCCFGL2MODE = "4-way cache (128k)";
    
    bios.GBL.CALLUSERINITFXN = 1;
    
    bios.GBL.BOARDNAME = "Zebra";
    
    bios.PRD_NDK.period = 0x64;
    
    bios.PRD_NDK.fxn = prog.extern("llTimerTick");
    
    bios.PRD_NDK.order = 1;
    
    bios.HST.OBJMEMSEG = prog.get("SDRAM");
    
    bios.TSK.OBJMEMSEG = prog.get("SDRAM");
    
    bios.TSK.STACKSEG = prog.get("SDRAM");
    
    bios.TSK_NetInit.fxn = prog.extern("NetInitTask");
    
    bios.TSK_NetInit.stackSize = 0x1400;
    
    bios.TSK_NetInit.stackMemSeg = prog.get("SDRAM");
    
    bios.TSK_NetInit.priority = 0x8;
    
    bios.TSK_NetComm.fxn = prog.extern("NetCommTask");
    
    bios.TSK_NetComm.stackSize = 0x800;
    
    bios.TSK_NetComm.stackMemSeg = prog.get("SDRAM");
    
    bios.TSK_NetComm.priority = 0x6;
    
    bios.TSK_MessageParser.fxn = prog.extern("messageParserTask");
    
    bios.TSK_MessageParser.stackMemSeg = prog.get("SDRAM");
    
    bios.TSK_NetTxComm.fxn = prog.extern("TSK_TxComm");
    
    bios.TSK_NetTxComm.stackMemSeg = prog.get("SDRAM");
    
    bios.LNK_dataPump.order = 1;
    
    bios.RTA_dispatcher.order = 0x2;
    
    bios.IDL_cpuLoad.order = 0x3;
    
    bios.LOG.OBJMEMSEG = prog.get("SDRAM");
    
    bios.trace.bufSeg = prog.get("SDRAM");
    
    bios.trace.bufLen = 0x400;
    
    bios.PIP.OBJMEMSEG = prog.get("SDRAM");
    
    bios.SIO.OBJMEMSEG = prog.get("SDRAM");
    
    bios.STS.OBJMEMSEG = prog.get("SDRAM");
    
    bios.GIO.ENABLEGIO = 1;
    
    bios.HOOK_NDK.initFxn = prog.extern("NDK_hookInit");
    
    bios.HOOK_NDK.createFxn = prog.extern("NDK_hookCreate");
    
    bios.GBL.C641XL2ALLOC3 = 0x7;
    
    bios.GBL.C641XL2ALLOC1 = 0x7;
    
    bios.GBL.USERINITFXN = prog.extern("BRD_HwInit");
    
    bios.PRD_clock.order = 1;
    
    bios.RTDX.RTDXDATASEG = prog.get("SDRAM");
    
    bios.HWI_INT4.useDispatcher = 1;
    
    bios.HWI_INT6.useDispatcher = 1;
    
    bios.HWI_INT7.useDispatcher = 1;
    
    bios.HWI_INT8.fxn = prog.extern("EDMA_intDispatcher");
    
    bios.HWI_INT8.useDispatcher = 1;
    
    bios.PRD_swi.priority = 0xe;
    
    bios.ISRAM.base = 0x400;
    
    bios.ISRAM.len = 0x1fc00;
    
    bios.ISRAM.createHeap = 0;
    
    bios.CACHE_L2.comment = "Generated by Cache Settings in GBL";
    
    bios.CACHE_L2.base = 0x20000;
    
    bios.HWI.RESETVECTOR = 1;
    
    bios.HWI.RESETVECTOR = 0;
    bios.TSK.instance("TSK_NetTxComm").order = 1;
    bios.TSK.instance("TSK_idle").order = 2;
    bios.TSK.instance("TSK_NetInit").order = 3;
    bios.TSK.instance("TSK_NetComm").order = 4;
    bios.TSK.instance("TSK_MessageParser").order = 5;
    bios.TSK.instance("TSK_NetTxComm").priority = 7;
    bios.MEM.STACKSIZE = 0x8000;
    bios.MEM.STACKSIZE = 0x9000;
    bios.MEM.instance("ISRAM").len = 0x0002fc00;
    bios.MEM.instance("CACHE_L2").base = 0x00030000;
    bios.MEM.instance("CACHE_L2").len = 0x00010000;
    bios.MEM.instance("CACHE_L2").base = 0x00020000;
    bios.MEM.instance("CACHE_L2").len = 0x00020000;
    bios.MEM.instance("ISRAM").len = 0x0001fc00;
    bios.MEM.STACKSEG = prog.get("SDRAM");
    bios.MEM.BIOSSEG = prog.get("SDRAM");
    bios.MEM.create("SDRAM_HEAP");
    bios.MEM.instance("SDRAM").len = 0x02600000;
    bios.MEM.instance("SDRAM_HEAP").base = 0x82600000;
    bios.MEM.instance("SDRAM_HEAP").len = 0x00a00000;
    bios.MEM.instance("SDRAM_HEAP").heapSize = 0x00a00000;
    bios.MEM.BIOSOBJSEG = prog.get("SDRAM_HEAP");
    bios.MEM.MALLOCSEG = prog.get("SDRAM_HEAP");
    bios.MEM.STACKSEG = prog.get("SDRAM");
    bios.TSK.STACKSEG = prog.get("SDRAM_HEAP");
    bios.MEM.instance("SDRAM").createHeap = 0;
    bios.MEM.instance("SDRAM_HEAP").space = "code/data";
    bios.MEM.instance("LOADER").len = 0x00700000;
    bios.MEM.instance("LOADER").base = 0x83900000;
    bios.MEM.instance("SDRAM_HEAP").heapSize = 0x00800000;
    bios.MEM.instance("NC_SDRAM").base = 0x82e00000;
    bios.MEM.instance("SDRAM_HEAP").len = 0x00800000;
    bios.MEM.instance("LOADER").len = 0x00900000;
    bios.MEM.instance("NC_SDRAM").base = 0x82c00000;
    bios.MEM.instance("SDRAM_HEAP").len = 0x00600000;
    bios.MEM.instance("SDRAM_HEAP").heapSize = 0x00600000;
    bios.MEM.instance("LOADER").base = 0x83800000;
    bios.MEM.instance("LOADER").len = 0x00a00000;
    bios.MEM.instance("NC_SDRAM").base = 0x82b00000;
    bios.MEM.instance("SDRAM_HEAP").len = 0x00500000;
    bios.MEM.instance("SDRAM_HEAP").heapSize = 0x00500000;
    bios.MEM.instance("LOADER").base = 0x83600000;
    bios.TSK.instance("TSK_MessageParser").stackSize = 4096;
    bios.TSK.instance("TSK_NetComm").stackSize = 4096;
    bios.TSK.instance("TSK_NetTxComm").stackSize = 4096;
    bios.MEM.instance("NC_SDRAM").base = 0x82000000;
    bios.MEM.instance("NC_SDRAM").len = 0x01600000;
    bios.MEM.instance("SDRAM").len = 0x01b00000;
    bios.MEM.instance("SDRAM_HEAP").base = 0x81b00000;
    bios.HWI.instance("HWI_NMI").fxn = prog.extern("NMI_isr");
    bios.PRD.create("PRD_WDT");
    bios.PRD.instance("PRD_WDT").order = 2;
    bios.PRD.instance("PRD_WDT").period = 151;
    bios.PRD.instance("PRD_WDT").fxn = prog.extern("WDT_resetPrd");
    bios.GBL.ENABLEINST = 0;
    bios.GBL.INSTRUMENTED = 0;
    bios.GBL.ENABLEALLTRC = 0;
    bios.PRD.instance("PRD_WDT").fxn = prog.extern("WDT_resetPrd", "asm");
    bios.PRD.instance("PRD_WDT").fxn = prog.extern("WDT_resetPrd");
    bios.HWI.instance("HWI_NMI").fxn = prog.extern("HWI_unused", "asm");
    bios.HWI.instance("HWI_INT4").useDispatcher = 0;
    bios.HWI.instance("HWI_INT7").interruptMask = "all";
    bios.HWI.instance("HWI_INT8").interruptMask = "all";
    bios.HWI.instance("HWI_INT14").interruptMask = "all";
    bios.MEM.instance("BOOT").len = 0x00000380;
    bios.MEM.create("BOOT_STACK");
    bios.MEM.instance("BOOT_STACK").base = 0x00000380;
    bios.MEM.instance("BOOT_STACK").createHeap = 0;
    bios.MEM.instance("BOOT_STACK").len = 0x00000080;
    bios.MEM.create("MSG_QUE_SEG");
    bios.MEM.instance("MSG_QUE_SEG").base = 0x80000000;
    bios.MEM.instance("MSG_QUE_SEG").len = 0x00400000;
    bios.MEM.instance("MSG_QUE_SEG").heapSize = 0x00400000;
    bios.MEM.instance("MSG_QUE_SEG").enableHeapLabel = 1;
    bios.MEM.instance("MSG_QUE_SEG").heapLabel = prog.extern("MSG_QUE_SEG_ID");
    bios.MEM.instance("SDRAM").base = 0x80400000;
    bios.MEM.instance("SDRAM").len = 0x01700000;
    bios.TSK.create("TSK_SystemInit");
    bios.TSK.instance("TSK_SystemInit").order = 6;
    bios.TSK.instance("TSK_SystemInit").stackSize = 4096;
    bios.TSK.instance("TSK_SystemInit").fxn = prog.extern("System_Init");
    bios.TSK.instance("TSK_SystemInit").fxn = prog.extern("SystemInitTask");
    bios.TSK.instance("TSK_SystemInit").priority = 15;
    bios.MEM.instance("LOADER").len = 0x000f0000;
    bios.MEM.create("LOADER_A");
    bios.MEM.instance("LOADER_A").base = 0x836f0000;
    bios.MEM.instance("LOADER_A").len = 0x00010000;
    bios.MEM.instance("LOADER_A").space = "code/data";
    bios.MEM.instance("LOADER_A").createHeap = 0;
    bios.MEM.instance("LOADER_A").destroy();
    bios.MEM.create("LOADER_A_SEG");
    bios.MEM.instance("LOADER_A_SEG").base = 0x836f0000;
    bios.MEM.instance("LOADER_A_SEG").createHeap = 0;
    bios.MEM.instance("LOADER_A_SEG").len = 0x00010000;
    bios.MEM.instance("LOADER_A_SEG").space = "code/data";
    bios.MEM.instance("LOADER").len = 0x000ff000;
    bios.MEM.instance("LOADER_A_SEG").len = 0x00001000;
    bios.MEM.instance("LOADER_A_SEG").base = 0x836ff000;
    bios.MEM.instance("LOADER_A_SEG").destroy();
    bios.MEM.instance("LOADER").len = 0x00100000;
    bios.MEM.instance("LOADER").len = 0x00a00000;
    bios.MEM.instance("LOADER").len = 0x00900000;
    bios.MEM.create("LOADER_A_SEG");
    bios.MEM.instance("LOADER_A_SEG").base = 0x83f00000;
    bios.MEM.instance("LOADER_A_SEG").len = 0x00100000;
    bios.MEM.instance("LOADER_A_SEG").space = "code/data";
    bios.MEM.instance("LOADER").len = 0x009f0000;
    bios.MEM.instance("LOADER_A_SEG").base = 0x83ff0000;
    bios.MEM.instance("LOADER_A_SEG").len = 0x00010000;
    bios.MEM.instance("LOADER_A_SEG").createHeap = 0;
    bios.MEM.instance("LOADER").len = 0x00960000;
    bios.MEM.instance("LOADER_A_SEG").base = 0x83f60000;
    bios.MEM.instance("LOADER_A_SEG").len = 0x00910000;
    bios.MEM.instance("LOADER").len = 0x00100000;
    bios.MEM.instance("LOADER_A_SEG").base = 0x08370000;
    bios.MEM.instance("LOADER_A_SEG").len = 0x00900000;
    bios.MEM.instance("LOADER").len = 0x000f0000;
    bios.MEM.instance("LOADER_A_SEG").base = 0x0836f000;
    bios.MEM.instance("LOADER_A_SEG").len = 0x00910000;
    bios.MEM.instance("LOADER_A_SEG").base = 0x836f0000;
    bios.MEM.instance("LOADER_A_SEG").destroy();
    bios.MEM.create("LOADER_A_DATA_SEG");
    bios.MEM.instance("LOADER_A_DATA_SEG").len = 0x00910000;
    bios.MEM.instance("LOADER_A_DATA_SEG").base = 0x836f0000;
    bios.MEM.create("LOADER_A_CODE_SEG");
    bios.MEM.instance("LOADER_A_CODE_SEG").createHeap = 0;
    bios.MEM.instance("LOADER_A_CODE_SEG").len = 0x00010000;
    bios.MEM.instance("LOADER_A_CODE_SEG").space = "code";
    bios.MEM.instance("LOADER_A_CODE_SEG").base = 0x836f0000;
    bios.MEM.instance("LOADER_A_DATA_SEG").createHeap = 0;
    bios.MEM.instance("LOADER").len = 0x000e0000;
    bios.MEM.instance("LOADER_A_CODE_SEG").base = 0x836e0000;
    bios.MEM.instance("LOADER").destroy();
    bios.MEM.instance("LOADER_A_CODE_SEG").base = 0x83600000;
    bios.MEM.instance("LOADER_A_DATA_SEG").base = 0x83610000;
    bios.MEM.instance("LOADER_A_DATA_SEG").len = 0x009f0000;
    bios.MEM.instance("LOADER_A_CODE_SEG").len = 0x00008000;
    bios.MEM.create("LOADER_B_CODE_SEG");
    bios.MEM.instance("LOADER_B_CODE_SEG").enableHeapLabel = 0;
    bios.MEM.instance("LOADER_B_CODE_SEG").createHeap = 0;
    bios.MEM.instance("LOADER_B_CODE_SEG").base = 0x83608000;
    bios.MEM.instance("LOADER_B_CODE_SEG").len = 0x00008000;
    bios.MEM.instance("LOADER_B_CODE_SEG").space = "code";
    bios.MEM.SYSINITSEG = prog.get("LOADER_A_CODE_SEG");
    bios.MEM.SYSINITSEG = prog.get("ISRAM");
    bios.MEM.SYSINITSEG = prog.get("LOADER_A_CODE_SEG");
    bios.MEM.SYSINITSEG = prog.get("ISRAM");
    bios.MEM.SYSINITSEG = prog.get("LOADER_A_CODE_SEG");
    bios.MEM.SYSINITSEG = prog.get("ISRAM");
    bios.MEM.SYSINITSEG = prog.get("LOADER_A_CODE_SEG");
    bios.MEM.SYSINITSEG = prog.get("ISRAM");
    bios.MEM.instance("NC_SDRAM").space = "code/data";
    bios.MEM.instance("NC_SDRAM").space = "data";
    bios.MEM.SYSINITSEG = prog.get("LOADER_A_CODE_SEG");
    bios.MEM.SYSINITSEG = prog.get("ISRAM");
    bios.GBL.C641XCONFIGUREL2 = 0;
    bios.GBL.C641XCONFIGUREL2 = 1;
    bios.GBL.C641XCCFGL2MODE = "4-way cache (64k)";
    bios.GBL.C641XCCFGL2MODE = "4-way cache (128k)";
    bios.GBL.CALLUSERINITFXN = 0;
    bios.MEM.SYSINITSEG = prog.get("LOADER_A_CODE_SEG");
    bios.MEM.SYSINITSEG = prog.get("ISRAM");
    bios.MEM.SYSINITSEG = prog.get("LOADER_A_CODE_SEG");
    bios.MEM.SYSINITSEG = prog.get("ISRAM");
    // !GRAPHICAL_CONFIG_TOOL_SCRIPT_INSERT_POINT!
    
    if (config.hasReportedError == false) {
        prog.gen();
    }
    

    //wait until bit 1 of L2WBINV going to 0 , as written on page 62 of spru610

     

    The C bit continues

    to read as 1 until the cache operation is complete. Programs can poll to

    determine when a cache operation is complete.

     

    While( (*(int *)0x01845004) & 0x1 != 0)

    {

      

    }

     

    But my program is stalled inside while loop ! Does it means that the cache invalidate never completed ? What wrong I my code ?

    See  attached TCF file with memory configuration ( i change the Tcf extention to TXT , because i can;t attach tcf files in this forum)

     

  • Genady,

    Have you given up on the IP and ID bits? That was what your thread started on? Are you asking a new question now, or how should I follow this, in case I am doing that incorrectly?

    What have you determined by debug of this new problem. Have you run to the while loop and examined the register to see if its value is stuck or if it was ever changed?

    Have you considered using our CSL to help you get past problems that were solved a long time ago in the implementation of the CSL? There are constants and pointers and data types and functions that we have written to do these things. And there are examples that go with these. Please consider using the CSL to avoid having to teach yourself all of the things that were solved previously.

    Regards,
    RandyP

  • Hi Randy

     All my questions  it’s about the same problem that I have .

    May be I need to give here full problem description

     I am trying to implement the tertiary boot loader (the first boot loader , its copying of 1k from flash, the secondary , its 1k that  copies the code of tertiary boot loader to the memory,

    And the tertiary boot loader, copies the final program to memory and jump to c_init  of main program)

     

    Everything works fine , in first and secondary boot loader, but in tertiary loader , I have a problem when I want to activate the final program.

    The tertiary loader and final program share the same memory space  , except the function that makes copy of code  , and variables , that I use in function

    Both , code function and variables place in separated memory segment

     

     

    I understand , that after the copying of code to program memory , I need manually  execute  cache invalidate operation, and I am trying to do  that , after copying of final before I jump to

    C_init

     

    asm(" .global _entryAddr ");

    asm(" mvkl _entryAddr, B1 ");

    asm(" mvkh _entryAddr, B1 ");

    asm(" ldw *B1, B2 ");

    asm(" nop 4 ");

     

    //here I need execute flash invalidate operation

    //

     

    asm(" b .S2 B2 ");

    asm(" nop 5 ");

     

    If I want to use here CSL function , I need to place the csl_cache.obj in separated segment , where is the copy code is located

    Instead that I choose to use the CSL macro directly , to access to cash register, I take the example from CSL source code

     

    asm(" .global _entryAddr ");

    asm(" mvkl _entryAddr, B1 ");

    asm(" mvkh _entryAddr, B1 ");

    asm(" ldw *B1, B2 ");

    asm(" nop 4 ");

     

    //code from CACHE_wbInvL2 CSL function

     CACHE_FSET(L2WBINV,C,1);

     while (CACHE_FGET(L2WBINV,C))

                    i++;

      if (i < 4)

     {

          CACHE_FSET(L2WBINV,C,1);

          while (CACHE_FGET(L2WBINV,C))

                ;

     }

     

    // and after that , invalidate the rest of lines in L1D and L1P

    CACHE_FSET(CCFG,ID,1);

    CACHE_FSET(CCFG,IP,1);

    //branch to c_init of new code

    asm(" b .S2 B2 ");

    asm(" nop 5 ");

     

    Its does not work . After branching to c_init (entryAddr) , the program execution is stalled

    What wrong in my code . I trying almost everything and It does not work, include the way from 2.4 Self-Modifying Code and L1P Coherence from SPRU656a.pdf

    Nothing help.

    But , if I put the c_init of final code in separated segment .Its means that the code not in cache for sure, everything is working ok.

    May be you have example code of tertiary boot loader , the TI provides only secondary boot loader application note

     

    Thanks  a lot for you help

     

     

     

     

  • Genady,

    There is no real difference I can imagine between the concept of a secondary bootloader (loads a program and runs it) and a tertiary bootloader (loads a program and runs it). Cache coherence is an issue in both cases and should be solved similarly in both cases, depending on the details of your design.

    Have you set a breakpoint at the B .s2 B2 to see if it goes to the right place and sees the right code?

    Regards,
    RandyP

  • You write , there is no difference in concept

    But in secondary boot loader , usually the L2 cache is disabled

    I have L2 already enabled

    I looked on spra999a application notes example code , they mention the cache coherency issue , in spra999a document

    but in their example of boot (rf3_dsk6713_boot_with_table project ,  boot_c671x.s62 file) I did not see any operations with cache

     When I set the breakpoint on “ B .s2 B2” command , I see that I jump to the right place and see the right code (in disassembly window)

    But when I try to execute this ,step by step , something strange happens .. its seems , like I see one code and execute another

     Seems to me like the problem  with L1P coherence .

     I tried 2 things:

     

          Disable and write all L2 and L1 cache before I start open the operational program image

     

    CACHE_wbInvAllL2(CACHE_WAIT);

       CACHE_invAllL1p();

       CACHE_wait();

       CACHE_reset()

       CACHE_resetEMIFA();

       CACHE_resetL2Queue(CACHE_L2Q0);

       CACHE_resetL2Queue(CACHE_L2Q1);

    CACHE_resetL2Queue(CACHE_L2Q2);

       CACHE_resetL2Queue(CACHE_L2Q3);

     

    ….

     

    Open the image

    ….

    Call to CSL macros to invalidate L1P and L1D cache

     

    CACHE_FSET(CCFG,ID,1);

    CACHE_FSET(CCFG,IP,1);

     

    Branch to c_init

     

    B .s2 B2

     

    But u still  have the same problem

     

    Regards

    Kagan Genady

  • Genady,

    You are making this very complicated and may be leaving out very important details. From what you have said, it is definitely a complicated and dangerous way to try to implement your bootloader. Let me quote a few statements that worry me:

    Genady Kagan said:

    But in secondary boot loader , usually the L2 cache is disabled

    I have L2 already enabled

    This is a red flag #1. If the usual process is different from what you are doing, then you should go back to the usual process. Try leaving L2 cache disabled until you get to the final program and let it take care of enabling cache as it needs to. Do not make your bootloading job harder than it needs to be. by doing things differently.

    Genady Kagan said:

    When I set the breakpoint on “ B .s2 B2” command , I see that I jump to the right place and see the right code (in disassembly window)

    But when I try to execute this ,step by step , something strange happens .. its seems , like I see one code and execute another

    Seems to me like the problem  with L1P coherence .

    This sounds like a classic example of cache problems. Using the CCSv5 Memory Browser, you can look at the program memory where “ B .s2 B2” is located and confirm that caching status of that location. The Memory Browser uses color coding to show if that location is cached or not. You can select on or off all three of the caches to see what is in the physical memory location (all unchecked) and compare that with what is in the cache, if anything, by checking the three cache boxes one at a time.

    Genady Kagan said:

    I am trying to implement the tertiary boot loader (the first boot loader , its copying of 1k from flash, the secondary , its 1k that  copies the code of tertiary boot loader to the memory,

    And the tertiary boot loader, copies the final program to memory and jump to c_init  of main program)

    Which one initializes the EMIF for external memory?

    Where do the secondary bootloader, tertiary bootloader, and final program run from in memory? Where are the tertiary bootloader and the final program loaded into memory, if different from their run location?

    Genady Kagan said:

    The tertiary loader and final program share the same memory space  , except the function that makes copy of code  , and variables , that I use in function

    Both , code function and variables place in separated memory segment

    Sharing the same memory space just begs to have a problem. You should consider this to be the wrong way to do this. Load or certainly run the tertiary bootloader from some memory space that is either not used at all by the final program, or is uninitialized data space such as heap (.sysmem) or stack or other large uninitialized data space.

    When the tertiary bootloader copies the final program onto the same memory space where the tertiary bootloader is running, almost everything that can happen is bad. Please, stop doing it that way. Or at the very least, stop doing it that way, get it working, then go back to doing the difficult way when you have spare time in the project.

    Genady Kagan said:

    asm(" ldw *B1, B2 ");

    //cache operations (or anything)

    //branch to c_init of new code

    asm(" b .S2 B2 ");

    You cannot interleave assembly and C like this. Yes, you can write it and compile it like this, but you cannot expect register values to survive from the "ldw B2" all the way down to the "b B2".  This is why I asked you about setting a breakpoint on the branch instruction and see if it goes to the right place. More specifically, you should inspect the B2 register from the Register window to see if it has the value of _c_init of the final program. And continue to use the Memory Browser to inspect memory through the cache color codes.

    Since you have not mentioned where the tertiary bootloader is being loaded from, or where the final program is being loaded from (Flash, Ethernet, serial port, etc.), it is not possible for me to fully understand the system operation of the bootloading.

    Other than the complexity of the source of the programs, the job of the bootloader should be as simple as

    1. Invalidate all cache.
    2. Load the program and initialized data, but not on top of the bootloader's program and data.
    3. WritebackInvalidate all data cache and invalidate all L1P.

    You were originally having trouble with the L1P/L1D global commands, but even if those were solved you would still have problems with the whole process because of the way the rest of the code and process are being done. I do not know if what I have said is helpful, but I hope it is not offensive in my choice of words. I need to tell you my true opinions or my advice is worth nothing to you, and that may be the case anyway. Best of luck.

    Regards,
    RandyP

  • Hi Randy

    I will probably use the different segment in memories model for my loader as you propose

     

    Thanks a lot