Skip to content

Commit 8933899

Browse files
authored
Merge pull request #841 from betrusted-io/backup-regs
Backup register features & SPIM timeout fixes
2 parents 8ac6e17 + e46a65e commit 8933899

File tree

17 files changed

+280
-70
lines changed

17 files changed

+280
-70
lines changed

bao1x-boot/boot1/src/main.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -219,10 +219,10 @@ pub unsafe extern "C" fn rust_entry() -> ! {
219219
// needed after reset for the display to initialize
220220
if let Some(ref mut sh1107) = oled {
221221
// show the boot logo
222-
sh1107.init();
222+
sh1107.init().ok();
223223
delay(100);
224224
sh1107.blit_screen(&ux_api::bitmaps::baochip128x128::BITMAP);
225-
sh1107.draw();
225+
sh1107.draw().ok();
226226
delay(150);
227227
} else {
228228
delay(250);
@@ -450,5 +450,5 @@ pub fn marquee(sh1107: &mut Oled128x128, msg: &str) {
450450
bao1x_hal::sh1107::Mono::White.into(),
451451
bao1x_hal::sh1107::Mono::Black.into(),
452452
);
453-
sh1107.draw();
453+
sh1107.draw().ok();
454454
}

bao1x-boot/boot1/src/platform/bao1x/usb/handlers.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,7 @@ pub fn usb_ep1_bulk_out_complete(
364364
None,
365365
),
366366
false,
367+
((100_000_000 / 2) / 2_000_000) as u8,
367368
),
368369
&iox,
369370
)

libs/bao1x-api/src/lib.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ pub mod signatures;
1818
pub use offsets::*;
1919
pub mod clocks;
2020
pub mod pubkeys;
21-
use arbitrary_int::u31;
21+
use arbitrary_int::u30;
2222
use bitbybit::bitfield;
2323
pub use clocks::*;
2424
pub mod bio;
@@ -65,8 +65,13 @@ pub const AUTO_AUDIT_LIMIT: u32 = 3;
6565
#[bitfield(u32)]
6666
#[derive(PartialEq, Eq, Debug)]
6767
pub struct BackupFlags {
68-
#[bits(1..=31, rw)]
69-
reserved: u31,
68+
#[bits(2..=31, rw)]
69+
reserved: u30,
70+
/// When true, the system has previously booted. This is reserved for OS-level management. It is
71+
/// not automatically managed by the bootloader. However, after an AORST_N, the flag should be `false`
72+
/// by hardware design.
73+
#[bit(1, rw)]
74+
warm_boot: bool,
7075
/// When `false`, indicates that the time in the RTC register is not synchronized to the offset
7176
/// that is read from disk. Upon first encounter with an external time source, the offset should
7277
/// be captured and recorded to disk.

libs/bao1x-hal/src/buram.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use core::ops::Range;
22

33
const KEY_RANGE: Range<usize> = 2..8;
4-
const KEY_LEN: usize = range_len(KEY_RANGE) * size_of::<u32>();
4+
pub const KEY_LEN: usize = range_len(KEY_RANGE) * size_of::<u32>();
55
const HASH_LOC: usize = 0;
66
const FLAGS_LOC: usize = 1;
77

libs/bao1x-hal/src/sh1107.rs

Lines changed: 44 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,7 @@ pub struct Oled128x128<'a> {
183183
powerdown: bool,
184184
power_port: IoxPort,
185185
power_pin: u8,
186+
clk_div: u8,
186187
}
187188

188189
impl<'a> Oled128x128<'a> {
@@ -267,9 +268,19 @@ impl<'a> Oled128x128<'a> {
267268
power_port,
268269
power_pin,
269270
powerdown: false,
271+
clk_div: ((perclk_freq / 2) / 2_000_000) as u8,
270272
}
271273
}
272274

