x86-64: better IoPort interface
This commit is contained in:
parent
67fe71bfc4
commit
9c419115e7
@ -10,7 +10,15 @@ pub struct IoPort<T> {
|
||||
_pd: PhantomData<T>,
|
||||
}
|
||||
|
||||
impl IoPort<u8> {
|
||||
/// Common interface for reading and writing I/O ports
|
||||
pub trait IoPortAccess<T> {
|
||||
/// Reads a value from the port
|
||||
fn read(&self) -> T;
|
||||
/// Writes a value to the port
|
||||
fn write(&self, value: T);
|
||||
}
|
||||
|
||||
impl<T> IoPort<T> {
|
||||
/// Constructs a new I/O port interface
|
||||
pub const fn new(address: u16) -> Self {
|
||||
Self {
|
||||
@ -18,20 +26,76 @@ impl IoPort<u8> {
|
||||
_pd: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Writes a byte into the port
|
||||
pub fn write(&self, value: u8) {
|
||||
impl IoPortAccess<u8> for IoPort<u8> {
|
||||
fn write(&self, value: u8) {
|
||||
unsafe {
|
||||
core::arch::asm!("outb %al, %dx", in("al") value, in("dx") self.address, options(att_syntax));
|
||||
outb(self.address, value);
|
||||
}
|
||||
}
|
||||
|
||||
/// Reads a byte from the port
|
||||
pub fn read(&self) -> u8 {
|
||||
let value: u8;
|
||||
unsafe {
|
||||
core::arch::asm!("inb %dx, %al", in("dx") self.address, out("al") value, options(att_syntax));
|
||||
}
|
||||
value
|
||||
fn read(&self) -> u8 {
|
||||
unsafe { inb(self.address) }
|
||||
}
|
||||
}
|
||||
|
||||
impl IoPortAccess<u16> for IoPort<u16> {
|
||||
fn write(&self, value: u16) {
|
||||
unsafe {
|
||||
outw(self.address, value);
|
||||
}
|
||||
}
|
||||
|
||||
fn read(&self) -> u16 {
|
||||
unsafe { inw(self.address) }
|
||||
}
|
||||
}
|
||||
|
||||
impl IoPortAccess<u32> for IoPort<u32> {
|
||||
fn write(&self, value: u32) {
|
||||
unsafe {
|
||||
outl(self.address, value);
|
||||
}
|
||||
}
|
||||
|
||||
fn read(&self) -> u32 {
|
||||
unsafe { inl(self.address) }
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn inb(port: u16) -> u8 {
|
||||
let value: u8;
|
||||
core::arch::asm!("inb %dx, %al", in("dx") port, out("al") value, options(att_syntax));
|
||||
value
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn inw(port: u16) -> u16 {
|
||||
let value: u16;
|
||||
core::arch::asm!("inb %dx, %ax", in("dx") port, out("ax") value, options(att_syntax));
|
||||
value
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn inl(port: u16) -> u32 {
|
||||
let value: u32;
|
||||
core::arch::asm!("inb %dx, %eax", in("dx") port, out("eax") value, options(att_syntax));
|
||||
value
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn outb(port: u16, value: u8) {
|
||||
core::arch::asm!("outb %al, %dx", in("dx") port, in("al") value, options(att_syntax));
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn outw(port: u16, value: u16) {
|
||||
core::arch::asm!("outw %ax, %dx", in("dx") port, in("ax") value, options(att_syntax));
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn outl(port: u16, value: u32) {
|
||||
core::arch::asm!("outl %eax, %dx", in("dx") port, in("eax") value, options(att_syntax));
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ use crate::{
|
||||
|
||||
use self::{
|
||||
apic::ioapic::IoApic,
|
||||
intrinsics::IoPort,
|
||||
intrinsics::{IoPort, IoPortAccess},
|
||||
peripherals::{hpet::Hpet, ps2::PS2Controller},
|
||||
smp::CPU_COUNT,
|
||||
};
|
||||
@ -494,10 +494,10 @@ impl X86_64 {
|
||||
unsafe fn disable_8259() {
|
||||
infoln!("Disabling i8259 PIC");
|
||||
// TODO should I make a module for 8259 if I don't even use it?
|
||||
let pic_master_cmd = IoPort::new(0x20);
|
||||
let pic_master_data = IoPort::new(0x21);
|
||||
let pic_slave_cmd = IoPort::new(0xA0);
|
||||
let pic_slave_data = IoPort::new(0xA1);
|
||||
let pic_master_cmd = IoPort::<u8>::new(0x20);
|
||||
let pic_master_data = IoPort::<u8>::new(0x21);
|
||||
let pic_slave_cmd = IoPort::<u8>::new(0xA0);
|
||||
let pic_slave_data = IoPort::<u8>::new(0xA1);
|
||||
|
||||
// Remap PIC IRQ vectors to 32..
|
||||
pic_master_cmd.write(0x11);
|
||||
|
@ -8,7 +8,10 @@ use device_api::{
|
||||
|
||||
use crate::{
|
||||
arch::{
|
||||
x86_64::{intrinsics::IoPort, IrqNumber},
|
||||
x86_64::{
|
||||
intrinsics::{IoPort, IoPortAccess},
|
||||
IrqNumber,
|
||||
},
|
||||
Architecture, ARCHITECTURE,
|
||||
},
|
||||
sync::IrqSafeSpinlock,
|
||||
|
@ -3,7 +3,10 @@ use abi::error::Error;
|
||||
use device_api::{serial::SerialDevice, Device};
|
||||
|
||||
use crate::{
|
||||
arch::x86_64::{intrinsics::IoPort, IrqNumber},
|
||||
arch::x86_64::{
|
||||
intrinsics::{IoPort, IoPortAccess},
|
||||
IrqNumber,
|
||||
},
|
||||
debug::DebugSink,
|
||||
sync::IrqSafeSpinlock,
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user