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.

PROCESSOR-SDK-OMAPL138: Moving all SYS/BIOS related to IRAM on OMAPL138

Part Number: PROCESSOR-SDK-OMAPL138
Other Parts Discussed in Thread: SYSBIOS, OMAPL138, OMAP-L138

Hi support,

I want to move all SYS/BIOS related from DDR and into IRAM to increase SYS/BIOS performance.

Tools:

  • SYSBIOS version: 6.76.03.01
  • xdctools_3_55_02_22_core
  • ipc_3_50_04_08

I stumbled upon this post: https://e2e.ti.com/support/legacy_forums/embedded/tirtos/f/ti-rtos-forum-read-only-archived/110524/why-is-it-so-difficult-to-assign-bios-memory-sections-for-sysbios-verses-dspbios
and created an additional ".cmd" file with wildcards for all knl, hwi and remaining sysbios related.

Ideally, I want to both "load" and "run" SYS/BIOS API's in IRAM, but I am somehow only able to "load" SYS/BIOS API's in DDR and "run" in IRAM.
I should also mention that I am running Linux on the ARM side and using remoteproc to load the DSP. I recall it was not possible to use remoteproc to translate IRAM addresses on OMAPL138, but I wonder if this is also still the case, since I have numerous memory sections loaded into IRAM as indicated in my ".cfg" script below and remoteproc is "succesfully" able to load the DSP. Only SYS/BIOS api's are unable to be loaded into IRAM.

This is e.g. How I am using the wildcards in the ".cmd" file.The DSP firmware is in elf format, hence the "_" before "ti" is removed:

    /* Place all the knl APIs in IRAM */

    .knl: { *.o*(.text:ti_sysbios_knl*) } LOAD = IRAM, RUN = IRAM, table(_knl_table)



    /* Place all the HWI APIs in IRAM */

    .hwi: { *.o*(.text:ti_sysbios*_Hwi_*) } LOAD = IRAM, RUN = IRAM, table(_hwi_table)



    /* Place all the remaining SYS/BIOS APIs in IRAM */

    .sysbios: { *.o*(.text:ti_sysbios*) } LOAD = IRAM, RUN = IRAM, table(_sysbios_table)


My RTSC platform from CCS:

My ".cfg" script.

/* root of the configuration object model */
var Program = xdc.useModule('xdc.cfg.Program');

// Use this to run function upon reset of DSP
//var Reset 	 					           = xdc.useModule('xdc.runtime.Reset');

// Make sure that copyDDRToIRAM function is ran prior to SYS/BIOS & before module initialization
var Startup 					           = xdc.useModule('xdc.runtime.Startup');
Startup.firstFxns[Startup.firstFxns.length++] = '&copyDDRToIRAM';

// Use this to load function after module initialization
//Startup.lastFxns[Startup.lastFxns.length++]   = '&myLast';

/* application uses the following modules and packages */
xdc.useModule('xdc.runtime.Assert');
xdc.useModule('xdc.runtime.Diags');
xdc.useModule('xdc.runtime.Error');
xdc.useModule('xdc.runtime.Log');
xdc.useModule('xdc.runtime.Registry');
xdc.useModule('ti.sysbios.knl.Semaphore');
xdc.useModule('ti.sysbios.knl.Task');

var Mailbox                     = xdc.useModule('ti.sysbios.knl.Mailbox');
var Timestamp                   = xdc.useModule('xdc.runtime.Timestamp');
var Hwi 	 					            = xdc.useModule('ti.sysbios.hal.Hwi');
var HeapMem                     = xdc.useModule('ti.sysbios.heaps.HeapMem');
var GateSwi                     = xdc.useModule('ti.sysbios.gates.GateSwi');
var Memory                      = xdc.useModule('xdc.runtime.Memory');
var Semaphore                   = xdc.useModule('ti.sysbios.knl.Semaphore');
var BIOS                        = xdc.useModule('ti.sysbios.BIOS');
var Exception                   = xdc.useModule('ti.sysbios.family.c64p.Exception');
Exception.enablePrint           = true;

// Use custom type to generate optimized library files for SYS/BIOS
BIOS.libType = BIOS.LibType_Custom;

