xref: /DragonOS/kernel/src/arch/x86_64/process/table.rs (revision bd70d2d1f490aabd570a5301b858bd5eb04149fa)
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)]
switch_fs_and_gs(fs: SegmentSelector, gs: SegmentSelector)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 {
new() -> Self391496ba7bSLoGin     const fn new() -> Self {
401496ba7bSLoGin         return Self {
41e2841179SLoGin             tss: [TaskStateSegment::new(); PerCpu::MAX_CPU_NUM as usize],
421496ba7bSLoGin         };
431496ba7bSLoGin     }
441496ba7bSLoGin 
451496ba7bSLoGin     /// 获取当前CPU的TSS
current_tss() -> &'static mut TaskStateSegment461496ba7bSLoGin     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
load_tr()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 
62*bd70d2d1SLoGin     #[allow(static_mut_refs)]
set_tss_descriptor(index: u16, vaddr: VirtAddr)631496ba7bSLoGin     unsafe fn set_tss_descriptor(index: u16, vaddr: VirtAddr) {
641496ba7bSLoGin         const LIMIT: u64 = 103;
651496ba7bSLoGin         let gdt_vaddr = VirtAddr::new(&GDT_Table as *const _ as usize);
661496ba7bSLoGin 
671496ba7bSLoGin         let gdt: &mut [u64] = core::slice::from_raw_parts_mut(gdt_vaddr.data() as *mut u64, 512);
681496ba7bSLoGin 
691496ba7bSLoGin         let vaddr = vaddr.data() as u64;
701496ba7bSLoGin         gdt[index as usize] = (LIMIT & 0xffff)
711496ba7bSLoGin             | ((vaddr & 0xffff) << 16)
721496ba7bSLoGin             | (((vaddr >> 16) & 0xff) << 32)
731496ba7bSLoGin             | (0x89 << 40)
741496ba7bSLoGin             | (((vaddr >> 24) & 0xff) << 56);
75b5b571e0SLoGin         gdt[index as usize + 1] = (vaddr >> 32) & 0xffffffff;
761496ba7bSLoGin     }
771496ba7bSLoGin }
78