[openfirmware] [commit] r2245 - cpu/arm cpu/arm/mmp2 cpu/arm/olpc cpu/arm/olpc/1.75 ofw/fcode

repository service svn at openfirmware.info
Sat Jun 4 22:25:49 CEST 2011


Author: wmb
Date: Sat Jun  4 22:25:49 2011
New Revision: 2245
URL: http://tracker.coreboot.org/trac/openfirmware/changeset/2245

Log:
OLPC XO-1.75 trac #10883 - Integrated memory test suite into XO-1.75 build and added a random address and data memory test based on a linear feedback shift register sequence generator.  To use, "test /memory", or "memtest" for a multi-pass test.

Modified:
   cpu/arm/memtest.fth
   cpu/arm/mmp2/mmuon.fth
   cpu/arm/olpc/1.75/addrs.fth
   cpu/arm/olpc/1.75/devices.fth
   cpu/arm/olpc/1.75/probemem.fth
   cpu/arm/olpc/initmmu.fth
   cpu/arm/scc.fth
   ofw/fcode/memtest.fth

Modified: cpu/arm/memtest.fth
==============================================================================
--- cpu/arm/memtest.fth	Sat Jun  4 08:48:27 2011	(r2244)
+++ cpu/arm/memtest.fth	Sat Jun  4 22:25:49 2011	(r2245)
@@ -7,7 +7,10 @@
 
 \ Report the progress through low-level tests
 0 0 2value test-name
-: show-status  ( adr len -- )  to test-name  ;
+: (quiet-show-status)  ( adr len -- )  to test-name  ;
+
+defer show-status
+' type to show-status
 
 code lfill  ( adr len l -- )
 				\ tos: pattern
@@ -86,6 +89,160 @@
 
    2dup afill  mask @ masked-atest
 ;
