acpi_tables/
mcfg.rs

1// Copyright © 2019 Intel Corporation
2// Copyright © 2023 Rivos, Inc.
3// Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved.
4//
5// SPDX-License-Identifier: Apache-2.0
6
7use 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}