28#if !defined( INC_INOSKERNEL_H )
29#define INC_INOSKERNEL_H
53#ifdef INOS_TIMINIG_CHECKS
54void DebugTimingFailureDetected(
CINOSTask* apTask, uint32 auTaskLoggerPattern,
55 const char* apFailureText, uint32 auDiff, uint32 auMaxAllowed);
57void PriorityInversionDetected(
const char* apMsg,
CINOSTask* apTask,
const char* apSyncObjName, uint32 auType);
63#ifdef INOS_TIMINIG_CHECKS_DISABLEINTERRUPTS
64extern uint32 g_uMaxIrqDisabledTicks;
67void INOSEnableInterrupts(uint32 aMask);
68uint32 INOSDisableInterrupts();
69uint32 INOSDisableAllInterrupts();
75inline uint32 INOSCoreLock()
77 return INOSDisableInterrupts();
81 return INOSDisableInterrupts();
86void INOSCoreUnlock(uint32 auMsr);
89inline void INOSCoreUnlock(uint32 auMsr)
91 INOSEnableInterrupts(auMsr);
95 INOSEnableInterrupts(auMsr);
98uint32 INOSSpinLock(uint32* apLock);
99void INOSSpinUnlock(uint32* apLock);
104 #define INOSOptimizationBarrier() \
105 asm volatile ("" ::: "memory");
107 #define INOSOptimizationBarrier()
110void INOSMemoryBarrier();
112uintnbr INOSReqSem(
void* aAddress, uintnbr aNumber);
113uintnbr INOSRelSem(
void* aAddress);
135 CTaskListLocker m_TaskListLock;
137 TINOSDoubleLinkedList<CINOSTask>* m_pTaskList;
142 explicit CSafeTaskList(TINOSDoubleLinkedList<CINOSTask>* apTaskList);
147 long GetItemsInContainer();
163 m_uMsr = INOSDisableInterrupts();
169 INOSEnableInterrupts(m_uMsr);
175 INOSEnableInterrupts(m_uMsr);
198 : m_pCoreLock(&aCoreLock)
200 m_uMsr = INOSCoreLock(*m_pCoreLock);
205 INOSCoreUnlock(*m_pCoreLock, m_uMsr);
210 INOSCoreUnlock(*m_pCoreLock, m_uMsr);
211 m_pCoreLock =
nullptr;
243 eCnsPriorityNumber = 32,
244 eCnsPriorityLowest = eCnsPriorityNumber-1,
246 eCnsStackSizeDefault = 0,
247 eCnsTimeSliceNone = 0xffffffff,
248 eCnsTimeSliceDefault = 100,
249 eCnsLogEntriesMin = 2048,
250 eCnsLogEntriesMax = 16*1024*1024,
251 eCnsLogEntriesSmall = 2048,
252 eCnsLogEntriesMedium = 65536,
253 eCnsLogEntriesLarge = 131072
260 eLogTypePreemption = 0,
263 eLogTypeResumeDispatch = 3,
264 eLogTypeRelinquish = 4,
265 eLogTypeChangePriority = 5,
266 eLogTypeTestpoint = 6,
267 eLogTypeTiminigIssue = 7,
288 static constexpr uint32 AsciiToUint32(
const char (&s)[5]) {
289 #ifdef INOS_BIG_ENDIAN
290 return (uint32(s[0]) << 24) | (uint32(s[1]) << 16) | (uint32(s[2]) << 8) | uint32(s[3]);
292 return (uint32(s[3]) << 24) | (uint32(s[2]) << 16) | (uint32(s[1]) << 8) | uint32(s[0]);
295 #if defined(INOS_TASK_LOGGER_EXTENDED)
296 static constexpr uint64 AsciiToUint64(
const char (&s)[9]) {
297 return *((uint64*) s);
306 eTskStatePureSuspended = 1,
313 eFlgCommandNone = 0x00000000,
314 eFlgCommandForeign = 0x00000001,
315 eFlgCommandShutdown = 0x00000002,
332 friend void Suspend(uint32 auTaskState, uint32 auFlags);
423 friend void Exit(uint32 auExitCode);
446 virtual void AddIdle(
void* apFunction,
void* apObject);
486 {
return m_iKernelState; };
495 friend void Preemption();
499 friend class CINOSHwTarget;
501 friend class CSafeTaskList;
502 friend void _suspend();
514 void ReadConfigSettings();
518 void Idle () INOS_COMPILE_NONOPTIMIZED;
530 static
void Create ();
534 static
void Startup ();
544 #if defined(INOS_TASK_LOGGER_EXTENDED)
552 uint64 DoLogging(uint8 aeLogType, uint8 aeSubType, uint64 auData) INOS_OCRAM;
559 inline uint64 DoLogging(uint8 aeLogType,
class CINOSTask* apTask) INOS_OCRAM
561 return DoLogging(aeLogType, 0, uintptr(apTask));
563 inline uint64 DoLogging(uint8 aeLogType, uint8 aeSubType,
class CINOSTask* apTask) INOS_OCRAM
565 return DoLogging(aeLogType, aeSubType, uintptr(apTask));
575 uint64 DoLogging(uint8 aeLogType, uint32 auData);
582 inline uint64 DoLogging(uint8 aeLogType,
class CINOSTask* apTask)
584 return DoLogging(aeLogType, inos_ptr_to_uint32(apTask));
592 inline CINOSTask* ActualLoggedTask() INOS_OCRAM
605 void AddTask(
CINOSTask* apTask, uint32 auParentId = 0);
610 class CINOSTask* GetHighestPriorityTask()
618 return m_pHead[inos_getlsb32(m_uReady)];
625 virtual uint32 CreateTask(
CINOSTask* apTask)
640 void AttachTask(
CINOSTask* apTask, uint32 auParentId = 0);
649 virtual void DestroyTask(
CINOSTask* apTask)
655 virtual void SetTaskName(
CINOSTask* apTask)
665 void ShutdownChildren();
670 return apTask == m_pTskMain;
675 return &m_sSyncStartup;
678 void SetStartupCallResult(
class CMcResult* apResult);
680 class CMcResult* GetStartupCallResult();
685 CINOSTask* FindTask(
const char* aTaskname);
689 void DisallowTaskListChanges();
692 void AllowTaskListChanges();
694 CSafeTaskList GetTaskList()
695 {
return CSafeTaskList(m_pTaskList); };
697 {
return mUpdateId; };
702 void DoTimingMeasurement();
704 virtual void PrepareTaskStack(
CINOSTask* apTask)=0;
706 virtual uint32 SingleStep(
CINOSTask* apTask)=0;
707 virtual uint32 RangeStep(
CINOSTask* apTask, uintptr auFrom, uintptr auTo)=0;
708 virtual uint32 Halt(
CINOSTask* apTask)=0;
711 virtual uint32 GetPC(
CINOSTask* apTask, uintnbr* aValue)=0;
712 virtual uint32 PutPC(
CINOSTask* apTask, uintnbr aValue)=0;
713 virtual uint32 GetLR(
CINOSTask* apTask, uintnbr* aValue)=0;
714 virtual uint32 GetSPR(
CINOSTask* apTask, uint32 aNumber, uint32* aValue)=0;
715 virtual uint32 PutSPR(
CINOSTask* apTask, uint32 aNumber, uint32 aValue)=0;
716 virtual uint32 GetSPRs(
CINOSTask* apTask, uint32* aResult)=0;
717 virtual uint32 GetSPRsGdb(
CINOSTask* apTask, uint32* aResult)=0;
719 virtual uint32 GetGPR(
CINOSTask* apTask, uint32 aNumber, uint32* aValue)=0;
720 virtual uint32 PutGPR(
CINOSTask* apTask, uint32 aNumber, uint32 aValue)=0;
722 virtual uint32 GetGPRs(
CINOSTask* apTask, uint32* aResult,
bool abNative)=0;
724 virtual uint32 GetFPR(
CINOSTask* apTask, uint32 aNumber,
double* aValue)=0;
725 virtual uint32 PutFPR(
CINOSTask* apTask, uint32 aNumber,
double aValue)=0;
726 virtual uint32 GetFPRs(
CINOSTask* apTask,
double* aResult)=0;
728 virtual uint32 GetTaskData(
CINOSTask* apTask, uint32 aDataDef, uintnbr* aResult, uint32& aLength)=0;
729 virtual uint32 PutTaskData(
CINOSTask* apTask, uint32 aDataDef, uint32* aData, uint32 aLength)=0;
733 virtual const char* GetTargetDescription() = 0;
737 virtual uint32 GetGdbRegsSize(
CINOSTask* apTask, uint32& auSize) = 0;
741 virtual uint32 GetGdbRegs(
CINOSTask* apTask,
void* apData)=0;
745 virtual uint32 PutGdbReg(
CINOSTask* apTask,
const uint32 auRegister,
const void* apData, uint32 auDataLength)=0;
751 static void Finalyse();
755 void MaskInterrupts()
757 #if defined(INOS_ARCH_ARM)
758 m_uIrqMask = 0x000000c0;
760 m_uIrqMask = 0xffff7fff;
769 eStaBootingCore0 = 0,
770 eStaBootingCore1 = 1,
771 eStaBootingCore2 = 2,
772 eStaBootingCore3 = 3,
773 eStaBootingCore4 = 4,
774 eStaBootingCore5 = 5,
775 eStaBootingCore6 = 6,
776 eStaBootingCore7 = 7,
777 eStaBootingCore8 = 8,
778 eStaBootingCore9 = 9,
779 eStaBootingCore10 = 10,
780 eStaBootingCore11 = 11,
781 eStaBootingCore12 = 12,
782 eStaBootingCore13 = 13,
783 eStaBootingCore14 = 14,
784 eStaBootingCore15 = 15,
785 eStaSyncTimebase = 64,
789 static int32 m_iKernelState;
796 CINOSTask* m_pHead[eCnsPriorityNumber+1];
805 uint64 m_uIdleCount = 0;
810 static uint8 m_uCoreShift;
812 static uint32 m_uCoreMask;
814 std::atomic<uint32> m_uTskIdCnt = {1};
822 static CINOSTask* GetTask(uint32 auTaskId);
826 static bool IsTaskValid(
CINOSTask* apTask);
831 CINCOObject* m_pRegister;
833 CINCOObject* m_pTask;
835 TINOSDoubleLinkedList<CINOSTask>* m_pTaskList;
844 uint32 m_uDisallowTaskListChangesCntr;
852 friend class CINOSTestpoint;
853 friend class CINCODataLogger;
854 friend class CINOSMcTargetKernelLogger;
855 friend class CINOSKernelLoggerTest;
858 uint32 LoggerCreate(uint32 auEntries);
860 uint32 LoggerDestroy();
862 uint32 LoggerStart(uint8 auType);
864 uint32 LoggerStart(uint8 auType, uint64 auTicks);
867 uint32 iLoggerStop();
869 uint32 LoggerCancel();
870 uint32 iLoggerCancel();
872 uint32 LoggerGetState();
874 void TriggerOccured(uint8 auType, uint8 auPercent);
875 void TriggerOccured(uint8 auType, uint8 auPercent, uint64 auTimeStamp);
876 void iTriggerOccured(uint8 auType, uint8 auPercent, uint64 auTimeStamp);
878 #if defined(INOS_TASK_LOGGER_EXTENDED)
879 struct SINOSKernelLoggerEntry
888 struct SINOSKernelLoggerEntry
901 #if defined(INOS_TASK_LOGGER_EXTENDED)
902 } m_eLogVersion = eLogExtended;
904 } m_eLogVersion = eLogStandard;
911 } m_eLogState = eLogStaIdle;
913 uint32 m_uLogEntries{};
917 uint64 m_uLogIndexWrt{};
919 uint64 m_uLogIndexStp{};
921 uint32 m_uLogIndexWrtMask{};
923 uint64 m_uLogTriggerTicks{};
925 SINOSKernelLoggerEntry* m_pLogBuffer{};
927 uint8 m_uLogTriggerPercent = 50;
929 uint8 m_uLogTriggerType{DF_INOS_LOG_TRIGGER_TYPE_UNKNOWN};
933 char m_cLogTriggerTask[64]{};
935 uintnbr m_uLogActualTask{};
938 uint64 m_uLogTicks{};
942 struct SINOSKernelCallback* m_pFirstIdle;
944 static struct SINOSKernelCallback* m_pFinalyseFst;
946 static struct SINOSKernelCallback* m_pFinalyseLst;
948 static struct SINOSKernelCallback* m_pFirstRunning;
960void Suspend(uint32 auTaskState=1, uint32 auFlags=0);
962void Resume(
class CINOSTask* apTask, uint32 auFlags=0);
963void Resume(
tTaskId aidTask, uint32 auFlags=0);
964void Ready(
class CINOSTask* apTask, uint32 auFlags=0);
965void Ready(
tTaskId aidTask, uint32 auFlags=0);
967extern void Suspend(uint32 auTaskState, uint32 auFlags);
969extern void Goodbye();
970extern void Resume(
class CINOSTask* apTask, uint32 auFlags);
971extern void Resume(
tTaskId aidTask, uint32 auFlags);
972extern void Ready(
class CINOSTask* apTask, uint32 auFlags);
973extern void Ready(
tTaskId aidTask, uint32 auFlags);
974extern uint32 SwitchCore(uint32 auCoreId);
975extern void Schedule();
976extern void Schedule(uint32 auCoreId);
977extern void Exit(uint32 auExitCode);
978extern void Relinquish();
979extern void Preemption();
980extern void ChangePriority(uint32 auPriority);
981#if defined(INOS_WINDOWS)
982extern long _Sleep(
long aTime);
983#define Sleep(aTime) _Sleep(aTime)
985extern long Sleep(
long aTime);
995#if defined(INOS_CPU_CORTEXA9)
997 #include <inoskernel_cortexa9.h>
998#elif defined(INOS_CPU_ARMV8)
1000 #include <inoskernel_armv8.h>
1001#elif defined(INOS_CPU_P50XX)
1003 #include <inoskernel_p50xx.h>
1004#elif defined(INOS_CPU_P2020)
1006 #include <inoskernel_p2020.h>
1007#elif defined(INOS_CPU_PPC750)
1009 #include <inoskernel_ppc750.h>
1010#elif defined(INOS_DESKTOP)
1012 #include <inoskernel_desktop.h>
1022 extern uint8 __cpu_cores_real;
1023 return __cpu_cores_real;
1026 extern uint8 __cpu_cores_virtual;
1027 return __cpu_cores_virtual;
1032 return GetCoreId() == 0;
1037 extern uint32 __cpu_coreid_primary;
1038 return __cpu_coreid_primary;
1043 extern uint32 __cpu_coreid_primary;
1044 return GetCoreId(
true) == __cpu_coreid_primary;
1062 ePointInternal0 = 0,
1063 ePointInternal1 = 1,
1064 ePointInternal2 = 2,
1065 ePointInternal3 = 3,
1066 ePointInternal4 = 4,
1067 ePointInternal5 = 5,
1068 ePointInternal6 = 6,
1069 ePointInternal7 = 7,
1070 ePointInternal8 = 8,
1071 ePointDataLogger = 9,
1094 #if defined(INOS_DESKTOP)
1098 while (__sync_lock_test_and_set(m_CoreLock.GetAddr(), 1));
1104 #if defined(INOS_DESKTOP)
1108 __sync_lock_release(m_CoreLock.GetAddr());
1119 for (uint32 i=0; i<ePointLast+1; i++) {
1121 __sync_fetch_and_or(m_CoreDone[i].GetAddr(), m_CoreMask.GetValue());
1127 __sync_fetch_and_or(m_CoreMask.GetAddr(), (1<<GetCoreId()));
1132 __sync_fetch_and_and(m_CoreMask.GetAddr(), ~(1<<GetCoreId()));
1142 return __atomic_load_n(m_CoreMask.GetAddr(), __ATOMIC_SEQ_CST);
1153 uint32 uCoreDone = __sync_fetch_and_and(m_CoreDone[auPointIndex].GetAddr(), ~(1<<GetCoreId()));
1155 bool bIsFirst = (uCoreDone == m_CoreMask.GetValue());
1172 uint32 uCoreDone = __sync_fetch_and_and(m_CoreDone[auPointIndex].GetAddr(), ~(1<<GetCoreId()));
1174 return (uCoreDone == (uint32) (1<<GetCoreId()));
1179 INOS_INLINE bool IsCore(uint32 auPointIndex, uint32 auCoreId)
1182 if (GetCoreId() == auCoreId) {
1188 volatile uint32* p = m_CoreDone[auPointIndex].GetAddr();
1190 while (*p & (1<<auCoreId));
1193 __sync_fetch_and_and(m_CoreDone[auPointIndex].GetAddr(), ~(1<<GetCoreId()));
1203 __sync_fetch_and_and(m_CoreDone[auPointIndex].GetAddr(), ~(1<<GetCoreId()));
Definition cinosbus.h:563
Definition inoskernel.h:229
friend void Ready(tTaskId aidTask, uint32 auFlags)
Put given task into ready list but do not schedule. This method is normally used in conjunction with ...
friend void Schedule(uint32 auCoreId)
Do an explicite schedule or given core. This method is normally used in in conjunction with Ready In ...
friend void SuspendEx(uint32 auTaskState, SINOSCoreLock *apLock, CINOSTask *apTask)
Suspend current task from execution and release the given lock. The lock will be released completely,...
friend void ChangePriority(uint32 auPriority)
Change priority of current task and do a reschedule if necessary. For more info see section Priority.
friend void Exit(uint32 auExitCode)
Terminate actual task.
friend void Ready(class CINOSTask *apTask, uint32 auFlags)
Put given task into ready list but do not schedule. This method is normally used in conjunction with ...
friend void Resume(tTaskId aidTask, uint32 auFlags)
Resume given task and put it into ready list.
static int32 GetKernelState()
Get kernel state. Valid values are.
Definition inoskernel.h:485
friend void Relinquish()
Give other tasks with the same priority a chance to run. For more info see section Relinquish.
friend void Resume(class CINOSTask *apTask, uint32 auFlags)
Resume given task and put it into ready list.
friend uint32 SwitchCore(uint32 auCoreId)
Switch current task to the given core.
virtual void AddIdle(void *apFunction, void *apObject)
Add idle handler. The given function is called whenever the CPU goes into idle state IMPORTANT things...
end of doxygen exclude friend void Suspend(uint32 auTaskState, uint32 auFlags)
Suspend current task from execution. Note that upon Resume, the interrupt state will be restored to t...
friend void Schedule()
Do an explicite schedule. This method is normally used in in conjunction with Ready In case of using ...
void AddBootedCallback(void *apFunction, void *apObject)
Add kernel booted callback, it is called after the kernel has entered the running state....
void AddFinalyse(void *apFunction, void *apObject)
Add kernel finalyse callback, it is called after the kernel has booted all cores and just before it g...
friend void Goodbye()
Suspend current task from execution without saving its context.
friend class CINOSTask * ActualTask()
Return pointer to actual running task.
Definition cinosmutex.h:36
Definition cinostask.h:52
#define DF_INOS_MAX_TASKS
Definition inosdefault.h:435
#define DF_INOS_TASK_PRIO_HIGHEST
Definition inosdefine.h:187
#define INOS_INLINE
Definition inosdefine.h:60
#define DF_INOS_MAX_CORES
Definition inosdefine.h:164
Definition inostype.h:258
Definition inostype.h:192