pub mod config; pub mod device; pub mod msix; pub use device::{BarInfo, DEVICE_TABLE, PciDeviceInfo}; use crate::acpi::mcfg::McfgEntry; use crate::mem::phys::BitmapFrameAllocator; use crate::static_vec::StaticVec; use crate::types::Pid; use x86_64::structures::paging::OffsetPageTable; #[derive(Clone, Copy)] pub struct BarMappingEntry { pub pid: Pid, pub device_idx: u8, pub bar_idx: u8, pub base_vaddr: u64, } pub static BAR_MAPPINGS: spin::Mutex> = spin::Mutex::new(StaticVec::new()); impl BarMappingEntry { pub fn matches(&self, pid: Pid, device_idx: u8, bar_idx: u8) -> bool { self.pid == pid && self.device_idx == device_idx && self.bar_idx == bar_idx } } #[cfg_attr(lancer_test, allow(dead_code))] pub fn enable_bus_master(device_table_idx: u8) -> Result<(), crate::error::KernelError> { let dev_table = DEVICE_TABLE.lock(); let dev = dev_table .get(device_table_idx as usize) .ok_or(crate::error::KernelError::InvalidObject)?; let mcfg_entries = crate::acpi::mcfg::cached_mcfg_entries(); let ecam_base = mcfg_entries .iter() .find(|e| dev.bus >= e.start_bus && dev.bus <= e.end_bus) .map(|e| e.base_address) .ok_or(crate::error::KernelError::InvalidObject)?; let addr = config::EcamAddress::new(ecam_base, dev.bus, dev.device, dev.function) .ok_or(crate::error::KernelError::InvalidParameter)?; drop(dev_table); let cmd = config::read_config_u16(addr, 0x04); config::write_config_u16(addr, 0x04, cmd | (1 << 2)); Ok(()) } pub fn enumerate( mcfg_entries: &StaticVec, mapper: &mut OffsetPageTable, allocator: &mut BitmapFrameAllocator, hhdm_offset: u64, ) { let mut table = DEVICE_TABLE.lock(); mcfg_entries.iter().for_each(|segment| { device::enumerate_segment(segment, mapper, allocator, hhdm_offset, &mut table); }); crate::kprintln!(" PCI: {} devices found", table.len()); }