diff --git a/config/projects.toml b/config/projects.toml index d873a6e..db42aa7 100644 --- a/config/projects.toml +++ b/config/projects.toml @@ -88,3 +88,9 @@ use_ssh = true cargo_build = true auto_update = true unless_env = "OXIDE_STAFF" + +[project.dmar-report] +github = "oxidecomputer/dmar-report" +use_ssh = true +cargo_build = true +auto_update = true diff --git a/image/amd/turin-cosmo-1.0.0.7-mbist-noaggr.toml b/image/amd/turin-cosmo-1.0.0.7-mbist-noaggr.toml new file mode 100644 index 0000000..6eccf19 --- /dev/null +++ b/image/amd/turin-cosmo-1.0.0.7-mbist-noaggr.toml @@ -0,0 +1,5 @@ +base = 'turin-cosmo-1.0.0.7.toml' + +[patch] +base = 'turin-cosmo-a.efs.json5' +diff = 'turin-cosmo-a-mbist-noaggr.patch' diff --git a/image/amd/turin-cosmo-1.0.0.7-mbist.toml b/image/amd/turin-cosmo-1.0.0.7-mbist.toml new file mode 100644 index 0000000..f9c2e11 --- /dev/null +++ b/image/amd/turin-cosmo-1.0.0.7-mbist.toml @@ -0,0 +1,5 @@ +base = 'turin-cosmo-1.0.0.7.toml' + +[patch] +base = 'turin-cosmo-a.efs.json5' +diff = 'turin-cosmo-a-mbist.patch' diff --git a/image/amd/turin-cosmo-a-mbist-noaggr.patch b/image/amd/turin-cosmo-a-mbist-noaggr.patch new file mode 100644 index 0000000..5fa08ca --- /dev/null +++ b/image/amd/turin-cosmo-a-mbist-noaggr.patch @@ -0,0 +1,56 @@ +--- turin-cosmo-1.0.0.7.efs.json5 Sat Oct 4 20:42:22 2025 ++++ turin-cosmo-1.0.0.7.mbist-mfg-v0-dext-len3.efs.json5 Wed Oct 15 20:06:13 2025 +@@ -10684,7 +10684,7 @@ + }, + { + Byte: { +- MemMbistAggressorsChannelDdrMode: "All" ++ MemMbistAggressorsChannelDdrMode: "SubChannel" + } + }, + { +@@ -10749,7 +10749,7 @@ + }, + { + Byte: { +- MemMbistPatternLengthDdr: 6 ++ MemMbistPatternLengthDdr: 3 + } + }, + { +@@ -10966,7 +10966,7 @@ + }, + { + Byte: { +- MemMbistPatternSelectDdr: "Auto" ++ MemMbistPatternSelectDdr: "Prbs" + } + }, + { +@@ -11046,7 +11046,7 @@ + }, + { + Byte: { +- MemMbistDataEyeSilentExecutionDdr: "Disabled" ++ MemMbistDataEyeSilentExecutionDdr: "Enabled" + } + }, + { +@@ -11136,7 +11136,7 @@ + }, + { + Byte: { +- MemMbistTestModeDdr: "Both" ++ MemMbistTestModeDdr: "DataEye" + } + }, + { +@@ -11265,7 +11265,7 @@ + }, + { + Byte: { +- MemMbistAggressorsDdr: "Auto" ++ MemMbistAggressorsDdr: "Disabled" + } + }, + { diff --git a/image/amd/turin-cosmo-a-mbist.patch b/image/amd/turin-cosmo-a-mbist.patch new file mode 100644 index 0000000..45426a0 --- /dev/null +++ b/image/amd/turin-cosmo-a-mbist.patch @@ -0,0 +1,56 @@ +--- turin-cosmo-1.0.0.7.efs.json5 Sat Oct 4 20:42:22 2025 ++++ turin-cosmo-1.0.0.7.mbist-mfg-v0-dext-len3.efs.json5 Wed Oct 15 20:06:13 2025 +@@ -10684,7 +10684,7 @@ + }, + { + Byte: { +- MemMbistAggressorsChannelDdrMode: "All" ++ MemMbistAggressorsChannelDdrMode: "SubChannel" + } + }, + { +@@ -10749,7 +10749,7 @@ + }, + { + Byte: { +- MemMbistPatternLengthDdr: 6 ++ MemMbistPatternLengthDdr: 3 + } + }, + { +@@ -10966,7 +10966,7 @@ + }, + { + Byte: { +- MemMbistPatternSelectDdr: "Auto" ++ MemMbistPatternSelectDdr: "Prbs" + } + }, + { +@@ -11046,7 +11046,7 @@ + }, + { + Byte: { +- MemMbistDataEyeSilentExecutionDdr: "Disabled" ++ MemMbistDataEyeSilentExecutionDdr: "Enabled" + } + }, + { +@@ -11136,7 +11136,7 @@ + }, + { + Byte: { +- MemMbistTestModeDdr: "Both" ++ MemMbistTestModeDdr: "DataEye" + } + }, + { +@@ -11265,7 +11265,7 @@ + }, + { + Byte: { +- MemMbistAggressorsDdr: "Auto" ++ MemMbistAggressorsDdr: "Enabled" + } + }, + { diff --git a/image/templates/sled/ramdisk-01-os.json b/image/templates/sled/ramdisk-01-os.json index 6e5a8cc..845b923 100644 --- a/image/templates/sled/ramdisk-01-os.json +++ b/image/templates/sled/ramdisk-01-os.json @@ -110,6 +110,10 @@ "/driver/network/opte@${optever}" ] }, + { "t": "pkg_install", "with": "mbist", "pkgs": [ + "/driver/developer/amd/zen" + ] }, + { "t": "pkg_install", "with": "mfg", "pkgs": [ "/driver/developer/amd/zen", "/driver/cpu/amd/psp", diff --git a/image/templates/sled/targets.toml b/image/templates/sled/targets.toml index 29b7b8b..4464257 100644 --- a/image/templates/sled/targets.toml +++ b/image/templates/sled/targets.toml @@ -6,3 +6,10 @@ app = "milan-gimlet-b-1.0.0.a.toml" efs = "turin-cosmo-a.efs.json5" app = "turin-cosmo-1.0.0.7.toml" +[cosmo-mbist] +app = "turin-cosmo-1.0.0.7-mbist.toml" +feature = "mbist" + +[cosmo-mbist-noaggr] +app = "turin-cosmo-1.0.0.7-mbist-noaggr.toml" +feature = "mbist" diff --git a/image/templates/sled/zfs.json b/image/templates/sled/zfs.json index 437f170..71a3a14 100644 --- a/image/templates/sled/zfs.json +++ b/image/templates/sled/zfs.json @@ -78,6 +78,11 @@ "owner": "root", "group": "bin", "mode": "0755" }, { "t": "include", "without": "no-pilot", "name": "compliance-common" }, + { "t": "ensure_file", "with": "mbist", + "file": "/usr/bin/dmar-report", + "extsrc": "dmar-report/target/release/dmar-report", + "owner": "root", "group": "bin", "mode": "0755" }, + { "t": "include", "with": "genproto", "name": "genproto", "file": "${genproto}" }, diff --git a/tools/helios-build/src/main.rs b/tools/helios-build/src/main.rs index 207b538..797c100 100644 --- a/tools/helios-build/src/main.rs +++ b/tools/helios-build/src/main.rs @@ -10,7 +10,7 @@ use helios_build_utils::metadata::{self, ArchiveType}; use helios_build_utils::tree; use serde::Deserialize; use slog::Logger; -use std::collections::HashMap; +use std::collections::{HashMap, HashSet}; use std::fs::File; use std::io::{BufReader, Read, Write}; use std::os::unix::fs::PermissionsExt; @@ -1312,18 +1312,22 @@ impl Publishers { #[derive(Clone, Debug, Deserialize)] struct Board { - efs: String, + efs: Option, app: String, + feature: Option, } impl Board { - fn efs_path(&self) -> Result { - if self.efs.starts_with("/") { - let p = PathBuf::from(self.efs.clone()); + fn efs_path(&self) -> Option> { + let Some(efs) = &self.efs else { + return None; + }; + if efs.starts_with("/") { + let p = PathBuf::from(efs.clone()); assert!(p.is_absolute()); - Ok(p) + Some(Ok(p)) } else { - top_path(&["image", "amd", &self.efs]) + Some(top_path(&["image", "amd", efs])) } } @@ -1442,10 +1446,12 @@ fn cmd_image(ca: &CommandArg) -> Result<()> { for (name, board) in target_boards.iter() { info!(log, "Checking files for board '{name}'"); - let efsfile = board.efs_path()?; - info!(log, " {efsfile:?}"); - if !efsfile.is_file() { - bail!("Missing AMD configuration file {efsfile:?} for {name}"); + if let Some(efsfile) = board.efs_path() { + let efsfile = efsfile?; + info!(log, " {efsfile:?}"); + if !efsfile.is_file() { + bail!("Missing AMD configuration file {efsfile:?} for {name}"); + } } let appfile = board.app_path()?; info!(log, " {appfile:?}"); @@ -1594,6 +1600,7 @@ fn cmd_image(ca: &CommandArg) -> Result<()> { let templates = top_path(&["image", "templates"])?; let brand_extras = rel_path(Some(&tempdir), &["omicron1"])?; let projects_extras = top_path(&["projects"])?; + let features = res.opt_strs("F").into_iter().collect::>(); std::fs::create_dir_all(&brand_extras)?; let basecmd = || -> Command { let mut cmd = Command::new("pfexec"); @@ -1628,7 +1635,7 @@ fn cmd_image(ca: &CommandArg) -> Result<()> { if recovery { cmd.arg("-F").arg("recovery"); } - for farg in res.opt_strs("F") { + for farg in &features { cmd.arg("-F").arg(farg); } cmd @@ -1963,30 +1970,44 @@ fn cmd_image(ca: &CommandArg) -> Result<()> { * Go through and create the per-board ROM images. */ for (name, board) in target_boards.iter() { + if let Some(feat) = &board.feature { + if !features.contains(feat) { + info!( + log, + "skipping building ROM for {name} ('{feat}' disabled)" + ); + continue; + } + } info!(log, "building ROM for {name}"); let romname = format!("{name}.rom"); let rom = rel_path(Some(&outdir), &[&romname])?; - ensure::run_in( - log, - &ahib_path, - &[ - "cargo", - "xtask", - "gen", - "--amd-firmware", - fw_path.to_str().unwrap(), - "--payload", - reset.to_str().unwrap(), - "--config", - board.efs_path()?.to_str().unwrap(), - "--app", - board.app_path()?.to_str().unwrap(), - "--image", - rom.to_str().unwrap(), - ], - )?; + let efs_path; + let app_path = board.app_path()?; + let root_path = top_path(&["image", "amd"])?; + let mut args = vec![ + "cargo", + "xtask", + "gen", + "--amd-firmware", + fw_path.to_str().unwrap(), + "--payload", + reset.to_str().unwrap(), + "--app", + app_path.to_str().unwrap(), + "--image", + rom.to_str().unwrap(), + "--root", + root_path.to_str().unwrap(), + ]; + if let Some(efs) = board.efs_path() { + efs_path = efs?; + args.push("--config"); + args.push(efs_path.to_str().unwrap()); + } + ensure::run_in(log, &ahib_path, &args)?; tar.add_file(&rom, &romname)?; @@ -2004,7 +2025,7 @@ fn cmd_image(ca: &CommandArg) -> Result<()> { * The configuration for amd-host-image-builder is stored in JSON5 * format. Read the file as a generic JSON object: */ - let f = std::fs::read_to_string(board.efs_path()?)?; + let f = std::fs::read_to_string(board.efs_path().unwrap()?)?; let inputcfg: serde_json::Value = json5::from_str(&f)?; for limit in [1600, 1866, 2133, 2400, 2667, 2933, 3200] {