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);
114void INOSInvalidateCaches(
void* aAddress, uint32 aNumber);
119void INOSFlushDCache(
void* aAddress, uint32 aNumber);
123void INOSInvalidateDCache(
void* aAddress, uint32 aNumber);
145 CTaskListLocker m_TaskListLock;
147 TINOSDoubleLinkedList<CINOSTask>* m_pTaskList;
152 explicit CSafeTaskList(TINOSDoubleLinkedList<CINOSTask>* apTaskList);
157 long GetItemsInContainer();
173 m_uMsr = INOSDisableInterrupts();
179 INOSEnableInterrupts(m_uMsr);
185 INOSEnableInterrupts(m_uMsr);
208 : m_pCoreLock(&aCoreLock)
210 m_uMsr = INOSCoreLock(*m_pCoreLock);
215 INOSCoreUnlock(*m_pCoreLock, m_uMsr);
220 INOSCoreUnlock(*m_pCoreLock, m_uMsr);
221 m_pCoreLock =
nullptr;
253 eCnsPriorityNumber = 32,
254 eCnsPriorityLowest = eCnsPriorityNumber-1,
256 eCnsStackSizeDefault = 0,
257 eCnsTimeSliceNone = 0xffffffff,
258 eCnsTimeSliceDefault = 100,
259 eCnsLogEntriesMin = 2048,
260 eCnsLogEntriesMax = 16*1024*1024,
261 eCnsLogEntriesSmall = 2048,
262 eCnsLogEntriesMedium = 65536,
263 eCnsLogEntriesLarge = 131072
270 eLogTypePreemption = 0,
273 eLogTypeResumeDispatch = 3,
274 eLogTypeRelinquish = 4,
275 eLogTypeChangePriority = 5,
276 eLogTypeTestpoint = 6,
277 eLogTypeTiminigIssue = 7,
298 static constexpr uint32 AsciiToUint32(
const char (&s)[5]) {
299 #ifdef INOS_BIG_ENDIAN
300 return (uint32(s[0]) << 24) | (uint32(s[1]) << 16) | (uint32(s[2]) << 8) | uint32(s[3]);
302 return (uint32(s[3]) << 24) | (uint32(s[2]) << 16) | (uint32(s[1]) << 8) | uint32(s[0]);
305 #if defined(INOS_TASK_LOGGER_EXTENDED)
306 static constexpr uint64 AsciiToUint64(
const char (&s)[9]) {
307 return *((uint64*) s);
316 eTskStatePureSuspended = 1,
323 eFlgCommandNone = 0x00000000,
324 eFlgCommandForeign = 0x00000001,
325 eFlgCommandShutdown = 0x00000002,
342 friend void Suspend(uint32 auTaskState, uint32 auFlags);
433 friend void Exit(uint32 auExitCode);
456 virtual void AddIdle(
void* apFunction,
void* apObject);
496 {
return m_iKernelState; };
505 friend void Preemption();
509 friend class CINOSHwTarget;
511 friend class CSafeTaskList;
512 friend void _suspend();
524 void ReadConfigSettings();
528 void Idle () INOS_COMPILE_NONOPTIMIZED;
540 static
void Create ();
544 static
void Startup ();
554 #if defined(INOS_TASK_LOGGER_EXTENDED)
562 uint64 DoLogging(uint8 aeLogType, uint8 aeSubType, uint64 auData) INOS_OCRAM;
569 inline uint64 DoLogging(uint8 aeLogType,
class CINOSTask* apTask) INOS_OCRAM
571 return DoLogging(aeLogType, 0, uintptr(apTask));
573 inline uint64 DoLogging(uint8 aeLogType, uint8 aeSubType,
class CINOSTask* apTask) INOS_OCRAM
575 return DoLogging(aeLogType, aeSubType, uintptr(apTask));
585 uint64 DoLogging(uint8 aeLogType, uint32 auData);
592 inline uint64 DoLogging(uint8 aeLogType,
class CINOSTask* apTask)
594 return DoLogging(aeLogType, inos_ptr_to_uint32(apTask));
602 inline CINOSTask* ActualLoggedTask() INOS_OCRAM
615 void AddTask(
CINOSTask* apTask, uint32 auParentId = 0);
620 class CINOSTask* GetHighestPriorityTask()
628 return m_pHead[inos_getlsb32(m_uReady)];
635 virtual uint32 CreateTask(
CINOSTask* apTask)
650 void AttachTask(
CINOSTask* apTask, uint32 auParentId = 0);
659 virtual void DestroyTask(
CINOSTask* apTask)
665 virtual void SetTaskName(
CINOSTask* apTask)
675 void ShutdownChildren();
680 return apTask == m_pTskMain;
685 return &m_sSyncStartup;
688 void SetStartupCallResult(
class CMcResult* apResult);
690 class CMcResult* GetStartupCallResult();
695 CINOSTask* FindTask(
const char* aTaskname);
699 void DisallowTaskListChanges();
702 void AllowTaskListChanges();
704 CSafeTaskList GetTaskList()
705 {
return CSafeTaskList(m_pTaskList); };
707 {
return mUpdateId; };
712 void DoTimingMeasurement();
714 virtual void PrepareTaskStack(
CINOSTask* apTask)=0;
716 virtual uint32 SingleStep(
CINOSTask* apTask)=0;
717 virtual uint32 RangeStep(
CINOSTask* apTask, uintptr auFrom, uintptr auTo)=0;
718 virtual uint32 Halt(
CINOSTask* apTask)=0;
721 virtual uint32 GetPC(
CINOSTask* apTask, uintnbr* aValue)=0;
722 virtual uint32 PutPC(
CINOSTask* apTask, uintnbr aValue)=0;
723 virtual uint32 GetLR(
CINOSTask* apTask, uintnbr* aValue)=0;
724 virtual uint32 GetSPR(
CINOSTask* apTask, uint32 aNumber, uint32* aValue)=0;
725 virtual uint32 PutSPR(
CINOSTask* apTask, uint32 aNumber, uint32 aValue)=0;
726 virtual uint32 GetSPRs(
CINOSTask* apTask, uint32* aResult)=0;
727 virtual uint32 GetSPRsGdb(
CINOSTask* apTask, uint32* aResult)=0;
729 virtual uint32 GetGPR(
CINOSTask* apTask, uint32 aNumber, uint32* aValue)=0;
730 virtual uint32 PutGPR(
CINOSTask* apTask, uint32 aNumber, uint32 aValue)=0;
732 virtual uint32 GetGPRs(
CINOSTask* apTask, uint32* aResult,
bool abNative)=0;
734 virtual uint32 GetFPR(
CINOSTask* apTask, uint32 aNumber,
double* aValue)=0;
735 virtual uint32 PutFPR(
CINOSTask* apTask, uint32 aNumber,
double aValue)=0;
736 virtual uint32 GetFPRs(
CINOSTask* apTask,
double* aResult)=0;
738 virtual uint32 GetTaskData(
CINOSTask* apTask, uint32 aDataDef, uintnbr* aResult, uint32& aLength)=0;
739 virtual uint32 PutTaskData(
CINOSTask* apTask, uint32 aDataDef, uint32* aData, uint32 aLength)=0;
743 virtual const char* GetTargetDescription() = 0;
747 virtual uint32 GetGdbRegsSize(
CINOSTask* apTask, uint32& auSize) = 0;
751 virtual uint32 GetGdbRegs(
CINOSTask* apTask,
void* apData)=0;
755 virtual uint32 PutGdbReg(
CINOSTask* apTask,
const uint32 auRegister,
const void* apData, uint32 auDataLength)=0;
761 static void Finalyse();
765 void MaskInterrupts()
767 #if defined(INOS_ARCH_ARM)
768 m_uIrqMask = 0x000000c0;
770 m_uIrqMask = 0xffff7fff;
779 eStaBootingCore0 = 0,
780 eStaBootingCore1 = 1,
781 eStaBootingCore2 = 2,
782 eStaBootingCore3 = 3,
783 eStaBootingCore4 = 4,
784 eStaBootingCore5 = 5,
785 eStaBootingCore6 = 6,
786 eStaBootingCore7 = 7,
787 eStaBootingCore8 = 8,
788 eStaBootingCore9 = 9,
789 eStaBootingCore10 = 10,
790 eStaBootingCore11 = 11,
791 eStaBootingCore12 = 12,
792 eStaBootingCore13 = 13,
793 eStaBootingCore14 = 14,
794 eStaBootingCore15 = 15,
795 eStaSyncTimebase = 64,
799 static int32 m_iKernelState;
806 CINOSTask* m_pHead[eCnsPriorityNumber+1];
818 static uint8 m_uCoreShift;
820 static uint32 m_uCoreMask;
822 std::atomic<uint32> m_uTskIdCnt = {1};
830 static CINOSTask* GetTask(uint32 auTaskId);
834 static bool IsTaskValid(
CINOSTask* apTask);
839 CINCOObject* m_pRegister;
841 CINCOObject* m_pTask;
843 TINOSDoubleLinkedList<CINOSTask>* m_pTaskList;
852 uint32 m_uDisallowTaskListChangesCntr;
860 friend class CINOSTestpoint;
861 friend class CINCODataLogger;
862 friend class CINOSMcTargetKernelLogger;
863 friend class CINOSKernelLoggerTest;
866 uint32 LoggerCreate(uint32 auEntries);
868 uint32 LoggerDestroy();
870 uint32 LoggerStart(uint8 auType);
872 uint32 LoggerStart(uint8 auType, uint64 auTicks);
875 uint32 iLoggerStop();
877 uint32 LoggerCancel();
878 uint32 iLoggerCancel();
880 uint32 LoggerGetState();
882 void TriggerOccured(uint8 auType, uint8 auPercent);
883 void TriggerOccured(uint8 auType, uint8 auPercent, uint64 auTimeStamp);
884 void iTriggerOccured(uint8 auType, uint8 auPercent, uint64 auTimeStamp);
886 #if defined(INOS_TASK_LOGGER_EXTENDED)
887 struct SINOSKernelLoggerEntry
896 struct SINOSKernelLoggerEntry
909 #if defined(INOS_TASK_LOGGER_EXTENDED)
910 } m_eLogVersion = eLogExtended;
912 } m_eLogVersion = eLogStandard;
919 } m_eLogState = eLogStaIdle;
921 uint32 m_uLogEntries{};
925 uint64 m_uLogIndexWrt{};
927 uint64 m_uLogIndexStp{};
929 uint32 m_uLogIndexWrtMask{};
931 uint64 m_uLogTriggerTicks{};
933 SINOSKernelLoggerEntry* m_pLogBuffer{};
935 uint8 m_uLogTriggerPercent = 50;
937 uint8 m_uLogTriggerType{DF_INOS_LOG_TRIGGER_TYPE_UNKNOWN};
941 char m_cLogTriggerTask[64]{};
943 uintnbr m_uLogActualTask{};
946 uint64 m_uLogTicks{};
950 struct SINOSKernelCallback* m_pFirstIdle;
952 static struct SINOSKernelCallback* m_pFinalyseFst;
954 static struct SINOSKernelCallback* m_pFinalyseLst;
956 static struct SINOSKernelCallback* m_pFirstRunning;
968void Suspend(uint32 auTaskState=1, uint32 auFlags=0);
970void Resume(
class CINOSTask* apTask, uint32 auFlags=0);
971void Resume(
tTaskId aidTask, uint32 auFlags=0);
972void Ready(
class CINOSTask* apTask, uint32 auFlags=0);
973void Ready(
tTaskId aidTask, uint32 auFlags=0);
975extern void Suspend(uint32 auTaskState, uint32 auFlags);
977extern void Goodbye();
978extern void Resume(
class CINOSTask* apTask, uint32 auFlags);
979extern void Resume(
tTaskId aidTask, uint32 auFlags);
980extern void Ready(
class CINOSTask* apTask, uint32 auFlags);
981extern void Ready(
tTaskId aidTask, uint32 auFlags);
982extern uint32 SwitchCore(uint32 auCoreId);
983extern void Schedule();
984extern void Schedule(uint32 auCoreId);
985extern void Exit(uint32 auExitCode);
986extern void Relinquish();
987extern void Preemption();
988extern void ChangePriority(uint32 auPriority);
989#if defined(INOS_WINDOWS)
990extern long _Sleep(
long aTime);
991#define Sleep(aTime) _Sleep(aTime)
993extern long Sleep(
long aTime);
1003#if defined(INOS_CPU_CORTEXA9)
1005 #include <inoskernel_cortexa9.h>
1006#elif defined(INOS_CPU_CORTEXA72)
1008 #include <inoskernel_cortexa72.h>
1009#elif defined(INOS_CPU_P50XX)
1011 #include <inoskernel_p50xx.h>
1012#elif defined(INOS_CPU_P2020)
1014 #include <inoskernel_p2020.h>
1015#elif defined(INOS_CPU_PPC750)
1017 #include <inoskernel_ppc750.h>
1018#elif defined(INOS_DESKTOP)
1020 #include <inoskernel_desktop.h>
1030 extern uint8 __cpu_cores_real;
1031 return __cpu_cores_real;
1034 extern uint8 __cpu_cores_virtual;
1035 return __cpu_cores_virtual;
1040 return GetCoreId() == 0;
1045 extern uint32 __cpu_coreid_primary;
1046 return __cpu_coreid_primary;
1051 extern uint32 __cpu_coreid_primary;
1052 return GetCoreId(
true) == __cpu_coreid_primary;
1070 ePointInternal0 = 0,
1071 ePointInternal1 = 1,
1072 ePointInternal2 = 2,
1073 ePointInternal3 = 3,
1074 ePointInternal4 = 4,
1075 ePointInternal5 = 5,
1076 ePointInternal6 = 6,
1077 ePointInternal7 = 7,
1078 ePointInternal8 = 8,
1079 ePointDataLogger = 9,
1102 #if defined(INOS_DESKTOP)
1106 while (__sync_lock_test_and_set(m_CoreLock.GetAddr(), 1));
1112 #if defined(INOS_DESKTOP)
1116 __sync_lock_release(m_CoreLock.GetAddr());
1127 for (uint32 i=0; i<ePointLast+1; i++) {
1129 __sync_fetch_and_or(m_CoreDone[i].GetAddr(), m_CoreMask.GetValue());
1135 __sync_fetch_and_or(m_CoreMask.GetAddr(), (1<<GetCoreId()));
1140 __sync_fetch_and_and(m_CoreMask.GetAddr(), ~(1<<GetCoreId()));
1150 return __atomic_load_n(m_CoreMask.GetAddr(), __ATOMIC_SEQ_CST);
1161 uint32 uCoreDone = __sync_fetch_and_and(m_CoreDone[auPointIndex].GetAddr(), ~(1<<GetCoreId()));
1163 bool bIsFirst = (uCoreDone == m_CoreMask.GetValue());
1180 uint32 uCoreDone = __sync_fetch_and_and(m_CoreDone[auPointIndex].GetAddr(), ~(1<<GetCoreId()));
1182 return (uCoreDone == (uint32) (1<<GetCoreId()));
1187 INOS_INLINE bool IsCore(uint32 auPointIndex, uint32 auCoreId)
1190 if (GetCoreId() == auCoreId) {
1196 volatile uint32* p = m_CoreDone[auPointIndex].GetAddr();
1198 while (*p & (1<<auCoreId));
1201 __sync_fetch_and_and(m_CoreDone[auPointIndex].GetAddr(), ~(1<<GetCoreId()));
1211 __sync_fetch_and_and(m_CoreDone[auPointIndex].GetAddr(), ~(1<<GetCoreId()));
Definition cinosbus.h:563
Definition inoskernel.h:239
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:495
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:182
#define INOS_INLINE
Definition inosdefine.h:60
#define DF_INOS_MAX_CORES
Definition inosdefine.h:164
Definition inostype.h:258
Definition inostype.h:192