// Use Debug type to generate binary with debug symbols to load in ccs
//BIOS.libType = BIOS.LibType_Debug;

BIOS.heapTrackEnabled = false;
BIOS.assertsEnabled = false;
BIOS.logsEnabled = false;

/* Enable task & swi DSP */
BIOS.taskEnabled = true;
BIOS.swiEnabled = true;

/*  Task */
var Task = xdc.useModule('ti.sysbios.knl.Task');
Task.common$.namedInstance = true;
Task.defaultStackSize = 2048;

/* HWI */
var Hwi_c64p = xdc.useModule('ti.sysbios.family.c64p.Hwi');
Hwi_c64p.enableException = true;
Hwi_c64p.dispatcherSwiSupport = true;
Hwi_c64p.dispatcherTaskSupport = true;

/* ======== Idle tasks ======== */
var Idle = xdc.useModule('ti.sysbios.knl.Idle')
Idle.addFunc('&cpuload_IdleFxn');
//Idle.addFunc('&heapTracker_IdleFxn');

/*
 *  ======== HEAP Configuration ========
 */

/* Allow malloc in swi */
HeapMem.common$.gate = GateSwi.create();

/* IRAM Heap Configuration */
var iramHeapParams  	     = new HeapMem.Params;
iramHeapParams.size 	     = 0x00004000;
iramHeapParams.sectionName = "IRAM_HEAP";
Program.global.iramHeap	   = HeapMem.create(iramHeapParams);

/* DDR Heap Configuration */
var ddrHeapParams  	   		 = new HeapMem.Params;
ddrHeapParams.size 	   		 = 0x00400000;
ddrHeapParams.sectionName  = "DDR_HEAP";
Program.global.ddrHeap     = HeapMem.create(ddrHeapParams);

/* STREAMING Heap Configuration */
var streamingDataHeapParams         = new HeapMem.Params;
streamingDataHeapParams.size 	      = 0x00fd0000;
streamingDataHeapParams.sectionName = "STREAMING_DATA_HEAP";
Program.global.streamingDataHeap	  = HeapMem.create(streamingDataHeapParams);

/* default memory heap */
var Memory = xdc.useModule('xdc.runtime.Memory');
Memory.defaultHeapInstance = Program.global.ddrHeap;

/* create a heap for MessageQ messages */
var HeapBuf = xdc.useModule('ti.sysbios.heaps.HeapBuf');
var params = new HeapBuf.Params;
params.align = 8;
params.blockSize = 512;
params.numBlocks = 256;
var msgHeap = HeapBuf.create(params);

Program.global.IPCHeap = HeapBuf.create(params);


/*
 *  ======== IPC Configuration ========
 */
var ipcmgr = xdc.useModule('ti.ipc.ipcmgr.IpcMgr');

/* describe the processors in the system */
var MultiProc = xdc.useModule('ti.sdo.utils.MultiProc');
MultiProc.setConfig("DSP", ["HOST", "DSP"]); // This sets the Multiproc id's for the ARM & DSP
                                             // ARM/HOST=0, DSP=1

/* Specify synchronization of processors */
//var Ipc = xdc.useModule('ti.sdo.ipc.Ipc');
//Ipc.procSync = Ipc.ProcSync_PAIR;

BIOS.addUserStartupFunction('&IpcMgr_ipcStartup');
//BIOS.addUserStartupFunction('&IpcMgr_callIpcStart');

var MessageQ  = xdc.useModule('ti.sdo.ipc.MessageQ');
//MessageQ.registerHeapMeta(msgHeap, 0); // Notice that HeapId is 0. Use this to refer to IPCHeap in C code
MessageQ.registerHeapMeta(Program.global.IPCHeap, 0); // Notice that HeapId is 0. Use this to refer to IPCHeap in C code

/* Setup MessageQ transport */
var RpmsgSetup = xdc.useModule('ti.ipc.transports.TransportRpmsgSetup');
MessageQ.SetupTransportProxy = RpmsgSetup;
//RpmsgSetup.common$.diags_INFO = Diags.RUNTIME_ON;

