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++] = '©DDRToIRAM'; // 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