1 #ifndef __ASM_IRQ_H 2 #define __ASM_IRQ_H 3 4 #define IRQ_STACK_SIZE THREAD_SIZE 5 #define IRQ_STACK_START_SP THREAD_START_SP 6 7 #ifndef __ASSEMBLER__ 8 9 #include <linux/percpu.h> 10 11 #include <asm-generic/irq.h> 12 #include <asm/thread_info.h> 13 14 struct pt_regs; 15 16 DECLARE_PER_CPU(unsigned long [IRQ_STACK_SIZE/sizeof(long)], irq_stack); 17 18 /* 19 * The highest address on the stack, and the first to be used. Used to 20 * find the dummy-stack frame put down by el?_irq() in entry.S, which 21 * is structured as follows: 22 * 23 * ------------ 24 * | | <- irq_stack_ptr 25 * top ------------ 26 * | x19 | <- irq_stack_ptr - 0x08 27 * ------------ 28 * | x29 | <- irq_stack_ptr - 0x10 29 * ------------ 30 * 31 * where x19 holds a copy of the task stack pointer where the struct pt_regs 32 * from kernel_entry can be found. 33 * 34 */ 35 #define IRQ_STACK_PTR(cpu) ((unsigned long)per_cpu(irq_stack, cpu) + IRQ_STACK_START_SP) 36 37 /* 38 * The offset from irq_stack_ptr where entry.S will store the original 39 * stack pointer. Used by unwind_frame() and dump_backtrace(). 40 */ 41 #define IRQ_STACK_TO_TASK_STACK(ptr) (*((unsigned long *)((ptr) - 0x08))) 42 43 extern void set_handle_irq(void (*handle_irq)(struct pt_regs *)); 44 45 static inline int nr_legacy_irqs(void) 46 { 47 return 0; 48 } 49 50 static inline bool on_irq_stack(unsigned long sp, int cpu) 51 { 52 /* variable names the same as kernel/stacktrace.c */ 53 unsigned long low = (unsigned long)per_cpu(irq_stack, cpu); 54 unsigned long high = low + IRQ_STACK_START_SP; 55 56 return (low <= sp && sp <= high); 57 } 58 59 #endif /* !__ASSEMBLER__ */ 60 #endif 61