stuff2
This commit is contained in:
+12
-12
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
},
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user