Reduce the difference of idt.rs between x86 and x86_64

This commit is contained in:
bjorn3
2024-02-25 13:58:50 +01:00
parent 39c20720ee
commit e9e3b4487d
3 changed files with 38 additions and 34 deletions
+7 -7
View File
@@ -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<X86IdtEntry> = 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);
+2 -2
View File
@@ -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();
+29 -25
View File
@@ -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<X86IdtEntry> = 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<Option<HashMap<LogicalCpuId, &'static mut Idt>>> = 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<NonZeroU8> {
@@ -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);