Skip to content

Commit 7d5c757

Browse files
committed
More review feedback
1 parent c86b772 commit 7d5c757

File tree

2 files changed

+55
-54
lines changed

2 files changed

+55
-54
lines changed

drv/cosmo-hf/src/apob.rs

Lines changed: 53 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -237,33 +237,35 @@ impl ApobSlot {
237237
}
238238
}
239239

240-
pub(crate) struct ApobBuf {
240+
pub(crate) struct ApobBufs {
241241
persistent_data: &'static mut [u8; APOB_PERSISTENT_DATA_STRIDE],
242242
page: &'static mut [u8; PAGE_SIZE_BYTES],
243243
scratch: &'static mut [u8; PAGE_SIZE_BYTES],
244244
}
245245

246246
/// Grabs references to the static buffers. Can only be called once.
247-
pub fn claim_statics() -> ApobBuf {
248-
use static_cell::ClaimOnceCell;
249-
static BUFS: ClaimOnceCell<(
250-
[u8; APOB_PERSISTENT_DATA_STRIDE],
251-
[u8; PAGE_SIZE_BYTES],
252-
[u8; PAGE_SIZE_BYTES],
253-
)> = ClaimOnceCell::new((
254-
[0; APOB_PERSISTENT_DATA_STRIDE],
255-
[0; PAGE_SIZE_BYTES],
256-
[0; PAGE_SIZE_BYTES],
257-
));
258-
let (persistent_data, page, scratch) = BUFS.claim();
259-
ApobBuf {
260-
persistent_data,
261-
page,
262-
scratch,
247+
impl ApobBufs {
248+
pub fn claim_statics() -> Self {
249+
use static_cell::ClaimOnceCell;
250+
static BUFS: ClaimOnceCell<(
251+
[u8; APOB_PERSISTENT_DATA_STRIDE],
252+
[u8; PAGE_SIZE_BYTES],
253+
[u8; PAGE_SIZE_BYTES],
254+
)> = ClaimOnceCell::new((
255+
[0; APOB_PERSISTENT_DATA_STRIDE],
256+
[0; PAGE_SIZE_BYTES],
257+
[0; PAGE_SIZE_BYTES],
258+
));
259+
let (persistent_data, page, scratch) = BUFS.claim();
260+
Self {
261+
persistent_data,
262+
page,
263+
scratch,
264+
}
263265
}
264266
}
265267

266-
/// State machine class, which implements the logic from RFD 593
268+
/// State machine data, which implements the logic from RFD 593
267269
///
268270
/// See rfd.shared.oxide.computer/rfd/593#_production_strength_implementation
269271
/// for details on the states and transitions. Note that the diagram in the RFD
@@ -273,11 +275,13 @@ pub fn claim_statics() -> ApobBuf {
273275
pub(crate) enum ApobState {
274276
/// Waiting for `ApobStart`
275277
Waiting {
276-
write_slot: ApobSlot,
278+
#[count(children)]
277279
read_slot: Option<ApobSlot>,
280+
write_slot: ApobSlot,
278281
},
279282
/// Receiving and writing data to host flash
280283
Ready {
284+
#[count(children)]
281285
write_slot: ApobSlot,
282286
expected_length: u32,
283287
expected_hash: ApobHash,
@@ -393,22 +397,35 @@ impl ApobState {
393397
///
394398
/// Searches for an active slot in the metadata regions, updating the offset
395399
/// in the FPGA driver if found, and erases unused or invalid slots.
396-
pub(crate) fn init(drv: &mut FlashDriver, buf: &mut ApobBuf) -> Self {
397-
if let Some(s) = Self::get_slot(drv, buf) {
400+
pub(crate) fn init(drv: &mut FlashDriver, buf: &mut ApobBufs) -> Self {
401+
// Look up persistent data, which specifies an active slot
402+
let out = if let Some(s) = Self::get_slot(drv) {
403+
// Erase the inactive slot, in preparation for writing
404+
Self::slot_erase(drv, buf, !s);
405+
406+
// Set the FPGA's offset so that the PSP reads valid data
398407
drv.set_apob_offset(s.base_addr());
408+
399409
ApobState::Waiting {
400410
read_slot: Some(s),
401411
write_slot: !s,
402412
}
403413
} else {
414+
// Erase both slots
415+
Self::slot_erase(drv, buf, ApobSlot::Slot0);
416+
Self::slot_erase(drv, buf, ApobSlot::Slot1);
417+
404418
// Pick a slot arbitrarily; it has just been erased and will fail
405419
// cryptographic checks in the PSP.
406420
drv.set_apob_offset(ApobSlot::Slot1.base_addr());
421+
407422
ApobState::Waiting {
408423
read_slot: None,
409424
write_slot: ApobSlot::Slot0,
410425
}
411-
}
426+
};
427+
ringbuf_entry!(Trace::State(out));
428+
out
412429
}
413430

414431
fn get_raw_persistent_data(
@@ -421,33 +438,17 @@ impl ApobState {
421438
a.max(b)
422439
}
423440

424-
/// Finds the currently active APOB slot, erasing any unused slots
425-
fn get_slot(drv: &mut FlashDriver, buf: &mut ApobBuf) -> Option<ApobSlot> {
426-
let best = Self::get_raw_persistent_data(drv);
427-
428-
// Erase inactive slot
429-
match best.map(|b| b.slot_select) {
430-
Some(0) => {
431-
Self::slot_erase(drv, buf, ApobSlot::Slot1);
432-
Some(ApobSlot::Slot0)
433-
}
434-
Some(1) => {
435-
Self::slot_erase(drv, buf, ApobSlot::Slot0);
436-
Some(ApobSlot::Slot1)
437-
}
438-
Some(_) => {
439-
unreachable!(); // prevented by is_valid check
440-
}
441-
None => {
442-
Self::slot_erase(drv, buf, ApobSlot::Slot0);
443-
Self::slot_erase(drv, buf, ApobSlot::Slot1);
444-
None
445-
}
446-
}
441+
fn get_slot(drv: &mut FlashDriver) -> Option<ApobSlot> {
442+
Self::get_raw_persistent_data(drv).map(|b| match b.slot_select {
443+
0 => ApobSlot::Slot0,
444+
1 => ApobSlot::Slot1,
445+
// prevented by is_valid check in slot_scan
446+
_ => unreachable!(),
447+
})
447448
}
448449

449450
/// Erases the given APOB slot
450-
fn slot_erase(drv: &mut FlashDriver, buf: &mut ApobBuf, slot: ApobSlot) {
451+
fn slot_erase(drv: &mut FlashDriver, buf: &mut ApobBufs, slot: ApobSlot) {
451452
static_assertions::const_assert!(
452453
APOB_SLOT_SIZE.is_multiple_of(SECTOR_SIZE_BYTES)
453454
);
@@ -462,7 +463,7 @@ impl ApobState {
462463
/// If `size > APOB_SLOT_SIZE`
463464
fn slot_erase_range(
464465
drv: &mut FlashDriver,
465-
buf: &mut ApobBuf,
466+
buf: &mut ApobBufs,
466467
slot: ApobSlot,
467468
size: u32,
468469
) {
@@ -577,7 +578,7 @@ impl ApobState {
577578
pub(crate) fn write(
578579
&mut self,
579580
drv: &mut FlashDriver,
580-
buf: &mut ApobBuf,
581+
buf: &mut ApobBufs,
581582
offset: u32,
582583
data: Leased<R, [u8]>,
583584
) -> Result<(), ApobWriteError> {
@@ -656,7 +657,7 @@ impl ApobState {
656657
pub(crate) fn read(
657658
&mut self,
658659
drv: &mut FlashDriver,
659-
buf: &mut ApobBuf,
660+
buf: &mut ApobBufs,
660661
offset: u32,
661662
data: Leased<W, [u8]>,
662663
) -> Result<usize, ApobReadError> {
@@ -715,7 +716,7 @@ impl ApobState {
715716
pub(crate) fn commit(
716717
&mut self,
717718
drv: &mut FlashDriver,
718-
buf: &mut ApobBuf,
719+
buf: &mut ApobBufs,
719720
) -> Result<(), ApobCommitError> {
720721
drv.check_flash_mux_state()
721722
.map_err(|_| ApobCommitError::InvalidState)?;
@@ -775,7 +776,7 @@ impl ApobState {
775776

776777
fn apob_validate(
777778
drv: &mut FlashDriver,
778-
buf: &mut ApobBuf,
779+
buf: &mut ApobBufs,
779780
expected_length: u32,
780781
expected_hash: ApobHash,
781782
write_slot: ApobSlot,
@@ -851,7 +852,7 @@ impl ApobState {
851852

852853
fn write_raw_persistent_data(
853854
drv: &mut FlashDriver,
854-
buf: &mut ApobBuf,
855+
buf: &mut ApobBufs,
855856
data: ApobRawPersistentData,
856857
meta: Meta,
857858
) {

drv/cosmo-hf/src/hf.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ pub struct ServerImpl {
3333
hash: HashData,
3434

3535
pub(crate) apob_state: apob::ApobState,
36-
pub(crate) apob_buf: apob::ApobBuf,
36+
pub(crate) apob_buf: apob::ApobBufs,
3737
}
3838

3939
/// This tunes how many bytes we hash in a single async timer notification
@@ -49,7 +49,7 @@ impl ServerImpl {
4949
/// Persistent data is loaded from the flash chip and used to select `dev`;
5050
/// in addition, it is made redundant (written to both virtual devices).
5151
pub fn new(mut drv: FlashDriver) -> Self {
52-
let mut apob_buf = apob::claim_statics();
52+
let mut apob_buf = apob::ApobBufs::claim_statics();
5353
let apob_state = apob::ApobState::init(&mut drv, &mut apob_buf);
5454

5555
let mut out = Self {

0 commit comments

Comments
 (0)