6
6
7
7
use super :: gdt:: GDTEntry ;
8
8
use crate :: address:: VirtAddr ;
9
+ use core:: num:: NonZeroU8 ;
9
10
10
11
// IST offsets
11
- pub const _IST_INVALID: usize = 0 ;
12
- pub const IST_DF : usize = 1 ;
12
+ pub const IST_DF : NonZeroU8 = unsafe { NonZeroU8 :: new_unchecked ( 1 ) } ;
13
13
14
14
#[ derive( Debug , Default , Clone , Copy ) ]
15
- #[ repr( C , packed) ]
15
+ #[ repr( C , packed( 4 ) ) ]
16
16
pub struct X86Tss {
17
- reserved1 : u32 ,
17
+ reserved0 : u32 ,
18
18
pub stacks : [ VirtAddr ; 3 ] ,
19
- pub ist_stacks : [ VirtAddr ; 8 ] ,
19
+ reserved1 : u64 ,
20
+ ist_stacks : [ VirtAddr ; 7 ] ,
20
21
reserved2 : u64 ,
21
22
reserved3 : u16 ,
22
23
io_bmp_base : u16 ,
@@ -27,15 +28,22 @@ pub const TSS_LIMIT: u64 = core::mem::size_of::<X86Tss>() as u64;
27
28
impl X86Tss {
28
29
pub const fn new ( ) -> Self {
29
30
X86Tss {
30
- reserved1 : 0 ,
31
+ reserved0 : 0 ,
31
32
stacks : [ VirtAddr :: null ( ) ; 3 ] ,
32
- ist_stacks : [ VirtAddr :: null ( ) ; 8 ] ,
33
+ reserved1 : 0 ,
34
+ ist_stacks : [ VirtAddr :: null ( ) ; 7 ] ,
33
35
reserved2 : 0 ,
34
36
reserved3 : 0 ,
35
37
io_bmp_base : ( TSS_LIMIT + 1 ) as u16 ,
36
38
}
37
39
}
38
40
41
+ pub fn set_ist_stack ( & mut self , index : NonZeroU8 , addr : VirtAddr ) {
42
+ // IST entries start at index 1
43
+ let index = usize:: from ( index. get ( ) - 1 ) ;
44
+ self . ist_stacks [ index] = addr;
45
+ }
46
+
39
47
pub fn to_gdt_entry ( & self ) -> ( GDTEntry , GDTEntry ) {
40
48
let addr = ( self as * const X86Tss ) as u64 ;
41
49
@@ -60,3 +68,20 @@ impl X86Tss {
60
68
( GDTEntry :: from_raw ( desc0) , GDTEntry :: from_raw ( desc1) )
61
69
}
62
70
}
71
+
72
+ #[ cfg( test) ]
73
+ mod test {
74
+ use super :: * ;
75
+ use core:: mem:: offset_of;
76
+
77
+ #[ test]
78
+ fn test_tss_offsets ( ) {
79
+ assert_eq ! ( offset_of!( X86Tss , reserved0) , 0x0 ) ;
80
+ assert_eq ! ( offset_of!( X86Tss , stacks) , 0x4 ) ;
81
+ assert_eq ! ( offset_of!( X86Tss , reserved1) , 0x1c ) ;
82
+ assert_eq ! ( offset_of!( X86Tss , ist_stacks) , 0x24 ) ;
83
+ assert_eq ! ( offset_of!( X86Tss , reserved2) , 0x5c ) ;
84
+ assert_eq ! ( offset_of!( X86Tss , reserved3) , 0x64 ) ;
85
+ assert_eq ! ( offset_of!( X86Tss , io_bmp_base) , 0x66 ) ;
86
+ }
87
+ }
0 commit comments