1
1
use amd_apcb:: { Apcb , ApcbIoOptions } ;
2
2
use amd_efs:: {
3
3
AddressMode , BhdDirectory , BhdDirectoryEntry , BhdDirectoryEntryType ,
4
- DirectoryEntry , Efs , ProcessorGeneration , PspDirectory , PspDirectoryEntry ,
4
+ DirectoryEntry , EfhBulldozerSpiMode , EfhNaplesSpiMode , EfhRomeSpiMode , Efs ,
5
+ ProcessorGeneration , PspDirectory , PspDirectoryEntry ,
5
6
PspDirectoryEntryType , ValueOrLocation ,
6
7
} ;
7
8
use amd_host_image_builder_config:: {
@@ -19,6 +20,7 @@ use std::cmp::min;
19
20
use std:: collections:: HashSet ;
20
21
use std:: fs;
21
22
use std:: fs:: File ;
23
+ use std:: io:: stdout;
22
24
use std:: io:: BufReader ;
23
25
use std:: io:: Read ;
24
26
use std:: io:: Seek ;
@@ -634,6 +636,29 @@ fn serde_from_bhd_entry(
634
636
}
635
637
}
636
638
639
+ /// Try to return RESULT?.
640
+ /// If that doesn't work, print RESULT_TEXT and then return FALLBACK instead.
641
+ /// This is useful because some images don't have SPI mode set. As far as
642
+ /// we can tell, the SPI mode is mandatory. In order not to fail the entire
643
+ /// dump just because of the SPI mode, we just make one up here.
644
+ fn spi_mode_fallback_on_error < T , E : std:: fmt:: Display > (
645
+ result : std:: result:: Result < T , E > ,
646
+ fallback : T ,
647
+ result_text : & str ,
648
+ ) -> T {
649
+ match result {
650
+ Ok ( x) => x,
651
+ Err ( e) => {
652
+ eprintln ! (
653
+ "{} was invalid: {}. Falling back to default." ,
654
+ result_text, e
655
+ ) ;
656
+ // TODO: Maybe set program error status somehow
657
+ fallback
658
+ }
659
+ }
660
+ }
661
+
637
662
fn dump_bhd_directory < ' a , T : FlashRead + FlashWrite > (
638
663
storage : & T ,
639
664
bhd_directory : & BhdDirectory ,
@@ -653,6 +678,11 @@ fn dump_bhd_directory<'a, T: FlashRead + FlashWrite>(
653
678
. map_while ( |entry| {
654
679
let entry = entry. clone ( ) ;
655
680
if let Ok ( typ) = entry. typ_or_err ( ) {
681
+ if typ == BhdDirectoryEntryType :: Apob {
682
+ // Since this is a runtime value we cannot read it
683
+ // from the image.
684
+ return None ;
685
+ }
656
686
let payload_beginning =
657
687
bhd_directory. payload_beginning ( & entry) . unwrap ( ) ;
658
688
let size = entry. size ( ) . unwrap ( ) as usize ;
@@ -727,6 +757,7 @@ fn dump_bhd_directory<'a, T: FlashRead + FlashWrite>(
727
757
fn dump (
728
758
image_filename : & Path ,
729
759
blob_dump_dirname : Option < PathBuf > ,
760
+ output_config_file : & mut impl std:: io:: Write ,
730
761
) -> std:: io:: Result < ( ) > {
731
762
let filename = image_filename;
732
763
let storage = FlashImage :: load ( filename) ?;
@@ -735,25 +766,48 @@ fn dump(
735
766
if filesize <= 0x100_0000 { Some ( filesize as u32 ) } else { None } ;
736
767
let efs = Efs :: load ( & storage, None , amd_physical_mode_mmio_size) . unwrap ( ) ;
737
768
if !efs. compatible_with_processor_generation ( ProcessorGeneration :: Milan ) {
738
- panic ! ( "only Milan is supported for dumping right now" ) ;
769
+ if !efs. compatible_with_processor_generation ( ProcessorGeneration :: Rome )
770
+ {
771
+ panic ! ( "only Milan or Rome is supported for dumping right now" ) ;
772
+ }
739
773
}
740
774
let mut apcb_buffer = [ 0xFFu8 ; Apcb :: MAX_SIZE ] ;
741
775
let mut apcb_buffer_option = Some ( & mut apcb_buffer[ ..] ) ;
776
+ let processor_generation = if efs
777
+ . compatible_with_processor_generation ( ProcessorGeneration :: Milan )
778
+ {
779
+ ProcessorGeneration :: Milan
780
+ } else {
781
+ ProcessorGeneration :: Rome
782
+ } ;
742
783
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 ( ) ,
784
+ processor_generation,
785
+ spi_mode_bulldozer : spi_mode_fallback_on_error (
786
+ efs. spi_mode_bulldozer ( ) ,
787
+ EfhBulldozerSpiMode :: default ( ) ,
788
+ "Bulldozer SPI Mode" ,
789
+ ) ,
790
+ spi_mode_zen_naples : spi_mode_fallback_on_error (
791
+ efs. spi_mode_zen_naples ( ) ,
792
+ EfhNaplesSpiMode :: default ( ) ,
793
+ "Naples SPI Mode" ,
794
+ ) ,
795
+ spi_mode_zen_rome : spi_mode_fallback_on_error (
796
+ efs. spi_mode_zen_rome ( ) ,
797
+ EfhRomeSpiMode :: default ( ) ,
798
+ "Rome SPI Mode" ,
799
+ ) ,
747
800
// TODO: psp_directory or psp_combo_directory
748
801
psp : dump_psp_directory (
749
802
& storage,
750
- & efs. psp_directory ( ) . unwrap ( ) ,
803
+ & efs. psp_directory ( ) . expect ( "PSP directory" ) ,
751
804
& blob_dump_dirname,
752
805
) ,
753
806
// TODO: bhd_directory or bhd_combo_directory
754
807
bhd : dump_bhd_directory (
755
808
& storage,
756
- & efs. bhd_directory ( None ) . unwrap ( ) ,
809
+ & efs. bhd_directory ( Some ( processor_generation) )
810
+ . expect ( "BHD directory" ) ,
757
811
& mut apcb_buffer_option,
758
812
& blob_dump_dirname,
759
813
) ,
@@ -766,7 +820,11 @@ fn dump(
766
820
let mut file = File :: create ( & path) . expect ( "creation failed" ) ;
767
821
writeln ! ( file, "{}" , json5:: to_string( & config) . unwrap( ) ) ?;
768
822
} else {
769
- println ! ( "{}" , serde_json:: to_string_pretty( & config) ?) ;
823
+ writeln ! (
824
+ output_config_file,
825
+ "{}" ,
826
+ serde_json:: to_string_pretty( & config) ?
827
+ ) ?;
770
828
}
771
829
Ok ( ( ) )
772
830
}
@@ -1155,21 +1213,42 @@ fn run() -> std::io::Result<()> {
1155
1213
} ;
1156
1214
match opts {
1157
1215
Opts :: Dump { input_filename, blob_dump_dirname } => {
1158
- dump ( & input_filename, blob_dump_dirname)
1216
+ dump ( & input_filename, blob_dump_dirname, & mut stdout ( ) . lock ( ) )
1159
1217
}
1160
1218
Opts :: Generate {
1161
1219
output_filename,
1162
1220
efs_configuration_filename,
1163
1221
reset_image_filename,
1164
1222
blobdirs,
1165
1223
verbose,
1166
- } => generate (
1167
- & output_filename,
1168
- & efs_configuration_filename,
1169
- & reset_image_filename,
1170
- blobdirs,
1171
- verbose,
1172
- ) ,
1224
+ } => {
1225
+ let x = generate (
1226
+ & output_filename,
1227
+ & efs_configuration_filename,
1228
+ & reset_image_filename,
1229
+ blobdirs,
1230
+ verbose,
1231
+ ) ;
1232
+
1233
+ // In order to make sure that we can dump it back out, try it.
1234
+ struct DummyOutput { }
1235
+ impl std:: io:: Write for DummyOutput {
1236
+ fn write (
1237
+ & mut self ,
1238
+ buf : & [ u8 ] ,
1239
+ ) -> std:: result:: Result < usize , std:: io:: Error >
1240
+ {
1241
+ Ok ( buf. len ( ) )
1242
+ }
1243
+ fn flush ( & mut self ) -> std:: result:: Result < ( ) , std:: io:: Error > {
1244
+ Ok ( ( ) )
1245
+ }
1246
+ }
1247
+ let mut dummy_output = DummyOutput { } ;
1248
+ dump ( & output_filename, None , & mut dummy_output)
1249
+ . expect ( "read it back out from the image" ) ;
1250
+ x
1251
+ }
1173
1252
}
1174
1253
}
1175
1254
0 commit comments