mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-09 05:16:47 +00:00
Add documentation to x86/device
This commit is contained in:
parent
c71ff237bc
commit
0970adb37b
@ -2,12 +2,12 @@
|
|||||||
|
|
||||||
use core::sync::atomic::{AtomicU8, Ordering::Relaxed};
|
use core::sync::atomic::{AtomicU8, Ordering::Relaxed};
|
||||||
|
|
||||||
use ostd::arch::x86::device::cmos::{get_century_register, CMOS_ADDRESS, CMOS_DATA};
|
use ostd::arch::x86::device::cmos::{century_register, CMOS_ADDRESS, CMOS_DATA};
|
||||||
|
|
||||||
pub(crate) static CENTURY_REGISTER: AtomicU8 = AtomicU8::new(0);
|
pub(crate) static CENTURY_REGISTER: AtomicU8 = AtomicU8::new(0);
|
||||||
|
|
||||||
pub fn init() {
|
pub fn init() {
|
||||||
let Some(century_register) = get_century_register() else {
|
let Some(century_register) = century_register() else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
CENTURY_REGISTER.store(century_register, Relaxed);
|
CENTURY_REGISTER.store(century_register, Relaxed);
|
||||||
|
@ -96,7 +96,7 @@ fn handle_serial_input(trap_frame: &TrapFrame) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn line_sts() -> LineSts {
|
fn line_sts() -> LineSts {
|
||||||
LineSts::from_bits_truncate(CONSOLE_COM1_PORT.line_status.read())
|
LineSts::from_bits_truncate(CONSOLE_COM1_PORT.line_status())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sends a byte on the serial port.
|
/// Sends a byte on the serial port.
|
||||||
@ -104,15 +104,15 @@ pub fn send(data: u8) {
|
|||||||
match data {
|
match data {
|
||||||
8 | 0x7F => {
|
8 | 0x7F => {
|
||||||
while !line_sts().contains(LineSts::OUTPUT_EMPTY) {}
|
while !line_sts().contains(LineSts::OUTPUT_EMPTY) {}
|
||||||
CONSOLE_COM1_PORT.data.write(8);
|
CONSOLE_COM1_PORT.send(8);
|
||||||
while !line_sts().contains(LineSts::OUTPUT_EMPTY) {}
|
while !line_sts().contains(LineSts::OUTPUT_EMPTY) {}
|
||||||
CONSOLE_COM1_PORT.data.write(b' ');
|
CONSOLE_COM1_PORT.send(b' ');
|
||||||
while !line_sts().contains(LineSts::OUTPUT_EMPTY) {}
|
while !line_sts().contains(LineSts::OUTPUT_EMPTY) {}
|
||||||
CONSOLE_COM1_PORT.data.write(8);
|
CONSOLE_COM1_PORT.send(8);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
while !line_sts().contains(LineSts::OUTPUT_EMPTY) {}
|
while !line_sts().contains(LineSts::OUTPUT_EMPTY) {}
|
||||||
CONSOLE_COM1_PORT.data.write(data);
|
CONSOLE_COM1_PORT.send(data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -120,7 +120,7 @@ pub fn send(data: u8) {
|
|||||||
/// Receives a byte on the serial port. non-blocking
|
/// Receives a byte on the serial port. non-blocking
|
||||||
pub fn receive_char() -> Option<u8> {
|
pub fn receive_char() -> Option<u8> {
|
||||||
if line_sts().contains(LineSts::INPUT_FULL) {
|
if line_sts().contains(LineSts::INPUT_FULL) {
|
||||||
Some(CONSOLE_COM1_PORT.data.read())
|
Some(CONSOLE_COM1_PORT.recv())
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,12 @@
|
|||||||
// SPDX-License-Identifier: MPL-2.0
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
|
//! Provides CMOS I/O port access.
|
||||||
|
//!
|
||||||
|
//! "CMOS" is a tiny bit of very low power static memory that lives on the same chip as the Real-Time Clock (RTC).
|
||||||
|
//!
|
||||||
|
//! Reference: <https://wiki.osdev.org/CMOS>
|
||||||
|
//!
|
||||||
|
|
||||||
#![allow(unused_variables)]
|
#![allow(unused_variables)]
|
||||||
|
|
||||||
use acpi::{fadt::Fadt, sdt::Signature};
|
use acpi::{fadt::Fadt, sdt::Signature};
|
||||||
@ -8,10 +15,14 @@ use x86_64::instructions::port::{ReadOnlyAccess, WriteOnlyAccess};
|
|||||||
use super::io_port::IoPort;
|
use super::io_port::IoPort;
|
||||||
use crate::arch::x86::kernel::acpi::ACPI_TABLES;
|
use crate::arch::x86::kernel::acpi::ACPI_TABLES;
|
||||||
|
|
||||||
|
/// CMOS address I/O port
|
||||||
pub static CMOS_ADDRESS: IoPort<u8, WriteOnlyAccess> = unsafe { IoPort::new(0x70) };
|
pub static CMOS_ADDRESS: IoPort<u8, WriteOnlyAccess> = unsafe { IoPort::new(0x70) };
|
||||||
|
|
||||||
|
/// CMOS data I/O port
|
||||||
pub static CMOS_DATA: IoPort<u8, ReadOnlyAccess> = unsafe { IoPort::new(0x71) };
|
pub static CMOS_DATA: IoPort<u8, ReadOnlyAccess> = unsafe { IoPort::new(0x71) };
|
||||||
|
|
||||||
pub fn get_century_register() -> Option<u8> {
|
/// Gets the century register location. This function is used in RTC(Real Time Clock) module initialization.
|
||||||
|
pub fn century_register() -> Option<u8> {
|
||||||
if !ACPI_TABLES.is_completed() {
|
if !ACPI_TABLES.is_completed() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
// SPDX-License-Identifier: MPL-2.0
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
|
//! I/O port access.
|
||||||
|
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
|
|
||||||
pub use x86_64::{
|
pub use x86_64::{
|
||||||
@ -29,7 +31,7 @@ pub struct IoPort<T, A> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<T, A> IoPort<T, A> {
|
impl<T, A> IoPort<T, A> {
|
||||||
/// Create an I/O port.
|
/// Creates an I/O port.
|
||||||
///
|
///
|
||||||
/// # Safety
|
/// # Safety
|
||||||
///
|
///
|
||||||
@ -45,6 +47,7 @@ impl<T, A> IoPort<T, A> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<T: PortRead, A: IoPortReadAccess> IoPort<T, A> {
|
impl<T: PortRead, A: IoPortReadAccess> IoPort<T, A> {
|
||||||
|
/// Reads from the I/O port
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn read(&self) -> T {
|
pub fn read(&self) -> T {
|
||||||
unsafe { PortRead::read_from_port(self.port) }
|
unsafe { PortRead::read_from_port(self.port) }
|
||||||
@ -52,6 +55,7 @@ impl<T: PortRead, A: IoPortReadAccess> IoPort<T, A> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<T: PortWrite, A: IoPortWriteAccess> IoPort<T, A> {
|
impl<T: PortWrite, A: IoPortWriteAccess> IoPort<T, A> {
|
||||||
|
/// Writes to the I/O port
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn write(&self, value: T) {
|
pub fn write(&self, value: T) {
|
||||||
unsafe { PortWrite::write_to_port(self.port, value) }
|
unsafe { PortWrite::write_to_port(self.port, value) }
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
//! A port-mapped UART. Copied from uart_16550.
|
//! A port-mapped UART. Copied from uart_16550.
|
||||||
|
|
||||||
|
#![allow(dead_code)]
|
||||||
|
|
||||||
use crate::arch::x86::device::io_port::{IoPort, ReadWriteAccess, WriteOnlyAccess};
|
use crate::arch::x86::device::io_port::{IoPort, ReadWriteAccess, WriteOnlyAccess};
|
||||||
|
|
||||||
/// A serial port.
|
/// A serial port.
|
||||||
@ -9,17 +11,24 @@ use crate::arch::x86::device::io_port::{IoPort, ReadWriteAccess, WriteOnlyAccess
|
|||||||
/// Serial ports are a legacy communications port common on IBM-PC compatible computers.
|
/// Serial ports are a legacy communications port common on IBM-PC compatible computers.
|
||||||
/// Ref: <https://wiki.osdev.org/Serial_Ports>
|
/// Ref: <https://wiki.osdev.org/Serial_Ports>
|
||||||
pub struct SerialPort {
|
pub struct SerialPort {
|
||||||
pub data: IoPort<u8, ReadWriteAccess>,
|
/// Data Register
|
||||||
pub int_en: IoPort<u8, WriteOnlyAccess>,
|
data: IoPort<u8, ReadWriteAccess>,
|
||||||
pub fifo_ctrl: IoPort<u8, WriteOnlyAccess>,
|
/// Interrupt Enable Register
|
||||||
pub line_ctrl: IoPort<u8, WriteOnlyAccess>,
|
int_en: IoPort<u8, WriteOnlyAccess>,
|
||||||
pub modem_ctrl: IoPort<u8, WriteOnlyAccess>,
|
/// First In First Out Control Register
|
||||||
pub line_status: IoPort<u8, ReadWriteAccess>,
|
fifo_ctrl: IoPort<u8, WriteOnlyAccess>,
|
||||||
pub modem_status: IoPort<u8, ReadWriteAccess>,
|
/// Line control Register
|
||||||
|
line_ctrl: IoPort<u8, WriteOnlyAccess>,
|
||||||
|
/// Modem Control Register
|
||||||
|
modem_ctrl: IoPort<u8, WriteOnlyAccess>,
|
||||||
|
/// Line status Register
|
||||||
|
line_status: IoPort<u8, ReadWriteAccess>,
|
||||||
|
/// Modem Status Register
|
||||||
|
modem_status: IoPort<u8, ReadWriteAccess>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SerialPort {
|
impl SerialPort {
|
||||||
/// Create a serial port.
|
/// Creates a serial port.
|
||||||
///
|
///
|
||||||
/// # Safety
|
/// # Safety
|
||||||
///
|
///
|
||||||
@ -43,6 +52,7 @@ impl SerialPort {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Initializes the serial port.
|
||||||
pub fn init(&self) {
|
pub fn init(&self) {
|
||||||
// Disable interrupts
|
// Disable interrupts
|
||||||
self.int_en.write(0x00);
|
self.int_en.write(0x00);
|
||||||
@ -62,4 +72,22 @@ impl SerialPort {
|
|||||||
// Enable interrupts
|
// Enable interrupts
|
||||||
self.int_en.write(0x01);
|
self.int_en.write(0x01);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sends data to the data port
|
||||||
|
#[inline]
|
||||||
|
pub fn send(&self, data: u8) {
|
||||||
|
self.data.write(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Receives data from the data port
|
||||||
|
#[inline]
|
||||||
|
pub fn recv(&self) -> u8 {
|
||||||
|
self.data.read()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets line status
|
||||||
|
#[inline]
|
||||||
|
pub fn line_status(&self) -> u8 {
|
||||||
|
self.line_status.read()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user