Author: wmb
Date: 2009-12-16 01:42:29 +0100 (Wed, 16 Dec 2009)
New Revision: 1618
Modified:
cpu/x86/pc/olpc/via/fsupdate.fth
dev/mmc/sdhci/sdhci.fth
dev/mmc/sdhci/sdmmc.fth
Log:
Fsupdate - check for output device too small for image and for zblocks line mismatch.
Modified: cpu/x86/pc/olpc/via/fsupdate.fth
===================================================================
--- cpu/x86/pc/olpc/via/fsupdate.fth 2009-12-15 23:32:49 UTC (rev 1617)
+++ cpu/x86/pc/olpc/via/fsupdate.fth 2009-12-16 00:42:29 UTC (rev 1618)
@@ -51,13 +51,26 @@
file ! ( )
;
+: ?compare-spec-line ( -- )
+ secure-fsupdate? if
+ data-buffer /spec-maxline filefd read-line ( len end? error? )
+ " Spec line read error" ?nand-abort ( len end? )
+ 0= " Spec line too long" ?nand-abort ( len )
+ data-buffer swap ( adr len )
+ source $= 0= " Spec line mismatch" ?nand-abort ( )
+ then
+;
+
vocabulary nand-commands
also nand-commands definitions
: zblocks: ( "eblock-size" "#eblocks" ... -- )
+ ?compare-spec-line
get-hex# to /nand-block
get-hex# to #image-eblocks
open-nand
+ " size" $call-nand #image-eblocks /nand-block um* d<
+ " Image size is larger than output device" ?nand-abort
#image-eblocks show-init
get-inflater
\ Separate the two buffers by enough space for both the compressed
@@ -71,8 +84,9 @@
: zblocks-end: ( -- )
\ Asynchronous writes
- " write-blocks-finish" $call-nand drop
- #image-eblocks erase-gap
+ " write-blocks-end" $call-nand ( error? )
+ " Write error" ?nand-abort
+\ #image-eblocks erase-gap
;
: data: ( "filename" -- )
@@ -83,11 +97,6 @@
true " " ?nand-abort
then to filefd
linefeed filefd force-line-delimiter
- \ Eat the initial "zblocks:" line
- load-base /spec-maxline filefd read-line ( len not-eof? error? )
- " Read error on .zd file" ?nand-abort ( len not-eof? )
- 0= " Premature EOF on .zd file" ?nand-abort ( len )
- drop ( )
true to secure-fsupdate?
;
@@ -97,17 +106,9 @@
;
: get-zdata ( comprlen -- )
- secure-fsupdate? if
- data-buffer /spec-maxline filefd read-line ( len end? error? )
- " Spec line read error" ?nand-abort ( len end? )
- 0= " Spec line too long" ?nand-abort ( len )
- data-buffer swap ( adr len )
- source $= 0= " Spec line mismatch" ?nand-abort ( )
+ ?compare-spec-line
- filefd ( ih )
- else ( )
- source-id ( ih )
- then ( ih )
+ secure-fsupdate? if filefd else source-id then ( ih )
>r data-buffer /nand-block + over r@ fgets ( comprlen #read r: ih )
<> " Short read of zdata file" ?nand-abort ( r: ih )
@@ -178,7 +179,8 @@
( eblock# )
\ Asynchronous writes
- data-buffer over nand-pages/block * nand-pages/block " write-blocks-start" $call-nand ( eblock# )
+ data-buffer over nand-pages/block * nand-pages/block " write-blocks-start" $call-nand ( eblock# error? )
+ " Write error" ?nand-abort ( eblock# )
\ data-buffer over nand-pages/block * nand-pages/block " write-blocks" $call-nand ( eblock# #written )
\ nand-pages/block <> " Write error" ?nand-abort ( eblock# )
swap-buffers ( eblock# )
Modified: dev/mmc/sdhci/sdhci.fth
===================================================================
--- dev/mmc/sdhci/sdhci.fth 2009-12-15 23:32:49 UTC (rev 1617)
+++ dev/mmc/sdhci/sdhci.fth 2009-12-16 00:42:29 UTC (rev 1618)
@@ -691,9 +691,29 @@
0 instance value writing?
+: .card-error ( value -- )
+ dup h# 8000.0000 and if ." Address out of range (past end?)" cr then
+ dup h# 4000.0000 and if ." Misaligned address" cr then
+ dup h# 2000.0000 and if ." Block length error" cr then
+ dup h# 1000.0000 and if ." Erase sequence error" cr then
+ dup h# 0800.0000 and if ." Invalid erase block error" cr then
+ dup h# 0400.0000 and if ." Write protect violation" cr then
+\ dup h# 0200.0000 and if ." Card is locked" cr then \ Status, not error
+ dup h# 0100.0000 and if ." Lock/Unlock failed" cr then
+ dup h# 0080.0000 and if ." Command CRC error" cr then
+ dup h# 0040.0000 and if ." Illegal command " cr then
+ dup h# 0020.0000 and if ." Card ECC failed" cr then
+ dup h# 0010.0000 and if ." Card controller error" cr then
+ dup h# 0008.0000 and if ." General error" cr then
+ dup h# 0001.0000 and if ." CIS/CSD overwrite" cr then
+ dup h# 0000.8000 and if ." Write-protected blocks skipped" cr then
+ dup h# 0000.0008 and if ." Authentication sequence error" cr then
+ drop
+;
+
\ This is the correct way to wait for programming complete.
-: wait-write-done ( -- )
- writing? 0= if exit then ( limit )
+: wait-write-done ( -- error? )
+ writing? 0= if false exit then ( limit )
get-msecs d# 1000 + ( limit )
begin get-status dup 9 rshift h# f and 7 = while ( limit status )
@@ -704,11 +724,13 @@
then
repeat ( limit status )
nip ( status )
- dup h# fff9.8008 and if ( status )
- cr ." SD Error - status = " . cr
- noop
+ dup h# fdf9.8008 and if ( status )
+ cr ." SD Error - status = " dup . cr
+ .card-error
+ true
else
drop
+ false
then
false to writing?
@@ -806,7 +828,7 @@
: detach-card ( -- )
wait-dma-done
- intstat-on wait-write-done intstat-off
+ intstat-on wait-write-done drop intstat-off
card-clock-off
card-power-off
\ unmap-regs
@@ -843,28 +865,34 @@
: detach-sdio-card ( -- )
;
+: r/w-blocks-end ( -- error? )
+ wait-dma-done
+ intstat-on wait-write-done intstat-off
+;
+
: r/w-blocks-finish ( -- actual )
wait-dma-done
dma-len /block /
;
-: r/w-blocks-start ( addr block# #blocks in? -- )
+: r/w-blocks-start ( addr block# #blocks in? -- error? )
wait-dma-done
- over 0= if 2drop 2drop 0 exit then \ Prevents hangs
+ over 0= if 2drop 2drop false exit then \ Prevents hangs
intstat-on
>r ( addr block# #blocks r: in? )
rot dma-setup ( block# r: in? )
- wait-write-done
+ wait-write-done if true exit then
address-shift lshift r> if
read-multiple
else
write-multiple true to writing?
then
true to dma?
+ false
;
: r/w-blocks ( addr block# #blocks in? -- actual )
- r/w-blocks-start r/w-blocks-finish
+ r/w-blocks-start if -1 exit then r/w-blocks-finish
;
: r/w-ioblocks ( reg# function# inc? addr len blksz in? -- actual )
@@ -874,7 +902,7 @@
2dup tuck 1- + swap / to io-#blocks ( reg# function# inc? addr len blksz r: in? )
4 pick write-blksz ( reg# function# inc? addr len r: in? )
iodma-setup ( reg# function# inc? r: in? )
- wait-write-done
+ wait-write-done if -1 exit then
r> if ( reg# function# inc? )
io-read-blocks
else
Modified: dev/mmc/sdhci/sdmmc.fth
===================================================================
--- dev/mmc/sdhci/sdmmc.fth 2009-12-15 23:32:49 UTC (rev 1617)
+++ dev/mmc/sdhci/sdmmc.fth 2009-12-16 00:42:29 UTC (rev 1618)
@@ -34,11 +34,11 @@
\ 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 -- )
+: write-blocks-start ( adr block# #blocks -- error? )
false " r/w-blocks-start" $call-parent
;
-: write-blocks-finish ( -- #written )
- false " r/w-blocks-finish" $call-parent
+: write-blocks-end ( -- error? )
+ false " r/w-blocks-end" $call-parent
;
: dma-alloc ( size -- vadr ) " dma-alloc" $call-parent ;