Remove stable #![feature] and most x86_64 static mut.

This commit is contained in:
4lDO2
2025-02-21 14:16:58 +01:00
parent 09eaf12201
commit f044ffb03b
11 changed files with 114 additions and 77 deletions
+6 -3
View File
@@ -1,4 +1,4 @@
use core::mem;
use core::{cell::SyncUnsafeCell, mem};
use super::{find_sdt, sdt::Sdt};
@@ -22,7 +22,10 @@ mod arch;
#[path = "arch/other.rs"]
mod arch;
pub static mut MADT: Option<Madt> = None;
static MADT: SyncUnsafeCell<Option<Madt>> = SyncUnsafeCell::new(None);
pub fn madt() -> Option<&'static Madt> {
unsafe { &*MADT.get() }.as_ref()
}
pub const FLAG_PCAT: u32 = 1;
impl Madt {
@@ -37,7 +40,7 @@ impl Madt {
if let Some(madt) = madt {
// safe because no APs have been started yet.
unsafe { MADT = Some(madt) };
unsafe { MADT.get().write(Some(madt)) };
println!(" APIC: {:>08X}: {}", madt.local_address, madt.flags);
+10 -10
View File
@@ -114,9 +114,9 @@ unsafe fn pic_mask(irq: u8) {
debug_assert!(irq < 16);
if irq >= 8 {
pic::SLAVE.mask_set(irq - 8);
pic::slave().mask_set(irq - 8);
} else {
pic::MASTER.mask_set(irq);
pic::master().mask_set(irq);
}
}
@@ -128,10 +128,10 @@ unsafe fn pic_eoi(irq: u8) {
debug_assert!(irq < 16);
if irq >= 8 {
pic::MASTER.ack();
pic::SLAVE.ack();
pic::master().ack();
pic::slave().ack();
} else {
pic::MASTER.ack();
pic::master().ack();
}
}
@@ -143,9 +143,9 @@ unsafe fn pic_unmask(irq: usize) {
debug_assert!(irq < 16);
if irq >= 8 {
pic::SLAVE.mask_clear(irq as u8 - 8);
pic::slave().mask_clear(irq as u8 - 8);
} else {
pic::MASTER.mask_clear(irq as u8);
pic::master().mask_clear(irq as u8);
}
}
@@ -213,7 +213,7 @@ interrupt!(floppy, || {
});
interrupt!(lpt1, || {
if irq_method() == IrqMethod::Pic && pic::MASTER.isr() & (1 << 7) == 0 {
if irq_method() == IrqMethod::Pic && pic::master().isr() & (1 << 7) == 0 {
// the IRQ was spurious, ignore it but increment a counter.
SPURIOUS_COUNT_IRQ7.fetch_add(1, Ordering::Relaxed);
return;
@@ -262,9 +262,9 @@ interrupt!(ata1, || {
});
interrupt!(ata2, || {
if irq_method() == IrqMethod::Pic && pic::SLAVE.isr() & (1 << 7) == 0 {
if irq_method() == IrqMethod::Pic && pic::slave().isr() & (1 << 7) == 0 {
SPURIOUS_COUNT_IRQ15.fetch_add(1, Ordering::Relaxed);
pic::MASTER.ack();
pic::master().ack();
return;
}
trigger(15);
+1 -1
View File
@@ -44,7 +44,7 @@ pub const GDT_F_LONG_MODE: u8 = 1 << 5;
const IOBITMAP_SIZE: u32 = 65536 / 8;
static mut INIT_GDT: [GdtEntry; 3] = [
static INIT_GDT: [GdtEntry; 3] = [
// Null
GdtEntry::new(0, 0, 0, 0),
// Kernel code
+10 -10
View File
@@ -114,9 +114,9 @@ unsafe fn pic_mask(irq: u8) {
debug_assert!(irq < 16);
if irq >= 8 {
pic::SLAVE.mask_set(irq - 8);
pic::slave().mask_set(irq - 8);
} else {
pic::MASTER.mask_set(irq);
pic::master().mask_set(irq);
}
}
@@ -128,10 +128,10 @@ unsafe fn pic_eoi(irq: u8) {
debug_assert!(irq < 16);
if irq >= 8 {
pic::MASTER.ack();
pic::SLAVE.ack();
pic::master().ack();
pic::slave().ack();
} else {
pic::MASTER.ack();
pic::master().ack();
}
}
@@ -143,9 +143,9 @@ unsafe fn pic_unmask(irq: usize) {
debug_assert!(irq < 16);
if irq >= 8 {
pic::SLAVE.mask_clear(irq as u8 - 8);
pic::slave().mask_clear(irq as u8 - 8);
} else {
pic::MASTER.mask_clear(irq as u8);
pic::master().mask_clear(irq as u8);
}
}
@@ -213,7 +213,7 @@ interrupt!(floppy, || {
});
interrupt!(lpt1, || {
if irq_method() == IrqMethod::Pic && pic::MASTER.isr() & (1 << 7) == 0 {
if irq_method() == IrqMethod::Pic && pic::master().isr() & (1 << 7) == 0 {
// the IRQ was spurious, ignore it but increment a counter.
SPURIOUS_COUNT_IRQ7.fetch_add(1, Ordering::Relaxed);
return;
@@ -262,9 +262,9 @@ interrupt!(ata1, || {
});
interrupt!(ata2, || {
if irq_method() == IrqMethod::Pic && pic::SLAVE.isr() & (1 << 7) == 0 {
if irq_method() == IrqMethod::Pic && pic::slave().isr() & (1 << 7) == 0 {
SPURIOUS_COUNT_IRQ15.fetch_add(1, Ordering::Relaxed);
pic::MASTER.ack();
pic::master().ack();
return;
}
trigger(15);
+10 -7
View File
@@ -3,7 +3,10 @@
/// It must create the IDT with the correct entries, those entries are
/// defined in other files inside of the `arch` module
use core::slice;
use core::sync::atomic::{AtomicBool, AtomicU32, AtomicUsize, Ordering};
use core::{
cell::SyncUnsafeCell,
sync::atomic::{AtomicBool, AtomicU32, AtomicUsize, Ordering},
};
use log::info;
@@ -21,9 +24,9 @@ use crate::{
};
/// Test of zero values in BSS.
static mut BSS_TEST_ZERO: usize = 0;
static BSS_TEST_ZERO: SyncUnsafeCell<usize> = SyncUnsafeCell::new(0);
/// Test of non-zero values in data.
static mut DATA_TEST_NONZERO: usize = usize::max_value();
static DATA_TEST_NONZERO: SyncUnsafeCell<usize> = SyncUnsafeCell::new(usize::max_value());
pub static KERNEL_BASE: AtomicUsize = AtomicUsize::new(0);
pub static KERNEL_SIZE: AtomicUsize = AtomicUsize::new(0);
@@ -69,8 +72,8 @@ pub unsafe extern "C" fn kstart(args_ptr: *const KernelArgs) -> ! {
// BSS should already be zero
{
assert_eq!(BSS_TEST_ZERO, 0);
assert_eq!(DATA_TEST_NONZERO, usize::max_value());
assert_eq!(BSS_TEST_ZERO.get().read(), 0);
assert_eq!(DATA_TEST_NONZERO.get().read(), usize::max_value());
}
KERNEL_BASE.store(args.kernel_base as usize, Ordering::SeqCst);
@@ -262,8 +265,8 @@ pub unsafe extern "C" fn kstart_ap(args_ptr: *const KernelArgsAp) -> ! {
let _stack_start = args.stack_start as usize;
let stack_end = args.stack_end as usize;
assert_eq!(BSS_TEST_ZERO, 0);
assert_eq!(DATA_TEST_NONZERO, usize::max_value());
assert_eq!(BSS_TEST_ZERO.get().read(), 0);
assert_eq!(DATA_TEST_NONZERO.get().read(), usize::max_value());
// Set up GDT before paging
gdt::init();
+16 -8
View File
@@ -1,4 +1,4 @@
use core::{fmt, ptr};
use core::{cell::SyncUnsafeCell, fmt, ptr};
use alloc::vec::Vec;
use spin::Mutex;
@@ -83,6 +83,8 @@ pub struct IoApic {
gsi_start: u32,
count: u8,
}
unsafe impl Send for IoApic {}
unsafe impl Sync for IoApic {}
impl IoApic {
#[allow(dead_code)]
pub fn new(regs_base: *const u32, gsi_start: u32) -> Self {
@@ -217,16 +219,20 @@ pub struct Override {
// static mut because only the AP initializes the I/O Apic, and when that is done, it's solely
// accessed immutably.
static mut IOAPICS: Option<Vec<IoApic>> = None;
static IOAPICS: SyncUnsafeCell<Option<Vec<IoApic>>> = SyncUnsafeCell::new(None);
// static mut for the same reason as above
static mut SRC_OVERRIDES: Option<Vec<Override>> = None;
static SRC_OVERRIDES: SyncUnsafeCell<Option<Vec<Override>>> = SyncUnsafeCell::new(None);
pub fn ioapics() -> &'static [IoApic] {
unsafe { IOAPICS.as_ref().map_or(&[], |vector| &vector[..]) }
unsafe { &*IOAPICS.get() }
.as_ref()
.map_or(&[], |vector| &vector[..])
}
pub fn src_overrides() -> &'static [Override] {
unsafe { SRC_OVERRIDES.as_ref().map_or(&[], |vector| &vector[..]) }
unsafe { &*SRC_OVERRIDES.get() }
.as_ref()
.map_or(&[], |vector| &vector[..])
}
#[cfg(feature = "acpi")]
@@ -263,7 +269,7 @@ pub unsafe fn handle_ioapic(mapper: &mut KernelMapper, madt_ioapic: &'static Mad
"mismatched ACPI MADT I/O APIC ID, and the ID reported by the I/O APIC"
);
IOAPICS.get_or_insert_with(Vec::new).push(ioapic);
(*IOAPICS.get()).get_or_insert_with(Vec::new).push(ioapic);
}
#[cfg(feature = "acpi")]
pub unsafe fn handle_src_override(src_override: &'static MadtIntSrcOverride) {
@@ -295,7 +301,9 @@ pub unsafe fn handle_src_override(src_override: &'static MadtIntSrcOverride) {
polarity,
trigger_mode,
};
SRC_OVERRIDES.get_or_insert_with(Vec::new).push(over);
(*SRC_OVERRIDES.get())
.get_or_insert_with(Vec::new)
.push(over);
}
#[allow(dead_code)]
@@ -305,7 +313,7 @@ pub unsafe fn init(active_table: &mut KernelMapper) {
// search the madt for all IOAPICs.
#[cfg(feature = "acpi")]
{
let madt: &'static Madt = match madt::MADT.as_ref() {
let madt: &'static Madt = match madt::madt() {
Some(m) => m,
// TODO: Parse MP tables too.
None => return,
+30 -16
View File
@@ -1,43 +1,57 @@
use core::cell::SyncUnsafeCell;
use crate::{
arch::interrupt::irq,
syscall::io::{Io, Pio},
};
pub static mut MASTER: Pic = Pic::new(0x20);
pub static mut SLAVE: Pic = Pic::new(0xA0);
static MASTER: SyncUnsafeCell<Pic> = SyncUnsafeCell::new(Pic::new(0x20));
static SLAVE: SyncUnsafeCell<Pic> = SyncUnsafeCell::new(Pic::new(0xA0));
// SAFETY: must be main thread
pub unsafe fn master<'a>() -> &'a mut Pic {
&mut *MASTER.get()
}
// SAFETY: must be main thread
pub unsafe fn slave<'a>() -> &'a mut Pic {
&mut *SLAVE.get()
}
pub unsafe fn init() {
let master = master();
let slave = slave();
// Start initialization
MASTER.cmd.write(0x11);
SLAVE.cmd.write(0x11);
master.cmd.write(0x11);
slave.cmd.write(0x11);
// Set offsets
MASTER.data.write(0x20);
SLAVE.data.write(0x28);
master.data.write(0x20);
slave.data.write(0x28);
// Set up cascade
MASTER.data.write(4);
SLAVE.data.write(2);
master.data.write(4);
slave.data.write(2);
// Set up interrupt mode (1 is 8086/88 mode, 2 is auto EOI)
MASTER.data.write(1);
SLAVE.data.write(1);
master.data.write(1);
slave.data.write(1);
// Unmask interrupts
MASTER.data.write(0);
SLAVE.data.write(0);
master.data.write(0);
slave.data.write(0);
// Ack remaining interrupts
MASTER.ack();
SLAVE.ack();
master.ack();
slave.ack();
// probably already set to PIC, but double-check
irq::set_irq_method(irq::IrqMethod::Pic);
}
pub unsafe fn disable() {
MASTER.data.write(0xFF);
SLAVE.data.write(0xFF);
master().data.write(0xFF);
slave().data.write(0xFF);
}
pub struct Pic {
+19 -8
View File
@@ -1,9 +1,20 @@
use core::cell::SyncUnsafeCell;
use crate::syscall::io::{Io, Pio};
pub static mut CHAN0: Pio<u8> = Pio::new(0x40);
static CHAN0: SyncUnsafeCell<Pio<u8>> = SyncUnsafeCell::new(Pio::new(0x40));
//pub static mut CHAN1: Pio<u8> = Pio::new(0x41);
//pub static mut CHAN2: Pio<u8> = Pio::new(0x42);
pub static mut COMMAND: Pio<u8> = Pio::new(0x43);
static COMMAND: SyncUnsafeCell<Pio<u8>> = SyncUnsafeCell::new(Pio::new(0x43));
// SAFETY: must be externally syncd
pub unsafe fn chan0<'a>() -> &'a mut Pio<u8> {
&mut *CHAN0.get()
}
// SAFETY: must be externally syncd
pub unsafe fn command<'a>() -> &'a mut Pio<u8> {
&mut *COMMAND.get()
}
const SELECT_CHAN0: u8 = 0b00 << 6;
const ACCESS_LATCH: u8 = 0b00 << 4;
@@ -20,15 +31,15 @@ pub const CHAN0_DIVISOR: u16 = 4847;
pub const RATE: u128 = (CHAN0_DIVISOR as u128 * PERIOD_FS) / 1_000_000;
pub unsafe fn init() {
COMMAND.write(SELECT_CHAN0 | ACCESS_LOHI | MODE_2);
CHAN0.write(CHAN0_DIVISOR as u8);
CHAN0.write((CHAN0_DIVISOR >> 8) as u8);
command().write(SELECT_CHAN0 | ACCESS_LOHI | MODE_2);
chan0().write(CHAN0_DIVISOR as u8);
chan0().write((CHAN0_DIVISOR >> 8) as u8);
}
pub unsafe fn read() -> u16 {
COMMAND.write(SELECT_CHAN0 | ACCESS_LATCH);
let low = CHAN0.read();
let high = CHAN0.read();
command().write(SELECT_CHAN0 | ACCESS_LATCH);
let low = chan0().read();
let high = chan0().read();
let counter = ((high as u16) << 8) | (low as u16);
// Counter is inverted, subtract from CHAN0_DIVISOR
CHAN0_DIVISOR.saturating_sub(counter)
-3
View File
@@ -42,19 +42,16 @@
// Ensure that all must_use results are used
#![deny(unused_must_use)]
#![feature(allocator_api)]
#![feature(asm_const)]
#![feature(core_intrinsics)]
#![allow(internal_features)]
#![feature(int_roundings)]
#![feature(iter_next_chunk)]
#![feature(let_chains)]
#![feature(naked_functions)]
#![feature(new_uninit)]
#![feature(sync_unsafe_cell)]
#![feature(variant_count)]
#![cfg_attr(not(test), no_std)]
#![cfg_attr(not(test), no_main)]
#![feature(option_get_or_insert_default)]
#![feature(array_chunks)]
#![feature(if_let_guard)]
#![feature(iterator_try_collect)]
+1 -1
View File
@@ -96,7 +96,7 @@ impl IrqScheme {
let cpus = {
use crate::acpi::madt::*;
match unsafe { MADT.as_ref() } {
match madt() {
Some(madt) => madt
.iter()
.filter_map(|entry| match entry {
+11 -10
View File
@@ -4,9 +4,10 @@ use crate::{
startup::memory::BootloaderMemoryKind::Null,
};
use core::{
cell::SyncUnsafeCell,
cmp::{max, min},
mem, slice,
slice::Iter,
mem,
slice::{self, Iter},
};
use rmm::{
Arch, BumpAllocator, MemoryArea, PageFlags, PageMapper, PhysicalAddress, TableKind,
@@ -127,14 +128,14 @@ impl MemoryMap {
}
}
static mut MEMORY_MAP: MemoryMap = MemoryMap {
static MEMORY_MAP: SyncUnsafeCell<MemoryMap> = SyncUnsafeCell::new(MemoryMap {
entries: [MemoryEntry {
start: 0,
end: 0,
kind: BootloaderMemoryKind::Null,
}; 512],
size: 0,
};
});
fn align_up(x: usize) -> usize {
(x.saturating_add(PAGE_SIZE - 1) / PAGE_SIZE) * PAGE_SIZE
@@ -146,7 +147,7 @@ fn align_down(x: usize) -> usize {
pub fn register_memory_region(base: usize, size: usize, kind: BootloaderMemoryKind) {
if kind != Null && size != 0 {
log::debug!("Registering {:?} memory {:X} size {:X}", kind, base, size);
unsafe { MEMORY_MAP.register(base, size, kind) }
unsafe { (*MEMORY_MAP.get()).register(base, size, kind) }
}
}
@@ -167,7 +168,7 @@ pub fn register_bootloader_areas(areas_base: usize, areas_size: usize) {
}
unsafe fn add_memory(areas: &mut [MemoryArea], area_i: &mut usize, mut area: MemoryEntry) {
for reservation in MEMORY_MAP.non_free() {
for reservation in (*MEMORY_MAP.get()).non_free() {
if area.end > reservation.start && area.end <= reservation.end {
log::info!(
"Memory {:X}:{:X} overlaps with reservation {:X}:{:X}",
@@ -304,7 +305,7 @@ unsafe fn map_memory<A: Arch>(areas: &[MemoryArea], mut bump_allocator: &mut Bum
}
}
let kernel_area = MEMORY_MAP.kernel().unwrap();
let kernel_area = (*MEMORY_MAP.get()).kernel().unwrap();
let kernel_base = kernel_area.start;
let kernel_size = kernel_area.end - kernel_area.start;
// Map kernel at KERNEL_OFFSET and identity map too
@@ -324,7 +325,7 @@ unsafe fn map_memory<A: Arch>(areas: &[MemoryArea], mut bump_allocator: &mut Bum
flush.ignore(); // Not the active table
}
for area in MEMORY_MAP.identity_mapped() {
for area in (*MEMORY_MAP.get()).identity_mapped() {
let base = area.start;
let size = area.end - area.start;
for i in 0..size / PAGE_SIZE {
@@ -339,7 +340,7 @@ unsafe fn map_memory<A: Arch>(areas: &[MemoryArea], mut bump_allocator: &mut Bum
}
//map dev mem
for area in MEMORY_MAP.devices() {
for area in (*MEMORY_MAP.get()).devices() {
let base = area.start;
let size = area.end - area.start;
for i in 0..size / PAGE_SIZE {
@@ -399,7 +400,7 @@ pub unsafe fn init(low_limit: Option<usize>, high_limit: Option<usize>) {
let mut area_i = 0;
// Copy initial memory map, and page align it
for area in MEMORY_MAP.free() {
for area in (*MEMORY_MAP.get()).free() {
log::debug!("{:X}:{:X}", area.start, area.end);
if let Some(area) = area.intersect(&physmem_limit) {