flowey_lib_hvlite/
download_uefi_mu_msvm.rs1use crate::common::CommonArch;
7use flowey::node::prelude::*;
8use std::collections::BTreeMap;
9
10#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
12pub enum FirmwareFlavor {
13 LegacyVs2022,
14 LegacyClangPdb,
15 PatinaClangPdb,
16}
17
18impl FirmwareFlavor {
19 fn default_for_arch(arch: CommonArch) -> Self {
20 match arch {
21 CommonArch::X86_64 | CommonArch::Aarch64 => Self::LegacyClangPdb,
22 }
23 }
24
25 fn file_name(self, arch: CommonArch) -> anyhow::Result<&'static str> {
26 Ok(match (self, arch) {
27 (Self::LegacyVs2022, CommonArch::X86_64) => "firmware-RELEASE-X64-VS2022.tar.gz",
28 (Self::LegacyVs2022, CommonArch::Aarch64) => {
29 anyhow::bail!("mu_msvm does not support AARCH64 with VS2022")
30 }
31 (Self::LegacyClangPdb, CommonArch::X86_64) => "firmware-RELEASE-X64-CLANGPDB.tar.gz",
32 (Self::LegacyClangPdb, CommonArch::Aarch64) => {
33 "firmware-RELEASE-AARCH64-CLANGPDB.tar.gz"
34 }
35 (Self::PatinaClangPdb, CommonArch::X86_64) => {
36 "firmware-RELEASE-X64-CLANGPDB-patina.tar.gz"
37 }
38 (Self::PatinaClangPdb, CommonArch::Aarch64) => {
39 "firmware-RELEASE-AARCH64-CLANGPDB-patina.tar.gz"
40 }
41 })
42 }
43}
44
45flowey_config! {
46 pub struct Config {
48 pub version: Option<String>,
50 pub local_paths: BTreeMap<CommonArch, ConfigVar<PathBuf>>,
52 }
53}
54
55flowey_request! {
56 pub enum Request {
57 GetMsvmFd {
59 arch: CommonArch,
60 flavor: Option<FirmwareFlavor>,
61 msvm_fd: WriteVar<PathBuf>
62 }
63 }
64}
65
66new_flow_node_with_config!(struct Node);
67
68impl FlowNodeWithConfig for Node {
69 type Request = Request;
70 type Config = Config;
71
72 fn imports(ctx: &mut ImportCtx<'_>) {
73 ctx.import::<flowey_lib_common::install_dist_pkg::Node>();
74 ctx.import::<flowey_lib_common::download_gh_release::Node>();
75 }
76
77 fn emit(
78 config: Config,
79 requests: Vec<Self::Request>,
80 ctx: &mut NodeCtx<'_>,
81 ) -> anyhow::Result<()> {
82 let version = config.version;
83 let local_paths = config.local_paths;
84 let mut reqs: BTreeMap<(CommonArch, FirmwareFlavor), Vec<WriteVar<PathBuf>>> =
85 BTreeMap::new();
86
87 for req in requests {
88 match req {
89 Request::GetMsvmFd {
90 arch,
91 flavor,
92 msvm_fd,
93 } => reqs
94 .entry((
95 arch,
96 flavor.unwrap_or_else(|| FirmwareFlavor::default_for_arch(arch)),
97 ))
98 .or_default()
99 .push(msvm_fd),
100 }
101 }
102
103 if version.is_some() && !local_paths.is_empty() {
104 anyhow::bail!("Cannot specify both Version and LocalPath requests");
105 }
106
107 if version.is_none() && local_paths.is_empty() {
108 anyhow::bail!("Must specify a Version or LocalPath request");
109 }
110
111 if reqs.is_empty() {
114 return Ok(());
115 }
116
117 if !local_paths.is_empty() {
118 ctx.emit_rust_step("use local mu_msvm UEFI", |ctx| {
119 let reqs = reqs.claim(ctx);
120 let local_paths: BTreeMap<_, _> = local_paths
121 .into_iter()
122 .map(|(arch, var)| (arch, var.claim(ctx)))
123 .collect();
124 move |rt| {
125 for ((arch, _flavor), out_vars) in reqs {
126 let msvm_fd_var = local_paths.get(&arch).ok_or_else(|| {
127 anyhow::anyhow!("No local path specified for architecture {:?}", arch)
128 })?;
129 let msvm_fd = rt.read(msvm_fd_var.clone());
130 for var in out_vars {
131 log::info!(
132 "using local uefi for {} at path {:?}",
133 match arch {
134 CommonArch::X86_64 => "x64",
135 CommonArch::Aarch64 => "aarch64",
136 },
137 msvm_fd
138 );
139 rt.write(var, &msvm_fd);
140 }
141 }
142 Ok(())
143 }
144 });
145
146 return Ok(());
147 }
148
149 let version = version.context("missing mu_msvm version")?;
150 let extract_archive_deps = flowey_lib_common::_util::extract::extract_zip_if_new_deps(ctx);
151
152 for ((arch, flavor), out_vars) in reqs {
153 let file_name = flavor.file_name(arch)?;
154
155 let mu_msvm_archive = ctx.reqv(|v| flowey_lib_common::download_gh_release::Request {
156 repo_owner: crate::common::OPENVMM_GITHUB_OWNER.into(),
157 repo_name: "mu_msvm".into(),
158 needs_auth: false,
159 tag: format!("v{version}"),
160 file_name: file_name.into(),
161 path: v,
162 });
163
164 let archive_file_version = format!("{version}-{file_name}");
165
166 ctx.emit_rust_step(
167 {
168 format!(
169 "unpack mu_msvm package ({})",
170 match arch {
171 CommonArch::X86_64 => "x64",
172 CommonArch::Aarch64 => "aarch64",
173 },
174 )
175 },
176 |ctx| {
177 let extract_archive_deps = extract_archive_deps.clone().claim(ctx);
178 let out_vars = out_vars.claim(ctx);
179 let mu_msvm_archive = mu_msvm_archive.claim(ctx);
180 move |rt| {
181 let mu_msvm_archive = rt.read(mu_msvm_archive);
182
183 let extract_dir = flowey_lib_common::_util::extract::extract_zip_if_new(
184 rt,
185 extract_archive_deps,
186 &mu_msvm_archive,
187 &archive_file_version,
188 )?;
189
190 let msvm_fd = extract_dir.join("FV/MSVM.fd");
191
192 for var in out_vars {
193 rt.write(var, &msvm_fd)
194 }
195
196 Ok(())
197 }
198 },
199 );
200 }
201
202 Ok(())
203 }
204}