Обработчик прерываний перенастроен
This commit is contained in:
parent
f7fa21b2a2
commit
7238a090b8
1
build.sh
1
build.sh
|
@ -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
|
|
@ -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
|
||||||
|
|
|
@ -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( );
|
|
||||||
}
|
}
|
|
@ -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[];
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue