mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-23 01:13: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
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
use alloc::sync::Arc;
|
use alloc::sync::Arc;
|
||||||
|
use core::mem::size_of;
|
||||||
|
|
||||||
use bitflags::bitflags;
|
use bitflags::bitflags;
|
||||||
|
|
||||||
use super::PciDeviceLocation;
|
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)]
|
#[repr(u16)]
|
||||||
pub enum PciDeviceCommonCfgOffset {
|
pub enum PciDeviceCommonCfgOffset {
|
||||||
@ -189,6 +194,35 @@ impl IoBar {
|
|||||||
self.size
|
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> {
|
fn new(location: &PciDeviceLocation, index: u8) -> Result<Self> {
|
||||||
let offset = index as u16 * 4 + PciDeviceCommonCfgOffset::Bar0 as u16;
|
let offset = index as u16 * 4 + PciDeviceCommonCfgOffset::Bar0 as u16;
|
||||||
let raw = location.read32(offset);
|
let raw = location.read32(offset);
|
||||||
|
Reference in New Issue
Block a user