Files
RedBear-OS/pcid/src/pci/func.rs
T

51 lines
1.4 KiB
Rust

use byteorder::{LittleEndian, ByteOrder};
use super::PciDev;
// TODO: PCI Express Configuration Space, which uses a flat memory buffer, rather than IN/OUT
// instructions.
pub trait ConfigReader {
unsafe fn read_range(&self, offset: u8, len: u8) -> Vec<u8> {
assert!(len > 3 && len % 4 == 0);
let mut ret = Vec::with_capacity(len as usize);
let results = (offset..offset + len).step_by(4).fold(Vec::new(), |mut acc, offset| {
let val = self.read_u32(offset);
acc.push(val);
acc
});
ret.set_len(len as usize);
LittleEndian::write_u32_into(&*results, &mut ret);
ret
}
unsafe fn read_u32(&self, offset: u8) -> u32;
unsafe fn read_u8(&self, offset: u8) -> u8 {
let dword_offset = (offset / 4) * 4;
let dword = self.read_u32(dword_offset);
let shift = (offset % 4) * 8;
((dword >> shift) & 0xFF) as u8
}
}
pub trait ConfigWriter {
unsafe fn write_u32(&self, offset: u8, value: u32);
}
pub struct PciFunc<'pci> {
pub dev: &'pci PciDev<'pci>,
pub num: u8,
}
impl<'pci> ConfigReader for PciFunc<'pci> {
unsafe fn read_u32(&self, offset: u8) -> u32 {
self.dev.read(self.num, offset)
}
}
impl<'pci> ConfigWriter for PciFunc<'pci> {
unsafe fn write_u32(&self, offset: u8, value: u32) {
self.dev.write(self.num, offset, value);
}
}