@@ -19,10 +19,16 @@ use amd_efs::{
19
19
use amd_flash:: Location ;
20
20
21
21
#[ derive( Debug ) ]
22
+ #[ derive( thiserror:: Error ) ]
23
+ #[ non_exhaustive]
22
24
pub enum Error {
25
+ #[ error( "Efs {0}" ) ]
23
26
Efs ( amd_efs:: Error ) ,
27
+ #[ error( "incompatible executable" ) ]
24
28
IncompatibleExecutable ,
29
+ #[ error( "Io {0}" ) ]
25
30
Io ( std:: io:: Error ) ,
31
+ #[ error( "image too big" ) ]
26
32
ImageTooBig ,
27
33
}
28
34
@@ -283,21 +289,102 @@ pub enum SerdeBhdDirectoryVariant<'a> {
283
289
#[ derive( serde:: Serialize , serde:: Deserialize , schemars:: JsonSchema ) ]
284
290
#[ serde( rename = "Config" ) ]
285
291
#[ serde( deny_unknown_fields) ]
286
- pub struct SerdeConfig < ' a > {
292
+ struct RawSerdeConfig < ' a > {
287
293
pub processor_generation : ProcessorGeneration ,
288
294
#[ serde( default ) ]
289
- pub spi_mode_bulldozer : EfhBulldozerSpiMode ,
295
+ pub spi_mode_bulldozer : Option < EfhBulldozerSpiMode > ,
290
296
#[ serde( default ) ]
291
- pub spi_mode_zen_naples : EfhNaplesSpiMode ,
297
+ pub spi_mode_zen_naples : Option < EfhNaplesSpiMode > ,
292
298
#[ serde( default ) ]
293
- pub spi_mode_zen_rome : EfhRomeSpiMode ,
299
+ pub spi_mode_zen_rome : Option < EfhRomeSpiMode > ,
294
300
pub psp : SerdePspDirectoryVariant ,
295
301
#[ serde( bound(
296
302
deserialize = "SerdeBhdDirectoryVariant<'a>: Deserialize<'de>"
297
303
) ) ]
298
304
pub bhd : SerdeBhdDirectoryVariant < ' a > ,
299
305
}
300
306
307
+ // TODO: #[serde(bound(serialize = "T: MySerTrait", deserialize = "T: MyDeTrait"))]
308
+ // TODO: impl serde::Serialize
309
+ #[ derive( serde:: Serialize , serde:: Deserialize ) ]
310
+ #[ serde( try_from = "RawSerdeConfig" ) ]
311
+ #[ serde( into = "RawSerdeConfig" ) ]
312
+ pub struct SerdeConfig < ' a > { // Note: same fields as above!
313
+ pub processor_generation : ProcessorGeneration ,
314
+ pub spi_mode_bulldozer : Option < EfhBulldozerSpiMode > ,
315
+ pub spi_mode_zen_naples : Option < EfhNaplesSpiMode > ,
316
+ pub spi_mode_zen_rome : Option < EfhRomeSpiMode > ,
317
+ pub psp : SerdePspDirectoryVariant ,
318
+ pub bhd : SerdeBhdDirectoryVariant < ' a > ,
319
+ }
320
+
321
+ impl < ' a > schemars:: JsonSchema for SerdeConfig < ' a > {
322
+ fn schema_name ( ) -> std:: string:: String {
323
+ RawSerdeConfig :: schema_name ( )
324
+ }
325
+ fn json_schema (
326
+ gen : & mut schemars:: gen:: SchemaGenerator ,
327
+ ) -> schemars:: schema:: Schema {
328
+ RawSerdeConfig :: json_schema ( gen)
329
+ }
330
+ fn is_referenceable ( ) -> bool {
331
+ RawSerdeConfig :: is_referenceable ( )
332
+ }
333
+ }
334
+
335
+ impl < ' a > From < SerdeConfig < ' a > > for RawSerdeConfig < ' a > {
336
+ fn from ( config : SerdeConfig < ' a > ) -> Self {
337
+ Self {
338
+ processor_generation : config. processor_generation ,
339
+ spi_mode_bulldozer : config. spi_mode_bulldozer ,
340
+ spi_mode_zen_naples : config. spi_mode_zen_naples ,
341
+ spi_mode_zen_rome : config. spi_mode_zen_rome ,
342
+ psp : config. psp ,
343
+ bhd : config. bhd ,
344
+ }
345
+ }
346
+ }
347
+
348
+ /// This validates whether the spi mode is compatible with the
349
+ /// processor generation (used to validate after deserialization
350
+ /// of a json5 config)
351
+ impl < ' a > core:: convert:: TryFrom < RawSerdeConfig < ' a > > for SerdeConfig < ' a > {
352
+ type Error = Error ;
353
+ fn try_from ( raw : RawSerdeConfig < ' a > ) -> core:: result:: Result < Self , Self :: Error > {
354
+ match raw. processor_generation {
355
+ ProcessorGeneration :: Naples => {
356
+ if raw. spi_mode_bulldozer . is_none ( )
357
+ && raw. spi_mode_zen_naples . is_some ( )
358
+ && raw. spi_mode_zen_rome . is_none ( ) {
359
+ return Ok ( SerdeConfig {
360
+ processor_generation : raw. processor_generation ,
361
+ spi_mode_bulldozer : raw. spi_mode_bulldozer ,
362
+ spi_mode_zen_naples : raw. spi_mode_zen_naples ,
363
+ spi_mode_zen_rome : raw. spi_mode_zen_rome ,
364
+ psp : raw. psp ,
365
+ bhd : raw. bhd ,
366
+ } ) ;
367
+ }
368
+ }
369
+ ProcessorGeneration :: Rome | ProcessorGeneration :: Milan => {
370
+ if raw. spi_mode_bulldozer . is_none ( )
371
+ && raw. spi_mode_zen_naples . is_none ( )
372
+ && raw. spi_mode_zen_rome . is_some ( ) {
373
+ return Ok ( SerdeConfig {
374
+ processor_generation : raw. processor_generation ,
375
+ spi_mode_bulldozer : raw. spi_mode_bulldozer ,
376
+ spi_mode_zen_naples : raw. spi_mode_zen_naples ,
377
+ spi_mode_zen_rome : raw. spi_mode_zen_rome ,
378
+ psp : raw. psp ,
379
+ bhd : raw. bhd ,
380
+ } ) ;
381
+ }
382
+ }
383
+ }
384
+ Err ( Error :: Efs ( amd_efs:: Error :: SpiModeMismatch ) )
385
+ }
386
+ }
387
+
301
388
#[ cfg( test) ]
302
389
mod tests {
303
390
#[ test]
0 commit comments