Skip to content

Improve dump subcommand. #162

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
amd-apcb = { git = "https://github.com/oxidecomputer/amd-apcb.git", tag = "v0.1.5", features = ["std", "serde", "schemars"] }
amd-efs = { git = "ssh://git@github.com/oxidecomputer/amd-efs.git", tag = "v0.3.0", features = ["std", "serde", "schemars"] }
amd-apcb = { git = "https://github.com/oxidecomputer/amd-apcb.git", branch = "issue-113", features = ["std", "serde", "schemars"] }
amd-efs = { git = "ssh://git@github.com/oxidecomputer/amd-efs.git", branch = "issue-99", features = ["std", "serde", "schemars"] }
Comment on lines +10 to +11
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is intended?

Copy link
Collaborator Author

@daym daym Jan 23, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's so the github CI and thus buildomat can build it. Otherwise all we'd see is a build failure.

But yeah, definitely not merge it like that.

amd-flash = { git = "ssh://git@github.com/oxidecomputer/amd-flash.git", tag = "v0.2.1", features = ["std"] }
goblin = { version = "0.4", features = ["elf64", "endian_fd"] }
#serde = { version = "1.0", default-features = false, features = ["derive"] }
Expand Down
4 changes: 2 additions & 2 deletions amd-host-image-builder-config/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
amd-apcb = { git = "https://github.com/oxidecomputer/amd-apcb.git", tag = "v0.1.5", features = ["std", "serde", "schemars"] }
amd-efs = { git = "ssh://git@github.com/oxidecomputer/amd-efs.git", tag = "v0.3.0", features = ["std", "serde", "schemars"] }
amd-apcb = { git = "https://github.com/oxidecomputer/amd-apcb.git", branch = "issue-113", features = ["std", "serde", "schemars"] }
amd-efs = { git = "ssh://git@github.com/oxidecomputer/amd-efs.git", branch = "issue-99", features = ["std", "serde", "schemars"] }
Comment on lines +9 to +10
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Likewise.

