1 /* 2 * Copyright (C) 2012 ARM Ltd. 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License version 2 as 6 * published by the Free Software Foundation. 7 * 8 * This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU General Public License for more details. 12 * 13 * You should have received a copy of the GNU General Public License 14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 15 */ 16 #ifndef __ASM_IRQFLAGS_H 17 #define __ASM_IRQFLAGS_H 18 19 #ifdef __KERNEL__ 20 21 #include <asm/ptrace.h> 22 23 /* 24 * CPU interrupt mask handling. 25 */ 26 static inline unsigned long arch_local_irq_save(void) 27 { 28 unsigned long flags; 29 asm volatile( 30 "mrs %0, daif // arch_local_irq_save\n" 31 "msr daifset, #2" 32 : "=r" (flags) 33 : 34 : "memory"); 35 return flags; 36 } 37 38 static inline void arch_local_irq_enable(void) 39 { 40 asm volatile( 41 "msr daifclr, #2 // arch_local_irq_enable" 42 : 43 : 44 : "memory"); 45 } 46 47 static inline void arch_local_irq_disable(void) 48 { 49 asm volatile( 50 "msr daifset, #2 // arch_local_irq_disable" 51 : 52 : 53 : "memory"); 54 } 55 56 #define local_fiq_enable() asm("msr daifclr, #1" : : : "memory") 57 #define local_fiq_disable() asm("msr daifset, #1" : : : "memory") 58 59 #define local_async_enable() asm("msr daifclr, #4" : : : "memory") 60 #define local_async_disable() asm("msr daifset, #4" : : : "memory") 61 62 /* 63 * Save the current interrupt enable state. 64 */ 65 static inline unsigned long arch_local_save_flags(void) 66 { 67 unsigned long flags; 68 asm volatile( 69 "mrs %0, daif // arch_local_save_flags" 70 : "=r" (flags) 71 : 72 : "memory"); 73 return flags; 74 } 75 76 /* 77 * restore saved IRQ state 78 */ 79 static inline void arch_local_irq_restore(unsigned long flags) 80 { 81 asm volatile( 82 "msr daif, %0 // arch_local_irq_restore" 83 : 84 : "r" (flags) 85 : "memory"); 86 } 87 88 static inline int arch_irqs_disabled_flags(unsigned long flags) 89 { 90 return flags & PSR_I_BIT; 91 } 92 93 /* 94 * save and restore debug state 95 */ 96 #define local_dbg_save(flags) \ 97 do { \ 98 typecheck(unsigned long, flags); \ 99 asm volatile( \ 100 "mrs %0, daif // local_dbg_save\n" \ 101 "msr daifset, #8" \ 102 : "=r" (flags) : : "memory"); \ 103 } while (0) 104 105 #define local_dbg_restore(flags) \ 106 do { \ 107 typecheck(unsigned long, flags); \ 108 asm volatile( \ 109 "msr daif, %0 // local_dbg_restore\n" \ 110 : : "r" (flags) : "memory"); \ 111 } while (0) 112 113 #endif 114 #endif 115