#![no_std]
use x86_64::structures::tss::TaskStateSegment;
use atomic_linked_list::atomic_map::AtomicMap;
use spin::Mutex;
use memory::VirtualAddress;
use cpu::CpuId;
pub const DOUBLE_FAULT_IST_INDEX: usize = 0;
static TSS: AtomicMap<CpuId, Mutex<TaskStateSegment>> = AtomicMap::new();
pub fn tss_set_rsp0(new_privilege_stack_top: VirtualAddress) -> Result<(), &'static str> {
let cpu_id = cpu::current_cpu();
let mut tss_entry = TSS.get(&cpu_id).ok_or_else(|| {
log::error!("tss_set_rsp0(): couldn't find TSS for CPU {}", cpu_id);
"No TSS for the current CPU"
})?.lock();
tss_entry.privilege_stack_table[0] = x86_64::VirtAddr::new(new_privilege_stack_top.value() as u64);
Ok(())
}
pub fn create_tss(
cpu_id: CpuId,
double_fault_stack_top_unusable: VirtualAddress,
privilege_stack_top_unusable: VirtualAddress
) -> &'static Mutex<TaskStateSegment> {
let mut tss = TaskStateSegment::new();
tss.privilege_stack_table[0] = x86_64::VirtAddr::new(privilege_stack_top_unusable.value() as u64);
tss.interrupt_stack_table[DOUBLE_FAULT_IST_INDEX] = x86_64::VirtAddr::new(double_fault_stack_top_unusable.value() as u64);
TSS.insert(cpu_id, Mutex::new(tss));
let tss_ref = TSS.get(&cpu_id).unwrap(); tss_ref
}