os/kernelhwsrv/kerneltest/e32test/nkernsa/nirqx.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     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