@@ -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 {
273275pub ( 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 ) {
0 commit comments