kernel/eka/include/nkernsmp/arm/nk_plat.h
changeset 9 96e5fb8b040d
child 43 c1f20ce4abcf
equal deleted inserted replaced
-1:000000000000 9:96e5fb8b040d
       
     1 // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of the License "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // e32\include\nkernsmp\arm\nk_plat.h
       
    15 // 
       
    16 // WARNING: This file contains some APIs which are internal and are subject
       
    17 //          to change without notice. Such APIs should therefore not be used
       
    18 //          outside the Kernel and Hardware Services package.
       
    19 //
       
    20 
       
    21 /**
       
    22  @file
       
    23  @internalComponent
       
    24 */
       
    25 
       
    26 #ifndef __NK_ARM_H__
       
    27 #define __NK_ARM_H__
       
    28 #include <nk_cpu.h>
       
    29 
       
    30 // These macros are intended for Symbian use only.
       
    31 // It may not be possible to build the kernel if any of these macros are undefined
       
    32 //#define __SCHEDULER_MACHINE_CODED__
       
    33 //#define __DFC_MACHINE_CODED__
       
    34 //#define __MSTIM_MACHINE_CODED__
       
    35 #define __PRI_LIST_MACHINE_CODED__
       
    36 #define __FAST_SEM_MACHINE_CODED__
       
    37 #define __FAST_MUTEX_MACHINE_CODED__
       
    38 #define __NTHREAD_WAITSTATE_MACHINE_CODED__
       
    39 
       
    40 // TSubScheduler member data
       
    41 #define	i_ScuAddr			iExtras[4]		// Address of SCU (also in TScheduler)
       
    42 #define	i_GicDistAddr		iExtras[5]		// Address of GIC Distributor (also in TScheduler)
       
    43 #define	i_GicCpuIfcAddr		iExtras[6]		// Address of GIC CPU Interface (also in TScheduler)
       
    44 #define	i_LocalTimerAddr	iExtras[7]		// Address of local timer registers (also in TScheduler)
       
    45 #define	i_IrqCount			iExtras[8]		// count of interrupts handled
       
    46 #define	i_IrqNestCount		iExtras[9]		// IRQ nest count for this CPU (starts at -1)
       
    47 #define	i_ExcInfo			iExtras[10]		// pointer to exception info for crash debugger
       
    48 #define	i_CrashState		iExtras[11]		// 0=normal, 1=this CPU faulted, 2=this CPU has received an NMI and halted
       
    49 #define	i_AbtStackTop		iExtras[12]		// Top of ABT stack for this CPU, also used to point to SFullArmRegSet
       
    50 #define	i_UndStackTop		iExtras[13]		// Top of UND stack for this CPU
       
    51 #define	i_FiqStackTop		iExtras[14]		// Top of FIQ stack for this CPU
       
    52 #define	i_IrqStackTop		iExtras[15]		// Top of IRQ stack for this CPU
       
    53 #define	i_TimerMultF		iExtras[16]		// Timer frequency / Max Timer frequency * 2^32
       
    54 #define	i_TimerMultI		iExtras[17]		// Max Timer frequency / Timer frequency * 2^24
       
    55 #define	i_CpuMult			iExtras[18]		// CPU frequency / Max CPU frequency * 2^32
       
    56 #define	i_LastTimerSet		iExtras[20]		// Value last written to local timer counter
       
    57 #define	i_TimestampError	iExtras[21]		// Current error in the timestamp
       
    58 #define	i_MaxCorrection		iExtras[22]		// Maximum correction to timestamp in one go
       
    59 #define	i_TimerGap			iExtras[23]		// Timestamp ticks taken to read and write local timer counter
       
    60 
       
    61 #define	i_Regs				iExtras[12]		// Alias for i_AbtStackTop
       
    62 
       
    63 // TScheduler member data
       
    64 #define	i_TimerMax			iExtras[16]		// Maximum per-CPU timer frequency (after prescaling)
       
    65 
       
    66 
       
    67 #define	RESCHED_IPI_VECTOR			0x00
       
    68 #define	GENERIC_IPI_VECTOR			0x01
       
    69 #define	TRANSFERRED_IRQ_VECTOR		0x02
       
    70 #define	CRASH_IPI_VECTOR			0x03	// would really like this to be a FIQ
       
    71 #define	BOOT_IPI_VECTOR				0x04	// used during boot to handshake with APs
       
    72 #define RESERVED_IPI_VECTOR_1		0x05	// reserved for future kernel functionality
       
    73 #define RESERVED_IPI_VECTOR_2		0x06	// reserved for future kernel functionality
       
    74 #define RESERVED_IPI_VECTOR_3		0x07	// reserved for future kernel functionality
       
    75 
       
    76 #if defined(__CPU_ARM11MP__)
       
    77 #define	TIMESLICE_VECTOR			0x1D	// vector 29 is per-CPU timer interrupt
       
    78 											// vector 30 is per-CPU Watchdog timer when not in watchdog mode
       
    79 											// vector 31 is external nIRQ local interrupt pin
       
    80 #elif defined(__CPU_CORTEX_A9__)
       
    81 #define	TIMESLICE_VECTOR			0x1D	// vector 29 is per-CPU timer interrupt
       
    82 											// vector 30 is per-CPU Watchdog timer when not in watchdog mode
       
    83 #else
       
    84 #error	TIMESLICE_VECTOR not defined
       
    85 #endif
       
    86 
       
    87 
       
    88 //extern "C" TSubScheduler* SubSchedulerLookupTable[256];		// look up subscheduler from APIC ID
       
    89 
       
    90 const TUint32 KNThreadContextFlagThumbBit0=1;
       
    91 
       
    92 /** Registers saved by the scheduler
       
    93 
       
    94 Let's just have the same stack layout for all CPUs shall we?
       
    95 TEEHBR, FpExc may not be used but leave space on the stack for them.
       
    96 
       
    97 @internalComponent
       
    98 */
       
    99 struct SThreadReschedStack
       
   100 	{
       
   101 	TUint32	iFpExc;			// VFP enable
       
   102 	TUint32	iCar;			// coprocessor access register
       
   103 	TUint32	iTEEHBR;		// Thumb2-EE Handler Base
       
   104 	TUint32	iRWROTID;		// User RO Thread ID
       
   105 	TUint32	iRWRWTID;		// User RW Thread ID
       
   106 	TUint32	iDacr;			// domain access control
       
   107 	TUint32	iSpare;
       
   108 	TUint32	iSpsrSvc;
       
   109 	TUint32 iSPRschdFlg;	// Stack pointer plus flag indicating reschedule occurred
       
   110 	TUint32	iR15;			// return address from Reschedule()
       
   111 	};
       
   112 
       
   113 /** Registers saved on any exception, interrupt or system call
       
   114 
       
   115 @internalComponent
       
   116 */
       
   117 struct SThreadExcStack
       
   118 	{
       
   119 	enum	TType
       
   120 		{
       
   121 		EPrefetch	=0,		// prefetch abort
       
   122 		EData		=1,		// data abort
       
   123 		EUndef		=2,		// undefined instruction
       
   124 		EIrq		=3,		// IRQ interrupt
       
   125 		EFiq		=4,		// FIQ interrupt
       
   126 		ESvc		=5,		// SWI
       
   127 		EInit		=6,		// Thread has never run
       
   128 		EStub		=7,		// Stub indicating parameter block still on stack
       
   129 		};
       
   130 
       
   131 	TUint32	iR0;
       
   132 	TUint32	iR1;
       
   133 	TUint32	iR2;
       
   134 	TUint32	iR3;
       
   135 	TUint32	iR4;
       
   136 	TUint32	iR5;
       
   137 	TUint32	iR6;
       
   138 	TUint32	iR7;
       
   139 	TUint32	iR8;
       
   140 	TUint32	iR9;
       
   141 	TUint32	iR10;
       
   142 	TUint32	iR11;
       
   143 	TUint32	iR12;
       
   144 	TUint32	iR13usr;		// always user mode R13
       
   145 	TUint32	iR14usr;		// always user mode R14
       
   146 	TUint32	iExcCode;
       
   147 	TUint32	iR15;			// return address
       
   148 	TUint32	iCPSR;			// return CPSR
       
   149 	};
       
   150 
       
   151 /**
       
   152 @internalComponent
       
   153 */
       
   154 struct SThreadStackStub
       
   155 	{
       
   156 	TLinAddr iPBlock;		// pointer to parameter block
       
   157 	TUint32	iExcCode;		// always EStub
       
   158 	TUint32	iR15;			// unused
       
   159 	TUint32	iCPSR;			// unused
       
   160 	};
       
   161 
       
   162 /**
       
   163 @internalComponent
       
   164 */
       
   165 struct SThreadInitStack
       
   166 	{
       
   167 	SThreadReschedStack		iR;
       
   168 	SThreadExcStack			iX;
       
   169 	};
       
   170 
       
   171 
       
   172 /**
       
   173 @internalComponent
       
   174 */
       
   175 struct SThreadIrqStack
       
   176 	{
       
   177 	SThreadReschedStack		iR;
       
   178 	TUint32					iUMGSave;	// User memory guard state (if active)
       
   179 	TUint32					iR14svc;
       
   180 	SThreadExcStack			iX;
       
   181 	};
       
   182 
       
   183 
       
   184 class TArmContextElement;
       
   185 class TArmRegSet;
       
   186 
       
   187 /** ARM-specific part of the nano-thread abstraction.
       
   188 	@internalComponent
       
   189  */
       
   190 class NThread : public NThreadBase
       
   191 	{
       
   192 public:
       
   193 	TInt Create(SNThreadCreateInfo& aInfo, TBool aInitial);
       
   194 	inline void Stillborn()
       
   195 		{}
       
   196 
       
   197 	/** Value indicating what event caused thread to enter privileged mode.
       
   198 		@publishedPartner
       
   199 		@released
       
   200 	 */
       
   201 	enum TUserContextType
       
   202 		{
       
   203 		EContextNone=0,             /**< Thread has no user context */
       
   204 		EContextException=1,		/**< Hardware exception while in user mode */
       
   205 		EContextUndefined,			
       
   206 		EContextUserInterrupt,		/**< Preempted by interrupt taken in user mode */
       
   207 		EContextUserInterruptDied,  /**< Killed while preempted by interrupt taken in user mode */	// NOT USED
       
   208 		EContextSvsrInterrupt1,     /**< Preempted by interrupt taken in executive call handler */
       
   209 		EContextSvsrInterrupt1Died, /**< Killed while preempted by interrupt taken in executive call handler */	// NOT USED
       
   210 		EContextSvsrInterrupt2,     /**< Preempted by interrupt taken in executive call handler */	// NOT USED
       
   211 		EContextSvsrInterrupt2Died, /**< Killed while preempted by interrupt taken in executive call handler */	// NOT USED
       
   212 		EContextWFAR,               /**< Blocked on User::WaitForAnyRequest() */
       
   213 		EContextWFARDied,           /**< Killed while blocked on User::WaitForAnyRequest() */		// NOT USED
       
   214 		EContextExec,				/**< Slow executive call */
       
   215 		EContextKernel,				/**< Kernel side context (for kernel threads) */
       
   216 		EContextKernel1,			/**< Kernel side context (for kernel threads) (NKern::Unlock, NKern::PreemptionPoint) */
       
   217 		EContextKernel2,			/**< Kernel side context (for kernel threads) (NKern::FSWait, NKern::WaitForAnyRequest) */
       
   218 		EContextKernel3,			/**< Kernel side context (for kernel threads) (Interrupt) */
       
   219 		EContextKernel4,			/**< Kernel side context (for kernel threads) (Exec::WaitForAnyRequest) */
       
   220 		};
       
   221 
       
   222 	IMPORT_C static const TArmContextElement* const* UserContextTables();
       
   223 	IMPORT_C TUserContextType UserContextType();
       
   224 	void GetUserContext(TArmRegSet& aContext, TUint32& aAvailRegistersMask);
       
   225 	void SetUserContext(const TArmRegSet& aContext, TUint32& aRegMask);
       
   226 	void GetSystemContext(TArmRegSet& aContext, TUint32& aAvailRegistersMask);
       
   227 
       
   228 	TUint32 Dacr();
       
   229 	void SetDacr(TUint32 aDacr);
       
   230 	TUint32 ModifyDacr(TUint32 aClearMask, TUint32 aSetMask);
       
   231 
       
   232 	void SetCar(TUint32 aDacr);
       
   233 	IMPORT_C TUint32 Car();
       
   234 	IMPORT_C TUint32 ModifyCar(TUint32 aClearMask, TUint32 aSetMask);
       
   235 
       
   236 #ifdef __CPU_HAS_VFP
       
   237 	void SetFpExc(TUint32 aDacr);
       
   238 #endif
       
   239 	IMPORT_C TUint32 FpExc();
       
   240 	IMPORT_C TUint32 ModifyFpExc(TUint32 aClearMask, TUint32 aSetMask);
       
   241 
       
   242 	void CompleteContextSave();
       
   243 	};
       
   244 
       
   245 
       
   246 struct SArmInterruptInfo
       
   247 	{
       
   248 	TLinAddr iIrqHandler;
       
   249 	TLinAddr iFiqHandler;
       
   250 	SCpuIdleHandler iCpuIdleHandler;
       
   251 	};
       
   252 
       
   253 extern "C" SArmInterruptInfo ArmInterruptInfo;
       
   254 
       
   255 #if defined(__ARMCC__)
       
   256 #ifndef __CIA__
       
   257 inline void mb()
       
   258 	{
       
   259 	TUint32 reg = 0;
       
   260 	asm("mcr p15, 0, reg, c7, c10, 5 ");
       
   261 	}
       
   262 
       
   263 inline void arm_dsb()
       
   264 	{
       
   265 	TUint32 reg = 0;
       
   266 	asm("mcr p15, 0, reg, c7, c10, 4 ");
       
   267 	}
       
   268 
       
   269 inline void arm_isb()
       
   270 	{
       
   271 	TUint32 reg = 0;
       
   272 	asm("mcr p15, 0, reg, c7, c5, 4 ");
       
   273 	}
       
   274 #endif
       
   275 #elif defined(__GNUC__) || defined(__GCC32__)
       
   276 #define	mb()	\
       
   277 	do	{	\
       
   278 		TUint32 reg = 0;	\
       
   279 		__asm__ __volatile__("mcr p15, 0, %0, c7, c10, 5" : : "r"(reg) : "memory");	\
       
   280 		} while(0)
       
   281 
       
   282 #define	arm_dsb()	\
       
   283 	do	{	\
       
   284 		TUint32 reg = 0;	\
       
   285 		__asm__ __volatile__("mcr p15, 0, %0, c7, c10, 4" : : "r"(reg) : "memory");	\
       
   286 		} while(0)
       
   287 
       
   288 #define	arm_isb()	\
       
   289 	do	{	\
       
   290 		TUint32 reg = 0;	\
       
   291 		__asm__ __volatile__("mcr p15, 0, %0, c7, c5, 4" : : "r"(reg) : "memory");	\
       
   292 		} while(0)
       
   293 #else
       
   294 #error Unknown ARM compiler
       
   295 #endif
       
   296 
       
   297 #define	smp_mb()	mb()
       
   298 #define	wmb()		mb()
       
   299 #define	smp_wmb()	mb()
       
   300 
       
   301 #ifdef	__IN_KERNEL__
       
   302 struct ArmScu;
       
   303 struct GicDistributor;
       
   304 struct GicCpuIfc;
       
   305 struct ArmLocalTimer;
       
   306 #define	SCU			(*(ArmScu*)TheScheduler.i_ScuAddr)
       
   307 #define	GIC_DIST	(*(GicDistributor*)TheScheduler.i_GicDistAddr)
       
   308 #define	GIC_CPU_IFC	(*(GicCpuIfc*)TheScheduler.i_GicCpuIfcAddr)
       
   309 #define	LOCAL_TIMER	(*(ArmLocalTimer*)TheScheduler.i_LocalTimerAddr)
       
   310 #endif
       
   311 
       
   312 
       
   313 // End of file
       
   314 #endif