Skip to content

Commit 408e711

Browse files
committed
Improve dump subcommand.
Fixes <#160>.
1 parent c919b79 commit 408e711

File tree

2 files changed

+95
-21
lines changed

2 files changed

+95
-21
lines changed

Cargo.lock

+4-4
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/main.rs

+91-17
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
use amd_apcb::{Apcb, ApcbIoOptions};
22
use amd_efs::{
33
AddressMode, BhdDirectory, BhdDirectoryEntry, BhdDirectoryEntryType,
4-
DirectoryEntry, Efs, ProcessorGeneration, PspDirectory, PspDirectoryEntry,
4+
DirectoryEntry, EfhBulldozerSpiMode, EfhNaplesSpiMode, EfhRomeSpiMode, Efs,
5+
ProcessorGeneration, PspDirectory, PspDirectoryEntry,
56
PspDirectoryEntryType, ValueOrLocation,
67
};
78
use amd_host_image_builder_config::{
@@ -19,6 +20,7 @@ use std::cmp::min;
1920
use std::collections::HashSet;
2021
use std::fs;
2122
use std::fs::File;
23+
use std::io::stdout;
2224
use std::io::BufReader;
2325
use std::io::Read;
2426
use std::io::Seek;
@@ -634,6 +636,24 @@ fn serde_from_bhd_entry(
634636
}
635637
}
636638

