[openfirmware] [commit] r3743 - cpu/x86/pc/olpc/via/Notes

repository service svn at openfirmware.info
Fri Oct 31 06:29:39 CET 2014


Author: quozl
Date: Fri Oct 31 06:29:38 2014
New Revision: 3743
URL: http://tracker.coreboot.org/trac/openfirmware/changeset/3743

Log:
OLPC XO-4 - add EC recovery

Added:
   cpu/x86/pc/olpc/via/Notes/fix-ec-4.fth

Added: cpu/x86/pc/olpc/via/Notes/fix-ec-4.fth
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ cpu/x86/pc/olpc/via/Notes/fix-ec-4.fth	Fri Oct 31 06:29:38 2014	(r3743)
@@ -0,0 +1,542 @@
+purpose: Recover EC FLASH on XO-4 using cable from XO-1.5
+
+\ HOWTO USE THIS
+\ Put this file and an EC image (60416 bytes) on a USB stick, insert into XO-1.5
+\ Connect 6-pin programming cable from XO-1.5 recovery driver port (J3) to
+\ XO-4 EDI "REFLASH EC HEADER" (J2)
+\ Power on XO-1.5
+\ Power on XO-4
+\ ok fload u:\fix-ec-4.fth
+\ ok select /spi
+\ ok excavate-ec u:\old.bin
+\ ok recover-ec u:\new.bin
+
+dev /spi
+
+\ from cpu/arm/olpc/4.0/config.fth
+h# ec00 constant /ec-flash
+char 7 constant expected-ec-version
+h# eb80 constant ec-flags-offset
+
+: pio16mhz  ( -- )
+   h# 01 h# 6c spi-b!    \ 33/(2*1) MHz
+   h# 00 h# 6e spi-b!    \ No special clocking
+   h# 08 h# 6d spi-b!    \ Dynamic clock, PIO mode, command posted write off   
+;
+: pio1.5mhz  ( -- )
+   d# 11 h# 6c spi-b!    \ 33/(2*11) = 1.5 MHz
+   h# 00 h# 6e spi-b!    \ No special clocking
+   h# 08 h# 6d spi-b!    \ Dynamic clock, PIO mode, command posted write off   
+;
+
+: edi-go  ( -- )
+   h# 802 spi-cmd!    ( )  \ Set go bit
+   wait-done     ( )  \ Wait for done bit
+   0 spi-cmd!    ( )  \ Clear go bit
+   \ The go bit must be cleared before clear-done, otherwise clear-done will not work
+   clear-done    ( )  \ Clear done bit
+;
+
+variable access-count  0 access-count !
+variable out-ptr
+variable #in-bytes
+: spi-cs-on  ( -- )
+\   access-count @ 1 =  if  pio8mhz  2 access-count !  then
+\   access-count @ 0=  if  pio1.5mhz  1 access-count ! then
+   8 out-ptr !   0 #in-bytes !
+;
+: spi-out  ( b -- )  out-ptr @ spi-b!  1 out-ptr +!  ;
+: spi-cs-off  ( -- )
+   out-ptr @ 8 -                ( #out-bytes )
+   dup 0=  if  drop exit  then  ( #out-bytes )
+   #in-bytes @ +  8 lshift  2 or  spi-cmd!
+   wait-done
+   0 spi-cmd!
+   clear-done
+;
+: spi-in  ( -- b )
+   1 #in-bytes !
+   spi-cs-off
+   out-ptr @ spi-b@
+   8 out-ptr !
+;
+
+: edi-wait-b  ( -- b )
+   4 #in-bytes !
+   spi-cs-off
+   out-ptr @  #in-bytes @  bounds  ?do
+      i spi-b@ h# 50 =  if
+         i 1+ spi-b@  unloop exit
+      then
+   loop
+   true abort" Did not receive EDI data ready byte"
+;
+
+\ This cheats by assuming how long it takes for the data to return
+\ It's interesting as an example of how fast the hardware can go.
+: edi-really-fast-next-b@  ( -- b )
+   h# 33 8 spi-b!
+   h# 402 spi-cmd!  wait-done
+   0 spi-cmd!
+   clear-done
+   b spi-b@
+;
+
+
+\ *** Start of verbatim inclusion of edi.fth
+
+\ The following code depends on externally-provided low-level SPI bus
+\ access primitives that are defined in "bbedi.fth" for the "native"
+\ case (EC and CPU on the same machine).  They can also be implemented
+\ for tethered programming from a different machine like an XO-1.5.
+\
+\ Low-level primitives:
+\  spi-start  ( -- )      - Init SPI bus
+\  spi-cs-on  ( -- )      - Assert SPI-bus CS#
+\  spi-cs-off ( -- )      - Deassert SPI-bus CS#
+\  spi-out    ( byte -- ) - Send byte
+\  spi-in     ( -- byte ) - Receive byte
+
+0 value edi-chip-id
+: kb9010?  ( -- flag )  edi-chip-id 4 =  ;
+
+: efcfg    ( -- reg# )  kb9010?  if  h# fead  else  h# fea0   then  ;
+: efcmd    ( -- reg# )  kb9010?  if  h# feac  else  h# fea7   then  ;
+: efdat    ( -- reg# )  kb9010?  if  h# feab  else  h# feaa   then  ; \ io3731 has different read and write regs
+h# feab constant efdat-in
+: rst8051  ( -- reg# )  kb9010?  if  h# ff14  else  h# f010   then  ;
+: ecreboot ( -- reg# )  kb9010?  if  h# ff01  else  h# f018   then  ;
+\ Issues with .py code
+\ A14:A8 should be A15:A8 several places
+\ inconsistent use of handle vs gd.handle in edi_erase_chip
+
+\ KB9010 stuff...
+d# 59 d# 1024 * constant /kb9010-flash
+h# fe80 constant wdtcfg
+h# fe81 constant wdtpf
+h# fe82 constant wdt
+h# fea2 constant shccfg
+\ h# fea5 constant xbicfg \ Unused
+h# fea6 constant xbics
+\ h# feae constant efdatr \ Unused
+\ h# feaf constant emfburw
+h# feb2 constant xbiwp
+\ h# feb6 constant xbipump
+\ h# feb7 constant xbifm
+\ h# feb8 constant sbivr
+h# feb9 constant xbis
+h# ff0d constant clkcfg
+h# ff0f constant pllcfg
+h# ff1d constant ecsts
+h# ff1f constant pllcfg2
+h# ff14 constant pxcfg
+
+\ end KB9010 stuff...
+
+d# 128 constant /flash-page
+defer edi-progress  ' 2drop to edi-progress  ( offset size -- )
+
+: edi-cmd,adr  ( offset cmd -- )   \ Send command plus 3 address bytes
+   spi-cs-on     ( offset cmd )
+   spi-out       ( offset )
+   lbsplit drop  spi-out spi-out spi-out  ( )
+;
+: edi-b!  ( byte offset -- )  \ Write byte to address inside EC chip
+   h# 40 edi-cmd,adr spi-out spi-cs-off
+;
+[ifndef] edi-wait-b
+: edi-wait-b  ( -- b )  \ Wait for and receive EC response byte
+   d# 100 0  do
+      spi-in              ( d )
+      dup h# 5f <>  if    ( d )
+         dup h# 50 =  if  ( d )
+            drop
+            spi-in        ( b )
+            spi-cs-off    ( b )
+            unloop exit
+         then             ( d )
+         spi-cs-off       ( d )
+	 \ The setup in the CL4 has can also report zeros when inactive.
+         2dup h# ff = 00 = or abort" EDI byte in inactive"
+	 ." Unknown EDI byte in response: " .h cr
+         true abort" EDI byte in confused"
+      then                ( d )
+      drop
+   loop
+   spi-cs-off
+   true abort" EDI byte in timeout"
+;
+[then]
+: edi-b@  ( offset -- b )  \ Read byte from address inside EC chip
+   h# 30 edi-cmd,adr  edi-wait-b
+;
+: edi-next-b@  ( -- b )  \ Read the next EC byte - auto-increment address
+   spi-cs-on  h# 33 spi-out  edi-wait-b
+;
+: edi-disable  ( -- )  \ Turn off the EC EDI interface
+   spi-cs-on
+   h# f3 spi-out
+   spi-in      ( b )
+   spi-cs-off
+   h# 8c <>  if
+      ." Unexpected response from edi-disable" cr
+   then 
+;
+
+0 [if]
+: edi-w@  ( offset -- w )  \ Read 16-bit word from address inside EC chip
+   dup 1+  edi-b@         ( offset b.low )
+   swap edi-b@            ( b.low b.high )
+   bwjoin
+;
+[else]
+: edi-w@  ( offset -- w )  \ Read 16-bit word from address inside EC chip
+   edi-b@ edi-next-b@ swap bwjoin
+;
+[then]
+: reset-8051  ( -- )  \ Reset 8-5
+   rst8051 edi-b@  1 or  rst8051 edi-b!
+;
+: unreset-8051  ( -- )  \ Reset 8-5
+   rst8051 edi-b@  1 invert and  rst8051 edi-b!
+   d# 2000 ms
+;
+
+\ 0 in bit 0 selects masked ROM as code source for 8051, 1 selects FLASH
+\ The 8051 should be in reset mode when changing that bit.
+
+: select-flash  ( -- )  \ Setup for access to FLASH inside the EC
+   kb9010?  if  exit  then
+   h# f011 edi-b@  1 or  h# f011 edi-b!
+;
+
+: edi-read-id  ( -- id )
+   spi-cs-on  h# 3e spi-out  spi-in  spi-cs-off
+;
+
+: probe-rdid  ( -- found? )  \ Verify that the EC is the one we think it is
+   select-flash
+   h# f01c ['] edi-w@ catch  if   ( x )
+      drop false exit             ( -- false )
+   then                           ( id )
+
+   1 invert and  h# 3730 =
+;
+
+: finished?  ( b -- flag )
+   kb9010?  if  2 and 0=  else h# 80 and h# 80 =  then
+;
+: wait-flash-busy  ( -- )  \ Wait for an erase/programming operation to complete
+   get-msecs  h# 1000 +    ( limit )
+   begin                   ( limit )
+      efcfg edi-b@         ( limit b )
+      finished?  if        ( limit )
+         drop exit         ( -- )
+      then                 ( limit )
+      dup get-msecs - 0<=  ( limit timeout? )
+   until                   ( limit )
+   drop
+   true abort" EDI FLASH busy timeout"
+;
+
+: flash-cmd  ( b -- )  efcmd edi-b!  ;
+
+: set-offset  ( offset -- )
+   lbsplit drop                                   ( offset-low mid hi )
+   kb9010?  if  h# feaa edi-b!  else  drop  then  ( offset-low mid )
+   h# fea9 edi-b!  h# fea8 edi-b!                 ( )
+;
+
+: erase-page  ( offset -- )
+   wait-flash-busy     ( offset )
+   set-offset          ( )
+   h# 20 flash-cmd     ( )
+;
+
+: erase-chip  ( -- )  
+   0 set-offset  \ New code does this (and does not wait-flash-busy)
+   wait-flash-busy  h# 60 flash-cmd  wait-flash-busy
+;
+
+: send-byte  ( b offset -- )  set-offset  efdat edi-b!  2 flash-cmd  ;
+
+: edi-program-page  ( adr offset -- )
+   \ Clear HVPL
+   wait-flash-busy  h# 80 flash-cmd  ( adr offset )
+
+   wait-flash-busy                ( adr offset )  \ Necessary?
+
+   \ Fill the page buffer
+   swap  /flash-page  bounds  do  ( offset )
+      i c@  over  send-byte       ( offset )
+      1+                          ( offset' )
+   loop                           ( offset )
+   drop                           ( )
+
+   \ Commit the buffer to the FLASH memory
+   wait-flash-busy                ( )  \ Redundant wait?
+   h# 70 flash-cmd                ( )  \ Program page command
+   wait-flash-busy                ( )
+;
+
+: edi-program-flash  ( adr len offset -- )
+   cr                                          ( adr len offset )
+   swap  0  ?do                                ( adr offset )
+      (cr i .                                  ( adr offset )
+      dup i + ec-flags-offset <>  if           ( adr offset )
+         dup i + erase-page                    ( adr offset )
+         over i +  over i +  edi-program-page  ( adr offset )
+      then                                     ( adr offset )
+      i /ec-flash  edi-progress                ( adr offset )
+   /flash-page +loop                           ( adr offset )
+   2drop                                       ( )
+;
+: edi-read-flash  ( adr len offset -- )
+   over 0=  if  3drop exit  then  ( adr len offset )
+   edi-b@                         ( adr len byte )
+   third c!                       ( adr len )
+   1 /string  bounds  ?do         ( )
+      edi-next-b@ i c!            ( )
+   loop                           ( )
+;
+
+: trim@  ( offset -- b )
+   set-offset
+   h# 90 flash-cmd
+   wait-flash-busy
+   efdat-in edi-b@   \ reg: efdat
+;
+
+: trim-tune  ( -- )
+\   firmware-id  0=  if
+      \ Read trim data and write to register (for ENE macros)
+      h# 100 trim@  h# 5a =  if
+         \ Low Voltage Detect TRIM register
+         h# f035 edi-b@               ( val )
+         h# 1f invert and             ( val' )
+         h# 101 trim@ h# 1f and  or   ( val' )
+         h# f035 edi-b!               ( )
+
+         \ Int Oscillator Control register - HKCOMOS32K
+         h# f02b edi-b@               ( val )
+         h# 0f invert and             ( val' )
+         h# 102 trim@ h# 0f and  or   ( val' )
+         h# f02b edi-b!               ( )
+      then
+
+      \ Read trim data and write to register (for HHNEC macros)
+      h# 1ff trim@  0<>  if
+         \ XBIMISC register - S[4:0]
+         h# fea6 edi-b@               ( val )
+         h# 1f invert and             ( val' )
+         h# 1f0 trim@ h# 1f and  or   ( val' )
+         h# fea6 edi-b!               ( )
+         
+         \ XBI Pump IP register - Pdac[3:0] | Ndac[3:0]
+         h# 1f1 trim@ 4 lshift        ( val )
+         h# 1f2 trim@ h# 0f and or    ( val' )
+         h# fea3 edi-b!               ( )
+         
+         \ XBI Flash IP register - Bdac[3:0]
+         h# fea4 edi-b@               ( val )
+         h# 0f invert and             ( val' )
+         h# 1f4 trim@ h# 0f and  or   ( val' )
+         h# fea4 edi-b!               ( )
+         
+         \ XB VR IP register - Tctrim[3:0] | Abstrim[3:0]  (Vref temp coef and absolute value)
+         h# 1f5 trim@ 4 lshift        ( val )
+         h# 1f6 trim@ h# 0f and or    ( val' )
+         h# fea5 edi-b!               ( )
+         
+         \ XBI Flash IP register - Itim[3:0] - Must be last
+         h# fea4 edi-b@               ( val )
+         h# f0 invert and             ( val' )
+         h# 1f4 trim@ 4 lshift  or    ( val' )
+         h# fea4 edi-b!               ( )
+         
+         3 us  \ Required after Itim[3:0] update
+
+         \ XBI Embedded Flash Configuration register
+         h# 10 h# fea0 edi-b!    \ Set FLASH clock
+
+         h# fea0 edi-b@  h# d0  =  if
+            ." Warning - XBIECFG is 0xd0" cr
+         then
+      then
+\   then
+;
+: set-chip-id  ( -- )
+   ['] edi-read-id  catch  if        ( )
+       edi-read-id                   ( id )
+   then                              ( id )
+   to edi-chip-id
+;
+: kb9010-init  ( -- )
+   h# 00 xbics  edi-b!
+   h# 00 xbiwp  edi-b! \ Clear XBI write protection
+   h# ff wdt    edi-b! \ Disable WDT
+   h# 00 wdtcfg edi-b!
+   h# 00 wdtpf  edi-b!
+   h# 00 shccfg edi-b! \ Disable SHC
+   h# 0c clkcfg edi-b! \ Set the 8051 to 32Mhz
+   h# 08 efcfg  edi-b! \ Enable the embedded flash cmd mode
+;
+base @ hex
+create special-row     1f0 w,  1f1 w,  1f2 w,  1f4 w,  1f5 w,  1f6 w,  1f3 w,
+create dest-regs      feb9 w, feb6 w, feb6 w, feb7 w, feb8 w, feb8 w, feb7 w,
+create source-bits      1f c,   0f c,   0f c,   0f c,   07 c,   1f c,   0f c,
+create dest-bits        1f c,   f0 c,   0f c,   0f c,   e0 c,   1f c,   f0 c,
+create shift-cnt         0 c,    4 c,    0 c,    0 c,    5 c,    0 c,    4 c,
+base !
+: kb9010-trimtune  ( -- )
+   h# 1ff trim@  0<>  if
+      7 0  do
+         special-row i wa+ w@  edi-b@         ( data )
+         source-bits i ca+ c@  or             ( field )
+         shift-cnt   i ca+ c@  lshift         ( field' )
+         dest-regs   i wa+ w@  edi-b@         ( field dest )
+         dest-bits   i ca+ c@  invert and or  ( dest' )
+         dest-regs   i wa+ w@  edi-b!         ( )
+      loop
+      wait-flash-busy
+   then
+   h# 80 trim@  h# 5a =  if
+      ecsts edi-b@                   ( old-ecsts )
+      dup 4 or  ecsts edi-b!         ( old-ecsts )  \ chipid is now pllcfg2
+
+      xbis edi-b@  h# 3f and               ( old-ecsts xbis-bits )
+      h# 81 trim@ 3 and  6 lshift or       ( old-ecsts xbis-value )
+      xbis edi-b!                          ( old-ecsts )
+
+      h# 82 trim@ h# f and 4 lshift        ( old-ecsts pll-high )
+      h# 83 trim@ h# f0 and 4 rshift or    ( old-ecsts pll-value )
+      pllcfg edi-b!                        ( old-ecsts )
+
+      pllcfg2 edi-b@ h# 3f and             ( old-ecsts pll2-bits )
+      h# 82 trim@ h# 30 and 2 lshift or    ( old-ecsts pll2-value )
+      pllcfg2 edi-b!                       ( old-ecsts )
+      
+      ecsts edi-b!                         ( )
+   then
+;
+\ This is used to start EDI from routines where you do not want to
+\ put the EC into reset.  ie the mfg tag reading routines
+: edi-open-active  ( -- )
+   spi-start
+
+   \ Does a dummy ready and throws away the result.
+   \ required to get the EDI interface enabled
+   h# ff22 ['] edi-b@ catch 2drop
+
+   set-chip-id
+
+   select-flash
+;
+\ Full EDI startup sequece.  Used when you want to reprogram the EC.
+: edi-open  ( -- )
+   edi-open-active
+
+   reset-8051
+
+   kb9010?  if
+      kb9010-init
+      kb9010-trimtune
+   else
+      trim-tune
+   then
+;
+
+\ *** End of verbatim inclusion of edi.fth
+
+\ *** Start of selective inclusion of cpu/arm/olpc/ecflash.fth
+
+: check-signature  ( adr -- )
+   /ec-flash +  h# 100 -                                 ( adr' )
+   dup  " XO-EC" comp abort" Bad signature in EC image"  ( adr )
+   dup ." EC firmware version: " cscount type cr         ( adr )
+   dup 6 + c@ expected-ec-version <>  abort" Wrong EC version"  ( adr )
+   drop
+;
+
+: ?ec-image-valid  ( adr len -- )
+   dup /ec-flash <>  abort" Image file is the wrong size"   ( adr len )
+   over c@ h# 02 <>  abort" Invalid EC image - must start with 02"
+   2dup 0 -rot  bounds ?do  i l@ +  /l +loop    ( adr len checksum )
+   abort" Incorrect EC image checksum"          ( adr len )
+   over check-signature                         ( adr len )
+   2drop
+;
+
+0 value ec-file-loaded?
+: get-ec-file  ( "name" -- )
+   safe-parse-word  ." Reading " 2dup type cr
+   $read-open
+   load-base /ec-flash  ifd @ fgets  ( len )
+   ifd @ fclose                      ( len )
+   load-base swap ?ec-image-valid
+;
+
+\ Tells the EC to auto-restart after power cycling
+: set-ec-reboot  ( -- )  1 ecreboot edi-b!  ;
+
+: ignore-ec-flags  ( adr -- )  ec-flags-offset +  /flash-page  erase  ;
+: reflash-ec  ( -- )
+
+   pio1.5mhz
+   edi-open
+   ." Writing ..."  load-base /ec-flash 0 edi-program-flash cr
+   ." Verifying ..."
+   load-base /ec-flash + /ec-flash 0 edi-read-flash
+
+   load-base  ignore-ec-flags
+   load-base  /ec-flash +  ignore-ec-flags
+   load-base  load-base /ec-flash +  /ec-flash  comp
+   abort"  Miscompare!"
+   cr
+
+   ." Restarting EC" cr
+   set-ec-reboot
+   unreset-8051
+;
+: recover-ec  ( "filename" -- )  get-ec-file reflash-ec  ;
+
+: read-ec-flash  ( -- )
+   pio1.5mhz
+   edi-open
+   flash-buf /ec-flash 0 edi-read-flash
+;
+: excavate-ec  ( "name" -- )
+   safe-parse-word $new-file
+   read-ec-flash
+   load-base /ec-flash ofd @ fputs
+   ofd @ fclose
+;
+
+\ *** End of selective inclusion of cpu/arm/olpc/ecflash.fth
+
+dend
+
+
+\ LICENSE_BEGIN
+\ Copyright (c) 2014 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



More information about the openfirmware mailing list