@@ -9,15 +9,16 @@ use drv_hf_api::{
99 HF_PERSISTENT_DATA_STRIDE ,
1010} ;
1111use idol_runtime:: {
12- LeaseBufReader , LeaseBufWriter , Leased , LenLimit , NotificationHandler ,
12+ ClientError , LeaseBufWriter , Leased , LenLimit , NotificationHandler ,
1313 RequestError , R , W ,
1414} ;
1515use ringbuf:: ringbuf_entry_root as ringbuf_entry;
1616use userlib:: { set_timer_relative, task_slot, RecvMessage , UnwrapLite } ;
1717use zerocopy:: { FromZeros , IntoBytes } ;
1818
1919use crate :: {
20- apob, FlashAddr , FlashDriver , Trace , PAGE_SIZE_BYTES , SECTOR_SIZE_BYTES ,
20+ apob, apob:: APOB_PERSISTENT_DATA_STRIDE , FlashAddr , FlashDriver , Trace ,
21+ PAGE_SIZE_BYTES , SECTOR_SIZE_BYTES ,
2122} ;
2223
2324task_slot ! ( HASH , hash_driver) ;
@@ -33,7 +34,36 @@ pub struct ServerImpl {
3334 hash : HashData ,
3435
3536 pub ( crate ) apob_state : apob:: ApobState ,
36- pub ( crate ) apob_buf : apob:: ApobBufs ,
37+ pub ( crate ) buf : HfBufs ,
38+ }
39+
40+ pub ( crate ) struct HfBufs {
41+ pub ( crate ) apob_persistent_data :
42+ & ' static mut [ u8 ; APOB_PERSISTENT_DATA_STRIDE ] ,
43+ pub ( crate ) page : & ' static mut [ u8 ; PAGE_SIZE_BYTES ] ,
44+ pub ( crate ) scratch : & ' static mut [ u8 ; PAGE_SIZE_BYTES ] ,
45+ }
46+
47+ /// Grabs references to the static buffers. Can only be called once.
48+ impl HfBufs {
49+ pub fn claim_statics ( ) -> Self {
50+ use static_cell:: ClaimOnceCell ;
51+ static BUFS : ClaimOnceCell < (
52+ [ u8 ; APOB_PERSISTENT_DATA_STRIDE ] ,
53+ [ u8 ; PAGE_SIZE_BYTES ] ,
54+ [ u8 ; PAGE_SIZE_BYTES ] ,
55+ ) > = ClaimOnceCell :: new ( (
56+ [ 0 ; APOB_PERSISTENT_DATA_STRIDE ] ,
57+ [ 0 ; PAGE_SIZE_BYTES ] ,
58+ [ 0 ; PAGE_SIZE_BYTES ] ,
59+ ) ) ;
60+ let ( apob_persistent_data, page, scratch) = BUFS . claim ( ) ;
61+ Self {
62+ apob_persistent_data,
63+ page,
64+ scratch,
65+ }
66+ }
3767}
3868
3969/// This tunes how many bytes we hash in a single async timer notification
@@ -49,15 +79,15 @@ impl ServerImpl {
4979 /// Persistent data is loaded from the flash chip and used to select `dev`;
5080 /// in addition, it is made redundant (written to both virtual devices).
5181 pub fn new ( mut drv : FlashDriver ) -> Self {
52- let mut apob_buf = apob :: ApobBufs :: claim_statics ( ) ;
53- let apob_state = apob:: ApobState :: init ( & mut drv, & mut apob_buf ) ;
82+ let mut buf = HfBufs :: claim_statics ( ) ;
83+ let apob_state = apob:: ApobState :: init ( & mut drv, & mut buf ) ;
5484
5585 let mut out = Self {
5686 dev : drv_hf_api:: HfDevSelect :: Flash0 ,
5787 drv,
5888 hash : HashData :: new ( HASH . get_task_id ( ) ) ,
5989 apob_state,
60- apob_buf ,
90+ buf ,
6191 } ;
6292 out. drv . set_flash_mux_state ( HfMuxState :: SP ) ;
6393 out. ensure_persistent_data_is_redundant ( ) ;
@@ -203,10 +233,7 @@ impl ServerImpl {
203233 addr
204234 }
205235 } ;
206- // flash_write is infallible when given a slice
207- self . drv
208- . flash_write ( addr, & mut raw_data. as_bytes ( ) )
209- . unwrap_lite ( ) ;
236+ self . drv . flash_write ( addr, raw_data. as_bytes ( ) ) ;
210237 }
211238
212239 /// Ensures that the persistent data is consistent between the virtual devs
@@ -421,12 +448,12 @@ impl idl::InOrderHostFlashImpl for ServerImpl {
421448 self . drv . check_flash_mux_state ( ) ?;
422449 let addr = self . flash_addr ( addr, data. len ( ) as u32 ) ?;
423450 self . invalidate_write ( ) ;
424- self . drv
425- . flash_write (
426- addr ,
427- & mut LeaseBufReader :: < _ , 32 > :: from ( data . into_inner ( ) ) ,
428- )
429- . map_err ( | ( ) | RequestError :: went_away ( ) )
451+ // Read the entire data block into our address space.
452+ data . read_range ( 0 ..data . len ( ) , & mut self . buf . scratch [ ..data . len ( ) ] )
453+ . map_err ( |_| RequestError :: Fail ( ClientError :: WentAway ) ) ? ;
454+
455+ self . drv . flash_write ( addr , & self . buf . scratch [ ..data . len ( ) ] ) ;
456+ Ok ( ( ) )
430457 }
431458
432459 fn page_program_dev (
@@ -527,7 +554,7 @@ impl idl::InOrderHostFlashImpl for ServerImpl {
527554 data : Leased < R , [ u8 ] > ,
528555 ) -> Result < ( ) , RequestError < drv_hf_api:: ApobWriteError > > {
529556 self . apob_state
530- . write ( & mut self . drv , & mut self . apob_buf , offset, data)
557+ . write ( & mut self . drv , & mut self . buf , offset, data)
531558 . map_err ( RequestError :: from)
532559 }
533560
@@ -536,7 +563,7 @@ impl idl::InOrderHostFlashImpl for ServerImpl {
536563 _: & RecvMessage ,
537564 ) -> Result < ( ) , RequestError < drv_hf_api:: ApobCommitError > > {
538565 self . apob_state
539- . commit ( & mut self . drv , & mut self . apob_buf )
566+ . commit ( & mut self . drv , & mut self . buf )
540567 . map_err ( RequestError :: from)
541568 }
542569
@@ -555,7 +582,7 @@ impl idl::InOrderHostFlashImpl for ServerImpl {
555582 data : Leased < W , [ u8 ] > ,
556583 ) -> Result < usize , RequestError < drv_hf_api:: ApobReadError > > {
557584 self . apob_state
558- . read ( & mut self . drv , & mut self . apob_buf , offset, data)
585+ . read ( & mut self . drv , & mut self . buf , offset, data)
559586 . map_err ( RequestError :: from)
560587 }
561588
@@ -589,7 +616,7 @@ impl idl::InOrderHostFlashImpl for ServerImpl {
589616 // This also unlocks the APOB so it can be written (once muxed back
590617 // to the SP).
591618 self . apob_state =
592- apob:: ApobState :: init ( & mut self . drv , & mut self . apob_buf ) ;
619+ apob:: ApobState :: init ( & mut self . drv , & mut self . buf ) ;
593620 }
594621 self . drv . set_flash_mux_state ( state) ;
595622 self . invalidate_mux_switch ( ) ;
0 commit comments