1use std::mem::size_of;
8
9use vm_memory::{Bytes, GuestAddress, GuestMemory};
10use zerocopy::{Immutable, IntoBytes};
11
12use crate::{Result, Sdt, SdtHeader, checksum};
13
14#[allow(dead_code)]
15#[repr(C, packed)]
16#[derive(Default, Debug, IntoBytes, Clone, Copy, Immutable)]
17struct PciRangeEntry {
18 pub base_address: u64,
19 pub segment: u16,
20 pub start: u8,
21 pub end: u8,
22 _reserved: u32,
23}
24
25#[allow(dead_code)]
26#[repr(C, packed)]
27#[derive(Clone, Copy, Debug, Default, IntoBytes, Immutable)]
28pub struct Mcfg {
29 header: SdtHeader,
30 _reserved: u64,
31 pci_range_entry: PciRangeEntry,
32}
33
34impl Mcfg {
35 pub fn new(
36 oem_id: [u8; 6],
37 oem_table_id: [u8; 8],
38 oem_revision: u32,
39 pci_mmio_config_addr: u64,
40 ) -> Self {
41 let header = SdtHeader::new(
42 *b"MCFG",
43 size_of::<Mcfg>().try_into().unwrap(),
44 1,
45 oem_id,
46 oem_table_id,
47 oem_revision,
48 );
49
50 let mut mcfg = Mcfg {
51 header,
52 pci_range_entry: PciRangeEntry {
53 base_address: pci_mmio_config_addr,
54 segment: 0,
55 start: 0,
56 end: 0,
57 ..Default::default()
58 },
59 ..Default::default()
60 };
61
62 mcfg.header.checksum = checksum(&[mcfg.as_bytes()]);
63
64 mcfg
65 }
66}
67
68impl Sdt for Mcfg {
69 fn len(&self) -> usize {
70 self.as_bytes().len()
71 }
72
73 fn write_to_guest<M: GuestMemory>(&mut self, mem: &M, address: GuestAddress) -> Result<()> {
74 mem.write_slice(self.as_bytes(), address)?;
75 Ok(())
76 }
77}