acpi_tables/
dsdt.rs

1// Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2// SPDX-License-Identifier: Apache-2.0
3
4use std::mem::size_of;
5
6use vm_memory::{Address, Bytes, GuestAddress, GuestMemory};
7use zerocopy::IntoBytes;
8
9use crate::{AcpiError, Result, Sdt, SdtHeader, checksum};
10
11/// Differentiated System Description Table (DSDT)
12///
13/// Table that includes hardware definition blocks.
14/// More information about this table can be found in the ACPI specification:
15/// https://uefi.org/specs/ACPI/6.5/05_ACPI_Software_Programming_Model.html#differentiated-system-description-table-dsdt
16#[derive(Debug, Clone)]
17pub struct Dsdt {
18    header: SdtHeader,
19    definition_block: Vec<u8>,
20}
21
22impl Dsdt {
23    pub fn new(
24        oem_id: [u8; 6],
25        oem_table_id: [u8; 8],
26        oem_revision: u32,
27        definition_block: Vec<u8>,
28    ) -> Self {
29        let header = SdtHeader::new(
30            *b"DSDT",
31            (size_of::<SdtHeader>() + definition_block.len())
32                .try_into()
33                .unwrap(),
34            2,
35            oem_id,
36            oem_table_id,
37            oem_revision,
38        );
39
40        let mut dsdt = Dsdt {
41            header,
42            definition_block,
43        };
44
45        dsdt.header.checksum =
46            checksum(&[dsdt.header.as_bytes(), dsdt.definition_block.as_slice()]);
47        dsdt
48    }
49}
50
51impl Sdt for Dsdt {
52    fn len(&self) -> usize {
53        self.header.length.get() as usize
54    }
55
56    fn write_to_guest<AS: GuestMemory>(&mut self, mem: &AS, address: GuestAddress) -> Result<()> {
57        mem.write_slice(self.header.as_bytes(), address)?;
58        let address = address
59            .checked_add(size_of::<SdtHeader>() as u64)
60            .ok_or(AcpiError::InvalidGuestAddress)?;
61        mem.write_slice(self.definition_block.as_slice(), address)?;
62
63        Ok(())
64    }
65}