Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Based on arch/arm/kernel/irq.c
0004  *
0005  * Copyright (C) 1992 Linus Torvalds
0006  * Modifications for ARM processor Copyright (C) 1995-2000 Russell King.
0007  * Support for Dynamic Tick Timer Copyright (C) 2004-2005 Nokia Corporation.
0008  * Dynamic Tick Timer written by Tony Lindgren <tony@atomide.com> and
0009  * Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>.
0010  * Copyright (C) 2012 ARM Ltd.
0011  */
0012 
0013 #include <linux/irq.h>
0014 #include <linux/memory.h>
0015 #include <linux/smp.h>
0016 #include <linux/hardirq.h>
0017 #include <linux/init.h>
0018 #include <linux/irqchip.h>
0019 #include <linux/kprobes.h>
0020 #include <linux/scs.h>
0021 #include <linux/seq_file.h>
0022 #include <linux/vmalloc.h>
0023 #include <asm/daifflags.h>
0024 #include <asm/vmap_stack.h>
0025 
0026 /* Only access this in an NMI enter/exit */
0027 DEFINE_PER_CPU(struct nmi_ctx, nmi_contexts);
0028 
0029 DEFINE_PER_CPU(unsigned long *, irq_stack_ptr);
0030 
0031 
0032 DECLARE_PER_CPU(unsigned long *, irq_shadow_call_stack_ptr);
0033 
0034 #ifdef CONFIG_SHADOW_CALL_STACK
0035 DEFINE_PER_CPU(unsigned long *, irq_shadow_call_stack_ptr);
0036 #endif
0037 
0038 static void init_irq_scs(void)
0039 {
0040     int cpu;
0041 
0042     if (!IS_ENABLED(CONFIG_SHADOW_CALL_STACK))
0043         return;
0044 
0045     for_each_possible_cpu(cpu)
0046         per_cpu(irq_shadow_call_stack_ptr, cpu) =
0047             scs_alloc(cpu_to_node(cpu));
0048 }
0049 
0050 #ifdef CONFIG_VMAP_STACK
0051 static void init_irq_stacks(void)
0052 {
0053     int cpu;
0054     unsigned long *p;
0055 
0056     for_each_possible_cpu(cpu) {
0057         p = arch_alloc_vmap_stack(IRQ_STACK_SIZE, cpu_to_node(cpu));
0058         per_cpu(irq_stack_ptr, cpu) = p;
0059     }
0060 }
0061 #else
0062 /* irq stack only needs to be 16 byte aligned - not IRQ_STACK_SIZE aligned. */
0063 DEFINE_PER_CPU_ALIGNED(unsigned long [IRQ_STACK_SIZE/sizeof(long)], irq_stack);
0064 
0065 static void init_irq_stacks(void)
0066 {
0067     int cpu;
0068 
0069     for_each_possible_cpu(cpu)
0070         per_cpu(irq_stack_ptr, cpu) = per_cpu(irq_stack, cpu);
0071 }
0072 #endif
0073 
0074 static void default_handle_irq(struct pt_regs *regs)
0075 {
0076     panic("IRQ taken without a root IRQ handler\n");
0077 }
0078 
0079 static void default_handle_fiq(struct pt_regs *regs)
0080 {
0081     panic("FIQ taken without a root FIQ handler\n");
0082 }
0083 
0084 void (*handle_arch_irq)(struct pt_regs *) __ro_after_init = default_handle_irq;
0085 void (*handle_arch_fiq)(struct pt_regs *) __ro_after_init = default_handle_fiq;
0086 
0087 int __init set_handle_irq(void (*handle_irq)(struct pt_regs *))
0088 {
0089     if (handle_arch_irq != default_handle_irq)
0090         return -EBUSY;
0091 
0092     handle_arch_irq = handle_irq;
0093     pr_info("Root IRQ handler: %ps\n", handle_irq);
0094     return 0;
0095 }
0096 
0097 int __init set_handle_fiq(void (*handle_fiq)(struct pt_regs *))
0098 {
0099     if (handle_arch_fiq != default_handle_fiq)
0100         return -EBUSY;
0101 
0102     handle_arch_fiq = handle_fiq;
0103     pr_info("Root FIQ handler: %ps\n", handle_fiq);
0104     return 0;
0105 }
0106 
0107 void __init init_IRQ(void)
0108 {
0109     init_irq_stacks();
0110     init_irq_scs();
0111     irqchip_init();
0112 
0113     if (system_uses_irq_prio_masking()) {
0114         /*
0115          * Now that we have a stack for our IRQ handler, set
0116          * the PMR/PSR pair to a consistent state.
0117          */
0118         WARN_ON(read_sysreg(daif) & PSR_A_BIT);
0119         local_daif_restore(DAIF_PROCCTX_NOIRQ);
0120     }
0121 }