diff -r 2fb8b9db1c86 -r d55eb581a87c baseport/syborg/specific/interrupts.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/baseport/syborg/specific/interrupts.cpp Tue Aug 04 10:28:23 2009 +0100 @@ -0,0 +1,149 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Syborg interrupt control and dispatch +* +*/ + +#include + +SInterruptHandler SyborgInterrupt::Handlers[KNumSyborgInts]; + +void SyborgInterrupt::DisableAndClearAll() +{ + WriteReg(KHwBaseSic, 3, 0); +} + +void SyborgInterrupt::Init1() +{ + __KTRACE_OPT(KBOOT,Kern::Printf("SyborgInterrupt::Init1()")); + + for(TUint i = 0; i < KNumSyborgInts; i++) + { + Handlers[i].iPtr = (TAny*)i; + Handlers[i].iIsr = Spurious; + } + + DisableAndClearAll(); + + Arm::SetIrqHandler((TLinAddr)SyborgInterrupt::IrqDispatch); + Arm::SetFiqHandler((TLinAddr)SyborgInterrupt::FiqDispatch); +} + +void SyborgInterrupt::Init3() +{ + __KTRACE_OPT(KHARDWARE,Kern::Printf("SyborgInterrupt::Init3()")); +} + +void SyborgInterrupt::Spurious(TAny* anId) +{ + // Handle an unexpected interrupt + Kern::Fault("SpuriousInt", (TInt)anId); +} + +EXPORT_C TInt Interrupt::Bind(TInt anId, TIsr anIsr, TAny* aPtr) +{ + __KTRACE_OPT(KHARDWARE,Kern::Printf("Interrupt::Bind(anId=%d anIsr=0x%X aPtr=0x%X)",anId,anIsr,aPtr)); + if((anId >= 0) && ((TUint)anId < KNumSyborgInts)) + { + SInterruptHandler& h = SyborgInterrupt::Handlers[anId]; + TInt irq = NKern::DisableAllInterrupts(); + TInt r; + if(h.iIsr != SyborgInterrupt::Spurious) + { + r = KErrInUse; + } + else + { + h.iPtr = aPtr; + h.iIsr = anIsr; + r = KErrNone; + } + NKern::RestoreInterrupts(irq); + return r; + } + return KErrArgument; +} + +EXPORT_C TInt Interrupt::Unbind(TInt anId) +{ + __KTRACE_OPT(KHARDWARE,Kern::Printf("Interrupt::Unbind(%d)",anId)); + if((anId >= 0) && ((TUint)anId < KNumSyborgInts)) + { + SInterruptHandler& h = SyborgInterrupt::Handlers[anId]; + TInt irq = NKern::DisableAllInterrupts(); + TInt r; + if(h.iIsr == SyborgInterrupt::Spurious) + { + r = KErrGeneral; + } + else + { + // Reset pointer to handler back to default + h.iPtr = (TAny*)anId; + h.iIsr = SyborgInterrupt::Spurious; + // Disable the interrupt + TSyborg::DisableInt(anId); + r = KErrNone; + } + NKern::RestoreInterrupts(irq); + return r; + } + return KErrArgument; +} + +EXPORT_C TInt Interrupt::Enable(TInt anId) +{ + __KTRACE_OPT(KHARDWARE,Kern::Printf("Interrupt::Enable(%d)",anId)); + if((anId >= 0) && ((TUint)anId < KNumSyborgInts)) + { + if(SyborgInterrupt::Handlers[anId].iIsr == SyborgInterrupt::Spurious) + { + return KErrNotReady; + } + else + { + TSyborg::EnableInt(anId); + return KErrNone; + } + } + return KErrArgument; +} + +EXPORT_C TInt Interrupt::Disable(TInt anId) +{ + __KTRACE_OPT(KHARDWARE,Kern::Printf("Interrupt::Disable(%d)",anId)); + if((anId >= 0) && ((TUint)anId < KNumSyborgInts)) + { + TSyborg::DisableInt(anId); + return KErrNone; + } + return KErrArgument; +} + +EXPORT_C TInt Interrupt::Clear(TInt anId) +{ + __KTRACE_OPT(KHARDWARE,Kern::Printf("Interrupt::Clear(%d)",anId)); + if((anId >= 0) && ((TUint)anId < KNumSyborgInts)) + { + return KErrNone; + } + return KErrArgument; +} + +EXPORT_C TInt Interrupt::SetPriority(TInt anId, TInt aPriority) +{ + __KTRACE_OPT(KHARDWARE,Kern::Printf("Interrupt::SetPriority(anId=%d aPriority=0x%X)",anId,aPriority)); + return KErrNotSupported; +} +