@@ -7,6 +7,16 @@ use zerocopy::FromZeros;
7
7
pub const UREG_TRAPNO_OFFSET : usize = 19 * core:: mem:: size_of :: < u64 > ( ) ;
8
8
pub const UREG_CS_OFFSET : usize = 22 * core:: mem:: size_of :: < u64 > ( ) ;
9
9
10
+ #[ derive( Clone , Copy , Debug , FromZeros ) ]
11
+ #[ repr( transparent) ]
12
+ pub struct HPA ( pub u64 ) ;
13
+
14
+ impl HPA {
15
+ pub fn from_phys ( pa : u64 ) -> HPA {
16
+ HPA ( pa)
17
+ }
18
+ }
19
+
10
20
/// The user register and trap frame structure.
11
21
///
12
22
/// This stores both user state during system calls, and
@@ -89,11 +99,36 @@ impl Default for Label {
89
99
90
100
/// The machine structure, which describes a CPU.
91
101
///
102
+ /// The small stacks, for specific exceptions, come first and
103
+ /// occupy the first 64KiB of the Mach. These have guard pages
104
+ /// immediately _after_ their data areas, which serve as guards
105
+ /// for the subsequent data. Since the Mach is mapped in a
106
+ /// per-CPU portion of virtual address space that is offset from
107
+ /// a 2MiB boundary, we know that the first stack is de facto
108
+ /// guarded.
109
+ ///
110
+ /// The main kstack for the scheduler comes next, and occupies
111
+ /// the next 64KiB. It is guarded by the NMI stack's guard page.
112
+ ///
113
+ /// Thus, stacks and their guards take up the first 128KiB of
114
+ /// virtual space in the Mach.
115
+ ///
116
+ /// Next, we have the smaller Mach data itself; this includes the
117
+ /// space required for the structures used in the pseudo-recursive
118
+ /// page table implementation.
119
+ ///
92
120
/// Warning: the layout of this structure is known to assembly
93
121
/// language.
94
122
#[ derive( FromZeros ) ]
95
123
#[ repr( C , align( 65536 ) ) ]
96
124
pub struct Mach {
125
+ pub debug_stack : ExStack , // Stack for debug exceptions
126
+ pub bp_stack : ExStack , // Stack for breakpoint exceptions
127
+ pub df_stack : ExStack , // Stack for double faults
128
+ pub nmi_stack : ExStack , // Stack for NMIs
129
+ pub zero : Page , // Mapped to (per-node) read-only zeroed page
130
+ pub stack : KStack , // Kernel stack for scheduler
131
+
97
132
me : * mut Mach , // %gs:0 is a `*mut Mach` pointing to this `Mach`.
98
133
scratch : usize , // A scratch word used on entry to kernel
99
134
splpc : usize , // PC of last caller to ` k`. Cleared by `spllo`.
@@ -114,24 +149,22 @@ pub struct Mach {
114
149
115
150
sched : Label ,
116
151
117
- // Architecturally defined.
118
- pub tss : Tss ,
119
-
120
- // All preceding data fits within a single 4KiB page. Structures
121
- // that follow are sized in page multiples and aligned.
122
- pml4 : Page , // PML4 root page table for this Mach
123
- pml3 : Page , // The PML3 that maps the kernel for this mach
124
- pml2 : Page , // PML2 for low 1GiB
125
- pml1 : Page , // PML1 for low 2MiB
126
- pub idt : Idt , // Interrupt descriptor table
127
- zero : Page , // Read-only, zeroed page
128
- pub df_stack : ExStack , // Stack for double faults
129
- pub debug_stack : ExStack , // Stack for debug exceptions
130
- pub nmi_stack : ExStack , // Stack for NMIs
131
- pub stack : KStack , // Kernel stack for scheduler
132
- pub gdt : Gdt , // Gdt is aligned to 64KiB.
152
+ // All preceding data after the stack fits within a single 4KiB page.
153
+ // Paging structures that follow are sized in page multiples and aligned.
154
+ pml4 : PTable , // PML4 root page table for this Mach
155
+ pml3 : PTable , // PML3 for rec 512GiB (root of all subtrees)
156
+ pml2 : PTable , // PML2 for rec 1GiB
157
+ pml1 : PTable , // PML1 for rec 2MiB (PML4 and all PML3s)
158
+ mpml3 : PTable , // PML3 for mapping region
159
+ mpml2 : PTable , // PML2 for mapping region
160
+ mpml1 : PTable , // PML1 for mapping region
161
+
162
+ // Architecturally defined data.
163
+ pub tss : Tss , // Truly per-CPU
164
+ idt : Idt , // Mapped to per-node IDT
165
+ gdt : Gdt , // Mapped to per-CPU GDT; padded to 64k with zeros
133
166
}
134
- static_assertions:: const_assert_eq!( core:: mem:: offset_of!( Mach , pml4) , 4096 ) ;
167
+ static_assertions:: const_assert_eq!( core:: mem:: offset_of!( Mach , pml4) , 65536 * 2 + 4096 ) ;
135
168
static_assertions:: const_assert_eq!( core:: mem:: offset_of!( Mach , stack) , 65536 ) ;
136
169
137
170
impl Mach {
@@ -142,10 +175,9 @@ impl Mach {
142
175
( 0 , & mut self . stack ) ,
143
176
( trap:: NMI_TRAPNO , & mut self . nmi_stack ) ,
144
177
( trap:: DEBUG_TRAPNO , & mut self . debug_stack ) ,
178
+ ( trap:: BREAKPOINT_TRAPNO , & mut self . bp_stack ) ,
145
179
( trap:: DOUBLE_FAULT_TRAPNO , & mut self . df_stack ) ,
146
180
] ) ;
147
- self . gdt . init ( & self . tss ) ;
148
- self . idt . init ( trap:: stubs ( ) ) ;
149
181
unsafe {
150
182
self . gdt . load ( ) ;
151
183
self . idt . load ( ) ;
@@ -224,6 +256,16 @@ impl Flags {
224
256
}
225
257
}
226
258
259
+ #[ derive( FromZeros ) ]
260
+ #[ repr( C , align( 4096 ) ) ]
261
+ pub struct PTable ( [ u64 ; 512 ] ) ;
262
+
263
+ impl PTable {
264
+ pub fn array_mut ( & mut self ) -> & mut [ u64 ; 512 ] {
265
+ & mut self . 0
266
+ }
267
+ }
268
+
227
269
/// The smallest basic page type.
228
270
#[ derive( FromZeros ) ]
229
271
#[ repr( C , align( 4096 ) ) ]
0 commit comments