Where can I find information about SMP (Symmetric Multi-Processing) that is in SYS/BIOS?
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.
Where can I find information about SMP (Symmetric Multi-Processing) that is in SYS/BIOS?
Target | Supported TI SOC devices |
---|---|
Dual-core Cortex-M3/M4 subsystem | OMAP44xx, OMAP54xx, DM81xx, DRA74x (Jacinto 6), TDA2x (ADAS), TDA3x, AM57xx (Sitara) |
Multi-core Cortex-A15 subsystem | OMAP54xx, DRA74x (Jacinto 6), TDA2x (ADAS), AM572x/AM574x (Sitara), Keystone2 |
The rule that the N highest priority ready tasks will be running at any given time may get violated if the application has a mix of don't care and fixed affinity tasks. However, the rule that the highest priority ready task is always running is never violated and guaranteed to be always true.
An application can leverage the ability to set the affinity of a task to come up with a scheme that allows certain tasks to always run on a given core and hence benefit from a warm cache. The ability to set the priority of a task can also be leveraged to minimize interference from other tasks. Here's an example scheme that demonstrates this idea:
Install the latest SYS/BIOS product (SYS/BIOS Download pages) and the corresponding XDC Tools (XDCTools Download pages).
SMP/BIOS needs to be configured before applications can be compiled and linked with it. Configuration is primarily used for specifying which modules to include and setting default values for the many tunable parameters in SMP/BIOS. The input to the configuration tool, configuro, is a text file with a .cfg extension written in JavaScript (ECMAScript). This file can be authored using a text editor or graphically generated using a plugin in CCS/Eclipse. The output of configuration is a set of options for the C compiler to be used when compiling user applications, and a set of linker options for use when linking applications.
In order to build a SYS/BIOS application to run in SMP mode:
var BIOS = xdc.useModule('ti.sysbios.BIOS'); BIOS.smpEnabled = true;
ti.sysbios.smp.LoggerBuf (Replaces xdc.runtime.LoggerBuf) ti.sysbios.smp.SysMin (Replaces xdc.runtime.SysMin) ti.sysbios.smp.SysStd (Replaces xdc.runtime.SysStd)
Cortex-A15 specific configuration settings:
var Core = xdc.useModule('ti.sysbios.family.arm.a15.smp.Core'); Core.useSkernelCmd = false; /* Set to false if running in CCS and using gel files to wake-up secondary cores */
var Core = xdc.useModule('ti.sysbios.family.arm.a15.smp.Core'); Core.numCores = 2;
var Timestamp = xdc.useModule('xdc.runtime.Timestamp'); Timestamp.SupportProxy = xdc.useModule('ti.sysbios.timers.timer64.TimestampProvider');
Example CCS Projects
THE APPLICATION CANNOT DEPEND ON TASK PRIORITIES TO GUARANTEE CRITICAL SECTION PROTECTION!
THE APPLICATION CANNOT DEPEND ON SWI/TASK PRIORITIES TO GUARANTEE CRITICAL SECTION PROTECTION!
Task.defaultAffinity = 0;
Task_Params tskParams; Task_Params_init(&tskParams); tskParams.affinity = 0; /* Force to run on Core 0 */ myTask = Task_create(myTaskFunc, &tskParams, NULL);
The SMP slides have a section dedicated to describing how to setup CCS for SMP debug.
The Hwi stack size is derived from "Program.stack" on all cores. On Cortex-M3/M4 specifically, Core 1's Hwi stack size can also be controlled via the Core module's core1HwiStackSize field. Such a special field is not available on other devices supporting SMP mode and it is recommended to modify the Hwi stack size using "Program.stack" on all devices.
An application that needs to measure CPU Load in SMP mode can use the SYS/BIOS Load module (ti.sysbios.utils.Load) to do so. The Load module can be used the same way it is used in non-SMP mode with the exception that the Global CPU load reported by the Load module is not correct when running in SMP mode. In order to measure the per core CPU Load, the below logic can be used:
#include <ti/sysbios/knl/Task.h> #include <ti/sysbios/utils/Load.h> #include <xdc/runtime/System.h> func() { UInt load; Load_stat stat; Task_Handle idlTskHandle; idleTskHandle = Task_getIdleTaskHandle(coreId); Load_getTaskLoad(idlTskHandle, &stat); load = Load_calculateLoad(&stat); System_printf("Load = %d\n", (100-load)); }
In addition to the problem with the Global CPU load in SMP mode, there are 2 other issues (tracked through bug Id SDOCM00115771) that will be fixed in future releases of SYS/BIOS. These issues can cause the Load module to report an incorrect idle task load. These can be worked around as follows:
var Idle = xdc.useModule('ti.sysbios.knl.Idle'); Idle.addCoreFunc ('&idle_func', 1);
Void idle_func() { Load_updateCurrentThreadTime(); ... }
This is due to a known issue (tracked through bug Id SDSCM00051817). In order to work around this issue, “Halt the target before any debugger accesses” option under "Auto Run and Launch Options" should be selected for each core in the Sync Group. This issue will be fixed in CCS v6.2 release.
One of 2 reasons maybe causing the A15 cores to hang at boot time. The first possibility (more likely when running in CCS) is that there is no sKernel but the kernel needs to use sKernel commands to wake-up the secondary cores. Please see "Configuring SMP/BIOS" section above for more info on how to disable sKernel commands and resolve this. A second possibility is that the SMP bit in ACTLR is not set. This can be set through a gel script in CCS. If using u-boot & sKernel, this will be done by the bootloader.
This may happen if one of the cores is running in secure mode. In order to resolve this problem, switch all cores to non-secure mode before loading and running the application. In CCS environment, a gel function can be used to switch the cores to secure mode.
Gel function to change Cortex-A15 security mode to non-secure:
hotmenu enterNonSecureMode() { int status; Disable_MMU(); Disable_Caches(); GEL_TextOut("Enabling non-secure access to cp10 and cp11\n"); status = REG_CTXA15_CP15_C1_NSACR; status |= 0x00000C00; status &= 0x7FFFFFFF; REG_CTXA15_CP15_C1_NSACR = status; GEL_TextOut("Enabled non-secure access to cp10 and cp11\n"); GEL_TextOut("Enabling SMP bit in ACTLR\n"); status = REG_CTXA15_CP15_C1_ACTLR; status |= 0x40; REG_CTXA15_CP15_C1_ACTLR = status; GEL_TextOut("Enabled SMP bit in ACTLR\n"); GEL_TextOut("Entering NonSecure Mode\n"); status = REG_CTXA15_CP15_C1_SCR; status |= 0x1; REG_CTXA15_CP15_C1_SCR = status; GEL_TextOut("Entered NonSecure Mode\n"); // Ensure MMU and Caches are disabled after changing security mode Disable_MMU(); Disable_Caches(); } define MMU_ON 0x1 define MMU_OFF ~MMU_ON hotmenu Disable_MMU() { int status; GEL_TextOut("Disabling MMU\n"); status = REG_CTXA15_CP15_C1_SCTLR; status &= MMU_OFF; REG_CTXA15_CP15_C1_SCTLR = status; } define ICACHE_ON 0x1000 define ICACHE_OFF ~ICACHE_ON define DCACHE_ON 0x4 define DCACHE_OFF ~DCACHE_ON hotmenu Disable_Caches() { int status; GEL_TextOut("Disabling Caches\n"); status = REG_CTXA15_CP15_C1_SCTLR; status &= DCACHE_OFF; status &= ICACHE_OFF; REG_CTXA15_CP15_C1_SCTLR = status; // invalidate entire instruction cache GEL_TextOut("Invalidate Instruction Caches\n"); REG_CTXA15_CP15_C7_ICIALLU = 1; return; }