Обработчик прерываний перенастроен

This commit is contained in:
Aren Elchinyan 2023-10-29 18:42:29 +03:00
parent f7fa21b2a2
commit 7238a090b8
5 changed files with 144 additions and 116 deletions

View File

@ -3,5 +3,6 @@ cd modules/
dos2unix */*.sh dos2unix */*.sh
cd helloworld/ && chmod +x build.sh && ./build.sh && cd .. cd helloworld/ && chmod +x build.sh && ./build.sh && cd ..
cd music/ && chmod +x build.sh && ./build.sh && cd .. cd music/ && chmod +x build.sh && ./build.sh && cd ..
cd simd/ && chmod +x build.sh && ./build.sh && cd ..
cd .. cd ..
python3 pbuild.py python3 pbuild.py

View File

@ -1,3 +1,3 @@
#define VERSION_MAJOR 0 #define VERSION_MAJOR 0
#define VERSION_MINOR 1 #define VERSION_MINOR 1
#define VERSION_BUILD 320 #define VERSION_BUILD 350

View File

@ -13,71 +13,48 @@
#include <stdint.h> #include <stdint.h>
#include <tool.h> #include <tool.h>
typedef struct __attribute__((packed)) { static struct idt_desc IDT[IDT_SIZE] __attribute__((aligned(16)));
uint16_t limit; struct idt_ptr IDT_POINT = { .limit = sizeof(IDT) - 1, .base = (uint64_t)IDT };
uint64_t base;
} idt_ptr_t;
typedef struct __attribute__((packed)) { const char *exception_names[] = { "Деление на ноль",
uint16_t offset_16; "Отладка",
uint16_t selector; "NMI",
uint8_t ist; "Точка останова",
uint8_t flags; "Переполнение",
uint16_t offset_middle_16; "Выход за границы",
uint32_t offset_high_32; "Недопустимая операция",
uint32_t reserved; "Устройство недоступно",
} idt_gate_t; "Двойное исключение",
NO_NAME,
"Недопустимый TSS",
"Сегмент не присутствует",
"Ошибка сегмента стека",
"Общая защитная ошибка",
"Ошибка страницы",
NO_NAME,
"x87 исключение",
"Проверка выравнивания",
"Ошибка машины",
"SIMD исключение",
"Виртуализация",
NO_NAME,
NO_NAME,
NO_NAME,
NO_NAME,
NO_NAME,
NO_NAME,
NO_NAME,
NO_NAME,
"Безопасность" };
struct frame { void exception_handler(struct frame state) {
uint64_t rbp;
uint64_t rbx;
uint64_t r15;
uint64_t r14;
uint64_t r13;
uint64_t r12;
uint64_t r11;
uint64_t r10;
uint64_t r9;
uint64_t r8;
uint64_t rax;
uint64_t rcx;
uint64_t rdx;
uint64_t rsi;
uint64_t rdi;
uint64_t int_number;
uint64_t err;
uint64_t rip;
uint64_t cs;
uint64_t rflags;
uint64_t rsp;
uint64_t ss;
} __attribute__((packed));
static idt_gate_t idt[256];
void *isr[256];
extern void *isr_stubs[];
static idt_ptr_t idtr;
void idt_load( ) {
asm volatile("lidt %0" : : "m"(idtr));
asm volatile("sti");
}
static void encode_idt_entry(uint8_t vector, void *handler, uint8_t flags) {
uint64_t ptr = (uint64_t)handler;
idt[vector].offset_16 = (uint16_t)ptr;
idt[vector].selector = 0x28;
idt[vector].ist = 0;
idt[vector].flags = flags;
idt[vector].offset_middle_16 = (uint16_t)(ptr >> 16);
idt[vector].offset_high_32 = (uint32_t)(ptr >> 32);
idt[vector].reserved = 0;
}
static void exception_handler(struct frame state) {
LOG("\nПОЛУЧЕНО ИСКЛЮЧЕНИЕ: %s\n", exception_names[state.int_number]); LOG("\nПОЛУЧЕНО ИСКЛЮЧЕНИЕ: %s\n", exception_names[state.int_number]);
uintptr_t rsp = state.rsp;
const uintptr_t stack_bottom = rsp & ~((uintptr_t)4096 - 1);
const uintptr_t stack_top = stack_bottom + 4096;
LOG(" RAX=%x RBX=%x\n" LOG(" RAX=%x RBX=%x\n"
" RCX=%x RDX=%x\n" " RCX=%x RDX=%x\n"
" RSI=%x RDI=%x\n" " RSI=%x RDI=%x\n"
@ -97,33 +74,43 @@ static void exception_handler(struct frame state) {
asm volatile("cli; hlt"); asm volatile("cli; hlt");
} }
void isr_generic(struct frame state) { static void idt_desc_setup(struct idt_desc *desc, unsigned sel, uintptr_t offs,
if (state.int_number < 32) { unsigned flags) {
exception_handler(state); desc->offs0 = offs & 0xfffful;
} else { desc->offs1 = (offs >> 16) & 0xfffful;
LOG("\nПрерывание! %u необработано :(\n", state.int_number); desc->offs2 = (offs >> 32) & 0xfffffffful;
}
desc->sel = sel;
desc->flags = flags;
desc->_reserved = 0;
} }
void idt_init( ) { static void idt_load( ) {
idtr = (idt_ptr_t){ .limit = sizeof(idt) - 1, .base = (uint64_t)idt }; struct idt_ptr *ptr = &IDT_POINT;
asm volatile("lidt %0" : : "m"(*ptr));
}
for (uint64_t i = 0; i < 256; i++) { void idt_set_int(uint8_t vector, void *int_handler) {}
if (i < 31) {
encode_idt_entry(i, isr_stubs[i], 0x8E); void idt_init( ) {
isr[i] = (void *)exception_handler; asm volatile("sti");
} else { fb_printf("Настройка прерываний...\n");
encode_idt_entry(i, isr_stubs[i], 0x8E);
isr[i] = (void *)isr_generic; 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( ); idt_load( );
LOG("IDT инициализирован\n"); LOG("IDT инициализирован\n");
}
void idt_set_int(uint8_t vector, void *int_handler) {
encode_idt_entry(vector, int_handler, 0x8E);
isr[vector] = int_handler;
idt_load( );
} }

View File

@ -1,32 +1,72 @@
#include <stdint.h>
#define NO_NAME "Не задано название" #define NO_NAME "Не задано название"
const char *exception_names[] = { "Деление на ноль", #define KERNEL_CS 0x08
"Отладка", #define KERNEL_DS 0x10
"NMI",
"Точка останова", #define IDT_SIZE 256
"Переполнение", #define IDT_EXCEPTIONS 32
"Выход за границы",
"Недопустимая операция", #define IDT_DPL(x) (((unsigned)(x)&0x3u) << 13)
"Устройство недоступно", #define IDT_KERNEL IDT_DPL(0)
"Двойное исключение",
NO_NAME, #define IDT_TYPE(x) (((unsigned)(x)&0xfu) << 8)
"Недопустимый TSS", #define IDT_INT_GATE IDT_TYPE(0xeu)
"Сегмент не присутствует", #define IDT_TRP_FATE IDT_TYPE(0xfu)
"Ошибка сегмента стека",
"Общая защитная ошибка", #define IDT_PRESENT (1u << 15)
"Ошибка страницы",
NO_NAME, #define IDT_EXCEPTION_FLAGS (IDT_KERNEL | IDT_INT_GATE | IDT_PRESENT)
"x87 исключение", #define IDT_INTERRUPT_FLAGS (IDT_KERNEL | IDT_INT_GATE | IDT_PRESENT)
"Проверка выравнивания", #define IDT_SPURIOUS_FLAGS (IDT_KERNEL | IDT_INT_GATE | IDT_PRESENT)
"Ошибка машины",
"SIMD исключение", struct frame {
"Виртуализация", uint64_t rbp;
NO_NAME, uint64_t rbx;
NO_NAME, uint64_t r15;
NO_NAME, uint64_t r14;
NO_NAME, uint64_t r13;
NO_NAME, uint64_t r12;
NO_NAME, uint64_t r11;
NO_NAME, uint64_t r10;
NO_NAME, uint64_t r9;
"Безопасность" }; uint64_t r8;
uint64_t rax;
uint64_t rcx;
uint64_t rdx;
uint64_t rsi;
uint64_t rdi;
uint64_t int_number;
uint64_t err;
uint64_t rip;
uint64_t cs;
uint64_t rflags;
uint64_t rsp;
uint64_t ss;
} __attribute__((packed));
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));
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[];

View File

@ -1,7 +1,7 @@
.text .text
.code64 .code64
.global isr_stubs .global isr_stubs
.extern isr_generic .extern exception_handler
common: common:
subq $120, %rsp subq $120, %rsp
@ -22,7 +22,7 @@ common:
movq %rdi, 112(%rsp) movq %rdi, 112(%rsp)
cld cld
movq %rsp, %rdi movq %rsp, %rdi
call isr_generic call exception_handler
movq 0(%rsp), %rbp movq 0(%rsp), %rbp
movq 8(%rsp), %rbx movq 8(%rsp), %rbx
movq 16(%rsp), %r15 movq 16(%rsp), %r15