This commit is contained in:
2026-08-11 17:48:20 +02:00
committed by Marvin Friedrich
parent cf33867e68
commit 0e2d4ed8c6
55 changed files with 279 additions and 346 deletions
+12 -12
View File
@@ -45,7 +45,7 @@ void lapic_init(struct local_apic* lapic) {
apic_msr |= 1 << 10;
else {
lapic->xapic_regs = mmio_new(apic_msr & 0xFFFF'F000, 0x1000);
ASSERT(lapic->xapic_regs, "Failed to allocate virtual memory!\n");
assert(lapic->xapic_regs, "Failed to allocate virtual memory!\n");
}
asm_wrmsr(0x1B, apic_msr);
@@ -86,18 +86,18 @@ void lapic_eoi(struct local_apic* lapic) {
#define PIC2_DATA_PORT 0xA1
void pic_disable() {
// Note: We initialize the PIC properly, but completely disable it and use the APIC in favor of it.
// We initialize the PIC properly, but completely disable it and use the APIC in favor of it.
// Remap IRQs so they start at 0x20 since interrupts 0x00..0x1F are used by CPU exceptions.
asm_outb(PIC1_COMMAND_PORT, 0x11); // ICW1: Begin initialization and set cascade mode.
asm_outb(PIC1_DATA_PORT, 0x20); // ICW2: Set where interrupts should be mapped to (0x20-0x27).
asm_outb(PIC1_DATA_PORT, 0x04); // ICW3: Connect IRQ2 (0x04) to the slave PIC.
asm_outb(PIC1_DATA_PORT, 0x01); // ICW4: Set the PIC to operate in 8086/88 mode.
asm_outb(PIC1_DATA_PORT, 0xFF); // Mask all interrupts.
asm_outb(PIC1_COMMAND_PORT, 0x11);
asm_outb(PIC1_DATA_PORT, 0x20);
asm_outb(PIC1_DATA_PORT, 0x04);
asm_outb(PIC1_DATA_PORT, 0x01);
asm_outb(PIC1_DATA_PORT, 0xFF);
// Same for the slave PIC.
asm_outb(PIC2_COMMAND_PORT, 0x11); // ICW1: Begin initialization.
asm_outb(PIC2_DATA_PORT, 0x28); // ICW2: Set where interrupts should be mapped to (0x28-0x2F).
asm_outb(PIC2_DATA_PORT, 0x02); // ICW3: Connect to master PIC at IRQ2.
asm_outb(PIC2_DATA_PORT, 0x01); // ICW4: Set the PIC to operate in 8086/88 mode.
asm_outb(PIC2_DATA_PORT, 0xFF); // Mask all interrupts.
asm_outb(PIC2_COMMAND_PORT, 0x11);
asm_outb(PIC2_DATA_PORT, 0x28);
asm_outb(PIC2_DATA_PORT, 0x02);
asm_outb(PIC2_DATA_PORT, 0x01);
asm_outb(PIC2_DATA_PORT, 0xFF);
}
+1 -1
View File
@@ -18,7 +18,7 @@ static const struct gdt main_gdt = {
.user_code64 = {.val = 0x00a0fb0000000000},
.tss = {
.limit0 = sizeof(struct tss) - 1,
.access = 0x89, // Present | DPL=0 | System | 64-bit TSS
.access = 0x89, // Present | DPL = 0 | System | 64-bit TSS
.limit1_flags = ((sizeof(struct tss) - 1) >> 16) & 0x0F,
.reserved = 0,
},
+2 -2
View File
@@ -53,7 +53,7 @@ void hpet_init() {
uacpi_setup_early_table_access(table_buf, sizeof(table_buf));
uacpi_table table = {0};
ASSERT(!uacpi_table_find_by_signature("HPET", &table), "HPET table not found!\n");
assert(!uacpi_table_find_by_signature("HPET", &table), "HPET table not found!\n");
struct acpi_hpet* hpet = table.ptr;
hpet_clock.regs = mmio_new(hpet->address.address, 0x1000);
@@ -65,5 +65,5 @@ void hpet_init() {
uint64_t caps = hpet_clock.regs[HPET_CAP];
hpet_clock.period = (caps >> 32) & 0xFFFF'FFFF;
ASSERT(clock_switch(&hpet_clock.clock), "Unable to switch to HPET!\n");
assert(clock_switch(&hpet_clock.clock), "Unable to switch to HPET!\n");
}
+1 -1
View File
@@ -50,7 +50,7 @@ void interrupt_handler(struct arch_context* ctx) {
break;
case 0x20 ...(0x20 + ARRAY_SIZE(cpu->arch.irq_lines)):
struct irq_line* line = cpu->arch.irq_lines[isr - 0x20];
ASSERT(line, "Unhandled interrupt on ISR %lu\n", isr);
assert(line, "Unhandled interrupt on ISR %lu\n", isr);
// TODO: irq_raise(line);
break;
default:
+16 -9
View File
@@ -10,22 +10,27 @@ struct arch_task_context {
uint64_t fs_base, gs_base;
};
#define ARCH_ABI(typ, reg, ...) \
union { \
typ reg, __VA_ARGS__; \
}
struct arch_context {
uint64_t r15;
uint64_t r14;
uint64_t r13;
uint64_t r12;
ARCH_ABI(uint64_t, r13, a7);
ARCH_ABI(uint64_t, r12, a6);
uint64_t r11;
uint64_t r10;
uint64_t r9;
uint64_t r8;
uint64_t rsi;
uint64_t rdi;
ARCH_ABI(uint64_t, r10, a5);
ARCH_ABI(uint64_t, r9, a3);
ARCH_ABI(uint64_t, r8, a4);
ARCH_ABI(uint64_t, rsi, a1);
ARCH_ABI(uint64_t, rdi, a0);
uint64_t rbp;
uint64_t rdx;
ARCH_ABI(uint64_t, rdx, a2, ret1);
uint64_t rcx;
uint64_t rbx;
uint64_t rax;
ARCH_ABI(uint64_t, rax, num, ret0);
uint64_t isr; // Pushed onto the stack by the interrupt handler stubs.
uint64_t error; // Pushed onto the stack by the CPU if the interrupt has an error code.
uint64_t rip; // The rest is pushed onto the stack by the CPU during an interrupt.
@@ -35,6 +40,8 @@ struct arch_context {
uint64_t ss;
};
static_assert(sizeof(struct arch_context) == 176);
#define ARCH_CTX_NUM rax
#define ARCH_CTX_A0 rdi
#define ARCH_CTX_A1 rsi
-1
View File
@@ -14,7 +14,6 @@
// The task frame consists of registers that the C ABI marks as callee-saved.
// If we don't save them, these registers are lost during a context switch.
// The order of these fields is important.
struct task_frame {
uint64_t rbx, rbp, r12, r13, r14, r15, rip;
};
+2 -2
View File
@@ -11,6 +11,7 @@ static const struct usercopy_region read_region = {
.fault_ip = x86_64_read_fault,
};
[[__naked]]
bool arch_usercopy_read(void* dst, const __user void* src, size_t len, struct usercopy_region** region) {
asm volatile(
"stac\n"
@@ -41,7 +42,6 @@ bool arch_usercopy_read(void* dst, const __user void* src, size_t len, struct us
: "i"(&read_region)
: "memory"
);
return false;
}
extern void x86_64_write_start();
@@ -54,6 +54,7 @@ static const struct usercopy_region write_region = {
.fault_ip = x86_64_write_fault,
};
[[__naked]]
bool arch_usercopy_write(__user void* dst, const void* src, size_t len, struct usercopy_region** region) {
asm volatile(
"stac\n"
@@ -84,7 +85,6 @@ bool arch_usercopy_write(__user void* dst, const void* src, size_t len, struct u
: "i"(&read_region)
: "memory"
);
return false;
}
extern void x86_64_strlen_start();