Nothing to see here, move along
1pub mod config;
2pub mod device;
3pub mod msix;
4
5pub use device::{BarInfo, DEVICE_TABLE, PciDeviceInfo};
6
7use crate::acpi::mcfg::McfgEntry;
8use crate::mem::phys::BitmapFrameAllocator;
9use crate::static_vec::StaticVec;
10use crate::types::Pid;
11use x86_64::structures::paging::OffsetPageTable;
12
13#[derive(Clone, Copy)]
14pub struct BarMappingEntry {
15 pub pid: Pid,
16 pub device_idx: u8,
17 pub bar_idx: u8,
18 pub base_vaddr: u64,
19}
20
21pub static BAR_MAPPINGS: spin::Mutex<StaticVec<BarMappingEntry, 64>> =
22 spin::Mutex::new(StaticVec::new());
23
24impl BarMappingEntry {
25 pub fn matches(&self, pid: Pid, device_idx: u8, bar_idx: u8) -> bool {
26 self.pid == pid && self.device_idx == device_idx && self.bar_idx == bar_idx
27 }
28}
29
30#[cfg_attr(lancer_test, allow(dead_code))]
31pub fn enable_bus_master(device_table_idx: u8) -> Result<(), crate::error::KernelError> {
32 let dev_table = DEVICE_TABLE.lock();
33 let dev = dev_table
34 .get(device_table_idx as usize)
35 .ok_or(crate::error::KernelError::InvalidObject)?;
36
37 let mcfg_entries = crate::acpi::mcfg::cached_mcfg_entries();
38 let ecam_base = mcfg_entries
39 .iter()
40 .find(|e| dev.bus >= e.start_bus && dev.bus <= e.end_bus)
41 .map(|e| e.base_address)
42 .ok_or(crate::error::KernelError::InvalidObject)?;
43
44 let addr = config::EcamAddress::new(ecam_base, dev.bus, dev.device, dev.function)
45 .ok_or(crate::error::KernelError::InvalidParameter)?;
46 drop(dev_table);
47
48 let cmd = config::read_config_u16(addr, 0x04);
49 config::write_config_u16(addr, 0x04, cmd | (1 << 2));
50
51 Ok(())
52}
53
54pub fn enumerate(
55 mcfg_entries: &StaticVec<McfgEntry, 4>,
56 mapper: &mut OffsetPageTable,
57 allocator: &mut BitmapFrameAllocator,
58 hhdm_offset: u64,
59) {
60 let mut table = DEVICE_TABLE.lock();
61
62 mcfg_entries.iter().for_each(|segment| {
63 device::enumerate_segment(segment, mapper, allocator, hhdm_offset, &mut table);
64 });
65
66 crate::kprintln!(" PCI: {} devices found", table.len());
67}