/*
* 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 <e32cia.h>
#include <syborg_priv.h>
#include <cpudefs.h>
// CIA symbols for ASSP code?
#if defined(__GCC32__)
// CIA symbol macros for Gcc98r2
#define CSM_ZN7NTimerQ4TickEv " Tick__7NTimerQ"
#elif defined(__ARMCC__)
// CIA symbol macros for RVCT
#define CSM_ZN7NTimerQ4TickEv " __cpp(NTimerQ::Tick)"
#else
// CIA symbol macros for EABI assemblers
#define CSM_ZN7NTimerQ4TickEv " _ZN7NTimerQ4TickEv"
#endif
/********************************************************************
* Wait for interrupt idle routine which does not disable interrupts
********************************************************************/
__NAKED__ void SyborgWFIIdle()
{
// Enter an idle state and wait for interrupts
asm("mov r0, #0");
asm("mcr p15, 0, r0, c7, c0, 4");
asm("bx lr");
}
/********************************************************************
* Service 1ms tick interrupt & timer 1 interrupt
********************************************************************/
__NAKED__ void SyborgInterrupt::MsTimerTick(TAny* /*aPtr*/)
{
// Service 1ms tick interrupt
asm("ldr r1, __KHwCounterTimer");
asm("push {r0}");
asm("mov r0, #1");
asm("str r0, [r1, #24]");
asm("pop {r0}");
asm("b "CSM_ZN7NTimerQ4TickEv);
asm("bx lr");
asm("__KHwCounterTimer:");
asm(".word %a0" : : "i" ((TInt)KHwBaseCounterTimer));
}
/********************************************************************
* Interrupt handling/dispatch
********************************************************************/
// IRQ dispatcher
// Enter with r0-r3, r12 and return address on IRQ stack
// Must preserve r4-r11
// Uses r4,r5,r12
__NAKED__ void SyborgInterrupt::IrqDispatch()
{
asm("push {r4,r5,lr} ");
asm("ldr r4, __KHwBaseSic");
asm("ldr r12, __SicHandlerStart");
asm("ldr r5, [r4, #8]"); // r5 - pending interrupt
asm("adr lr, Clear");
asm("add r12, r5, lsl #3");
asm("ldm r12, {r0, pc}");
asm("Clear:");
// asm("str r5, [r4, #16]"); // TODO: error
asm("pop {r4,r5,pc}");
asm("__KHwBaseSic:");
asm(".word %a0" : : "i" ((TInt)KHwBaseSic));
asm("__SicHandlerStart:");
asm(".word %a0" : : "i" ((TInt)&Handlers[0]));
}
__NAKED__ void SyborgInterrupt::FiqDispatch()
{
// FIQ dispatcher
// Enter with return address on FIQ stack
// We may use r8-r12, but must preserve other registers
// NOTE: STACK IS MISALIGNED ON ENTRY (1 WORD PUSHED)
asm("push {r0-r3,lr}");
// FIQ Handler to go in here.
// Not needed because no FIQs are currently used
asm("pop {r0-r3,pc}");
}