From f3532f45492785e8dd06ce42a22401288cfdef29 Mon Sep 17 00:00:00 2001 From: 4lDO2 <4lDO2@protonmail.com> Date: Mon, 8 Jul 2024 13:13:47 +0200 Subject: [PATCH] Fix static mut ref warnings. --- src/acpi/madt.rs | 4 +-- src/arch/x86/interrupt/irq.rs | 4 +-- src/arch/x86_64/interrupt/irq.rs | 6 ++-- src/arch/x86_shared/device/local_apic.rs | 12 +++++--- src/arch/x86_shared/idt.rs | 17 +++++------ src/arch/x86_shared/interrupt/ipi.rs | 10 +++--- src/arch/x86_shared/ipi.rs | 10 +++--- src/cpu_set.rs | 6 ---- src/log.rs | 39 +++++++++++------------- 9 files changed, 50 insertions(+), 58 deletions(-) diff --git a/src/acpi/madt.rs b/src/acpi/madt.rs index 2e950ba227..b5112171b9 100644 --- a/src/acpi/madt.rs +++ b/src/acpi/madt.rs @@ -10,7 +10,7 @@ use super::{find_sdt, sdt::Sdt}; use core::sync::atomic::{AtomicU8, Ordering}; use crate::{ - device::local_apic::LOCAL_APIC, + device::local_apic::the_local_apic, interrupt, start::{kstart_ap, AP_READY, CPU_COUNT}, }; @@ -45,7 +45,7 @@ impl Madt { println!(" APIC: {:>08X}: {}", madt.local_address, madt.flags); - let local_apic = unsafe { &mut LOCAL_APIC }; + let local_apic = unsafe { the_local_apic() }; let me = local_apic.id() as u8; if local_apic.x2 { diff --git a/src/arch/x86/interrupt/irq.rs b/src/arch/x86/interrupt/irq.rs index ab678b661e..2cfb81b7d3 100644 --- a/src/arch/x86/interrupt/irq.rs +++ b/src/arch/x86/interrupt/irq.rs @@ -136,7 +136,7 @@ unsafe fn pic_eoi(irq: u8) { } unsafe fn lapic_eoi() { - local_apic::LOCAL_APIC.eoi() + local_apic::the_local_apic().eoi() } unsafe fn pic_unmask(irq: usize) { @@ -279,7 +279,7 @@ interrupt!(lapic_timer, || { interrupt!(lapic_error, || { println!( "Local apic internal error: ESR={:#0x}", - local_apic::LOCAL_APIC.esr() + local_apic::the_local_apic().esr() ); lapic_eoi(); }); diff --git a/src/arch/x86_64/interrupt/irq.rs b/src/arch/x86_64/interrupt/irq.rs index 71911f3eca..b769a36f85 100644 --- a/src/arch/x86_64/interrupt/irq.rs +++ b/src/arch/x86_64/interrupt/irq.rs @@ -136,7 +136,7 @@ unsafe fn pic_eoi(irq: u8) { } unsafe fn lapic_eoi() { - local_apic::LOCAL_APIC.eoi() + local_apic::the_local_apic().eoi() } unsafe fn pic_unmask(irq: usize) { @@ -282,9 +282,9 @@ interrupt!(aux_timer, || { }); interrupt!(lapic_error, || { - println!( + log::error!( "Local apic internal error: ESR={:#0x}", - local_apic::LOCAL_APIC.esr() + local_apic::the_local_apic().esr() ); lapic_eoi(); }); diff --git a/src/arch/x86_shared/device/local_apic.rs b/src/arch/x86_shared/device/local_apic.rs index fa412a4e4e..7563bee5ae 100644 --- a/src/arch/x86_shared/device/local_apic.rs +++ b/src/arch/x86_shared/device/local_apic.rs @@ -1,4 +1,5 @@ use core::{ + cell::SyncUnsafeCell, ptr::{read_volatile, write_volatile}, sync::atomic::{self, AtomicU32}, }; @@ -8,17 +9,20 @@ use crate::{paging::{KernelMapper, PageFlags, PhysicalAddress, RmmA, RmmArch}, i use crate::arch::cpuid::cpuid; -pub static mut LOCAL_APIC: LocalApic = LocalApic { +static LOCAL_APIC: SyncUnsafeCell = SyncUnsafeCell::new(LocalApic { address: 0, x2: false, -}; +}); +pub unsafe fn the_local_apic() -> &'static mut LocalApic { + &mut *LOCAL_APIC.get() +} pub unsafe fn init(active_table: &mut KernelMapper) { - LOCAL_APIC.init(active_table); + the_local_apic().init(active_table); } pub unsafe fn init_ap() { - LOCAL_APIC.init_ap(); + the_local_apic().init_ap(); } /// Local APIC diff --git a/src/arch/x86_shared/idt.rs b/src/arch/x86_shared/idt.rs index fbd9d6d634..7fd806e241 100644 --- a/src/arch/x86_shared/idt.rs +++ b/src/arch/x86_shared/idt.rs @@ -1,7 +1,5 @@ use core::{ - mem, - num::NonZeroU8, - sync::atomic::{AtomicU32, Ordering}, + cell::SyncUnsafeCell, mem, num::NonZeroU8, sync::atomic::{AtomicU32, Ordering} }; use alloc::boxed::Box; @@ -18,7 +16,7 @@ use crate::{cpu_set::LogicalCpuId, interrupt::*, ipi::IpiKind, paging::PAGE_SIZE use spin::RwLock; -pub static mut INIT_IDT: [IdtEntry; 32] = [IdtEntry::new(); 32]; +pub static INIT_IDT: SyncUnsafeCell<[IdtEntry; 32]> = SyncUnsafeCell::new([IdtEntry::new(); 32]); pub type IdtEntries = [IdtEntry; 256]; pub type IdtReservations = [AtomicU32; 8]; @@ -69,7 +67,7 @@ impl Idt { } } -static mut INIT_BSP_IDT: Idt = Idt::new(); +static INIT_BSP_IDT: SyncUnsafeCell = SyncUnsafeCell::new(Idt::new()); // TODO: VecMap? pub static IDTS: RwLock>> = RwLock::new(None); @@ -141,8 +139,9 @@ macro_rules! use_default_irqs( ); pub unsafe fn init() { - set_exceptions(&mut INIT_IDT); - dtables::lidt(&DescriptorTablePointer::new(&INIT_IDT)); + let idt = &mut *INIT_IDT.get(); + set_exceptions(idt); + dtables::lidt(&DescriptorTablePointer::new(&idt)); } fn set_exceptions(idt: &mut [IdtEntry]) { @@ -193,7 +192,7 @@ pub unsafe fn init_paging_post_heap(cpu_id: LogicalCpuId) { let idts_btree = idts_guard.get_or_insert_with(HashMap::new); if cpu_id == LogicalCpuId::BSP { - idts_btree.insert(cpu_id, &mut INIT_BSP_IDT); + idts_btree.insert(cpu_id, &mut *INIT_BSP_IDT.get()); } else { let idt = idts_btree .entry(cpu_id) @@ -205,7 +204,7 @@ pub unsafe fn init_paging_post_heap(cpu_id: LogicalCpuId) { /// 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(LogicalCpuId::BSP, &mut INIT_BSP_IDT); + init_generic(LogicalCpuId::BSP, &mut *INIT_BSP_IDT.get()); } /// Initializes an IDT for any type of processor. diff --git a/src/arch/x86_shared/interrupt/ipi.rs b/src/arch/x86_shared/interrupt/ipi.rs index 1652211bed..12c69e01b0 100644 --- a/src/arch/x86_shared/interrupt/ipi.rs +++ b/src/arch/x86_shared/interrupt/ipi.rs @@ -1,24 +1,24 @@ use crate::percpu::PercpuBlock; -use crate::{context, device::local_apic::LOCAL_APIC}; +use crate::{context, device::local_apic::the_local_apic}; interrupt!(wakeup, || { - LOCAL_APIC.eoi(); + the_local_apic().eoi(); }); interrupt!(tlb, || { PercpuBlock::current().maybe_handle_tlb_shootdown(); - LOCAL_APIC.eoi(); + the_local_apic().eoi(); }); interrupt!(switch, || { - LOCAL_APIC.eoi(); + the_local_apic().eoi(); let _ = context::switch(); }); interrupt!(pit, || { - LOCAL_APIC.eoi(); + the_local_apic().eoi(); // Switch after a sufficient amount of time since the last switch. context::switch::tick(); diff --git a/src/arch/x86_shared/ipi.rs b/src/arch/x86_shared/ipi.rs index b13e58ed76..440489ed5f 100644 --- a/src/arch/x86_shared/ipi.rs +++ b/src/arch/x86_shared/ipi.rs @@ -25,28 +25,28 @@ pub fn ipi(_kind: IpiKind, _target: IpiTarget) {} #[cfg(feature = "multi_core")] #[inline(always)] pub fn ipi(kind: IpiKind, target: IpiTarget) { - use crate::device::local_apic::LOCAL_APIC; + use crate::device::local_apic::the_local_apic; #[cfg(feature = "profiling")] if matches!(kind, IpiKind::Profile) { let icr = (target as u64) << 18 | 1 << 14 | 0b100 << 8; - unsafe { LOCAL_APIC.set_icr(icr) }; + unsafe { the_local_apic().set_icr(icr) }; return; } let icr = (target as u64) << 18 | 1 << 14 | (kind as u64); - unsafe { LOCAL_APIC.set_icr(icr) }; + unsafe { the_local_apic().set_icr(icr) }; } use crate::cpu_set::LogicalCpuId; #[cfg(feature = "multi_core")] #[inline(always)] pub fn ipi_single(kind: IpiKind, target: LogicalCpuId) { - use crate::device::local_apic::LOCAL_APIC; + use crate::device::local_apic::the_local_apic; unsafe { // TODO: Distinguish between logical and physical CPU IDs - LOCAL_APIC.ipi(target.get(), kind); + the_local_apic().ipi(target.get(), kind); } } diff --git a/src/cpu_set.rs b/src/cpu_set.rs index 54180eaf34..fc2fb6adca 100644 --- a/src/cpu_set.rs +++ b/src/cpu_set.rs @@ -52,8 +52,6 @@ pub struct LogicalCpuSet([AtomicUsize; SET_WORDS]); fn parts(id: LogicalCpuId) -> (usize, u32) { ((id.get() / usize::BITS) as usize, id.get() % usize::BITS) } -const MASK_SIZE: usize = SET_WORDS * core::mem::size_of::(); - impl LogicalCpuSet { pub const fn empty() -> Self { const ZEROES: AtomicUsize = AtomicUsize::new(0); @@ -67,10 +65,6 @@ impl LogicalCpuSet { let (word, bit) = parts(id); *self.0[word].get_mut() & (1 << bit) != 0 } - pub fn contains_now(&self, id: LogicalCpuId) -> bool { - let (word, bit) = parts(id); - self.0[word].load(Ordering::Acquire) & (1 << bit) != 0 - } pub fn atomic_set(&self, id: LogicalCpuId) { let (word, bit) = parts(id); let _ = self.0[word].fetch_or(1 << bit, Ordering::Release); diff --git a/src/log.rs b/src/log.rs index 387b35fc8c..860bd00885 100644 --- a/src/log.rs +++ b/src/log.rs @@ -1,6 +1,5 @@ use alloc::collections::VecDeque; -use core::sync::atomic::{AtomicBool, Ordering}; -use spin::Mutex; +use spin::{Mutex, Once}; pub static LOG: Mutex> = Mutex::new(None); @@ -37,7 +36,6 @@ impl Log { struct RedoxLogger { log_func: fn(&log::Record), - pub initialized: AtomicBool, } impl ::log::Log for RedoxLogger { @@ -50,26 +48,23 @@ impl ::log::Log for RedoxLogger { fn flush(&self) {} } -pub fn init_logger(func: fn(&log::Record)) { - unsafe { - match LOGGER.initialized.load(Ordering::SeqCst) { - false => { - ::log::set_max_level(::log::LevelFilter::Info); - LOGGER.log_func = func; - match ::log::set_logger(&LOGGER) { - Ok(_) => ::log::info!("Logger initialized."), - Err(e) => println!("Logger setup failed! error: {}", e), - } - LOGGER.initialized.store(true, Ordering::SeqCst); - } - true => { - ::log::info!("Tried to reinitialize the logger, which is not possible. Ignoring.") - } +pub fn init_logger(log_func: fn(&log::Record)) { + let mut called = false; + let logger = LOGGER.call_once(|| { + ::log::set_max_level(::log::LevelFilter::Info); + called = true; + + RedoxLogger { + log_func, } + }); + if !called { + log::error!("Tried to reinitialize the logger, which is not possible. Ignoring.") + } + match ::log::set_logger(logger) { + Ok(_) => log::info!("Logger initialized."), + Err(e) => println!("Logger setup failed! error: {}", e), } } -static mut LOGGER: RedoxLogger = RedoxLogger { - log_func: |_| {}, - initialized: AtomicBool::new(false), -}; +static LOGGER: Once = Once::new();