1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/kernel/eka/include/nkernsmp/nk_irq.h Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,201 @@
1.4 +// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of the License "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +// e32\include\nkernsmp\nk_irq.h
1.18 +//
1.19 +// WARNING: This file contains some APIs which are internal and are subject
1.20 +// to change without notice. Such APIs should therefore not be used
1.21 +// outside the Kernel and Hardware Services package.
1.22 +//
1.23 +
1.24 +/**
1.25 + @file
1.26 + @internalTechnology
1.27 +*/
1.28 +
1.29 +#ifndef __NK_IRQ_H__
1.30 +#define __NK_IRQ_H__
1.31 +
1.32 +#ifndef NK_MAX_IRQS
1.33 +#if defined(__CPU_ARM)
1.34 +#define NK_MAX_IRQS 96 // 32-127 on GIC
1.35 +#else
1.36 +#define NK_MAX_IRQS 32
1.37 +#endif
1.38 +#endif
1.39 +
1.40 +#ifndef NK_MAX_IRQ_HANDLERS
1.41 +#if defined(__CPU_ARM)
1.42 +#define NK_MAX_IRQ_HANDLERS (1*NK_MAX_IRQS)
1.43 +#else
1.44 +#define NK_MAX_IRQ_HANDLERS (2*NK_MAX_IRQS)
1.45 +#endif
1.46 +#endif
1.47 +
1.48 +#include <nklib.h>
1.49 +#include <nk_event.h>
1.50 +
1.51 +class NSchedulable;
1.52 +class NThreadBase;
1.53 +class NThread;
1.54 +class NFastSemaphore;
1.55 +class NFastMutex;
1.56 +
1.57 +/******************************************************************************
1.58 + * Class per peripheral interrupt
1.59 + ******************************************************************************/
1.60 +class NIrqHandler;
1.61 +class NIrqX;
1.62 +class NIrq
1.63 + {
1.64 +public:
1.65 + NIrq();
1.66 +public:
1.67 + // client services
1.68 + TInt BindRaw(NIsr aIsr, TAny* aPtr);
1.69 + TInt UnbindRaw();
1.70 + TInt DisableRaw(TBool aUnbind);
1.71 + TInt EnableRaw();
1.72 + TInt Bind(NIrqHandler* aH);
1.73 + static TInt FromHandle(TInt& aHandle, NIrq*& aIrq, NIrqHandler*& aHandler);
1.74 +public:
1.75 + // HW access
1.76 + void HwIsr();
1.77 + void HwEoi();
1.78 + void HwEnable();
1.79 + void HwDisable();
1.80 + void HwSetCpu(TInt aCpu);
1.81 + void HwSetCpuMask(TUint32 aMask);
1.82 + void HwInit();
1.83 + static void HwInit0();
1.84 + static void HwInit1();
1.85 + static void HwInit2AP();
1.86 + TBool HwPending();
1.87 + void HwWaitCpus();
1.88 +public:
1.89 + // functions to manipulate iIState
1.90 + TUint32 EnterIsr(); // wait for EWait clear, increment run count, return original iIState
1.91 + TBool IsrDone(); // decrement run count, return TRUE if still not zero
1.92 + void Wait(); // wait until run count is zero and we can transition EWait from 0 to 1
1.93 + void Done(); // set EWait back to 0
1.94 +public:
1.95 + enum { // iStaticFlags
1.96 + ELevel=0x01, // set for level triggered, clear for edge
1.97 + EPolarity=0x02, // set for active high, clear for active low
1.98 + EShared=0x10, // set if interrupt can be shared
1.99 + };
1.100 + enum { // iIState bits 0-7
1.101 + EWait=0x01,
1.102 + ERaw=0x02, // raw ISR with no processing, can't be shared
1.103 + ECount=0x04, // if set count all interrupts else limit pending count to 1
1.104 + EUnbind=0x08, // raw ISR being unbound
1.105 + };
1.106 +public:
1.107 + TSpinLock iNIrqLock;
1.108 + SDblQue iHandlers;
1.109 + volatile TUint32 iIState; // bits 0-7=flags, bits 8-15=CPU on which it is running, bits 16-31=run count
1.110 + TUint16 iStaticFlags;
1.111 + TUint16 iIndex;
1.112 + volatile TUint32 iEventsPending;
1.113 + volatile TUint32 iEnabledEvents; // bits 1-31 = count of enabled handlers, bit 0 = 1 if temporarily disabled
1.114 + volatile TUint32 iGeneration; // incremented on unbind raw or enable while bound as raw
1.115 + TUint32 iHwId;
1.116 + TUint32 iVector;
1.117 + NIrqX* iX;
1.118 + TUint32 iNIrqSpare[16-10-sizeof(TSpinLock)/sizeof(TUint32)];
1.119 + };
1.120 +
1.121 +__ASSERT_COMPILE(!(_FOFF(NIrq,iNIrqLock)&7));
1.122 +__ASSERT_COMPILE(sizeof(NIrq)==64);
1.123 +
1.124 +class NIrqX
1.125 + {
1.126 +public:
1.127 + typedef void (*TEoiFn)(NIrq*);
1.128 + typedef void (*TEnableFn)(NIrq*);
1.129 + typedef void (*TDisableFn)(NIrq*);
1.130 + typedef void (*TSetCpuFn)(NIrq*, TUint32);
1.131 + typedef void (*TInitFn)(NIrq*);
1.132 + typedef TBool (*TPendingFn)(NIrq*);
1.133 + typedef void (*TWaitFn)(NIrq*);
1.134 +public:
1.135 + TEoiFn iEoiFn;
1.136 + TEnableFn iEnableFn;
1.137 + TDisableFn iDisableFn;
1.138 + TSetCpuFn iSetCpuFn;
1.139 + TInitFn iInitFn;
1.140 + TPendingFn iPendingFn;
1.141 + TWaitFn iWaitFn;
1.142 + };
1.143 +
1.144 +/******************************************************************************
1.145 + * Class per interrupt handler
1.146 + ******************************************************************************/
1.147 +typedef NEventFn NIsr;
1.148 +class TSubScheduler;
1.149 +class NIrqHandler : public NEventHandler
1.150 + {
1.151 +public:
1.152 + NIrqHandler();
1.153 + static NIrqHandler* Alloc();
1.154 + void Free();
1.155 + void Activate(TInt aCount);
1.156 + TInt Enable(TInt aHandle);
1.157 + TInt Disable(TBool aUnbind, TInt aHandle);
1.158 + TInt Unbind(TInt aId, NSchedulable* aTied);
1.159 + void DoUnbind();
1.160 +public:
1.161 + // functions to manipulate iHState
1.162 + TUint32 DoSetEnabled(); // if EUnbound clear, clear EDisable. Return original iHState
1.163 + TUint32 DoActivate(TInt);
1.164 + TUint32 EventBegin();
1.165 + TUint32 EventDone();
1.166 +public:
1.167 + enum { // iHState bits 8-31
1.168 + EDisable =0x00000100u,
1.169 + EUnbind =0x00000200u, // this handler is being unbound
1.170 + EBind =0x00000400u, // this handler has been bound but not enabled
1.171 + ENotReady =0x00000800u, // this handler is being bound
1.172 + ECount =0x00001000u, // if set count all interrupts else limit pending count to 1
1.173 + EActive =0x00002000u, // handler is running or about to run
1.174 + EExclusive =0x00004000u, // exclusive access to shared interrupt
1.175 + ERunCountMask =0xffff0000u
1.176 + };
1.177 +public:
1.178 + SDblQueLink iIrqLink; // link to NIrq
1.179 + NIrq* volatile iIrq;
1.180 + volatile TUint32 iGeneration; // incremented on enable or bind
1.181 + volatile TUint32 iHandle; // bits 0-15 = array index, bits 16-30 = cookie, 1-32767
1.182 + TUint32 iNIrqHandlerSpare[3]; // round to power of 2
1.183 +public:
1.184 + static NIrqHandler* FirstFree; // protected by NEventHandler::TiedLock
1.185 + };
1.186 +
1.187 +__ASSERT_COMPILE(sizeof(NIrqHandler)==64);
1.188 +
1.189 +
1.190 +#if 0
1.191 +#include <e32btrace.h>
1.192 +#define IRQ_TRACE_CAT 253 // FIXME
1.193 +#define TRACE_IRQ0(n) BTraceContextPc0(IRQ_TRACE_CAT, n)
1.194 +#define TRACE_IRQ4(n,a) BTraceContextPc4(IRQ_TRACE_CAT, n, a)
1.195 +#define TRACE_IRQ8(n,a,b) BTraceContextPc8(IRQ_TRACE_CAT, n, a, b)
1.196 +#define TRACE_IRQ12(n,a,b,c) BTraceContextPc12(IRQ_TRACE_CAT, n, a, b, c)
1.197 +#else
1.198 +#define TRACE_IRQ0(n)
1.199 +#define TRACE_IRQ4(n,a)
1.200 +#define TRACE_IRQ8(n,a,b)
1.201 +#define TRACE_IRQ12(n,a,b,c)
1.202 +#endif
1.203 +
1.204 +#endif // __NK_IRQ_H__