@@ -7,7 +7,10 @@ use core::sync::atomic::{AtomicUsize, Ordering};
7
7
use lazy_static:: lazy_static;
8
8
use testing:: { exit_qemu, serial_print, serial_println, QemuExitCode } ;
9
9
10
+ use x86_64:: instructions:: interrupts;
11
+
10
12
static BREAKPOINT_HANDLER_CALLED : AtomicUsize = AtomicUsize :: new ( 0 ) ;
13
+ static INTERRUPT_HANDLER_CALLED : AtomicUsize = AtomicUsize :: new ( 0 ) ;
11
14
12
15
#[ no_mangle]
13
16
pub extern "C" fn _start ( ) -> ! {
@@ -16,13 +19,10 @@ pub extern "C" fn _start() -> ! {
16
19
init_test_idt ( ) ;
17
20
18
21
// invoke a breakpoint exception
19
- x86_64 :: instructions :: interrupts:: int3 ( ) ;
22
+ interrupts:: int3 ( ) ;
20
23
21
24
match BREAKPOINT_HANDLER_CALLED . load ( Ordering :: SeqCst ) {
22
- 1 => {
23
- serial_println ! ( "[ok]" ) ;
24
- exit_qemu ( QemuExitCode :: Success ) ;
25
- }
25
+ 1 => { }
26
26
0 => {
27
27
serial_println ! ( "[failed]" ) ;
28
28
serial_println ! ( " Breakpoint handler was not called." ) ;
@@ -35,6 +35,29 @@ pub extern "C" fn _start() -> ! {
35
35
}
36
36
}
37
37
38
+ serial_print ! ( "interrupt 42... " ) ;
39
+ unsafe { interrupts:: software_interrupt :: < 42 > ( ) } ;
40
+ serial_print ! ( "interrupt 77... " ) ;
41
+ unsafe { interrupts:: software_interrupt :: < 77 > ( ) } ;
42
+ serial_print ! ( "interrupt 42... " ) ;
43
+ unsafe { interrupts:: software_interrupt :: < 42 > ( ) } ;
44
+
45
+ match INTERRUPT_HANDLER_CALLED . load ( Ordering :: SeqCst ) {
46
+ 3 => { }
47
+ 0 => {
48
+ serial_println ! ( "[failed]" ) ;
49
+ serial_println ! ( " Interrupt handler was not called." ) ;
50
+ exit_qemu ( QemuExitCode :: Failed ) ;
51
+ }
52
+ other => {
53
+ serial_println ! ( "[failed]" ) ;
54
+ serial_println ! ( " Interrupt handler was called {} times" , other) ;
55
+ exit_qemu ( QemuExitCode :: Failed ) ;
56
+ }
57
+ }
58
+
59
+ serial_println ! ( "[ok]" ) ;
60
+ exit_qemu ( QemuExitCode :: Success ) ;
38
61
loop { }
39
62
}
40
63
@@ -49,6 +72,8 @@ lazy_static! {
49
72
static ref TEST_IDT : InterruptDescriptorTable = {
50
73
let mut idt = InterruptDescriptorTable :: new( ) ;
51
74
idt. breakpoint. set_handler_fn( breakpoint_handler) ;
75
+ idt[ 42 ] . set_handler_fn( interrupt_handler) ;
76
+ idt[ 77 ] . set_handler_fn( interrupt_handler) ;
52
77
idt
53
78
} ;
54
79
}
@@ -60,3 +85,7 @@ pub fn init_test_idt() {
60
85
extern "x86-interrupt" fn breakpoint_handler ( _stack_frame : & mut InterruptStackFrame ) {
61
86
BREAKPOINT_HANDLER_CALLED . fetch_add ( 1 , Ordering :: SeqCst ) ;
62
87
}
88
+
89
+ extern "x86-interrupt" fn interrupt_handler ( _stack_frame : & mut InterruptStackFrame ) {
90
+ INTERRUPT_HANDLER_CALLED . fetch_add ( 1 , Ordering :: SeqCst ) ;
91
+ }
0 commit comments