639+
fn spi_fallback_on_error<T, E: std::fmt::Display>(
640+
result: std::result::Result<T, E>,
641+
fallback: T,
642+
result_text: &str,
643+
) -> T {
644+
match result {
645+
Ok(x) => x,
646+
Err(e) => {
647+
eprintln!(
648+
"{} was invalid: {}. Falling back to default.",
649+
result_text, e
650+
);
651+
// TODO: Maybe set program error status somehow
652+
fallback
653+
}
654+
}
655+
}
656+
637657
fn dump_bhd_directory<'a, T: FlashRead + FlashWrite>(
638658
storage: &T,
639659
bhd_directory: &BhdDirectory,
@@ -653,6 +673,11 @@ fn dump_bhd_directory<'a, T: FlashRead + FlashWrite>(
653673
.map_while(|entry| {
654674
let entry = entry.clone();
655675
if let Ok(typ) = entry.typ_or_err() {
676+
if typ == BhdDirectoryEntryType::Apob {
677+
// Since this is a runtime value we cannot read it
678+
// from the image.
679+
return None;
680+
}
656681
let payload_beginning =
657682
bhd_directory.payload_beginning(&entry).unwrap();
658683
let size = entry.size().unwrap() as usize;
@@ -727,6 +752,7 @@ fn dump_bhd_directory<'a, T: FlashRead + FlashWrite>(
727752
fn dump(
728753
image_filename: &Path,
729754
blob_dump_dirname: Option<PathBuf>,
755+
output_config_file: &mut impl std::io::Write,
730756
) -> std::io::Result<()> {
731757
let filename = image_filename;
732758
let storage = FlashImage::load(filename)?;
@@ -735,25 +761,48 @@ fn dump(
735761
if filesize <= 0x100_0000 { Some(filesize as u32) } else { None };
736762
let efs = Efs::load(&storage, None, amd_physical_mode_mmio_size).unwrap();
737763
if !efs.compatible_with_processor_generation(ProcessorGeneration::Milan) {
738-
panic!("only Milan is supported for dumping right now");
764+
if !efs.compatible_with_processor_generation(ProcessorGeneration::Rome)
765+
{
766+
panic!("only Milan or Rome is supported for dumping right now");
767+
}
739768
}
740769
let mut apcb_buffer = [0xFFu8; Apcb::MAX_SIZE];
741770
let mut apcb_buffer_option = Some(&mut apcb_buffer[..]);
771+
let processor_generation = if efs
772+
.compatible_with_processor_generation(ProcessorGeneration::Milan)
773+
{
774+
ProcessorGeneration::Milan
775+
} else {
776+
ProcessorGeneration::Rome
777+
};
742778
let config = SerdeConfig {
743-
processor_generation: ProcessorGeneration::Milan, // FIXME could be ambiguous
744-
spi_mode_bulldozer: efs.spi_mode_bulldozer().unwrap(),
745-
spi_mode_zen_naples: efs.spi_mode_zen_naples().unwrap(),
746-
spi_mode_zen_rome: efs.spi_mode_zen_rome().unwrap(),
779+
processor_generation,
780+
spi_mode_bulldozer: spi_fallback_on_error(
781+
efs.spi_mode_bulldozer(),
782+
EfhBulldozerSpiMode::default(),
783+
"Bulldozer SPI Mode",
784+
),
785+
spi_mode_zen_naples: spi_fallback_on_error(
786+
efs.spi_mode_zen_naples(),
787+
EfhNaplesSpiMode::default(),
788+
"Naples SPI Mode",
789+
),
790+
spi_mode_zen_rome: spi_fallback_on_error(
791+
efs.spi_mode_zen_rome(),
792+
EfhRomeSpiMode::default(),
793+
"Rome SPI Mode",
794+
),
747795
// TODO: psp_directory or psp_combo_directory
748796
psp: dump_psp_directory(
749797
&storage,
750-
&efs.psp_directory().unwrap(),
798+
&efs.psp_directory().expect("PSP directory"),
751799
&blob_dump_dirname,
752800
),
753801
// TODO: bhd_directory or bhd_combo_directory
754802
bhd: dump_bhd_directory(
755803
&storage,
756-
&efs.bhd_directory(None).unwrap(),
804+
&efs.bhd_directory(Some(processor_generation))
805+
.expect("BHD directory"),
757806
&mut apcb_buffer_option,
758807
&blob_dump_dirname,
759808
),
@@ -766,7 +815,11 @@ fn dump(
766815
let mut file = File::create(&path).expect("creation failed");
767816
writeln!(file, "{}", json5::to_string(&config).unwrap())?;
768817
} else {
769-
println!("{}", serde_json::to_string_pretty(&config)?);
818+
writeln!(
819+
output_config_file,
820+
"{}",
821+
serde_json::to_string_pretty(&config)?
822+
)?;
770823
}
771824
Ok(())
772825
}
@@ -1155,21 +1208,42 @@ fn run() -> std::io::Result<()> {
11551208
};
11561209
match opts {
11571210
Opts::Dump { input_filename, blob_dump_dirname } => {
1158-
dump(&input_filename, blob_dump_dirname)
1211+
dump(&input_filename, blob_dump_dirname, &mut stdout().lock())
11591212
}
11601213
Opts::Generate {
11611214
output_filename,
11621215
efs_configuration_filename,
11631216
reset_image_filename,
11641217
blobdirs,
11651218
verbose,
1166-
} => generate(
1167-
&output_filename,
1168-
&efs_configuration_filename,
1169-
&reset_image_filename,
1170-
blobdirs,
1171-
verbose,
1172-
),
1219+
} => {
1220+
let x = generate(
1221+
&output_filename,
1222+
&efs_configuration_filename,
1223+
&reset_image_filename,
1224+
blobdirs,
1225+
verbose,
1226+
);
1227+
1228+
// In order to make sure that we can dump it back out, try it.
1229+
struct DummyOutput {}
1230+
impl std::io::Write for DummyOutput {
1231+
fn write(
1232+
&mut self,
1233+
buf: &[u8],
1234+
) -> std::result::Result<usize, std::io::Error>
1235+
{
1236+
Ok(buf.len())
1237+
}
1238+
fn flush(&mut self) -> std::result::Result<(), std::io::Error> {
1239+
Ok(())
1240+
}
1241+
}
1242+
let mut dummy_output = DummyOutput {};
1243+
dump(&output_filename, None, &mut dummy_output)
1244+
.expect("read it back out from the image");
1245+
x
1246+
}
11731247
}
11741248
}
11751249

0 commit comments

Comments
 (0)