xref: /DragonOS/kernel/src/arch/x86_64/init/mod.rs (revision 5b59005f930266d0e9c0092373e894826150f862)
1*5b59005fSLoGin use core::sync::atomic::{compiler_fence, Ordering};
2*5b59005fSLoGin 
3*5b59005fSLoGin use system_error::SystemError;
4*5b59005fSLoGin use x86::dtables::DescriptorTablePointer;
5*5b59005fSLoGin 
6*5b59005fSLoGin use crate::{
7*5b59005fSLoGin     arch::process::table::TSSManager,
8*5b59005fSLoGin     driver::pci::pci::pci_init,
9*5b59005fSLoGin     include::bindings::bindings::{cpu_init, irq_init},
10*5b59005fSLoGin     init::init::start_kernel,
11*5b59005fSLoGin     kdebug,
12*5b59005fSLoGin     mm::{MemoryManagementArch, PhysAddr},
13*5b59005fSLoGin };
14*5b59005fSLoGin 
15*5b59005fSLoGin use super::{
16*5b59005fSLoGin     driver::{
17*5b59005fSLoGin         hpet::{hpet_init, hpet_instance},
18*5b59005fSLoGin         tsc::TSCManager,
19*5b59005fSLoGin     },
20*5b59005fSLoGin     MMArch,
21*5b59005fSLoGin };
22*5b59005fSLoGin 
2345626c85SLoGin #[derive(Debug)]
2445626c85SLoGin pub struct ArchBootParams {}
2545626c85SLoGin 
2645626c85SLoGin impl ArchBootParams {
2745626c85SLoGin     pub const DEFAULT: Self = ArchBootParams {};
2845626c85SLoGin }
29*5b59005fSLoGin 
30*5b59005fSLoGin extern "C" {
31*5b59005fSLoGin     static mut GDT_Table: [usize; 0usize];
32*5b59005fSLoGin     static mut IDT_Table: [usize; 0usize];
33*5b59005fSLoGin     fn head_stack_start();
34*5b59005fSLoGin 
35*5b59005fSLoGin     fn multiboot2_init(mb2_info: u64, mb2_magic: u32) -> bool;
36*5b59005fSLoGin     fn __init_set_cpu_stack_start(cpu: u32, stack_start: u64);
37*5b59005fSLoGin     fn sys_vector_init();
38*5b59005fSLoGin }
39*5b59005fSLoGin 
40*5b59005fSLoGin #[no_mangle]
41*5b59005fSLoGin unsafe extern "C" fn kernel_main(
42*5b59005fSLoGin     mb2_info: u64,
43*5b59005fSLoGin     mb2_magic: u64,
44*5b59005fSLoGin     bsp_gdt_size: u64,
45*5b59005fSLoGin     bsp_idt_size: u64,
46*5b59005fSLoGin ) -> ! {
47*5b59005fSLoGin     let mut gdtp = DescriptorTablePointer::<usize>::default();
48*5b59005fSLoGin     let gdt_vaddr =
49*5b59005fSLoGin         MMArch::phys_2_virt(PhysAddr::new(&GDT_Table as *const usize as usize)).unwrap();
50*5b59005fSLoGin     let idt_vaddr =
51*5b59005fSLoGin         MMArch::phys_2_virt(PhysAddr::new(&IDT_Table as *const usize as usize)).unwrap();
52*5b59005fSLoGin     gdtp.base = gdt_vaddr.data() as *const usize;
53*5b59005fSLoGin     gdtp.limit = bsp_gdt_size as u16 - 1;
54*5b59005fSLoGin 
55*5b59005fSLoGin     let mut idtp = DescriptorTablePointer::<usize>::default();
56*5b59005fSLoGin     idtp.base = idt_vaddr.data() as *const usize;
57*5b59005fSLoGin     idtp.limit = bsp_idt_size as u16 - 1;
58*5b59005fSLoGin 
59*5b59005fSLoGin     x86::dtables::lgdt(&gdtp);
60*5b59005fSLoGin     x86::dtables::lidt(&idtp);
61*5b59005fSLoGin 
62*5b59005fSLoGin     compiler_fence(Ordering::SeqCst);
63*5b59005fSLoGin     multiboot2_init(mb2_info, (mb2_magic & 0xFFFF_FFFF) as u32);
64*5b59005fSLoGin     compiler_fence(Ordering::SeqCst);
65*5b59005fSLoGin 
66*5b59005fSLoGin     start_kernel();
67*5b59005fSLoGin }
68*5b59005fSLoGin 
69*5b59005fSLoGin /// 在内存管理初始化之前的架构相关的早期初始化
70*5b59005fSLoGin #[inline(never)]
71*5b59005fSLoGin pub fn early_setup_arch() -> Result<(), SystemError> {
72*5b59005fSLoGin     let stack_start = unsafe { *(head_stack_start as *const u64) } as usize;
73*5b59005fSLoGin     kdebug!("head_stack_start={:#x}\n", stack_start);
74*5b59005fSLoGin     unsafe {
75*5b59005fSLoGin         let gdt_vaddr =
76*5b59005fSLoGin             MMArch::phys_2_virt(PhysAddr::new(&GDT_Table as *const usize as usize)).unwrap();
77*5b59005fSLoGin         let idt_vaddr =
78*5b59005fSLoGin             MMArch::phys_2_virt(PhysAddr::new(&IDT_Table as *const usize as usize)).unwrap();
79*5b59005fSLoGin 
80*5b59005fSLoGin         kdebug!("GDT_Table={:?}, IDT_Table={:?}\n", gdt_vaddr, idt_vaddr);
81*5b59005fSLoGin     }
82*5b59005fSLoGin 
83*5b59005fSLoGin     set_current_core_tss(stack_start, 0);
84*5b59005fSLoGin     unsafe { TSSManager::load_tr() };
85*5b59005fSLoGin     unsafe { __init_set_cpu_stack_start(0, stack_start as u64) };
86*5b59005fSLoGin     unsafe { sys_vector_init() };
87*5b59005fSLoGin 
88*5b59005fSLoGin     return Ok(());
89*5b59005fSLoGin }
90*5b59005fSLoGin 
91*5b59005fSLoGin /// 架构相关的初始化
92*5b59005fSLoGin #[inline(never)]
93*5b59005fSLoGin pub fn setup_arch() -> Result<(), SystemError> {
94*5b59005fSLoGin     unsafe {
95*5b59005fSLoGin         irq_init();
96*5b59005fSLoGin         cpu_init();
97*5b59005fSLoGin     }
98*5b59005fSLoGin 
99*5b59005fSLoGin     // todo: 将来pci接入设备驱动模型之后,删掉这里。
100*5b59005fSLoGin     pci_init();
101*5b59005fSLoGin     return Ok(());
102*5b59005fSLoGin }
103*5b59005fSLoGin 
104*5b59005fSLoGin /// 架构相关的初始化(在IDLE的最后一个阶段)
105*5b59005fSLoGin #[inline(never)]
106*5b59005fSLoGin pub fn setup_arch_post() -> Result<(), SystemError> {
107*5b59005fSLoGin     hpet_init().expect("hpet init failed");
108*5b59005fSLoGin     hpet_instance().hpet_enable().expect("hpet enable failed");
109*5b59005fSLoGin     TSCManager::init().expect("tsc init failed");
110*5b59005fSLoGin 
111*5b59005fSLoGin     return Ok(());
112*5b59005fSLoGin }
113*5b59005fSLoGin 
114*5b59005fSLoGin fn set_current_core_tss(stack_start: usize, ist0: usize) {
115*5b59005fSLoGin     let current_tss = unsafe { TSSManager::current_tss() };
116*5b59005fSLoGin     kdebug!(
117*5b59005fSLoGin         "set_current_core_tss: stack_start={:#x}, ist0={:#x}\n",
118*5b59005fSLoGin         stack_start,
119*5b59005fSLoGin         ist0
120*5b59005fSLoGin     );
121*5b59005fSLoGin     current_tss.set_rsp(x86::Ring::Ring0, stack_start as u64);
122*5b59005fSLoGin     current_tss.set_ist(0, ist0 as u64);
123*5b59005fSLoGin }
124