feat: setup gdt and idt and handle basic ISRs

This commit is contained in:
2023-10-01 19:49:56 +02:00
parent f79e6e10ac
commit 295c11e107
11 changed files with 511 additions and 3 deletions

View 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

View 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

View 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;