@@ -72,3 +72,131 @@ pub fn end_interrupt_disable() {
72
72
assert ! ( prev_count > 0 ) ;
73
73
interrupts:: enable ( ) ;
74
74
}
75
+
76
+ macro_rules! exception {
77
+ ( $id: ident, $name: literal) => {
78
+ extern "x86-interrupt" fn $id( frame: InterruptStackFrame ) {
79
+ cpu_exception( frame, $name) ;
80
+ }
81
+ } ;
82
+ }
83
+
84
+ macro_rules! exception_errcode {
85
+ ( $id: ident, $name: literal) => {
86
+ extern "x86-interrupt" fn $id( frame: InterruptStackFrame , errcode: u64 ) {
87
+ cpu_exception_errcode( frame, $name, errcode) ;
88
+ }
89
+ } ;
90
+ }
91
+
92
+ macro_rules! exception_diverging {
93
+ ( $id: ident, $name: literal) => {
94
+ extern "x86-interrupt" fn $id( frame: InterruptStackFrame ) -> ! {
95
+ cpu_exception( frame, $name) ;
96
+ }
97
+ } ;
98
+ }
99
+
100
+ macro_rules! exception_diverging_errcode {
101
+ ( $id: ident, $name: literal) => {
102
+ extern "x86-interrupt" fn $id( frame: InterruptStackFrame , errcode: u64 ) -> ! {
103
+ cpu_exception_errcode( frame, $name, errcode) ;
104
+ }
105
+ } ;
106
+ }
107
+
108
+ exception ! ( handler_divide_error, "Divide error" ) ;
109
+ exception ! ( handler_debug, "Debug exception" ) ;
110
+ exception ! ( handler_non_maskable_interrupt, "Non-maskable interrupt" ) ;
111
+ exception ! ( handler_breakpoint, "Breakpoint exception" ) ;
112
+ exception ! ( handler_overflow, "Overflow exception" ) ;
113
+ exception ! ( handler_bound_range_exceeded, "Bound range exceeded" ) ;
114
+ exception ! ( handler_invalid_opcode, "Invalid opcode" ) ;
115
+ exception ! ( handler_device_not_available, "Device not available" ) ;
116
+ exception_diverging_errcode ! ( handler_double_fault, "Double fault" ) ;
117
+ exception_errcode ! ( handler_invalid_tss, "Invalid TSS" ) ;
118
+ exception_errcode ! ( handler_segment_not_present, "Segment not present" ) ;
119
+ exception_errcode ! ( handler_stack_segment_fault, "Stack segment exception" ) ;
120
+ exception_errcode ! ( handler_general_protection_fault, "General protection fault" ) ;
121
+ // See below for page fault handler
122
+ exception ! ( handler_x87_floating_point, "x87 floating-point exception" ) ;
123
+ exception_errcode ! ( handler_alignment_check, "Alignment check exception" ) ;
124
+ exception_diverging ! ( handler_machine_check, "Machine check exception" ) ;
125
+ exception ! ( handler_simd_floating_point, "SIMD floating-point exception" ) ;
126
+ exception ! ( handler_virtualization, "Virtualization exception" ) ;
127
+ exception_errcode ! (
128
+ handler_vmm_communication_exception,
129
+ "VMM communication exception"
130
+ ) ;
131
+ exception_errcode ! ( handler_security_exception, "Security exception" ) ;
132
+
133
+ fn cpu_exception ( frame : InterruptStackFrame , name : & ' static str ) -> ! {
134
+ IN_KERNEL_INTERRUPT_HANDLER . store ( true , Ordering :: Relaxed ) ;
135
+ IN_KERNEL_EXCEPTION_HANDLER . store ( true , Ordering :: Relaxed ) ;
136
+ panic ! ( "CPU exception: {}, stack frame: {:?}" , name, frame) ;
137
+ }
138
+
139
+ fn cpu_exception_errcode ( frame : InterruptStackFrame , name : & ' static str , errcode : u64 ) -> ! {
140
+ IN_KERNEL_INTERRUPT_HANDLER . store ( true , Ordering :: Relaxed ) ;
141
+ IN_KERNEL_EXCEPTION_HANDLER . store ( true , Ordering :: Relaxed ) ;
142
+ panic ! (
143
+ "CPU exception: {}, error code: {}, stack frame: {:?}" ,
144
+ name, errcode, frame
145
+ ) ;
146
+ }
147
+
148
+ extern "x86-interrupt" fn handler_page_fault (
149
+ frame : InterruptStackFrame ,
150
+ errcode : idt:: PageFaultErrorCode ,
151
+ ) {
152
+ IN_KERNEL_INTERRUPT_HANDLER . store ( true , Ordering :: Relaxed ) ;
153
+ IN_KERNEL_EXCEPTION_HANDLER . store ( true , Ordering :: Relaxed ) ;
154
+ panic ! (
155
+ "CPU exception: Page fault, error code: {:?}, address: {:?}, stack frame: {:?}" ,
156
+ errcode,
157
+ Cr2 :: read( ) ,
158
+ frame
159
+ ) ;
160
+ }
161
+
162
+ /// Initializes interrupt handling.
163
+ ///
164
+ /// This requires heap allocation to be initialized first.
165
+ pub fn init ( ) {
166
+ let idt = Box :: leak (
167
+ Box :: try_new ( InterruptDescriptorTable :: new ( ) ) . expect ( "Allocation should succeed" ) ,
168
+ ) ;
169
+ idt. divide_error . set_handler_fn ( handler_divide_error) ;
170
+ idt. debug . set_handler_fn ( handler_debug) ;
171
+ idt. non_maskable_interrupt
172
+ . set_handler_fn ( handler_non_maskable_interrupt) ;
173
+ idt. breakpoint . set_handler_fn ( handler_breakpoint) ;
174
+ idt. overflow . set_handler_fn ( handler_overflow) ;
175
+ idt. bound_range_exceeded
176
+ . set_handler_fn ( handler_bound_range_exceeded) ;
177
+ idt. invalid_opcode . set_handler_fn ( handler_invalid_opcode) ;
178
+ idt. device_not_available
179
+ . set_handler_fn ( handler_device_not_available) ;
180
+ idt. double_fault . set_handler_fn ( handler_double_fault) ;
181
+ idt. invalid_tss . set_handler_fn ( handler_invalid_tss) ;
182
+ idt. segment_not_present
183
+ . set_handler_fn ( handler_segment_not_present) ;
184
+ idt. stack_segment_fault
185
+ . set_handler_fn ( handler_stack_segment_fault) ;
186
+ idt. general_protection_fault
187
+ . set_handler_fn ( handler_general_protection_fault) ;
188
+ idt. page_fault . set_handler_fn ( handler_page_fault) ;
189
+ idt. x87_floating_point
190
+ . set_handler_fn ( handler_x87_floating_point) ;
191
+ idt. alignment_check . set_handler_fn ( handler_alignment_check) ;
192
+ idt. machine_check . set_handler_fn ( handler_machine_check) ;
193
+ idt. simd_floating_point
194
+ . set_handler_fn ( handler_simd_floating_point) ;
195
+ idt. virtualization . set_handler_fn ( handler_virtualization) ;
196
+ idt. vmm_communication_exception
197
+ . set_handler_fn ( handler_vmm_communication_exception) ;
198
+ idt. security_exception
199
+ . set_handler_fn ( handler_security_exception) ;
200
+
201
+ idt. load ( ) ;
202
+ }
0 commit comments