Skip to content

Commit 48af639

Browse files
committed
ifd: rework helpers, add helpers to (un)set bits
Also leave some open questions and TODOs. Signed-off-by: Daniel Maslowski <[email protected]>
1 parent 9b668c0 commit 48af639

File tree

1 file changed

+86
-10
lines changed

1 file changed

+86
-10
lines changed

src/ifd.rs

Lines changed: 86 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ use serde::{Deserialize, Serialize};
5151
use zerocopy::{FromBytes, IntoBytes};
5252
use 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.
5757
const 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.
520526
impl 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

Comments
 (0)