/* Setup NameServer remote proxy */
var NameServer = xdc.useModule("ti.sdo.utils.NameServer");
var NsRemote = xdc.useModule("ti.ipc.namesrv.NameServerRemoteRpmsg");
NameServer.SetupProxy = NsRemote;

/* Enable Memory Translation module that operates on the Resource Table */
var Resource = xdc.useModule('ti.ipc.remoteproc.Resource');
Resource.loadSegment = Program.platform.dataMemory;
Resource.customTable = true; // Compile rsc_table_omapl138.c file & use as resource table

/*  Use SysMin because trace buffer address is required for Linux/QNX
 *  trace debug driver, plus provides better performance.
 */
//var System = xdc.useModule('xdc.runtime.System');
//var SysMin = xdc.useModule('ti.trace.SysMin');
//System.SupportProxy = SysMin;
//SysMin.bufSize  = 0x2000;


/*
 *  ======== Cache Configuration ========
 */
var Cache = xdc.useModule('ti.sysbios.family.c64p.Cache');

/* Set 0xc0000000 -> 0xc3ffffff to be non-cached VirtQueue based IPC
 * Set 0xc4000000 -> 0xc4ffffff to be cached. Not currently not used
 */
Cache.MAR128_159 = 0x0; // Do not cache shared memory
//Cache.MAR192_223 = 0xFFFFFF7F; // Cache DDR memory except 0xC700 0000 - C7FF FFFF
Cache.MAR192_223 = 0x00000010;


/*
 *  ======== Clock Configuration ========
 */
/* Configure clock module */
var Clock = xdc.useModule('ti.sysbios.knl.Clock');
Clock.timerId = 3; // SYS/BIOS can use timer 2-3, Linux is using 0-1
Clock.tickPeriod = 1000; // 1ms between ticks
                         // tickPeriod is specified in microseconds
Clock.tickSource = Clock.TickSource_TIMER;

/* Create pm 1ms timer*/
var prd1msClockParams = new Clock.Params;
prd1msClockParams.startFlag = true;
prd1msClockParams.period = 1;
var prd1msClock = Clock.create('&PmOn1ms', 1, prd1msClockParams);


/*
 *  ======== Memory section Configuration ========
 */
//Program.sectMap[".tracebuf"] = "DDR";
//Program.sectMap[".errorbuf"] = "DDR";

Program.sectMap[".text:_c_int00"] = new Program.SectionSpec();
Program.sectMap[".text:_c_int00"].loadSegment = "DDR";
Program.sectMap[".text:_c_int00"].loadAlign = 0x400;

/* System stack size (used by ISRs and Swis) */
Program.sectMap[".stack"] = new Program.SectionSpec();
Program.sectMap[".stack"].loadSegment = "IRAM";

// Move SYS/BIOS APIs to IRAM
//Program.sectMap[".text:ti_sysbios_knl_Swi_post__E"] = new Program.SectionSpec();
//Program.sectMap[".text:ti_sysbios_knl_Swi_post__E"] = "IRAM";

// Heaps
Program.sectMap["DDR_HEAP"]  			                 = new Program.SectionSpec();
Program.sectMap["DDR_HEAP"].loadSegment            = "DDR";

Program.sectMap["IRAM_HEAP"] 			                 = new Program.SectionSpec();
Program.sectMap["IRAM_HEAP"].loadSegment           = "IRAM";

Program.sectMap["STREAMING_DATA_HEAP"]             = new Program.SectionSpec();
Program.sectMap["STREAMING_DATA_HEAP"].loadSegment = "STREAMING_DATA";

Program.sectMap["IPC_HEAP"]                        = new Program.SectionSpec();
Program.sectMap["IPC_HEAP"].loadSegment            = "RPMSG_MEM"

// Move to IRAM
Program.sectMap[".sysmem"] = new Program.SectionSpec();
Program.sectMap[".sysmem"].loadSegment = "IRAM";
Program.sectMap[".sysmem"].runSegment = "IRAM";

Program.sectMap[".c6xabi.exidx"] = new Program.SectionSpec();
Program.sectMap[".c6xabi.exidx"].loadSegment = "IRAM";
Program.sectMap[".c6xabi.exidx"].runSegment = "IRAM";

