162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (C) 2014-15 Synopsys, Inc. (www.synopsys.com) 462306a36Sopenharmony_ci */ 562306a36Sopenharmony_ci 662306a36Sopenharmony_ci#ifndef __ASM_IRQFLAGS_ARCV2_H 762306a36Sopenharmony_ci#define __ASM_IRQFLAGS_ARCV2_H 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci#include <asm/arcregs.h> 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci/* status32 Bits */ 1262306a36Sopenharmony_ci#define STATUS_AD_BIT 19 /* Disable Align chk: core supports non-aligned */ 1362306a36Sopenharmony_ci#define STATUS_IE_BIT 31 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci#define STATUS_AD_MASK (1<<STATUS_AD_BIT) 1662306a36Sopenharmony_ci#define STATUS_IE_MASK (1<<STATUS_IE_BIT) 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci/* status32 Bits as encoded/expected by CLRI/SETI */ 1962306a36Sopenharmony_ci#define CLRI_STATUS_IE_BIT 4 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci#define CLRI_STATUS_E_MASK 0xF 2262306a36Sopenharmony_ci#define CLRI_STATUS_IE_MASK (1 << CLRI_STATUS_IE_BIT) 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_ci#define AUX_USER_SP 0x00D 2562306a36Sopenharmony_ci#define AUX_IRQ_CTRL 0x00E 2662306a36Sopenharmony_ci#define AUX_IRQ_ACT 0x043 /* Active Intr across all levels */ 2762306a36Sopenharmony_ci#define AUX_IRQ_LVL_PEND 0x200 /* Pending Intr across all levels */ 2862306a36Sopenharmony_ci#define AUX_IRQ_HINT 0x201 /* For generating Soft Interrupts */ 2962306a36Sopenharmony_ci#define AUX_IRQ_PRIORITY 0x206 3062306a36Sopenharmony_ci#define ICAUSE 0x40a 3162306a36Sopenharmony_ci#define AUX_IRQ_SELECT 0x40b 3262306a36Sopenharmony_ci#define AUX_IRQ_ENABLE 0x40c 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_ci/* Was Intr taken in User Mode */ 3562306a36Sopenharmony_ci#define AUX_IRQ_ACT_BIT_U 31 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_ci/* 3862306a36Sopenharmony_ci * Hardware supports 16 priorities (0 highest, 15 lowest) 3962306a36Sopenharmony_ci * Linux by default runs at 1, priority 0 reserved for NMI style interrupts 4062306a36Sopenharmony_ci */ 4162306a36Sopenharmony_ci#define ARCV2_IRQ_DEF_PRIO 1 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ci/* seed value for status register */ 4462306a36Sopenharmony_ci#ifdef CONFIG_ARC_USE_UNALIGNED_MEM_ACCESS 4562306a36Sopenharmony_ci#define __AD_ENB STATUS_AD_MASK 4662306a36Sopenharmony_ci#else 4762306a36Sopenharmony_ci#define __AD_ENB 0 4862306a36Sopenharmony_ci#endif 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_ci#define ISA_INIT_STATUS_BITS (STATUS_IE_MASK | __AD_ENB | \ 5162306a36Sopenharmony_ci (ARCV2_IRQ_DEF_PRIO << 1)) 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci#ifndef __ASSEMBLY__ 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_ci/* 5662306a36Sopenharmony_ci * Save IRQ state and disable IRQs 5762306a36Sopenharmony_ci */ 5862306a36Sopenharmony_cistatic inline long arch_local_irq_save(void) 5962306a36Sopenharmony_ci{ 6062306a36Sopenharmony_ci unsigned long flags; 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ci __asm__ __volatile__(" clri %0 \n" : "=r" (flags) : : "memory"); 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_ci return flags; 6562306a36Sopenharmony_ci} 6662306a36Sopenharmony_ci 6762306a36Sopenharmony_ci/* 6862306a36Sopenharmony_ci * restore saved IRQ state 6962306a36Sopenharmony_ci */ 7062306a36Sopenharmony_cistatic inline void arch_local_irq_restore(unsigned long flags) 7162306a36Sopenharmony_ci{ 7262306a36Sopenharmony_ci __asm__ __volatile__(" seti %0 \n" : : "r" (flags) : "memory"); 7362306a36Sopenharmony_ci} 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_ci/* 7662306a36Sopenharmony_ci * Unconditionally Enable IRQs 7762306a36Sopenharmony_ci */ 7862306a36Sopenharmony_cistatic inline void arch_local_irq_enable(void) 7962306a36Sopenharmony_ci{ 8062306a36Sopenharmony_ci unsigned int irqact = read_aux_reg(AUX_IRQ_ACT); 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_ci if (irqact & 0xffff) 8362306a36Sopenharmony_ci write_aux_reg(AUX_IRQ_ACT, irqact & ~0xffff); 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci __asm__ __volatile__(" seti \n" : : : "memory"); 8662306a36Sopenharmony_ci} 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_ci/* 8962306a36Sopenharmony_ci * Unconditionally Disable IRQs 9062306a36Sopenharmony_ci */ 9162306a36Sopenharmony_cistatic inline void arch_local_irq_disable(void) 9262306a36Sopenharmony_ci{ 9362306a36Sopenharmony_ci __asm__ __volatile__(" clri \n" : : : "memory"); 9462306a36Sopenharmony_ci} 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_ci/* 9762306a36Sopenharmony_ci * save IRQ state 9862306a36Sopenharmony_ci */ 9962306a36Sopenharmony_cistatic inline long arch_local_save_flags(void) 10062306a36Sopenharmony_ci{ 10162306a36Sopenharmony_ci unsigned long temp; 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_ci __asm__ __volatile__( 10462306a36Sopenharmony_ci " lr %0, [status32] \n" 10562306a36Sopenharmony_ci : "=&r"(temp) 10662306a36Sopenharmony_ci : 10762306a36Sopenharmony_ci : "memory"); 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_ci /* To be compatible with irq_save()/irq_restore() 11062306a36Sopenharmony_ci * encode the irq bits as expected by CLRI/SETI 11162306a36Sopenharmony_ci * (this was needed to make CONFIG_TRACE_IRQFLAGS work) 11262306a36Sopenharmony_ci */ 11362306a36Sopenharmony_ci temp = (1 << 5) | 11462306a36Sopenharmony_ci ((!!(temp & STATUS_IE_MASK)) << CLRI_STATUS_IE_BIT) | 11562306a36Sopenharmony_ci ((temp >> 1) & CLRI_STATUS_E_MASK); 11662306a36Sopenharmony_ci return temp; 11762306a36Sopenharmony_ci} 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_ci/* 12062306a36Sopenharmony_ci * Query IRQ state 12162306a36Sopenharmony_ci */ 12262306a36Sopenharmony_cistatic inline int arch_irqs_disabled_flags(unsigned long flags) 12362306a36Sopenharmony_ci{ 12462306a36Sopenharmony_ci return !(flags & CLRI_STATUS_IE_MASK); 12562306a36Sopenharmony_ci} 12662306a36Sopenharmony_ci 12762306a36Sopenharmony_cistatic inline int arch_irqs_disabled(void) 12862306a36Sopenharmony_ci{ 12962306a36Sopenharmony_ci return arch_irqs_disabled_flags(arch_local_save_flags()); 13062306a36Sopenharmony_ci} 13162306a36Sopenharmony_ci 13262306a36Sopenharmony_cistatic inline void arc_softirq_trigger(int irq) 13362306a36Sopenharmony_ci{ 13462306a36Sopenharmony_ci write_aux_reg(AUX_IRQ_HINT, irq); 13562306a36Sopenharmony_ci} 13662306a36Sopenharmony_ci 13762306a36Sopenharmony_cistatic inline void arc_softirq_clear(int irq) 13862306a36Sopenharmony_ci{ 13962306a36Sopenharmony_ci write_aux_reg(AUX_IRQ_HINT, 0); 14062306a36Sopenharmony_ci} 14162306a36Sopenharmony_ci 14262306a36Sopenharmony_ci#else 14362306a36Sopenharmony_ci 14462306a36Sopenharmony_ci#ifdef CONFIG_TRACE_IRQFLAGS 14562306a36Sopenharmony_ci 14662306a36Sopenharmony_ci.macro TRACE_ASM_IRQ_DISABLE 14762306a36Sopenharmony_ci bl trace_hardirqs_off 14862306a36Sopenharmony_ci.endm 14962306a36Sopenharmony_ci 15062306a36Sopenharmony_ci.macro TRACE_ASM_IRQ_ENABLE 15162306a36Sopenharmony_ci bl trace_hardirqs_on 15262306a36Sopenharmony_ci.endm 15362306a36Sopenharmony_ci 15462306a36Sopenharmony_ci#else 15562306a36Sopenharmony_ci 15662306a36Sopenharmony_ci.macro TRACE_ASM_IRQ_DISABLE 15762306a36Sopenharmony_ci.endm 15862306a36Sopenharmony_ci 15962306a36Sopenharmony_ci.macro TRACE_ASM_IRQ_ENABLE 16062306a36Sopenharmony_ci.endm 16162306a36Sopenharmony_ci 16262306a36Sopenharmony_ci#endif 16362306a36Sopenharmony_ci.macro IRQ_DISABLE scratch 16462306a36Sopenharmony_ci clri 16562306a36Sopenharmony_ci TRACE_ASM_IRQ_DISABLE 16662306a36Sopenharmony_ci.endm 16762306a36Sopenharmony_ci 16862306a36Sopenharmony_ci.macro IRQ_ENABLE scratch 16962306a36Sopenharmony_ci TRACE_ASM_IRQ_ENABLE 17062306a36Sopenharmony_ci seti 17162306a36Sopenharmony_ci.endm 17262306a36Sopenharmony_ci 17362306a36Sopenharmony_ci#endif /* __ASSEMBLY__ */ 17462306a36Sopenharmony_ci 17562306a36Sopenharmony_ci#endif 176