1use underhill_confidentiality::OPENHCL_CONFIDENTIAL_DEBUG_ENV_VAR_NAME;
7
8const ENABLE_VTL2_GPA_POOL: &str = "OPENHCL_ENABLE_VTL2_GPA_POOL=";
19
20const SIDECAR: &str = "OPENHCL_SIDECAR=";
28
29const DISABLE_NVME_KEEP_ALIVE: &str = "OPENHCL_DISABLE_NVME_KEEP_ALIVE=";
31
32#[derive(Debug, PartialEq)]
33pub struct BootCommandLineOptions {
34 pub confidential_debug: bool,
35 pub enable_vtl2_gpa_pool: Option<u64>,
36 pub sidecar: bool,
37 pub sidecar_logging: bool,
38 pub disable_nvme_keep_alive: bool,
39}
40
41impl BootCommandLineOptions {
42 pub const fn new() -> Self {
43 BootCommandLineOptions {
44 confidential_debug: false,
45 enable_vtl2_gpa_pool: None,
46 sidecar: true, sidecar_logging: false,
48 disable_nvme_keep_alive: false,
49 }
50 }
51}
52
53impl BootCommandLineOptions {
54 pub fn parse(&mut self, cmdline: &str) {
56 for arg in cmdline.split_whitespace() {
57 if arg.starts_with(OPENHCL_CONFIDENTIAL_DEBUG_ENV_VAR_NAME) {
58 let arg = arg.split_once('=').map(|(_, arg)| arg);
59 if arg.is_some_and(|a| a != "0") {
60 self.confidential_debug = true;
61 }
62 } else if arg.starts_with(ENABLE_VTL2_GPA_POOL) {
63 self.enable_vtl2_gpa_pool = arg.split_once('=').and_then(|(_, arg)| {
64 let num = arg.parse::<u64>().unwrap_or(0);
65 if num == 0 { None } else { Some(num) }
68 });
69 } else if arg.starts_with(SIDECAR) {
70 if let Some((_, arg)) = arg.split_once('=') {
71 for arg in arg.split(',') {
72 match arg {
73 "off" => self.sidecar = false,
74 "on" => self.sidecar = true,
75 "log" => self.sidecar_logging = true,
76 _ => {}
77 }
78 }
79 }
80 } else if arg.starts_with(DISABLE_NVME_KEEP_ALIVE) {
81 let arg = arg.split_once('=').map(|(_, arg)| arg);
82 if arg.is_some_and(|a| a != "0") {
83 self.disable_nvme_keep_alive = true;
84 }
85 }
86 }
87 }
88}
89
90#[cfg(test)]
91mod tests {
92 use super::*;
93
94 fn parse_boot_command_line(cmdline: &str) -> BootCommandLineOptions {
95 let mut options = BootCommandLineOptions::new();
96 options.parse(cmdline);
97 options
98 }
99
100 #[test]
101 fn test_vtl2_gpa_pool_parsing() {
102 assert_eq!(
103 parse_boot_command_line("OPENHCL_ENABLE_VTL2_GPA_POOL=1"),
104 BootCommandLineOptions {
105 enable_vtl2_gpa_pool: Some(1),
106 ..BootCommandLineOptions::new()
107 }
108 );
109 assert_eq!(
110 parse_boot_command_line("OPENHCL_ENABLE_VTL2_GPA_POOL=0"),
111 BootCommandLineOptions {
112 enable_vtl2_gpa_pool: None,
113 ..BootCommandLineOptions::new()
114 }
115 );
116 assert_eq!(
117 parse_boot_command_line("OPENHCL_ENABLE_VTL2_GPA_POOL=asdf"),
118 BootCommandLineOptions {
119 enable_vtl2_gpa_pool: None,
120 ..BootCommandLineOptions::new()
121 }
122 );
123 assert_eq!(
124 parse_boot_command_line("OPENHCL_ENABLE_VTL2_GPA_POOL=512"),
125 BootCommandLineOptions {
126 enable_vtl2_gpa_pool: Some(512),
127 ..BootCommandLineOptions::new()
128 }
129 );
130 }
131
132 #[test]
133 fn test_sidecar_parsing() {
134 assert_eq!(
135 parse_boot_command_line("OPENHCL_SIDECAR=on"),
136 BootCommandLineOptions {
137 sidecar: true,
138 ..BootCommandLineOptions::new()
139 }
140 );
141 assert_eq!(
142 parse_boot_command_line("OPENHCL_SIDECAR=off"),
143 BootCommandLineOptions {
144 sidecar: false,
145 ..BootCommandLineOptions::new()
146 }
147 );
148 assert_eq!(
149 parse_boot_command_line("OPENHCL_SIDECAR=on,off"),
150 BootCommandLineOptions {
151 sidecar: false,
152 ..BootCommandLineOptions::new()
153 }
154 );
155 assert_eq!(
156 parse_boot_command_line("OPENHCL_SIDECAR=on,log"),
157 BootCommandLineOptions {
158 sidecar: true,
159 sidecar_logging: true,
160 ..BootCommandLineOptions::new()
161 }
162 );
163 assert_eq!(
164 parse_boot_command_line("OPENHCL_SIDECAR=log"),
165 BootCommandLineOptions {
166 sidecar: true,
167 sidecar_logging: true,
168 ..BootCommandLineOptions::new()
169 }
170 );
171 }
172}