1use super::ring::Ring;
8use kernel::utilities::registers::register_bitfields;
9use tock_registers::LocalRegisterCopy;
10
11#[cfg(target_arch = "x86")]
12use core::arch::asm;
13
14macro_rules! bit {
15 ($x:expr) => {
16 1 << $x
17 };
18}
19
20register_bitfields![u16,
21 pub SEGMENT_SELECTOR[
27 RPL OFFSET(0) NUMBITS(2) [],
28 TI OFFSET (2) NUMBITS(1) [
29 GDT = 0,
30 LDT = 1
31 ],
32 INDEX OFFSET (3) NUMBITS (12) []
33 ],
34];
35
36#[repr(transparent)]
37#[derive(Copy, Clone, Debug)]
38pub struct SegmentSelector(LocalRegisterCopy<u16, SEGMENT_SELECTOR::Register>);
39
40impl SegmentSelector {
41 pub const fn new(index: u16, rpl: Ring) -> SegmentSelector {
46 SegmentSelector(LocalRegisterCopy::new(index << 3 | (rpl as u16)))
47 }
48
49 pub fn index(&self) -> u16 {
51 self.0.get() >> 3
52 }
53
54 pub fn from_raw(bits: u16) -> SegmentSelector {
56 SegmentSelector(LocalRegisterCopy::new(bits))
57 }
58
59 pub fn bits(&self) -> u16 {
60 self.0.get()
61 }
62}
63
64#[derive(Copy, Clone, Debug, Default)]
67#[repr(C, packed)]
68pub struct Descriptor {
69 pub lower: u32,
70 pub upper: u32,
71}
72
73impl Descriptor {
74 pub const NULL: Descriptor = Descriptor { lower: 0, upper: 0 };
75
76 pub(crate) fn apply_builder_settings(&mut self, builder: &DescriptorBuilder) {
77 if let Some(ring) = builder.dpl {
78 self.set_dpl(ring)
79 }
80
81 if let Some((base, limit)) = builder.base_limit {
82 self.set_base_limit(base as u32, limit as u32)
83 }
84
85 if let Some((selector, offset)) = builder.selector_offset {
86 self.set_selector_offset(selector, offset as u32)
87 }
88
89 if builder.present {
90 self.set_p();
91 }
92 if builder.avl {
93 self.set_avl();
94 }
95 if builder.db {
96 self.set_db();
97 }
98 if builder.limit_granularity_4k {
99 self.set_g();
100 }
101 if builder.l {
102 self.set_l();
103 }
104 }
105
106 pub fn set_dpl(&mut self, ring: Ring) {
109 assert!(ring as u32 <= 0b11);
110 self.upper &= !(0b11 << 13);
111 self.upper |= (ring as u32) << 13;
112 }
113
114 pub fn set_base_limit(&mut self, base: u32, limit: u32) {
115 self.lower = 0;
117 self.upper &= 0x00F0FF00;
118
119 self.lower |= base << 16;
121 self.upper |= (base >> 16) & 0xff;
122 self.upper |= (base >> 24) << 24;
123
124 self.lower |= limit & 0xffff;
126 let limit_last_four_bits = (limit >> 16) & 0x0f;
127 self.upper |= limit_last_four_bits << 16;
128 }
129
130 pub fn set_selector_offset(&mut self, selector: SegmentSelector, offset: u32) {
135 self.lower = 0;
137 self.upper &= 0x0000ffff;
138
139 self.lower |= (selector.bits() as u32) << 16;
141
142 self.lower |= offset & 0x0000ffff;
144 self.upper |= offset & 0xffff0000;
145 }
146
147 pub fn set_type(&mut self, typ: u8) {
152 self.upper &= !(0x0f << 8); self.upper |= (typ as u32 & 0x0f) << 8;
154 }
155
156 pub fn set_p(&mut self) {
161 self.upper |= bit!(15);
162 }
163
164 pub fn set_avl(&mut self) {
166 self.upper |= bit!(20);
167 }
168
169 pub fn set_db(&mut self) {
173 self.upper |= bit!(22);
174 }
175
176 pub fn set_g(&mut self) {
181 self.upper |= bit!(23);
182 }
183
184 pub fn set_l(&mut self) {
190 self.upper |= bit!(21);
191 }
192
193 pub fn set_s(&mut self) {
195 self.upper |= bit!(12);
196 }
197}
198
199pub trait BuildDescriptor<Descriptor> {
200 fn finish(&self) -> Descriptor;
201}
202
203impl BuildDescriptor<Descriptor> for DescriptorBuilder {
204 fn finish(&self) -> Descriptor {
205 let mut desc = Descriptor::default();
206 desc.apply_builder_settings(self);
207 let typ = match self.typ {
208 Some(DescriptorType::System32(typ)) => typ as u8,
209 Some(DescriptorType::Data(typ)) => {
210 desc.set_s();
211 typ as u8
212 }
213 Some(DescriptorType::Code(typ)) => {
214 desc.set_s();
215 typ as u8
216 }
217 None => unreachable!("Type not set, this is a library bug in x86."),
218 };
219 desc.set_type(typ);
220 desc
221 }
222}
223
224#[repr(u8)]
227#[derive(Copy, Clone, Debug, Eq, PartialEq)]
228pub enum CodeSegmentType {
229 Execute = 0b1000,
231
232 ExecuteAccessed = 0b1001,
234
235 ExecuteRead = 0b1010,
237
238 ExecuteReadAccessed = 0b1011,
240
241 ExecuteConforming = 0b1100,
243
244 ExecuteConformingAccessed = 0b1101,
246
247 ExecuteReadConforming = 0b1110,
249
250 ExecuteReadConformingAccessed = 0b1111,
252}
253
254#[repr(u8)]
257#[derive(Copy, Clone, Debug, Eq, PartialEq)]
258pub enum DataSegmentType {
259 ReadOnly = 0b0000,
261
262 ReadOnlyAccessed = 0b0001,
264
265 ReadWrite = 0b0010,
267
268 ReadWriteAccessed = 0b0011,
270
271 ReadExpand = 0b0100,
273
274 ReadExpandAccessed = 0b0101,
276
277 ReadWriteExpand = 0b0110,
279
280 ReadWriteExpandAccessed = 0b0111,
282}
283
284pub trait GateDescriptorBuilder<Size> {
287 fn tss_descriptor(base: u64, limit: u64, available: bool) -> Self;
288 fn call_gate_descriptor(selector: SegmentSelector, offset: Size) -> Self;
289 fn interrupt_descriptor(selector: SegmentSelector, offset: Size) -> Self;
290 fn trap_gate_descriptor(selector: SegmentSelector, offset: Size) -> Self;
291}
292
293impl GateDescriptorBuilder<u32> for DescriptorBuilder {
294 fn tss_descriptor(base: u64, limit: u64, available: bool) -> DescriptorBuilder {
295 let typ = match available {
296 true => DescriptorType::System32(SystemDescriptorTypes32::TssAvailable32),
297 false => DescriptorType::System32(SystemDescriptorTypes32::TssBusy32),
298 };
299 DescriptorBuilder::with_base_limit(base, limit).set_type(typ)
300 }
301
302 fn call_gate_descriptor(selector: SegmentSelector, offset: u32) -> DescriptorBuilder {
303 DescriptorBuilder::with_selector_offset(selector, offset.into()).set_type(
304 DescriptorType::System32(SystemDescriptorTypes32::CallGate32),
305 )
306 }
307
308 fn interrupt_descriptor(selector: SegmentSelector, offset: u32) -> DescriptorBuilder {
309 DescriptorBuilder::with_selector_offset(selector, offset.into()).set_type(
310 DescriptorType::System32(SystemDescriptorTypes32::InterruptGate32),
311 )
312 }
313
314 fn trap_gate_descriptor(selector: SegmentSelector, offset: u32) -> DescriptorBuilder {
315 DescriptorBuilder::with_selector_offset(selector, offset.into()).set_type(
316 DescriptorType::System32(SystemDescriptorTypes32::TrapGate32),
317 )
318 }
319}
320
321pub trait SegmentDescriptorBuilder<Size> {
323 fn code_descriptor(base: Size, limit: Size, cst: CodeSegmentType) -> Self;
324 fn data_descriptor(base: Size, limit: Size, dst: DataSegmentType) -> Self;
325}
326
327impl SegmentDescriptorBuilder<u32> for DescriptorBuilder {
328 fn code_descriptor(base: u32, limit: u32, cst: CodeSegmentType) -> DescriptorBuilder {
329 DescriptorBuilder::with_base_limit(base.into(), limit.into())
330 .set_type(DescriptorType::Code(cst))
331 }
332
333 fn data_descriptor(base: u32, limit: u32, dst: DataSegmentType) -> DescriptorBuilder {
334 DescriptorBuilder::with_base_limit(base.into(), limit.into())
335 .set_type(DescriptorType::Data(dst))
336 }
337}
338
339pub struct DescriptorBuilder {
341 pub(crate) base_limit: Option<(u64, u64)>,
345
346 pub(crate) selector_offset: Option<(SegmentSelector, u64)>,
348
349 pub(crate) typ: Option<DescriptorType>,
351
352 pub(crate) dpl: Option<Ring>,
354
355 pub(crate) present: bool,
357
358 pub(crate) avl: bool,
360
361 pub(crate) db: bool,
363
364 pub(crate) limit_granularity_4k: bool,
366
367 pub(crate) l: bool,
369}
370
371impl DescriptorBuilder {
372 pub(crate) fn with_base_limit(base: u64, limit: u64) -> DescriptorBuilder {
374 DescriptorBuilder {
375 base_limit: Some((base, limit)),
376 selector_offset: None,
377 typ: None,
378 dpl: None,
379 present: false,
380 avl: false,
381 db: false,
382 limit_granularity_4k: false,
383 l: false,
384 }
385 }
386
387 pub(crate) fn with_selector_offset(
389 selector: SegmentSelector,
390 offset: u64,
391 ) -> DescriptorBuilder {
392 DescriptorBuilder {
393 base_limit: None,
394 selector_offset: Some((selector, offset)),
395 typ: None,
396 dpl: None,
397 present: false,
398 avl: false,
399 db: false,
400 limit_granularity_4k: false,
401 l: false,
402 }
403 }
404
405 pub fn limit_granularity_4kb(mut self) -> DescriptorBuilder {
407 self.limit_granularity_4k = true;
408 self
409 }
410
411 pub fn present(mut self) -> DescriptorBuilder {
413 self.present = true;
414 self
415 }
416
417 pub fn dpl(mut self, dpl: Ring) -> DescriptorBuilder {
419 self.dpl = Some(dpl);
420 self
421 }
422
423 pub fn avl(mut self) -> DescriptorBuilder {
425 self.avl = true;
426 self
427 }
428
429 pub fn db(mut self) -> DescriptorBuilder {
431 self.db = true;
432 self
433 }
434
435 pub(crate) fn set_type(mut self, typ: DescriptorType) -> DescriptorBuilder {
436 self.typ = Some(typ);
437 self
438 }
439}
440
441#[cfg(target_arch = "x86")]
445pub unsafe fn load_ss(sel: SegmentSelector) {
446 unsafe {
447 asm!("movw {0:x}, %ss", in(reg) sel.bits(), options(att_syntax));
448 }
449}
450
451#[cfg(target_arch = "x86")]
455pub unsafe fn load_ds(sel: SegmentSelector) {
456 unsafe {
457 asm!("movw {0:x}, %ds", in(reg) sel.bits(), options(att_syntax));
458 }
459}
460
461#[cfg(target_arch = "x86")]
465pub unsafe fn load_es(sel: SegmentSelector) {
466 unsafe {
467 asm!("movw {0:x}, %es", in(reg) sel.bits(), options(att_syntax));
468 }
469}
470
471#[cfg(target_arch = "x86")]
475pub unsafe fn load_fs(sel: SegmentSelector) {
476 unsafe {
477 asm!("movw {0:x}, %fs", in(reg) sel.bits(), options(att_syntax));
478 }
479}
480
481#[cfg(target_arch = "x86")]
485pub unsafe fn load_gs(sel: SegmentSelector) {
486 unsafe {
487 asm!("movw {0:x}, %gs", in(reg) sel.bits(), options(att_syntax));
488 }
489}
490
491#[cfg(target_arch = "x86")]
492pub unsafe fn load_cs(sel: SegmentSelector) {
493 unsafe {
494 asm!("pushl {0}; \
495 pushl $1f; \
496 lretl; \
497 1:", in(reg) sel.bits() as u32, options(att_syntax));
498 }
499}
500
501#[derive(Debug, Eq, PartialEq)]
502pub(crate) enum DescriptorType {
503 System32(SystemDescriptorTypes32),
504 Data(DataSegmentType),
505 Code(CodeSegmentType),
506}
507
508#[allow(clippy::upper_case_acronyms)]
513#[repr(u8)]
514#[derive(Copy, Clone, Debug, Eq, PartialEq)]
515pub enum SystemDescriptorTypes32 {
516 TSSAvailable16 = 0b0001,
518 LDT = 0b0010,
519 TSSBusy16 = 0b0011,
520 CallGate16 = 0b0100,
521 TaskGate = 0b0101,
522 InterruptGate16 = 0b0110,
523 TrapGate16 = 0b0111,
524
525 TssAvailable32 = 0b1001,
527
528 TssBusy32 = 0b1011,
530 CallGate32 = 0b1100,
531
532 InterruptGate32 = 0b1110,
534 TrapGate32 = 0b1111,
535}
536
537#[cfg(not(any(doc, target_arch = "x86")))]
540pub unsafe fn load_ss(_sel: SegmentSelector) {
541 unimplemented!()
542}
543
544#[cfg(not(any(doc, target_arch = "x86")))]
545pub unsafe fn load_ds(_sel: SegmentSelector) {
546 unimplemented!()
547}
548
549#[cfg(not(any(doc, target_arch = "x86")))]
550pub unsafe fn load_es(_sel: SegmentSelector) {
551 unimplemented!()
552}
553
554#[cfg(not(any(doc, target_arch = "x86")))]
555pub unsafe fn load_fs(_sel: SegmentSelector) {
556 unimplemented!()
557}
558
559#[cfg(not(any(doc, target_arch = "x86")))]
560pub unsafe fn load_gs(_sel: SegmentSelector) {
561 unimplemented!()
562}
563
564#[cfg(not(any(doc, target_arch = "x86")))]
565pub unsafe fn load_cs(_sel: SegmentSelector) {
566 unimplemented!()
567}