Program.sectMap[".c6xabi.extab"] = new Program.SectionSpec();
Program.sectMap[".c6xabi.extab"].loadSegment = "IRAM";
Program.sectMap[".c6xabi.extab"].runSegment = "IRAM";

Program.sectMap[".ti.handler_table"] = new Program.SectionSpec();
Program.sectMap[".ti.handler_table"].loadSegment = "IRAM";

Program.sectMap[".bss"] = new Program.SectionSpec();
Program.sectMap[".bss"].loadSegment = "IRAM";
Program.sectMap[".bss"].runSegment = "IRAM";

Program.sectMap[".neardata"] = new Program.SectionSpec();
Program.sectMap[".neardata"].loadSegment = "IRAM";
Program.sectMap[".neardata"].runSegment = "IRAM";

Program.sectMap[".rodata"] = new Program.SectionSpec();
Program.sectMap[".rodata"].loadSegment = "IRAM";
Program.sectMap[".rodata"].runSegment = "IRAM";

My custom ressource table:

#ifndef _RSC_TABLE_OMAPL138_H_
#define _RSC_TABLE_OMAPL138_H_

#include "rsc_types.h"

/* ====== DSP Memory Map ====== */
#define L3_CBA_RAM_BASE        (0x80000000)
#define CACHE_L2_BASE          (0x11820000)
#define CACHE_L1P_BASE         (0x11e00000)
#define CACHE_L1D_BASE         (0x11f00000)
#define UPP_BASE               (0x11800000)
#define IRAM_BASE              (0x11800400)
#define DDR_BASE               (0xC6100000)
#define STREAMING_DATA         (0xC7030000)
#define RPMSG_MEM              (0xC6800000)
// #define POOLMEM                (0xC6900000)

#define L3_CBA_RAM_SIZE        (0x20000)
#define CACHE_L2_SIZE          (0x20000)
#define CACHE_L1P_SIZE         (0x8000)
#define CACHE_L1D_SIZE         (0x8000)
#define UPP_SIZE               (0x400)
#define IRAM_SIZE              (0x1FC00)
#define DDR_SIZE               (0x6F0000)
#define STREAMING_DATA_SIZE    (0xFD0000)
#define RPMSG_MEM_SIZE         (0x100000)

// #define POOLMEM_SIZE           (0x730000)
// #define POOLMEM_SIZE           (0x6ACFC0)

// #define TRACEBUFSIZE           (0x1000) // If this is changed, remember to also change in dsp.cfg

/*
 * sizes of the virtqueues (expressed in number of buffers supported,
 * and must be power of 2)
 */
#define RPMSG_VQ0_SIZE          256
#define RPMSG_VQ1_SIZE          256

/* flip up bits whose indices represent features we support */
#define RPMSG_DSP_FEATURES      1

/* Amount of rsc table entries */
#define NUM_RSC_ENTRIES 10

struct my_resource_table {
    struct resource_table base;

    UInt32 offset[NUM_RSC_ENTRIES];

    /* rpmsg vdev entry */
    struct fw_rsc_vdev rpmsg_vdev;
    struct fw_rsc_vdev_vring rpmsg_vring0;
    struct fw_rsc_vdev_vring rpmsg_vring1;

    /* data carveout entry */
    struct fw_rsc_carveout ddr_cout;

    /* iram carveout entry */
    struct fw_rsc_carveout upp_cout;

    /* iram carveout entry */
    struct fw_rsc_carveout iram_cout;

    /* shared mem carveout entry */
    struct fw_rsc_carveout sm_cout;

    /* cache L2 carveout entry */
    struct fw_rsc_carveout l2_cout;

    /* cache L1P carveout entry */
    struct fw_rsc_carveout l1p_cout;

    /* cache L1D carveout entry */
    struct fw_rsc_carveout l1d_cout;

    /* streaming data carveout entry */
    struct fw_rsc_carveout streaming_data_cout;

    /* streaming data carveout entry */
    struct fw_rsc_carveout rpmsg_cout;

    /* poolmem data carveout entry */
    // struct fw_rsc_carveout poolmem_cout;

    /* trace entry */
    // struct fw_rsc_trace trace;
};

