Author: wmb Date: 2009-08-05 22:39:38 +0200 (Wed, 05 Aug 2009) New Revision: 1277
Modified: cpu/x86/pc/olpc/via/fsupdate.fth dev/mmc/sdhci/sdhci.fth dev/mmc/sdhci/sdmmc.fth Log: Via fs-update speedups from Luke Gorrie.
Modified: cpu/x86/pc/olpc/via/fsupdate.fth =================================================================== --- cpu/x86/pc/olpc/via/fsupdate.fth 2009-08-05 20:37:27 UTC (rev 1276) +++ cpu/x86/pc/olpc/via/fsupdate.fth 2009-08-05 20:39:38 UTC (rev 1277) @@ -103,7 +103,11 @@ get-inflater ;
-: zblocks-end: ( -- ) #image-eblocks erase-gap ; +: zblocks-end: ( -- ) +\ Asynchronous writes +\ " write-blocks-finish" $call-nand drop + #image-eblocks erase-gap +;
: data: ( "filename" -- ) safe-parse-word fn-buf place @@ -117,12 +121,20 @@ #image-eblocks show-writing ;
+\ We simultaneously DMA one data buffer onto NAND while unpacking the +\ next block of data into another. The buffers exchange roles after +\ each block. +load-base value dma-buffer +load-base /nand-block 4 * + value data-buffer + +: swap-buffers ( -- ) data-buffer dma-buffer to data-buffer to dma-buffer ; + : get-zdata ( comprlen -- ) secure-fsupdate? if - load-base /spec-maxline fileih read-line ( len end? error? ) + data-buffer /spec-maxline fileih read-line ( len end? error? ) " Spec line read error" ?nand-abort ( len end? ) 0= " Spec line too long" ?nand-abort ( len ) - load-base swap ( adr len ) + data-buffer swap ( adr len ) source $= 0= " Spec line mismatch" ?nand-abort ( )
fileih ( ih ) @@ -130,17 +142,31 @@ source-id ( ih ) then ( ih )
- >r load-base /nand-block + over r@ fgets ( comprlen #read r: ih ) + >r data-buffer /nand-block + over r@ fgets ( comprlen #read r: ih ) <> " Short read of zdata file" ?nand-abort ( r: ih )
r> fgetc newline <> ( error? ) " Missing newline after zdata" ?nand-abort ( )
\ The "2+" skips the Zlib header - load-base /nand-block + 2+ load-base true (inflate) ( len ) + data-buffer /nand-block + 2+ data-buffer true (inflate) ( len ) /nand-block <> " Wrong expanded data length" ?nand-abort ( ) ;
+false value check-hash? + +: check-hash ( -- ) + 2>r ( eblock# hashname$ r: hash$ ) + data-buffer /nand-block 2swap ( eblock# data$ hashname$ r: hash$ ) + hash ( eblock# calc-hash$ r: hash$ ) + 2r> $= 0= if ( eblock# ) + ." Bad hash for eblock# " .x cr cr + ." Your USB key may be bad. Please try a different one." cr + ." See http://wiki.laptop.org/go/Bad_hash" cr cr + abort + then ( eblock# ) +; + : zblock: ( "eblock#" "comprlen" "hashname" "hash-of-128KiB" -- ) get-hex# ( eblock# ) get-hex# >r ( eblock# r: comprlen ) @@ -150,26 +176,18 @@
r> get-zdata ( eblock# hashname$ hash$ )
- 2>r ( eblock# hashname$ r: hash$ ) - load-base /nand-block 2swap ( eblock# data$ hashname$ r: hash$ ) - hash ( eblock# calc-hash$ r: hash$ ) - - 2r> $= 0= if ( eblock# ) - ." Bad hash for eblock# " .x cr cr - ." Your USB key may be bad. Please try a different one." cr - ." See http://wiki.laptop.org/go/Bad_hash" cr cr - abort - then ( eblock# ) - - dup erase-gap ( eblock# ) + check-hash? if + check-hash ( eblock# ) + else + 2drop 2drop ( eblock# ) + then
- dup /nand-block um* " seek" $call-nand ( eblock# error ) - " Bad seek" ?nand-abort ( eblock# ) + ( eblock# ) +\ Asynchronous writes +\ data-buffer over nand-pages/block * nand-pages/block " write-blocks-start" $call-nand + data-buffer over nand-pages/block * nand-pages/block " write-blocks" $call-nand + swap-buffers
- load-base /nand-block " write" $call-nand ( eblock# #written ) - /nand-block <> ( eblock# error? ) - " Error writing to NAND FLASH" ?nand-abort ( eblock# ) - dup to last-eblock# ( eblock# ) show-written ( ) ;
Modified: dev/mmc/sdhci/sdhci.fth =================================================================== --- dev/mmc/sdhci/sdhci.fth 2009-08-05 20:37:27 UTC (rev 1276) +++ dev/mmc/sdhci/sdhci.fth 2009-08-05 20:39:38 UTC (rev 1277) @@ -798,7 +798,24 @@ : dma-alloc ( size -- vadr ) " dma-alloc" $call-parent ; : dma-free ( vadr size -- ) " dma-free" $call-parent ;
-: r/w-blocks ( addr block# #blocks in? -- actual ) +0 instance value dma? + +: wait-dma-done ( -- ) + dma? if + 2 wait + dma-release + intstat-off + false to dma? + then +; + +: r/w-blocks-finish ( -- actual ) + wait-dma-done + dma-len /block / +; + +: r/w-blocks-start ( addr block# #blocks in? -- ) + wait-dma-done over 0= if 2drop 2drop 0 exit then \ Prevents hangs intstat-on >r ( addr block# #blocks r: in? ) @@ -807,14 +824,14 @@ address-shift lshift r> if read-multiple else - write-multiple true to writing? + write-multiple true to writing? true to dma? then - 2 wait - dma-release - dma-len /block / - intstat-off ;
+: r/w-blocks ( addr block# #blocks in? -- actual ) + r/w-blocks-start r/w-blocks-finish +; + : r/w-ioblocks ( reg# function# inc? addr len blksz in? -- actual ) 2 pick 0= if 2drop 2drop 2drop drop 0 exit then \ Prevents hangs intstat-on @@ -844,6 +861,7 @@ ;
: close ( -- ) + wait-dma-done open-count 1 = if scratch-buf d# 64 " dma-free" $call-parent then
Modified: dev/mmc/sdhci/sdmmc.fth =================================================================== --- dev/mmc/sdhci/sdmmc.fth 2009-08-05 20:37:27 UTC (rev 1276) +++ dev/mmc/sdhci/sdmmc.fth 2009-08-05 20:39:38 UTC (rev 1277) @@ -31,6 +31,16 @@ false " r/w-blocks" $call-parent ;
+\ Asynchronous write. Completes on the next call to +\ write-blocks-start, write-blocks-finish, or close. +\ (Don't do other read/write operations in between.) +: write-blocks-start ( adr block# #blocks -- ) + false " r/w-blocks-start" $call-parent +; +: write-blocks-finish ( -- #written ) + false " r/w-blocks-finish" $call-parent +; + : dma-alloc ( size -- vadr ) " dma-alloc" $call-parent ; : dma-free ( vadr size -- ) " dma-free" $call-parent ;