+code random-fill  ( adr len data index polynomial -- )
+   ldmia sp!,{r1,r2,r3,r4}  \ tos:poly r1:index r2:data r3:len r4:adr
+
+   movs  r3,r3,lsr #2    \ Convert to longword count
+   nxteq
+
+   sub   r0,r3,#1         \ r0:remaining count
+   
+   \ r3:address-lfsr r4:data-lfsr r5:data-poly
+   set r5,#0x80200003  \ 32-bit polynomial
+
+   begin
+      \ Compute new data value with an LFSR step
+      movs  r2,r2,lsr #1
+      eorcs r2,r2,r5
+
+      \ Compute new address index, discarding values >= len
+      begin
+	 movs  r1,r1,lsr #1
+	 eorcs r1,r1,tos
+         cmp   r1,r3
+      u< until
+
+      \ Write the "random" value to the "random" address (adr[index])
+      str  r2,[r4,r1,lsl #2]
+
+      decs  r0,#1
+   0= until   
+
+   pop tos,sp
+c;
+code random-check  ( adr len data index remain polynomial -- false | adr len data index remain true )
+   ldmia sp!,{r0,r1,r2,r3,r4}  \ tos:poly r0:remain  r1:index r2:data r3:len r4:adr
+
+   cmp     r0,#0
+   moveq   tos,#0  \ Return false
+   nxteq
+
+   mov   r7,r3,lsr #2    \ Convert to longword count
+
+   set r5,#0x80200003  \ 32-bit polynomial
+
+   begin
+      \ Compute new data value with an LFSR step
+      movs  r2,r2,lsr #1
+      eorcs r2,r2,r5
+
+      \ Compute new address index, discarding values >= len
+      begin
+	 movs  r1,r1,lsr #1
+	 eorcs r1,r1,tos
+         cmp   r1,r7
+      u< until
+
+      \ Read the value at the "random" address (adr[index])
+      ldr  r6,[r4,r1,lsl #2]
+
+      \ Compare it to the calculated value
+      cmp  r6,r2
+
+      decne   r0,#1
+      stmnedb sp!,{r0,r1,r2,r3,r4}  \ Push results
+      mvnne   tos,#0    \ True on top of stack
+      nxtne
+
+      decs  r0,#1
+   0= until   
+
+   mov tos,#0
+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
+   ." 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

Modified: cpu/arm/mmp2/mmuon.fth
==============================================================================
--- cpu/arm/mmp2/mmuon.fth	Sat Jun  4 08:48:27 2011	(r2244)
+++ cpu/arm/mmp2/mmuon.fth	Sat Jun  4 22:25:49 2011	(r2245)
@@ -25,7 +25,7 @@
 : ofw-sections  ( -- )
    h# 0000.0000  h# c0e  over  dma-base     map-sections  \ Cache and write bufferable
    dma-base      h# c02  over  dma-size     map-sections  \ Non-cacheable DMA space
-   extra-mem-base h# c0e over  extra-mem-size map-sections  \ Cache and write bufferable
+   extra-mem-pa  h# c0e  over  /extra-mem   map-sections  \ Cache and write bufferable
    fw-pa         h# c0e  over  /fw-ram      map-sections  \ Cache and write bufferable
    fb-pa         h# c06  over  fb-size      map-sections  \ Write bufferable
 \  h# d100.0000  h# c0e  over  h# 0030.0000 map-sections  \ Cache and write bufferable (SRAM)

Modified: cpu/arm/olpc/1.75/addrs.fth
==============================================================================
--- cpu/arm/olpc/1.75/addrs.fth	Sat Jun  4 08:48:27 2011	(r2244)
+++ cpu/arm/olpc/1.75/addrs.fth	Sat Jun  4 22:25:49 2011	(r2245)
@@ -29,8 +29,8 @@
 h# 1f00.0000 constant dma-base
 h#   80.0000 constant dma-size
 
-h# 1f80.0000 constant extra-mem-base
-h#   20.0000 constant extra-mem-size
+h# 1f80.0000 constant extra-mem-pa
+h#   20.0000 constant /extra-mem
 
 [ifdef] virtual-mode
 h# f700.0000 constant fw-virt-base

Modified: cpu/arm/olpc/1.75/devices.fth
==============================================================================
--- cpu/arm/olpc/1.75/devices.fth	Sat Jun  4 08:48:27 2011	(r2244)
+++ cpu/arm/olpc/1.75/devices.fth	Sat Jun  4 22:25:49 2011	(r2245)
@@ -373,7 +373,7 @@
 warning !
 
 stand-init: More memory
-   extra-mem-base extra-mem-size add-memory
+   extra-mem-pa /extra-mem add-memory
 ;
 
 \ LICENSE_BEGIN

Modified: cpu/arm/olpc/1.75/probemem.fth
==============================================================================
--- cpu/arm/olpc/1.75/probemem.fth	Sat Jun  4 08:48:27 2011	(r2244)
+++ cpu/arm/olpc/1.75/probemem.fth	Sat Jun  4 22:25:49 2011	(r2245)
@@ -17,7 +17,6 @@
 headers
 : probe  ( -- )
    0 available-ram-size log&release
-\   h# 2000.0000 h# 1000.0000 log&release
 
    0 0 encode-bytes                                   ( adr 0 )
    physavail  ['] make-phys-memlist  find-node        ( adr len  prev 0 )
@@ -25,7 +24,95 @@
 
    \ Claim the memory used by OFW
    fw-pa  /fw-ram    0 claim  drop
-\   high h# 10.0000 -  h# 10.0000    0 claim  drop
+   extra-mem-pa  /extra-mem  0 claim  drop
+
+   0 pagesize  0 claim  drop       \ Vector table
+;
+
+\ The parameters depend on CPU-specific cache parameters
+: flush-entire-dcache  ( -- )
+   \ Flush L1 dcache
+   
+   h# 1000 0  do     \ Loop over sets - h# 1000 is L1 #sets
+      0 0  do        \ Loop over ways
+	 i j + clean&flush-d$-entry-way  \ Operate on L1 cache
+      h# 2000.0000 +loop  \ h# 2000.0000 depends on L1 #ways
+   h# 20 +loop       \ h# 20 is L1 line size
+
+   h# 10000 0  do    \ Loop over sets - h# 10000 is L2 #sets
+      0 0  do        \ Loop over ways
+	 i j + 2+ clean&flush-d$-entry-way  \ Operate on L2 cache (2+)
+      h# 2000.0000 +loop  \ h# 2000.0000 depends on L2 #ways
+   h# 20 +loop       \ h# 20 is L2 line size
+;
+' flush-entire-dcache to memtest-flush-cache
+
+0 value p-adr
+0 value v-adr
+
+false value mem-fail?
+
+: show-line  ( adr len -- )  (cr type  3 spaces  kill-line  ;
+' show-line to show-status
+
+: test-mem  ( adr len -- )	\ Test a chunk 'o memory
+   ."   Testing address 0x" over .x ." length 0x" dup .x cr
+
+   2>r
+   2r@ 0 mem-claim to p-adr		( ) ( r: adr len )
+[ifdef] virtual-mode
+   2r@ nip 1 mmu-claim to v-adr		( ) ( r: adr len )
+   2r@ v-adr swap h# c00 mmu-map	( ) ( r: adr len ) \ c00 = non-cached
+   v-adr				( adr )
+[else]
+   p-adr				( adr )
+[then]
+
+   2r@ nip memory-test-suite		( status ) ( r: adr len )
+   0<>  if  true to mem-fail?  then
+
+[ifdef] virtual-mode
+   v-adr 2r@ nip mmu-unmap		( ) ( r: adr len )
+   v-adr 2r@ nip mmu-release		( ) ( r: adr len )
+[then]
+   p-adr 2r> nip mem-release		( )
+
+   mem-fail?  if                        ( )
+      "     !!Failed!!" show-status  cr ( )
+   else                                 ( )
+      "     Succeeded" show-status  cr  ( )
+   then                                 ( )
+;
+
+: selftest  ( -- error? )
+
+   false to mem-fail?
+
+   " available" get-my-property  if
+      ." No available property in memory node" cr
+      true exit
+   then                                ( adr len )
+
+   begin  dup  while                   ( adr len )
+      decode-int >r  decode-int        ( adr len this-len r: this-padr )
+      r> swap test-mem                 ( adr len )
+      mem-fail?  if                    ( adr len )
+         2drop true exit               ( -- error )
+      then                             ( adr len )
+   repeat                              ( adr len )
+   2drop                               ( )
+
+   mem-fail?
 ;
 
 device-end
+
+: memtest  ( -- )
+   true to diag-switch?
+   1  begin                       ( pass# )
+      ." Pass " dup .d  cr  1+    ( pass# )
+      " /memory" test-dev         ( pass# )
+   key? until                     ( pass# )
+   key drop                       ( pass# )
+   drop                           ( )
+;

Modified: cpu/arm/olpc/initmmu.fth
==============================================================================
--- cpu/arm/olpc/initmmu.fth	Sat Jun  4 08:48:27 2011	(r2244)
+++ cpu/arm/olpc/initmmu.fth	Sat Jun  4 22:25:49 2011	(r2245)
@@ -215,8 +215,8 @@
    set r3,#0xc02                        \ No caching or write buffering
    bl  `map-sections-v=p`
 
-   set r1,`extra-mem-base #`            \ Address of additional allocatable memory
-   set r2,`extra-mem-size #`            \ Size of additional allocatable memory
+   set r1,`extra-mem-pa #`              \ Address of additional allocatable memory
+   set r2,`/extra-mem #`                \ Size of additional allocatable memory
    set r3,#0xc0e                        \ Write bufferable
    bl  `map-sections-v=p`
 

Modified: cpu/arm/scc.fth
==============================================================================
--- cpu/arm/scc.fth	Sat Jun  4 08:48:27 2011	(r2244)
+++ cpu/arm/scc.fth	Sat Jun  4 22:25:49 2011	(r2245)
@@ -119,6 +119,13 @@
 code disable-mclk       ( -- )     mcr p15,0,r0,cr15,cr4,2  c;
 code wait-for-interrupt ( -- )     mcr p15,0,r0,cr15,cr8,2  c;
 
+code cache-level@  ( -- level )  psh tos,sp  mrc p15,2,tos,cr0,cr0,0  c;
+code cache-level!  ( level -- )              mcr p15,2,tos,cr0,cr0,0  pop tos,sp  c;
+code cache-size-id@  ( -- n )    psh tos,sp  mrc p15,1,tos,cr0,cr0,0  c;
+code cache-level-id@  ( -- n )   psh tos,sp  mrc p15,1,tos,cr0,cr0,1  c;
+
+code silicon-id@  ( -- id )  psh tos,sp  mrc p15,1,tos,cr0,cr0,7  c;
+
 : ttbase  ( -- n )  ttbase@ h# 3ff invert and  ;
 
 : .control  ( -- )  control@  " i..rsb...wcam" show-bits  ;

Modified: ofw/fcode/memtest.fth
==============================================================================
--- ofw/fcode/memtest.fth	Sat Jun  4 08:48:27 2011	(r2244)
+++ ofw/fcode/memtest.fth	Sat Jun  4 22:25:49 2011	(r2245)
@@ -127,6 +127,8 @@
 hex
 
 headers
+defer memtest-flush-cache  ' noop to memtest-flush-cache
+
 defer meml!
 defer meml@
 defer memw!
@@ -203,6 +205,7 @@
    \ First we write all zeroes to the top and bottom memory locations
    0 add-base @ meml!   0 add-top  @ meml!
 
+   memtest-flush-cache
    \ Now we write all ones to 2 locations: the location whose address
    \ differs from the bottom address only by the address line under test,
    \ and the location whose address differs from the top address only by
@@ -212,6 +215,7 @@
    add-base @ over +  ffffffff swap meml! \ store ones at "base + [1 << addr#]"
    add-top  @ over -  ffffffff swap meml! \ store ones at "top  - [1 << addr#]"
 				( addr# offset )
+   memtest-flush-cache
 
    \ Now we check to see if either of the top or bottom locations got
    \ clobbered when we wrote the other two locations.  This tests for
@@ -234,6 +238,8 @@
    add-base @ over +  0 swap meml! \ store 0 at location "base + [ 1 << addr#]"
    add-top  @ over -  0 swap meml! \ store 0 at location "top - [ 1 << addr#]"
 
+   memtest-flush-cache
+
    ffffffff add-base @  mem-test
    ffffffff add-top  @  mem-test
 				( addr# offset )
@@ -290,6 +296,8 @@
    temp-buf      w@   over      memw!
    temp-buf wa1+ w@   over wa1+ memw!	     ( membase )
 
+   memtest-flush-cache
+
    h# 12345678  over  mem-test               ( membase )
 
    \ write data in byte size
@@ -298,6 +306,7 @@
    temp-buf 2 ca+ c@  over 2 ca+ memc!
    temp-buf 3 ca+ c@  over 3 ca+ memc!       ( membase )
 
+   memtest-flush-cache
    h# 12345678  over  mem-test               ( membase )
    drop
    failed @			\ place failed flag on stack
@@ -311,12 +320,14 @@
     				( membase )
    d# 32 0 do			\ loop over all 32 data lines
       1 i <<  over  meml!	( membase )
+      memtest-flush-cache
       1 i <<  over  mem-test	( membase )
    loop                         ( membase )
 
    \ Walking zeroes
    d# 32 0 do			 \ loop over all 32 data lines
       1 i << invert  over  meml!     ( membase )
+      memtest-flush-cache
       1 i << invert  over  mem-test  ( membase )
    /l +  loop                        ( membase )
 
@@ -330,8 +341,8 @@
    failed off			\ set failed flag to false
 
    bounds			( memtop membase )
-   2dup  ?do  h# ffffffff  i  2dup meml!  mem-test  /l +loop  \ stuck at 0 test
-         ?do  h# 00000000  i  2dup meml!  mem-test  /l +loop  \ stuck at 1 test
+   2dup  ?do  h# ffffffff  i  2dup meml!  memtest-flush-cache  mem-test  /l +loop  \ stuck at 0 test
+         ?do  h# 00000000  i  2dup meml!  memtest-flush-cache  mem-test  /l +loop  \ stuck at 1 test
 
    failed @			\ put failed flag onto the stack
 ;
@@ -343,6 +354,8 @@
 
    bounds  2dup  do  i i meml!  /l +loop	( memtop membase )
 
+   memtest-flush-cache
+
    failed off
    do  i i mem-test  /l +loop
    failed @			\ return failed flag on stack
@@ -365,6 +378,8 @@
                    i 2 la+ meml!
    /l 3 * +loop
 
+   memtest-flush-cache
+
    failed off		( memtop membase )
    do
       mats-pattern @
@@ -394,7 +409,10 @@
       2dup address=data-test  ?suite-failed   ( membase memsize )
 \ Don't do the mats test, because I'm not convinced that it is useful
 \       2dup h# a5a5a5a5  mats-test  ?suite-failed   ( membase memsize )
-   then
+[ifdef] random-test
+      2dup random-test  ?suite-failed         ( membase memsize )
+[then]
+   then                                       ( membase memsize )
    2drop
 
    suite-failed @



More information about the openfirmware mailing list