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
Author: wmb
Date: Tue Aug 9 06:26:34 2011
New Revision: 2432
URL: http://tracker.coreboot.org/trac/openfirmware/changeset/2432
Log:
Alex - added SPI FLASH reprogramming.
Added:
cpu/x86/pc/alex/spiui.fth
dev/intel/spi.fth
Modified:
cpu/x86/pc/alex/devices.fth
dev/olpc/spiflash/spiflash.fth
ofw/fs/cbfs.fth
Modified: cpu/x86/pc/alex/devices.fth
==============================================================================
--- cpu/x86/pc/alex/devices.fth Tue Aug 9 06:25:40 2011 (r2431)
+++ cpu/x86/pc/alex/devices.fth Tue Aug 9 06:26:34 2011 (r2432)
@@ -34,6 +34,14 @@
h# 28 to vector-base1
device-end
+fload ${BP}/dev/olpc/spiflash/flashif.fth \ Generic FLASH interface
+
+fload ${BP}/dev/olpc/spiflash/memflash.fth \ Memory-mapped FLASH read access
+
+warning @ warning off
+: stand-init-io stand-init-io h# ffc0.0000 to flash-base ;
+warning !
+
fload ${BP}/ofw/fs/cbfs.fth \ Coreboot ROM filesystem
\ Create the top-level device node to access the entire boot FLASH device
@@ -168,8 +176,16 @@
fload ${BP}/ofw/core/muxdev.fth \ I/O collection/distribution device
+fload ${BP}/dev/olpc/spiflash/spiif.fth \ Generic low-level SPI bus access
+fload ${BP}/dev/intel/spi.fth \ SPI FLASH programming
+
fload ${BP}/cpu/x86/pc/reset.fth \ reset-all
+: ?enough-power ; \ Implement based on AC presence and battery status
+
+fload ${BP}/cpu/x86/pc/alex/spiui.fth \ User interface for SPI FLASH programming
+: urom ( -- ) " flash! u:\alex.rom" evaluate ;
+
\ LICENSE_BEGIN
\ Copyright (c) 2011 FirmWorks
\
Added: cpu/x86/pc/alex/spiui.fth
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ cpu/x86/pc/alex/spiui.fth Tue Aug 9 06:26:34 2011 (r2432)
@@ -0,0 +1,177 @@
+\ See license at end of file
+purpose: User interface for reflashing SPI FLASH parts
+
+\ This code is concerned with the user interface for getting
+\ a new firmware image into memory and using it to program
+\ a FLASH device from that image. The details of how to actually
+\ access the FLASH device are defined elsewhere.
+
+h# 4000 constant /chunk \ Convenient sized piece for progress reports
+
+: write-flash-range ( adr end-offset start-offset -- )
+ ." Writing" cr
+ ?do ( adr )
+ \ Save time - don't write if the data is the same
+ i .x (cr ( adr )
+ spi-us d# 20 >= if ( adr )
+ \ Just write if reading is slow
+ true ( adr must-write? )
+ else ( adr )
+ dup /flash-block i flash-verify ( adr must-write? )
+ then ( adr must-write? )
+
+ if
+ i flash-erase-block
+ dup /flash-block i flash-write ( adr )
+ then
+ /flash-block + ( adr' )
+ /flash-block +loop ( adr )
+ cr drop ( )
+;
+
+: verify-flash-range ( adr end-offset start-offset -- )
+ ." Verifying" cr
+ ?do ( adr )
+ i .x (cr
+ dup /flash-block i flash-verify abort" Verify failed"
+ /flash-block + ( adr' )
+ /flash-block +loop ( adr )
+ cr drop ( )
+;
+
+
+\ Perform a series of sanity checks on the new firmware image.
+
+[ifdef] load-base
+: flash-buf load-base ;
+[else]
+/flash buffer: flash-buf
+[then]
+
+0 value file-loaded?
+
+: -cbid ( offset -- ) flash-buf /flash + swap - ;
+
+: check-id-string ( offset expect$ -- )
+ rot -cbid @ -cbid cscount ( expect$ got$ )
+ 2over 2over $= 0= if ( expect$ got$ )
+ ." Expecting " 2swap type ." , got " type cr
+ abort
+ then ( expect$ got$ )
+ 4drop ( )
+;
+: ?coreboot-id ( -- )
+ h# 14 -cbid @ /flash <> abort" Coreboot flash size mismatch"
+ h# 1c " Samsung" check-id-string
+ h# 18 " Alex" check-id-string
+;
+: ?cbfs ( -- )
+ flash-buf " LARCHIVE" comp abort" Image file is not in CBFS format"
+ \ We could also check the integrity of the CBFS headers
+;
+
+: ?image-valid ( len -- )
+ /flash <> abort" Image file is the wrong length"
+
+ ?cbfs
+ ?coreboot-id
+;
+
+: $get-file ( "filename" -- )
+ $read-open
+ flash-buf /flash ifd @ fgets ( len )
+ ifd @ fclose
+
+ ?image-valid
+
+ true to file-loaded?
+;
+
+: ?file ( -- )
+ file-loaded? 0= if
+ ." You must first load a valid FLASH image file with" cr
+ ." get-file filename" cr
+ abort
+ then
+;
+
+: read-flash ( "filename" -- )
+ writing
+ /flash 0 do
+ i .x (cr
+ flash-buf i + /chunk i flash-read
+ /chunk +loop
+ flash-buf /flash ofd @ fputs
+ ofd @ fclose
+;
+
+: verify ( -- ) ?file flash-buf /flash 0 verify-flash-range ;
+
+: verify-firmware ( -- )
+ flash-buf /flash 0 verify-flash-range \ Verify first part
+;
+
+: write-firmware ( -- )
+ flash-buf /flash 0 write-flash-range \ Write first part
+;
+
+: reflash ( -- ) \ Flash from data already in memory
+ ?file
+ flash-write-enable
+
+ write-firmware
+
+ ['] verify-firmware catch if
+ ." Verify failed. Retrying once" cr
+ spi-identify
+ write-firmware
+ verify-firmware
+ then
+ flash-write-disable
+;
+
+defer fw-filename$ ' null$ to fw-filename$
+
+: get-file ( ["filename"] -- )
+ parse-word ( adr len )
+ dup 0= if 2drop fw-filename$ then ( adr len )
+ ." Reading " 2dup type cr ( adr len )
+ $get-file
+;
+
+: flash ( ["filename"] -- ) get-file ?enough-power reflash ;
+: flash! ( ["filename"] -- ) get-file reflash ;
+
+: safe-flash-read ( -- )
+ flash-buf /flash 0 flash-read
+;
+
+dev /flash
+: selftest ( -- error? )
+ .cbfs
+;
+device-end
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2011 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
Added: dev/intel/spi.fth
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dev/intel/spi.fth Tue Aug 9 06:26:34 2011 (r2432)
@@ -0,0 +1,258 @@
+\ See license at end of file
+purpose: Driver for SPI FLASH chips connected via Intel NM10 SPI interface
+
+h# fed1f020 value spi-base
+: spi-reg-b! ( b offset -- ) spi-base + c! ;
+: spi-reg-w! ( w offset -- ) spi-base + w! ;
+: spi-reg-l! ( l offset -- ) spi-base + l! ;
+: spi-reg-b@ ( offset -- b ) spi-base + c@ ;
+: spi-reg-w@ ( offset -- w ) spi-base + w@ ;
+: spi-reg-l@ ( offset -- l ) spi-base + l@ ;
+
+: spi-data ( -- adr ) spi-base 8 + ;
+
+: spi-stat@ ( -- w ) 0 spi-reg-w@ ;
+: spi-stat! ( w -- ) 0 spi-reg-w! ;
+: spi-ctrl! ( w -- ) 2 spi-reg-w! ;
+: spi-addr! ( l -- ) 4 spi-reg-l! ;
+: spi-prefix! ( n -- ) h# 54 spi-reg-w! ;
+: spi-type! ( n -- ) h# 56 spi-reg-w! ;
+: spi-opcode! ( b opcode# -- ) h# 58 + spi-reg-b! ;
+
+d# 64 constant max-spi-data
+
+
+\ Commands
+\ # t DCOA P Op
+\ 0 0 4102 5 <no address> <1 data in> read-status
+\ 1 2 4n12 3 <ADDR> <N data in> read
+\ 2 0 4322 9f <no address> <3 data in> jedec-id
+\ 3 2 4232 90 <ADDR=0> <2 data in> 90-id
+\ 4 2 4142 ab <ADDR=0> <1 data in> ab-id
+\ 5 1 4156 6 1 <no address> <1 data out> write-status
+\ 6 3 4n66 6 2 <ADDR> <N data out> write
+\ 7 3 0076 6 d8 <ADDR> <no data> erase-block
+
+4 base ! 33122020 hex constant cycle-types
+: intel-spi-start ( -- )
+ h# 0406 spi-prefix! \ Prefix 0 is write-enable, 1 is write-disable
+ h# d80201ab h# 5c spi-reg-l! \ opcodes 7-4
+ h# 909f0305 h# 58 spi-reg-l! \ opcodes 3-0
+ cycle-types h# 56 spi-reg-w!
+ h# 0c spi-stat!
+;
+: spi-do-cmd ( code -- )
+ begin spi-stat@ 1 and 0= until
+ spi-ctrl!
+ begin spi-stat@ 4 and until
+ 4 spi-stat!
+;
+: spi-read-status ( -- b )
+ h# 4002 spi-do-cmd
+ spi-data c@
+;
+: wait-write-done ( -- )
+ d# 100000 0 do
+ spi-read-status 1 and 0= if unloop exit then
+ d# 10 us
+ loop
+;
+: spi-read-n ( adr len offset -- )
+ spi-addr! ( adr len )
+ dup 1- 8 lshift h# 4012 or spi-do-cmd ( adr len )
+ spi-data -rot move ( )
+;
+: jedec-id ( -- b3b2b1 )
+ h# 4222 spi-do-cmd
+ spi-data w@ spi-data 2+ c@ wljoin
+;
+: 90-id ( -- b2b1 )
+ 0 spi-addr!
+ h# 4132 spi-do-cmd
+ spi-data w@
+;
+: ab-id ( -- b1 )
+ 0 spi-addr!
+ h# 4042 spi-do-cmd
+ spi-data c@
+;
+: spi-write-status ( b -- )
+ spi-data c! ( )
+ h# 4056 spi-do-cmd ( )
+ wait-write-done ( )
+;
+: spi-write-n ( adr len offset -- )
+ spi-addr! ( adr len )
+ tuck ( len adr len )
+ spi-data swap move ( len )
+ 1- 8 lshift h# 4066 or spi-do-cmd ( )
+ wait-write-done ( )
+;
+: erase-spi-block ( offset -- )
+ spi-addr! ( )
+ h# 0076 spi-do-cmd ( )
+ wait-write-done ( )
+;
+
+\ Write within one SPI FLASH page. Offset + len must not cross a page boundary
+
+: write-spi-page ( adr len offset -- )
+ begin over while ( adr len offset )
+ over max-spi-data min >r ( adr len offset r: this )
+ 2 pick r@ 2 pick spi-write-n ( adr len offset r: this )
+ rot r@ + rot r@ - rot r> + ( adr' len' offset' )
+ repeat ( adr len offset )
+ 3drop ( )
+;
+
+: read-spi-flash ( adr len offset -- )
+ begin over while ( adr len offset )
+ over max-spi-data min >r ( adr len offset r: this )
+ 2 pick r@ 2 pick spi-read-n ( adr len offset r: this )
+ rot r@ + rot r@ - rot r> + ( adr' len' offset' )
+ repeat ( adr len offset )
+ 3drop ( )
+;
+
+\ Verify the contents of SPI FLASH starting at offset against
+\ the memory range adr,len . Aborts with a message on mismatch.
+
+: verify-spi-flash ( adr len offset -- mismatch? )
+ over alloc-mem >r ( adr len offset r: temp-adr )
+ r@ 2 pick rot ( adr len temp-adr len offset r: temp-adr )
+ flash-read ( adr len r: temp-adr )
+ tuck r@ swap comp ( len mismatch? r: temp-adr )
+ r> rot free-mem ( mismatch? )
+;
+
+h# 10000 constant /spi-eblock \ Smallest erase block common to all chips
+h# 100 constant /spi-page \ Largest write for page-oriented chips
+
+\ Figures out how many bytes can be written in one transaction,
+\ subject to not crossing a 256-byte page boundary.
+
+: left-in-page ( len offset -- len offset #left )
+ \ Determine how many bytes are left in the page containing offset
+ /spi-page over /spi-page 1- and - ( adr len offset left-in-page )
+
+ \ Determine the number of bytes to write in this transaction
+ 2 pick min ( adr len offset r: #to-write )
+;
+
+\ Adjust address, length, and write offset by the number of
+\ bytes transferred in the last action
+
+: adjust ( adr len offset #transferred -- adr+ len- offset+ )
+ tuck + >r /string r>
+;
+
+\ Determine if it's worthwhile to write; writing FF's is pointless
+: non-blank? ( adr len -- non-blank? ) h# ff bskip 0<> ;
+
+\ Write as many bytes as can be done in one operation, limited
+\ by page boundaries, and adjust the parameters to reflect the
+\ data that was written. If the data that would be written is
+\ all FFs, save time by not actually writing it.
+
+: write-spi-some ( adr len offset -- adr' len' offset' )
+ left-in-page ( adr len offset #to-write )
+
+ 3 pick over non-blank? if ( adr len offset #to-write )
+ 3 pick over 3 pick ( adr len offset #to-write adr #to-write offset )
+ write-spi-page ( adr len offset #to-write )
+ then ( adr len offset #to-write )
+
+ adjust ( adr' len' offset' )
+;
+
+\ Write data from the range adr,len to SPI FLASH beginning at offset
+\ Does not erase automatically; you have to do that beforehand.
+
+\ This version works for parts that support page writes with
+\ multiple data bytes after command 2
+
+: write-spi-flash ( adr len offset -- )
+ begin over while ( adr len offset )
+ write-spi-some ( adr' len' offset' )
+ repeat ( adr 0 offset )
+ 3drop
+;
+
+\ Get the SPI FLASH ID and decode it to the extent that we need.
+\ There are several different commands to get ID information,
+\ and the various SPI FLASH chips support different subsets of
+\ those commands. The AB command seems to be supported by all
+\ of them, so it's a good starting point.
+
+0 value spi-id#
+: spi-identify ( -- )
+ ab-id to spi-id#
+ spi-id# case
+ h# 13 of endof
+ h# 15 of endof
+ h# 34 of endof
+ ( default ) true abort" Unsupported SPI FLASH ID"
+ endcase
+ 0 spi-write-status \ Turn off write protect bits
+;
+
+\ Display a message telling what kind of part was found
+
+: .spi-id ( -- )
+ ." SPI FLASH is "
+ spi-id# case
+ h# 13 of ." type 13 - Spansion, Winbond, or ST" endof
+ h# 15 of ." type 15 - Macronyx" endof
+ h# 34 of ." type 34 - Macronyx" endof
+ endcase
+;
+
+: spi-flash-open ( -- )
+ \ One retry
+ spi-start ['] spi-identify catch if
+ spi-start spi-identify
+ then
+;
+: spi-flash-write-enable ( -- ) flash-open .spi-id cr ;
+
+: use-spi-flash-read ( -- ) ['] read-spi-flash to flash-read ;
+
+\ Install the SPI FLASH versions as their implementations.
+: use-spi-flash ( -- )
+ ['] spi-flash-open to flash-open
+ ['] noop to flash-close
+ ['] spi-flash-write-enable to flash-write-enable
+ ['] noop to flash-write-disable
+ ['] write-spi-flash to flash-write
+ ['] verify-spi-flash to flash-verify
+ ['] erase-spi-block to flash-erase-block
+ use-mem-flash-read \ Might be overridden
+ h# 40.0000 to /flash
+ /spi-eblock to /flash-block
+;
+use-spi-flash
+' intel-spi-start to spi-start
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2011 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: dev/olpc/spiflash/spiflash.fth
==============================================================================
--- dev/olpc/spiflash/spiflash.fth Tue Aug 9 06:25:40 2011 (r2431)
+++ dev/olpc/spiflash/spiflash.fth Tue Aug 9 06:26:34 2011 (r2432)
@@ -64,7 +64,7 @@
\ You have to wait after any command that modifies stuff
\ inside the part - writes, erases, status register writes
-: wait-write-done ( -- timeout? )
+: wait-write-done ( -- )
\ The Spansion part's datasheet claims that the only operation
\ that takes longer than 500mS is bulk erase and we don't ever
\ want to use that command
@@ -73,7 +73,6 @@
spi-read-status 1 and 0= if unloop exit then \ Test WIP bit
d# 10 us
loop
- -1
;
\ Common start sequence for writes and erases - anything that
Modified: ofw/fs/cbfs.fth
==============================================================================
--- ofw/fs/cbfs.fth Tue Aug 9 06:25:40 2011 (r2431)
+++ ofw/fs/cbfs.fth Tue Aug 9 06:26:34 2011 (r2432)
@@ -1,7 +1,6 @@
purpose: Coreboot filesystem ("CBFS") package
\ See license at end of file
-h# ffc0.0000 value flash-base
: .cbfs-type ( type -- )
case
h# 10 of ." stage" endof
Author: wmb
Date: Mon Aug 8 23:18:36 2011
New Revision: 2430
URL: http://tracker.coreboot.org/trac/openfirmware/changeset/2430
Log:
ELF header creation - fixed incorrect offset for coreboot case.
Modified:
cpu/x86/pc/elfhdr.fth
Modified: cpu/x86/pc/elfhdr.fth
==============================================================================
--- cpu/x86/pc/elfhdr.fth Sat Aug 6 02:32:41 2011 (r2429)
+++ cpu/x86/pc/elfhdr.fth Mon Aug 8 23:18:36 2011 (r2430)
@@ -28,7 +28,7 @@
dropin-base h# 20 + to elf-entry \ Skip OBMD header in RAM copy
1 to #pheaders \ The pheader causes the image to be copied to RAM
0 to file-offset \ Copy the whole thing, don't skip the ELF headers
- dropin-base h# 80 - to elf-addr \ Copied headers will precede dropin-base
+ dropin-base h# 60 - to elf-addr \ Copied headers will precede dropin-base
[else]
\ For coreboot running from ROM, we can leave everything in ROM, no need to copy,
\ so there's no need for a pheader.