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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // e32\include\nkernsmp\arm\nk_plat.h
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.
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__
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
61 #define i_Regs iExtras[12] // Alias for i_AbtStackTop
63 // TScheduler member data
64 #define i_TimerMax iExtras[16] // Maximum per-CPU timer frequency (after prescaling)
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
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
84 #error TIMESLICE_VECTOR not defined
88 //extern "C" TSubScheduler* SubSchedulerLookupTable[256]; // look up subscheduler from APIC ID
90 const TUint32 KNThreadContextFlagThumbBit0=1;
92 /** Registers saved by the scheduler
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.
99 struct SThreadReschedStack
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
109 TUint32 iSPRschdFlg; // Stack pointer plus flag indicating reschedule occurred
110 TUint32 iR15; // return address from Reschedule()
113 /** Registers saved on any exception, interrupt or system call
117 struct SThreadExcStack
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
127 EInit =6, // Thread has never run
128 EStub =7, // Stub indicating parameter block still on stack
144 TUint32 iR13usr; // always user mode R13
145 TUint32 iR14usr; // always user mode R14
147 TUint32 iR15; // return address
148 TUint32 iCPSR; // return CPSR
154 struct SThreadStackStub
156 TLinAddr iPBlock; // pointer to parameter block
157 TUint32 iExcCode; // always EStub
158 TUint32 iR15; // unused
159 TUint32 iCPSR; // unused
165 struct SThreadInitStack
167 SThreadReschedStack iR;
175 struct SThreadIrqStack
177 SThreadReschedStack iR;
178 TUint32 iUMGSave; // User memory guard state (if active)
184 class TArmContextElement;
187 /** ARM-specific part of the nano-thread abstraction.
190 class NThread : public NThreadBase
193 TInt Create(SNThreadCreateInfo& aInfo, TBool aInitial);
194 inline void Stillborn()
197 /** Value indicating what event caused thread to enter privileged mode.
201 enum TUserContextType
203 EContextNone=0, /**< Thread has no user context */
204 EContextException=1, /**< Hardware exception while in user mode */
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) */
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);
229 void SetDacr(TUint32 aDacr);
230 TUint32 ModifyDacr(TUint32 aClearMask, TUint32 aSetMask);
232 void SetCar(TUint32 aDacr);
233 IMPORT_C TUint32 Car();
234 IMPORT_C TUint32 ModifyCar(TUint32 aClearMask, TUint32 aSetMask);
237 void SetFpExc(TUint32 aDacr);
239 IMPORT_C TUint32 FpExc();
240 IMPORT_C TUint32 ModifyFpExc(TUint32 aClearMask, TUint32 aSetMask);
242 void CompleteContextSave();
246 struct SArmInterruptInfo
248 TLinAddr iIrqHandler;
249 TLinAddr iFiqHandler;
250 SCpuIdleHandler iCpuIdleHandler;
253 extern "C" SArmInterruptInfo ArmInterruptInfo;
255 #if defined(__ARMCC__)
260 asm("mcr p15, 0, reg, c7, c10, 5 ");
263 inline void arm_dsb()
266 asm("mcr p15, 0, reg, c7, c10, 4 ");
269 inline void arm_isb()
272 asm("mcr p15, 0, reg, c7, c5, 4 ");
275 #elif defined(__GNUC__) || defined(__GCC32__)
279 __asm__ __volatile__("mcr p15, 0, %0, c7, c10, 5" : : "r"(reg) : "memory"); \
285 __asm__ __volatile__("mcr p15, 0, %0, c7, c10, 4" : : "r"(reg) : "memory"); \
291 __asm__ __volatile__("mcr p15, 0, %0, c7, c5, 4" : : "r"(reg) : "memory"); \
294 #error Unknown ARM compiler
297 #define smp_mb() mb()
299 #define smp_wmb() mb()
303 struct GicDistributor;
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)