blob: f56965231f70ba9d5d3573d06088716f5d7dbf48 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
//! Interrupt Handler Stub Assembly
const std = @import("std");
pub const push_zero = "push $0\n";
pub fn push_vector(comptime vector: u8) []const u8 {
return comptime std.fmt.comptimePrint("push ${d}\n", .{vector});
}
pub const push_all =
\\push %%rax
\\push %%rbx
\\push %%rcx
\\push %%rdx
\\push %%rsi
\\push %%rdi
\\push %%rbp
\\push %%r8
\\push %%r9
\\push %%r10
\\push %%r11
\\push %%r12
\\push %%r13
\\push %%r14
\\push %%r15
;
pub const pop_all =
\\pop %%r15
\\pop %%r14
\\pop %%r13
\\pop %%r12
\\pop %%r11
\\pop %%r10
\\pop %%r9
\\pop %%r8
\\pop %%rbp
\\pop %%rdi
\\pop %%rsi
\\pop %%rdx
\\pop %%rcx
\\pop %%rbx
\\pop %%rax
;
pub const iret_cleanup =
\\add $16, %%rsp
\\iretq
;
pub const call_exception_dispatch =
\\mov %%rsp, %%rdi
\\call exception_dispatch
;
pub const call_irq_dispatch =
\\mov %%rsp, %%rdi
\\call irq_dispatch
;
pub fn exception_stub(comptime vector: u8, comptime has_error_code: bool) []const u8 {
return (if (!has_error_code) push_zero else "") ++
push_vector(vector) ++
push_all ++
call_exception_dispatch ++
pop_all ++
iret_cleanup;
}
pub fn irq_stub(comptime irq: u8) []const u8 {
return push_zero ++
push_vector(irq + 32) ++
push_all ++
call_irq_dispatch ++
pop_all ++
iret_cleanup;
}
pub fn make_exception_handler(comptime vector: u8, comptime has_error_code: bool) fn () callconv(.Naked) void {
return struct {
fn handler() callconv(.Naked) void {
asm volatile (exception_stub(vector, has_error_code));
}
}.handler;
}
pub fn make_irq_handler(comptime irq: u8) fn () callconv(.Naked) void {
return struct {
fn handler() callconv(.Naked) void {
asm volatile (irq_stub(irq));
}
}.handler;
}
|