|
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\nk_irq.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 @internalTechnology |
|
24 */ |
|
25 |
|
26 #ifndef __NK_IRQ_H__ |
|
27 #define __NK_IRQ_H__ |
|
28 |
|
29 #ifndef NK_MAX_IRQS |
|
30 #if defined(__CPU_ARM) |
|
31 #define NK_MAX_IRQS 96 // 32-127 on GIC |
|
32 #else |
|
33 #define NK_MAX_IRQS 32 |
|
34 #endif |
|
35 #endif |
|
36 |
|
37 #ifndef NK_MAX_IRQ_HANDLERS |
|
38 #if defined(__CPU_ARM) |
|
39 #define NK_MAX_IRQ_HANDLERS (1*NK_MAX_IRQS) |
|
40 #else |
|
41 #define NK_MAX_IRQ_HANDLERS (2*NK_MAX_IRQS) |
|
42 #endif |
|
43 #endif |
|
44 |
|
45 #include <nklib.h> |
|
46 #include <nk_event.h> |
|
47 |
|
48 class NSchedulable; |
|
49 class NThreadBase; |
|
50 class NThread; |
|
51 class NFastSemaphore; |
|
52 class NFastMutex; |
|
53 |
|
54 /****************************************************************************** |
|
55 * Class per peripheral interrupt |
|
56 ******************************************************************************/ |
|
57 class NIrqHandler; |
|
58 class NIrqX; |
|
59 class NIrq |
|
60 { |
|
61 public: |
|
62 NIrq(); |
|
63 public: |
|
64 // client services |
|
65 TInt BindRaw(NIsr aIsr, TAny* aPtr); |
|
66 TInt UnbindRaw(); |
|
67 TInt DisableRaw(TBool aUnbind); |
|
68 TInt EnableRaw(); |
|
69 TInt Bind(NIrqHandler* aH); |
|
70 static TInt FromHandle(TInt& aHandle, NIrq*& aIrq, NIrqHandler*& aHandler); |
|
71 public: |
|
72 // HW access |
|
73 void HwIsr(); |
|
74 void HwEoi(); |
|
75 void HwEnable(); |
|
76 void HwDisable(); |
|
77 void HwSetCpu(TInt aCpu); |
|
78 void HwSetCpuMask(TUint32 aMask); |
|
79 void HwInit(); |
|
80 static void HwInit0(); |
|
81 static void HwInit1(); |
|
82 static void HwInit2AP(); |
|
83 TBool HwPending(); |
|
84 void HwWaitCpus(); |
|
85 public: |
|
86 // functions to manipulate iIState |
|
87 TUint32 EnterIsr(); // wait for EWait clear, increment run count, return original iIState |
|
88 TBool IsrDone(); // decrement run count, return TRUE if still not zero |
|
89 void Wait(); // wait until run count is zero and we can transition EWait from 0 to 1 |
|
90 void Done(); // set EWait back to 0 |
|
91 public: |
|
92 enum { // iStaticFlags |
|
93 ELevel=0x01, // set for level triggered, clear for edge |
|
94 EPolarity=0x02, // set for active high, clear for active low |
|
95 EShared=0x10, // set if interrupt can be shared |
|
96 }; |
|
97 enum { // iIState bits 0-7 |
|
98 EWait=0x01, |
|
99 ERaw=0x02, // raw ISR with no processing, can't be shared |
|
100 ECount=0x04, // if set count all interrupts else limit pending count to 1 |
|
101 EUnbind=0x08, // raw ISR being unbound |
|
102 }; |
|
103 public: |
|
104 TSpinLock iNIrqLock; |
|
105 SDblQue iHandlers; |
|
106 volatile TUint32 iIState; // bits 0-7=flags, bits 8-15=CPU on which it is running, bits 16-31=run count |
|
107 TUint16 iStaticFlags; |
|
108 TUint16 iIndex; |
|
109 volatile TUint32 iEventsPending; |
|
110 volatile TUint32 iEnabledEvents; // bits 1-31 = count of enabled handlers, bit 0 = 1 if temporarily disabled |
|
111 volatile TUint32 iGeneration; // incremented on unbind raw or enable while bound as raw |
|
112 TUint32 iHwId; |
|
113 TUint32 iVector; |
|
114 NIrqX* iX; |
|
115 TUint32 iNIrqSpare[16-10-sizeof(TSpinLock)/sizeof(TUint32)]; |
|
116 }; |
|
117 |
|
118 __ASSERT_COMPILE(!(_FOFF(NIrq,iNIrqLock)&7)); |
|
119 __ASSERT_COMPILE(sizeof(NIrq)==64); |
|
120 |
|
121 class NIrqX |
|
122 { |
|
123 public: |
|
124 typedef void (*TEoiFn)(NIrq*); |
|
125 typedef void (*TEnableFn)(NIrq*); |
|
126 typedef void (*TDisableFn)(NIrq*); |
|
127 typedef void (*TSetCpuFn)(NIrq*, TUint32); |
|
128 typedef void (*TInitFn)(NIrq*); |
|
129 typedef TBool (*TPendingFn)(NIrq*); |
|
130 typedef void (*TWaitFn)(NIrq*); |
|
131 public: |
|
132 TEoiFn iEoiFn; |
|
133 TEnableFn iEnableFn; |
|
134 TDisableFn iDisableFn; |
|
135 TSetCpuFn iSetCpuFn; |
|
136 TInitFn iInitFn; |
|
137 TPendingFn iPendingFn; |
|
138 TWaitFn iWaitFn; |
|
139 }; |
|
140 |
|
141 /****************************************************************************** |
|
142 * Class per interrupt handler |
|
143 ******************************************************************************/ |
|
144 typedef NEventFn NIsr; |
|
145 class TSubScheduler; |
|
146 class NIrqHandler : public NEventHandler |
|
147 { |
|
148 public: |
|
149 NIrqHandler(); |
|
150 static NIrqHandler* Alloc(); |
|
151 void Free(); |
|
152 void Activate(TInt aCount); |
|
153 TInt Enable(TInt aHandle); |
|
154 TInt Disable(TBool aUnbind, TInt aHandle); |
|
155 TInt Unbind(TInt aId, NSchedulable* aTied); |
|
156 void DoUnbind(); |
|
157 public: |
|
158 // functions to manipulate iHState |
|
159 TUint32 DoSetEnabled(); // if EUnbound clear, clear EDisable. Return original iHState |
|
160 TUint32 DoActivate(TInt); |
|
161 TUint32 EventBegin(); |
|
162 TUint32 EventDone(); |
|
163 public: |
|
164 enum { // iHState bits 8-31 |
|
165 EDisable =0x00000100u, |
|
166 EUnbind =0x00000200u, // this handler is being unbound |
|
167 EBind =0x00000400u, // this handler has been bound but not enabled |
|
168 ENotReady =0x00000800u, // this handler is being bound |
|
169 ECount =0x00001000u, // if set count all interrupts else limit pending count to 1 |
|
170 EActive =0x00002000u, // handler is running or about to run |
|
171 EExclusive =0x00004000u, // exclusive access to shared interrupt |
|
172 ERunCountMask =0xffff0000u |
|
173 }; |
|
174 public: |
|
175 SDblQueLink iIrqLink; // link to NIrq |
|
176 NIrq* volatile iIrq; |
|
177 volatile TUint32 iGeneration; // incremented on enable or bind |
|
178 volatile TUint32 iHandle; // bits 0-15 = array index, bits 16-30 = cookie, 1-32767 |
|
179 TUint32 iNIrqHandlerSpare[3]; // round to power of 2 |
|
180 public: |
|
181 static NIrqHandler* FirstFree; // protected by NEventHandler::TiedLock |
|
182 }; |
|
183 |
|
184 __ASSERT_COMPILE(sizeof(NIrqHandler)==64); |
|
185 |
|
186 |
|
187 #if 0 |
|
188 #include <e32btrace.h> |
|
189 #define IRQ_TRACE_CAT 253 // FIXME |
|
190 #define TRACE_IRQ0(n) BTraceContextPc0(IRQ_TRACE_CAT, n) |
|
191 #define TRACE_IRQ4(n,a) BTraceContextPc4(IRQ_TRACE_CAT, n, a) |
|
192 #define TRACE_IRQ8(n,a,b) BTraceContextPc8(IRQ_TRACE_CAT, n, a, b) |
|
193 #define TRACE_IRQ12(n,a,b,c) BTraceContextPc12(IRQ_TRACE_CAT, n, a, b, c) |
|
194 #else |
|
195 #define TRACE_IRQ0(n) |
|
196 #define TRACE_IRQ4(n,a) |
|
197 #define TRACE_IRQ8(n,a,b) |
|
198 #define TRACE_IRQ12(n,a,b,c) |
|
199 #endif |
|
200 |
|
201 #endif // __NK_IRQ_H__ |