1 /*
2 * Copyright (c) 2013-2015, Wind River Systems, Inc.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 /**
8 * @file
9 * @brief system module for variants with LOAPIC
10 *
11 */
12
13 #include <sys/__assert.h>
14 #include <kernel.h>
15 #include <arch/cpu.h>
16 #include <drivers/interrupt_controller/ioapic.h>
17 #include <drivers/interrupt_controller/loapic.h>
18 #include <drivers/interrupt_controller/sysapic.h>
19 #include <irq.h>
20 #include <linker/sections.h>
21
22 #define IS_IOAPIC_IRQ(irq) (irq < z_loapic_irq_base())
23 #define HARDWARE_IRQ_LIMIT ((z_loapic_irq_base() + LOAPIC_IRQ_COUNT) - 1)
24
25 /**
26 *
27 * @brief Program interrupt controller
28 *
29 * This routine programs the interrupt controller with the given vector
30 * based on the given IRQ parameter.
31 *
32 * Drivers call this routine instead of IRQ_CONNECT() when interrupts are
33 * configured statically.
34 *
35 * The Galileo board virtualizes IRQs as follows:
36 *
37 * - The first z_ioapic_num_rtes() IRQs are provided by the IOAPIC so the
38 * IOAPIC is programmed for these IRQs
39 * - The remaining IRQs are provided by the LOAPIC and hence the LOAPIC is
40 * programmed.
41 *
42 * @param vector the vector number
43 * @param irq the virtualized IRQ
44 * @param flags interrupt flags
45 *
46 */
47 __boot_func
z_irq_controller_irq_config(unsigned int vector,unsigned int irq,uint32_t flags)48 void z_irq_controller_irq_config(unsigned int vector, unsigned int irq,
49 uint32_t flags)
50 {
51 __ASSERT(irq <= HARDWARE_IRQ_LIMIT, "invalid irq line");
52
53 if (IS_IOAPIC_IRQ(irq)) {
54 z_ioapic_irq_set(irq, vector, flags);
55 } else {
56 z_loapic_int_vec_set(irq - z_loapic_irq_base(), vector);
57 }
58 }
59
60 /**
61 *
62 * @brief Enable an individual interrupt (IRQ)
63 *
64 * The public interface for enabling/disabling a specific IRQ for the IA-32
65 * architecture is defined as follows in include/arch/x86/arch.h
66 *
67 * extern void irq_enable (unsigned int irq);
68 * extern void irq_disable (unsigned int irq);
69 *
70 * The irq_enable() routine is provided by the interrupt controller driver due
71 * to the IRQ virtualization that is performed by this platform. See the
72 * comments in _interrupt_vector_allocate() for more information regarding IRQ
73 * virtualization.
74 *
75 * @return N/A
76 */
77 __pinned_func
arch_irq_enable(unsigned int irq)78 void arch_irq_enable(unsigned int irq)
79 {
80 if (IS_IOAPIC_IRQ(irq)) {
81 z_ioapic_irq_enable(irq);
82 } else {
83 z_loapic_irq_enable(irq - z_loapic_irq_base());
84 }
85 }
86
87 /**
88 *
89 * @brief Disable an individual interrupt (IRQ)
90 *
91 * The irq_disable() routine is provided by the interrupt controller driver due
92 * to the IRQ virtualization that is performed by this platform. See the
93 * comments in _interrupt_vector_allocate() for more information regarding IRQ
94 * virtualization.
95 *
96 * @return N/A
97 */
98 __pinned_func
arch_irq_disable(unsigned int irq)99 void arch_irq_disable(unsigned int irq)
100 {
101 if (IS_IOAPIC_IRQ(irq)) {
102 z_ioapic_irq_disable(irq);
103 } else {
104 z_loapic_irq_disable(irq - z_loapic_irq_base());
105 }
106 }
107