sl@0: // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of the License "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // e32test\nkernsa\nirqx.cpp sl@0: // sl@0: // sl@0: sl@0: #include sl@0: sl@0: #ifdef __X86__ sl@0: #include sl@0: #endif sl@0: sl@0: class NIrqXTest : public NIrqX sl@0: { sl@0: public: sl@0: NIrqXTest(); sl@0: void Kick(); sl@0: void Set(TBool aLevel); sl@0: public: sl@0: static void DoEoi(NIrq* aIrq); sl@0: static void DoEnable(NIrq* aIrq); sl@0: static void DoDisable(NIrq* aIrq); sl@0: static void DoSetCpu(NIrq* aIrq, TUint32 aMask); sl@0: static void DoInit(NIrq* aIrq); sl@0: static TBool DoPending(NIrq* aIrq); sl@0: static void DoWait(NIrq* aIrq); sl@0: public: sl@0: TSpinLock iLock; sl@0: NIrq* iIrq; sl@0: TUint32 iCpuMask; sl@0: TUint8 iEnabled; sl@0: TUint8 iPending; sl@0: TUint8 iLevel; sl@0: }; sl@0: sl@0: NIrqXTest::NIrqXTest() sl@0: { sl@0: iIrq = 0; sl@0: iCpuMask = 0x1; sl@0: iEnabled = 0; sl@0: iPending = 0; sl@0: iLevel = 0; sl@0: } sl@0: sl@0: void NIrqXTest::Set(TBool aLevel) sl@0: { sl@0: TBool active = FALSE; sl@0: TInt irq = __SPIN_LOCK_IRQSAVE(iLock); sl@0: TUint32 f = iIrq->iStaticFlags; sl@0: if (f & NIrq::ELevel) sl@0: { sl@0: if (f & NIrq::EPolarity) sl@0: { sl@0: active = aLevel; sl@0: } sl@0: else sl@0: { sl@0: active = !aLevel; sl@0: } sl@0: } sl@0: else sl@0: { sl@0: if (f & NIrq::EPolarity) sl@0: { sl@0: active = aLevel && !iLevel; sl@0: } sl@0: else sl@0: { sl@0: active = !aLevel && iLevel; sl@0: } sl@0: } sl@0: iLevel = (TUint8)(aLevel ? 1 : 0); sl@0: if (active && iEnabled) sl@0: Kick(); sl@0: __SPIN_UNLOCK_IRQRESTORE(iLock,irq); sl@0: } sl@0: sl@0: #if defined (__X86__) sl@0: __NAKED__ void NIrqXTest::Kick() sl@0: { sl@0: _asm mov al, 1 sl@0: _asm lock xchg al, [ecx]NIrqXTest.iPending sl@0: _asm cmp al, 0 sl@0: _asm jne short kick0 sl@0: _asm mov eax, [ecx]NIrqXTest.iCpuMask sl@0: _asm shl eax, 24 sl@0: _asm jz short kick0 // no CPUs, so nothing to do sl@0: _asm mov ds:[X86_LOCAL_APIC_BASE + X86_LOCAL_APIC_OFFSET_ICRH], eax sl@0: _asm mov eax, [ecx]NIrqXTest.iIrq sl@0: _asm mov eax, [eax]NIrq.iVector sl@0: _asm or eax, 0x4800 sl@0: _asm mov ds:[X86_LOCAL_APIC_BASE + X86_LOCAL_APIC_OFFSET_ICRL], eax sl@0: _asm kick0: sl@0: _asm ret sl@0: } sl@0: #endif sl@0: sl@0: void NIrqXTest::DoEoi(NIrq* aIrq) sl@0: { sl@0: NIrqXTest* pX = (NIrqXTest*)iX; sl@0: TInt irq = __SPIN_LOCK_IRQSAVE(pX->iLock); sl@0: if (pX->iPending) sl@0: { sl@0: pX->iPending = 0; sl@0: TUint32 f = aIrq->iStaticFlags; sl@0: if (f & NIrq::ELevel) sl@0: { sl@0: TUint active_level = (f & NIrq::EPolarity) ? 1 : 0; sl@0: if (pX->iLevel==active_level && pX->iEnabled) sl@0: pX->Kick(); sl@0: } sl@0: } sl@0: __SPIN_UNLOCK_IRQRESTORE(pX->iLock,irq); sl@0: } sl@0: sl@0: void NIrqXTest::DoEnable(NIrq* aIrq) sl@0: { sl@0: } sl@0: sl@0: void NIrqXTest::DoDisable(NIrq* aIrq) sl@0: { sl@0: } sl@0: sl@0: void NIrqXTest::DoSetCpu(NIrq* aIrq, TUint32 aMask) sl@0: { sl@0: } sl@0: sl@0: void NIrqXTest::DoInit(NIrq* aIrq) sl@0: { sl@0: iIrq = aIrq; sl@0: } sl@0: sl@0: TBool NIrqXTest::DoPending(NIrq* aIrq) sl@0: { sl@0: } sl@0: sl@0: void NIrqXTest::DoWait(NIrq* aIrq) sl@0: { sl@0: } sl@0: