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>,
|
_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
|
/// Constructs a new I/O port interface
|
||||||
pub const fn new(address: u16) -> Self {
|
pub const fn new(address: u16) -> Self {
|
||||||
Self {
|
Self {
|
||||||
@ -18,20 +26,76 @@ impl IoPort<u8> {
|
|||||||
_pd: PhantomData,
|
_pd: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Writes a byte into the port
|
impl IoPortAccess<u8> for IoPort<u8> {
|
||||||
pub fn write(&self, value: u8) {
|
fn write(&self, value: u8) {
|
||||||
unsafe {
|
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
|
fn read(&self) -> u8 {
|
||||||
pub fn read(&self) -> u8 {
|
unsafe { inb(self.address) }
|
||||||
let value: u8;
|
|
||||||
unsafe {
|
|
||||||
core::arch::asm!("inb %dx, %al", in("dx") self.address, out("al") value, options(att_syntax));
|
|
||||||
}
|
|
||||||
value
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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::{
|
use self::{
|
||||||
apic::ioapic::IoApic,
|
apic::ioapic::IoApic,
|
||||||
intrinsics::IoPort,
|
intrinsics::{IoPort, IoPortAccess},
|
||||||
peripherals::{hpet::Hpet, ps2::PS2Controller},
|
peripherals::{hpet::Hpet, ps2::PS2Controller},
|
||||||
smp::CPU_COUNT,
|
smp::CPU_COUNT,
|
||||||
};
|
};
|
||||||
@ -494,10 +494,10 @@ impl X86_64 {
|
|||||||
unsafe fn disable_8259() {
|
unsafe fn disable_8259() {
|
||||||
infoln!("Disabling i8259 PIC");
|
infoln!("Disabling i8259 PIC");
|
||||||
// TODO should I make a module for 8259 if I don't even use it?
|
// 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_cmd = IoPort::<u8>::new(0x20);
|
||||||
let pic_master_data = IoPort::new(0x21);
|
let pic_master_data = IoPort::<u8>::new(0x21);
|
||||||
let pic_slave_cmd = IoPort::new(0xA0);
|
let pic_slave_cmd = IoPort::<u8>::new(0xA0);
|
||||||
let pic_slave_data = IoPort::new(0xA1);
|
let pic_slave_data = IoPort::<u8>::new(0xA1);
|
||||||
|
|
||||||
// Remap PIC IRQ vectors to 32..
|
// Remap PIC IRQ vectors to 32..
|
||||||
pic_master_cmd.write(0x11);
|
pic_master_cmd.write(0x11);
|
||||||
|
@ -8,7 +8,10 @@ use device_api::{
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
arch::{
|
arch::{
|
||||||
x86_64::{intrinsics::IoPort, IrqNumber},
|
x86_64::{
|
||||||
|
intrinsics::{IoPort, IoPortAccess},
|
||||||
|
IrqNumber,
|
||||||
|
},
|
||||||
Architecture, ARCHITECTURE,
|
Architecture, ARCHITECTURE,
|
||||||
},
|
},
|
||||||
sync::IrqSafeSpinlock,
|
sync::IrqSafeSpinlock,
|
||||||
|
@ -3,7 +3,10 @@ use abi::error::Error;
|
|||||||
use device_api::{serial::SerialDevice, Device};
|
use device_api::{serial::SerialDevice, Device};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
arch::x86_64::{intrinsics::IoPort, IrqNumber},
|
arch::x86_64::{
|
||||||
|
intrinsics::{IoPort, IoPortAccess},
|
||||||
|
IrqNumber,
|
||||||
|
},
|
||||||
debug::DebugSink,
|
debug::DebugSink,
|
||||||
sync::IrqSafeSpinlock,
|
sync::IrqSafeSpinlock,
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user