-
Notifications
You must be signed in to change notification settings - Fork 47
/
lib.rs
170 lines (150 loc) · 5.18 KB
/
lib.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
//! ## `humility spctrl`
//!
//! `humility spctrl` runs commands on the RoT to control the SP.
//!
//! You must run `humility spctrl init` before any other commands
//!
//! ```console
//! % humility spctrl init
//! [Ok([])]
//! ```
//!
//! You can read/write memory on the SP via the RoT
//! ```console
//! % humility spctrl -W read 0x08000000 64
//! humility: attached via CMSIS-DAP
//! \/ 4 8 c
//! 0x08000000 | 20000400 08000299 08003b6d 08004271 | ... ....m;..qB..
//! 0x08000010 | 08003c8d 08003ccd 08003cd3 00000000 | .<...<...<......
//! 0x08000020 | 00000000 00000000 00000000 0800398b | .............9..
//! 0x08000030 | 08003b6d 00000000 08003aa9 080039dd | m;.......:...9..
//!
//! % humility spctrl -W read 0x00000000 64
//! humility: attached via CMSIS-DAP
//! \/ 4 8 c
//! 0x00000000 | 3d0fbf49 991373d9 9107611c f6d84242 | I..=.s...a..BB..
//! 0x00000010 | 742397db c7c60242 decc7515 ce719848 | ..#tB....u..H.q.
//! 0x00000020 | b2d2639e faf8049b e202de8c 2ae12025 | .c..........% .*
//! 0x00000030 | f739ba6f 20067a60 310c4e08 e42eca28 | o.9.`z. .N.1(...
//!
//! % humility spctrl -W write 0x00000000 0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88
//! humility: attached via CMSIS-DAP
//! [Ok([])]
//!
//! % humility spctrl -W read 0x00000000 64
//! humility: attached via CMSIS-DAP
//! \/ 4 8 c
//! 0x00000000 | 44332211 88776655 9107611c f6d84242 | ."3DUfw..a..BB..
//! 0x00000010 | 742397db c7c60242 decc7515 ce719848 | ..#tB....u..H.q.
//! 0x00000020 | b2d2639e faf8049b e202de8c 2ae12025 | .c..........% .*
//! 0x00000030 | f739ba6f 20067a60 310c4e08 e42eca28 | o.9.`z. .N.1(...
//! ```
use humility::core::Core;
use humility::hubris::*;
use humility_cmd::hiffy::*;
use humility_cmd::{Archive, Args, Attach, Command, Dumper, Validate};
use std::str;
use anyhow::{bail, Result};
use clap::Command as ClapCommand;
use clap::{CommandFactory, Parser};
use hif::*;
#[derive(Parser, Debug)]
#[clap(name = "subcmd")]
enum SpCtrlCmd {
Write {
#[clap(value_parser=parse_int::parse::<u32>)]
addr: u32,
bytes: String,
},
Read {
#[clap(value_parser=parse_int::parse::<u32>)]
addr: u32,
nbytes: usize,
},
Init,
}
#[derive(Parser, Debug)]
#[clap(name = "spctrl", about = env!("CARGO_PKG_DESCRIPTION"))]
struct SpCtrlArgs {
/// sets timeout
#[clap(
long, short = 'T', default_value = "5000", value_name = "timeout_ms",
value_parser=parse_int::parse::<u32>,
)]
timeout: u32,
#[clap(subcommand)]
cmd: SpCtrlCmd,
/// print out data read as words rather than bytes
#[clap(long, short = 'W')]
word: bool,
}
fn spctrl(
hubris: &HubrisArchive,
core: &mut dyn Core,
_args: &Args,
subargs: &[String],
) -> Result<()> {
let subargs = SpCtrlArgs::try_parse_from(subargs)?;
let mut context = HiffyContext::new(hubris, core, subargs.timeout)?;
let funcs = context.functions()?;
let mut ops = vec![];
match subargs.cmd {
SpCtrlCmd::Write { addr, bytes } => {
let bytes: Vec<&str> = bytes.split(',').collect();
let mut arr = vec![];
for byte in &bytes {
if let Ok(val) = parse_int::parse::<u8>(byte) {
arr.push(val);
} else {
bail!("invalid byte {}", byte)
}
}
ops.push(Op::Push32(addr as u32));
ops.push(Op::Push32(arr.len() as u32));
let sp_write = funcs.get("WriteToSp", 2)?;
ops.push(Op::Call(sp_write.id));
ops.push(Op::Done);
let results = context.run(core, ops.as_slice(), Some(&arr))?;
println!("{:x?}", results);
}
SpCtrlCmd::Read { addr, nbytes } => {
ops.push(Op::Push32(addr as u32));
ops.push(Op::Push32(nbytes as u32));
let sp_read = funcs.get("ReadFromSp", 2)?;
ops.push(Op::Call(sp_read.id));
ops.push(Op::Done);
let results = context.run(core, ops.as_slice(), None)?;
if let Ok(results) = &results[0] {
let mut dumper = Dumper::new();
dumper.size = if subargs.word { 4 } else { 1 };
dumper.dump(results, addr);
return Ok(());
} else {
println!("{:x?}", results);
}
}
SpCtrlCmd::Init => {
let init = funcs.get("SpCtrlInit", 0)?;
ops.push(Op::Call(init.id));
ops.push(Op::Done);
let results = context.run(core, ops.as_slice(), None)?;
println!("{:?}", results);
}
}
Ok(())
}
pub fn init() -> (Command, ClapCommand<'static>) {
(
Command::Attached {
name: "spctrl",
archive: Archive::Required,
attach: Attach::LiveOnly,
validate: Validate::Booted,
run: spctrl,
},
SpCtrlArgs::command(),
)
}