/* intArmLib.h - ARM-specific interrupt library header file */ /* * Copyright (c) 1997-1998, 2003, 2007-2010, 2012 Wind River Systems, Inc. * * The right to copy, distribute or otherwise make use of this software * may be licensed only pursuant to the terms of an applicable Wind River * license agreement. */ /* modification history -------------------- 01l,07may12,jdw Add ARMARCH7M header include 01j,03dec10,j_b add unified FIQ/IRQ handling support 01i,23oct09,j_b fix _inline_intCpuMicroUnlock for gnu 01h,18may09,j_b add _inline_intCpuMicroLock/Unlock support 01h,25feb09,j_b merge ARM SMP support: 21jun07,jb3 Convert to vxBus 01g,16jun08,zl added memory clobber for GNUC version of inline routines. 01f,20may08,j_b fix memory accesses outside lock in _inline_intCpuLock/Unlock for gnu (WIND00121559) 01e,07aug07,jb3 Defect00095620 wrong gnu assembler instruction. 01d,21jun07,zl updated inline build configuration. 01c,22aug03,to added inline intLock()/intUnlock(). 01b,20aug98,cdp added intIFLock(), intIFUnlock(). 01a,25nov97,cdp created. */ #ifndef __INCintArmLibh #define __INCintArmLibh #if (CPU == ARMARCH7M) #include #else /* (CPU == ARMARCH7M) */ #ifdef __cplusplus extern "C" { #endif /* interrupt model feature selection bits (OR'd together) */ #define INT_NON_PREEMPT_MODEL 0 #define INT_PREEMPT_MODEL 1 #define INT_HDWE_LOCK_LVL 2 #ifndef _ASMLANGUAGE /* inline intCpuLock()/intCpuUnlock() and intCpuMicroLock/Unlock() */ #if !(ARM_THUMB) #if defined (__DCC__) __asm volatile int _inline_intCpuLock () { ! "r1" /* r1 clobbered */ mrs r1, cpsr /* get current status */ #ifdef _WRS_CONFIG_UNIFIED_FIQ_IRQ and r0, r1, #0xC0 /* return current I & F in r0 */ orr r1, r1, #0xC0 /* set I & F (1<<7 | 1<<6) */ #else and r0, r1, #0x80 /* return current I_BIT in r0 */ orr r1, r1, #0x80 /* set I_BIT (1<<7) */ #endif /* _WRS_CONFIG_UNIFIED_FIQ_IRQ */ msr cpsr, r1 /* set new status */ } __asm volatile void _inline_intCpuUnlock (int key) { % reg key; /* input: key in r0 */ ! "r0", "r1" /* r0, r1 clobbered */ mrs r1, cpsr /* get current status */ #ifdef _WRS_CONFIG_UNIFIED_FIQ_IRQ bic r1, r1, #0xC0 /* clear I & F (1<<7 | 1<<6) */ and r0, key, #0xC0 /* get passed I & F values */ #else bic r1, r1, #0x80 /* clear I_BIT (1<<7) */ and r0, key, #0x80 /* get passed I_BIT value */ #endif /* _WRS_CONFIG_UNIFIED_FIQ_IRQ */ orr r1, r1, r0 /* or in passed value */ msr cpsr,r1 /* set new status */ } __asm volatile int _inline_intCpuMicroLock () { ! "r1" /* r1 clobbered */ mrs r0, cpsr /* get, return current status */ #ifdef _WRS_CONFIG_UNIFIED_FIQ_IRQ orr r1, r0, #0xC0 /* set I & F (1<<7 | 1<<6) */ #else orr r1, r0, #0x80 /* set I_BIT (1<<7) */ #endif /* _WRS_CONFIG_UNIFIED_FIQ_IRQ */ msr cpsr_c, r1 /* set new status */ } __asm volatile void _inline_intCpuMicroUnlock (int key) { % reg key; /* input: key in r0 */ msr cpsr_c, key /* restore previous status */ } #elif defined (__GNUC__) static __inline__ int _inline_intCpuLock (void) { int key; __asm__ volatile ( "mrs r1, cpsr; " /* get current status */ #ifdef _WRS_CONFIG_UNIFIED_FIQ_IRQ "and %0, r1, #0xC0; " /* return current I & F */ "orr r1, r1, #0xC0; " /* set I & F (1<<7 | 1<<6) */ #else "and %0, r1, #0x80; " /* return current I_BIT */ "orr r1, r1, #0x80; " /* set I_BIT (1<<7) */ #endif /* _WRS_CONFIG_UNIFIED_FIQ_IRQ */ "msr cpsr, r1 " /* set new status */ : "=&r" (key) /* output: key is %0 */ : /* no input */ : "r1", "memory" /* r1 clobbered; memory */ /* clobber for code barrier */ ); return key; } static __inline__ void _inline_intCpuUnlock (int key) { __asm__ volatile ( "mrs r1, cpsr; " /* get current status */ #ifdef _WRS_CONFIG_UNIFIED_FIQ_IRQ "bic r1, r1, #0xC0; " /* clear I & F (1<<7 | 1<<6) */ "and r0, %0, #0xC0; " /* get passed I & F values */ #else "bic r1, r1, #0x80; " /* clear I_BIT (1<<7) */ "and r0, %0, #0x80; " /* get passed I_BIT value */ #endif /* _WRS_CONFIG_UNIFIED_FIQ_IRQ */ "orr r1, r1, r0; " /* or in passed I_BIT value */ "msr cpsr, r1" /* set new status */ : /* no output */ : "r" (key) /* input: key is %0 */ : "r0", "r1", "memory" /* r0, r1 clobbered; memory */ /* clobber for code barrier */ ); } static __inline__ int _inline_intCpuMicroLock (void) { int key; __asm__ volatile ( "mrs %0, cpsr; " /* get, return current status */ #ifdef _WRS_CONFIG_UNIFIED_FIQ_IRQ "orr r1, %0, #0xC0; " /* set I & F (1<<7 | 1<<6) */ #else "orr r1, %0, #0x80; " /* set I_BIT (1<<7) */ #endif /* _WRS_CONFIG_UNIFIED_FIQ_IRQ */ "msr cpsr_c, r1 " /* set new status */ : "=&r" (key) /* output: key is %0 */ : /* no input */ : "r1", "memory" /* r1 clobbered; memory */ /* clobber for code barrier */ ); return key; } static __inline__ void _inline_intCpuMicroUnlock (int key) { __asm__ volatile ( "msr cpsr_c, %0" /* restore previous status */ : /* no output */ : "r" (key) /* input: key is %0 */ /* no regs, memory clobbered */ ); } #else #define _inline_intCpuLock() intCpuLock() #define _inline_intCpuUnlock(key) intCpuUnlock(key) #define _inline_intCpuMicroLock() intCpuMicroLock() #define _inline_intCpuMicroUnlock(key) intCpuMicroUnlock(key) #endif /* __DCC__ */ #endif /* !ARM_THUMB */ /* functions in intArchLib.c and intALib.s */ extern STATUS intDisable (int); extern STATUS intEnable (int); extern STATUS intLibInit (int, int, int); extern int intIFLock (void); extern void intIFUnlock (int); #ifdef _WRS_CONFIG_UNIFIED_FIQ_IRQ extern int intILock (void); extern void intIUnlock (int); extern int intFLock (void); extern void intFUnlock (int); #endif /* _WRS_CONFIG_UNIFIED_FIQ_IRQ */ /* * Function pointers used in intArchLib.c and interrupt driver */ IMPORT FUNCPTR sysIntLvlVecChkRtn; IMPORT FUNCPTR sysIntLvlVecAckRtn; IMPORT FUNCPTR sysIntLvlChgRtn; IMPORT FUNCPTR sysIntLvlEnableRtn; IMPORT FUNCPTR sysIntLvlDisableRtn; /* * vxBus function pointers used in intArchLib.c and interrupt driver */ IMPORT FUNCPTR _func_IntLvlVecChkRtn; IMPORT FUNCPTR _func_IntLvlVecAckRtn; IMPORT FUNCPTR _func_IntLvlChgRtn; IMPORT FUNCPTR _func_IntLvlEnableRtn; IMPORT void * intCtlrDevID; IMPORT FUNCPTR _func_IntLvlDisableRtn; #endif /* _ASMLANGUAGE */ #ifdef __cplusplus } #endif #endif /* (CPU == ARMARCH7M) */ #endif /* __INCintArmLibh */