diff --git a/build.sh b/build.sh index a76fa1d..1d935da 100755 --- a/build.sh +++ b/build.sh @@ -3,5 +3,6 @@ cd modules/ dos2unix */*.sh cd helloworld/ && 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 .. python3 pbuild.py \ No newline at end of file diff --git a/include/version.h b/include/version.h index 57e5812..6a41b49 100644 --- a/include/version.h +++ b/include/version.h @@ -1,3 +1,3 @@ #define VERSION_MAJOR 0 #define VERSION_MINOR 1 -#define VERSION_BUILD 320 +#define VERSION_BUILD 350 diff --git a/kernel/arch/idt.c b/kernel/arch/idt.c index 344a125..716e167 100644 --- a/kernel/arch/idt.c +++ b/kernel/arch/idt.c @@ -13,71 +13,48 @@ #include #include -typedef struct __attribute__((packed)) { - uint16_t limit; - uint64_t base; -} idt_ptr_t; +static struct idt_desc IDT[IDT_SIZE] __attribute__((aligned(16))); +struct idt_ptr IDT_POINT = { .limit = sizeof(IDT) - 1, .base = (uint64_t)IDT }; -typedef struct __attribute__((packed)) { - uint16_t offset_16; - uint16_t selector; - uint8_t ist; - uint8_t flags; - uint16_t offset_middle_16; - uint32_t offset_high_32; - uint32_t reserved; -} idt_gate_t; +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, + "Безопасность" }; -struct frame { - 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) { +void exception_handler(struct frame state) { 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" " RCX=%x RDX=%x\n" " RSI=%x RDI=%x\n" @@ -97,33 +74,43 @@ static void exception_handler(struct frame state) { asm volatile("cli; hlt"); } -void isr_generic(struct frame state) { - if (state.int_number < 32) { - exception_handler(state); - } else { - LOG("\nПрерывание! %u необработано :(\n", state.int_number); - } +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_init( ) { - idtr = (idt_ptr_t){ .limit = sizeof(idt) - 1, .base = (uint64_t)idt }; +static void idt_load( ) { + struct idt_ptr *ptr = &IDT_POINT; + asm volatile("lidt %0" : : "m"(*ptr)); +} - for (uint64_t i = 0; i < 256; i++) { - if (i < 31) { - encode_idt_entry(i, isr_stubs[i], 0x8E); - isr[i] = (void *)exception_handler; - } else { - encode_idt_entry(i, isr_stubs[i], 0x8E); - isr[i] = (void *)isr_generic; - } +void idt_set_int(uint8_t vector, void *int_handler) {} + +void idt_init( ) { + asm volatile("sti"); + fb_printf("Настройка прерываний...\n"); + + 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"); -} - -void idt_set_int(uint8_t vector, void *int_handler) { - encode_idt_entry(vector, int_handler, 0x8E); - isr[vector] = int_handler; - idt_load( ); } \ No newline at end of file diff --git a/kernel/arch/idt.h b/kernel/arch/idt.h index 5fa6932..3c732b0 100644 --- a/kernel/arch/idt.h +++ b/kernel/arch/idt.h @@ -1,32 +1,72 @@ +#include + #define NO_NAME "Не задано название" -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, - "Безопасность" }; \ No newline at end of file +#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; + 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)); + +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[]; \ No newline at end of file diff --git a/kernel/arch/idt_stubs.s b/kernel/arch/idt_stubs.s index 06b17ac..36eafdd 100644 --- a/kernel/arch/idt_stubs.s +++ b/kernel/arch/idt_stubs.s @@ -1,7 +1,7 @@ .text .code64 .global isr_stubs - .extern isr_generic + .extern exception_handler common: subq $120, %rsp @@ -22,7 +22,7 @@ common: movq %rdi, 112(%rsp) cld movq %rsp, %rdi - call isr_generic + call exception_handler movq 0(%rsp), %rbp movq 8(%rsp), %rbx movq 16(%rsp), %r15