275+
// used to recover a wedged SPI interface
276+
pub fn reinit_spi(&mut self) {
277+
self.spim.send_cmd_list(&[crate::udma::SpimCmd::Config(
278+
SpimClkPol::LeadingEdgeRise,
279+
SpimClkPha::CaptureOnLeading,
280+
self.clk_div,
281+
)]);
282+
}
283+
273284
/// This should only be called to initialize the panic handler with its own
274285
/// copy of hardware registers.
275286
///
@@ -300,8 +311,9 @@ impl<'a> Oled128x128<'a> {
300311
Option<CommandSet>,
301312
),
302313
bool,
314+
u8,
303315
) {
304-
(self.spim.into_raw_parts(), self.powerdown)
316+
(self.spim.into_raw_parts(), self.powerdown, self.clk_div)
305317
}
306318

307319
/// Creates a clone of the display handle. This is only safe if the handles are used in a
@@ -331,6 +343,7 @@ impl<'a> Oled128x128<'a> {
331343
Option<CommandSet>,
332344
),
333345
bool,
346+
u8,
334347
),
335348
iox: &'a T,
336349
) -> Self
@@ -354,6 +367,7 @@ impl<'a> Oled128x128<'a> {
354367
command_set,
355368
),
356369
powerdown,
370+
clk_div,
357371
) = display_parts;
358372
// compile them into a new object
359373
let mut spim = unsafe {
@@ -398,6 +412,7 @@ impl<'a> Oled128x128<'a> {
398412
powerdown,
399413
power_pin,
400414
power_port,
415+
clk_div,
401416
}
402417
}
403418

