aboutsummaryrefslogtreecommitdiff
path: root/src/bits64/segmentation.rs
blob: 4c440e9afb32e1ceb88ce1cc232955eda27b6e9a (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
use core::mem::size_of;

use ::descriptor;
use ::PrivilegeLevel;
pub use ::segmentation::*;
use bits64::task::*;

/// Reload code segment register.
/// Note this is special since we can not directly move
/// to %cs. Instead we push the new segment selector
/// and return value on the stack and use lretq
/// to reload cs and continue at 1:.
#[cfg(target_arch="x86-64")]
pub unsafe fn set_cs(sel: SegmentSelector) {
    asm!("pushq $0; \
          leaq  1f(%rip), %rax; \
          pushq %rax; \
          lretq; \
          1:" :: "ri" (sel.bits() as usize) : "rax" "memory");
}

pub enum SegmentBitness {
    Bits32,
    Bits64,
}

impl SegmentBitness {
    pub fn pack(self) -> Flags {
        match self {
            SegmentBitness::Bits32 => FLAGS_DB,
            SegmentBitness::Bits64 => FLAGS_L,
        }
    }
}

impl SegmentDescriptor {
    pub fn new_memory64(base: u32, limit: u32, ty: Type, accessed: bool, dpl: PrivilegeLevel, bitness: SegmentBitness) -> SegmentDescriptor {
        let ty1 = descriptor::Type::SegmentDescriptor {
            ty: ty,
            accessed: accessed,
        };
        let flags = bitness.pack();
        let seg = SegmentDescriptor::memory_or_tss(base, limit, ty1, dpl, flags);
        seg
    }

    pub fn new_tss64(tss: &TaskStateSegment, dpl: PrivilegeLevel) -> [SegmentDescriptor; 2] {
        let tss_ptr = tss as *const TaskStateSegment;
        let ty1 = descriptor::Type::SystemDescriptor {
            size: true,
            ty: descriptor::SystemType::TssAvailable,
        };
        let seg1 = SegmentDescriptor::memory_or_tss(tss_ptr as u32, size_of::<TaskStateSegment>() as u32, ty1, dpl, Flags::empty());
        let seg2 = SegmentDescriptor::high(tss_ptr as u64);
        [seg1, seg2]
    }
}