11496ba7bSLoGin use x86::{current::task::TaskStateSegment, segmentation::SegmentSelector, Ring}; 21496ba7bSLoGin 31496ba7bSLoGin use crate::{ 41496ba7bSLoGin mm::{percpu::PerCpu, VirtAddr}, 51496ba7bSLoGin smp::core::smp_get_processor_id, 61496ba7bSLoGin }; 71496ba7bSLoGin 81496ba7bSLoGin // === 段选择子在GDT中的索引 === 91496ba7bSLoGin /// kernel code segment selector 101496ba7bSLoGin pub const KERNEL_CS: SegmentSelector = SegmentSelector::new(1, Ring::Ring0); 111496ba7bSLoGin /// kernel data segment selector 121496ba7bSLoGin pub const KERNEL_DS: SegmentSelector = SegmentSelector::new(2, Ring::Ring0); 131496ba7bSLoGin /// user data segment selector 1416033951SGnoCiYeH pub const USER_DS: SegmentSelector = SegmentSelector::new(5, Ring::Ring3); 1516033951SGnoCiYeH /// user code segment selector 1616033951SGnoCiYeH /// 如果改这里,记得改syscall_64里面写死的常量 1716033951SGnoCiYeH pub const USER_CS: SegmentSelector = SegmentSelector::new(6, Ring::Ring3); 181496ba7bSLoGin 191496ba7bSLoGin static mut TSS_MANAGER: TSSManager = TSSManager::new(); 201496ba7bSLoGin 211496ba7bSLoGin extern "C" { 221496ba7bSLoGin static mut GDT_Table: [u64; 512]; 231496ba7bSLoGin } 241496ba7bSLoGin /// 切换fs和gs段寄存器 251496ba7bSLoGin /// 261496ba7bSLoGin /// 由于需要return使得它生效,所以不能inline 271496ba7bSLoGin #[inline(never)] 281496ba7bSLoGin pub unsafe fn switch_fs_and_gs(fs: SegmentSelector, gs: SegmentSelector) { 291496ba7bSLoGin x86::segmentation::load_fs(fs); 301496ba7bSLoGin x86::segmentation::load_gs(gs); 311496ba7bSLoGin } 321496ba7bSLoGin 331496ba7bSLoGin #[derive(Debug)] 341496ba7bSLoGin pub struct TSSManager { 35e2841179SLoGin tss: [TaskStateSegment; PerCpu::MAX_CPU_NUM as usize], 361496ba7bSLoGin } 371496ba7bSLoGin 381496ba7bSLoGin impl TSSManager { 391496ba7bSLoGin const fn new() -> Self { 401496ba7bSLoGin return Self { 41e2841179SLoGin tss: [TaskStateSegment::new(); PerCpu::MAX_CPU_NUM as usize], 421496ba7bSLoGin }; 431496ba7bSLoGin } 441496ba7bSLoGin 451496ba7bSLoGin /// 获取当前CPU的TSS 461496ba7bSLoGin pub unsafe fn current_tss() -> &'static mut TaskStateSegment { 47e2841179SLoGin &mut TSS_MANAGER.tss[smp_get_processor_id().data() as usize] 481496ba7bSLoGin } 491496ba7bSLoGin 501496ba7bSLoGin /// 加载当前CPU的TSS 511496ba7bSLoGin pub unsafe fn load_tr() { 52e2841179SLoGin let index = (10 + smp_get_processor_id().data() * 2) as u16; 531496ba7bSLoGin let selector = SegmentSelector::new(index, Ring::Ring0); 541496ba7bSLoGin 551496ba7bSLoGin Self::set_tss_descriptor( 561496ba7bSLoGin index, 571496ba7bSLoGin VirtAddr::new(Self::current_tss() as *mut TaskStateSegment as usize), 581496ba7bSLoGin ); 591496ba7bSLoGin x86::task::load_tr(selector); 601496ba7bSLoGin } 611496ba7bSLoGin 621496ba7bSLoGin unsafe fn set_tss_descriptor(index: u16, vaddr: VirtAddr) { 631496ba7bSLoGin const LIMIT: u64 = 103; 641496ba7bSLoGin let gdt_vaddr = VirtAddr::new(&GDT_Table as *const _ as usize); 651496ba7bSLoGin 661496ba7bSLoGin let gdt: &mut [u64] = core::slice::from_raw_parts_mut(gdt_vaddr.data() as *mut u64, 512); 671496ba7bSLoGin 681496ba7bSLoGin let vaddr = vaddr.data() as u64; 691496ba7bSLoGin gdt[index as usize] = (LIMIT & 0xffff) 701496ba7bSLoGin | ((vaddr & 0xffff) << 16) 711496ba7bSLoGin | (((vaddr >> 16) & 0xff) << 32) 721496ba7bSLoGin | (0x89 << 40) 731496ba7bSLoGin | (((vaddr >> 24) & 0xff) << 56); 74*b5b571e0SLoGin gdt[index as usize + 1] = (vaddr >> 32) & 0xffffffff; 751496ba7bSLoGin } 761496ba7bSLoGin } 77