Author: wmb
Date: 2007-05-04 11:00:05 +0200 (Fri, 04 May 2007)
New Revision: 355
Added:
cpu/x86/adpcm.fth
cpu/x86/k6cputest.fth
Modified:
cpu/x86/pc/olpc/devices.fth
cpu/x86/pc/olpc/disptest.fth
cpu/x86/pc/olpc/olpc.bth
dev/geode/ac97/ac97.fth
dev/geode/ac97/selftest.fth
dev/olpc/cafenand/methods.fth
dev/olpc/cafenand/selftest.fth
Log:
OLPC - Added a bunch of selftests from Lilian.
Added: cpu/x86/adpcm.fth
===================================================================
--- cpu/x86/adpcm.fth (rev 0)
+++ cpu/x86/adpcm.fth 2007-05-04 09:00:05 UTC (rev 355)
@@ -0,0 +1,223 @@
+\ See license at end of file
+purpose: decode IMA/DVI ADPCM .wav file
+
+\ Uncompressed data format:
+\ 16-bit Left, 16-bit Right, ...
+\
+\ Compressed data format:
+\ nibbles 0.hi 0.lo 1.hi 1.lo 2.hi 2.lo 3.hi 3.lo 4.hi 4.lo 5.hi 5.lo ...
+\ L1 L0 L3 L2 L5 L4 L7 L6 R1 R0 R3 R2 ...
+
+\ Work on one channel at a time.
+
+0 value val-pred \ predicted value
+0 value index \ current step change index
+0 value in-val \ place to keep (encoded) input value
+0 value in-skip \ # bytes to skip on channel input
+0 value out-skip \ # bytes to skip on channel output
+0 value buf-skip \ toggle flag for writing values
+
+0 value #ch \ # channels
+0 value blk-size \ # bytes per compressed block
+0 value #sample/blk \ (blk-size-(#ch*4)) + 1
+
+decimal
+create index-table -1 , -1 , -1 , -1 , 2 , 4 , 6 , 8 ,
+ -1 , -1 , -1 , -1 , 2 , 4 , 6 , 8 ,
+
+create stepsize-table \ 89 entries
+ 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 16 , 17 ,
+ 19 , 21 , 23 , 25 , 28 , 31 , 34 , 37 , 41 , 45 ,
+ 50 , 55 , 60 , 66 , 73 , 80 , 88 , 97 , 107 , 118 ,
+ 130 , 143 , 157 , 173 , 190 , 209 , 230 , 253 , 279 , 307 ,
+ 337 , 371 , 408 , 449 , 494 , 544 , 598 , 658 , 724 , 796 ,
+ 876 , 963 , 1060 , 1166 , 1282 , 1411 , 1552 , 1707 , 1878 , 2066 ,
+ 2272 , 2499 , 2749 , 3024 , 3327 , 3660 , 4026 , 4428 , 4871 , 5358 ,
+ 5894 , 6484 , 7132 , 7845 , 8630 , 9493 , 10442 , 11487 , 12635 , 13899 ,
+ 15289 , 16818 , 18500 , 20350 , 22385 , 24623 , 27086 , 29794 , 32767 ,
+hex
+
+0 value 'index-table
+0 value 'stepsize-table
+
+: init-ch-vars ( in out -- in' out' )
+ over <w@ dup to val-pred \ The first entry is the initial value
+ over w!
+ over 2 + c@ to index \ And the initial index
+ out-skip +
+ swap in-skip + swap
+;
+
+code adpcm-decode-sample ( in out sample# -- in' out' )
+ \ Get the delta value
+ eax pop ( in out )
+ 7 # eax and 0= if
+ 4 [esp] ecx mov \ Read the next 4 bytes
+ 0 [ecx] ebx mov
+ 'user in-skip ecx mov \ Increment in to the next data for the channel
+ ecx 4 [esp] add
+ else
+ 'user in-val ebx mov
+ ebx 4 # shr
+ then
+ ebx 'user in-val mov \ Save the input data
+ h# f # ebx and \ delta
+
+ \ Compute difference and new predicated value
+ \ Computes 'vpdiff = (delta+0.5)*step/4', but see comment in adpcm-coder.
+ 'user index eax mov \ index
+ 'user 'stepsize-table ecx mov \ address of stepsize-table
+ 0 [ecx] [eax] *4 ecx mov \ step = stepsize-table[index]
+
+ ecx eax mov eax 3 # shr \ vpdiff
+
+ 4 # bl test 0<> if ecx eax add then
+ 2 # bl test 0<> if ecx edx mov edx 1 # shr edx eax add then
+ 1 # bl test 0<> if ecx edx mov edx 2 # shr edx eax add then
+
+ \ Clamp down output value
+ 'user val-pred edx mov
+ 8 # ebx test 0= if
+ eax edx add
+ else
+ eax edx sub
+ then
+ d# 32767 # edx cmp > if d# 32767 # edx mov then
+ d# -32768 # edx cmp < if d# -32768 # edx mov then
+ edx 'user val-pred mov \ Update valpred
+ 0 [esp] eax mov \ out
+ op: dx 0 [eax] mov \ [out] = valpred
+ 'user out-skip eax mov
+ eax 0 [esp] add \ Advance out pointer
+
+ \ Update index value
+ 'user 'index-table eax mov \ address of index-table
+ 0 [eax] [ebx] *4 eax mov \ index-table[delta]
+
+ 'user index eax add \ index+index-table[delta]
+ 0 # eax cmp < if eax eax xor then
+ d# 88 # eax cmp > if d# 88 # eax mov then
+ eax 'user index mov \ Update index
+c;
+
+: adpcm-decode-ch ( in out #sample -- )
+ 0 ?do
+ i adpcm-decode-sample ( in' out' )
+ loop 2drop
+;
+
+: adpcm-decode-blk ( in out #sample -- )
+ #ch 0 ?do ( in out #sample )
+ 2 pick i /l * + ( in out #sample in' )
+ 2 pick i /w * + ( in out #sample in out' )
+ init-ch-vars ( in out #sample in' out' )
+ 2 pick 1- ( in out #sample in out #sample-1 )
+ adpcm-decode-ch ( in out #sample )
+ loop 3drop ( )
+;
+
+: adpcm-decoder ( in out #sample #ch blk-size -- )
+ index-table to 'index-table
+ stepsize-table to 'stepsize-table
+
+ dup to blk-size ( in out #sample #ch blk-size )
+ over 4 * - 1+ to #sample/blk ( in out #sample #ch )
+ dup to #ch ( in out #sample #ch )
+ dup /l * to in-skip ( in out #sample #ch )
+ /w * to out-skip ( in out #sample )
+
+ begin dup 0> while ( in out #sample )
+ 3dup #sample/blk min adpcm-decode-blk
+ rot blk-size + ( out #sample in' )
+ rot #sample/blk #ch * wa+ ( #sample in out' )
+ rot #sample/blk - ( in out #sample' )
+ repeat 3drop
+;
+
+\ Decode an .wav file
+\
+\ .wav file format:
+\ "RIFF" L<len of file> "WAVE"
+\ "fmt " L<len of fmt data> W<compression code> W<#channels> L<sample rate>
+\ L<bytes/second>] W<block align> W<bits/sample> W<extra bytes>
+\ W<#samples/block>]
+\ "fact" L<len of fact> L<#samples>
+\ "data" L<len of data> <blocks of data>
+\
+\ Each <block of data> contains:
+\ W<sample> B<index> B<0> per channel
+\ (block size - 1) samples of compressed data
+
+: find-wav-chunk? ( in chunk$ -- in' true | false )
+ rot dup 4 + le-l@ over + swap h# c + ( chunk$ in-end in' )
+ begin 2dup u> while ( chunk$ in-end in )
+ dup 4 pick 4 pick comp 0= if ( chunk$ in-end in )
+ nip nip nip true exit ( in true )
+ then
+ 4 + dup le-l@ + 4 + ( chunk$ in-end in' )
+ repeat 4drop
+ false
+;
+
+: wav-ok? ( in -- ok? )
+ dup " RIFF" comp swap 8 + " WAVE" comp or 0=
+;
+
+: fmt-ok? ( in -- #ch blk-size true | false )
+ " fmt " find-wav-chunk? 0= if false exit then ( in' )
+ dup 8 + le-w@ h# 11 = \ compression code: DVI_ADPCM
+ over h# 16 + le-w@ 4 = and if \ bits/sample
+ dup h# a + le-w@ ( #ch )
+ swap h# 14 + le-w@ true ( #ch blk-size true )
+ else
+ drop false ( false )
+ then
+;
+
+: fact-ok? ( in -- #sample true | false )
+ " fact" find-wav-chunk? dup if swap 8 + le-l@ swap then
+;
+
+: data-ok? ( in -- in' true | false )
+ " data" find-wav-chunk? dup if swap 8 + swap then
+;
+
+: adpcm-decode ( in out -- actual )
+ over wav-ok? not if 2drop 0 exit then ( in out )
+ swap dup data-ok? not if 2drop 0 exit then ( out in in' )
+ -rot dup fact-ok? not if 3drop 0 exit then ( in' out in #sample )
+ swap fmt-ok? not if 3drop 0 exit then ( in' out #sample #ch blk-size )
+ 2 pick 2 pick /w * * >r ( in' out #sample #ch blk-size ) ( R: actual )
+ adpcm-decoder r> ( actual )
+;
+
+: adpcm-size ( in -- actual )
+ dup wav-ok? not if drop 0 exit then ( in )
+ dup fact-ok? not if drop 0 exit then ( in #sample )
+ swap fmt-ok? not if drop 0 exit then ( #sample #ch blk-size )
+ drop /w * * ( actual )
+;
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 FirmWorks
+\
+\ Permission is hereby granted, free of charge, to any person obtaining
+\ a copy of this software and associated documentation files (the
+\ "Software"), to deal in the Software without restriction, including
+\ without limitation the rights to use, copy, modify, merge, publish,
+\ distribute, sublicense, and/or sell copies of the Software, and to
+\ permit persons to whom the Software is furnished to do so, subject to
+\ the following conditions:
+\
+\ The above copyright notice and this permission notice shall be
+\ included in all copies or substantial portions of the Software.
+\
+\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+\ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+\ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+\ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+\ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+\ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+\ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+\
+\ LICENSE_END
Property changes on: cpu/x86/adpcm.fth
___________________________________________________________________
Name: svn:executable
+ *
Added: cpu/x86/k6cputest.fth
===================================================================
--- cpu/x86/k6cputest.fth (rev 0)
+++ cpu/x86/k6cputest.fth 2007-05-04 09:00:05 UTC (rev 355)
@@ -0,0 +1,116 @@
+purpose: Burnin diagnostic for AMD K6 and similar CPUs
+\ See license at end of file
+
+hex
+
+also assembler definitions
+: finit ( -- ) 9b asm8, db asm8, e3 asm8, ;
+: fldpi ( -- ) d9 asm8, eb asm8, ;
+: fldl ( disp mr rmid -- ) dd asm8, 0 mem, ;
+: fmull ( disp mr rmid -- ) dc asm8, 1 mem, ;
+: faddp ( -- ) de asm8, c1 asm8, ;
+: fsubp ( -- ) de asm8, e1 asm8, ;
+: fcompp ( -- ) de asm8, d9 asm8, ;
+: fstswax ( -- ) 9b asm8, df asm8, e0 asm8, ;
+
+\ Returns an addressing mode that refers to the end of the datum
+: 'user+8 ( -- offset reg ) 'user swap 8 + swap ;
+
+previous definitions
+
+
+dev /cpu
+
+d# 60 constant default#passes
+d# 10,000,000 constant spins/pass
+0 value #cnt
+7fff.ffff value #half
+0000.0000 value #half2
+ffff.ffff 3fdf.ffff 2value #e
+ffff.ffff 3fef.ffff 2value #rt
+
+code burnK6 ( count -- error? )
+ ecx pop \ Loop count
+
+ finit
+ esi push
+
+ 'user #half edx mov \ DX: '#half
+ eax eax xor \ AX: 0
+ eax ebx mov \ BX: 0
+ -1 [eax] esi lea \ Index = -1
+ fldpi
+ nop nop
+
+ begin
+ 'user+8 #rt [esi] *8 fldl \ Account for -1 index
+ 'user+8 #e [esi] *8 fmull
+ 'user+8 #half [esi] *8 edx add
+ 75 c, 0 c, \ jnz .+2
+ faddp
+ 'user+8 #rt [esi] *8 fldl
+ ebx dec
+ 'user+8 #half [esi] *8 edx sub
+ eb c, 0 c, \ jmp .+2
+ 'user+8 #e [esi] *8 fmull
+ ebx inc
+ 'user+8 #cnt [esi] *8 dec
+ fsubp
+ loopa
+
+ esi pop
+
+ ebx ebx test 0<> if 1 # ebx mov then
+ 'user #half edx cmp <> if 2 # ebx or then
+ fldpi
+ fcompp \ compare ST(0) and ST(1) and pop them
+ fstswax
+ sahf 0<> if 4 # ebx or then
+
+ ebx push
+c;
+
+: selftest ( -- error? )
+ my-args dup if
+ push-decimal
+ $number abort" Argument to /cpu selftest must be a decimal number"
+ pop-base
+ else
+ 2drop
+ default#passes
+ then
+
+ dup .d ." passes of CPU Burnin. Press a key to abort." cr
+ 0 ?do
+ (cr ." Pass " i .d
+ spins/pass burnk6 if true exit then
+ key? if key drop cr leave then
+ loop
+ false
+;
+
+device-end
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 FirmWorks
+\
+\ Permission is hereby granted, free of charge, to any person obtaining
+\ a copy of this software and associated documentation files (the
+\ "Software"), to deal in the Software without restriction, including
+\ without limitation the rights to use, copy, modify, merge, publish,
+\ distribute, sublicense, and/or sell copies of the Software, and to
+\ permit persons to whom the Software is furnished to do so, subject to
+\ the following conditions:
+\
+\ The above copyright notice and this permission notice shall be
+\ included in all copies or substantial portions of the Software.
+\
+\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+\ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+\ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+\ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+\ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+\ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+\ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+\
+\ LICENSE_END
Property changes on: cpu/x86/k6cputest.fth
___________________________________________________________________
Name: svn:executable
+ *
Modified: cpu/x86/pc/olpc/devices.fth
===================================================================
--- cpu/x86/pc/olpc/devices.fth 2007-05-04 07:29:47 UTC (rev 354)
+++ cpu/x86/pc/olpc/devices.fth 2007-05-04 09:00:05 UTC (rev 355)
@@ -123,6 +123,7 @@
;
fload ${BP}/cpu/x86/pc/cpunode.fth
+fload ${BP}/cpu/x86/k6cputest.fth \ Burnin test for K6 CPU
0 [if]
fload ${BP}/ofw/console/bailout.fth
@@ -306,6 +307,8 @@
fload ${BP}/dev/geode/acpi.fth \ Power management
+fload ${BP}/cpu/x86/adpcm.fth \ ADPCM decoding
+
[ifdef] notdef-olpc
\ fload ${BP}/dev/olpc/plccflash.fth \ PLCC LPC debug FLASH
Modified: cpu/x86/pc/olpc/disptest.fth
===================================================================
--- cpu/x86/pc/olpc/disptest.fth 2007-05-04 07:29:47 UTC (rev 354)
+++ cpu/x86/pc/olpc/disptest.fth 2007-05-04 09:00:05 UTC (rev 355)
@@ -1,3 +1,6 @@
+purpose: Display test
+\ See license at end of file
+
dev /display
d# 100 constant bar-int
@@ -21,14 +24,80 @@
i test-color16 i 0 bar-int 4 pick " fill-rectangle" $call-screen
bar-int +loop drop
;
+
+instance variable rn \ Random number
+d# 60,000 constant burnin-time \ 1 minute
+
+: random ( -- n )
+ rn @ d# 1103515245 * d# 12345 + h# 7FFFFFFF and dup rn !
+;
+
+: randomize-color ( -- c )
+ random h# 1f and d# 11 <<
+ random h# 3f and d# 5 << or
+ random h# 1f and or
+;
+: randomize-xy ( -- x y )
+ dimensions ( width height )
+ random 3ff and min swap ( y width )
+ random 7ff and min swap ( x y )
+;
+: randomize-wh ( x y -- w h )
+ dimensions ( x y width height )
+ rot - -rot ( max-h x width )
+ swap - swap ( max-w max-h )
+ randomize-xy ( max-w max-h w h )
+ rot min -rot min swap ( w' h' )
+;
+: .random-rect ( -- )
+ randomize-color ( c )
+ randomize-xy ( c x y )
+ 2dup randomize-wh ( c x y w h )
+ " fill-rectangle" $call-screen ( )
+;
+
+: random-selftest ( -- error? )
+ get-msecs rn !
+ get-msecs burnin-time +
+ begin get-msecs over u< key? not and while
+ .random-rect
+ repeat
+;
+
: selftest ( -- error? )
bytes/pixel 2 <> if false exit then
.horizontal-bars16
d# 2000 ms
.vertical-bars16
d# 2000 ms
+ ." Press a key to abort." cr
+ d# 1000 ms
+ random-selftest
false
;
device-end
+\ LICENSE_BEGIN
+\ Copyright (c) 2007 FirmWorks
+\
+\ Permission is hereby granted, free of charge, to any person obtaining
+\ a copy of this software and associated documentation files (the
+\ "Software"), to deal in the Software without restriction, including
+\ without limitation the rights to use, copy, modify, merge, publish,
+\ distribute, sublicense, and/or sell copies of the Software, and to
+\ permit persons to whom the Software is furnished to do so, subject to
+\ the following conditions:
+\
+\ The above copyright notice and this permission notice shall be
+\ included in all copies or substantial portions of the Software.
+\
+\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+\ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+\ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+\ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+\ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+\ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+\ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+\
+\ LICENSE_END
Modified: cpu/x86/pc/olpc/olpc.bth
===================================================================
--- cpu/x86/pc/olpc/olpc.bth 2007-05-04 07:29:47 UTC (rev 354)
+++ cpu/x86/pc/olpc/olpc.bth 2007-05-04 09:00:05 UTC (rev 355)
@@ -72,7 +72,8 @@
" sourceurl" " sourceurl" $add-dropin
[ifndef] lx-devel
- " ${BP}/clients/memtest86/memtest" " memtest" $add-deflated-dropin
+ " ${BP}/clients/memtest86/memtest" " memtest" $add-deflated-dropin
+ " ${BP}/cpu/x86/pc/olpc/images/olpc-t0.wav" " splash" $add-deflated-dropin
[then]
[ifdef] lx-devel
" ${BP}/dev/pci/build/pcibridg.fc" " class060400" $add-deflated-dropin
Modified: dev/geode/ac97/ac97.fth
===================================================================
--- dev/geode/ac97/ac97.fth 2007-05-04 07:29:47 UTC (rev 354)
+++ dev/geode/ac97/ac97.fth 2007-05-04 09:00:05 UTC (rev 355)
@@ -295,8 +295,9 @@
prd-out-phys false out-channel start-dma ( len )
;
+: open-args ( -- arg$ ) my-args ascii : left-parse-string 2swap 2drop ;
: parse-args ( -- flag )
- my-args begin dup while \ Execute mode modifiers
+ open-args begin dup while \ Execute mode modifiers
ascii , left-parse-string ( rem$ first$ )
my-self ['] $call-method catch if ( rem$ x x x )
." Unknown argument" cr
Modified: dev/geode/ac97/selftest.fth
===================================================================
--- dev/geode/ac97/selftest.fth 2007-05-04 07:29:47 UTC (rev 354)
+++ dev/geode/ac97/selftest.fth 2007-05-04 09:00:05 UTC (rev 355)
@@ -35,7 +35,6 @@
negate 1+ 2* 3 / dup bwjoin to glevel
;
-
: play ( -- )
open-out plevel set-pcm-gain glevel h# 38 codec!
record-base record-len audio-out drop write-done
@@ -93,30 +92,70 @@
;
: make-wave ( -- )
- record-base record-len 2/ bounds ( endadr startadr )
- begin 2dup u> while cycle repeat ( endadr startadr )
- 2drop
+ record-base record-len 2/ bounds ( endadr startadr )
+ begin 2dup u> while cycle repeat ( endadr startadr )
+ 2drop
- record-base record-len bounds ( endadr startadr )
- record-len 2/ + wa1+
- begin 2dup u> while cycle repeat ( endadr startadr )
- 2drop
+ record-base record-len bounds ( endadr startadr )
+ record-len 2/ + wa1+
+ begin 2dup u> while cycle repeat ( endadr startadr )
+ 2drop
;
+
+0 value raw-buf
+0 value /raw-buf
+
+: selftest-args ( -- arg$ ) my-args ascii : left-parse-string 2drop ;
+
+: ?play-wav-file ( -- )
+ selftest-args dup 0= if drop exit then
+
+ \ Read the .wav file
+ 2dup ." Play " type cr
+ " boot-read" evaluate
+
+ \ Allocate raw audio buffer
+ " loaded" evaluate 0= if drop exit then \ No data loaded
+ " adpcm-size" evaluate ( /raw-buf )
+ ?dup 0= if exit then \ Not an IMA ADPCM .wav file
+ dup to /raw-buf alloc-mem to raw-buf ( )
+
+ \ Decode the .wav file
+ " load-base" evaluate ( in )
+ raw-buf " adpcm-decode" evaluate ( /raw-buf ) ( R: len wav-buf )
+ ?dup 0= if exit then \ Not an IMA ADPCM .wav file
+
+ \ Play the raw audio data
+ ." Press a key to abort" cr
+ open-out plevel set-pcm-gain glevel h# 38 codec!
+ begin
+ raw-buf /raw-buf audio-out drop
+ key? until write-done
+ key drop
+
+ \ Release the raw audio buffer
+ raw-buf /raw-buf free-mem 0 to raw-buf 0 to /raw-buf
+;
+
: selftest ( -- error? )
open 0= if ." Failed to open /audio" cr true exit then
+ 0 set-plevel 0 set-glevel
+ ?play-wav-file
record-len alloc-mem to record-base
." Play tone" cr
0 set-plevel d# -12 set-glevel
make-wave play
- ." Record and playback" cr
+ ." Recording ..." cr
0 set-plevel 0 set-glevel
- record play
+ record
+ ." Playing ..." cr
+ play
record-base record-len free-mem
close false
;
\ LICENSE_BEGIN
-\ Copyright (c) 2006 FirmWorks
+\ Copyright (c) 2007 FirmWorks
\
\ Permission is hereby granted, free of charge, to any person obtaining
\ a copy of this software and associated documentation files (the
Modified: dev/olpc/cafenand/methods.fth
===================================================================
--- dev/olpc/cafenand/methods.fth 2007-05-04 07:29:47 UTC (rev 354)
+++ dev/olpc/cafenand/methods.fth 2007-05-04 09:00:05 UTC (rev 355)
@@ -24,6 +24,8 @@
total-pages 0= \ Error if there are no chips
;
+: open-args ( -- arg$ ) my-args ascii : left-parse-string 2swap 2drop ;
+
external
: dma-alloc ( len -- adr ) " dma-alloc" $call-parent ;
@@ -62,7 +64,7 @@
get-bbt
- my-args dup if ( arg$ )
+ open-args dup if ( arg$ )
ascii , left-parse-string ( arg2$ arg1$ )
2dup " zip" $= if ( arg2$ arg1$ )
2drop ( arg2$ )
Modified: dev/olpc/cafenand/selftest.fth
===================================================================
--- dev/olpc/cafenand/selftest.fth 2007-05-04 07:29:47 UTC (rev 354)
+++ dev/olpc/cafenand/selftest.fth 2007-05-04 09:00:05 UTC (rev 355)
@@ -1,11 +1,18 @@
\ See license at end of file
purpose: Selftest for NAND FLASH section of the OLPC CaFe chip
-0 value test-block#
-0 value sbuf \ Original content of block
-0 value obuf \ Block data written
-0 value ibuf \ Block data read
-: test-page# ( -- n ) test-block# pages/eblock * ;
+instance variable rn \ Random number
+
+: random ( -- n )
+ rn @ d# 1103515245 * d# 12345 + h# 7FFFFFFF and dup rn !
+;
+
+false value selftest-err?
+: record-err ( error? -- ) if true to selftest-err? then ;
+
+0 value sbuf \ Original content of block
+0 value obuf \ Block data written
+0 value ibuf \ Block data read
: alloc-test-bufs ( -- )
sbuf 0= if
erase-size alloc-mem to sbuf
@@ -20,40 +27,164 @@
ibuf erase-size free-mem 0 to ibuf
then
;
-: determine-test-block# ( -- error? )
- -1 to test-block#
- size erase-size um/mod nip 1- ( block# )
- begin dup 0> test-block# -1 = and while
- dup pages/eblock * block-bad? not if dup to test-block# then
- 1- ( block#' )
- repeat drop
- test-block# -1 =
+: read-eblock ( adr page# -- error? )
+ pages/eblock read-blocks pages/eblock <>
;
-: read-eblock ( adr -- error? )
- test-page# pages/eblock read-blocks pages/eblock <>
+: write-eblock ( adr page# -- error? )
+ dup erase-block
+ pages/eblock write-blocks pages/eblock <>
;
-: write-eblock ( adr -- error? )
- test-page# erase-block
- test-page# pages/eblock write-blocks pages/eblock <>
-;
-: test-eblock ( pattern -- error? )
- obuf erase-size 2 pick fill obuf write-eblock if true exit then
- ibuf erase-size rot invert fill ibuf read-eblock if true exit then
+: test-eblock ( page# pattern -- error? )
+ obuf erase-size 2 pick fill
+ ibuf erase-size rot invert fill
+ obuf over write-eblock if true exit then
+ ibuf swap read-eblock if true exit then
ibuf obuf erase-size comp
;
-: write-test ( -- error? )
- determine-test-block# if true exit then
+
+\ Destroy content of flash. No argument.
+: erase ( subarg$ -- ) 2drop ." Erasing..." cr wipe ;
+
+\ Destroy content of flash. Argument is hex byte pattern value.
+: .skip-bad ( page# -- ) cr ." Skipping bad block" .page-byte cr ;
+: fill ( subarg$ -- )
+ $number if 0 else 0 max h# ff min then
+ ." Fill nandflash with h# " dup u. cr
+
+ usable-page-limit 0 ?do
+ i block-bad? if
+ i .skip-bad
+ else
+ (cr i . i over test-eblock record-err
+ then
+ pages/eblock +loop drop
+;
+
+\ Non-destructive. Argument is number of blocks to test.
+: random-page ( -- n ) random total-pages 1- and usable-page-limit min ;
+: fast ( subarg$ -- )
+ $number if d# 10 else 0 max usable-page-limit pages/eblock / min then
+ ." Fill " dup .d ." random blocks with h# 55, h# aa and h# ff" cr
+
+ 0 ?do
+ i 1 > if random-page else i 0<> if usable-page-limit 1- else 0 then then
+ pages/eblock 1- invert and
+
+ dup block-bad? not if
+ (cr dup .
+ sbuf over read-eblock dup record-err 0= if
+ dup h# 55 test-eblock record-err
+ dup h# aa test-eblock record-err
+ dup h# ff test-eblock record-err
+ then
+ sbuf swap write-eblock record-err
+ then
+ loop
+;
+
+\ Non-destructive. Argument is <#blk>,<blk#>
+\ <#blk>+1 is number of blocks as a test unit
+\ If <#blk> is absent, all blocks are tested.
+\ <blk#> is the block to test in the test unit, in range of 0..<#blk>
+\ If <blk#> is absent, 0 is assumed.
+\ For example: test /nandflash::full test all blocks
+\ test /nandflash::full,1,0 test even blocks
+\ test /nandflash::full,1,1 test odd blocks
+\ test /nandflash::full,2,<0-2> test 33%
+\ test /nandflash::full,3,<0-3> test 25%
+\ test /nandflash::full,4,<0-4> test 20%
+\ test /nandflash::full,9,<0-9> test 10%
+: parse-full-args ( subarg$ -- #blk blk# )
+ ?dup 0= if drop 0 0 exit then
+ ascii , left-parse-string ( blk#$ #blk$ )
+ $number if 2drop 0 0 exit then ( blk#$ #blk )
+ 0 max usable-page-limit pages/eblock 1- / min
+ -rot $number if 0 else 0 max over min then ( #blk blk# )
+;
+: .full-arg ( #blk blk# -- )
+ ." Test "
+ over 0= if 2drop ." every block" cr exit then
+ ." block " u. ." every " 1+ u. ." blocks" cr
+;
+: full ( subarg$ -- )
+ parse-full-args ( #blk blk# )
+ 2dup .full-arg ( #blk blk# )
+
+ pages/eblock * swap 1+ pages/eblock * ( page# #page )
+ usable-page-limit rot ?do ( #blk+1 )
+ i block-bad? not if
+ (cr i .
+ sbuf i read-eblock dup record-err 0= if
+ i h# 55 test-eblock record-err
+ i h# aa test-eblock record-err
+ then
+ sbuf i write-eblock record-err
+ then
+ dup +loop drop
+;
+
+: none ( subarg$ -- ) 2drop exit ;
+
+: help ( subarg$ -- )
+ 2drop
+ ." Usage:" cr
+ ." test /nandflash[::<arg>[;<arg>[;<arg>...]]]" cr
+ cr
+ ." If no <arg> is present, the fast test is performed." cr
+ cr
+ ." <arg> can be one of the following:" cr
+ ." none to do nothing" cr
+ ." help to get this usage guide" cr
+ ." erase to erase the flash (destructive)" cr
+ ." fill[,<data>] to fill the flash with hex byte pattern <data> (destructive)" cr
+ ." Default <data> is 00" cr
+ ." fast[,<#blk>] to non-destructively test the specified <#blk> of flash" cr
+ ." Default <#blk> is decimal 10" cr
+ ." full[,<#blk>[,<blk#>]" cr
+ ." to non-destructively test the specified <blk#> every" cr
+ ." <#blk>+1 number of blocks" cr
+ ." Default <#blk> and <blk#> are 0" cr
+ ." E.g., full,1,0 test even blocks" cr
+ ." full,1,1 test odd blocks" cr
+ ." full,2,0 test 33% of the flash" cr
+ cr
+;
+
+: parse-selftest-args ( arg$ -- )
+ begin ( arg$ )
+ ascii ; left-parse-string ?dup if ( rem$ arg$' )
+ ascii , left-parse-string ( rem$ subarg$ method$ )
+ my-self ['] $call-method catch if ( rem$ x x x x x )
+ ." Unknown argument" cr
+ 3drop 2drop 2drop
+ true to selftest-err?
+ exit
+ then ( rem$ )
+ else
+ drop ( rem$ )
+ then
+ ?dup 0= until drop ( )
+;
+: selftest-args ( -- arg$ ) my-args ascii : left-parse-string 2drop ;
+
+: (selftest) ( -- error? )
+ false to selftest-err?
alloc-test-bufs
- sbuf read-eblock if free-test-bufs true exit then
- h# 5a test-eblock if free-test-bufs true exit then
- h# a5 test-eblock if free-test-bufs true exit then
- sbuf write-eblock \ Restore original content
+ selftest-args ?dup if
+ parse-selftest-args
+ else
+ drop " " fast
+ then
free-test-bufs
+ selftest-err?
;
+
: selftest ( -- error? )
open 0= if true exit then
- show-bbt
- write-test
+ get-msecs rn !
+ read-id 1+ c@ h# dc <> if close true exit then
+ show-bbt cr
+ (selftest)
close
;