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.

TMS320C6678: Can we place .stack on MSMC SRAM ?

Part Number: TMS320C6678

Hi All,

I am trying to port my code to a TMDSEVM6678LE. We have function that does a lot of recursions and it runs for when I place the .stack on the L2SRAM. However, if I try to place it on MSMC SRAM I get the below error when I try to load the program on a core. 

Please let me know if there is any workaround.

Regards

  • Hello Mike,

    I do not know, whether there is any limitation to put stack onto MCSM, hope gurus will say their word.

    Meantime I'd like to point, that approach you have chosen might not be that efficient. Although MCSM access is optimized in terms of throughput, its access latency would exceed that one of L2SRAM. Normally we want these temporary storage memories like stack to be maximally fast and with lowest latency. In your case you abuse stack in a way, that recursion simplifies your algorithm. In your shoes I would rather work on algorithm complexity, which may do its job with either no recursion, or recursion with little amount of auto variables, keeping data buffers pre-allocated.

  • Hi rrlagic,

    You are right, I better keep the stack on L2SRAM for performance sake. The application is an OpenMP one so it has a cfg file from which the linker.cmd is derived. If I search in the cfg file, only .stack is placed there and as I checked the TMDSEVM6678LE   data sheet, L2SRAM size is 512KB for each core; however, I noticed that I can only increase the stack size up to 330KB (otherwise the .stack won't fit in L2SRAM) making me believe that there are are other stuff placed in L2SRAM. 

    When I checked linker.cmd, I found the below other stuff placed on the L2SRAM too and I am wondering how much space each takes and which ones can potentially be placed on other memories such as MSMC. 

    .ti.decompress: load > L2SRAM
    .pinit: load >> L2SRAM
    .init_array: load > L2SRAM
    .switch: load >> L2SRAM
    .cio: load >> L2SRAM
    .ti.handler_table: load > L2SRAM
    .c6xabi.exidx: load > L2SRAM
    .c6xabi.extab: load >> L2SRAM
    .vecs: load > L2SRAM
    
    

    Question #1: So my first question is if there is any way to find out the size of each section placed on L2SRAM so I can track down the largest ones and place in other memory segements? 

    Below you can find the linker.cmd fie along with the cfg file which I used successfully in serial execution (-p ti.platforms.evm6678).

    Question #2: The other thing that confuses me is that if a program can run successfully in serial mode why wouldn't it run in OpenMP mode and possibly suffer from lack if stack size given the fact that each core has its own L2SRAM and each omp thread should logically have enough space when placed on a processor core if things could run successfully in serial mode.

    Please let me know... 

    Regards 

    Here is the linker.cmd

    /*
     * Do not modify this file; it is automatically generated from the template
     * linkcmd.xdt in the ti.targets.elf package and will be overwritten.
     */
    
    /*
     * put '"'s around paths because, without this, the linker
     * considers '-' as minus operator, not a file name character.
     */
    
    
    -l"C:\Users\Mehdi-laptop\workspace_v9_2\ark_cpplab\Debug\configPkg\package\cfg\omp_config_pe66.oe66"
    -l"C:\Users\Mehdi-laptop\workspace_v9_2\ark_cpplab\src\sysbios\sysbios.ae66"
    -l"C:\ti\bios_6_76_02_02\packages\ti\targets\rts6000\lib\ti.targets.rts6000.ae66"
    -l"C:\ti\bios_6_76_02_02\packages\ti\targets\rts6000\lib\boot.ae66"
    
    --retain="*(xdc.meta)"
    
    
    --args 0x0
    -heap  0x0
    -stack 0x52800
    
    MEMORY
    {
        L2SRAM (RWX) : org = 0x800000, len = 0x80000
        MSMCSRAM (RWX) : org = 0xc000000, len = 0x400000
        DDR3 : org = 0x80000000, len = 0x20000000
    }
    
    /*
     * Linker command file contributions from all loaded packages:
     */
    
    /* Content from xdc.services.global (null): */
    
    /* Content from xdc (null): */
    
    /* Content from xdc.corevers (null): */
    
    /* Content from xdc.rov (null): */
    
    /* Content from xdc.runtime (null): */
    
    /* Content from xdc.rov.runtime (null): */
    
    /* Content from xdc.shelf (null): */
    
    /* Content from xdc.services.spec (null): */
    
    /* Content from xdc.services.intern.xsr (null): */
    
    /* Content from xdc.services.intern.gen (null): */
    
    /* Content from xdc.services.intern.cmd (null): */
    
    /* Content from xdc.bld (null): */
    
    /* Content from ti.targets (null): */
    
    /* Content from ti.targets.elf (null): */
    
    /* Content from ti.targets.rts6000 (null): */
    
    /* Content from ti.sysbios.interfaces (null): */
    
    /* Content from ti.sysbios.family (null): */
    
    /* Content from xdc.services.getset (null): */
    
    /* Content from ti.sysbios.family.c62 (null): */
    
    /* Content from xdc.runtime.knl (null): */
    
    /* Content from ti.sysbios.family.c64p.tci6488 (null): */
    
    /* Content from ti.catalog.c6000 (null): */
    
    /* Content from ti.catalog (null): */
    
    /* Content from ti.catalog.peripherals.hdvicp2 (null): */
    
    /* Content from xdc.platform (null): */
    
    /* Content from xdc.cfg (null): */
    
    /* Content from ti.platforms.evm6678 (null): */
    
    /* Content from ti.sysbios (null): */
    
    /* Content from ti.sysbios.rts (null): */
    
    /* Content from ti.sysbios.rts.ti (ti/sysbios/rts/ti/linkcmd.xdt): */
    
    /* Content from ti.sysbios.family.c64p (ti/sysbios/family/c64p/linkcmd.xdt): */
    
    /* Content from ti.sysbios.knl (null): */
    
    /* Content from ti.sysbios.timers.timer64 (null): */
    
    /* Content from ti.sysbios.family.c66 (ti/sysbios/family/c66/linkcmd.xdt): */
    ti_sysbios_family_c66_Cache_l1dSize = 32768;
    ti_sysbios_family_c66_Cache_l1pSize = 32768;
    ti_sysbios_family_c66_Cache_l2Size = 0;
    
    /* Content from ti.sysbios.hal (null): */
    
    /* Content from ti.sysbios.gates (null): */
    
    /* Content from ti.sysbios.xdcruntime (null): */
    
    /* Content from ti.sysbios.heaps (null): */
    
    /* Content from ti.sysbios.utils (null): */
    
    /* Content from configPkg (null): */
    
    /* Content from xdc.services.io (null): */
    
    
    /*
     * symbolic aliases for static instance objects
     */
    xdc_runtime_Startup__EXECFXN__C = 1;
    xdc_runtime_Startup__RESETFXN__C = 1;
    xdc_rov_runtime_Mon__checksum = 1;
    xdc_rov_runtime_Mon__write = 1;
    
    SECTIONS
    {
        .text: load >> MSMCSRAM
        .ti.decompress: load > L2SRAM
        .stack: load > L2SRAM
        GROUP: load > DDR3
        {
            .bss:
            .neardata:
            .rodata:
        }
        .cinit: load > DDR3
        .pinit: load >> L2SRAM
        .init_array: load > L2SRAM
        .const: load >> DDR3
        .data: load >> DDR3
        .fardata: load >> DDR3
        .switch: load >> L2SRAM
        .sysmem: load > DDR3
        .far: load >> DDR3
        .args: load > DDR3 align = 0x4, fill = 0 {_argsize = 0x0; }
        .cio: load >> L2SRAM
        .ti.handler_table: load > L2SRAM
        .c6xabi.exidx: load > L2SRAM
        .c6xabi.extab: load >> L2SRAM
        systemHeap: load > DDR3
        .vecs: load > L2SRAM
        xdc.meta: load > DDR3, type = COPY
    
    }
    




    Here is the omp_config.cfg

     

    /***************************/
    /* SECTION MAPPING         */
    /***************************/
    var program = xdc.useModule('xdc.cfg.Program');
    
    program.sectMap[".args"]        = new Program.SectionSpec();
    program.sectMap[".bss"]         = new Program.SectionSpec();
    program.sectMap[".cinit"]       = new Program.SectionSpec();
    program.sectMap[".cio"]         = new Program.SectionSpec();
    program.sectMap[".const"]       = new Program.SectionSpec();
    program.sectMap[".data"]        = new Program.SectionSpec();
    program.sectMap[".far"]         = new Program.SectionSpec();
    program.sectMap[".fardata"]     = new Program.SectionSpec();
    program.sectMap[".neardata"]    = new Program.SectionSpec();
    program.sectMap[".rodata"]      = new Program.SectionSpec();
    program.sectMap[".stack"]       = new Program.SectionSpec();
    program.sectMap[".switch"]      = new Program.SectionSpec();
    program.sectMap[".sysmem"]      = new Program.SectionSpec();
    program.sectMap[".text"]        = new Program.SectionSpec();
        
    // Must place these sections in core local memory 
    program.sectMap[".args"].loadSegment        = "DDR3";
    program.sectMap[".cio"].loadSegment         = "L2SRAM";
    
    // Variables in the following data sections can potentially be 'shared' in
    // OpenMP. These sections must be placed in shared memory.
    program.sectMap[".bss"].loadSegment         = "DDR3";
    program.sectMap[".cinit"].loadSegment       = "DDR3";
    program.sectMap[".const"].loadSegment       = "DDR3";
    program.sectMap[".data"].loadSegment        = "DDR3";
    program.sectMap[".far"].loadSegment         = "DDR3";
    program.sectMap[".fardata"].loadSegment     = "DDR3";
    program.sectMap[".neardata"].loadSegment    = "DDR3";
    program.sectMap[".rodata"].loadSegment      = "DDR3";
    program.sectMap[".sysmem"].loadSegment      = "DDR3";
    
    // Code sections shared by cores - place in shared memory to avoid duplication
    program.sectMap[".switch"].loadSegment      = program.platform.codeMemory;
    program.sectMap[".text"].loadSegment        = "MSMCSRAM";
    print(" program.platform.codeMemory = ", program.platform.codeMemory);
    
    // Size the default stack and place it in L2SRAM 
    var deviceName = String(Program.cpu.deviceName);
    if  (deviceName.search("DRA7XX") == -1) { program.stack = 330*1024; }
    else                                    { program.stack = 0x8000;  }
    program.sectMap[".stack"].loadSegment       = "L2SRAM"; // works in serial mode 256KB .stack
    
    // Since there are no arguments passed to main, set .args size to 0
    program.argSize = 0;
    /********************************/ /* OPENMP RUNTIME CONFIGURATION */ /********************************/ USE_OPENMP = false; if (USE_OPENMP) { // Include OMP runtime in the build var ompSettings = xdc.useModule("ti.runtime.openmp.Settings"); // Set to true if the application uses or has dependencies on BIOS components ompSettings.usingRtsc = true; if (ompSettings.usingRtsc) { /* Configure OpenMP for BIOS * - OpenMP.configureCores(masterCoreId, numberofCoresInRuntime) * Configures the id of the master core and the number of cores * available to the runtime. */ var OpenMP = xdc.useModule('ti.runtime.ompbios.OpenMP'); // Configure the index of the master core and the number of cores available // to the runtime. The cores are contiguous. OpenMP.masterCoreIdx = 0; // Setup number of cores based on the device if (deviceName.search("DRA7XX") != -1) { OpenMP.numCores = 2; } else if (deviceName.search("6670") != -1) { OpenMP.numCores = 4; } else if (deviceName.search("6657") != -1) { OpenMP.numCores = 2; } else if (deviceName.search("K2L") != -1) { OpenMP.numCores = 4; } else { OpenMP.numCores = 8; } // Pull in memory ranges described in Platform.xdc to configure the runtime var ddr3 = Program.cpu.memoryMap["DDR3"]; var ddr3_nc = Program.cpu.memoryMap["DDR3_NC"]; var msmc = Program.cpu.memoryMap["MSMCSRAM"]; var msmcNcVirt = Program.cpu.memoryMap["OMP_MSMC_NC_VIRT"]; var msmcNcPhy = Program.cpu.memoryMap["OMP_MSMC_NC_PHY"]; // Initialize the runtime with memory range information if (deviceName.search("DRA7XX") == -1) { OpenMP.msmcBase = msmc.base OpenMP.msmcSize = msmc.len; OpenMP.msmcNoCacheVirtualBase = msmcNcVirt.base; OpenMP.msmcNoCacheVirtualSize = msmcNcVirt.len; OpenMP.msmcNoCachePhysicalBase = msmcNcPhy.base; } else { OpenMP.allocateStackFromHeap = true; OpenMP.allocateStackFromHeapSize = 0x010000; OpenMP.hasMsmc = false; OpenMP.ddrNoCacheBase = ddr3_nc.base; OpenMP.ddrNoCacheSize = ddr3_nc.len; } OpenMP.ddrBase = ddr3.base; OpenMP.ddrSize = ddr3.len; // Configure memory allocation using HeapOMP // HeapOMP handles // - Memory allocation requests from BIOS components (core local memory) // - Shared memory allocation by utilizing the IPC module to enable // multiple cores to allocate memory out of the same heap - used by malloc if (deviceName.search("DRA7XX") == -1) { print("deviceName.search(\"DRA7XX\") == -1") var HeapOMP = xdc.useModule('ti.runtime.ompbios.HeapOMP'); // Shared Region 0 must be initialized for IPC var sharedRegionId = 0; // Size of the core local heap var localHeapSize = 0x8000; // Size of the heap shared by all the cores // var sharedHeapSize = 0x08000000; var sharedHeapSize = (512-32-22)*1024*1024; // Initialize a Shared Region & create a heap in the DDR3 memory region var SharedRegion = xdc.useModule('ti.sdo.ipc.SharedRegion'); SharedRegion.setEntryMeta( sharedRegionId, { base: ddr3.base, len: sharedHeapSize, ownerProcId: OpenMP.masterCoreIdx, cacheEnable: true, createHeap: true, isValid: true, name: "DDR3_SR0", }); // Configure and setup HeapOMP HeapOMP.configure(sharedRegionId, localHeapSize); /* var HeapTrack = xdc.useModule('ti.sysbios.heaps.HeapTrack'); var heapTrackParams = new HeapTrack.Params; heapTrackParams.heap = HeapOMP; var myHeapTracker = HeapTrack.create(heapTrackParams); */ } else { OpenMP.useIpcSharedHeap = false; OpenMP.allocateLocalHeapSize = 0x8000 OpenMP.allocateSharedHeapSize = 0x00800000 } var Startup = xdc.useModule('xdc.runtime.Startup'); Startup.lastFxns.$add('&__TI_omp_initialize_rtsc_mode'); } else { /* Size the heap. It must be placed in shared memory */ program.heap = sharedHeapSize; } var BIOS = xdc.useModule('ti.sysbios.BIOS'); print("BIOS.heapSize = ", BIOS.heapSize) // BIOS.cpuFreq.lo = 1250000000; // Use no openmp } else { var BIOS = xdc.useModule('ti.sysbios.BIOS'); BIOS.heapSize = (512-32-22)*1024*1024; Program.sectMap["systemHeap"] = new Program.SectionSpec(); Program.sectMap["systemHeap"].loadSegment = "DDR3"; BIOS.heapSection = "systemHeap"; }

  • Hi,

    From *.map file you can see how big each section is. 

    If you code can run with .stack in L2, they should be able to be placed on MSMC as well. Maybe this is a multiple-core program and each core should have it is own stack. So you can move some common code/data into MSMC to shared among all cores and leave room for stack per core. An example .cmd is attached.https://e2e.ti.com/cfs-file/__key/communityserver-discussions-components-files/791/pcieboot_5F00_helloworld.cmd

    Regards, Eric