Skip to content

Commit

Permalink
Рефакторинг обработчика прерываний
Browse files Browse the repository at this point in the history
  • Loading branch information
Aren committed Nov 30, 2023
1 parent 96b3696 commit af63a87
Show file tree
Hide file tree
Showing 4 changed files with 125 additions and 1,677 deletions.
95 changes: 27 additions & 68 deletions kernel/arch/idt.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,41 +13,11 @@
#include <stdint.h>
#include <tool.h>

static struct idt_desc IDT[IDT_SIZE] __attribute__((aligned(16)));
struct idt_ptr IDT_POINT = { .limit = sizeof(IDT) - 1, .base = (uint64_t)IDT };

const char *exception_names[] = { "Деление на ноль",
"Отладка",
"NMI",
"Точка останова",
"Переполнение",
"Выход за границы",
"Недопустимая операция",
"Устройство недоступно",
"Двойное исключение",
NO_NAME,
"Недопустимый TSS",
"Сегмент не присутствует",
"Ошибка сегмента стека",
"Общая защитная ошибка",
"Ошибка страницы",
NO_NAME,
"x87 исключение",
"Проверка выравнивания",
"Ошибка машины",
"SIMD исключение",
"Виртуализация",
NO_NAME,
NO_NAME,
NO_NAME,
NO_NAME,
NO_NAME,
NO_NAME,
NO_NAME,
NO_NAME,
"Безопасность" };
static struct idt_ptr idt_ptr;
static idt_entry_t idt[256];

void exception_handler(struct frame state) {
asm volatile("cli");
LOG("\nПОЛУЧЕНО ИСКЛЮЧЕНИЕ: %s\n", exception_names[state.int_number]);

uintptr_t rsp = state.rsp;
Expand All @@ -64,57 +34,46 @@ void exception_handler(struct frame state) {
" R12=%x R13=%x\n"
" R14=%x R15=%x\n"
" RIP=%x RFLAGS=%x\n"
" CS=%x SS=%x\n"
" CS=%x SS=%x\n"
" ERR=%x INT=%u",
state.rax, state.rbx, state.rcx, state.rdx, state.rsi, state.rdi,
state.rbp, state.rsp, state.r8, state.r9, state.r10, state.r11,
state.r12, state.r13, state.r14, state.r15, state.rip, state.rflags,
state.cs, state.ss, state.err, state.int_number);
LOG("stack_top = %x\n", stack_top);

asm volatile("cli; hlt");
asm volatile("hlt");
}