extern char * ti_trace_SysMin_Module_State_0_outbuf__A;
#define TRACEBUFADDR (UInt32)&ti_trace_SysMin_Module_State_0_outbuf__A

#pragma DATA_SECTION(ti_ipc_remoteproc_ResourceTable, ".resource_table")
#pragma DATA_ALIGN(ti_ipc_remoteproc_ResourceTable, 4096)
#define RPMSG_VRING_ADDR_ANY FW_RSC_ADDR_ANY

/* ====== Resource table ====== */
struct my_resource_table ti_ipc_remoteproc_ResourceTable = {
    1, /* we're the first version that implements this */
    NUM_RSC_ENTRIES, /* number of entries in the table */
    0, 0, /* reserved, must be zero */

    /* offsets to entries */
    {
        offsetof(struct my_resource_table, rpmsg_vdev),
        offsetof(struct my_resource_table, ddr_cout),
        offsetof(struct my_resource_table, upp_cout),
        offsetof(struct my_resource_table, iram_cout),
        offsetof(struct my_resource_table, sm_cout),
        offsetof(struct my_resource_table, l2_cout),
        offsetof(struct my_resource_table, l1p_cout),
        offsetof(struct my_resource_table, l1d_cout),
        offsetof(struct my_resource_table, streaming_data_cout),
        offsetof(struct my_resource_table, rpmsg_cout),
        // offsetof(struct my_resource_table, poolmem_cout),
        // offsetof(struct my_resource_table, trace),
    },

    /* rpmsg vdev entry */
    {
        TYPE_VDEV, VIRTIO_ID_RPMSG, 0,
        RPMSG_DSP_FEATURES, 0, 0, 0, 2, { 0, 0 },
        /* no config data */
    },
    /* the two vrings */
    { RPMSG_VRING_ADDR_ANY, 4096, RPMSG_VQ0_SIZE, 1, 0 },
    { RPMSG_VRING_ADDR_ANY, 4096, RPMSG_VQ1_SIZE, 2, 0 },

    {
        TYPE_CARVEOUT,
        DDR_BASE, DDR_BASE,
        DDR_SIZE, 0, 0, "DDR",
    },

    {
      TYPE_CARVEOUT,
      UPP_BASE, UPP_BASE,
      UPP_SIZE, 0, 0, "UPP",
    },

    {
      TYPE_CARVEOUT,
      IRAM_BASE, IRAM_BASE,
      IRAM_SIZE, 0, 0, "IRAM",
    },

    {
      TYPE_CARVEOUT,
      L3_CBA_RAM_BASE, L3_CBA_RAM_BASE,
      L3_CBA_RAM_SIZE, 0, 0, "SHARED_MEM",
    },

    {
      TYPE_CARVEOUT,
      CACHE_L2_BASE, CACHE_L2_BASE,
      CACHE_L2_SIZE, 0, 0, "CACHE_L2",
    },

    {
      TYPE_CARVEOUT,
      CACHE_L1P_BASE, CACHE_L1P_BASE,
      CACHE_L1P_SIZE, 0, 0, "CACHE_L1P",
    },

    {
      TYPE_CARVEOUT,
      CACHE_L1D_BASE, CACHE_L1D_BASE,
      CACHE_L1D_SIZE, 0, 0, "CACHE_L1D",
    },

    {
      TYPE_CARVEOUT,
      STREAMING_DATA, STREAMING_DATA,
      STREAMING_DATA_SIZE, 0, 0, "STREAMING_DATA",
    },

    {
      TYPE_CARVEOUT,
      RPMSG_MEM, RPMSG_MEM,
      RPMSG_MEM_SIZE, 0, 0, "RPMSG",
    },

    // {
    //   TYPE_CARVEOUT,
    //   POOLMEM, POOLMEM,
    //   POOLMEM_SIZE, 0, 0, "POOLMEM",
    // },

    // {
    //   TYPE_TRACE,
    //   TRACEBUFADDR,
    //   TRACEBUFSIZE, 0, "trace:dsp",
    // },
};

#endif /* _RSC_TABLE_OMAPL138_H_ */

Thanks & Regards,
Kim