You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
91 lines
3.1 KiB
C
91 lines
3.1 KiB
C
/* See the end of this file for copyright and license terms. */
|
|
|
|
#include <arch/cpufunc.h>
|
|
#include <arch/interrupt.h>
|
|
#include <arch/port.h>
|
|
#include <arch/segment.h>
|
|
#include <arch/trap.h>
|
|
|
|
#include <gay/kprintf.h>
|
|
#include <gay/types.h>
|
|
|
|
struct x86_idt_entry x86_idt[X86_INTR_COUNT] __aligned(16);
|
|
|
|
void x86_setup_interrupts(void)
|
|
{
|
|
/* make sure all IRQs are masked first */
|
|
x86_outb(X86_PORT_PIC1_DATA, 0xff);
|
|
x86_outb(X86_PORT_PIC2_DATA, 0xff);
|
|
|
|
x86_set_trap_gate(X86_VECT_DE, _x86_isr_divide_error);
|
|
x86_set_trap_gate(X86_VECT_DB, _x86_isr_debug_exception);
|
|
x86_set_trap_gate(X86_VECT_NMI, _x86_isr_nmi);
|
|
x86_set_trap_gate(X86_VECT_BP, _x86_isr_breakpoint);
|
|
x86_set_trap_gate(X86_VECT_OF, _x86_isr_overflow);
|
|
x86_set_trap_gate(X86_VECT_BR, _x86_isr_bound_range_exceeded);
|
|
x86_set_trap_gate(X86_VECT_UD, _x86_isr_invalid_opcode);
|
|
x86_set_trap_gate(X86_VECT_NM, _x86_isr_device_not_available);
|
|
x86_set_trap_gate(X86_VECT_DF, _x86_isr_double_fault);
|
|
x86_set_trap_gate(X86_VECT_TS, _x86_isr_invalid_tss);
|
|
x86_set_trap_gate(X86_VECT_NP, _x86_isr_segment_not_present);
|
|
x86_set_trap_gate(X86_VECT_SS, _x86_isr_stack_segment_fault);
|
|
x86_set_trap_gate(X86_VECT_GP, _x86_isr_general_protection);
|
|
x86_set_trap_gate(X86_VECT_PF, _x86_isr_page_fault);
|
|
x86_set_trap_gate(X86_VECT_MF, _x86_isr_x87_fpu_error);
|
|
x86_set_trap_gate(X86_VECT_AC, _x86_isr_alignment_check);
|
|
x86_set_trap_gate(X86_VECT_MC, _x86_isr_machine_check);
|
|
x86_set_trap_gate(X86_VECT_XM, _x86_isr_simd_floating_point_exception);
|
|
x86_set_trap_gate(X86_VECT_VE, _x86_isr_virtualization_exception);
|
|
x86_set_trap_gate(X86_VECT_CP, _x86_isr_control_protection_exception);
|
|
|
|
x86_load_idt();
|
|
enable_intr();
|
|
}
|
|
|
|
void x86_set_gate(u8 vector, void (*handler)(void), u8 flags)
|
|
{
|
|
struct x86_idt_entry *entry = &x86_idt[vector];
|
|
entry->selector = X86_32_KERN_CS;
|
|
entry->_rsvd0 = 0;
|
|
entry->attr = flags;
|
|
|
|
entry->offset0 = (uintptr_t)handler & 0xffff;
|
|
entry->offset1 = ((uintptr_t)handler >> 16) & 0xffff;
|
|
#ifdef __x86_64__
|
|
entry->offset2 = ((uintptr_t)handler >> 32) & 0xffffffff;
|
|
entry->_rsvd1 = 0;
|
|
#endif
|
|
}
|
|
|
|
void x86_set_trap_gate(u8 vector, void (*isr)(void))
|
|
{
|
|
u8 flags = X86_IDT_PRESENT | X86_IDT_GATE_TRAP32 | X86_IDT_DPL(0);
|
|
if (vector < X86_VECT_IRQ_BASE)
|
|
x86_set_gate(vector, isr, flags);
|
|
else
|
|
kprintf("Tried to assign non-trap vector %d to a trap gate\n", vector);
|
|
}
|
|
|
|
void x86_set_intr_gate(u8 vector, void (*isr)(void))
|
|
{
|
|
u8 flags = X86_IDT_PRESENT | X86_IDT_GATE_INTR32 | X86_IDT_DPL(0);
|
|
if (vector < X86_VECT_IRQ_BASE)
|
|
kprintf("Tried to assign non-interrupt vector %d to an interrupt gate\n", vector);
|
|
else
|
|
x86_set_gate(vector, isr, flags);
|
|
}
|
|
|
|
/*
|
|
* This file is part of GayBSD.
|
|
* Copyright (c) 2021 fef <owo@fef.moe>.
|
|
*
|
|
* GayBSD is nonviolent software: you may only use, redistribute, and/or
|
|
* modify it under the terms of the Cooperative Nonviolent Public License
|
|
* (CNPL) as found in the LICENSE file in the source code root directory
|
|
* or at <https://git.pixie.town/thufie/npl-builder>; either version 7
|
|
* of the license, or (at your option) any later version.
|
|
*
|
|
* GayBSD comes with ABSOLUTELY NO WARRANTY, to the extent
|
|
* permitted by applicable law. See the CNPL for details.
|
|
*/
|