@@ -407,7 +422,7 @@ impl<'a> Oled128x128<'a> {
407422

408423
pub fn screen_size(&self) -> Point { Point::new(WIDTH, LINES) }
409424

410-
pub fn redraw(&mut self) { self.draw(); }
425+
pub fn redraw(&mut self) -> Result<(), xous::Error> { self.draw() }
411426

412427
pub fn blit_screen(&mut self, bmp: &[u32]) { self.buffer.copy_from_slice(bmp); }
413428

@@ -417,21 +432,21 @@ impl<'a> Oled128x128<'a> {
417432

418433
pub fn stash(&mut self) { self.stash.copy_from_slice(&self.buffer); }
419434

420-
pub fn pop(&mut self) {
435+
pub fn pop(&mut self) -> Result<(), xous::Error> {
421436
self.buffer.copy_from_slice(&self.stash);
422-
self.redraw();
437+
self.redraw()
423438
}
424439

425440
fn set_data(&self) { self.iox.set_gpio_pin_value(self.cd_port, self.cd_pin, IoxValue::High); }
426441

427442
fn set_command(&self) { self.iox.set_gpio_pin_value(self.cd_port, self.cd_pin, IoxValue::Low); }
428443

429-
pub fn send_command<'b, U>(&'b mut self, cmd: U)
444+
pub fn send_command<'b, U>(&'b mut self, cmd: U) -> Result<(), xous::Error>
430445
where
431446
U: IntoIterator<Item = u8> + 'b,
432447
{
433448
if self.powerdown {
434-
return;
449+
return Ok(());
435450
}
436451
self.set_command();
437452
let total_buf_len = self.buffer.len() * size_of::<u32>();
@@ -451,16 +466,18 @@ impl<'a> Oled128x128<'a> {
451466
.txrx_data_async_from_parts::<u8>(total_buf_len, len, true, false)
452467
.expect("Couldn't initiate oled command");
453468
}
454-
self.spim.txrx_await(false).unwrap_or_else(|_e| {
455-
#[cfg(feature = "std")]
456-
log::error!("txrx err {:?}", _e);
457-
&[]
458-
});
469+
self.spim
470+
.txrx_await(false)
471+
.inspect_err(|_| {
472+
#[cfg(feature = "std")]
473+
log::error!("timeout in send_command");
474+
})
475+
.map(|_| ())
459476
}
460477

461-
pub fn init(&mut self) {
478+
pub fn init(&mut self) -> Result<(), xous::Error> {
462479
if self.powerdown {
463-
return;
480+
return Ok(());
464481
}
465482
use Command::*;
466483
let init_sequence = [
@@ -483,17 +500,18 @@ impl<'a> Oled128x128<'a> {
483500

484501
for command in init_sequence {
485502
let bytes = command.encode();
486-
self.send_command(bytes);
503+
self.send_command(bytes)?;
487504
}
488505
// clear the frame buffer
489506
self.buffer_mut().fill(0xFFFF_FFFF);
490-
self.draw();
507+
self.draw()?;
491508

492509
let display_on = [DisplayOnOff(DisplayState::On)];
493510
for command in display_on {
494511
let bytes = command.encode();
495-
self.send_command(bytes);
512+
self.send_command(bytes)?;
496513
}
514+
Ok(())
497515
}
498516

499517
pub fn powerdown(&mut self) {
@@ -516,9 +534,9 @@ impl<'a> Oled128x128<'a> {
516534
self.powerdown = false;
517535
}
518536

519-
pub fn brightness(&mut self, level: u8) {
537+
pub fn brightness(&mut self, level: u8) -> Result<(), xous::Error> {
520538
let bytes = Command::SetContrastControl(level).encode();
521-
self.send_command(bytes);
539+
self.send_command(bytes)
522540
}
523541

524542
#[cfg(feature = "std")]
@@ -574,10 +592,10 @@ impl<'a> Oled128x128<'a> {
574592

575593
impl<'a> FrameBuffer for Oled128x128<'a> {
576594
/// Copies the SRAM buffer to IFRAM and then transfers that over SPI
577-
fn draw(&mut self) {
595+
fn draw(&mut self) -> Result<(), xous::Error> {
578596
self.hw_buf.copy_from_slice(&self.buffer);
579597
if self.powerdown {
580-
return;
598+
return Ok(());
581599
}
582600
let chunk_size = 16;
583601
let chunks = self.buffer().len() * size_of::<u32>() / chunk_size;
@@ -588,8 +606,8 @@ impl<'a> FrameBuffer for Oled128x128<'a> {
588606
// the transaction is done before the data is done transmitting, and we have to
589607
// toggle set_data() only after the physical transaction is done, not after the
590608
// the last UDMA action has been queued.
591-
self.send_command(Command::SetPageAddress(0).encode());
592-
self.send_command(Command::SetColumnAddress(page as u8).encode());
609+
self.send_command(Command::SetPageAddress(0).encode())?;
610+
self.send_command(Command::SetColumnAddress(page as u8).encode())?;
593611
// wait for commands to finish before toggling set_data
594612
// self.spim.tx_data_await(false);
595613
// crate::println!("Send page {}, offset {:x}", page, page * chunk_size);
@@ -600,12 +618,12 @@ impl<'a> FrameBuffer for Oled128x128<'a> {
600618
.txrx_data_async_from_parts::<u8>(page * chunk_size, chunk_size, true, false)
601619
.expect("Couldn't initiate oled data transfer");
602620
}
603-
self.spim.txrx_await(false).unwrap_or_else(|_e| {
621+
self.spim.txrx_await(false).inspect_err(|_| {
604622
#[cfg(feature = "std")]
605-
log::error!("txrx err {:?}", _e);
606-
&[]
607-
});
623+
log::error!("timeout in draw");
624+
})?;
608625
}
626+
Ok(())
609627
}
610628

611629
fn clear(&mut self) { self.buffer_mut().fill(0xFFFF_FFFF); }

libs/bao1x-hal/src/udma/spim.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -476,7 +476,7 @@ impl Spim {
476476
&self.ifram.as_phys_slice()[..self.tx_buf_len_bytes / size_of::<T>()]
477477
}
478478

479-
fn send_cmd_list(&mut self, cmds: &[SpimCmd]) {
479+
pub fn send_cmd_list(&mut self, cmds: &[SpimCmd]) {
480480
for cmd_chunk in cmds.chunks(SPIM_CMD_BUF_LEN_BYTES / size_of::<u32>()) {
481481
for (src, dst) in cmd_chunk.iter().zip(self.cmd_buf_mut().iter_mut()) {
482482
*dst = (*src).into();

libs/keystore-api/src/gen2_api.rs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,15 @@ pub enum Opcode {
1515
AesOracle = 4,
1616
/// initiate key wrapper operation
1717
AesKwp = 5,
18-
/// Ephemeral secret operations
19-
EphemeralOp = 256,
18+
/// Ephemeral secret operations. Split into MSB/LSB pairs, because we want to strictly use
19+
/// scalar messages only for this. This helps to ensure to leakage of secrets to memory pages
20+
/// (there is some risk of stack spillage, but this at least reduces the attack surface).
21+
/// The ephemeral secret is 192 bits long - so the `Scalar` operation is split into 1x control
22+
/// word, and 3x 32 bit words that transmit the secret.
23+
Ephemeral = 256,
24+
/// Flag operations
25+
GetFlags = 512,
26+
SetFlags = 513,
2027

2128
// ----- below are non-cryptographic opcodes but used to manipulate sensitive state -----
2229
/// Set bootwait parameters
@@ -26,3 +33,11 @@ pub enum Opcode {
2633
/// Used to map unknown opcodes
2734
InvalidCall = 65535,
2835
}
36+
37+
#[derive(num_derive::FromPrimitive, num_derive::ToPrimitive, Debug)]
38+
pub enum EphemeralOp {
39+
GetLsb,
40+
SetLsb,
41+
GetMsb,
42+
SetMsb,
43+
}

libs/ux-api/src/minigfx/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ pub trait FrameBuffer {
4747
/// and background colors for a color theme.
4848
fn xor_pixel(&mut self, p: Point);
4949
/// Swaps the drawable buffer to the screen and sends it to the hardware
50-
fn draw(&mut self);
50+
fn draw(&mut self) -> Result<(), xous::Error>;
5151
/// Clears the drawable buffer
5252
fn clear(&mut self);
5353
/// Returns the size of the frame buffer as a Point
@@ -68,7 +68,7 @@ impl FrameBuffer for DynFb<'_> {
6868

6969
fn get_pixel(&self, p: Point) -> Option<ColorNative> { self.0.get_pixel(p) }
7070

71-
fn draw(&mut self) { self.0.draw(); }
71+
fn draw(&mut self) -> Result<(), xous::Error> { self.0.draw() }
7272

7373
fn clear(&mut self) { self.0.clear(); }
7474

loader/src/platform/bao1x/bao1x.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -168,10 +168,10 @@ pub fn early_init_hw() -> u32 {
168168
&mut iox,
169169
&mut udma_global,
170170
);
171-
sh1107.init();
171+
sh1107.init().ok();
172172
sh1107.buffer_mut().fill(0xFFFF_FFFF);
173173
sh1107.blit_screen(&ux_api::bitmaps::baochip128x128::BITMAP);
174-
sh1107.draw();
174+
sh1107.draw().ok();
175175
}
176176

177177
#[cfg(feature = "board-dabao")]
@@ -228,10 +228,10 @@ pub fn oled_init<'a>(
228228
iox,
229229
udma_global,
230230
);
231-
sh1107.init();
231+
sh1107.init().ok();
232232
sh1107.buffer_mut().fill(0xFFFF_FFFF);
233233
sh1107.blit_screen(&ux_api::bitmaps::baochip128x128::BITMAP);
234-
sh1107.draw();
234+
sh1107.draw().ok();
235235
sh1107
236236
}
237237

@@ -415,5 +415,5 @@ pub fn progress_bar(fb: &mut dyn FrameBuffer, progress: usize) {
415415
false,
416416
);
417417
}
418-
fb.0.draw();
418+
fb.0.draw().ok();
419419
}

0 commit comments

Comments
 (0)