qemu_command_builder/
acpitable.rs

1use std::path::PathBuf;
2
3use bon::Builder;
4
5use crate::to_command::ToCommand;
6
7pub enum DataFile {
8    File(Vec<PathBuf>),
9    Data(Vec<PathBuf>),
10}
11
12/// Add ACPI table with specified header fields and context from
13/// specified files. For file=, take whole ACPI table from the specified
14/// files, including all ACPI headers (possible overridden by other
15/// options). For data=, only data portion of the table is used, all
16/// header information is specified in the command line. If a SLIC table
17/// is supplied to QEMU, then the SLIC's oem\_id and oem\_table\_id
18/// fields will override the same in the RSDT and the FADT (a.k.a.
19/// FACP), in order to ensure the field matches required by the
20/// Microsoft SLIC spec and the ACPI spec.
21#[derive(Default, Builder)]
22pub struct AcpiTable {
23    sig: Option<String>,
24    rev: Option<usize>,
25    oem_id: Option<String>,
26    oem_table_id: Option<String>,
27    oem_rev: Option<usize>,
28    asl_compiler_id: Option<String>,
29    asl_compiler_rev: Option<usize>,
30    data: Option<DataFile>,
31}
32
33impl ToCommand for AcpiTable {
34    fn to_command(&self) -> Vec<String> {
35        let mut cmd = vec![];
36
37        cmd.push("-acpitable".to_string());
38
39        let mut args = vec![];
40        if let Some(sig) = &self.sig {
41            args.push(format!("sig={}", sig));
42        }
43        if let Some(rev) = self.rev {
44            args.push(format!("rev={}", rev));
45        }
46        if let Some(oem_id) = &self.oem_id {
47            args.push(format!("oem_id={}", oem_id));
48        }
49        if let Some(oem_table_id) = &self.oem_table_id {
50            args.push(format!("oem_table_id={}", oem_table_id));
51        }
52        if let Some(oem_rev) = self.oem_rev {
53            args.push(format!("oem_rev={}", oem_rev));
54        }
55        if let Some(asl_compiler_id) = &self.asl_compiler_id {
56            args.push(format!("asl_compiler_id={}", asl_compiler_id));
57        }
58        if let Some(asl_compiler_rev) = self.asl_compiler_rev {
59            args.push(format!("asl_compiler_rev={}", asl_compiler_rev));
60        }
61        if let Some(data) = &self.data {
62            match data {
63                DataFile::File(data) => {
64                    let files: Vec<String> = data.iter().map(|p| p.display().to_string()).collect();
65                    args.push(format!("file={}", files.join(":")));
66                }
67                DataFile::Data(data) => {
68                    let files: Vec<String> = data.iter().map(|p| p.display().to_string()).collect();
69                    args.push(format!("file={}", files.join(":")));
70                }
71            }
72        }
73
74        cmd.push(args.join(","));
75        cmd
76    }
77}