[openfirmware] r1277 - cpu/x86/pc/olpc/via dev/mmc/sdhci
svn at openfirmware.info
svn at openfirmware.info
Wed Aug 5 22:39:39 CEST 2009
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 ;
More information about the openfirmware
mailing list