From e9e3b4487d482f75e052ced031ccbc6e75f5f60a Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 25 Feb 2024 13:58:50 +0100 Subject: [PATCH] Reduce the difference of idt.rs between x86 and x86_64 --- src/arch/x86/idt.rs | 14 +++++------ src/arch/x86/start.rs | 4 ++-- src/arch/x86_64/idt.rs | 54 +++++++++++++++++++++++------------------- 3 files changed, 38 insertions(+), 34 deletions(-) diff --git a/src/arch/x86/idt.rs b/src/arch/x86/idt.rs index 42a765aec9..665c52f0f8 100644 --- a/src/arch/x86/idt.rs +++ b/src/arch/x86/idt.rs @@ -157,28 +157,28 @@ const fn new_idt_reservations() -> [AtomicU32; 8] { } /// Initialize the IDT for a -pub unsafe fn init_paging_post_heap(is_bsp: bool, cpu_id: LogicalCpuId) { +pub unsafe fn init_paging_post_heap(cpu_id: LogicalCpuId) { let mut idts_guard = IDTS.write(); let idts_btree = idts_guard.get_or_insert_with(HashMap::new); - if is_bsp { + if cpu_id == LogicalCpuId::BSP { idts_btree.insert(cpu_id, &mut INIT_BSP_IDT); } else { let idt = idts_btree .entry(cpu_id) .or_insert_with(|| Box::leak(Box::new(Idt::new()))); - init_generic(is_bsp, idt); + init_generic(cpu_id, idt); } } /// Initializes a fully functional IDT for use before it be moved into the map. This is ONLY called /// on the BSP, since the kernel heap is ready for the APs. pub unsafe fn init_paging_bsp() { - init_generic(true, &mut INIT_BSP_IDT); + init_generic(LogicalCpuId::BSP, &mut INIT_BSP_IDT); } /// Initializes an IDT for any type of processor. -pub unsafe fn init_generic(is_bsp: bool, idt: &mut Idt) { +pub unsafe fn init_generic(cpu_id: LogicalCpuId, idt: &mut Idt) { let (current_idt, current_reservations) = (&mut idt.entries, &mut idt.reservations); let idtr: DescriptorTablePointer = DescriptorTablePointer { @@ -250,7 +250,7 @@ pub unsafe fn init_generic(is_bsp: bool, idt: &mut Idt) { // reserve bits 31:0, i.e. the first 32 interrupts, which are reserved for exceptions *current_reservations[0].get_mut() |= 0x0000_0000_FFFF_FFFF; - if is_bsp { + if cpu_id == LogicalCpuId::BSP { // Set up IRQs current_idt[32].set_func(irq::pit_stack); current_idt[33].set_func(irq::keyboard); @@ -278,7 +278,7 @@ pub unsafe fn init_generic(is_bsp: bool, idt: &mut Idt) { current_idt[49].set_func(irq::lapic_error); // reserve bit 49 - *current_reservations[1].get_mut() |= (1 << 17); + *current_reservations[1].get_mut() |= 1 << 17; } use_default_irqs!(current_idt); diff --git a/src/arch/x86/start.rs b/src/arch/x86/start.rs index 499f29d63a..5c0155263c 100644 --- a/src/arch/x86/start.rs +++ b/src/arch/x86/start.rs @@ -185,7 +185,7 @@ pub unsafe extern "C" fn kstart(args_ptr: *const KernelArgs) -> ! { #[cfg(feature = "graphical_debug")] graphical_debug::init_heap(); - idt::init_paging_post_heap(true, LogicalCpuId::BSP); + idt::init_paging_post_heap(LogicalCpuId::BSP); // Activate memory logging log::init(); @@ -266,7 +266,7 @@ pub unsafe extern "C" fn kstart_ap(args_ptr: *const KernelArgsAp) -> ! { gdt::init_paging(stack_end, cpu_id); // Set up IDT for AP - idt::init_paging_post_heap(false, cpu_id); + idt::init_paging_post_heap(cpu_id); // Set up syscall instruction interrupt::syscall::init(); diff --git a/src/arch/x86_64/idt.rs b/src/arch/x86_64/idt.rs index a7dd5aee04..6b90af1735 100644 --- a/src/arch/x86_64/idt.rs +++ b/src/arch/x86_64/idt.rs @@ -1,7 +1,7 @@ use core::{ mem, num::NonZeroU8, - sync::atomic::{AtomicU64, Ordering}, + sync::atomic::{AtomicU32, Ordering}, }; use alloc::boxed::Box; @@ -29,11 +29,11 @@ pub static mut INIT_IDTR: DescriptorTablePointer = DescriptorTableP }; pub type IdtEntries = [IdtEntry; 256]; -pub type IdtReservations = [AtomicU64; 4]; +pub type IdtReservations = [AtomicU32; 8]; #[repr(C)] pub struct Idt { - pub(crate) entries: IdtEntries, + entries: IdtEntries, reservations: IdtReservations, } impl Idt { @@ -45,35 +45,35 @@ impl Idt { } #[inline] pub fn is_reserved(&self, index: u8) -> bool { - let byte_index = index / 64; - let bit = index % 64; + let byte_index = index / 32; + let bit = index % 32; { &self.reservations[usize::from(byte_index)] }.load(Ordering::Acquire) & (1 << bit) != 0 } #[inline] pub fn set_reserved(&self, index: u8, reserved: bool) { - let byte_index = index / 64; - let bit = index % 64; + let byte_index = index / 32; + let bit = index % 32; { &self.reservations[usize::from(byte_index)] } - .fetch_or(u64::from(reserved) << bit, Ordering::AcqRel); + .fetch_or(u32::from(reserved) << bit, Ordering::AcqRel); } #[inline] pub fn is_reserved_mut(&mut self, index: u8) -> bool { - let byte_index = index / 64; - let bit = index % 64; + let byte_index = index / 32; + let bit = index % 32; *{ &mut self.reservations[usize::from(byte_index)] }.get_mut() & (1 << bit) != 0 } #[inline] pub fn set_reserved_mut(&mut self, index: u8, reserved: bool) { - let byte_index = index / 64; - let bit = index % 64; + let byte_index = index / 32; + let bit = index % 32; *{ &mut self.reservations[usize::from(byte_index)] }.get_mut() |= - u64::from(reserved) << bit; + u32::from(reserved) << bit; } } @@ -84,8 +84,8 @@ pub static IDTS: RwLock>> = RwLoc #[inline] pub fn is_reserved(cpu_id: LogicalCpuId, index: u8) -> bool { - let byte_index = index / 64; - let bit = index % 64; + let byte_index = index / 32; + let bit = index % 32; { &IDTS @@ -103,8 +103,8 @@ pub fn is_reserved(cpu_id: LogicalCpuId, index: u8) -> bool { #[inline] pub fn set_reserved(cpu_id: LogicalCpuId, index: u8, reserved: bool) { - let byte_index = index / 64; - let bit = index % 64; + let byte_index = index / 32; + let bit = index % 32; { &IDTS @@ -115,7 +115,7 @@ pub fn set_reserved(cpu_id: LogicalCpuId, index: u8, reserved: bool) { .unwrap() .reservations[usize::from(byte_index)] } - .fetch_or(u64::from(reserved) << bit, Ordering::AcqRel); + .fetch_or(u32::from(reserved) << bit, Ordering::AcqRel); } pub fn allocate_interrupt() -> Option { @@ -137,12 +137,16 @@ pub unsafe fn init() { dtables::lidt(&INIT_IDTR); } -const fn new_idt_reservations() -> [AtomicU64; 4] { +const fn new_idt_reservations() -> [AtomicU32; 8] { [ - AtomicU64::new(0), - AtomicU64::new(0), - AtomicU64::new(0), - AtomicU64::new(0), + AtomicU32::new(0), + AtomicU32::new(0), + AtomicU32::new(0), + AtomicU32::new(0), + AtomicU32::new(0), + AtomicU32::new(0), + AtomicU32::new(0), + AtomicU32::new(0), ] } @@ -271,13 +275,13 @@ pub unsafe fn init_generic(cpu_id: LogicalCpuId, idt: &mut Idt) { current_idt[49].set_func(irq::lapic_error); // reserve bits 49:32, which are for the standard IRQs, and for the local apic timer and error. - *current_reservations[0].get_mut() |= 0x0003_FFFF_0000_0000; + *current_reservations[1].get_mut() |= 0x0003_FFFF; } else { // TODO: use_default_irqs! but also the legacy IRQs that are only needed on one CPU current_idt[49].set_func(irq::lapic_error); // reserve bit 49 - *current_reservations[0].get_mut() |= 1 << 49; + *current_reservations[1].get_mut() |= 1 << 17; } // Set IPI handlers current_idt[IpiKind::Wakeup as usize].set_func(ipi::wakeup);