1use crate::spec::cfg_space;
7use inspect::Inspect;
8
9#[derive(Debug, Inspect)]
11pub struct BarMapping {
12 pub index: u8,
14 pub base_address: u64,
16 pub len: u64,
18}
19
20#[derive(Debug, Default)]
22pub struct BarMappings(Vec<BarMapping>);
23
24impl Inspect for BarMappings {
25 fn inspect(&self, req: inspect::Request<'_>) {
26 let mut res = req.respond();
27 for bar in self.0.iter() {
28 res.field(
29 &format!("bar{}", bar.index),
30 format!("{:#010x?}:{:#x?}", bar.base_address, bar.len),
31 );
32 }
33 }
34}
35
36impl BarMappings {
37 pub fn parse(base_addresses: &[u32; 6], bar_masks: &[u32; 6]) -> Self {
39 let mut mappings = Vec::new();
40 let mut i = 0;
41 while i < base_addresses.len() {
42 let bar_address;
43 let mut bar_mask;
44 let len;
45 if cfg_space::BarEncodingBits::from_bits(bar_masks[i]).type_64_bit() {
46 bar_mask = (bar_masks[i + 1] as u64) << 32 | bar_masks[i] as u64;
47 bar_address = (base_addresses[i + 1] as u64) << 32 | base_addresses[i] as u64;
48 len = 2;
49 } else {
50 bar_mask = bar_masks[i] as i32 as i64 as u64; bar_address = base_addresses[i] as u64;
52 len = 1;
53 };
54 bar_mask &= !0xf;
55 if bar_mask != 0 {
56 mappings.push(BarMapping {
57 index: i as u8,
58 base_address: bar_address & bar_mask,
59 len: !bar_mask + 1,
60 });
61 }
62 i += len;
63 }
64 Self(mappings)
65 }
66
67 pub fn find(&self, address: u64) -> Option<(u8, u16)> {
69 for bar_mapping in self.0.iter() {
70 if address >= bar_mapping.base_address
71 && address - bar_mapping.base_address < bar_mapping.len
72 {
73 return Some((
74 bar_mapping.index,
75 (address - bar_mapping.base_address).try_into().unwrap(),
76 ));
77 }
78 }
79 None
80 }
81
82 pub fn get(&self, bar: u8) -> Option<u64> {
84 for bar_mapping in self.0.iter() {
85 if bar_mapping.index == bar {
86 return Some(bar_mapping.base_address);
87 }
88 }
89 None
90 }
91
92 pub fn iter(&self) -> impl Iterator<Item = &BarMapping> {
94 self.0.iter()
95 }
96}