mirror of
https://github.com/rdmsr/zag.git
synced 2026-11-01 15:48:21 +00:00
feat: amd64 interrupts
This commit is contained in:
@@ -5,6 +5,8 @@ const amd64 = b.arch;
|
||||
|
||||
const std = @import("std");
|
||||
|
||||
pub const early_init = @import("init.zig").early_init;
|
||||
|
||||
pub const Cpu = struct {
|
||||
self_ptr: *Cpu,
|
||||
percpu_offset: usize,
|
||||
@@ -122,15 +124,15 @@ pub inline fn set_hardware_ipl(ipl: ke.Ipl) void {
|
||||
}
|
||||
|
||||
pub inline fn enable_interrupts() void {
|
||||
amd64.cpu.sti();
|
||||
amd64.sti();
|
||||
}
|
||||
|
||||
pub inline fn disable_interrupts() bool {
|
||||
const rflags = amd64.cpu.rflags();
|
||||
const ie = amd64.rflags().interrupt_enable;
|
||||
|
||||
amd64.cpu.cli();
|
||||
amd64.cli();
|
||||
|
||||
return rflags & (1 << 9) != 0;
|
||||
return ie;
|
||||
}
|
||||
|
||||
pub inline fn restore_interrupts(state: bool) void {
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
const amd64 = @import("arch");
|
||||
const int = @import("int.zig");
|
||||
const b = @import("base");
|
||||
|
||||
var gdt = extern struct {
|
||||
entries: [9]u64 align(1),
|
||||
tss: amd64.TssDescriptor align(1),
|
||||
}{
|
||||
.entries = .{
|
||||
0, // null
|
||||
0x00009a000000ffff, // code16
|
||||
0x000093000000ffff, // data16
|
||||
0x00cf9a000000ffff, // code32
|
||||
0x00cf93000000ffff, // data32
|
||||
0x00af9b000000ffff, // kernel code64
|
||||
0x00af93000000ffff, // kernel data64
|
||||
0x00aff3000000ffff, // user code64
|
||||
0x00affb000000ffff, // user data64
|
||||
},
|
||||
|
||||
.tss = undefined,
|
||||
};
|
||||
|
||||
extern fn gdt_load(gdtr: *const amd64.Gdtr) callconv(.{ .x86_64_sysv = .{} }) void;
|
||||
|
||||
pub fn early_init() linksection(b.init) void {
|
||||
const gdtr: amd64.Gdtr = .{
|
||||
.limit = @sizeOf(@TypeOf(gdt)) - 1,
|
||||
.base = @intFromPtr(&gdt),
|
||||
};
|
||||
|
||||
gdt_load(&gdtr);
|
||||
|
||||
int.init();
|
||||
|
||||
asm volatile ("int3");
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
const amd64 = @import("arch");
|
||||
const std = @import("std");
|
||||
const b = @import("base");
|
||||
|
||||
extern const __interrupt_vectors: [256]usize;
|
||||
|
||||
var idt: [256]amd64.IdtEntry align(16) = undefined;
|
||||
|
||||
const exception_msg = [32][]const u8{
|
||||
"Divide Error",
|
||||
"Debug",
|
||||
"Non-Maskable Interrupt",
|
||||
"Breakpoint",
|
||||
"Overflow",
|
||||
"Bound Range Exceeded",
|
||||
"Invalid Opcode",
|
||||
"Device Not Available",
|
||||
"Double Fault",
|
||||
"Coprocessor Segment Overrun",
|
||||
"Invalid TSS",
|
||||
"Segment Not Present",
|
||||
"Stack-Segment Fault",
|
||||
"General Protection Fault",
|
||||
"Page Fault",
|
||||
"???",
|
||||
"x87 Floating-Point Exception",
|
||||
"Alignment Check",
|
||||
"Machine Check",
|
||||
"SIMD Floating-Point Exception",
|
||||
"Virtualization Exception",
|
||||
"Control Protection Exception",
|
||||
"???",
|
||||
"???",
|
||||
"???",
|
||||
"???",
|
||||
"???",
|
||||
"???",
|
||||
"???",
|
||||
"???",
|
||||
"???",
|
||||
"Security Exception",
|
||||
};
|
||||
|
||||
export fn isr_handler_main(frame: *const amd64.IrqFrame) callconv(.{ .x86_64_sysv = .{} }) void {
|
||||
if (frame.intno < 32) {
|
||||
std.log.info("Unhandled exception: 0x{x} ({s}), err=0x{x}, pc=0x{x}", .{ frame.intno, exception_msg[frame.intno], frame.errcode, frame.rip });
|
||||
std.log.info("RAX=0x{x:0>16} RBX=0x{x:0>16} RCX=0x{x:0>16} RDX=0x{x:0>16}", .{ frame.rax, frame.rbx, frame.rcx, frame.rdx });
|
||||
std.log.info("RSI=0x{x:0>16} RDI=0x{x:0>16} RBP=0x{x:0>16} RSP=0x{x:0>16}", .{ frame.rsi, frame.rdi, frame.rbp, frame.rsp });
|
||||
std.log.info("R8= 0x{x:0>16} R9=0x{x:0>16} R10=0x{x:0>16} R11=0x{x:0>16}", .{ frame.r8, frame.r9, frame.r10, frame.r11 });
|
||||
std.log.info("R12=0x{x:0>16} R13=0x{x:0>16} R14=0x{x:0>16} R15=0x{x:0>16}", .{ frame.r12, frame.r13, frame.r14, frame.r15 });
|
||||
const cr2 = amd64.read_cr(2);
|
||||
const cr3 = amd64.read_cr(3);
|
||||
const rflags = amd64.rflags();
|
||||
std.log.info("CR2=0x{x:0>16} CR3=0x{x:0>16} RFLAGS={x}", .{ cr2, cr3, @as(u64, @bitCast(rflags)) });
|
||||
|
||||
@panic("Unhandled exception");
|
||||
}
|
||||
}
|
||||
|
||||
extern fn idt_load(idt_ptr: *const amd64.Idtr) callconv(.{ .x86_64_sysv = .{} }) void;
|
||||
|
||||
pub fn init() linksection(b.init) void {
|
||||
const idtr: amd64.Idtr = .{
|
||||
.limit = @sizeOf(@TypeOf(idt)) - 1,
|
||||
.base = @intFromPtr(&idt),
|
||||
};
|
||||
|
||||
for (&idt, 0..256) |*entry, i| {
|
||||
entry.* = .init(0x28, 0, .InterruptGate, __interrupt_vectors[i]);
|
||||
}
|
||||
|
||||
idt_load(&idtr);
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
.altmacro
|
||||
.code64
|
||||
|
||||
.section .text
|
||||
.globl gdt_load
|
||||
gdt_load:
|
||||
lgdt (%rdi)
|
||||
|
||||
/* Set ss, ds and es to data segment */
|
||||
mov $0x30, %ax
|
||||
mov %ax, %ds
|
||||
mov %ax, %es
|
||||
mov %ax, %ss
|
||||
|
||||
/* Save return address */
|
||||
pop %rdi
|
||||
|
||||
/* Push CS so the CPU will pop it off with retfq */
|
||||
mov $0x28, %rax
|
||||
push %rax
|
||||
push %rdi
|
||||
lretq
|
||||
|
||||
|
||||
.globl idt_load
|
||||
idt_load:
|
||||
lidt (%rdi)
|
||||
ret
|
||||
|
||||
.macro pushall
|
||||
push %rax
|
||||
push %rbx
|
||||
push %rcx
|
||||
push %rdx
|
||||
push %rbp
|
||||
push %rdi
|
||||
push %rsi
|
||||
push %r8
|
||||
push %r9
|
||||
push %r10
|
||||
push %r11
|
||||
push %r12
|
||||
push %r13
|
||||
push %r14
|
||||
push %r15
|
||||
.endm
|
||||
|
||||
.macro popall
|
||||
pop %r15
|
||||
pop %r14
|
||||
pop %r13
|
||||
pop %r12
|
||||
pop %r11
|
||||
pop %r10
|
||||
pop %r9
|
||||
pop %r8
|
||||
pop %rsi
|
||||
pop %rdi
|
||||
pop %rbp
|
||||
pop %rdx
|
||||
pop %rcx
|
||||
pop %rbx
|
||||
pop %rax
|
||||
.endm
|
||||
|
||||
.extern isr_handler_main
|
||||
isr_handler:
|
||||
cld
|
||||
pushall
|
||||
mov %rsp, %rdi
|
||||
call isr_handler_main
|
||||
popall
|
||||
cli
|
||||
add $16, %rsp
|
||||
iretq
|
||||
|
||||
.macro INTERRUPT_NOERR num
|
||||
.globl isr\num
|
||||
isr\num :
|
||||
pushq $0
|
||||
pushq $\num
|
||||
jmp isr_handler
|
||||
.endm
|
||||
|
||||
.macro INTERRUPT_ERR num
|
||||
.globl isr\num
|
||||
isr\num :
|
||||
pushq $\num
|
||||
jmp isr_handler
|
||||
.endm
|
||||
|
||||
INTERRUPT_NOERR 0
|
||||
INTERRUPT_NOERR 1
|
||||
INTERRUPT_NOERR 2
|
||||
INTERRUPT_NOERR 3
|
||||
INTERRUPT_NOERR 4
|
||||
INTERRUPT_NOERR 5
|
||||
INTERRUPT_NOERR 6
|
||||
INTERRUPT_NOERR 7
|
||||
INTERRUPT_ERR 8
|
||||
INTERRUPT_NOERR 9
|
||||
INTERRUPT_ERR 10
|
||||
INTERRUPT_ERR 11
|
||||
INTERRUPT_ERR 12
|
||||
INTERRUPT_ERR 13
|
||||
INTERRUPT_ERR 14
|
||||
INTERRUPT_NOERR 15
|
||||
INTERRUPT_NOERR 16
|
||||
INTERRUPT_ERR 17
|
||||
INTERRUPT_NOERR 18
|
||||
INTERRUPT_NOERR 19
|
||||
INTERRUPT_NOERR 20
|
||||
INTERRUPT_NOERR 21
|
||||
INTERRUPT_NOERR 22
|
||||
INTERRUPT_NOERR 23
|
||||
INTERRUPT_NOERR 24
|
||||
INTERRUPT_NOERR 25
|
||||
INTERRUPT_NOERR 26
|
||||
INTERRUPT_NOERR 27
|
||||
INTERRUPT_NOERR 28
|
||||
INTERRUPT_NOERR 29
|
||||
INTERRUPT_ERR 30
|
||||
INTERRUPT_NOERR 31
|
||||
|
||||
.rept 224
|
||||
INTERRUPT_NOERR %32+\+
|
||||
.endr
|
||||
|
||||
.global __interrupt_vectors
|
||||
__interrupt_vectors:
|
||||
.rept 256
|
||||
.quad isr\()\+
|
||||
.endr
|
||||
Reference in New Issue
Block a user