mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-22 17:03:23 +00:00
Implement read/write functions for IoBar
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
11df16d65e
commit
461c872c43
@ -1,11 +1,16 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
use alloc::sync::Arc;
|
||||
use core::mem::size_of;
|
||||
|
||||
use bitflags::bitflags;
|
||||
|
||||
use super::PciDeviceLocation;
|
||||
use crate::{io_mem::IoMem, Error, Result};
|
||||
use crate::{
|
||||
arch::device::io_port::{PortRead, PortWrite},
|
||||
io_mem::IoMem,
|
||||
Error, Result,
|
||||
};
|
||||
|
||||
#[repr(u16)]
|
||||
pub enum PciDeviceCommonCfgOffset {
|
||||
@ -189,6 +194,35 @@ impl IoBar {
|
||||
self.size
|
||||
}
|
||||
|
||||
pub fn read<T: PortRead>(&self, offset: u32) -> Result<T> {
|
||||
// Check alignment
|
||||
if (self.base + offset) % size_of::<T>() as u32 != 0 {
|
||||
return Err(Error::InvalidArgs);
|
||||
}
|
||||
// Check overflow
|
||||
if self.size < size_of::<T>() as u32 || offset > self.size - size_of::<T>() as u32 {
|
||||
return Err(Error::InvalidArgs);
|
||||
}
|
||||
// Safety: The range of ports accessed is within the scope managed by the IoBar and
|
||||
// an out-of-bounds check is performed.
|
||||
unsafe { Ok(T::read_from_port((self.base + offset) as u16)) }
|
||||
}
|
||||
|
||||
pub fn write<T: PortWrite>(&self, offset: u32, value: T) -> Result<()> {
|
||||
// Check alignment
|
||||
if (self.base + offset) % size_of::<T>() as u32 != 0 {
|
||||
return Err(Error::InvalidArgs);
|
||||
}
|
||||
// Check overflow
|
||||
if size_of::<T>() as u32 > self.size || offset > self.size - size_of::<T>() as u32 {
|
||||
return Err(Error::InvalidArgs);
|
||||
}
|
||||
// Safety: The range of ports accessed is within the scope managed by the IoBar and
|
||||
// an out-of-bounds check is performed.
|
||||
unsafe { T::write_to_port((self.base + offset) as u16, value) }
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn new(location: &PciDeviceLocation, index: u8) -> Result<Self> {
|
||||
let offset = index as u16 * 4 + PciDeviceCommonCfgOffset::Bar0 as u16;
|
||||
let raw = location.read32(offset);
|
||||
|
Reference in New Issue
Block a user