Better output when flashing EC
This commit is contained in:
113
tool/src/main.rs
113
tool/src/main.rs
@ -2,6 +2,7 @@ use ectool::{
|
|||||||
Ec,
|
Ec,
|
||||||
Error,
|
Error,
|
||||||
Firmware,
|
Firmware,
|
||||||
|
Spi,
|
||||||
SpiRom,
|
SpiRom,
|
||||||
SpiTarget,
|
SpiTarget,
|
||||||
Timeout,
|
Timeout,
|
||||||
@ -74,9 +75,30 @@ unsafe fn console() -> Result<(), Error> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsafe fn flash_read<S: Spi>(spi: &mut SpiRom<S, StdTimeout>, rom: &mut [u8], sector_size: usize) -> Result<(), Error> {
|
||||||
|
let mut address = 0;
|
||||||
|
while address < rom.len() {
|
||||||
|
eprint!("\rSPI Read {}K", address / 1024);
|
||||||
|
let next_address = address + sector_size;
|
||||||
|
let count = spi.read_at(address as u32, &mut rom[address..next_address])?;
|
||||||
|
if count != sector_size {
|
||||||
|
eprintln!("\ncount {} did not match sector size {}", count, sector_size);
|
||||||
|
return Err(Error::Verify);
|
||||||
|
}
|
||||||
|
address = next_address;
|
||||||
|
}
|
||||||
|
eprintln!("\rSPI Read {}K", address / 1024);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
unsafe fn flash_inner(ec: &mut Ec<StdTimeout>, firmware: &Firmware, target: SpiTarget, scratch: bool) -> Result<(), Error> {
|
unsafe fn flash_inner(ec: &mut Ec<StdTimeout>, firmware: &Firmware, target: SpiTarget, scratch: bool) -> Result<(), Error> {
|
||||||
let rom_size = 128 * 1024;
|
let rom_size = 128 * 1024;
|
||||||
let sector_size = 1024;
|
let sector_size = 4096;
|
||||||
|
|
||||||
|
let mut new_rom = firmware.data.to_vec();
|
||||||
|
while new_rom.len() < rom_size {
|
||||||
|
new_rom.push(0xFF);
|
||||||
|
}
|
||||||
|
|
||||||
let mut spi_bus = ec.spi(target, scratch)?;
|
let mut spi_bus = ec.spi(target, scratch)?;
|
||||||
let mut spi = SpiRom::new(
|
let mut spi = SpiRom::new(
|
||||||
@ -84,10 +106,8 @@ unsafe fn flash_inner(ec: &mut Ec<StdTimeout>, firmware: &Firmware, target: SpiT
|
|||||||
StdTimeout::new(Duration::new(1, 0))
|
StdTimeout::new(Duration::new(1, 0))
|
||||||
);
|
);
|
||||||
|
|
||||||
// Read entire ROM
|
let mut rom = vec![0xFF; rom_size];
|
||||||
let mut rom = vec![0; rom_size];
|
flash_read(&mut spi, &mut rom, sector_size)?;
|
||||||
eprintln!("SPI read");
|
|
||||||
spi.read_at(0, &mut rom)?;
|
|
||||||
|
|
||||||
eprintln!("Saving ROM to backup.rom");
|
eprintln!("Saving ROM to backup.rom");
|
||||||
fs::write("backup.rom", &rom).map_err(|_| Error::Verify)?;
|
fs::write("backup.rom", &rom).map_err(|_| Error::Verify)?;
|
||||||
@ -105,59 +125,68 @@ unsafe fn flash_inner(ec: &mut Ec<StdTimeout>, firmware: &Firmware, target: SpiT
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Erase entire chip, sector by sector
|
||||||
{
|
{
|
||||||
// Chip erase
|
|
||||||
// eprintln!("SPI chip erase");
|
|
||||||
// spi.erase_chip()?;
|
|
||||||
|
|
||||||
// Sector erase
|
|
||||||
let mut address = 0;
|
let mut address = 0;
|
||||||
while address < rom_size {
|
while address < rom_size {
|
||||||
|
eprint!("\rSPI Erase {}K", address / 1024);
|
||||||
|
let next_address = address + sector_size;
|
||||||
let mut erased = true;
|
let mut erased = true;
|
||||||
for &b in &rom[address..address + sector_size] {
|
for &b in &rom[address..next_address] {
|
||||||
if b != 0xFF {
|
if b != 0xFF {
|
||||||
erased =false;
|
erased =false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if ! erased {
|
||||||
|
spi.erase_sector(address as u32)?;
|
||||||
|
}
|
||||||
|
address = next_address;
|
||||||
|
}
|
||||||
|
eprintln!("\rSPI Erase {}K", address / 1024);
|
||||||
|
|
||||||
if erased {
|
// Verify chip erase
|
||||||
eprintln!("SPI sector already erased {:06X}", address);
|
flash_read(&mut spi, &mut rom, sector_size)?;
|
||||||
address += sector_size;
|
for i in 0..rom.len() {
|
||||||
} else {
|
if rom[i] != 0xFF {
|
||||||
eprintln!("SPI sector erase {:06X}", address);
|
eprintln!("Failed to erase: {:X} is {:X} instead of {:X}", i, rom[i], 0xFF);
|
||||||
address += spi.erase_sector(address as u32)?;
|
return Err(Error::Verify);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read entire ROM
|
|
||||||
eprintln!("SPI read");
|
|
||||||
spi.read_at(0, &mut rom)?;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify chip erase
|
// Write entire chip, sector by sector
|
||||||
for i in 0..rom.len() {
|
//TODO: write signature last
|
||||||
if rom[i] != 0xFF {
|
|
||||||
eprintln!("Failed to erase: {:X} is {:X} instead of {:X}", i, rom[i], 0xFF);
|
|
||||||
return Err(Error::Verify);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Program
|
|
||||||
{
|
{
|
||||||
eprintln!("SPI AAI word program");
|
let mut address = 0;
|
||||||
spi.write_at(0, &firmware.data)?;
|
while address < rom_size {
|
||||||
|
eprint!("\rSPI Write {}K", address / 1024);
|
||||||
|
let next_address = address + sector_size;
|
||||||
|
let mut erased = true;
|
||||||
|
for &b in &new_rom[address..next_address] {
|
||||||
|
if b != 0xFF {
|
||||||
|
erased =false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ! erased {
|
||||||
|
let count = spi.write_at(address as u32, &new_rom[address..next_address])?;
|
||||||
|
if count != sector_size {
|
||||||
|
eprintln!("\nWrite count {} did not match sector size {}", count, sector_size);
|
||||||
|
return Err(Error::Verify);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
address = next_address;
|
||||||
|
}
|
||||||
|
eprintln!("\rSPI Write {}K", address / 1024);
|
||||||
|
|
||||||
// Read entire ROM
|
// Verify chip write
|
||||||
eprintln!("SPI read");
|
flash_read(&mut spi, &mut rom, sector_size)?;
|
||||||
spi.read_at(0, &mut rom)?;
|
for i in 0..rom.len() {
|
||||||
}
|
if rom[i] != new_rom[i] {
|
||||||
|
eprintln!("Failed to program: {:X} is {:X} instead of {:X}", i, rom[i], new_rom[i]);
|
||||||
// Verify program
|
return Err(Error::Verify);
|
||||||
for i in 0..rom.len() {
|
}
|
||||||
if &rom[i] != firmware.data.get(i).unwrap_or(&0xFF) {
|
|
||||||
eprintln!("Failed to program: {:X} is {:X} instead of {:X}", i, rom[i], firmware.data[i]);
|
|
||||||
return Err(Error::Verify);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,7 +81,7 @@ impl<'a, S: Spi, T: Timeout> SpiRom<'a, S, T> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn erase_sector(&mut self, address: u32) -> Result<usize, Error> {
|
pub unsafe fn erase_sector(&mut self, address: u32) -> Result<(), Error> {
|
||||||
if (address & 0xFF00_0000) > 0 {
|
if (address & 0xFF00_0000) > 0 {
|
||||||
return Err(Error::Parameter);
|
return Err(Error::Parameter);
|
||||||
}
|
}
|
||||||
@ -90,7 +90,7 @@ impl<'a, S: Spi, T: Timeout> SpiRom<'a, S, T> {
|
|||||||
|
|
||||||
self.spi.reset()?;
|
self.spi.reset()?;
|
||||||
self.spi.write(&[
|
self.spi.write(&[
|
||||||
0xD7,
|
0x20,
|
||||||
(address >> 16) as u8,
|
(address >> 16) as u8,
|
||||||
(address >> 8) as u8,
|
(address >> 8) as u8,
|
||||||
address as u8,
|
address as u8,
|
||||||
@ -101,8 +101,7 @@ impl<'a, S: Spi, T: Timeout> SpiRom<'a, S, T> {
|
|||||||
|
|
||||||
self.write_disable()?;
|
self.write_disable()?;
|
||||||
|
|
||||||
//TODO: dynamically figure out this value
|
Ok(())
|
||||||
Ok(1024)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn read_at(&mut self, address: u32, data: &mut [u8]) -> Result<usize, Error> {
|
pub unsafe fn read_at(&mut self, address: u32, data: &mut [u8]) -> Result<usize, Error> {
|
||||||
|
Reference in New Issue
Block a user