@@ -51,7 +51,7 @@ use serde::{Deserialize, Serialize};
5151use zerocopy:: { FromBytes , IntoBytes } ;
5252use zerocopy_derive:: { FromBytes , Immutable , IntoBytes } ;
5353
54- use crate :: EMPTY ;
54+ use crate :: { EMPTY , me :: Generation , ver :: Version } ;
5555
5656// NOTE: This is the LE representation.
5757const MAGIC : u32 = 0x0ff0_a55a ;
@@ -509,40 +509,116 @@ impl Debug for IFD {
509509 }
510510}
511511
512- // Extract a bit from a given byte, as bool.
513- fn extract_bit ( byte : u32 , bit : u32 ) -> bool {
514- byte >> bit & 1 == 1
512+ /// Extract a bit from a given byte, as bool.
513+ fn extract_bit ( straps : & Vec < u32 > , byte : usize , bit : u32 ) -> bool {
514+ straps[ byte] >> bit & 1 == 1
515+ }
516+
517+ /// Set or clear a bit in a given strap, identified by its number.
518+ fn set_bit ( straps : & mut Vec < u32 > , byte : usize , bit : u32 , s : bool ) {
519+ let b = straps[ byte] ;
520+ straps[ byte] = b & !( 1 << bit) | ( ( s as u32 ) << bit) ;
515521}
516522
517523// TODO: The straps changed over the generations of processors.
518524// Specifically the HAP bit on Skylake and later has moved, so we should not
519525// blindly assume it.
520526impl IFD {
527+ // TODO: What is CSE in debug mode?
528+ // https://review.coreboot.org/c/coreboot/+/88307/5
529+
521530 /// Direct Connect Interface
522531 // from <https://review.coreboot.org/c/coreboot/+/82272>
523532 // <https://edc.intel.com/content/www/us/en/design/products-and-solutions/processors-and-chipsets/700-series-chipset-family-platform-controller-hub-datasheet-volume-1-of/004/intel-direct-connect-interface-dci/>
524533 pub fn dci ( & self ) -> bool {
525- extract_bit ( self . pch_straps [ 0 ] , 17 )
534+ extract_bit ( & self . pch_straps , 0 , 17 )
526535 }
536+ /// Direct Connect Interface
537+ pub fn set_dci ( & mut self , s : bool ) {
538+ set_bit ( & mut self . pch_straps , 0 , 17 , s)
539+ }
540+
541+ // TODO: there is a _different_ soft-disable feature
542+ // https://review.coreboot.org/c/coreboot/+/78911/comments/61e2b541_b4faa3e4
543+ // TODO: make ME version a parameter to infer platform
527544 /// High-Assurance Platform (ME soft-disable), ME Gen 3
528545 pub fn hap ( & self ) -> bool {
529- extract_bit ( self . pch_straps [ 0 ] , 16 )
546+ extract_bit ( & self . pch_straps , 0 , 16 )
530547 }
548+ /// High-Assurance Platform (ME soft-disable), ME Gen 3
549+ pub fn set_hap ( & mut self , s : bool ) {
550+ set_bit ( & mut self . pch_straps , 0 , 16 , s)
551+ }
552+
531553 /// I/O Controller Hub, ME Gen 1
532554 pub fn ich_me_disabled ( & self ) -> bool {
533- extract_bit ( self . pch_straps [ 0 ] , 0 )
555+ extract_bit ( & self . pch_straps , 0 , 0 )
556+ }
557+ /// I/O Controller Hub, ME Gen 1
558+ pub fn set_ich_me_disabled ( & mut self , s : bool ) {
559+ set_bit ( & mut self . pch_straps , 0 , 0 , s)
534560 }
561+
535562 /// Memory Controller Hub, ME Gen 1
536563 pub fn mch_me_disabled ( & self ) -> bool {
537- extract_bit ( self . mch_straps [ 0 ] , 0 )
564+ extract_bit ( & self . mch_straps , 0 , 0 )
565+ }
566+ /// Memory Controller Hub, ME Gen 1
567+ pub fn set_mch_me_disabled ( & mut self , s : bool ) {
568+ set_bit ( & mut self . mch_straps , 0 , 0 , s)
538569 }
570+
539571 /// Memory Controller Hub (alternative), ME Gen 1
540572 pub fn mch_alt_me_disabled ( & self ) -> bool {
541- extract_bit ( self . mch_straps [ 0 ] , 7 )
573+ extract_bit ( & self . mch_straps , 0 , 7 )
574+ }
575+ /// Memory Controller Hub (alternative), ME Gen 1
576+ pub fn set_mch_alt_me_disabled ( & mut self , s : bool ) {
577+ set_bit ( & mut self . mch_straps , 0 , 7 , s)
542578 }
579+
543580 /// Disable ME (alternative), ME Gen 2
544581 pub fn alt_me_disabled ( & self ) -> bool {
545- extract_bit ( self . pch_straps [ 10 ] , 7 )
582+ extract_bit ( & self . pch_straps , 10 , 7 )
583+ }
584+ /// Disable ME (alternative), ME Gen 2
585+ pub fn set_alt_me_disabled ( & mut self , s : bool ) {
586+ set_bit ( & mut self . pch_straps , 10 , 7 , s)
587+ }
588+
589+ /// Disable ME for ME generation 3.
590+ /// Requires passing the ME version in order to infer the platform.
591+ pub fn disable_me_gen3 ( & mut self , me_ver : & Option < Version > ) -> Result < ( ) , String > {
592+ if let Some ( ver) = me_ver {
593+ match ver. major {
594+ 11 => self . set_hap ( true ) ,
595+ _ => return Err ( "ME > 11 not yet supported" . into ( ) ) ,
596+ }
597+ }
598+ Ok ( ( ) )
599+ }
600+
601+ /// Disable the ME using any mechanism given the ME generation and version.
602+ pub fn disable_me (
603+ & mut self ,
604+ me_gen : & Generation ,
605+ me_ver : & Option < Version > ,
606+ ) -> Result < ( ) , String > {
607+ match me_gen {
608+ Generation :: Gen1 => {
609+ self . set_ich_me_disabled ( true ) ;
610+ self . set_mch_me_disabled ( true ) ;
611+ // NOTE: coreboot ifdtool would also set the AltMeDisable bit here.
612+ // TODO: self.set_alt_me_disabled(true);
613+ Ok ( ( ) )
614+ }
615+ Generation :: Gen2 => {
616+ self . set_alt_me_disabled ( true ) ;
617+ Ok ( ( ) )
618+ }
619+ Generation :: Gen3 => self . disable_me_gen3 ( me_ver) ,
620+ _ => Err ( "Unknown ME generation/version" . into ( ) ) ,
621+ }
546622 }
547623}
548624
0 commit comments