feat: setup gdt and idt and handle basic ISRs
This commit is contained in:
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;
|
||||
Reference in New Issue
Block a user