2015-03-05 19:13:56 +05:30
/*
* Copyright ( C ) 2014 - 15 Synopsys , Inc . ( www . synopsys . com )
* Copyright ( C ) 2004 , 2007 - 2010 , 2011 - 2012 Synopsys , Inc . ( www . synopsys . com )
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation .
*/
# ifndef __ASM_IRQFLAGS_ARCOMPACT_H
# define __ASM_IRQFLAGS_ARCOMPACT_H
/* vineetg: March 2010 : local_irq_save( ) optimisation
* - Remove explicit mov of current status32 into reg , that is not needed
* - Use BIC insn instead of INVERTED + AND
* - Conditionally disable interrupts ( if they are not enabled , don ' t disable )
*/
# include <asm/arcregs.h>
/* status32 Reg bits related to Interrupt Handling */
# define STATUS_E1_BIT 1 /* Int 1 enable */
# define STATUS_E2_BIT 2 /* Int 2 enable */
# define STATUS_A1_BIT 3 /* Int 1 active */
# define STATUS_A2_BIT 4 /* Int 2 active */
2015-09-05 23:08:31 +05:30
# define STATUS_AE_BIT 5 /* Exception active */
2015-03-05 19:13:56 +05:30
# define STATUS_E1_MASK (1<<STATUS_E1_BIT)
# define STATUS_E2_MASK (1<<STATUS_E2_BIT)
# define STATUS_A1_MASK (1<<STATUS_A1_BIT)
# define STATUS_A2_MASK (1<<STATUS_A2_BIT)
2015-09-05 23:08:31 +05:30
# define STATUS_AE_MASK (1<<STATUS_AE_BIT)
2015-03-05 19:13:56 +05:30
# define STATUS_IE_MASK (STATUS_E1_MASK | STATUS_E2_MASK)
/* Other Interrupt Handling related Aux regs */
# define AUX_IRQ_LEV 0x200 /* IRQ Priority: L1 or L2 */
# define AUX_IRQ_HINT 0x201 /* For generating Soft Interrupts */
# define AUX_IRQ_LV12 0x43 /* interrupt level register */
# define AUX_IENABLE 0x40c
# define AUX_ITRIGGER 0x40d
# define AUX_IPULSE 0x415
ARCv2: Support for ARCv2 ISA and HS38x cores
The notable features are:
- SMP configurations of upto 4 cores with coherency
- Optional L2 Cache and IO-Coherency
- Revised Interrupt Architecture (multiple priorites, reg banks,
auto stack switch, auto regfile save/restore)
- MMUv4 (PIPT dcache, Huge Pages)
- Instructions for
* 64bit load/store: LDD, STD
* Hardware assisted divide/remainder: DIV, REM
* Function prologue/epilogue: ENTER_S, LEAVE_S
* IRQ enable/disable: CLRI, SETI
* pop count: FFS, FLS
* SETcc, BMSKN, XBFU...
Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
2013-05-13 18:30:41 +05:30
# define ISA_INIT_STATUS_BITS STATUS_IE_MASK
2015-11-16 13:52:07 +05:30
# define ISA_SLEEP_ARG 0x3
2015-03-05 19:13:56 +05:30
# ifndef __ASSEMBLY__
/******************************************************************
* IRQ Control Macros
*
* All of them have " memory " clobber ( compiler barrier ) which is needed to
* ensure that LD / ST requiring irq safetly ( R - M - W when LLSC is not available )
* are redone after IRQs are re - enabled ( and gcc doesn ' t reuse stale register )
*
* Noted at the time of Abilis Timer List corruption
* Orig Bug + Rejected solution : https : //lkml.org/lkml/2013/3/29/67
* Reasoning : https : //lkml.org/lkml/2013/4/8/15
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* Save IRQ state and disable IRQs
*/
static inline long arch_local_irq_save ( void )
{
unsigned long temp , flags ;
__asm__ __volatile__ (
" lr %1, [status32] \n "
" bic %0, %1, %2 \n "
" and.f 0, %1, %2 \n "
" flag.nz %0 \n "
: " =r " ( temp ) , " =r " ( flags )
: " n " ( ( STATUS_E1_MASK | STATUS_E2_MASK ) )
: " memory " , " cc " ) ;
return flags ;
}
/*
* restore saved IRQ state
*/
static inline void arch_local_irq_restore ( unsigned long flags )
{
__asm__ __volatile__ (
" flag %0 \n "
:
: " r " ( flags )
: " memory " ) ;
}
/*
* Unconditionally Enable IRQs
*/
2015-09-05 22:47:30 +05:30
static inline void arch_local_irq_enable ( void )
{
unsigned long temp ;
__asm__ __volatile__ (
" lr %0, [status32] \n "
" or %0, %0, %1 \n "
" flag %0 \n "
: " =&r " ( temp )
: " n " ( ( STATUS_E1_MASK | STATUS_E2_MASK ) )
: " cc " , " memory " ) ;
}
2015-03-05 19:13:56 +05:30
/*
* Unconditionally Disable IRQs
*/
static inline void arch_local_irq_disable ( void )
{
unsigned long temp ;
__asm__ __volatile__ (
" lr %0, [status32] \n "
" and %0, %0, %1 \n "
" flag %0 \n "
: " =&r " ( temp )
: " n " ( ~ ( STATUS_E1_MASK | STATUS_E2_MASK ) )
: " memory " ) ;
}
/*
* save IRQ state
*/
static inline long arch_local_save_flags ( void )
{
unsigned long temp ;
__asm__ __volatile__ (
" lr %0, [status32] \n "
: " =&r " ( temp )
:
: " memory " ) ;
return temp ;
}
/*
* Query IRQ state
*/
static inline int arch_irqs_disabled_flags ( unsigned long flags )
{
return ! ( flags & ( STATUS_E1_MASK
# ifdef CONFIG_ARC_COMPACT_IRQ_LEVELS
| STATUS_E2_MASK
# endif
) ) ;
}
static inline int arch_irqs_disabled ( void )
{
return arch_irqs_disabled_flags ( arch_local_save_flags ( ) ) ;
}
# else
# ifdef CONFIG_TRACE_IRQFLAGS
. macro TRACE_ASM_IRQ_DISABLE
bl trace_hardirqs_off
. endm
. macro TRACE_ASM_IRQ_ENABLE
bl trace_hardirqs_on
. endm
# else
. macro TRACE_ASM_IRQ_DISABLE
. endm
. macro TRACE_ASM_IRQ_ENABLE
. endm
# endif
. macro IRQ_DISABLE scratch
lr \ scratch , [ status32 ]
bic \ scratch , \ scratch , ( STATUS_E1_MASK | STATUS_E2_MASK )
flag \ scratch
TRACE_ASM_IRQ_DISABLE
. endm
. macro IRQ_ENABLE scratch
2016-08-04 17:56:53 -07:00
TRACE_ASM_IRQ_ENABLE
2015-03-05 19:13:56 +05:30
lr \ scratch , [ status32 ]
or \ scratch , \ scratch , ( STATUS_E1_MASK | STATUS_E2_MASK )
flag \ scratch
. endm
# endif /* __ASSEMBLY__ */
# endif