From 68b9acd249990c27c668e1714cf6794d56a89aa6 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Wed, 26 Feb 2020 13:43:31 -0700 Subject: [PATCH] Add ability to flash backup rom --- src/board/system76/darp5/smfi.c | 8 +++- src/board/system76/galp3-c/smfi.c | 8 +++- src/board/system76/lemp9/smfi.c | 8 +++- src/common/include/common/command.h | 2 + tool/src/ec.rs | 62 ++++++++++++++++++++--------- tool/src/lib.rs | 2 +- tool/src/main.rs | 3 +- tool/src/spi.rs | 4 ++ 8 files changed, 71 insertions(+), 26 deletions(-) diff --git a/src/board/system76/darp5/smfi.c b/src/board/system76/darp5/smfi.c index 38a67e3..2708e83 100644 --- a/src/board/system76/darp5/smfi.c +++ b/src/board/system76/darp5/smfi.c @@ -82,8 +82,12 @@ static enum Result cmd_spi(void) { #ifdef __SCRATCH__ uint8_t len = smfi_cmd[3]; - // Enable chip (internal) - ECINDAR3 = 0x7F; + // Enable chip + if (flags & CMD_SPI_FLAG_BACKUP) { + ECINDAR3 = 0xFF; + } else { + ECINDAR3 = 0x7F; + } ECINDAR2 = 0xFF; ECINDAR1 = 0xFD; ECINDAR0 = 0x00; diff --git a/src/board/system76/galp3-c/smfi.c b/src/board/system76/galp3-c/smfi.c index 38a67e3..2708e83 100644 --- a/src/board/system76/galp3-c/smfi.c +++ b/src/board/system76/galp3-c/smfi.c @@ -82,8 +82,12 @@ static enum Result cmd_spi(void) { #ifdef __SCRATCH__ uint8_t len = smfi_cmd[3]; - // Enable chip (internal) - ECINDAR3 = 0x7F; + // Enable chip + if (flags & CMD_SPI_FLAG_BACKUP) { + ECINDAR3 = 0xFF; + } else { + ECINDAR3 = 0x7F; + } ECINDAR2 = 0xFF; ECINDAR1 = 0xFD; ECINDAR0 = 0x00; diff --git a/src/board/system76/lemp9/smfi.c b/src/board/system76/lemp9/smfi.c index 38a67e3..2708e83 100644 --- a/src/board/system76/lemp9/smfi.c +++ b/src/board/system76/lemp9/smfi.c @@ -82,8 +82,12 @@ static enum Result cmd_spi(void) { #ifdef __SCRATCH__ uint8_t len = smfi_cmd[3]; - // Enable chip (internal) - ECINDAR3 = 0x7F; + // Enable chip + if (flags & CMD_SPI_FLAG_BACKUP) { + ECINDAR3 = 0xFF; + } else { + ECINDAR3 = 0x7F; + } ECINDAR2 = 0xFF; ECINDAR1 = 0xFD; ECINDAR0 = 0x00; diff --git a/src/common/include/common/command.h b/src/common/include/common/command.h index d37da28..1f61566 100644 --- a/src/common/include/common/command.h +++ b/src/common/include/common/command.h @@ -34,6 +34,8 @@ enum CommandSpiFlag { CMD_SPI_FLAG_DISABLE = (1 << 1), // Run firmware from scratch RAM if necessary CMD_SPI_FLAG_SCRATCH = (1 << 2), + // Write to backup ROM instead + CMD_SPI_FLAG_BACKUP = (1 << 3), }; #endif // _COMMON_COMMAND_H diff --git a/tool/src/ec.rs b/tool/src/ec.rs index a93be11..7b2fe5b 100644 --- a/tool/src/ec.rs +++ b/tool/src/ec.rs @@ -3,6 +3,7 @@ use hwio::{Io, Pio}; use crate::{ Error, Spi, + SpiTarget, SuperIo, Timeout, timeout @@ -23,6 +24,7 @@ pub enum Cmd { pub const CMD_SPI_FLAG_READ: u8 = (1 << 0); pub const CMD_SPI_FLAG_DISABLE: u8 = (1 << 1); pub const CMD_SPI_FLAG_SCRATCH: u8 = (1 << 2); +pub const CMD_SPI_FLAG_BACKUP: u8 = (1 << 3); pub struct Ec { cmd: u16, @@ -149,9 +151,10 @@ impl Ec { Ok(i) } - pub unsafe fn spi(&mut self, scratch: bool) -> Result, Error> { + pub unsafe fn spi(&mut self, target: SpiTarget, scratch: bool) -> Result, Error> { let mut spi = EcSpi { ec: self, + target, scratch, }; spi.reset()?; @@ -165,49 +168,71 @@ impl Ec { pub struct EcSpi<'a, T: Timeout> { ec: &'a mut Ec, + target: SpiTarget, scratch: bool, } +impl<'a, T: Timeout> EcSpi<'a, T> { + fn flags(&self, read: bool, disable: bool) -> u8 { + let mut flags = 0; + + if read { + flags |= CMD_SPI_FLAG_READ; + } + + if disable { + flags |= CMD_SPI_FLAG_DISABLE; + } + + if self.scratch { + flags |= CMD_SPI_FLAG_SCRATCH; + } + + match self.target { + SpiTarget::Main => (), + SpiTarget::Backup => { + flags |= CMD_SPI_FLAG_BACKUP; + }, + } + + flags + } +} + impl<'a, T: Timeout> Spi for EcSpi<'a, T> { /// Disable SPI chip, must be done before and after a transaction unsafe fn reset(&mut self) -> Result<(), Error> { - let flags = - CMD_SPI_FLAG_DISABLE | - if self.scratch { CMD_SPI_FLAG_SCRATCH } else { 0 }; - + let flags = self.flags(false, true); self.ec.write(2, flags); self.ec.write(3, 0); self.ec.command(Cmd::Spi)?; - assert_eq!(self.ec.read(3), 0); - + if self.ec.read(3) != 0 { + return Err(Error::Verify); + } Ok(()) } /// SPI read unsafe fn read(&mut self, data: &mut [u8]) -> Result { - let flags = - CMD_SPI_FLAG_READ | - if self.scratch { CMD_SPI_FLAG_SCRATCH } else { 0 }; - + let flags = self.flags(true, false); for chunk in data.chunks_mut(256 - 4) { self.ec.write(2, flags); self.ec.write(3, chunk.len() as u8); self.ec.command(Cmd::Spi)?; - assert_eq!(self.ec.read(3), chunk.len() as u8); + if self.ec.read(3) != chunk.len() as u8 { + return Err(Error::Verify); + } for i in 0..chunk.len() { chunk[i] = self.ec.read(i as u8 + 4); } } - Ok(data.len()) } /// SPI write unsafe fn write(&mut self, data: &[u8]) -> Result { - let flags = - if self.scratch { CMD_SPI_FLAG_SCRATCH } else { 0 }; - + let flags = self.flags(false, false); for chunk in data.chunks(256 - 4) { for i in 0..chunk.len() { self.ec.write(i as u8 + 4, chunk[i]); @@ -216,9 +241,10 @@ impl<'a, T: Timeout> Spi for EcSpi<'a, T> { self.ec.write(2, flags); self.ec.write(3, chunk.len() as u8); self.ec.command(Cmd::Spi)?; - assert_eq!(self.ec.read(3), chunk.len() as u8); + if self.ec.read(3) != chunk.len() as u8 { + return Err(Error::Verify); + } } - Ok(data.len()) } } diff --git a/tool/src/lib.rs b/tool/src/lib.rs index e95400c..6ebe681 100644 --- a/tool/src/lib.rs +++ b/tool/src/lib.rs @@ -15,7 +15,7 @@ mod legacy; pub use self::pmc::Pmc; mod pmc; -pub use self::spi::{Spi, SpiRom}; +pub use self::spi::{Spi, SpiRom, SpiTarget}; mod spi; pub use self::super_io::SuperIo; diff --git a/tool/src/main.rs b/tool/src/main.rs index 84e47f0..786cd80 100644 --- a/tool/src/main.rs +++ b/tool/src/main.rs @@ -3,6 +3,7 @@ use ectool::{ Error, Firmware, SpiRom, + SpiTarget, Timeout, }; use std::{ @@ -77,7 +78,7 @@ unsafe fn flash_inner(ec: &mut Ec, firmware: &Firmware) -> Result<() let rom_size = 128 * 1024; let sector_size = 1024; - let mut spi_bus = ec.spi(true)?; + let mut spi_bus = ec.spi(SpiTarget::Main, true)?; let mut spi = SpiRom::new( &mut spi_bus, StdTimeout::new(Duration::new(1, 0)) diff --git a/tool/src/spi.rs b/tool/src/spi.rs index 3aab087..dbef79b 100644 --- a/tool/src/spi.rs +++ b/tool/src/spi.rs @@ -9,6 +9,10 @@ pub trait Spi { unsafe fn write(&mut self, data: &[u8]) -> Result; } +pub enum SpiTarget { + Main, + Backup, +} pub struct SpiRom<'a, S: Spi, T: Timeout> { spi: &'a mut S,