0
|
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__
|