|
AquilaOS documentation
How it works, and its code
|
x86: devices' interrupts (IRQs), whichever controller brings them: the 8259s or the APIC, each an x86_irq_chip. More...
#include <core/system.h>#include <core/arch.h>#include <core/panic.h>#include <core/string.h>#include <cpu/cpu.h>#include <dev/irq.h>#include <platform/misc.h>#include <sys/sched.h>#include <sys/signal.h>#include <sys/lock.h>#include <mm/pmap.h>Go to the source code of this file.
Data Structures | |
| struct | handler |
| An installed handler, on its interrupt's list. More... | |
| struct | [struct].irqs |
Functions | |
| static struct x86_irq_chip * | chip_of (unsigned irq) |
| Returns the controller of an IRQ: its own, or the system's. | |
| void | x86_irq_chip_set (struct x86_irq_chip *c) |
| Sets the system's interrupt controller. | |
| const char * | x86_irq_chip_name (void) |
| Returns the name of the system's interrupt controller. | |
| void | x86_irq_alloc_from (unsigned first) |
| Sets the first IRQ that x86_irq_alloc() may give: past the I/O APICs' last pin. | |
| int | x86_irq_alloc (struct x86_irq_chip *c) |
| Gives a free IRQ with a controller of its own, for an MSI. | |
| int | irq_install (unsigned irq, irq_handler_t fn, void *arg) |
| Installs a handler for an IRQ. | |
| void | irq_uninstall (unsigned irq, irq_handler_t fn, void *arg) |
| Removes a handler that irq_install() installed. | |
| void | x86_irq_tick_switch (void) |
| Asks for a thread switch once the current interrupt is done: the tick calls it. | |
| static void | irq_handle (struct x86_regs *r) |
| Runs an interrupt's handlers, then tells its controller that it is done. | |
| static void | irq_dispatch (struct x86_regs *r) |
| Handles an interrupt, then switches threads if the tick asked for it or an urgent thread was woken, and returns to what was interrupted. | |
| void | __x86_irq_handler (struct x86_regs *r) |
| Handles an interrupt: a device's, the tick, or an IPI. | |
| void | x86_irq_gates_setup (void) |
| Sets the IDT's gates for the interrupts: vectors 32 to 79, the local APIC's timer, the TLB and wake IPIs, and its spurious interrupt. | |
| int | arch_interrupts_info (char *buf, size_t size) |
| Writes /proc/interrupts: the controller, then how many times each IRQ with handlers came, and how many TLB flushes each CPU did for another. | |
Variables | |
| static struct | irqs [X86_IRQ_NR] |
| static struct x86_irq_chip * | chip |
| static unsigned | alloc_first = X86_IRQ_TIMER |
x86: devices' interrupts (IRQs), whichever controller brings them: the 8259s or the APIC, each an x86_irq_chip.
IRQ n is vector 32 + n. With the 8259s, the IRQs are the ISA bus's 16. With the APIC, they are what the I/O APICs route from their pins: the ISA IRQs too (on the pins the MADT says), and PCI devices' lines (from their configuration space). The local APIC's timer, vector 240, is an IRQ of its own here (X86_IRQ_TIMER).
An IRQ may have several handlers, because a PCI line can be shared: each is called, and each looks at its own device. An IRQ may also have a controller of its own: an MSI's is the device itself (x86_irq_alloc() gives those IRQs, above the I/O APICs' pins).
After the handlers, the controller is told that the interrupt is done (the EOI; a level-triggered line would raise it again before). Only then may what the interrupt woke up run (an urgent thread, or the thread switch the tick asked for).
Definition in file irq.c.
| void __x86_irq_handler | ( | struct x86_regs * | r | ) |
Handles an interrupt: a device's, the tick, or an IPI.
The stubs in cpu.S call it. It takes the kernel lock if it came from user mode or the idle loop (in the kernel, the lock is held already), and lets go of it on the way back. The TLB IPI is handled without the lock, because the CPU that sent it holds it, waiting.
| r | the interrupted registers, saved on the kernel stack |
Definition at line 237 of file irq.c.
References __x86_irq_handler(), curthread, irq_dispatch(), irq_handle(), kernel_enter(), kernel_leave(), sched_thread_killed(), x86_regs::vec, x86_lapic_eoi(), x86_lapic_timer_cpu_start(), x86_tlb_ipi(), X86_TLB_VECTOR, and X86_WAKE_VECTOR.
Referenced by __x86_irq_handler().
| int arch_interrupts_info | ( | char * | buf, |
| size_t | size ) |
Writes /proc/interrupts: the controller, then how many times each IRQ with handlers came, and how many TLB flushes each CPU did for another.
| buf | where to write it |
| size | the buffer's size |
Definition at line 310 of file irq.c.
References arch_interrupts_info(), chip, chip_of(), cpus, cpus_count, x86_irq_chip::describe, handlers, irqs, snprintf(), x86_irq_chip::timer, x86_irq_chip_name(), X86_IRQ_NR, and X86_IRQ_TIMER.
|
static |
Returns the controller of an IRQ: its own, or the system's.
Definition at line 57 of file irq.c.
References chip, chip_of(), and irqs.
Referenced by arch_interrupts_info(), chip_of(), irq_handle(), irq_install(), and irq_uninstall().
|
static |
Handles an interrupt, then switches threads if the tick asked for it or an urgent thread was woken, and returns to what was interrupted.
Definition at line 197 of file irq.c.
References x86_regs::cs, curthread, irq_dispatch(), irq_handle(), sched_idle_wakeup(), sched_urgent, schedule(), and x86_return_to_user().
Referenced by __x86_irq_handler(), and irq_dispatch().
|
static |
Runs an interrupt's handlers, then tells its controller that it is done.
Definition at line 176 of file irq.c.
References chip, chip_of(), x86_irq_chip::eoi, handlers, irq_handle(), irqs, x86_regs::vec, X86_IRQ_NR, X86_IRQ_TIMER, and X86_TIMER_VECTOR.
| int irq_install | ( | unsigned | irq, |
| irq_handler_t | fn, | ||
| void * | arg ) |
Installs a handler for an IRQ.
The first handler installed unmasks the IRQ at its interrupt controller.
| irq | the IRQ, the platform's number for it |
| fn | the handler |
| arg | the argument the handler is called with |
Definition at line 115 of file irq.c.
References handler::arg, chip_of(), handler::fn, irq_install(), irqs, kmalloc(), M_ZERO, handler::next, x86_irq_chip::unmask, X86_IRQ_NR, and X86_IRQ_TIMER.
| void irq_uninstall | ( | unsigned | irq, |
| irq_handler_t | fn, | ||
| void * | arg ) |
Removes a handler that irq_install() installed.
The last handler removed masks the IRQ at its interrupt controller.
| irq | the IRQ |
| fn | the handler, as it was installed |
| arg | its argument, as it was installed |
Definition at line 147 of file irq.c.
References handler::arg, chip_of(), handler::fn, handlers, irq_uninstall(), irqs, kfree(), x86_irq_chip::mask, handler::next, X86_IRQ_NR, and X86_IRQ_TIMER.
| int x86_irq_alloc | ( | struct x86_irq_chip * | c | ) |
Gives a free IRQ with a controller of its own, for an MSI.
| c | the IRQ's controller |
Definition at line 99 of file irq.c.
References alloc_first, chip, handlers, irqs, x86_irq_alloc(), and X86_IRQ_TIMER.
Referenced by arch_msi_alloc(), and x86_irq_alloc().
| void x86_irq_alloc_from | ( | unsigned | first | ) |
Sets the first IRQ that x86_irq_alloc() may give: past the I/O APICs' last pin.
| first | the first IRQ |
Definition at line 88 of file irq.c.
References alloc_first, and x86_irq_alloc_from().
Referenced by x86_apic_setup(), and x86_irq_alloc_from().
| const char * x86_irq_chip_name | ( | void | ) |
Returns the name of the system's interrupt controller.
Definition at line 77 of file irq.c.
References chip, x86_irq_chip::name, and x86_irq_chip_name().
Referenced by arch_interrupts_info(), x86_irq_chip_name(), and x86_pc_irq_init().
| void x86_irq_chip_set | ( | struct x86_irq_chip * | c | ) |
Sets the system's interrupt controller.
| c | the controller: the 8259s or the APIC |
Definition at line 67 of file irq.c.
References chip, and x86_irq_chip_set().
Referenced by x86_apic_setup(), x86_irq_chip_set(), and x86_pc_irq_init().
| void x86_irq_gates_setup | ( | void | ) |
Sets the IDT's gates for the interrupts: vectors 32 to 79, the local APIC's timer, the TLB and wake IPIs, and its spurious interrupt.
Definition at line 266 of file irq.c.
References x86_idt_gate_set(), x86_irq_gates_setup(), X86_SPURIOUS_VECTOR, X86_TIMER_VECTOR, X86_TLB_VECTOR, and X86_WAKE_VECTOR.
Referenced by x86_irq_gates_setup(), and x86_pc_irq_init().
| void x86_irq_tick_switch | ( | void | ) |
Asks for a thread switch once the current interrupt is done: the tick calls it.
Definition at line 169 of file irq.c.
References x86_irq_tick_switch().
Referenced by x86_irq_tick_switch(), and x86_sched_handler().
|
static |
Definition at line 54 of file irq.c.
Referenced by x86_irq_alloc(), and x86_irq_alloc_from().
|
static |
Definition at line 51 of file irq.c.
Referenced by arch_interrupts_info(), chip_of(), irq_handle(), x86_irq_alloc(), x86_irq_chip_name(), and x86_irq_chip_set().
| struct [struct].irqs irqs[X86_IRQ_NR] |
Referenced by arch_interrupts_info(), chip_of(), irq_handle(), irq_install(), irq_uninstall(), and x86_irq_alloc().