diff --git a/ostd/src/arch/x86/device/cmos.rs b/ostd/src/arch/x86/device/cmos.rs index 8b4d78f17..1a72c690f 100644 --- a/ostd/src/arch/x86/device/cmos.rs +++ b/ostd/src/arch/x86/device/cmos.rs @@ -12,13 +12,17 @@ use acpi::fadt::Fadt; use x86_64::instructions::port::{ReadOnlyAccess, WriteOnlyAccess}; -use crate::{arch::x86::kernel::acpi::get_acpi_tables, io::IoPort}; +use crate::{ + arch::x86::kernel::acpi::get_acpi_tables, + io::{sensitive_io_port, IoPort}, +}; -/// CMOS address I/O port -pub static CMOS_ADDRESS: IoPort = unsafe { IoPort::new(0x70) }; - -/// CMOS data I/O port -pub static CMOS_DATA: IoPort = unsafe { IoPort::new(0x71) }; +sensitive_io_port!(unsafe { + /// CMOS address I/O port + pub static CMOS_ADDRESS: IoPort = IoPort::new(0x70); + /// CMOS data I/O port + pub static CMOS_DATA: IoPort = IoPort::new(0x71); +}); /// Gets the century register location. This function is used in RTC(Real Time Clock) module initialization. pub fn century_register() -> Option { diff --git a/ostd/src/arch/x86/kernel/pic.rs b/ostd/src/arch/x86/kernel/pic.rs index 24cba4999..04bc97f40 100644 --- a/ostd/src/arch/x86/kernel/pic.rs +++ b/ostd/src/arch/x86/kernel/pic.rs @@ -6,12 +6,20 @@ use core::sync::atomic::{AtomicBool, AtomicU8, Ordering::Relaxed}; use log::info; -use crate::{arch::x86::device::io_port::WriteOnlyAccess, io::IoPort, trap::IrqLine}; +use crate::{ + arch::x86::device::io_port::WriteOnlyAccess, + io::{sensitive_io_port, IoPort}, + trap::IrqLine, +}; -static MASTER_CMD: IoPort = unsafe { IoPort::new(0x20) }; -static MASTER_DATA: IoPort = unsafe { IoPort::new(0x21) }; -static SLAVE_CMD: IoPort = unsafe { IoPort::new(0xA0) }; -static SLAVE_DATA: IoPort = unsafe { IoPort::new(0xA1) }; +sensitive_io_port! { + unsafe{ + static MASTER_CMD: IoPort = IoPort::new(0x20); + static MASTER_DATA: IoPort = IoPort::new(0x21); + static SLAVE_CMD: IoPort = IoPort::new(0xA0); + static SLAVE_DATA: IoPort = IoPort::new(0xA1); + } +} const IRQ_OFFSET: u8 = 0x20; diff --git a/ostd/src/arch/x86/serial.rs b/ostd/src/arch/x86/serial.rs index 631b1719e..5ef9cfd18 100644 --- a/ostd/src/arch/x86/serial.rs +++ b/ostd/src/arch/x86/serial.rs @@ -13,6 +13,7 @@ use super::{ kernel::{self, IO_APIC}, }; use crate::{ + io::reserve_io_port_range, sync::SpinLock, trap::{IrqLine, TrapFrame}, }; @@ -53,6 +54,7 @@ bitflags::bitflags! { } static CONSOLE_COM1_PORT: SerialPort = unsafe { SerialPort::new(0x3F8) }; +reserve_io_port_range!(0x3F8..0x400); static CONSOLE_IRQ_CALLBACK: Once> = Once::new(); static SERIAL_INPUT_CALLBACKS: SpinLock>> = SpinLock::new(Vec::new()); diff --git a/ostd/src/arch/x86/timer/pit.rs b/ostd/src/arch/x86/timer/pit.rs index ad25848b4..8f6bf7415 100644 --- a/ostd/src/arch/x86/timer/pit.rs +++ b/ostd/src/arch/x86/timer/pit.rs @@ -11,7 +11,7 @@ use crate::{ arch::{kernel::IO_APIC, timer::TIMER_FREQ, x86::device::io_port::WriteOnlyAccess}, - io::IoPort, + io::{sensitive_io_port, IoPort}, trap::IrqLine, }; @@ -131,33 +131,36 @@ enum Channel { ReadBackCommand = 0b11, } -/// The output from PIT channel 0 is connected to the PIC chip and generate "IRQ 0". -/// If connected to PIC, the IRQ0 will generate by the **rising edge** of the output voltage. -static CHANNEL0_PORT: IoPort = unsafe { IoPort::new(0x40) }; +sensitive_io_port! { + unsafe { + /// The output from PIT channel 0 is connected to the PIC chip and generate "IRQ 0". + /// If connected to PIC, the IRQ0 will generate by the **rising edge** of the output voltage. + static CHANNEL0_PORT: IoPort = IoPort::new(0x40); -/// The output from PIT channel 1 was once used for refreshing the DRAM or RAM so that -/// the capacitors don't forget their state. -/// -/// On later machines, the DRAM refresh is done with dedicated hardware and this channel -/// is no longer used. -#[expect(unused)] -static CHANNEL1_PORT: IoPort = unsafe { IoPort::new(0x41) }; + /// The output from PIT channel 1 was once used for refreshing the DRAM or RAM so that + /// the capacitors don't forget their state. + /// + /// On later machines, the DRAM refresh is done with dedicated hardware and this channel + /// is no longer used. + static CHANNEL1_PORT: IoPort = IoPort::new(0x41); -/// The output from PIT channel 2 is connected to the PC speaker, so the frequency of the -/// output determines the frequency of the sound produced by the speaker. For more information, -/// check https://wiki.osdev.org/PC_Speaker. -#[expect(unused)] -static CHANNEL2_PORT: IoPort = unsafe { IoPort::new(0x42) }; + /// The output from PIT channel 2 is connected to the PC speaker, so the frequency of the + /// output determines the frequency of the sound produced by the speaker. For more information, + /// check https://wiki.osdev.org/PC_Speaker. + static CHANNEL2_PORT: IoPort = IoPort::new(0x42); + + /// PIT command port. + /// ```text + /// Bits Usage + /// 6 and 7 channel + /// 4 and 5 Access mode + /// 1 to 3 Operating mode + /// 0 BCD/Binary mode: 0 = 16-bit binary, 1 = four-digit BCD + /// ``` + static MODE_COMMAND_PORT: IoPort = IoPort::new(0x43); + } +} -/// PIT command port. -/// ```text -/// Bits Usage -/// 6 and 7 channel -/// 4 and 5 Access mode -/// 1 to 3 Operating mode -/// 0 BCD/Binary mode: 0 = 16-bit binary, 1 = four-digit BCD -/// ``` -static MODE_COMMAND_PORT: IoPort = unsafe { IoPort::new(0x43) }; const TIMER_RATE: u32 = 1193182; pub(crate) fn init(operating_mode: OperatingMode) {