static void idt_desc_setup(struct idt_desc *desc, unsigned sel, uintptr_t offs,
unsigned flags) {
desc->offs0 = offs & 0xfffful;
desc->offs1 = (offs >> 16) & 0xfffful;
desc->offs2 = (offs >> 32) & 0xfffffffful;

desc->sel = sel;
desc->flags = flags;
desc->_reserved = 0;
void idt_set_gate(uint8_t num, interrupt_handler_t handler, uint16_t selector, uint8_t flags, int userspace) {
uintptr_t base = (uintptr_t)handler;
idt[num].base_low = (base & 0xFFFF);
idt[num].base_mid = (base >> 16) & 0xFFFF;
idt[num].base_high = (base >> 32) & 0xFFFFFFFF;
idt[num].selector = selector;
idt[num].zero = 0;
idt[num].pad = 0;
idt[num].flags = flags | (userspace ? 0x60 : 0);
}


static void idt_load( ) {
struct idt_ptr *ptr = &IDT_POINT;
asm volatile("lidt %0" : : "m"(*ptr));
asm volatile (
"lidt %0"
: : "m"(idt_ptr)
);
}

void idt_set_int(uint8_t vector, void *int_handler) {
idt_desc_setup(&IDT[vector], KERNEL_CS, (uintptr_t)int_handler,
IDT_INTERRUPT_FLAGS);
void idt_set_int(uint8_t vector, void *int_handler, char *name) {
idt_desc_setup(&IDT[vector], KERNEL_CS, (uintptr_t)int_handler, 0x8E);
idt_load( );
}

void idt_init( ) {
asm volatile("sti");

for (int i = 0; i != IDT_EXCEPTIONS; ++i) {
const uintptr_t handler = (uintptr_t)isr_stubs[i];

idt_desc_setup(&IDT[i], KERNEL_CS, handler, IDT_EXCEPTION_FLAGS);
}

for (int i = IDT_EXCEPTIONS; i != IDT_SIZE; ++i) {
const uintptr_t handler = (uintptr_t)isr_stubs[i];

idt_desc_setup(&IDT[i], KERNEL_CS, handler, IDT_INTERRUPT_FLAGS);
}

idt_desc_setup(&IDT[255], KERNEL_CS, (uintptr_t)isr_stubs[255],
IDT_SPURIOUS_FLAGS);

idt_load( );
LOG("IDT инициализирован\n");
asm volatile("cli");
asm volatile (
"lidt %0"
: : "m"(idt_ptr)
);
LOG("IDT инициализирован 0x%x\n", IDT_INTERRUPT_FLAGS);
}
125 changes: 92 additions & 33 deletions kernel/arch/idt.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,6 @@

#define NO_NAME "Не задано название"

#define KERNEL_CS 0x08
#define KERNEL_DS 0x10

#define IDT_SIZE 256
#define IDT_EXCEPTIONS 32

#define IDT_DPL(x) (((unsigned)(x)&0x3u) << 13)
#define IDT_KERNEL IDT_DPL(0)

#define IDT_TYPE(x) (((unsigned)(x)&0xfu) << 8)
#define IDT_INT_GATE IDT_TYPE(0xeu)
#define IDT_TRP_FATE IDT_TYPE(0xfu)

#define IDT_PRESENT (1u << 15)

#define IDT_EXCEPTION_FLAGS (IDT_KERNEL | IDT_INT_GATE | IDT_PRESENT)
#define IDT_INTERRUPT_FLAGS (IDT_KERNEL | IDT_INT_GATE | IDT_PRESENT)
#define IDT_SPURIOUS_FLAGS (IDT_KERNEL | IDT_INT_GATE | IDT_PRESENT)

struct frame {
uint64_t rbp;
uint64_t rbx;
Expand Down Expand Up @@ -49,24 +30,102 @@ struct frame {
typedef void (*exception_handler_t)(void);
typedef void (*interrupt_handler_t)(void);

struct idt_desc {
uint16_t offs0;
uint16_t sel;
uint16_t flags;
uint16_t offs1;
uint32_t offs2;
uint32_t _reserved;
} __attribute__((packed));
typedef struct {
uint16_t base_low;
uint16_t selector;

uint8_t zero;
uint8_t flags;

uint16_t base_mid;
uint32_t base_high;
uint32_t pad;
} __attribute__((packed)) idt_entry_t;

struct idt_ptr {
uint16_t limit;
uint64_t base;
} __attribute__((packed));

struct int_desc {
interrupt_handler_t handler;
int busy;
};

typedef void (*int_entry_t)(void);
extern int_entry_t isr_stubs[];
extern int_entry_t isr_stubs[];

static const char *exception_names[] = { "Деление на ноль",
"Отладка",
"NMI",
"Точка останова",
"Переполнение",
"Выход за границы",
"Недопустимая операция",
"Устройство недоступно",
"Двойное исключение",
NO_NAME,
"Недопустимый TSS",
"Сегмент не присутствует",
"Ошибка сегмента стека",
"Общая защитная ошибка",
"Ошибка страницы",
NO_NAME,
"x87 исключение",
"Проверка выравнивания",
"Ошибка машины",
"SIMD исключение",
"Ошибка виртуализации",
NO_NAME,
NO_NAME,
NO_NAME,
NO_NAME,
NO_NAME,
NO_NAME,
NO_NAME,
NO_NAME,
"Ошибка безопасности" };
extern struct regs * _isr0(struct regs*);
extern struct regs * _isr1(struct regs*);
extern struct regs * _isr2(struct regs*);
extern struct regs * _isr3(struct regs*);
extern struct regs * _isr4(struct regs*);
extern struct regs * _isr5(struct regs*);
extern struct regs * _isr6(struct regs*);
extern struct regs * _isr7(struct regs*);
extern struct regs * _isr8(struct regs*);
extern struct regs * _isr9(struct regs*);
extern struct regs * _isr10(struct regs*);
extern struct regs * _isr11(struct regs*);
extern struct regs * _isr12(struct regs*);
extern struct regs * _isr13(struct regs*);
extern struct regs * _isr14(struct regs*);
extern struct regs * _isr15(struct regs*);
extern struct regs * _isr16(struct regs*);
extern struct regs * _isr17(struct regs*);
extern struct regs * _isr18(struct regs*);
extern struct regs * _isr19(struct regs*);
extern struct regs * _isr20(struct regs*);
extern struct regs * _isr21(struct regs*);
extern struct regs * _isr22(struct regs*);
extern struct regs * _isr23(struct regs*);
extern struct regs * _isr24(struct regs*);
extern struct regs * _isr25(struct regs*);
extern struct regs * _isr26(struct regs*);
extern struct regs * _isr27(struct regs*);
extern struct regs * _isr28(struct regs*);
extern struct regs * _isr29(struct regs*);
extern struct regs * _isr30(struct regs*);
extern struct regs * _isr31(struct regs*);
extern struct regs * _irq0(struct regs*);
extern struct regs * _irq1(struct regs*);
extern struct regs * _irq2(struct regs*);
extern struct regs * _irq3(struct regs*);
extern struct regs * _irq4(struct regs*);
extern struct regs * _irq5(struct regs*);
extern struct regs * _irq6(struct regs*);
extern struct regs * _irq7(struct regs*);
extern struct regs * _irq8(struct regs*);
extern struct regs * _irq9(struct regs*);
extern struct regs * _irq10(struct regs*);
extern struct regs * _irq11(struct regs*);
extern struct regs * _irq12(struct regs*);
extern struct regs * _irq13(struct regs*);
extern struct regs * _irq14(struct regs*);
extern struct regs * _irq15(struct regs*);
extern struct regs * _isr123(struct regs*);
Loading

0 comments on commit af63a87

Please sign in to comment.