1use 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#[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}