kerneltest/e32test/nkernsa/nirqx.cpp
changeset 0 a41df078684a
equal deleted inserted replaced
-1:000000000000 0:a41df078684a
       
     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 // e32test\nkernsa\nirqx.cpp
       
    15 // 
       
    16 //
       
    17 
       
    18 #include <nk_irq.h>
       
    19 
       
    20 #ifdef __X86__
       
    21 #include <apic.h>
       
    22 #endif
       
    23 
       
    24 class NIrqXTest : public NIrqX
       
    25 	{
       
    26 public:
       
    27 	NIrqXTest();
       
    28 	void Kick();
       
    29 	void Set(TBool aLevel);
       
    30 public:
       
    31 	static void DoEoi(NIrq* aIrq);
       
    32 	static void DoEnable(NIrq* aIrq);
       
    33 	static void DoDisable(NIrq* aIrq);
       
    34 	static void DoSetCpu(NIrq* aIrq, TUint32 aMask);
       
    35 	static void DoInit(NIrq* aIrq);
       
    36 	static TBool DoPending(NIrq* aIrq);
       
    37 	static void DoWait(NIrq* aIrq);
       
    38 public:
       
    39 	TSpinLock			iLock;
       
    40 	NIrq*				iIrq;
       
    41 	TUint32				iCpuMask;
       
    42 	TUint8				iEnabled;
       
    43 	TUint8				iPending;
       
    44 	TUint8				iLevel;
       
    45 	};
       
    46 
       
    47 NIrqXTest::NIrqXTest()
       
    48 	{
       
    49 	iIrq = 0;
       
    50 	iCpuMask = 0x1;
       
    51 	iEnabled = 0;
       
    52 	iPending = 0;
       
    53 	iLevel = 0;
       
    54 	}
       
    55 
       
    56 void NIrqXTest::Set(TBool aLevel)
       
    57 	{
       
    58 	TBool active = FALSE;
       
    59 	TInt irq = __SPIN_LOCK_IRQSAVE(iLock);
       
    60 	TUint32 f = iIrq->iStaticFlags;
       
    61 	if (f & NIrq::ELevel)
       
    62 		{
       
    63 		if (f & NIrq::EPolarity)
       
    64 			{
       
    65 			active = aLevel;
       
    66 			}
       
    67 		else
       
    68 			{
       
    69 			active = !aLevel;
       
    70 			}
       
    71 		}
       
    72 	else
       
    73 		{
       
    74 		if (f & NIrq::EPolarity)
       
    75 			{
       
    76 			active = aLevel && !iLevel;
       
    77 			}
       
    78 		else
       
    79 			{
       
    80 			active = !aLevel && iLevel;
       
    81 			}
       
    82 		}
       
    83 	iLevel = (TUint8)(aLevel ? 1 : 0);
       
    84 	if (active && iEnabled)
       
    85 		Kick();
       
    86 	__SPIN_UNLOCK_IRQRESTORE(iLock,irq);
       
    87 	}
       
    88 
       
    89 #if defined (__X86__)
       
    90 __NAKED__ void NIrqXTest::Kick()
       
    91 	{
       
    92 	_asm mov al, 1
       
    93 	_asm lock xchg al, [ecx]NIrqXTest.iPending
       
    94 	_asm cmp al, 0
       
    95 	_asm jne short kick0
       
    96 	_asm mov eax, [ecx]NIrqXTest.iCpuMask
       
    97 	_asm shl eax, 24
       
    98 	_asm jz short kick0	// no CPUs, so nothing to do
       
    99 	_asm mov ds:[X86_LOCAL_APIC_BASE + X86_LOCAL_APIC_OFFSET_ICRH], eax
       
   100 	_asm mov eax, [ecx]NIrqXTest.iIrq
       
   101 	_asm mov eax, [eax]NIrq.iVector
       
   102 	_asm or eax, 0x4800
       
   103 	_asm mov ds:[X86_LOCAL_APIC_BASE + X86_LOCAL_APIC_OFFSET_ICRL], eax
       
   104 	_asm kick0:
       
   105 	_asm ret
       
   106 	}
       
   107 #endif
       
   108 
       
   109 void NIrqXTest::DoEoi(NIrq* aIrq)
       
   110 	{
       
   111 	NIrqXTest* pX = (NIrqXTest*)iX;
       
   112 	TInt irq = __SPIN_LOCK_IRQSAVE(pX->iLock);
       
   113 	if (pX->iPending)
       
   114 		{
       
   115 		pX->iPending = 0;
       
   116 		TUint32 f = aIrq->iStaticFlags;
       
   117 		if (f & NIrq::ELevel)
       
   118 			{
       
   119 			TUint active_level = (f & NIrq::EPolarity) ? 1 : 0;
       
   120 			if (pX->iLevel==active_level && pX->iEnabled)
       
   121 				pX->Kick();
       
   122 			}
       
   123 		}
       
   124 	__SPIN_UNLOCK_IRQRESTORE(pX->iLock,irq);
       
   125 	}
       
   126 
       
   127 void NIrqXTest::DoEnable(NIrq* aIrq)
       
   128 	{
       
   129 	}
       
   130 
       
   131 void NIrqXTest::DoDisable(NIrq* aIrq)
       
   132 	{
       
   133 	}
       
   134 
       
   135 void NIrqXTest::DoSetCpu(NIrq* aIrq, TUint32 aMask)
       
   136 	{
       
   137 	}
       
   138 
       
   139 void NIrqXTest::DoInit(NIrq* aIrq)
       
   140 	{
       
   141 	iIrq = aIrq;
       
   142 	}
       
   143 
       
   144 TBool NIrqXTest::DoPending(NIrq* aIrq)
       
   145 	{
       
   146 	}
       
   147 
       
   148 void NIrqXTest::DoWait(NIrq* aIrq)
       
   149 	{
       
   150 	}
       
   151