Nothing to see here, move along meow
1use crate::static_vec::StaticVec;
2
3#[derive(Debug, Clone, Copy)]
4pub struct McfgEntry {
5 pub base_address: u64,
6 #[allow(dead_code)]
7 pub segment_group: u16,
8 pub start_bus: u8,
9 pub end_bus: u8,
10}
11
12static CACHED_MCFG: spin::Mutex<StaticVec<McfgEntry, 4>> = spin::Mutex::new(StaticVec::new());
13
14pub fn cache_mcfg_entries(entries: &StaticVec<McfgEntry, 4>) {
15 let mut cached = CACHED_MCFG.lock();
16 entries.iter().for_each(|e| {
17 let _ = cached.push(*e);
18 });
19}
20
21pub fn cached_mcfg_entries() -> spin::MutexGuard<'static, StaticVec<McfgEntry, 4>> {
22 CACHED_MCFG.lock()
23}
24
25const MCFG_HEADER_SIZE: usize = 44;
26const MCFG_ENTRY_SIZE: usize = 16;
27
28pub fn parse_mcfg(virt_addr: u64, length: u32) -> StaticVec<McfgEntry, 4> {
29 let base = virt_addr as *const u8;
30 let data_len = (length as usize).saturating_sub(MCFG_HEADER_SIZE);
31 let entry_count = data_len / MCFG_ENTRY_SIZE;
32
33 (0..entry_count).fold(StaticVec::new(), |mut entries, i| {
34 let offset = MCFG_HEADER_SIZE + i * MCFG_ENTRY_SIZE;
35 let entry_ptr = unsafe { base.add(offset) };
36
37 let base_address = unsafe { core::ptr::read_unaligned(entry_ptr as *const u64) };
38 let segment_group = unsafe { core::ptr::read_unaligned(entry_ptr.add(8) as *const u16) };
39 let start_bus = unsafe { core::ptr::read_unaligned(entry_ptr.add(10)) };
40 let end_bus = unsafe { core::ptr::read_unaligned(entry_ptr.add(11)) };
41
42 if base_address == 0 || base_address & 0xFFF != 0 {
43 crate::kprintln!(
44 " MCFG: invalid base_address {:#x}, skipping segment {}",
45 base_address,
46 segment_group
47 );
48 return entries;
49 }
50
51 let entry = McfgEntry {
52 base_address,
53 segment_group,
54 start_bus,
55 end_bus,
56 };
57
58 match entries.push(entry) {
59 Ok(()) => {
60 crate::kprintln!(
61 " MCFG: ECAM at {:#x}, segment {} bus {}-{}",
62 base_address,
63 segment_group,
64 start_bus,
65 end_bus
66 );
67 }
68 Err(_) => {
69 crate::kprintln!(
70 " MCFG: entry table full, dropping segment {}",
71 segment_group
72 );
73 }
74 }
75
76 entries
77 })
78}