kernel/eka/nkernsmp/nk_irq.cpp
author Tom Cosgrove <tom.cosgrove@nokia.com>
Fri, 28 May 2010 16:29:07 +0100
changeset 30 8aab599e3476
parent 8 538db54a451d
child 43 c1f20ce4abcf
permissions -rw-r--r--
Fix for bug 2283 (RVCT 4.0 support is missing from PDK 3.0.h) Have multiple extension sections in the bld.inf, one for each version of the compiler. The RVCT version building the tools will build the runtime libraries for its version, but make sure we extract all the other versions from zip archives. Also add the archive for RVCT4.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
     1
// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
     2
// All rights reserved.
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
     3
// This component and the accompanying materials are made available
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
     4
// under the terms of the License "Eclipse Public License v1.0"
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
     5
// which accompanies this distribution, and is available
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
     7
//
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
     8
// Initial Contributors:
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
     9
// Nokia Corporation - initial contribution.
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    10
//
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    11
// Contributors:
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    12
//
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    13
// Description:
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    14
// e32\nkernsmp\nk_irq.cpp
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    15
// 
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    16
//
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    17
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    18
/**
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    19
 @file
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    20
 @internalTechnology
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    21
*/
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    22
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    23
#include <e32cmn.h>
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    24
#include <e32cmn_private.h>
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    25
#include "nk_priv.h"
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    26
#include <nk_irq.h>
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    27
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    28
NIrq		Irq[NK_MAX_IRQS];
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    29
NIrqHandler	Handlers[NK_MAX_IRQ_HANDLERS];
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    30
NIrqHandler* NIrqHandler::FirstFree;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    31
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    32
extern "C" void send_irq_ipi(TSubScheduler*);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    33
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    34
void StepCookie(volatile TUint16& p, TInt n)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    35
	{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    36
	TUint32 x = p<<17;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    37
	while(n--)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    38
		{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    39
		TUint32 y = x;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    40
		x<<=1;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    41
		y^=x;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    42
		x |= ((y>>31)<<17);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    43
		}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    44
	p = (TUint16)(x>>17);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    45
	}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    46
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    47
NIrq::NIrq()
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    48
	:	iNIrqLock(TSpinLock::EOrderNIrq)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    49
	{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    50
	iIState = EWait;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    51
	iEventsPending = 0;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    52
	iEnabledEvents = 0;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    53
	iHwId = 0;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    54
	iX = 0;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    55
	}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    56
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    57
TInt NIrq::BindRaw(NIsr aIsr, TAny* aPtr)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    58
	{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    59
	// Call only from thread context
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    60
	TInt r = KErrNone;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    61
	Wait();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    62
	iNIrqLock.LockOnly();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    63
	if (iStaticFlags & EShared)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    64
		{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    65
		r = KErrAccessDenied;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    66
		goto error;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    67
		}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    68
	if ( (iIState & ERaw) || !iHandlers.IsEmpty())
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    69
		{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    70
		r = KErrInUse;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    71
		goto error;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    72
		}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    73
	iHandlers.iA.iNext = (SDblQueLink*)aIsr;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    74
	iHandlers.iA.iPrev = (SDblQueLink*)aPtr;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    75
	__e32_atomic_ior_rel32(&iIState, ERaw);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    76
error:
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    77
	iNIrqLock.UnlockOnly();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    78
	Done();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    79
	return r;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    80
	}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    81
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    82
TInt NIrq::UnbindRaw()
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    83
	{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    84
	// Call only from thread context
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    85
	TInt r = DisableRaw(TRUE);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    86
	if (r != KErrNone)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    87
		return r;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    88
	Wait();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    89
	iNIrqLock.LockOnly();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    90
	if (iIState & ERaw)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    91
		{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    92
		iHandlers.iA.iNext = 0;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    93
		iHandlers.iA.iPrev = 0;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    94
		++iGeneration;	// release anyone still waiting in Disable()
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    95
		__e32_atomic_and_rel32(&iIState, ~(ERaw|EUnbind));
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    96
		}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    97
	iNIrqLock.UnlockOnly();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    98
	Done();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
    99
	return r;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   100
	}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   101
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   102
TInt NIrq::DisableRaw(TBool aUnbind)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   103
	{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   104
	TBool wait = FALSE;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   105
	TInt r = KErrNone;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   106
	TInt irq = __SPIN_LOCK_IRQSAVE(iNIrqLock);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   107
	if (!(iIState & ERaw))
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   108
		r = KErrGeneral;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   109
	else
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   110
		{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   111
		wait = TRUE;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   112
		if (aUnbind)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   113
			__e32_atomic_ior_acq32(&iIState, EUnbind);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   114
		if (!(iEnabledEvents & 1))
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   115
			{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   116
			iEnabledEvents |= 1;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   117
			HwDisable();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   118
//			wait = TRUE;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   119
			}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   120
		}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   121
	__SPIN_UNLOCK_IRQRESTORE(iNIrqLock,irq);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   122
	TInt c = NKern::CurrentContext();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   123
	if (wait && c!=NKern::EInterrupt)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   124
		{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   125
		// wait for currently running handler to finish or interrupt to be reenabled
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   126
		if (c==NKern::EThread)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   127
			NKern::ThreadEnterCS();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   128
		HwWaitCpus();	// ensure other CPUs have had a chance to accept any outstanding interrupts
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   129
		TUint32 g = iGeneration;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   130
		while ( ((iIState >> 16) || HwPending()) && (iGeneration == g))
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   131
			{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   132
			__chill();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   133
			}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   134
		if (c==NKern::EThread)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   135
			NKern::ThreadLeaveCS();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   136
		}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   137
	return r;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   138
	}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   139
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   140
TInt NIrq::EnableRaw()
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   141
	{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   142
	TInt r = KErrNone;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   143
	TInt irq = __SPIN_LOCK_IRQSAVE(iNIrqLock);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   144
	if (!(iIState & ERaw))
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   145
		r = KErrGeneral;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   146
	else if (iIState & EUnbind)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   147
		r = KErrNotReady;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   148
	else if (iEnabledEvents & 1)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   149
		{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   150
		iEnabledEvents = 0;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   151
		HwEnable();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   152
		++iGeneration;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   153
		}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   154
	__SPIN_UNLOCK_IRQRESTORE(iNIrqLock,irq);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   155
	return r;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   156
	}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   157
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   158
TInt NIrq::Bind(NIrqHandler* aH)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   159
	{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   160
	// Call only from thread context
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   161
	TInt r = KErrInUse;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   162
	Wait();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   163
	if (!(iIState & ERaw))
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   164
		{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   165
		r = KErrNone;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   166
		TBool empty = iHandlers.IsEmpty();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   167
		TBool shared = iStaticFlags & EShared;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   168
		TBool exclusive = iIState & NIrqHandler::EExclusive;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   169
		if (!empty)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   170
			{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   171
			if (!shared || exclusive)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   172
				{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   173
				r = KErrAccessDenied;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   174
				goto error;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   175
				}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   176
			NIrqHandler* h = _LOFF(iHandlers.First(), NIrqHandler, iIrqLink);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   177
			if (h->iHState & NIrqHandler::EExclusive)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   178
				{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   179
				r = KErrAccessDenied;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   180
				goto error;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   181
				}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   182
			}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   183
		aH->iIrq = this;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   184
		iHandlers.Add(&aH->iIrqLink);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   185
		}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   186
error:
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   187
	Done();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   188
	return r;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   189
	}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   190
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   191
void NIrq::HwIsr()
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   192
	{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   193
	TRACE_IRQ12(16, this, iVector, iIState);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   194
	TBool eoi_done = FALSE;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   195
	TUint32 rcf0 = EnterIsr();		// for initial run count
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   196
	TUint32 rcf1 = iIState;			// might have changed while we were waiting in EnterIsr()
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   197
	if (rcf1 & ERaw)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   198
		{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   199
		if (!(rcf1 & EUnbind))
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   200
			{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   201
			NIsr f = (NIsr)iHandlers.iA.iNext;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   202
			TAny* p = iHandlers.iA.iPrev;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   203
			(*f)(p);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   204
			}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   205
		HwEoi();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   206
		IsrDone();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   207
		return;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   208
		}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   209
	if (rcf0 >> 16)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   210
		{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   211
		HwEoi();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   212
		return;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   213
		}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   214
	if (!(iStaticFlags & ELevel))
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   215
		{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   216
		eoi_done = TRUE;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   217
		HwEoi();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   218
		}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   219
	do	{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   220
		// Handler list can't be touched now
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   221
		SDblQueLink* anchor = &iHandlers.iA;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   222
		SDblQueLink* p = anchor->iNext;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   223
		while (p != anchor)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   224
			{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   225
			NIrqHandler* h = _LOFF(p, NIrqHandler, iIrqLink);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   226
			h->Activate(1);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   227
			p = p->iNext;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   228
			}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   229
		if (!eoi_done)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   230
			{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   231
			eoi_done = TRUE;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   232
			HwEoi();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   233
			}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   234
		if ((iStaticFlags & ELevel) && iEventsPending)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   235
			{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   236
			// For a level triggered interrupt make sure interrupt is disabled until
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   237
			// all pending event handlers have run, to avoid a continuous interrupt.
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   238
			TInt irq = __SPIN_LOCK_IRQSAVE(iNIrqLock);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   239
			if (iEventsPending)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   240
				{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   241
				iEnabledEvents |= 1;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   242
				HwDisable();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   243
				}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   244
			__SPIN_UNLOCK_IRQRESTORE(iNIrqLock,irq);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   245
			}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   246
		} while (IsrDone());
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   247
	}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   248
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   249
void NIrqHandler::Activate(TInt aCount)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   250
	{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   251
	TUint32 orig = DoActivate(aCount);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   252
	TRACE_IRQ12(17, this, orig, aCount);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   253
	if (orig & (EDisable|EUnbind|EActive))
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   254
		return;	// disabled or already active
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   255
	if (iTied)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   256
		{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   257
		// we need to enforce mutual exclusion between the event handler
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   258
		// and the tied thread or thread group, so the event handler must
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   259
		// run on the CPU to which the thread or group is currently attached
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   260
		// once the event has been attached to that CPU, the thread/group
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   261
		// can't be migrated until the event handler completes.
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   262
		// need a pending event count for the tied thread/group
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   263
		// so we know when the thread/group can be migrated
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   264
		TInt tied_cpu = iTied->BeginTiedEvent();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   265
		TInt this_cpu = NKern::CurrentCpu();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   266
		if (tied_cpu != this_cpu)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   267
			{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   268
			__e32_atomic_add_acq32(&iIrq->iEventsPending, 1);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   269
			TheSubSchedulers[tied_cpu].QueueEventAndKick(this);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   270
			// FIXME: move IRQ over to tied CPU if this is the only handler for that IRQ
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   271
			//			what to do about shared IRQs?
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   272
			return;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   273
			}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   274
		}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   275
	// event can run on this CPU so run it now
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   276
	if (aCount)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   277
		{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   278
		orig = EventBegin();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   279
		TRACE_IRQ8(18, this, orig);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   280
		(*iFn)(iPtr);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   281
		orig = EventDone();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   282
		TRACE_IRQ8(19, this, orig);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   283
		if (!(orig & EActive))
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   284
			{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   285
			if (iTied)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   286
				iTied->EndTiedEvent();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   287
			return;	// that was last occurrence or event now disabled
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   288
			}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   289
		}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   290
	__e32_atomic_add_ord32(&iIrq->iEventsPending, 1);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   291
//	add event to this cpu
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   292
	SubScheduler().QueueEventAndKick(this);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   293
	}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   294
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   295
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   296
NIrqHandler::NIrqHandler()
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   297
	{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   298
	iIrqLink.iNext = 0;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   299
	iIrq = 0;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   300
	iTied = 0;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   301
	iHState = EDisable|EBind|ENotReady|EEventHandlerIrq;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   302
	iFn = 0;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   303
	iPtr = 0;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   304
	memclr(iNIrqHandlerSpare, sizeof(iNIrqHandlerSpare));
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   305
	}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   306
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   307
void NIrqHandler::Free()
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   308
	{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   309
	NKern::Lock();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   310
	NEventHandler::TiedLock.LockOnly();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   311
	if (!iTied)	// Only free if iTied has been cleared
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   312
		{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   313
		iIrqLink.iNext = FirstFree;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   314
		FirstFree = this;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   315
		}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   316
	NEventHandler::TiedLock.UnlockOnly();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   317
	NKern::Unlock();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   318
	}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   319
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   320
NIrqHandler* NIrqHandler::Alloc()
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   321
	{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   322
	NKern::Lock();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   323
	NEventHandler::TiedLock.LockOnly();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   324
	NIrqHandler* p = FirstFree;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   325
	if (p)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   326
		FirstFree = (NIrqHandler*)p->iIrqLink.iNext;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   327
	NEventHandler::TiedLock.UnlockOnly();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   328
	NKern::Unlock();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   329
	if (p)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   330
		new (p) NIrqHandler();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   331
	return p;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   332
	}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   333
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   334
TInt NIrqHandler::Enable(TInt aHandle)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   335
	{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   336
	// call from any context
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   337
	TBool reactivate = FALSE;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   338
	TInt r = KErrNotReady;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   339
	NIrq* pI = iIrq;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   340
	if (!pI)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   341
		return KErrNotReady;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   342
	TInt irq = __SPIN_LOCK_IRQSAVE(pI->iNIrqLock);	// OK since NIrq's are never deleted
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   343
	if (iIrq==pI && TUint(aHandle)==iHandle)	// check handler not unbound
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   344
		{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   345
		TUint32 orig = DoSetEnabled();	// clear EDisable and EBind provided neither EUnbind nor ENotReady set
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   346
		if (!(orig & (EUnbind|ENotReady)))
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   347
			{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   348
			r = KErrNone;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   349
			if (orig & EDisable)	// check not already enabled
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   350
				{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   351
				++iGeneration;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   352
				TUint32 n = pI->iEnabledEvents;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   353
				pI->iEnabledEvents += 2;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   354
				if (n==0)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   355
					pI->HwEnable();	// enable HW interrupt if this is first handler to be enabled
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   356
				if ((orig >> 16) && !(orig & EActive))
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   357
					// replay remembered interrupt(s)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   358
					reactivate = TRUE;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   359
				}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   360
			}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   361
		}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   362
	if (reactivate)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   363
		{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   364
		pI->iNIrqLock.UnlockOnly();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   365
		Activate(0);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   366
		pI->iNIrqLock.LockOnly();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   367
		}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   368
	__SPIN_UNLOCK_IRQRESTORE(pI->iNIrqLock,irq);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   369
	return r;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   370
	}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   371
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   372
TInt NIrqHandler::Disable(TBool aUnbind, TInt aHandle)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   373
	{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   374
	// call from any context
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   375
	NIrq* pI = iIrq;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   376
	if (!pI)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   377
		return KErrGeneral;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   378
	TInt irq = __SPIN_LOCK_IRQSAVE(pI->iNIrqLock);	// OK since NIrq's are never deleted
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   379
	if (iIrq != pI || TUint(aHandle)!=iHandle)	// check handler not unbound
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   380
		{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   381
		__SPIN_UNLOCK_IRQRESTORE(pI->iNIrqLock,irq);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   382
		return KErrGeneral;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   383
		}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   384
	TInt r = aUnbind ? KErrGeneral : KErrNone;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   385
	TUint32 f = aUnbind ? EUnbind|EDisable : EDisable;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   386
	TUint32 orig = __e32_atomic_ior_acq32(&iHState, f);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   387
	TUint32 g = iGeneration;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   388
	if (!(orig & EDisable))	// check not already disabled
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   389
		{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   390
		pI->iEnabledEvents -= 2;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   391
		if (!pI->iEnabledEvents)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   392
			pI->HwDisable();	// disable HW interrupt if no more enabled handlers
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   393
		}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   394
	if (aUnbind && !(orig & EUnbind))
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   395
		{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   396
		volatile TUint16& cookie = *(volatile TUint16*)(((TUint8*)&iHandle)+2);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   397
		StepCookie(cookie, 1);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   398
		r = KErrNone;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   399
		}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   400
	__SPIN_UNLOCK_IRQRESTORE(pI->iNIrqLock,irq);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   401
	if (NKern::CurrentContext() != NKern::EInterrupt)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   402
		{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   403
		// wait for currently running handler to finish or interrupt to be reenabled
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   404
 		while ((iHState & EActive) && (iGeneration == g))
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   405
			{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   406
			__chill();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   407
			}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   408
		}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   409
	return r;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   410
	}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   411
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   412
TInt NIrqHandler::Unbind(TInt aId, NSchedulable* aTied)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   413
	{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   414
	TInt r = Disable(TRUE, aId);	// waits for any current activation of ISR to finish
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   415
	if (r==KErrNone || aTied)	// returns KErrGeneral if someone else already unbound this interrupt handler
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   416
		{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   417
		// Possible race condition here between tied thread termination and interrupt unbind.
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   418
		// We need to be sure that the iTied field must be NULL before the tied thread/group
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   419
		// is destroyed.
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   420
		NKern::Lock();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   421
		NEventHandler::TiedLock.LockOnly();	// this guarantees pH->iTied cannot change
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   422
		NSchedulable* t = iTied;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   423
		if (t)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   424
			{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   425
			// We need to guarantee the object pointed to by t cannot be deleted until we
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   426
			// have finished with it.
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   427
			t->AcqSLock();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   428
			if (iTiedLink.iNext)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   429
				{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   430
				iTiedLink.Deque();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   431
				iTiedLink.iNext = 0;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   432
				iTied = 0;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   433
				}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   434
			if (aTied && aTied==t)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   435
				iTied = 0;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   436
			t->RelSLock();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   437
			}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   438
		NEventHandler::TiedLock.UnlockOnly();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   439
		NKern::Unlock();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   440
		}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   441
	if (r==KErrNone)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   442
		{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   443
		DoUnbind();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   444
		Free();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   445
		}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   446
	return r;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   447
	}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   448
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   449
void NIrqHandler::DoUnbind()
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   450
	{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   451
	// Call only from thread context
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   452
	NIrq* pI = iIrq;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   453
	pI->Wait();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   454
	iIrqLink.Deque();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   455
	iIrq = 0;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   456
	pI->Done();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   457
	}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   458
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   459
TBool TSubScheduler::QueueEvent(NEventHandler* aEvent)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   460
	{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   461
	TInt irq = __SPIN_LOCK_IRQSAVE(iEventHandlerLock);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   462
	TBool pending = iEventHandlersPending;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   463
	iEventHandlersPending = TRUE;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   464
	iEventHandlers.Add(aEvent);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   465
	__SPIN_UNLOCK_IRQRESTORE(iEventHandlerLock,irq);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   466
	return !pending;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   467
	}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   468
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   469
void TSubScheduler::QueueEventAndKick(NEventHandler* aEvent)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   470
	{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   471
	if (QueueEvent(aEvent))
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   472
		{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   473
		// extra barrier ?
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   474
		send_irq_ipi(this);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   475
		}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   476
	}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   477
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   478
extern "C" void run_event_handlers(TSubScheduler* aS)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   479
	{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   480
	while (aS->iEventHandlersPending)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   481
		{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   482
		TInt irq = __SPIN_LOCK_IRQSAVE(aS->iEventHandlerLock);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   483
		if (aS->iEventHandlers.IsEmpty())
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   484
			{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   485
			aS->iEventHandlersPending = FALSE;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   486
			__SPIN_UNLOCK_IRQRESTORE(aS->iEventHandlerLock, irq);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   487
			break;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   488
			}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   489
		NIrqHandler* h = (NIrqHandler*)aS->iEventHandlers.First()->Deque();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   490
		if (aS->iEventHandlers.IsEmpty())
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   491
			aS->iEventHandlersPending = FALSE;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   492
		TInt type = h->iHType;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   493
		NSchedulable* tied = h->iTied;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   494
		if (type == NEventHandler::EEventHandlerNTimer)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   495
			{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   496
			NEventFn f = h->iFn;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   497
			TAny* p = h->iPtr;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   498
			mb();	// make sure dequeue observed and iFn,iPtr,iTied sampled before state change observed
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   499
			h->i8888.iHState1 = NTimer::EIdle; // can't touch timer again after this
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   500
			__SPIN_UNLOCK_IRQRESTORE(aS->iEventHandlerLock, irq);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   501
			(*f)(p);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   502
			if (tied)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   503
				tied->EndTiedEvent();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   504
			continue;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   505
			}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   506
		__SPIN_UNLOCK_IRQRESTORE(aS->iEventHandlerLock, irq);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   507
		TBool requeue = TRUE;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   508
		switch (h->iHType)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   509
			{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   510
			case NEventHandler::EEventHandlerIrq:
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   511
				{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   512
				TUint32 orig;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   513
				// event can run on this CPU so run it now
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   514
				// if event tied, migration of tied thread/group will have been blocked
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   515
				orig = h->EventBegin();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   516
				TRACE_IRQ8(20, h, orig);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   517
				(*h->iFn)(h->iPtr);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   518
				TRACE_IRQ4(21, h);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   519
				if (!(h->iHState & NIrqHandler::ERunCountMask))	// if run count still nonzero, definitely still active
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   520
					{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   521
					NIrq* pI = h->iIrq;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   522
					irq = __SPIN_LOCK_IRQSAVE(pI->iNIrqLock);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   523
					orig = h->EventDone();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   524
					TRACE_IRQ8(22, h, orig);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   525
					if (!(orig & NIrqHandler::EActive))
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   526
						{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   527
						// handler is no longer active - can't touch it again
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   528
						// pI is OK since NIrq's are never deleted/reused
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   529
						requeue = FALSE;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   530
						if (__e32_atomic_add_rel32(&pI->iEventsPending, TUint32(-1)) == 1)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   531
							{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   532
							if (pI->iEnabledEvents & 1)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   533
								{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   534
								pI->iEnabledEvents &= ~1;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   535
								if (pI->iEnabledEvents)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   536
									pI->HwEnable();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   537
								}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   538
							}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   539
						}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   540
					__SPIN_UNLOCK_IRQRESTORE(pI->iNIrqLock,irq);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   541
					}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   542
				break;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   543
				}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   544
			default:
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   545
				__KTRACE_OPT(KPANIC,DEBUGPRINT("h=%08x",h));
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   546
				__NK_ASSERT_ALWAYS(0);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   547
			}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   548
		if (tied && !requeue)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   549
			{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   550
			// If the tied thread/group has no more tied events outstanding
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   551
			// and has a migration pending, trigger the migration now.
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   552
			// Atomically change the tied_cpu to the target CPU here. An IDFC
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   553
			// can then effect the migration.
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   554
			// Note that the tied code can't run in parallel with us until
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   555
			// the tied_cpu is changed. However it could run as soon as the
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   556
			// tied_cpu is changed (e.g. if added to ready list after change)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   557
			tied->EndTiedEvent();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   558
			}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   559
		if (requeue)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   560
			{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   561
			// still pending so put it back on the queue
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   562
			// leave interrupt disabled (if so) and migration of tied thread/group blocked
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   563
			aS->QueueEvent(h);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   564
			}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   565
		}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   566
	}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   567
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   568
/******************************************************************************
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   569
 * Public interrupt management functions
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   570
 ******************************************************************************/
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   571
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   572
void NKern::InterruptInit0()
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   573
	 {
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   574
	 TInt i;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   575
	 TUint16 cookie = 1;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   576
	 NIrqHandler::FirstFree = 0;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   577
	 for (i=NK_MAX_IRQ_HANDLERS-1; i>=0; --i)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   578
		 {
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   579
		 StepCookie(cookie, 61);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   580
		 NIrqHandler* h = &::Handlers[i];
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   581
		__KTRACE_OPT(KBOOT,DEBUGPRINT("NIrqHandler[%d] at %08x", i, h));
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   582
		 h->iGeneration = 0;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   583
		 h->iHandle = (cookie << 16) | i;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   584
		 h->iIrqLink.iNext = NIrqHandler::FirstFree;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   585
		 NIrqHandler::FirstFree = h;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   586
		 }
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   587
	 NIrq::HwInit0();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   588
	 }
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   589
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   590
EXPORT_C TInt NKern::InterruptInit(TInt aId, TUint32 aFlags, TInt aVector, TUint32 aHwId, TAny* aExt)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   591
	{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   592
	__KTRACE_OPT(KBOOT,DEBUGPRINT("NKII: ID=%02x F=%08x V=%03x HWID=%08x X=%08x", aId, aFlags, aVector, aHwId, aExt));
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   593
	TRACE_IRQ12(0, (aId|(aVector<<16)), aFlags, aHwId);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   594
	if (TUint(aId) >= TUint(NK_MAX_IRQS))
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   595
  		return KErrArgument;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   596
	NIrq* pI = &Irq[aId];
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   597
	__KTRACE_OPT(KBOOT,DEBUGPRINT("NIrq[%02x] at %08x", aId, pI));
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   598
	TRACE_IRQ8(1, aId, pI);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   599
	new (pI) NIrq;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   600
	pI->iX = (NIrqX*)aExt;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   601
	pI->iIndex = (TUint16)aId;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   602
	pI->iHwId = aHwId;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   603
	pI->iVector = aVector;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   604
	pI->iStaticFlags = (TUint16)(aFlags & 0x13);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   605
	if (aFlags & NKern::EIrqInit_Count)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   606
		pI->iIState |= NIrq::ECount;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   607
	pI->HwInit();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   608
	__e32_atomic_and_rel32(&pI->iIState, ~NIrq::EWait);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   609
	return KErrNone;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   610
	}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   611
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   612
EXPORT_C TInt NKern::InterruptBind(TInt aId, NIsr aIsr, TAny* aPtr, TUint32 aFlags, NSchedulable* aTied)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   613
	{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   614
	__KTRACE_OPT(KNKERN,DEBUGPRINT(">NKIB: ID=%02x ISR=%08x(%08x) F=%08x T=%T", aId, aIsr, aPtr, aFlags, aTied));
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   615
	TRACE_IRQ12(2, aId, aIsr, aPtr);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   616
	TRACE_IRQ12(3, aId, aFlags, aTied);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   617
	CHECK_PRECONDITIONS(MASK_THREAD_STANDARD,"NKern::InterruptBind");
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   618
	if (TUint(aId) >= TUint(NK_MAX_IRQS))
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   619
		{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   620
		TRACE_IRQ8(4, aId, KErrArgument);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   621
		return KErrArgument;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   622
		}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   623
	NIrq* pI = &Irq[aId];
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   624
	NIrqHandler* pH = 0;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   625
	NSchedulable* pT = 0;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   626
	if (aFlags & NKern::EIrqBind_Tied)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   627
		{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   628
		if (!aTied)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   629
			aTied = NKern::CurrentThread();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   630
		pT = aTied;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   631
		}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   632
	TInt r = KErrNoMemory;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   633
	TInt handle = 0;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   634
	NKern::ThreadEnterCS();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   635
	if (!(aFlags & NKern::EIrqBind_Raw))
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   636
		{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   637
		pH = NIrqHandler::Alloc();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   638
		if (!pH)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   639
			goto out;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   640
		pH->iFn = aIsr;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   641
		pH->iPtr = aPtr;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   642
		__e32_atomic_add_ord32(&pH->iGeneration, 1);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   643
		if (aFlags & EIrqBind_Exclusive)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   644
			pH->iHState |= NIrqHandler::EExclusive;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   645
		if (aFlags & EIrqBind_Count)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   646
			pH->iHState |= NIrqHandler::ECount;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   647
		r = pI->Bind(pH);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   648
		if (r==KErrNone)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   649
			{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   650
			handle = pH->iHandle;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   651
			// We assume that aTied cannot disappear entirely before we return
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   652
			if (pT)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   653
				{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   654
				NKern::Lock();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   655
				r = pT->AddTiedEvent(pH);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   656
				NKern::Unlock();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   657
				}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   658
			if (r!=KErrNone)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   659
				{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   660
				// unbind
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   661
				pH->DoUnbind();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   662
				}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   663
			}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   664
		if (r!=KErrNone)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   665
			pH->Free();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   666
		}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   667
	else
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   668
		{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   669
		if (aFlags & NKern::EIrqBind_Tied)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   670
			r = KErrNotSupported;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   671
		else
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   672
			r = pI->BindRaw(aIsr, aPtr);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   673
		}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   674
out:
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   675
	if (r==KErrNone)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   676
		{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   677
		// clear ENotReady so handler can be enabled
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   678
		__e32_atomic_and_rel32(&pH->iHState, ~NIrqHandler::ENotReady);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   679
		r = handle;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   680
		}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   681
	NKern::ThreadLeaveCS();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   682
	__KTRACE_OPT(KNKERN,DEBUGPRINT("<NKIB: %08x", r));
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   683
	TRACE_IRQ8(4, aId, r);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   684
	return r;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   685
	}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   686
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   687
TInt NIrq::FromHandle(TInt& aHandle, NIrq*& aIrq, NIrqHandler*& aHandler)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   688
	{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   689
	TRACE_IRQ4(5, aHandle);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   690
	aIrq = 0;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   691
	aHandler = 0;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   692
	NIrqHandler* pH = 0;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   693
	NIrqHandler* pH2 = 0;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   694
	NIrq* pI = 0;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   695
	SDblQueLink* anchor = 0;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   696
	TUint32 i;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   697
	TInt r = KErrArgument;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   698
	if (aHandle & NKern::EIrqCookieMask)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   699
		{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   700
		i = aHandle & NKern::EIrqIndexMask;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   701
		if (i>=NK_MAX_IRQ_HANDLERS)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   702
			goto out;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   703
		pH = &::Handlers[i];
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   704
		if (pH->iHandle != TUint(aHandle))
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   705
			goto out;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   706
		aHandler = pH;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   707
		aIrq = pH->iIrq;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   708
		r = KErrNone;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   709
		goto out;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   710
		}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   711
	if (TUint32(aHandle)>=NK_MAX_IRQS)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   712
		goto out;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   713
	pI = &::Irq[aHandle];
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   714
	if (pI->iIState & NIrq::ERaw)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   715
		{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   716
		aIrq = pI;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   717
		r = KErrNone;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   718
		goto out;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   719
		}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   720
	if (pI->iStaticFlags & NIrq::EShared)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   721
		goto out;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   722
	anchor = &pI->iHandlers.iA;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   723
	pH = _LOFF(anchor->iNext, NIrqHandler, iIrqLink);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   724
	i = pH - ::Handlers;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   725
	if (i>=NK_MAX_IRQ_HANDLERS)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   726
		goto out;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   727
	pH2 = &::Handlers[i];
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   728
	if (pH2 != pH)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   729
		goto out;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   730
	if (pH->iIrq != pI || anchor->iPrev != anchor->iNext)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   731
		goto out;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   732
	aHandle = pH->iHandle;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   733
	aHandler = pH;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   734
	aIrq = pI;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   735
	r = KErrNone;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   736
out:
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   737
	TRACE_IRQ4(6, r);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   738
	TRACE_IRQ12(7, aHandle, aIrq, aHandler);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   739
	return r;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   740
	}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   741
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   742
EXPORT_C TInt NKern::InterruptUnbind(TInt aId)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   743
	{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   744
	TRACE_IRQ4(8, aId);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   745
	__KTRACE_OPT(KNKERN,DEBUGPRINT(">NKIU: ID=%08x", aId));
8
538db54a451d Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents: 0
diff changeset
   746
	CHECK_PRECONDITIONS(MASK_THREAD_STANDARD,"NKern::InterruptUnbind");
0
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   747
	NIrq* pI;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   748
	NIrqHandler* pH;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   749
	TInt r = NIrq::FromHandle(aId, pI, pH);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   750
	if (r!=KErrNone)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   751
		return r;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   752
	NKern::ThreadEnterCS();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   753
	if (!pH)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   754
		{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   755
		// raw ISR
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   756
		r = pI->UnbindRaw();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   757
		}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   758
	else
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   759
		{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   760
		r = pH->Unbind(aId, 0);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   761
		}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   762
	NKern::ThreadLeaveCS();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   763
	TRACE_IRQ4(9, r);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   764
	return r;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   765
	}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   766
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   767
EXPORT_C TInt NKern::InterruptEnable(TInt aId)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   768
	{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   769
	__KTRACE_OPT(KNKERN,DEBUGPRINT(">NKIE: ID=%08x", aId));
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   770
	TRACE_IRQ4(10, aId);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   771
	NIrq* pI;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   772
	NIrqHandler* pH;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   773
	TInt r = NIrq::FromHandle(aId, pI, pH);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   774
	if (r==KErrNone)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   775
		r = pH ? pH->Enable(aId) : pI->EnableRaw();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   776
	TRACE_IRQ4(11, r);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   777
	return r;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   778
	}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   779
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   780
EXPORT_C TInt NKern::InterruptDisable(TInt aId)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   781
	{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   782
	__KTRACE_OPT(KNKERN,DEBUGPRINT(">NKID: ID=%08x", aId));
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   783
	TRACE_IRQ4(12, aId);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   784
	NIrq* pI;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   785
	NIrqHandler* pH;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   786
	TInt r = NIrq::FromHandle(aId, pI, pH);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   787
	if (r==KErrNone)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   788
		r = pH ? pH->Disable(FALSE, aId) : pI->DisableRaw(FALSE);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   789
	TRACE_IRQ4(13, r);
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   790
	return r;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   791
	}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   792
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   793
EXPORT_C TInt NKern::InterruptClear(TInt aId)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   794
	{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   795
	__KTRACE_OPT(KNKERN,DEBUGPRINT(">NKIC: ID=%08x", aId));
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   796
	return KErrNotSupported;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   797
	}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   798
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   799
EXPORT_C TInt NKern::InterruptSetPriority(TInt aId, TInt aPri)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   800
	{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   801
	__KTRACE_OPT(KNKERN,DEBUGPRINT(">NKIS: ID=%08x PRI=%08x", aId, aPri));
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   802
	return KErrNotSupported;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   803
	}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   804
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   805
EXPORT_C TInt NKern::InterruptSetCpuMask(TInt aId, TUint32 aMask)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   806
	{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   807
	__KTRACE_OPT(KNKERN,DEBUGPRINT(">NKIM: ID=%08x M=%08x", aId, aMask));
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   808
	return KErrNotSupported;
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   809
	}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   810
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   811
EXPORT_C void NKern::Interrupt(TInt aId)
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   812
	{
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   813
	__NK_ASSERT_ALWAYS(TUint(aId) < TUint(NK_MAX_IRQS));
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   814
	NIrq* pI = &Irq[aId];
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   815
	pI->HwIsr();
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   816
	}
a41df078684a Convert Kernelhwsrv package from SFL to EPL
John Imhofe
parents:
diff changeset
   817