129 int first = !
irqs[irq].handlers;
171 curcpu()->arch.tick_switch = 1;
183 curcpu()->arch.irq_regs = r;
203 if (curcpu()->arch.tick_switch) {
204 curcpu()->arch.tick_switch = 0;
206 if (curcpu()->idle) {
209 extern void x86_preempt(
void);
219 extern void x86_preempt(
void);
268 extern void __x86_irq0(
void), __x86_irq1(
void), __x86_irq2(
void), __x86_irq3(
void),
269 __x86_irq4(
void), __x86_irq5(
void), __x86_irq6(
void), __x86_irq7(
void),
270 __x86_irq8(
void), __x86_irq9(
void), __x86_irq10(
void), __x86_irq11(
void),
271 __x86_irq12(
void), __x86_irq13(
void), __x86_irq14(
void), __x86_irq15(
void),
272 __x86_irq16(
void), __x86_irq17(
void), __x86_irq18(
void), __x86_irq19(
void),
273 __x86_irq20(
void), __x86_irq21(
void), __x86_irq22(
void), __x86_irq23(
void),
274 __x86_irq24(
void), __x86_irq25(
void), __x86_irq26(
void), __x86_irq27(
void),
275 __x86_irq28(
void), __x86_irq29(
void), __x86_irq30(
void), __x86_irq31(
void),
276 __x86_irq32(
void), __x86_irq33(
void), __x86_irq34(
void), __x86_irq35(
void),
277 __x86_irq36(
void), __x86_irq37(
void), __x86_irq38(
void), __x86_irq39(
void),
278 __x86_irq40(
void), __x86_irq41(
void), __x86_irq42(
void), __x86_irq43(
void),
279 __x86_irq44(
void), __x86_irq45(
void), __x86_irq46(
void), __x86_irq47(
void),
280 __x86_irq240(
void), __x86_irq241(
void), __x86_irq242(
void), __x86_spurious(
void);
282 static void (*stubs[48])(void) = {
283 __x86_irq0, __x86_irq1, __x86_irq2, __x86_irq3, __x86_irq4, __x86_irq5,
284 __x86_irq6, __x86_irq7, __x86_irq8, __x86_irq9, __x86_irq10, __x86_irq11,
285 __x86_irq12, __x86_irq13, __x86_irq14, __x86_irq15, __x86_irq16, __x86_irq17,
286 __x86_irq18, __x86_irq19, __x86_irq20, __x86_irq21, __x86_irq22, __x86_irq23,
287 __x86_irq24, __x86_irq25, __x86_irq26, __x86_irq27, __x86_irq28, __x86_irq29,
288 __x86_irq30, __x86_irq31, __x86_irq32, __x86_irq33, __x86_irq34, __x86_irq35,
289 __x86_irq36, __x86_irq37, __x86_irq38, __x86_irq39, __x86_irq40, __x86_irq41,
290 __x86_irq42, __x86_irq43, __x86_irq44, __x86_irq45, __x86_irq46, __x86_irq47,
293 for (
int i = 0; i < 48; ++i)
321 snprintf(line,
sizeof(line),
"timer: %ld %s\n",
irqs[irq].count,
324 snprintf(line,
sizeof(line),
"%d: %ld %s\n", irq,
irqs[irq].count,
327 n +=
snprintf(buf + n, size - n,
"%s", line);
332 n +=
snprintf(buf + n, size - n,
"tlb:");
335 n +=
snprintf(buf + n, size - n,
" %ld",
cpus[i].arch.tlb_flushes);
337 if ((
size_t) n < size)
338 n +=
snprintf(buf + n, size - n,
"\n");
void x86_return_to_user(struct x86_regs *r, int syscall)
Delivers the current process's pending signals on the way back to user mode: stops and default action...
void x86_tlb_ipi(void)
Does the pending request if it is for the running CPU.
void x86_idt_gate_set(uint32_t id, uintptr_t offset)
Sets an interrupt gate that only the hardware (and the kernel) can raise: an exception or a device in...
struct cpu cpus[CPUS_MAX]
void(*) irq_handler_t(void *arg)
#define MALLOC_DEFINE(type, _name, _desc)
void * kmalloc(size_t size, struct malloc_type *type, int flags)
Allocates memory for one of the kernel's structures.
void kfree(void *)
Frees an object that kmalloc() gave.
void kernel_leave(int took)
Lets go of the kernel lock on leaving the kernel, if kernel_enter() took it.
int kernel_enter(void)
Takes the kernel lock on entering the kernel, unless this CPU holds it already (an exception inside t...
void x86_irq_gates_setup(void)
Sets the IDT's gates for the interrupts: vectors 32 to 79, the local APIC's timer,...
void x86_irq_tick_switch(void)
Asks for a thread switch once the current interrupt is done: the tick calls it.
int x86_irq_alloc(struct x86_irq_chip *chip)
Gives a free IRQ with a controller of its own, for an MSI.
void x86_lapic_eoi(void)
Tells the running CPU's local APIC that its interrupt (an IPI) is handled.
void x86_irq_chip_set(struct x86_irq_chip *chip)
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.
void x86_lapic_timer_cpu_start(void)
Starts the running CPU's local APIC timer, with the boot CPU's calibration, once it has been done.
#define X86_SPURIOUS_VECTOR
void sched_idle_wakeup(void)
Runs a ready thread now if an interrupt made one ready while this CPU was idle, rather than at the ne...
void sched_thread_killed(void)
Ends the current thread, which was killed while it ran on this CPU (thread->killed).
void schedule(void)
Switches to the next ready thread.
int snprintf(char *s, size_t n, const char *fmt,...)
Formats a string into a buffer.
unsigned long long int uint64_t
struct handler * handlers
struct x86_irq_chip * chip
An installed handler, on its interrupt's list.
An interrupt controller: the 8259s, or the APIC.
const char *(*) describe(unsigned irq)
void(*) unmask(unsigned irq)
void(*) eoi(unsigned irq)
void(*) mask(unsigned irq)
The registers an interrupt or exception saved, on the kernel stack, as cpu.S's stubs push them: the g...
void irq_handle(void)
Runs the handlers of the interrupt that came, then tells the GIC it's done, before any thread switch,...