From 15e2dee97ae604d148f63ac7c5de165ed8ca2cb0 Mon Sep 17 00:00:00 2001 From: Tim Crawford Date: Wed, 7 Jun 2023 11:01:33 -0600 Subject: [PATCH] Invalidate CMOS checksum after flashing Ensure that coreboot will write out the default CMOS options after flashing a new firmware image by invalidating the checksum field. Signed-off-by: Tim Crawford --- src/app/bios.rs | 11 +++++++++-- src/app/cmos.rs | 33 +++++++++++++++++++++++++++++++++ src/app/mod.rs | 1 + 3 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 src/app/cmos.rs diff --git a/src/app/bios.rs b/src/app/bios.rs index c635f8c..6b7530b 100644 --- a/src/app/bios.rs +++ b/src/app/bios.rs @@ -15,8 +15,8 @@ use std::uefi::status::{Error, Result, Status}; use std::vars::{get_boot_item, get_boot_order, set_boot_item, set_boot_order}; use super::{ - pci_mcfg, shell, Component, UefiMapper, FIRMWARECAP, FIRMWAREDIR, FIRMWARENSH, FIRMWAREROM, - H2OFFT, IFLASHV, UEFIFLASH, + cmos, pci_mcfg, shell, Component, UefiMapper, FIRMWARECAP, FIRMWAREDIR, FIRMWARENSH, + FIRMWAREROM, H2OFFT, IFLASHV, UEFIFLASH, }; fn copy_region( @@ -512,6 +512,13 @@ impl Component for BiosComponent { } println!(); } + + // Invalidate the 2-byte CMOS checksum to force writing the option defaults. + let mut cmos = cmos::Cmos::default(); + let old_hi = cmos.read(123); + let old_lo = cmos.read(124); + cmos.write(123, !old_hi); + cmos.write(124, !old_lo); } else { find(FIRMWARENSH)?; diff --git a/src/app/cmos.rs b/src/app/cmos.rs new file mode 100644 index 0000000..ba2ce25 --- /dev/null +++ b/src/app/cmos.rs @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: GPL-3.0-only + +use hwio::{Io, Pio}; + +pub struct Cmos { + port: Pio, + data: Pio, +} + +impl Cmos { + pub fn new(port: u16) -> Self { + Self { + port: Pio::::new(port), + data: Pio::::new(port + 1), + } + } + + pub fn read(&mut self, addr: u8) -> u8 { + self.port.write(addr); + self.data.read() + } + + pub fn write(&mut self, addr: u8, data: u8) { + self.port.write(addr); + self.data.write(data); + } +} + +impl Default for Cmos { + fn default() -> Self { + Self::new(0x70) + } +} diff --git a/src/app/mod.rs b/src/app/mod.rs index 429ad4a..0dbe109 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -28,6 +28,7 @@ pub use self::mapper::UefiMapper; pub use self::pci::{pci_mcfg, pci_read}; mod bios; +mod cmos; mod component; mod ec; mod mapper;