@@ -178,7 +178,7 @@ pub unsafe extern "C" fn ProgramPage_impl(adr: u32, sz: u32, buf: *const u8) ->
178178}
179179
180180#[ no_mangle]
181- pub unsafe extern "C" fn ReadFlash_impl ( adr : u32 , sz : u32 , buf : * mut u8 ) -> i32 {
181+ pub unsafe extern "C" fn Verify_impl ( adr : u32 , sz : u32 , buf : * const u8 ) -> i32 {
182182 if !is_inited ( ) {
183183 return ERROR_BASE_INTERNAL - 1 ;
184184 } ;
@@ -188,26 +188,44 @@ pub unsafe extern "C" fn ReadFlash_impl(adr: u32, sz: u32, buf: *mut u8) -> i32
188188 return ERROR_BASE_INTERNAL - 5 ;
189189 }
190190
191- dprintln ! ( "READ FLASH {} bytes @ {}" , sz, adr) ;
191+ dprintln ! ( "PROGRAM {} bytes @ {}" , sz, adr) ;
192192
193- let buffer = core:: slice:: from_raw_parts_mut ( buf, sz as usize ) ;
194- crate :: flash:: read_flash ( adr, buffer)
193+ let input = core:: slice:: from_raw_parts ( buf, sz as usize ) ;
194+
195+ ( * DECOMPRESSOR ) . verify ( adr, input)
195196}
196197
197198#[ no_mangle]
198- pub unsafe extern "C" fn UnInit_impl ( _fnc : u32 ) -> i32 {
199+ pub unsafe extern "C" fn ReadFlash_impl ( adr : u32 , sz : u32 , buf : * mut u8 ) -> i32 {
199200 if !is_inited ( ) {
200201 return ERROR_BASE_INTERNAL - 1 ;
201202 } ;
202203
203- ( * DECOMPRESSOR ) . flush ( ) ;
204+ if ( buf as u32 ) % 4 != 0 {
205+ dprintln ! ( "ERROR buf not word aligned" ) ;
206+ return ERROR_BASE_INTERNAL - 5 ;
207+ }
208+
209+ dprintln ! ( "READ FLASH {} bytes @ {}" , sz, adr) ;
210+
211+ let buf = core:: slice:: from_raw_parts_mut ( buf, sz as usize ) ;
212+ crate :: flash:: read_flash ( adr, buf)
213+ }
204214
205- // The flash ROM functions don't wait for the end of the last operation.
206- let r = flash:: wait_for_idle ( ) ;
215+ #[ no_mangle]
216+ pub unsafe extern "C" fn UnInit_impl ( fnc : u32 ) -> i32 {
217+ if !is_inited ( ) {
218+ return ERROR_BASE_INTERNAL - 1 ;
219+ } ;
207220
208221 * INITED = 0 ;
209222
210- r
223+ if fnc == 2 {
224+ // The flash ROM functions don't wait for the end of the last operation.
225+ flash:: wait_for_idle ( )
226+ } else {
227+ 0
228+ }
211229}
212230
213231pub struct Decompressor {
@@ -239,7 +257,7 @@ impl Decompressor {
239257 self . output . take ( |_| { } ) ;
240258 }
241259
242- fn decompress ( & mut self , input : & [ u8 ] ) -> i32 {
260+ fn decompress ( & mut self , input : & [ u8 ] , process : fn ( u32 , & [ u8 ] ) -> i32 ) -> i32 {
243261 if self . remaining_compressed == 0 {
244262 return ERROR_BASE_INTERNAL - 3 ;
245263 }
@@ -262,7 +280,7 @@ impl Decompressor {
262280 if status == TINFL_STATUS_DONE as i32 || self . output . full ( ) {
263281 // We're either finished or the decompressor can't continue
264282 // until we flush the buffer.
265- let flush_status = self . flush ( ) ;
283+ let flush_status = self . flush ( process ) ;
266284
267285 if flush_status < 0 {
268286 return ERROR_BASE_FLASH + flush_status;
@@ -277,26 +295,29 @@ impl Decompressor {
277295 }
278296 }
279297
280- pub fn flush ( & mut self ) -> i32 {
298+ pub fn flush ( & mut self , process : fn ( address : u32 , data : & [ u8 ] ) -> i32 ) -> i32 {
281299 let mut offset = self . offset ;
282300 let address = self . image_start + offset;
283301
284302 // Take buffer contents, write to flash and update offset.
285303 let status = self . output . take ( |data| {
286304 offset += data. len ( ) as u32 ;
287- crate :: flash:: write_flash ( address, data)
305+
306+ process ( address, data)
288307 } ) ;
289308
290309 self . offset = offset;
291310
292311 status
293312 }
294313
295- pub fn program ( & mut self , address : u32 , mut data : & [ u8 ] ) -> i32 {
314+ fn handle_compressed (
315+ & mut self ,
316+ address : u32 ,
317+ mut data : & [ u8 ] ,
318+ process : fn ( u32 , & [ u8 ] ) -> i32 ,
319+ ) -> i32 {
296320 if self . image_start != address {
297- // Finish previous image
298- self . flush ( ) ;
299-
300321 if data. len ( ) < 4 {
301322 // We don't have enough bytes to read the length
302323 return ERROR_BASE_INTERNAL - 4 ;
@@ -315,6 +336,70 @@ impl Decompressor {
315336
316337 self . reinit ( address, compressed_length) ;
317338 }
318- self . decompress ( data)
339+ self . decompress ( data, process)
340+ }
341+
342+ pub fn program ( & mut self , address : u32 , data : & [ u8 ] ) -> i32 {
343+ self . handle_compressed ( address, data, write_to_flash)
344+ }
345+
346+ pub fn verify ( & mut self , address : u32 , data : & [ u8 ] ) -> i32 {
347+ // We're supposed to return the address up to which we've verified.
348+ // However, we process compressed data and the caller expects us to respond in terms of
349+ // compressed offsets, so we don't actually know where comparison fails.
350+ let status = if self . handle_compressed ( address, data, verify_flash) == 0 {
351+ address + data. len ( ) as u32
352+ } else {
353+ address
354+ } ;
355+
356+ status as i32
357+ }
358+ }
359+
360+ fn write_to_flash ( address : u32 , data : & [ u8 ] ) -> i32 {
361+ let status = crate :: flash:: write_flash ( address, data) ;
362+
363+ if status < 0 {
364+ return ERROR_BASE_FLASH + status;
365+ }
366+
367+ 0
368+ }
369+
370+ fn verify_flash ( mut address : u32 , mut data : & [ u8 ] ) -> i32 {
371+ const READBACK_BUFFER : usize = 256 ;
372+ let mut readback = unsafe {
373+ let mut buf = core:: mem:: MaybeUninit :: < [ u8 ; READBACK_BUFFER ] > :: uninit ( ) ;
374+ for i in 0 ..READBACK_BUFFER {
375+ buf. as_mut_ptr ( ) . cast :: < u8 > ( ) . write_volatile ( i as u8 ) ;
376+ }
377+ buf. assume_init ( )
378+ } ;
379+
380+ while !data. is_empty ( ) {
381+ let chunk_size = READBACK_BUFFER . min ( data. len ( ) ) ;
382+ let ( slice, rest) = unsafe {
383+ // SAFETY: skip is always at most `data.len()`
384+ data. split_at_unchecked ( chunk_size)
385+ } ;
386+ data = rest;
387+
388+ let readback_slice = & mut readback[ ..chunk_size] ;
389+
390+ let status = crate :: flash:: read_flash ( address, readback_slice) ;
391+ if status < 0 {
392+ return -1 ;
393+ }
394+
395+ for ( a, b) in slice. iter ( ) . zip ( readback_slice. iter ( ) ) {
396+ if a != b {
397+ return -1 ;
398+ }
399+ }
400+
401+ address += chunk_size as u32 ;
319402 }
403+
404+ 0
320405}
0 commit comments