[openfirmware] [commit] r2435 - cpu/x86
repository service
svn at openfirmware.info
Tue Aug 9 20:17:05 CEST 2011
Author: lwalter
Date: Tue Aug 9 20:17:04 2011
New Revision: 2435
URL: http://tracker.coreboot.org/trac/openfirmware/changeset/2435
Log:
Add random test
Modified:
cpu/x86/memtest.fth
Modified: cpu/x86/memtest.fth
==============================================================================
--- cpu/x86/memtest.fth Tue Aug 9 06:29:27 2011 (r2434)
+++ cpu/x86/memtest.fth Tue Aug 9 20:17:04 2011 (r2435)
@@ -1,3 +1,17 @@
+purpose: Memory test primitives in assembly language
+\ See license at end of file
+
+headers
+\needs mask nuser mask mask on
+headerless
+
+\ Report the progress through low-level tests
+0 0 2value test-name
+: (quiet-show-status) ( adr len -- ) to test-name ;
+
+defer show-status
+' type to show-status
+
: bits-run ( adr len pattern -- fail? )
dup .x ." pattern ... "
3dup lfill ( adr len pattern )
@@ -13,6 +27,7 @@
then
;
: mem-bits-test ( membase memsize -- fail-status )
+ " Data bits test" show-status
2dup h# aaaaaaaa bits-run if true exit then
h# 55555555 bits-run
;
@@ -41,7 +56,7 @@
c;
: address=data-test ( membase memsize -- fail-status )
- ." Address=data test ..."
+ " Address=data test" show-status
2dup inc-fill ( membase memsize )
inc-check ( false | adr data true )
if
@@ -52,3 +67,220 @@
false
then
;
+
+\ random-fill uses registers where possible to minimize memory accesses.
+\ Stack use by random-fill: register usage:
+\ 0 /l* push esi
+\ 1 /l* pop polynomial; push edi ebx = polynomial
+ 2 /l* constant rf-idx \ edi = idx/4
+ 3 /l* constant rf-dta \ eax = data
+ 4 /l* constant rf-len \ esi = len/4, ecx = counter
+ 5 /l* constant rf-adr \ edx = adr
+
+code random-fill ( adr len data index polynomial -- )
+ ebx pop \ ebx: polynomial
+ edi push esi push \ Save esi and edi
+
+ rf-len [esp] ecx mov \ Convert to 32-bit word count
+ 2 # ecx shr \ ecx: remaining count
+
+ 0<> if
+ ecx esi mov \ esi: index upper limit
+ ecx dec
+
+ rf-dta [esp] eax mov \ eax: data
+ rf-idx [esp] edi mov \ edi: index
+ rf-adr [esp] edx mov \ edx: base address
+
+ begin
+ \ Compute new data value with an LFSR step
+ 1 # eax shr
+ carry? if h# 8020.0003 # eax xor then
+
+ \ Compute new address index, discarding values >= len
+ begin
+ 1 # edi shr
+ carry? if ebx edi xor then
+ esi edi cmp
+ u< until
+
+ \ Write the "random" value to the "random" address (adr[index])
+ eax 0 [edx] [edi] *4 mov
+ loopa
+
+ then
+ esi pop edi pop
+ 4 /l* # esp add \ Remove the remaining arguments on the stack
+c;
+
+\ random-check uses registers where possible to minimize memory accesses.
+\ Stack use by random-check: register usage:
+\ 0 /l* push esi
+\ 1 /l* pop polynomial; push edi ebx = polynomial
+ 2 /l* constant rc-rem \ ecx = remain (counter)
+ 3 /l* constant rc-idx \ edi = idx/4
+ 4 /l* constant rc-dta \ eax = data
+ 5 /l* constant rc-len \ esi = len/4
+ 6 /l* constant rc-adr \ edx = adr
+
+code random-check ( adr len data index remain polynomial -- false | adr len data index remain true )
+ 1 /l* [esp] ecx mov \ ecx: remain
+ ecx ecx or \ Check remain
+ 0= if
+ \ No more memory to check
+ 6 /l* # esp add \ Remove the arguments on the stack
+ 0 # push \ Return false
+ next
+ then
+
+ \ Check memory
+ ebx pop \ ebx: polynomial
+ edi push esi push \ Save esi and edi
+
+ rc-len [esp] esi mov \ esi: index upper limit
+ 2 # esi shr \ Convert to 32-bit word count
+ rc-dta [esp] eax mov \ eax: data
+ rc-idx [esp] edi mov \ edi: index
+ rc-adr [esp] edx mov \ edx: base address
+
+ begin
+ \ Compute new data value with an LFSR step
+ 1 # eax shr
+ carry? if h# 8020.0003 # eax xor then
+
+ \ Compute new address index, discarding values >= len
+ begin
+ 1 # edi shr
+ carry? if ebx edi xor then
+ esi edi cmp
+ u< until
+
+ \ Compare the "random" value to the "random" address (adr[index])
+ \ with the calculated data value
+ eax 0 [edx] [edi] *4 cmp
+ <> if
+ eax rc-dta [esp] mov \ Calculated data value
+ edi rc-idx [esp] mov \ Index where failure occurred
+ ecx dec
+ ecx rc-rem [esp] mov \ Update remain
+ esi pop edi pop
+ -1 # push \ Return true
+ next
+ then
+ loopa
+
+ esi pop edi pop
+ 5 /l* # esp add \ Remove the remaining arguments on the stack
+ 0 # push \ Return false
+c;
+
+\ Polynomials for maximal length LFSRs for different bit lengths
+\ The values come from the Wikipedia article for Linear Feedback Shift Register and from
+\ http://www.xilinx.com/support/documentation/application_notes/xapp052.pdf
+create polynomials \ #bits period
+h# 0 , \ 0 0
+h# 1 , \ 1 1
+h# 3 , \ 2 3
+h# 6 , \ 3 7
+h# c , \ 4 f
+h# 14 , \ 5 1f
+h# 30 , \ 6 3f
+h# 60 , \ 7 7f
+h# b8 , \ 8 ff
+h# 110 , \ 9 1ff
+h# 240 , \ 10 3ff
+h# 500 , \ 11 7ff
+h# e08 , \ 12 fff
+h# 1c80 , \ 13 1fff
+h# 3802 , \ 14 3fff
+h# 6000 , \ 15 7fff
+h# b400 , \ 16 ffff
+h# 12000 , \ 17 1ffff
+h# 20400 , \ 18 3ffff
+h# 72000 , \ 19 7ffff
+h# 90000 , \ 20 fffff
+h# 140000 , \ 21 1fffff
+h# 300000 , \ 22 3fffff
+h# 420000 , \ 23 7fffff
+h# e10000 , \ 24 ffffff
+h# 1200000 , \ 25 1ffffff
+h# 2000023 , \ 26 3ffffff
+h# 4000013 , \ 27 7ffffff
+h# 9000000 , \ 28 fffffff
+h# 14000000 , \ 29 1fffffff
+h# 20000029 , \ 30 3fffffff
+h# 48000000 , \ 31 7fffffff
+h# 80200003 , \ 32 ffffffff
+
+: round-up-log2 ( n -- log2 )
+ dup log2 ( n log2 )
+ tuck 1 swap lshift ( log2 n 2^log2 )
+ > - ( log2' )
+;
+
+defer .lfsr-mem-error
+: (.lfsr-mem-error) ( adr len data index remain -- adr len data index remain )
+ push-hex
+ ??cr
+ ." Error at address " 4 pick 2 pick la+ dup 8 u.r ( adr len data index remain err-adr )
+ ." - expected " 3 pick 8 u.r ( adr len data index remain err-adr )
+ ." got " l@ 8 u.r cr
+ pop-base
+;
+' (.lfsr-mem-error) to .lfsr-mem-error
+: throw-lfsr-error ( adr len data index remain -- <thrown> )
+ (.lfsr-mem-error) -1 throw
+;
+
+: (random-test) ( adr len -- )
+ dup /l <= if 2drop exit then ( adr len #bits )
+ dup /l / round-up-log2 ( adr len #bits )
+ polynomials swap la+ l@ ( adr len polynomial )
+
+ 3dup 1 1 rot random-fill ( adr len polynomial )
+
+ >r ( adr len r: polynomial )
+ 1 1 2 pick /l / 1- ( adr len data index remain r: polynomial )
+ begin ( adr len data index remain r: polynomial )
+ r@ random-check ( false | adr len data index remain true r: polynomial )
+ while ( adr len data index remain r: polynomial )
+ .lfsr-mem-error ( adr len data index remain r: polynomial )
+ repeat ( r: polynomial )
+ r> drop
+;
+
+\ Not truly random - uses LFSR sequences
+: random-test ( adr len -- error? )
+ " Random address and data test" show-status
+
+ ['] throw-lfsr-error to .lfsr-mem-error
+ ['] (random-test) catch if
+ 2drop true
+ else
+ false
+ then
+;
+
+\ LICENSE_BEGIN
+\ Copyright (c) 1997 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
\ No newline at end of file
More information about the openfirmware
mailing list