ax_cpu/arch/x86_64/entry/
boot.rs1use core::{
6 hint::spin_loop,
7 sync::atomic::{AtomicU8, Ordering},
8};
9
10use x86::{
11 bits64::segmentation::Descriptor64,
12 dtables::{self, DescriptorTablePointer},
13 segmentation::{BuildDescriptor, DescriptorBuilder, GateDescriptorBuilder, cs},
14};
15
16use super::super::context::TrapFrame;
17
18#[repr(C, align(16))]
19pub struct BootVectorTable([Descriptor64; 256]);
22static mut IDT: BootVectorTable = BootVectorTable([Descriptor64::NULL; 256]);
23static STATE: AtomicU8 = AtomicU8::new(0);
24
25core::arch::global_asm!(include_str!("gpr.S"), include_str!("boot.S"),
26 ".purgem PUSH_GENERAL_REGS", ".purgem POP_GENERAL_REGS", dispatch = sym dispatch);
27
28unsafe extern "C" {
29 fn __ax_cpu_x86_boot_0();
30 fn __ax_cpu_x86_boot_1();
31 fn __ax_cpu_x86_boot_2();
32 fn __ax_cpu_x86_boot_3();
33 fn __ax_cpu_x86_boot_4();
34 fn __ax_cpu_x86_boot_5();
35 fn __ax_cpu_x86_boot_6();
36 fn __ax_cpu_x86_boot_7();
37 fn __ax_cpu_x86_boot_8();
38 fn __ax_cpu_x86_boot_9();
39 fn __ax_cpu_x86_boot_10();
40 fn __ax_cpu_x86_boot_11();
41 fn __ax_cpu_x86_boot_12();
42 fn __ax_cpu_x86_boot_13();
43 fn __ax_cpu_x86_boot_14();
44 fn __ax_cpu_x86_boot_15();
45 fn __ax_cpu_x86_boot_16();
46 fn __ax_cpu_x86_boot_17();
47 fn __ax_cpu_x86_boot_18();
48 fn __ax_cpu_x86_boot_19();
49 fn __ax_cpu_x86_boot_20();
50 fn __ax_cpu_x86_boot_21();
51 fn __ax_cpu_x86_boot_22();
52 fn __ax_cpu_x86_boot_23();
53 fn __ax_cpu_x86_boot_24();
54 fn __ax_cpu_x86_boot_25();
55 fn __ax_cpu_x86_boot_26();
56 fn __ax_cpu_x86_boot_27();
57 fn __ax_cpu_x86_boot_28();
58 fn __ax_cpu_x86_boot_29();
59 fn __ax_cpu_x86_boot_30();
60 fn __ax_cpu_x86_boot_31();
61}
62
63unsafe extern "C" fn dispatch(frame: *const TrapFrame) {
64 let frame = unsafe { &*frame };
66 let fault = unsafe { x86::controlregs::cr2() };
68 crate::trap::boot::boot_trap_handler::handle(&crate::trap::boot::BootException {
69 registers: frame.regs,
70 pc: frame.rip as usize,
71 sp: frame.rsp as usize,
72 status: frame.rflags,
73 syndrome: frame.error_code,
74 vector: frame.vector as u8,
75 fault_address: crate::VirtAddr::from_usize(fault as usize),
76 });
77}
78
79pub unsafe fn install() {
87 if STATE
88 .compare_exchange(0, 1, Ordering::Acquire, Ordering::Acquire)
89 .is_ok()
90 {
91 unsafe {
93 core::ptr::addr_of_mut!(IDT).write(BootVectorTable::new());
94 }
95 STATE.store(2, Ordering::Release);
96 } else {
97 while STATE.load(Ordering::Acquire) != 2 {
98 spin_loop();
99 }
100 }
101 unsafe {
104 dtables::lidt(&DescriptorTablePointer {
105 base: core::ptr::addr_of!(IDT.0).cast::<Descriptor64>(),
106 limit: (core::mem::size_of::<BootVectorTable>() - 1) as u16,
107 });
108 }
109}
110
111pub fn current_vector_table() -> usize {
113 let mut pointer: DescriptorTablePointer<Descriptor64> = Default::default();
114 unsafe {
116 dtables::sidt(&mut pointer);
117 }
118 pointer.base as usize
119}
120
121impl Default for BootVectorTable {
122 fn default() -> Self {
123 Self::new()
124 }
125}
126
127impl BootVectorTable {
128 pub fn new() -> Self {
130 let entries = [
131 __ax_cpu_x86_boot_0 as *const () as u64,
132 __ax_cpu_x86_boot_1 as *const () as u64,
133 __ax_cpu_x86_boot_2 as *const () as u64,
134 __ax_cpu_x86_boot_3 as *const () as u64,
135 __ax_cpu_x86_boot_4 as *const () as u64,
136 __ax_cpu_x86_boot_5 as *const () as u64,
137 __ax_cpu_x86_boot_6 as *const () as u64,
138 __ax_cpu_x86_boot_7 as *const () as u64,
139 __ax_cpu_x86_boot_8 as *const () as u64,
140 __ax_cpu_x86_boot_9 as *const () as u64,
141 __ax_cpu_x86_boot_10 as *const () as u64,
142 __ax_cpu_x86_boot_11 as *const () as u64,
143 __ax_cpu_x86_boot_12 as *const () as u64,
144 __ax_cpu_x86_boot_13 as *const () as u64,
145 __ax_cpu_x86_boot_14 as *const () as u64,
146 __ax_cpu_x86_boot_15 as *const () as u64,
147 __ax_cpu_x86_boot_16 as *const () as u64,
148 __ax_cpu_x86_boot_17 as *const () as u64,
149 __ax_cpu_x86_boot_18 as *const () as u64,
150 __ax_cpu_x86_boot_19 as *const () as u64,
151 __ax_cpu_x86_boot_20 as *const () as u64,
152 __ax_cpu_x86_boot_21 as *const () as u64,
153 __ax_cpu_x86_boot_22 as *const () as u64,
154 __ax_cpu_x86_boot_23 as *const () as u64,
155 __ax_cpu_x86_boot_24 as *const () as u64,
156 __ax_cpu_x86_boot_25 as *const () as u64,
157 __ax_cpu_x86_boot_26 as *const () as u64,
158 __ax_cpu_x86_boot_27 as *const () as u64,
159 __ax_cpu_x86_boot_28 as *const () as u64,
160 __ax_cpu_x86_boot_29 as *const () as u64,
161 __ax_cpu_x86_boot_30 as *const () as u64,
162 __ax_cpu_x86_boot_31 as *const () as u64,
163 ];
164 let mut table = Self([Descriptor64::NULL; 256]);
165 let selector = cs();
166 for (vector, address) in entries.into_iter().enumerate() {
167 table.0[vector] = DescriptorBuilder::interrupt_descriptor(selector, address)
168 .present()
169 .finish();
170 }
171 table
172 }
173
174 pub unsafe fn install(&self) {
181 unsafe {
183 dtables::lidt(&DescriptorTablePointer {
184 base: self.0.as_ptr(),
185 limit: (core::mem::size_of::<Self>() - 1) as u16,
186 });
187 }
188 }
189}