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];
808 static uint8 m_uCoreShift;
810 static uint32 m_uCoreMask;
812 std::atomic<uint32> m_uTskIdCnt = {1};
820 static CINOSTask* GetTask(uint32 auTaskId);
824 static bool IsTaskValid(
CINOSTask* apTask);
829 CINCOObject* m_pRegister;
831 CINCOObject* m_pTask;
833 TINOSDoubleLinkedList<CINOSTask>* m_pTaskList;
842 uint32 m_uDisallowTaskListChangesCntr;
850 friend class CINOSTestpoint;
851 friend class CINCODataLogger;
852 friend class CINOSMcTargetKernelLogger;
853 friend class CINOSKernelLoggerTest;
856 uint32 LoggerCreate(uint32 auEntries);
858 uint32 LoggerDestroy();
860 uint32 LoggerStart(uint8 auType);
862 uint32 LoggerStart(uint8 auType, uint64 auTicks);
865 uint32 iLoggerStop();
867 uint32 LoggerCancel();
868 uint32 iLoggerCancel();
870 uint32 LoggerGetState();
872 void TriggerOccured(uint8 auType, uint8 auPercent);
873 void TriggerOccured(uint8 auType, uint8 auPercent, uint64 auTimeStamp);
874 void iTriggerOccured(uint8 auType, uint8 auPercent, uint64 auTimeStamp);
876 #if defined(INOS_TASK_LOGGER_EXTENDED)
877 struct SINOSKernelLoggerEntry
886 struct SINOSKernelLoggerEntry
899 #if defined(INOS_TASK_LOGGER_EXTENDED)
900 } m_eLogVersion = eLogExtended;
902 } m_eLogVersion = eLogStandard;
909 } m_eLogState = eLogStaIdle;
911 uint32 m_uLogEntries{};
915 uint64 m_uLogIndexWrt{};
917 uint64 m_uLogIndexStp{};
919 uint32 m_uLogIndexWrtMask{};
921 uint64 m_uLogTriggerTicks{};
923 SINOSKernelLoggerEntry* m_pLogBuffer{};
925 uint8 m_uLogTriggerPercent = 50;
927 uint8 m_uLogTriggerType{DF_INOS_LOG_TRIGGER_TYPE_UNKNOWN};
931 char m_cLogTriggerTask[64]{};
933 uintnbr m_uLogActualTask{};
936 uint64 m_uLogTicks{};
940 struct SINOSKernelCallback* m_pFirstIdle;
942 static struct SINOSKernelCallback* m_pFinalyseFst;
944 static struct SINOSKernelCallback* m_pFinalyseLst;
946 static struct SINOSKernelCallback* m_pFirstRunning;
958void Suspend(uint32 auTaskState=1, uint32 auFlags=0);
960void Resume(
class CINOSTask* apTask, uint32 auFlags=0);
961void Resume(
tTaskId aidTask, uint32 auFlags=0);
962void Ready(
class CINOSTask* apTask, uint32 auFlags=0);
963void Ready(
tTaskId aidTask, uint32 auFlags=0);
965extern void Suspend(uint32 auTaskState, uint32 auFlags);
967extern void Goodbye();
968extern void Resume(
class CINOSTask* apTask, uint32 auFlags);
969extern void Resume(
tTaskId aidTask, uint32 auFlags);
970extern void Ready(
class CINOSTask* apTask, uint32 auFlags);
971extern void Ready(
tTaskId aidTask, uint32 auFlags);
972extern uint32 SwitchCore(uint32 auCoreId);
973extern void Schedule();
974extern void Schedule(uint32 auCoreId);
975extern void Exit(uint32 auExitCode);
976extern void Relinquish();
977extern void Preemption();
978extern void ChangePriority(uint32 auPriority);
979#if defined(INOS_WINDOWS)
980extern long _Sleep(
long aTime);
981#define Sleep(aTime) _Sleep(aTime)
983extern long Sleep(
long aTime);
993#if defined(INOS_CPU_CORTEXA9)
995 #include <inoskernel_cortexa9.h>
996#elif defined(INOS_CPU_ARMV8)
998 #include <inoskernel_armv8.h>
999#elif defined(INOS_CPU_P50XX)
1001 #include <inoskernel_p50xx.h>
1002#elif defined(INOS_CPU_P2020)
1004 #include <inoskernel_p2020.h>
1005#elif defined(INOS_CPU_PPC750)
1007 #include <inoskernel_ppc750.h>
1008#elif defined(INOS_DESKTOP)
1010 #include <inoskernel_desktop.h>
1020 extern uint8 __cpu_cores_real;
1021 return __cpu_cores_real;
1024 extern uint8 __cpu_cores_virtual;
1025 return __cpu_cores_virtual;
1030 return GetCoreId() == 0;
1035 extern uint32 __cpu_coreid_primary;
1036 return __cpu_coreid_primary;
1041 extern uint32 __cpu_coreid_primary;
1042 return GetCoreId(
true) == __cpu_coreid_primary;
1060 ePointInternal0 = 0,
1061 ePointInternal1 = 1,
1062 ePointInternal2 = 2,
1063 ePointInternal3 = 3,
1064 ePointInternal4 = 4,
1065 ePointInternal5 = 5,
1066 ePointInternal6 = 6,
1067 ePointInternal7 = 7,
1068 ePointInternal8 = 8,
1069 ePointDataLogger = 9,
1092 #if defined(INOS_DESKTOP)
1096 while (__sync_lock_test_and_set(m_CoreLock.GetAddr(), 1));
1102 #if defined(INOS_DESKTOP)
1106 __sync_lock_release(m_CoreLock.GetAddr());
1117 for (uint32 i=0; i<ePointLast+1; i++) {
1119 __sync_fetch_and_or(m_CoreDone[i].GetAddr(), m_CoreMask.GetValue());
1125 __sync_fetch_and_or(m_CoreMask.GetAddr(), (1<<GetCoreId()));
1130 __sync_fetch_and_and(m_CoreMask.GetAddr(), ~(1<<GetCoreId()));
1140 return __atomic_load_n(m_CoreMask.GetAddr(), __ATOMIC_SEQ_CST);
1151 uint32 uCoreDone = __sync_fetch_and_and(m_CoreDone[auPointIndex].GetAddr(), ~(1<<GetCoreId()));
1153 bool bIsFirst = (uCoreDone == m_CoreMask.GetValue());
1170 uint32 uCoreDone = __sync_fetch_and_and(m_CoreDone[auPointIndex].GetAddr(), ~(1<<GetCoreId()));
1172 return (uCoreDone == (uint32) (1<<GetCoreId()));
1177 INOS_INLINE bool IsCore(uint32 auPointIndex, uint32 auCoreId)
1180 if (GetCoreId() == auCoreId) {
1186 volatile uint32* p = m_CoreDone[auPointIndex].GetAddr();
1188 while (*p & (1<<auCoreId));
1191 __sync_fetch_and_and(m_CoreDone[auPointIndex].GetAddr(), ~(1<<GetCoreId()));
1201 __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