Author: wmb
Date: 2008-08-13 12:12:48 +0200 (Wed, 13 Aug 2008)
New Revision: 879
Added:
dev/flashui.fth
dev/flashwritepkg.fth
dev/lpcflash.fth
Modified:
cpu/x86/pc/neptune/addrs.fth
cpu/x86/pc/neptune/devices.fth
cpu/x86/pc/neptune/fw.bth
cpu/x86/pc/neptune/msrinit.fth
cpu/x86/pc/neptune/neptune.bth
Log:
Neptune - FLASH writing support.
Modified: cpu/x86/pc/neptune/addrs.fth
===================================================================
--- cpu/x86/pc/neptune/addrs.fth 2008-08-12 08:49:21 UTC (rev 878)
+++ cpu/x86/pc/neptune/addrs.fth 2008-08-13 10:12:48 UTC (rev 879)
@@ -1,67 +1,18 @@
\ See license at end of file
purpose: Establish address and I/O configuration definitions
-[ifdef] use-meg0
-h# f0.0000 constant dropin-base
-h# 08.0000 constant dropin-size
-h# 0.4000 constant fw-pa
-h# f.c000 constant /fw-ram
-[then]
+h# fff0.0000 constant rom-pa \ Physical address of boot ROM
+h# 10.0000 constant /rom \ Size of boot ROM
-[ifdef] rom-loaded
-h# fff8.0000 constant rom-pa \ Physical address of boot ROM
-h# 8.0000 constant /rom \ Size of boot ROM
-rom-pa constant dropin-base
-
+h# 8.0000 constant dropin-offset
+rom-pa dropin-offset + constant dropin-base
h# 8.0000 constant dropin-size
dropin-base h# 20 + constant ResetBase \ Location of "reset" dropin in ROM
h# 1c0.0000 constant fw-pa
h# 20.0000 constant /fw-ram
-[then]
-[ifdef] linuxbios-loaded
-\ h# d8.0000 constant dropin-base
-h# fff2.0000 constant dropin-base \ Location of payload in FLASH
-\ h# fff8.0000 constant dropin-base \ Location of payload in FLASH
-dropin-base h# 80 + h# 20 + constant ResetBase \ Location of "reset" dropin in ROM
-h# 08.0000 constant dropin-size
-h# 1e0.0000 constant fw-pa
-h# 20.0000 constant /fw-ram
-h# fff0.0000 constant rom-pa
-h# 10.0000 constant /rom
-[then]
-
-[ifdef] old-bzimage-loaded
-\ h# d8.0000 constant dropin-base
-h# 10.0020 constant dropin-base \ RAM address where Linux normally loads
-h# 08.0000 constant dropin-size
-h# 20.0000 constant fw-pa
-h# 20.0000 constant /fw-ram
-[then]
-
-[ifdef] bzimage-loaded
-h# 1d8.0020 constant dropin-base \ RAM address where we want to end up
-h# 08.0000 constant dropin-size
-h# 1e0.0000 constant fw-pa
-h# 20.0000 constant /fw-ram
-[then]
-
-[ifdef] syslinux-loaded
-h# 10.1020 constant dropin-base
-h# 07.e0e0 constant dropin-size
-h# 20.0000 constant fw-pa
-h# 20.0000 constant /fw-ram
-[then]
-
-[ifdef] grub-loaded
-h# 1b8.0000 constant dropin-base
-h# 08.0000 constant dropin-size
-h# 1c0.0000 constant fw-pa
-h# 20.0000 constant /fw-ram
-[then]
-
h# 80.0000 constant def-load-base \ Convenient for initrd
\ The heap starts at RAMtop, which on this system is "fw-pa /fw-ram +"
@@ -100,7 +51,7 @@
fload ${BP}/cpu/x86/pc/virtaddr.fth
[ifndef] virtual-mode
-h# ff80.0000 to fw-virt-base \ Override the usual setting; we use an MSR to double-map some memory up high
+h# fec0.0000 to fw-virt-base \ Override the usual setting; we use an MSR to double-map some memory up high
h# 40.0000 to fw-virt-size
[then]
Modified: cpu/x86/pc/neptune/devices.fth
===================================================================
--- cpu/x86/pc/neptune/devices.fth 2008-08-12 08:49:21 UTC (rev 878)
+++ cpu/x86/pc/neptune/devices.fth 2008-08-13 10:12:48 UTC (rev 879)
@@ -80,23 +80,36 @@
warning !
\ Create the top-level device node to access the entire boot FLASH device
-\ 0 0 " fff00000" " /" begin-package
-0 0 dropin-base <# u#s u#> " /" begin-package
+0 0 " fff00000" " /" begin-package
" flash" device-name
h# 10.0000 value /device
h# 10.0000 constant /device-phys
my-address my-space /device-phys reg
+
+ h# 40.0000 negate constant regs-offset
+ h# 1.0000 value block-size
+
+ : write-enable ( -- )
+ h# 1808 rdmsr h# ff.ffff and h# 2100.0000 or h# 1808 wrmsr
+ ;
+ : write-disable ( -- )
+ h# 1808 rdmsr h# ff.ffff and h# 2500.0000 or h# 1808 wrmsr
+ ;
+
fload ${BP}/dev/flashpkg.fth
- fload ${BP}/dev/flashwrite.fth
+ fload ${BP}/dev/lpcflash.fth
+ fload ${BP}/dev/flashwritepkg.fth
end-package
+devalias flash /flash@fff00000
+
\ Create a node below the top-level FLASH node to accessing the portion
\ containing the dropin modules
-0 0 " 00000" " /flash" begin-package
+0 0 dropin-offset <# u#s u#> " /flash" begin-package
" dropins" device-name
- h# 70000 constant /device
+ dropin-size constant /device
fload ${BP}/dev/subrange.fth
end-package
@@ -108,6 +121,29 @@
\ This devalias lets us say, for example, "dir rom:"
devalias rom /dropin-fs
+\ Create the top-level device node to access the entire boot FLASH device
+0 0 " ffe00000" " /" begin-package
+ " flash" device-name
+
+ h# 10.0000 value /device
+ h# 10.0000 constant /device-phys
+ my-address my-space /device-phys reg
+ h# 1.0000 value block-size
+
+ h# 40.0000 negate constant regs-offset
+
+ : write-enable ( -- )
+ h# 1808 rdmsr h# ff.ffff and h# 2100.0000 or h# 1808 wrmsr
+ ;
+ : write-disable ( -- )
+ h# 1808 rdmsr h# ff.ffff and h# 2500.0000 or h# 1808 wrmsr
+ ;
+
+ fload ${BP}/dev/flashpkg.fth
+ fload ${BP}/dev/lpcflash.fth
+ fload ${BP}/dev/flashwritepkg.fth
+end-package
+
fload ${BP}/cpu/x86/forthint.fth \ Low-level interrupt handling code
fload ${BP}/dev/isa/irq.fth \ ISA interrupt dispatcher
fload ${BP}/cpu/x86/pc/isatick.fth \ Use ISA timer as the alarm tick timer
@@ -259,10 +295,6 @@
dend
;
-fload ${BP}/cpu/x86/pc/neptune/lpcflash.fth
-
-fload ${BP}/dev/geode/lpcflash.fth \ Reflasher for PLCC FLASH on A-test
-
: +i encode-int encode+ ; : 0+i 0 +i ;
[ifdef] rom-loaded
Modified: cpu/x86/pc/neptune/fw.bth
===================================================================
--- cpu/x86/pc/neptune/fw.bth 2008-08-12 08:49:21 UTC (rev 878)
+++ cpu/x86/pc/neptune/fw.bth 2008-08-13 10:12:48 UTC (rev 879)
@@ -420,15 +420,8 @@
;
-h# ffac0000 constant lpc-flash2-phys
-h# 40000 constant /lpc-flash2 \ size
+fload ${BP}/dev/flashui.fth
-: neptune-flash2-map
-
- lpc-flash2-phys /lpc-flash2 0 mmu-claim drop \ Reserve the virtual address range
- lpc-flash2-phys dup /lpc-flash2 -1 mmu-map \ Create a mapping
-;
-
: vme ( -- )
." Running Lattice programmer "
com1 io
Modified: cpu/x86/pc/neptune/msrinit.fth
===================================================================
--- cpu/x86/pc/neptune/msrinit.fth 2008-08-12 08:49:21 UTC (rev 878)
+++ cpu/x86/pc/neptune/msrinit.fth 2008-08-13 10:12:48 UTC (rev 879)
@@ -219,7 +219,7 @@
\ msr: 5140.0012 \ LBAR_FLSH2
\ msr: 5140.0013 \ LBAR_FLSH3
\ msr: 5140.0014 00000000.80070003. \ LEG_IO already set in romreset
- msr: 5140.0015 00000000.00000f7d. \ BALL_OPTS - IDE pins are IDE, not NAND
+ msr: 5140.0015 00000000.00000f71. \ BALL_OPTS - IDE pins are IDE, not NAND, LPC FLASH mode
\ msr: 5140.001b 00000000.07770777. \ NANDF_DATA - default
\ msr: 5140.001c 00000000.00000777. \ NANDF_CTL - default
msr: 5140.001f 00000000.00000011. \ KEL_CTRL
Modified: cpu/x86/pc/neptune/neptune.bth
===================================================================
--- cpu/x86/pc/neptune/neptune.bth 2008-08-12 08:49:21 UTC (rev 878)
+++ cpu/x86/pc/neptune/neptune.bth 2008-08-13 10:12:48 UTC (rev 879)
@@ -73,22 +73,22 @@
[then]
" ${BP}/dev/pci/build/pcibridg.fc" " class060400" $add-deflated-dropin
- /rom h# 400 - pad-file \ rmstart image must start 0x400 from end
+ dropin-size h# 400 - pad-file \ rmstart image must start 0x400 from end
" rmstart.img" $add-file
\ Insert the revision signature
-/rom h# 40 - ofd @ fseek
+dropin-size h# 40 - ofd @ fseek
" DA1 ${FW_VERSION} D1${FW_MAJOR}" expand$ ofd @ fputs
/l buffer: crcbuf
-/rom buffer: filebuf
+dropin-size buffer: filebuf
0 ofd @ fseek
\ Read the entire image, compute the CRC, and store it h# 30 from the end
-filebuf /rom ofd @ fgets /rom <> abort" Can't read back image"
-0 crctab filebuf /rom ($crc) crcbuf !
+filebuf dropin-size ofd @ fgets dropin-size <> abort" Can't read back image"
+0 crctab filebuf dropin-size ($crc) crcbuf !
-/rom h# 30 - ofd @ fseek
+dropin-size h# 30 - ofd @ fseek
crcbuf /l ofd @ fputs
ofd @ fclose
Added: dev/flashui.fth
===================================================================
--- dev/flashui.fth (rev 0)
+++ dev/flashui.fth 2008-08-13 10:12:48 UTC (rev 879)
@@ -0,0 +1,117 @@
+purpose: Simple FLASH write user interface, calling flash node methods
+\ See license at end of file.
+
+[ifndef] reflash
+0 value flash-buf
+0 value /flash
+0 value /flash-block
+
+\ Simple UI for reflashing, assuming that you want to overwrite
+\ the entire FLASH contents. That's not always a good assumption;
+\ some systems use certain FLASH blocks for persistent data like
+\ configuration variables or manufacturing data ("Vital Product Data").
+
+0 value file-loaded?
+
+: ?image-valid ( len -- )
+ /flash <> abort" Image file is the wrong length"
+;
+
+0 value flash-ih
+
+: $call-flash ( ??? -- ??? ) flash-ih $call-method ;
+: close-flash ( -- )
+ flash-ih if
+ flash-ih close-dev
+ 0 to flash-ih
+ flash-buf /flash free-mem
+ then
+;
+
+: ?open-flash ( -- )
+ flash-ih if exit then
+
+ " flash" open-dev to flash-ih
+ flash-ih 0= abort" Can't open FLASH device"
+
+ " writable?" $call-flash 0= if
+ close-flash
+ true abort" FLASH device is not writable"
+ then
+
+ " block-size" $call-flash to /flash-block
+ " size" $call-flash drop to /flash
+ /flash alloc-mem to flash-buf
+;
+
+: $get-flash-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
+;
+
+: reflash ( -- ) \ Flash from data already in memory
+ ?open-flash
+ ?file
+
+ ." Writing" cr
+
+ /flash 0 ?do
+ (cr i .
+ flash-buf i + /flash-block i " flash-write" $call-flash ( )
+ /flash-block +loop
+
+ close-flash
+;
+
+\ Set this defer word to return a string naming the default
+\ filename for firmware updates
+defer fw-filename$ ' null$ to fw-filename$
+
+: get-flash-file ( ["filename"] -- )
+ ?open-flash
+ parse-word ( adr len )
+ dup 0= if 2drop fw-filename$ then ( adr len )
+ ." Reading " 2dup type cr ( adr len )
+ $get-flash-file
+;
+
+: flash ( ["filename"] -- ) get-flash-file reflash ;
+[then]
+
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2008 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/flashwritepkg.fth
===================================================================
--- dev/flashwritepkg.fth (rev 0)
+++ dev/flashwritepkg.fth 2008-08-13 10:12:48 UTC (rev 879)
@@ -0,0 +1,115 @@
+purpose: Support routines for NOR FLASH writing
+\ See license at end of file.
+
+\ This defines a "write" method for NOR FLASH than handles the
+\ problems that you have to erase a block before writing and
+\ the erase granularity may be larger than the write granularity.
+\ This is intended to be part of the implementation of a FLASH
+\ device node, where lower level erase-block and flash-write
+\ routines are already defined.
+
+\ On NOR FLASH, you can write as many times as you want as long as
+\ you keep turning 1's into 0's. You only have to erase when you
+\ want to make some bits go from 0 to 1. An efficient algorithm is:
+\
+\ Break the entire write range into pieces each contained in one
+\ erase unit. For each piece:
+\
+\ Compare the existing and new contents to see if the unit needs erasing
+\
+\ If no bits need to go from 0 to 1, erase is unnecessary, so just write.
+\ (It's a little more complicated if the write granularity is >1 byte.)
+\
+\ Otherwise, copy the existing contents of the erase unit to a buffer,
+\ merge in the new data, erase, then write back the buffer.
+
+: left-in-block ( len offset -- #left )
+ \ Determine how many bytes are left in the page containing offset
+ block-size swap block-size 1- and - ( len left-in-page )
+ min ( #left )
+;
+
+: must-erase? ( adr len -- flag )
+ device-base seek-ptr + ( adr len dev-adr )
+ swap 0 ?do ( adr dev-adr )
+ over i + c@ over i + c@ ( adr dev-adr new-byte old-byte )
+ \ Must erase if a bit in old-byte is 0 and that bit in new-byte is 1
+ invert and if ( adr dev-adr )
+ 2drop true unloop exit
+ then ( adr dev-adr )
+ loop ( adr dev-adr )
+ 2drop false
+;
+
+: erase+write ( adr len -- )
+ dup block-size = if
+ \ If we are going to overwrite the entire block, there's no need to
+ \ preserve the old data. This can only happen if we are already
+ \ aligned on an erase block boundary.
+ seek-ptr erase-block ( adr len )
+ seek-ptr flash-write ( )
+ else
+ \ Allocate a buffer to save the old block contents
+ block-size alloc-mem >r ( adr len )
+
+ seek-ptr block-size round-down ( adr len block-start )
+
+ \ Copy existing data from FLASH block to the buffer
+ dup device-base + r@ block-size lmove ( adr len block-start )
+
+ \ Merge new bytes into the buffer
+ -rot ( block-start adr len )
+ seek-ptr block-size mod ( block-start adr len buf-offset )
+ r@ + swap move ( block-start )
+
+ \ Erase the block and rewrite it from the buffer
+ dup erase-block ( block-start )
+ r@ block-size rot flash-write ( )
+
+ \ Release the buffer
+ r> block-size free-mem
+ then
+;
+
+: handle-block ( adr len -- adr' len' )
+ dup seek-ptr left-in-block ( adr len #left )
+ >r ( adr len r: #left )
+ over r@ must-erase? if ( adr len r: #left )
+ over r@ erase+write ( adr len r: #left )
+ else ( adr len r: #left )
+ over r@ seek-ptr flash-write ( adr len r: #left )
+ then ( adr len r: #left )
+ seek-ptr r@ + to seek-ptr ( adr len r: #left )
+ r> /string ( adr' len' )
+;
+
+: write ( adr len -- #written )
+ writable? 0= if 2drop 0 exit then
+ tuck ( len adr len )
+ begin dup while handle-block repeat ( len adr' remain' )
+ 2drop ( len )
+;
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2008 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/lpcflash.fth
===================================================================
--- dev/lpcflash.fth (rev 0)
+++ dev/lpcflash.fth 2008-08-13 10:12:48 UTC (rev 879)
@@ -0,0 +1,104 @@
+purpose: LPC/FWH FLASH low-level write words for use inside a device node
+\ See license at end of file.
+
+\ write-enable and write-disable need to be defined externally
+\ Typically you load flashpkg.fth before and flashwritepkg.fth after this
+
+0 instance value regs-adr
+
+: unmap-regs ( -- )
+ regs-adr if
+ regs-adr /device " map-out" $call-parent
+ 0 to regs-adr
+ write-disable
+ then
+;
+
+: writable? ( -- flag )
+ regs-adr if true exit then
+
+ my-address my-space regs-offset + /device " map-in" $call-parent to regs-adr
+ regs-adr h# c.0000 + c@ ( id0 )
+
+ dup 0<> swap h# ff <> and ( writable? )
+
+ dup if write-enable else unmap-regs then
+;
+
+warning @ warning off \ Intentional chained definition
+: close ( -- ) unmap-regs close ;
+warning !
+
+: >lpc-adr ( offset -- ) device-base + ;
+: jedec! ( byte -- ) h# 5555 >lpc-adr c! ;
+
+\ The write enable for the block at fffx.0000 is at ffbx.0002
+: write-enable-block ( offset -- )
+ h# ffff invert and 2 or ( we-offset )
+ regs-adr + 0 swap c!
+;
+
+: write-setup ( -- ) h# aa jedec! h# 55 h# 2aaa >lpc-adr c! ;
+
+: lpc! ( byte offset -- )
+ over h# ff = if 2drop exit then
+ >lpc-adr ( byte lpc-adr )
+ write-setup h# a0 jedec! ( byte lpc-adr )
+ 2dup c! ( byte lpc-adr )
+ begin 2dup c@ = until 2drop ( )
+;
+
+: wait-toggle ( -- )
+ device-base c@ ( value )
+ begin device-base c@ tuck = until ( value )
+ drop
+;
+: erase-block ( offset -- )
+ dup write-enable-block
+ write-setup h# 80 jedec!
+ write-setup h# 50 swap >lpc-adr c!
+ wait-toggle
+;
+
+: flash-read ( adr len offset -- )
+ device-base + -rot move
+;
+: flash-verify ( adr len offset -- )
+ device-base + -rot comp
+ abort" LPC FLASH verify failed"
+;
+
+: flash-write ( adr len offset -- )
+ -rot bounds ?do ( offset )
+ i c@ over lpc! 1+ ( offset' )
+ loop ( offset )
+ drop
+;
+: write-block ( adr len offset -- )
+ dup erase-block ( adr len offset )
+ flash-write
+;
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2008 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