os/kernelhwsrv/kernel/eka/include/nkernsmp/arm/nk_plat.h
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     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