[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