feat: setup gdt and idt and handle basic ISRs
This commit is contained in:
@@ -2,4 +2,9 @@
|
|||||||
|
|
||||||
ISO=${1}
|
ISO=${1}
|
||||||
|
|
||||||
qemu-system-x86_64 -bios /usr/share/ovmf/x64/OVMF.fd -cdrom "${ISO}" -S -s -d guest_errors
|
qemu-system-x86_64 \
|
||||||
|
-cpu qemu64 \
|
||||||
|
-m 8G \
|
||||||
|
-drive if=pflash,format=raw,readonly=on,file=/usr/share/ovmf/x64/OVMF_CODE.fd \
|
||||||
|
-cdrom "${ISO}" \
|
||||||
|
-S -s -d guest_errors,pcall,cpu_reset
|
||||||
@@ -75,12 +75,26 @@ if (NOT IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/src/platform/${CMAKE_SYSTEM_PRO
|
|||||||
message(FATAL_ERROR "Unknown architecture ${CMAKE_CURRENT_SOURCE_DIR}/src/platform/${CMAKE_SYSTEM_PROCESSOR}")
|
message(FATAL_ERROR "Unknown architecture ${CMAKE_CURRENT_SOURCE_DIR}/src/platform/${CMAKE_SYSTEM_PROCESSOR}")
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
file(GLOB PLATFORM_SPECIFIC_SOURCES src/platform/${CMAKE_SYSTEM_PROCESSOR}/*.c)
|
file(GLOB_RECURSE PLATFORM_SPECIFIC_SOURCES src/platform/${CMAKE_SYSTEM_PROCESSOR}/*.c)
|
||||||
file(GLOB PLATFORM_SPECIFIC_ASM_SOURCES src/platform/${CMAKE_SYSTEM_PROCESSOR}/*.asm)
|
file(GLOB_RECURSE PLATFORM_SPECIFIC_ASM_SOURCES src/platform/${CMAKE_SYSTEM_PROCESSOR}/*.asm)
|
||||||
|
|
||||||
file(GLOB CRTI src/platform/generic/crt/crti.c)
|
file(GLOB CRTI src/platform/generic/crt/crti.c)
|
||||||
file(GLOB CRTN src/platform/generic/crt/crtn.c)
|
file(GLOB CRTN src/platform/generic/crt/crtn.c)
|
||||||
|
|
||||||
|
file(GLOB_RECURSE PYTHON_GENERATORS src/**/*.generator.py)
|
||||||
|
|
||||||
|
|
||||||
|
foreach (GENERATOR IN LISTS PYTHON_GENERATORS)
|
||||||
|
get_filename_component(GENERATED_BARE ${GENERATOR} NAME_WE)
|
||||||
|
add_custom_command(
|
||||||
|
COMMAND python3 ${GENERATOR}
|
||||||
|
OUTPUT ${GENERATED_BARE}.c
|
||||||
|
COMMENT "Generates ${GENERATED_BARE}.c"
|
||||||
|
)
|
||||||
|
list(APPEND GENERATED_SOURCES ${GENERATED_BARE}.c)
|
||||||
|
endforeach ()
|
||||||
|
|
||||||
|
|
||||||
# Define aggregate sources
|
# Define aggregate sources
|
||||||
set(KERNEL_SOURCE_FILES
|
set(KERNEL_SOURCE_FILES
|
||||||
${KERNEL_SOURCES}
|
${KERNEL_SOURCES}
|
||||||
@@ -89,6 +103,7 @@ set(KERNEL_SOURCE_FILES
|
|||||||
${PLATFORM_GENERIC_SOURCES}
|
${PLATFORM_GENERIC_SOURCES}
|
||||||
${PLATFORM_SPECIFIC_SOURCES}
|
${PLATFORM_SPECIFIC_SOURCES}
|
||||||
${PLATFORM_SPECIFIC_ASM_SOURCES}
|
${PLATFORM_SPECIFIC_ASM_SOURCES}
|
||||||
|
${GENERATED_SOURCES}
|
||||||
)
|
)
|
||||||
|
|
||||||
# Define executable
|
# Define executable
|
||||||
|
|||||||
12
yak-kernel/include/yak/platform/x86_64/cpu/cpu.h
Normal file
12
yak-kernel/include/yak/platform/x86_64/cpu/cpu.h
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
//
|
||||||
|
// Created by rick on 30-9-23.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef YAK_CPU_H
|
||||||
|
#define YAK_CPU_H
|
||||||
|
|
||||||
|
void gdt_init();
|
||||||
|
|
||||||
|
void idt_init();
|
||||||
|
|
||||||
|
#endif //YAK_CPU_H
|
||||||
60
yak-kernel/include/yak/platform/x86_64/cpu/gdt.h
Normal file
60
yak-kernel/include/yak/platform/x86_64/cpu/gdt.h
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
//
|
||||||
|
// Created by rick on 22-3-23.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef YAK_GDT_H
|
||||||
|
#define YAK_GDT_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint64_t base;
|
||||||
|
uint32_t limit;
|
||||||
|
uint8_t access;
|
||||||
|
uint8_t flags;
|
||||||
|
} gdt_segment_c_t;
|
||||||
|
|
||||||
|
typedef struct gdt_segment {
|
||||||
|
uint16_t limit1;
|
||||||
|
uint16_t base1;
|
||||||
|
uint8_t base2;
|
||||||
|
uint8_t access_byte;
|
||||||
|
uint8_t limit2: 4;
|
||||||
|
uint8_t flags: 4;
|
||||||
|
uint8_t base3;
|
||||||
|
uint32_t base4;
|
||||||
|
uint32_t: 32; // reserved
|
||||||
|
} __attribute__((packed)) gdt_segment_t;
|
||||||
|
_Static_assert(sizeof(gdt_segment_t) == 16, "GDT must be 128 bits/16 bytes");
|
||||||
|
|
||||||
|
typedef struct gdtr {
|
||||||
|
uint16_t limit;
|
||||||
|
uint64_t pointer;
|
||||||
|
} __attribute__((packed)) gdtr_t;
|
||||||
|
|
||||||
|
#define ACCESS_BYTE_PRESENT (0b1<<7)
|
||||||
|
#define ACCESS_BYTE_DPL_0 (0b00 << 5)
|
||||||
|
#define ACCESS_BYTE_DPL_1 (0b01 << 5)
|
||||||
|
#define ACCESS_BYTE_DPL_2 (0b10 << 5)
|
||||||
|
#define ACCESS_BYTE_DPL_3 (0b11 << 5)
|
||||||
|
#define ACCESS_BYTE_CODE_DATA (0b1 << 4)
|
||||||
|
#define ACCESS_BYTE_EXECUTABLE (0b1 << 3)
|
||||||
|
#define ACCESS_BYTE_DC (0b1 << 2)
|
||||||
|
#define ACCESS_BYTE_RW (0b1 << 1)
|
||||||
|
#define ACCESS_BYTE_ACCESSED (0b1 << 0)
|
||||||
|
|
||||||
|
#define GDT_FLAG_GRANULARITY (1 << 3)
|
||||||
|
#define GDT_FLAG_SIZE_32 (1 << 2)
|
||||||
|
#define GDT_FLAG_LONG (1 << 1)
|
||||||
|
#define GDT_FLAG_RESERVED (1 << 0)
|
||||||
|
|
||||||
|
#define GDT_OFFSET_NULL 0x00
|
||||||
|
#define GDT_OFFSET_KERNEL_CODE 0x10
|
||||||
|
#define GDT_OFFSET_KERNEL_DATA 0x20
|
||||||
|
#define GDT_OFFSET_USER_32_CODE 0x30
|
||||||
|
#define GDT_OFFSET_USER_32_DATA 0x40
|
||||||
|
#define GDT_OFFSET_USER_64_CODE 0x50
|
||||||
|
#define GDT_OFFSET_USER_64_DATA 0x60
|
||||||
|
#define GDT_OFFSET_TSS 0x38
|
||||||
|
|
||||||
|
#endif //YAK_GDT_H
|
||||||
25
yak-kernel/include/yak/platform/x86_64/cpu/idt.h
Normal file
25
yak-kernel/include/yak/platform/x86_64/cpu/idt.h
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define IDT_MAX_DESCRIPTORS 256
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint16_t isr_low; // The lower 16 bits of the ISR's address
|
||||||
|
uint16_t kernel_cs; // The GDT segment selector that the CPU will load into CS before calling the ISR
|
||||||
|
uint8_t ist; // The IST in the TSS that the CPU will load into RSP; set to zero for now
|
||||||
|
uint8_t attributes; // Type and attributes; see the IDT page
|
||||||
|
uint16_t isr_mid; // The higher 16 bits of the lower 32 bits of the ISR's address
|
||||||
|
uint32_t isr_high; // The higher 32 bits of the ISR's address
|
||||||
|
uint32_t reserved; // Set to zero
|
||||||
|
} __attribute__((packed)) idt_entry_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint16_t limit;
|
||||||
|
uint64_t base;
|
||||||
|
} __attribute((packed)) idtr_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint64_t ds; // pushed in common handler
|
||||||
|
uint64_t r15, r14, r13, r12, r11, r10, r9, r8, rdi, rsi, rbx, rdx, rcx, rax; // pusha/popa
|
||||||
|
uint64_t int_no, err_code; // pushed by handlers
|
||||||
|
uint64_t rip, cs, rflags, userrsp, ss; // isr/iret
|
||||||
|
} isr_registers_t;
|
||||||
24
yak-kernel/src/platform/x86_64/cpu/gdt.asm
Normal file
24
yak-kernel/src/platform/x86_64/cpu/gdt.asm
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
.code64
|
||||||
|
|
||||||
|
.global gdt_reload_segments
|
||||||
|
gdt_reload_segments:
|
||||||
|
pushq %rbp
|
||||||
|
movq %rsp, %rbp
|
||||||
|
|
||||||
|
# Reload data segment registers
|
||||||
|
movw $0x20,%ax # 0x10 is a stand-in for your data segment
|
||||||
|
movw %ax,%ds
|
||||||
|
movw %ax,%es
|
||||||
|
movw %ax,%fs
|
||||||
|
movw %ax,%gs
|
||||||
|
movw %ax,%ss
|
||||||
|
|
||||||
|
# Reload CS register:
|
||||||
|
push $0x10 # Push code segment to stack, 0x08 is a stand-in for your code segment
|
||||||
|
leaq .reload_CS, %rax
|
||||||
|
pushq %rax
|
||||||
|
lretq
|
||||||
|
.reload_CS:
|
||||||
|
|
||||||
|
popq %rbp
|
||||||
|
ret
|
||||||
92
yak-kernel/src/platform/x86_64/cpu/gdt.c
Normal file
92
yak-kernel/src/platform/x86_64/cpu/gdt.c
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
//
|
||||||
|
// Created by rick on 22-3-23.
|
||||||
|
//
|
||||||
|
#include <yak/platform/x86_64/cpu/cpu.h>
|
||||||
|
#include <yak/platform/x86_64/cpu/gdt.h>
|
||||||
|
|
||||||
|
#define NO_GDT_ENTRIES 8
|
||||||
|
|
||||||
|
gdt_segment_t gdt_table[NO_GDT_ENTRIES] = {
|
||||||
|
{0}, // 0x0
|
||||||
|
{ // 0x8
|
||||||
|
.base1 = 0,
|
||||||
|
.base2 = 0,
|
||||||
|
.base3 = 0,
|
||||||
|
.base4 = 0,
|
||||||
|
.limit1 = 0x0,
|
||||||
|
.limit2 = 0x0,
|
||||||
|
.flags = GDT_FLAG_LONG,
|
||||||
|
.access_byte = ACCESS_BYTE_PRESENT | ACCESS_BYTE_DPL_0 | ACCESS_BYTE_CODE_DATA |
|
||||||
|
ACCESS_BYTE_EXECUTABLE | ACCESS_BYTE_RW | ACCESS_BYTE_ACCESSED,
|
||||||
|
},
|
||||||
|
{ // 0x10
|
||||||
|
.base1 = 0,
|
||||||
|
.base2 = 0,
|
||||||
|
.base3 = 0,
|
||||||
|
.base4 = 0,
|
||||||
|
.limit1 = 0x0,
|
||||||
|
.limit2 = 0x0000,
|
||||||
|
.flags = 0,
|
||||||
|
.access_byte = ACCESS_BYTE_PRESENT | ACCESS_BYTE_DPL_0 | ACCESS_BYTE_CODE_DATA | ACCESS_BYTE_RW |
|
||||||
|
ACCESS_BYTE_ACCESSED,
|
||||||
|
},
|
||||||
|
{ // 0x18
|
||||||
|
.base1 = 0,
|
||||||
|
.base2 = 0,
|
||||||
|
.base3 = 0,
|
||||||
|
.base4 = 0,
|
||||||
|
.limit1 = 0xFFFF,
|
||||||
|
.limit2 = 0xF,
|
||||||
|
.flags = GDT_FLAG_SIZE_32 | GDT_FLAG_GRANULARITY,
|
||||||
|
.access_byte = ACCESS_BYTE_PRESENT | ACCESS_BYTE_DPL_0 | ACCESS_BYTE_CODE_DATA |
|
||||||
|
ACCESS_BYTE_EXECUTABLE | ACCESS_BYTE_RW | ACCESS_BYTE_ACCESSED,
|
||||||
|
},
|
||||||
|
{ // 0x20
|
||||||
|
.base1 = 0,
|
||||||
|
.base2 = 0,
|
||||||
|
.base3 = 0,
|
||||||
|
.base4 = 0,
|
||||||
|
.limit1 = 0xFFFF,
|
||||||
|
.limit2 = 0xF,
|
||||||
|
.flags = GDT_FLAG_SIZE_32 | GDT_FLAG_GRANULARITY,
|
||||||
|
.access_byte = ACCESS_BYTE_PRESENT | ACCESS_BYTE_DPL_0 | ACCESS_BYTE_CODE_DATA | ACCESS_BYTE_RW |
|
||||||
|
ACCESS_BYTE_ACCESSED,
|
||||||
|
},
|
||||||
|
{ // 0x28
|
||||||
|
.base1 = 0,
|
||||||
|
.base2 = 0,
|
||||||
|
.base3 = 0,
|
||||||
|
.base4 = 0,
|
||||||
|
.limit1 = 0x0,
|
||||||
|
.limit2 = 0x0,
|
||||||
|
.flags = GDT_FLAG_LONG,
|
||||||
|
.access_byte = ACCESS_BYTE_PRESENT | ACCESS_BYTE_DPL_0 | ACCESS_BYTE_CODE_DATA |
|
||||||
|
ACCESS_BYTE_EXECUTABLE | ACCESS_BYTE_RW | ACCESS_BYTE_ACCESSED,
|
||||||
|
},
|
||||||
|
{ // 0x30
|
||||||
|
.base1 = 0,
|
||||||
|
.base2 = 0,
|
||||||
|
.base3 = 0,
|
||||||
|
.base4 = 0,
|
||||||
|
.limit1 = 0x0,
|
||||||
|
.limit2 = 0x0,
|
||||||
|
.flags = GDT_FLAG_LONG,
|
||||||
|
.access_byte = ACCESS_BYTE_PRESENT | ACCESS_BYTE_DPL_0 | ACCESS_BYTE_CODE_DATA | ACCESS_BYTE_RW |
|
||||||
|
ACCESS_BYTE_ACCESSED,
|
||||||
|
},
|
||||||
|
{0}
|
||||||
|
// todo tss
|
||||||
|
};
|
||||||
|
|
||||||
|
gdtr_t gdtr = {
|
||||||
|
.limit = sizeof(gdt_table) - 1,
|
||||||
|
.pointer = (uintptr_t) gdt_table,
|
||||||
|
};
|
||||||
|
|
||||||
|
extern void gdt_reload_segments();
|
||||||
|
|
||||||
|
void gdt_init() {
|
||||||
|
__asm__ volatile ("lgdt %0" : : "m"(gdtr));
|
||||||
|
gdt_reload_segments();
|
||||||
|
// todo map virtual address to physical
|
||||||
|
}
|
||||||
156
yak-kernel/src/platform/x86_64/cpu/idt.asm
Normal file
156
yak-kernel/src/platform/x86_64/cpu/idt.asm
Normal file
@@ -0,0 +1,156 @@
|
|||||||
|
.code64
|
||||||
|
|
||||||
|
.extern isr_handler
|
||||||
|
|
||||||
|
# TODO SSE(2), AVX, FP, ...
|
||||||
|
.macro save_registers_stack
|
||||||
|
pushq %rax
|
||||||
|
pushq %rbx
|
||||||
|
pushq %rcx
|
||||||
|
pushq %rdx
|
||||||
|
pushq %rsi
|
||||||
|
pushq %rdi
|
||||||
|
# skip RSP and RBP
|
||||||
|
pushq %r8
|
||||||
|
pushq %r9
|
||||||
|
pushq %r10
|
||||||
|
pushq %r11
|
||||||
|
pushq %r12
|
||||||
|
pushq %r13
|
||||||
|
pushq %r14
|
||||||
|
pushq %r15
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro restore_registers_stack
|
||||||
|
popq %r15
|
||||||
|
popq %r14
|
||||||
|
popq %r13
|
||||||
|
popq %r12
|
||||||
|
popq %r11
|
||||||
|
popq %r10
|
||||||
|
popq %r9
|
||||||
|
popq %r8
|
||||||
|
# skip RSP and RBP
|
||||||
|
popq %rdi
|
||||||
|
popq %rsi
|
||||||
|
popq %rdx
|
||||||
|
popq %rcx
|
||||||
|
popq %rbx
|
||||||
|
popq %rax
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro isr_common_stub
|
||||||
|
save_registers_stack
|
||||||
|
|
||||||
|
# Push DS
|
||||||
|
xor %rax, %rax
|
||||||
|
movw %ds, %ax
|
||||||
|
pushq %rax
|
||||||
|
# switch to kernel DS
|
||||||
|
movw $0x20,%ax
|
||||||
|
movw %ax,%ds
|
||||||
|
movw %ax,%es
|
||||||
|
movw %ax,%fs
|
||||||
|
movw %ax,%gs
|
||||||
|
|
||||||
|
call isr_handler
|
||||||
|
|
||||||
|
popq %rax
|
||||||
|
movw %ax,%ds
|
||||||
|
movw %ax,%es
|
||||||
|
movw %ax,%fs
|
||||||
|
movw %ax,%gs
|
||||||
|
|
||||||
|
restore_registers_stack
|
||||||
|
|
||||||
|
# Removes Error Code and ISR number
|
||||||
|
addq $8,%rsp
|
||||||
|
|
||||||
|
sti
|
||||||
|
iretq
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro isr_err_stub isr_num
|
||||||
|
.global isr_stub_\isr_num
|
||||||
|
isr_stub_\isr_num:
|
||||||
|
cli
|
||||||
|
push $\isr_num
|
||||||
|
isr_common_stub
|
||||||
|
.endm
|
||||||
|
.macro isr_no_err_stub isr_num
|
||||||
|
.global isr_stub_\isr_num
|
||||||
|
isr_stub_\isr_num:
|
||||||
|
cli
|
||||||
|
pushq $0
|
||||||
|
push $\isr_num
|
||||||
|
isr_common_stub
|
||||||
|
.endm
|
||||||
|
|
||||||
|
isr_no_err_stub 0
|
||||||
|
isr_no_err_stub 1
|
||||||
|
isr_no_err_stub 2
|
||||||
|
isr_no_err_stub 3
|
||||||
|
isr_no_err_stub 4
|
||||||
|
isr_no_err_stub 5
|
||||||
|
isr_no_err_stub 6
|
||||||
|
isr_no_err_stub 7
|
||||||
|
isr_err_stub 8
|
||||||
|
isr_no_err_stub 9
|
||||||
|
isr_err_stub 10
|
||||||
|
isr_err_stub 11
|
||||||
|
isr_err_stub 12
|
||||||
|
isr_err_stub 13
|
||||||
|
isr_err_stub 14
|
||||||
|
isr_no_err_stub 15
|
||||||
|
isr_no_err_stub 16
|
||||||
|
isr_err_stub 17
|
||||||
|
isr_no_err_stub 18
|
||||||
|
isr_no_err_stub 19
|
||||||
|
isr_no_err_stub 20
|
||||||
|
isr_err_stub 21
|
||||||
|
isr_no_err_stub 22
|
||||||
|
isr_no_err_stub 23
|
||||||
|
isr_no_err_stub 24
|
||||||
|
isr_no_err_stub 25
|
||||||
|
isr_no_err_stub 26
|
||||||
|
isr_no_err_stub 27
|
||||||
|
isr_no_err_stub 28
|
||||||
|
isr_err_stub 29
|
||||||
|
isr_err_stub 30
|
||||||
|
isr_no_err_stub 31
|
||||||
|
|
||||||
|
# python3 -c "print('\n'.join(f'.quad isr_stub_{i}' for i in range(32)))"
|
||||||
|
.global isr_stub_table
|
||||||
|
isr_stub_table:
|
||||||
|
.quad isr_stub_0
|
||||||
|
.quad isr_stub_1
|
||||||
|
.quad isr_stub_2
|
||||||
|
.quad isr_stub_3
|
||||||
|
.quad isr_stub_4
|
||||||
|
.quad isr_stub_5
|
||||||
|
.quad isr_stub_6
|
||||||
|
.quad isr_stub_7
|
||||||
|
.quad isr_stub_8
|
||||||
|
.quad isr_stub_9
|
||||||
|
.quad isr_stub_10
|
||||||
|
.quad isr_stub_11
|
||||||
|
.quad isr_stub_12
|
||||||
|
.quad isr_stub_13
|
||||||
|
.quad isr_stub_14
|
||||||
|
.quad isr_stub_15
|
||||||
|
.quad isr_stub_16
|
||||||
|
.quad isr_stub_17
|
||||||
|
.quad isr_stub_18
|
||||||
|
.quad isr_stub_19
|
||||||
|
.quad isr_stub_20
|
||||||
|
.quad isr_stub_21
|
||||||
|
.quad isr_stub_22
|
||||||
|
.quad isr_stub_23
|
||||||
|
.quad isr_stub_24
|
||||||
|
.quad isr_stub_25
|
||||||
|
.quad isr_stub_26
|
||||||
|
.quad isr_stub_27
|
||||||
|
.quad isr_stub_28
|
||||||
|
.quad isr_stub_29
|
||||||
|
.quad isr_stub_30
|
||||||
|
.quad isr_stub_31
|
||||||
94
yak-kernel/src/platform/x86_64/cpu/idt.c
Normal file
94
yak-kernel/src/platform/x86_64/cpu/idt.c
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
//
|
||||||
|
// Created by rick on 29-9-23.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <yak/rt/panic.h>
|
||||||
|
|
||||||
|
#include <yak/platform/x86_64/cpu/cpu.h>
|
||||||
|
#include <yak/platform/x86_64/cpu/gdt.h>
|
||||||
|
#include <yak/platform/x86_64/cpu/idt.h>
|
||||||
|
|
||||||
|
#define NO_ISR 256
|
||||||
|
|
||||||
|
|
||||||
|
extern void* isr_entries[];
|
||||||
|
|
||||||
|
__attribute((aligned(0x10))) static idt_entry_t idt[NO_ISR];
|
||||||
|
static idtr_t idtr;
|
||||||
|
void *isr_vectors[NO_ISR] = {0};
|
||||||
|
|
||||||
|
char *exception_messages[] = {
|
||||||
|
"Division By Zero",
|
||||||
|
"Debug",
|
||||||
|
"Non Maskable Interrupt",
|
||||||
|
"Breakpoint",
|
||||||
|
"Into Detected Overflow",
|
||||||
|
"Out of Bounds",
|
||||||
|
"Invalid Opcode",
|
||||||
|
"No Coprocessor",
|
||||||
|
"Double Fault",
|
||||||
|
"Coprocessor Segment Overrun",
|
||||||
|
"Bad TSS",
|
||||||
|
"Segment Not Present",
|
||||||
|
"Stack Fault",
|
||||||
|
"General Protection Fault",
|
||||||
|
"Page Fault",
|
||||||
|
"Reserved",
|
||||||
|
"Coprocessor Fault",
|
||||||
|
"Alignment Check",
|
||||||
|
"Machine Check",
|
||||||
|
"SIMD Floating Point Exception",
|
||||||
|
"Virtualization Exception",
|
||||||
|
"Control Protection Exception",
|
||||||
|
"Reserved",
|
||||||
|
"Reserved",
|
||||||
|
"Reserved",
|
||||||
|
"Reserved",
|
||||||
|
"Reserved",
|
||||||
|
"Reserved",
|
||||||
|
"Hypervisor Injection Exception",
|
||||||
|
"VMM Communication Exception",
|
||||||
|
"Security Exception",
|
||||||
|
"Reserved",
|
||||||
|
};
|
||||||
|
|
||||||
|
__attribute__((unused)) void isr_handler(isr_registers_t r) {
|
||||||
|
if (r.int_no <= 31) {
|
||||||
|
char buffer[256];
|
||||||
|
snprintf(buffer, 256, "ISR Received: %s af 0x%16lx\n", exception_messages[r.int_no], r.rip);
|
||||||
|
panic(buffer);
|
||||||
|
}
|
||||||
|
panic("ISR Received");
|
||||||
|
}
|
||||||
|
|
||||||
|
void idt_set_descriptor(uint8_t vector, void *isr, uint8_t flags) {
|
||||||
|
idt_entry_t *descriptor = &idt[vector];
|
||||||
|
|
||||||
|
descriptor->isr_low = (uint64_t) isr & 0xFFFF;
|
||||||
|
descriptor->kernel_cs = GDT_OFFSET_KERNEL_CODE;
|
||||||
|
descriptor->ist = 0;
|
||||||
|
descriptor->attributes = flags;
|
||||||
|
descriptor->isr_mid = ((uint64_t) isr >> 16) & 0xFFFF;
|
||||||
|
descriptor->isr_high = ((uint64_t) isr >> 32) & 0xFFFFFFFF;
|
||||||
|
descriptor->reserved = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void idt_init() {
|
||||||
|
idtr.base = (uint64_t) idt;
|
||||||
|
idtr.limit = sizeof(idt_entry_t) * IDT_MAX_DESCRIPTORS - 1;
|
||||||
|
|
||||||
|
memset(idt, 0, sizeof(idt_entry_t) * NO_ISR);
|
||||||
|
|
||||||
|
// register
|
||||||
|
for (int i = 0; i < 32; ++i) {
|
||||||
|
idt_set_descriptor(i, isr_entries[i], 0x8E);
|
||||||
|
isr_vectors[i] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
__asm__ volatile ("lidt %0" : : "m"(idtr));
|
||||||
|
__asm__ volatile ("sti");
|
||||||
|
}
|
||||||
21
yak-kernel/src/platform/x86_64/cpu/idt_stub.generator.py
Normal file
21
yak-kernel/src/platform/x86_64/cpu/idt_stub.generator.py
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
|
||||||
|
NO_ISRS = 32
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
with open('idt_stub.c', 'w') as f:
|
||||||
|
for stub in range(NO_ISRS):
|
||||||
|
f.write(f"extern void isr_stub_{stub}();\n")
|
||||||
|
|
||||||
|
f.write("\n")
|
||||||
|
f.write("void* isr_entries[] = {\n")
|
||||||
|
|
||||||
|
for stub in range(NO_ISRS):
|
||||||
|
f.write(f" isr_stub_{stub},\n")
|
||||||
|
|
||||||
|
f.write("};\n")
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
@@ -3,9 +3,13 @@
|
|||||||
//
|
//
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <yak/platform/generic/platform.h>
|
#include <yak/platform/generic/platform.h>
|
||||||
|
#include <yak/platform/x86_64/cpu/cpu.h>
|
||||||
|
|
||||||
void platform_init() {
|
void platform_init() {
|
||||||
printf("Init X86_64\n");
|
printf("Init X86_64\n");
|
||||||
|
__asm__("cli");
|
||||||
|
gdt_init();
|
||||||
|
idt_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
void __attribute__((noreturn)) halt_forever() {
|
void __attribute__((noreturn)) halt_forever() {
|
||||||
|
|||||||
Reference in New Issue
Block a user