diff -r 000000000000 -r a41df078684a kernel/eka/include/nkernsmp/nk_irq.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kernel/eka/include/nkernsmp/nk_irq.h Mon Oct 19 15:55:17 2009 +0100 @@ -0,0 +1,201 @@ +// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// e32\include\nkernsmp\nk_irq.h +// +// WARNING: This file contains some APIs which are internal and are subject +// to change without notice. Such APIs should therefore not be used +// outside the Kernel and Hardware Services package. +// + +/** + @file + @internalTechnology +*/ + +#ifndef __NK_IRQ_H__ +#define __NK_IRQ_H__ + +#ifndef NK_MAX_IRQS +#if defined(__CPU_ARM) +#define NK_MAX_IRQS 96 // 32-127 on GIC +#else +#define NK_MAX_IRQS 32 +#endif +#endif + +#ifndef NK_MAX_IRQ_HANDLERS +#if defined(__CPU_ARM) +#define NK_MAX_IRQ_HANDLERS (1*NK_MAX_IRQS) +#else +#define NK_MAX_IRQ_HANDLERS (2*NK_MAX_IRQS) +#endif +#endif + +#include +#include + +class NSchedulable; +class NThreadBase; +class NThread; +class NFastSemaphore; +class NFastMutex; + +/****************************************************************************** + * Class per peripheral interrupt + ******************************************************************************/ +class NIrqHandler; +class NIrqX; +class NIrq + { +public: + NIrq(); +public: + // client services + TInt BindRaw(NIsr aIsr, TAny* aPtr); + TInt UnbindRaw(); + TInt DisableRaw(TBool aUnbind); + TInt EnableRaw(); + TInt Bind(NIrqHandler* aH); + static TInt FromHandle(TInt& aHandle, NIrq*& aIrq, NIrqHandler*& aHandler); +public: + // HW access + void HwIsr(); + void HwEoi(); + void HwEnable(); + void HwDisable(); + void HwSetCpu(TInt aCpu); + void HwSetCpuMask(TUint32 aMask); + void HwInit(); + static void HwInit0(); + static void HwInit1(); + static void HwInit2AP(); + TBool HwPending(); + void HwWaitCpus(); +public: + // functions to manipulate iIState + TUint32 EnterIsr(); // wait for EWait clear, increment run count, return original iIState + TBool IsrDone(); // decrement run count, return TRUE if still not zero + void Wait(); // wait until run count is zero and we can transition EWait from 0 to 1 + void Done(); // set EWait back to 0 +public: + enum { // iStaticFlags + ELevel=0x01, // set for level triggered, clear for edge + EPolarity=0x02, // set for active high, clear for active low + EShared=0x10, // set if interrupt can be shared + }; + enum { // iIState bits 0-7 + EWait=0x01, + ERaw=0x02, // raw ISR with no processing, can't be shared + ECount=0x04, // if set count all interrupts else limit pending count to 1 + EUnbind=0x08, // raw ISR being unbound + }; +public: + TSpinLock iNIrqLock; + SDblQue iHandlers; + volatile TUint32 iIState; // bits 0-7=flags, bits 8-15=CPU on which it is running, bits 16-31=run count + TUint16 iStaticFlags; + TUint16 iIndex; + volatile TUint32 iEventsPending; + volatile TUint32 iEnabledEvents; // bits 1-31 = count of enabled handlers, bit 0 = 1 if temporarily disabled + volatile TUint32 iGeneration; // incremented on unbind raw or enable while bound as raw + TUint32 iHwId; + TUint32 iVector; + NIrqX* iX; + TUint32 iNIrqSpare[16-10-sizeof(TSpinLock)/sizeof(TUint32)]; + }; + +__ASSERT_COMPILE(!(_FOFF(NIrq,iNIrqLock)&7)); +__ASSERT_COMPILE(sizeof(NIrq)==64); + +class NIrqX + { +public: + typedef void (*TEoiFn)(NIrq*); + typedef void (*TEnableFn)(NIrq*); + typedef void (*TDisableFn)(NIrq*); + typedef void (*TSetCpuFn)(NIrq*, TUint32); + typedef void (*TInitFn)(NIrq*); + typedef TBool (*TPendingFn)(NIrq*); + typedef void (*TWaitFn)(NIrq*); +public: + TEoiFn iEoiFn; + TEnableFn iEnableFn; + TDisableFn iDisableFn; + TSetCpuFn iSetCpuFn; + TInitFn iInitFn; + TPendingFn iPendingFn; + TWaitFn iWaitFn; + }; + +/****************************************************************************** + * Class per interrupt handler + ******************************************************************************/ +typedef NEventFn NIsr; +class TSubScheduler; +class NIrqHandler : public NEventHandler + { +public: + NIrqHandler(); + static NIrqHandler* Alloc(); + void Free(); + void Activate(TInt aCount); + TInt Enable(TInt aHandle); + TInt Disable(TBool aUnbind, TInt aHandle); + TInt Unbind(TInt aId, NSchedulable* aTied); + void DoUnbind(); +public: + // functions to manipulate iHState + TUint32 DoSetEnabled(); // if EUnbound clear, clear EDisable. Return original iHState + TUint32 DoActivate(TInt); + TUint32 EventBegin(); + TUint32 EventDone(); +public: + enum { // iHState bits 8-31 + EDisable =0x00000100u, + EUnbind =0x00000200u, // this handler is being unbound + EBind =0x00000400u, // this handler has been bound but not enabled + ENotReady =0x00000800u, // this handler is being bound + ECount =0x00001000u, // if set count all interrupts else limit pending count to 1 + EActive =0x00002000u, // handler is running or about to run + EExclusive =0x00004000u, // exclusive access to shared interrupt + ERunCountMask =0xffff0000u + }; +public: + SDblQueLink iIrqLink; // link to NIrq + NIrq* volatile iIrq; + volatile TUint32 iGeneration; // incremented on enable or bind + volatile TUint32 iHandle; // bits 0-15 = array index, bits 16-30 = cookie, 1-32767 + TUint32 iNIrqHandlerSpare[3]; // round to power of 2 +public: + static NIrqHandler* FirstFree; // protected by NEventHandler::TiedLock + }; + +__ASSERT_COMPILE(sizeof(NIrqHandler)==64); + + +#if 0 +#include +#define IRQ_TRACE_CAT 253 // FIXME +#define TRACE_IRQ0(n) BTraceContextPc0(IRQ_TRACE_CAT, n) +#define TRACE_IRQ4(n,a) BTraceContextPc4(IRQ_TRACE_CAT, n, a) +#define TRACE_IRQ8(n,a,b) BTraceContextPc8(IRQ_TRACE_CAT, n, a, b) +#define TRACE_IRQ12(n,a,b,c) BTraceContextPc12(IRQ_TRACE_CAT, n, a, b, c) +#else +#define TRACE_IRQ0(n) +#define TRACE_IRQ4(n,a) +#define TRACE_IRQ8(n,a,b) +#define TRACE_IRQ12(n,a,b,c) +#endif + +#endif // __NK_IRQ_H__