Add more subcommands to tool
This commit is contained in:
parent
d511a57bff
commit
8d0bab01f7
68
tool/src/legacy.rs
Normal file
68
tool/src/legacy.rs
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
use crate::{
|
||||||
|
Error,
|
||||||
|
Pmc,
|
||||||
|
SuperIo,
|
||||||
|
Timeout,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct EcLegacy<T: Timeout> {
|
||||||
|
pub pmc: Pmc<T>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Timeout> EcLegacy<T> {
|
||||||
|
/// Probes for a compatible EC
|
||||||
|
pub unsafe fn new(primary: bool, timeout: T) -> Result<Self, Error> {
|
||||||
|
let mut sio = SuperIo::new(if primary { 0x2E } else { 0x4E });
|
||||||
|
|
||||||
|
let id =
|
||||||
|
(sio.read(0x20) as u16) << 8 |
|
||||||
|
(sio.read(0x21) as u16);
|
||||||
|
|
||||||
|
match id {
|
||||||
|
0x5570 | 0x8587 => (),
|
||||||
|
_ => return Err(Error::SuperIoId(id)),
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: is there a good way to probe?
|
||||||
|
|
||||||
|
Ok(Self {
|
||||||
|
pmc: Pmc::new(if primary { 0x62 } else { 0x68 }, timeout),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn project(&mut self, data: &mut [u8]) -> Result<usize, Error> {
|
||||||
|
let mut i = 0;
|
||||||
|
self.pmc.command(0x92)?;
|
||||||
|
while i < data.len() {
|
||||||
|
data[i] = self.pmc.read()?;
|
||||||
|
if data[i] == b'$' {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
Ok(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn version(&mut self, data: &mut [u8]) -> Result<usize, Error> {
|
||||||
|
// Prepend `1.` to version string
|
||||||
|
let mut i = 0;
|
||||||
|
if i < data.len() {
|
||||||
|
data[i] = b'1';
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
if i < data.len() {
|
||||||
|
data[i] = b'.';
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.pmc.command(0x93)?;
|
||||||
|
while i < data.len() {
|
||||||
|
data[i] = self.pmc.read()?;
|
||||||
|
if data[i] == b'$' {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
Ok(i)
|
||||||
|
}
|
||||||
|
}
|
@ -9,6 +9,9 @@ mod error;
|
|||||||
pub use self::firmware::Firmware;
|
pub use self::firmware::Firmware;
|
||||||
mod firmware;
|
mod firmware;
|
||||||
|
|
||||||
|
pub use self::legacy::EcLegacy;
|
||||||
|
mod legacy;
|
||||||
|
|
||||||
pub use self::pmc::Pmc;
|
pub use self::pmc::Pmc;
|
||||||
mod pmc;
|
mod pmc;
|
||||||
|
|
||||||
|
150
tool/src/main.rs
150
tool/src/main.rs
@ -1,12 +1,17 @@
|
|||||||
use ectool::{
|
use ectool::{
|
||||||
Ec,
|
Ec,
|
||||||
Error,
|
Error,
|
||||||
|
Firmware,
|
||||||
Timeout,
|
Timeout,
|
||||||
};
|
};
|
||||||
use std::{
|
use std::{
|
||||||
|
env,
|
||||||
|
fs,
|
||||||
io,
|
io,
|
||||||
process,
|
process,
|
||||||
|
str,
|
||||||
time::{Duration, Instant},
|
time::{Duration, Instant},
|
||||||
|
thread,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct StdTimeout {
|
pub struct StdTimeout {
|
||||||
@ -33,7 +38,82 @@ impl Timeout for StdTimeout {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn tool() -> Result<(), Error> {
|
unsafe fn iopl() {
|
||||||
|
extern {
|
||||||
|
fn iopl(level: isize) -> isize;
|
||||||
|
}
|
||||||
|
|
||||||
|
if iopl(3) < 0 {
|
||||||
|
eprintln!("failed to get I/O permission: {}", io::Error::last_os_error());
|
||||||
|
process::exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe fn console() -> Result<(), Error> {
|
||||||
|
iopl();
|
||||||
|
|
||||||
|
let mut ec = Ec::new(
|
||||||
|
true,
|
||||||
|
StdTimeout::new(Duration::new(1, 0)),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let mut head = ec.debug(0) as usize;
|
||||||
|
loop {
|
||||||
|
let tail = ec.debug(0) as usize;
|
||||||
|
if tail == 0 || head == tail {
|
||||||
|
thread::sleep(Duration::from_millis(1));
|
||||||
|
} else {
|
||||||
|
while head != tail {
|
||||||
|
head += 1;
|
||||||
|
if head >= 256 { head = 1; }
|
||||||
|
let c = ec.debug(head as u8);
|
||||||
|
print!("{}", c as char);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe fn flash(path: &str) -> Result<(), Error> {
|
||||||
|
//TODO: remove unwraps
|
||||||
|
let firmware_data = fs::read(path).unwrap();
|
||||||
|
let firmware = Firmware::new(&firmware_data).unwrap();
|
||||||
|
println!("file board: {:?}", str::from_utf8(firmware.board));
|
||||||
|
println!("file version: {:?}", str::from_utf8(firmware.version));
|
||||||
|
|
||||||
|
iopl();
|
||||||
|
|
||||||
|
let mut ec = Ec::new(
|
||||||
|
true,
|
||||||
|
StdTimeout::new(Duration::new(1, 0)),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut data = [0; 256];
|
||||||
|
let size = ec.board(&mut data)?;
|
||||||
|
|
||||||
|
let ec_board = &data[..size];
|
||||||
|
println!("ec board: {:?}", str::from_utf8(ec_board));
|
||||||
|
|
||||||
|
if ec_board != firmware.board {
|
||||||
|
panic!("file board does not match ec board");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
print!("ec version: ");
|
||||||
|
let mut data = [0; 256];
|
||||||
|
let size = ec.version(&mut data)?;
|
||||||
|
|
||||||
|
let ec_version = &data[..size];
|
||||||
|
println!("ec version: {:?}", str::from_utf8(ec_version));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe fn info() -> Result<(), Error> {
|
||||||
|
iopl();
|
||||||
|
|
||||||
let mut ec = Ec::new(
|
let mut ec = Ec::new(
|
||||||
true,
|
true,
|
||||||
StdTimeout::new(Duration::new(1, 0)),
|
StdTimeout::new(Duration::new(1, 0)),
|
||||||
@ -62,21 +142,55 @@ unsafe fn tool() -> Result<(), Error> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn usage() {
|
||||||
extern {
|
eprintln!(" console");
|
||||||
fn iopl(level: isize) -> isize;
|
eprintln!(" flash [file]");
|
||||||
}
|
eprintln!(" info");
|
||||||
|
}
|
||||||
if unsafe { iopl(3) < 0 } {
|
|
||||||
eprintln!("failed to get I/O permission: {}", io::Error::last_os_error());
|
fn main() {
|
||||||
process::exit(1);
|
let mut args = env::args().skip(1);
|
||||||
}
|
|
||||||
|
match args.next() {
|
||||||
match unsafe { tool() } {
|
Some(arg) => match arg.as_str() {
|
||||||
Ok(()) => (),
|
"console" => match unsafe { console() } {
|
||||||
Err(err) => {
|
Ok(()) => (),
|
||||||
eprintln!("failed to run tool: {:X?}", err);
|
Err(err) => {
|
||||||
process::exit(1);
|
eprintln!("failed to read console: {:X?}", err);
|
||||||
}
|
process::exit(1);
|
||||||
}
|
},
|
||||||
|
},
|
||||||
|
"flash" => match args.next() {
|
||||||
|
Some(path) => match unsafe { flash(&path) } {
|
||||||
|
Ok(()) => (),
|
||||||
|
Err(err) => {
|
||||||
|
eprintln!("failed to flash '{}': {:X?}", path, err);
|
||||||
|
process::exit(1);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
None => {
|
||||||
|
eprintln!("no file provided");
|
||||||
|
process::exit(1);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"info" => match unsafe { info() } {
|
||||||
|
Ok(()) => (),
|
||||||
|
Err(err) => {
|
||||||
|
eprintln!("failed to read info: {:X?}", err);
|
||||||
|
process::exit(1);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
_ => {
|
||||||
|
eprintln!("unknown subcommand '{}'", arg);
|
||||||
|
usage();
|
||||||
|
process::exit(1);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
None => {
|
||||||
|
eprintln!("no subcommand provided");
|
||||||
|
usage();
|
||||||
|
process::exit(1);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user