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,24 @@ fn serde_from_bhd_entry(
634
636
}
635
637
}
636
638
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
+
637
657
fn dump_bhd_directory < ' a , T : FlashRead + FlashWrite > (
638
658
storage : & T ,
639
659
bhd_directory : & BhdDirectory ,
@@ -653,6 +673,11 @@ fn dump_bhd_directory<'a, T: FlashRead + FlashWrite>(
653
673
. map_while ( |entry| {
654
674
let entry = entry. clone ( ) ;
655
675
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
+ }
656
681
let payload_beginning =
657
682
bhd_directory. payload_beginning ( & entry) . unwrap ( ) ;
658
683
let size = entry. size ( ) . unwrap ( ) as usize ;
@@ -727,6 +752,7 @@ fn dump_bhd_directory<'a, T: FlashRead + FlashWrite>(
727
752
fn dump (
728
753
image_filename : & Path ,
729
754
blob_dump_dirname : Option < PathBuf > ,
755
+ output_config_file : & mut impl std:: io:: Write ,
730
756
) -> std:: io:: Result < ( ) > {
731
757
let filename = image_filename;
732
758
let storage = FlashImage :: load ( filename) ?;
@@ -735,25 +761,48 @@ fn dump(
735
761
if filesize <= 0x100_0000 { Some ( filesize as u32 ) } else { None } ;
736
762
let efs = Efs :: load ( & storage, None , amd_physical_mode_mmio_size) . unwrap ( ) ;
737
763
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
+ }
739
768
}
740
769
let mut apcb_buffer = [ 0xFFu8 ; Apcb :: MAX_SIZE ] ;
741
770
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
+ } ;
742
778
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
+ ) ,
747
795
// TODO: psp_directory or psp_combo_directory
748
796
psp : dump_psp_directory (
749
797
& storage,
750
- & efs. psp_directory ( ) . unwrap ( ) ,
798
+ & efs. psp_directory ( ) . expect ( "PSP directory" ) ,
751
799
& blob_dump_dirname,
752
800
) ,
753
801
// TODO: bhd_directory or bhd_combo_directory
754
802
bhd : dump_bhd_directory (
755
803
& storage,
756
- & efs. bhd_directory ( None ) . unwrap ( ) ,
804
+ & efs. bhd_directory ( Some ( processor_generation) )
805
+ . expect ( "BHD directory" ) ,
757
806
& mut apcb_buffer_option,
758
807
& blob_dump_dirname,
759
808
) ,
@@ -766,7 +815,11 @@ fn dump(
766
815
let mut file = File :: create ( & path) . expect ( "creation failed" ) ;
767
816
writeln ! ( file, "{}" , json5:: to_string( & config) . unwrap( ) ) ?;
768
817
} else {
769
- println ! ( "{}" , serde_json:: to_string_pretty( & config) ?) ;
818
+ writeln ! (
819
+ output_config_file,
820
+ "{}" ,
821
+ serde_json:: to_string_pretty( & config) ?
822
+ ) ?;
770
823
}
771
824
Ok ( ( ) )
772
825
}
@@ -1155,21 +1208,42 @@ fn run() -> std::io::Result<()> {
1155
1208
} ;
1156
1209
match opts {
1157
1210
Opts :: Dump { input_filename, blob_dump_dirname } => {
1158
- dump ( & input_filename, blob_dump_dirname)
1211
+ dump ( & input_filename, blob_dump_dirname, & mut stdout ( ) . lock ( ) )
1159
1212
}
1160
1213
Opts :: Generate {
1161
1214
output_filename,
1162
1215
efs_configuration_filename,
1163
1216
reset_image_filename,
1164
1217
blobdirs,
1165
1218
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
+ }
1173
1247
}
1174
1248
}
1175
1249
0 commit comments