2015-03-06 14:08:20 +05:30
/*
* Copyright ( C ) 2014 - 15 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_ARCV2_H
# define __ASM_IRQFLAGS_ARCV2_H
# include <asm/arcregs.h>
/* status32 Bits */
# define STATUS_AD_BIT 19 /* Disable Align chk: core supports non-aligned */
# define STATUS_IE_BIT 31
# define STATUS_AD_MASK (1<<STATUS_AD_BIT)
# define STATUS_IE_MASK (1<<STATUS_IE_BIT)
2016-03-23 12:26:52 +03:00
/* status32 Bits as encoded/expected by CLRI/SETI */
# define CLRI_STATUS_IE_BIT 4
# define CLRI_STATUS_E_MASK 0xF
# define CLRI_STATUS_IE_MASK (1 << CLRI_STATUS_IE_BIT)
2015-03-06 14:08:20 +05:30
# define AUX_USER_SP 0x00D
# define AUX_IRQ_CTRL 0x00E
# define AUX_IRQ_ACT 0x043 /* Active Intr across all levels */
# define AUX_IRQ_LVL_PEND 0x200 /* Pending Intr across all levels */
2016-02-23 11:55:16 +05:30
# define AUX_IRQ_HINT 0x201 /* For generating Soft Interrupts */
2015-03-06 14:08:20 +05:30
# define AUX_IRQ_PRIORITY 0x206
# define ICAUSE 0x40a
# define AUX_IRQ_SELECT 0x40b
# define AUX_IRQ_ENABLE 0x40c
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
/* Was Intr taken in User Mode */
# define AUX_IRQ_ACT_BIT_U 31
2016-02-07 12:54:35 +05:30
/*
2016-09-30 16:13:28 -07:00
* Hardware supports 16 priorities ( 0 highest , 15 lowest )
* Linux by default runs at 1 , priority 0 reserved for NMI style interrupts
2016-02-07 12:54:35 +05:30
*/
2016-09-30 16:13:28 -07:00
# define ARCV2_IRQ_DEF_PRIO 1
2015-03-06 14:08:20 +05:30
/* seed value for status register */
# define ISA_INIT_STATUS_BITS (STATUS_IE_MASK | STATUS_AD_MASK | \
( ARCV2_IRQ_DEF_PRIO < < 1 ) )
# ifndef __ASSEMBLY__
/*
* Save IRQ state and disable IRQs
*/
static inline long arch_local_irq_save ( void )
{
unsigned long flags ;
__asm__ __volatile__ ( " clri %0 \n " : " =r " ( flags ) : : " memory " ) ;
return flags ;
}
/*
* restore saved IRQ state
*/
static inline void arch_local_irq_restore ( unsigned long flags )
{
__asm__ __volatile__ ( " seti %0 \n " : : " r " ( flags ) : " memory " ) ;
}
/*
* Unconditionally Enable IRQs
*/
static inline void arch_local_irq_enable ( void )
{
2014-11-15 17:00:08 +05:30
unsigned int irqact = read_aux_reg ( AUX_IRQ_ACT ) ;
if ( irqact & 0xffff )
write_aux_reg ( AUX_IRQ_ACT , irqact & ~ 0xffff ) ;
2015-03-06 14:08:20 +05:30
__asm__ __volatile__ ( " seti \n " : : : " memory " ) ;
}
/*
* Unconditionally Disable IRQs
*/
static inline void arch_local_irq_disable ( void )
{
__asm__ __volatile__ ( " clri \n " : : : " memory " ) ;
}
/*
* save IRQ state
*/
static inline long arch_local_save_flags ( void )
{
unsigned long temp ;
__asm__ __volatile__ (
" lr %0, [status32] \n "
: " =&r " ( temp )
:
: " memory " ) ;
2016-03-23 12:26:52 +03:00
/* To be compatible with irq_save()/irq_restore()
* encode the irq bits as expected by CLRI / SETI
* ( this was needed to make CONFIG_TRACE_IRQFLAGS work )
*/
temp = ( 1 < < 5 ) |
( ( ! ! ( temp & STATUS_IE_MASK ) ) < < CLRI_STATUS_IE_BIT ) |
2016-09-30 13:27:25 -07:00
( ( temp > > 1 ) & CLRI_STATUS_E_MASK ) ;
2015-03-06 14:08:20 +05:30
return temp ;
}
/*
* Query IRQ state
*/
static inline int arch_irqs_disabled_flags ( unsigned long flags )
{
2016-03-23 12:26:52 +03:00
return ! ( flags & CLRI_STATUS_IE_MASK ) ;
2015-03-06 14:08:20 +05:30
}
static inline int arch_irqs_disabled ( void )
{
return arch_irqs_disabled_flags ( arch_local_save_flags ( ) ) ;
}
2016-02-23 11:55:16 +05:30
static inline void arc_softirq_trigger ( int irq )
{
write_aux_reg ( AUX_IRQ_HINT , irq ) ;
}
static inline void arc_softirq_clear ( int irq )
{
write_aux_reg ( AUX_IRQ_HINT , 0 ) ;
}
2015-03-06 14:08:20 +05:30
# else
2016-03-23 12:26:52 +03:00
# 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
2015-03-06 14:08:20 +05:30
. macro IRQ_DISABLE scratch
clri
2016-03-23 12:26:52 +03:00
TRACE_ASM_IRQ_DISABLE
2015-03-06 14:08:20 +05:30
. endm
. macro IRQ_ENABLE scratch
2016-03-23 12:26:52 +03:00
TRACE_ASM_IRQ_ENABLE
2015-03-06 14:08:20 +05:30
seti
. endm
# endif /* __ASSEMBLY__ */
# endif