amd-flash = { git = "ssh://git@github.com/oxidecomputer/amd-flash.git", tag = "v0.2.1", features = ["std"] }
schemars = "0.8.8"
serde = { version = "1.0", default-features = false, features = ["derive"] }
Expand Down
121 changes: 103 additions & 18 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use amd_apcb::{Apcb, ApcbIoOptions};
use amd_efs::{
AddressMode, BhdDirectory, BhdDirectoryEntry, BhdDirectoryEntryType,
DirectoryEntry, Efs, ProcessorGeneration, PspDirectory, PspDirectoryEntry,
DirectoryEntry, EfhBulldozerSpiMode, EfhNaplesSpiMode, EfhRomeSpiMode, Efs,
ProcessorGeneration, PspDirectory, PspDirectoryEntry,
PspDirectoryEntryType, ValueOrLocation,
};
use amd_host_image_builder_config::{
Expand All @@ -19,6 +20,7 @@ use std::cmp::min;
use std::collections::HashSet;
use std::fs;
use std::fs::File;
use std::io::stdout;
use std::io::BufReader;
use std::io::Read;
use std::io::Seek;
Expand All @@ -30,6 +32,9 @@ use structopt::StructOpt;
mod static_config;
use amd_flash::allocators::{ArenaFlashAllocator, FlashAllocate};

mod serializers;
use serializers::DummySerializer;

use amd_flash::{
ErasableLocation, ErasableRange, FlashAlign, FlashRead, FlashWrite,
Location,
Expand Down Expand Up @@ -634,6 +639,29 @@ fn serde_from_bhd_entry(
}
}

/// Try to return RESULT?.
/// If that doesn't work, print RESULT_TEXT and then return FALLBACK instead.
/// This is useful because some images don't have SPI mode set. As far as
/// we can tell, the SPI mode is mandatory. In order not to fail the entire
/// dump just because of the SPI mode, we just make one up here.
fn spi_mode_fallback_on_error<T, E: std::fmt::Display>(
result: std::result::Result<T, E>,
fallback: T,
result_text: &str,
) -> T {
match result {
Copy link
Contributor

@dancrossnyc dancrossnyc Jan 23, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is unwrap_or_else, isn't it? E.g.,

result.unwrap_or_else(|e| { eprintln!("{result_text} was invalid: {e}.  Falling back to default"); default })

Ok(x) => x,
Err(e) => {
eprintln!(
"{} was invalid: {}. Falling back to default.",
result_text, e
);
// TODO: Maybe set program error status somehow
fallback
}
}
}

fn dump_bhd_directory<'a, T: FlashRead + FlashWrite>(
storage: &T,
bhd_directory: &BhdDirectory,
Expand All @@ -653,6 +681,11 @@ fn dump_bhd_directory<'a, T: FlashRead + FlashWrite>(
.map_while(|entry| {
let entry = entry.clone();
if let Ok(typ) = entry.typ_or_err() {
if typ == BhdDirectoryEntryType::Apob {
// Since this is a runtime value we cannot read it
// from the image.
return None;
}
let payload_beginning =
bhd_directory.payload_beginning(&entry).unwrap();
let size = entry.size().unwrap() as usize;
Expand All @@ -669,11 +702,14 @@ fn dump_bhd_directory<'a, T: FlashRead + FlashWrite>(
)
.unwrap();

let apcb_options = ApcbIoOptions::builder()
.with_check_checksum(false)
.build();
let apcb = Apcb::load(
std::borrow::Cow::Borrowed(
&mut apcb_buffer[..],
),
&ApcbIoOptions::default(),
&apcb_options,
)
.unwrap();
apcb.validate(None).unwrap(); // TODO: abl0 version ?
Expand Down Expand Up @@ -727,6 +763,7 @@ fn dump_bhd_directory<'a, T: FlashRead + FlashWrite>(
fn dump(
image_filename: &Path,
blob_dump_dirname: Option<PathBuf>,
output_config_file: &mut impl std::io::Write,
) -> std::io::Result<()> {
let filename = image_filename;
let storage = FlashImage::load(filename)?;
Expand All @@ -735,25 +772,48 @@ fn dump(
if filesize <= 0x100_0000 { Some(filesize as u32) } else { None };
let efs = Efs::load(&storage, None, amd_physical_mode_mmio_size).unwrap();
if !efs.compatible_with_processor_generation(ProcessorGeneration::Milan) {
panic!("only Milan is supported for dumping right now");
if !efs.compatible_with_processor_generation(ProcessorGeneration::Rome)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Surely this could be phrased as a compound condition. Is there a reason not to?

{
panic!("only Milan or Rome is supported for dumping right now");
}
}
let mut apcb_buffer = [0xFFu8; Apcb::MAX_SIZE];
let mut apcb_buffer_option = Some(&mut apcb_buffer[..]);
let processor_generation = if efs
.compatible_with_processor_generation(ProcessorGeneration::Milan)
{
ProcessorGeneration::Milan
} else {
ProcessorGeneration::Rome
};
let config = SerdeConfig {
processor_generation: ProcessorGeneration::Milan, // FIXME could be ambiguous
spi_mode_bulldozer: efs.spi_mode_bulldozer().unwrap(),
spi_mode_zen_naples: efs.spi_mode_zen_naples().unwrap(),
spi_mode_zen_rome: efs.spi_mode_zen_rome().unwrap(),
processor_generation,
spi_mode_bulldozer: spi_mode_fallback_on_error(
efs.spi_mode_bulldozer(),
EfhBulldozerSpiMode::default(),
"Bulldozer SPI Mode",
),
spi_mode_zen_naples: spi_mode_fallback_on_error(
efs.spi_mode_zen_naples(),
EfhNaplesSpiMode::default(),
"Naples SPI Mode",
),
spi_mode_zen_rome: spi_mode_fallback_on_error(
efs.spi_mode_zen_rome(),
EfhRomeSpiMode::default(),
"Rome SPI Mode",
),
// TODO: psp_directory or psp_combo_directory
psp: dump_psp_directory(
&storage,
&efs.psp_directory().unwrap(),
&efs.psp_directory().expect("PSP directory"),
&blob_dump_dirname,
),
// TODO: bhd_directory or bhd_combo_directory
bhd: dump_bhd_directory(
&storage,
&efs.bhd_directory(None).unwrap(),
&efs.bhd_directory(Some(processor_generation))
.expect("BHD directory"),
&mut apcb_buffer_option,
&blob_dump_dirname,
),
Expand All @@ -766,7 +826,11 @@ fn dump(
let mut file = File::create(&path).expect("creation failed");
writeln!(file, "{}", json5::to_string(&config).unwrap())?;
} else {
println!("{}", serde_json::to_string_pretty(&config)?);
writeln!(
output_config_file,
"{}",
serde_json::to_string_pretty(&config)?
)?;
}
Ok(())
}
Expand Down Expand Up @@ -1155,21 +1219,42 @@ fn run() -> std::io::Result<()> {
};
match opts {
Opts::Dump { input_filename, blob_dump_dirname } => {
dump(&input_filename, blob_dump_dirname)
dump(&input_filename, blob_dump_dirname, &mut stdout().lock())
}
Opts::Generate {
output_filename,
efs_configuration_filename,
reset_image_filename,
blobdirs,
verbose,
} => generate(
&output_filename,
&efs_configuration_filename,
&reset_image_filename,
blobdirs,
verbose,
),
} => {
let x = generate(
&output_filename,
&efs_configuration_filename,
&reset_image_filename,
blobdirs,
verbose,
);

// In order to make sure that we can dump it back out, try it.
struct DummyOutput {}
impl std::io::Write for DummyOutput {
fn write(
&mut self,
buf: &[u8],
) -> std::result::Result<usize, std::io::Error>
{
Ok(buf.len())
}
fn flush(&mut self) -> std::result::Result<(), std::io::Error> {
Ok(())
}
}
let mut dummy_output = DummyOutput {};
dump(&output_filename, None, &mut dummy_output)
.expect("read it back out from the image");
x
}
}
}

Expand Down
Loading