Author: wmb Date: Fri Jun 25 01:23:28 2010 New Revision: 1832 URL: http://tracker.coreboot.org/trac/openfirmware/changeset/1832
Log: OLPC - support for wireless NANDblaster on XO-1.5 (also affected XO-1 code through refactoring).
Added: cpu/x86/pc/olpc/nbrx.fth cpu/x86/pc/olpc/via/nbrx.fth dev/mmc/sdhci/mv8686/ring.fth Modified: cpu/x86/pc/olpc/fw.bth cpu/x86/pc/olpc/mcastnand.bth cpu/x86/pc/olpc/nandcastui.fth cpu/x86/pc/olpc/versions.fth cpu/x86/pc/olpc/via/fsupdate.fth cpu/x86/pc/olpc/via/fw-version.fth cpu/x86/pc/olpc/via/fw.bth cpu/x86/pc/olpc/via/mcastnand.bth cpu/x86/pc/olpc/via/mcnand-version.fth cpu/x86/pc/olpc/via/olpc.bth cpu/x86/pc/olpc/via/wlan-version.fth cpu/x86/pc/olpc/wifichannel.fth dev/libertas.fth dev/mmc/sdhci/mv8686/mv8686.bth dev/mmc/sdhci/mv8686/mv8686.fth dev/mmc/sdhci/sdhci.fth dev/mmc/sdhci/sdmmc.fth dev/usb2/device/wlan/usb8388.fth
Modified: cpu/x86/pc/olpc/fw.bth ============================================================================== --- cpu/x86/pc/olpc/fw.bth Fri Jun 25 01:01:24 2010 (r1831) +++ cpu/x86/pc/olpc/fw.bth Fri Jun 25 01:23:28 2010 (r1832) @@ -466,6 +466,7 @@ fload ${BP}/cpu/x86/bootascall.fth fload ${BP}/cpu/x86/pc/olpc/nandcastui.fth fload ${BP}/cpu/x86/pc/olpc/wifichannel.fth +fload ${BP}/cpu/x86/pc/olpc/nbrx.fth fload ${BP}/cpu/x86/pc/olpc/fsupdate.fth
fload ${BP}/ofw/inet/sntp.fth @@ -672,6 +673,7 @@ \ " wifi media lab 802.11" eval \ " flash http:\18.85.46.172\new.rom" eval ; +: urom " flash! u:\new.rom" eval ;
\ Fancy battery charge logger. fload ${BP}/cpu/x86/pc/olpc/charge.fth
Modified: cpu/x86/pc/olpc/mcastnand.bth ============================================================================== --- cpu/x86/pc/olpc/mcastnand.bth Fri Jun 25 01:01:24 2010 (r1831) +++ cpu/x86/pc/olpc/mcastnand.bth Fri Jun 25 01:23:28 2010 (r1832) @@ -5,6 +5,7 @@
fload ${BP}/cpu/x86/pc/olpc/versions.fth
+1 [if] " ${MCNAND_VERSION}" expand$ " test" $= [if] " multicast-nand/Makefile" $file-exists? 0= [if] " git clone -q git://dev.laptop.org/users/wmb/multicast-nand" expand$ $sh @@ -18,6 +19,10 @@ [then]
" (cd multicast-nand; make BPDIR=../../../../../.. nandblaster_rx.bin nandblaster_tx.bin; cp nandblaster_rx.bin nandblaster_tx.bin ..)" expand$ $sh +[else] +" (cd /home/wmb/Git/multicast-nand; make BPDIR=/home/wmb/ofw.test nandblaster15_rx.bin nandblaster_rx.bin nandblaster_tx.bin;)" $sh +" cp /home/wmb/Git/multicast-nand/*blaster*.bin ." expand$ $sh +[then]
\ This forces the creation of a .log file, so we don't re-fetch writing mcastnand.version
Modified: cpu/x86/pc/olpc/nandcastui.fth ============================================================================== --- cpu/x86/pc/olpc/nandcastui.fth Fri Jun 25 01:01:24 2010 (r1831) +++ cpu/x86/pc/olpc/nandcastui.fth Fri Jun 25 01:23:28 2010 (r1832) @@ -1,11 +1,6 @@ -purpose: User interface for NAND multicast updater +purpose: User interface for NAND multicast updater - transmission \ See license at end of file
-\ Number of blocks NANDblaster read in zdata mode -\ nb_rx will set this using the interpret client service. --1 value nb-zd-#sectors -: set-nb-zd-#sectors ( n -- ) to nb-zd-#sectors ; - : mesh-ssids ( -- $ ) " olpc-mesh"nolpc-mesh"nolpc-mesh"nolpc-mesh"nolpc-mesh"nolpc-mesh" ; @@ -36,12 +31,6 @@
d# 20 value redundancy
-: #nb ( channel# -- ) - depth 1 < abort" Usage: channel# #nb" - secure$ rot - -1 to nb-zd-#sectors - " rom:nb_rx ether:%d %s" sprintf boot-load go -; : #nb-clone ( channel# -- ) depth 1 < abort" Usage: channel# #nb-clone" redundancy swap @@ -84,48 +73,60 @@ : nb-secure6 ( -- ) 6 #nb-secure-def ; : nb-secure11 ( -- ) d# 11 #nb-secure-def ;
-: nb1 ( -- ) 1 #nb ; -: nb6 ( -- ) 6 #nb ; -: nb11 ( -- ) d# 11 #nb ; - : mesh-clone use-mesh false to already-go? redundancy " boot rom:nb_tx udp:239.255.1.2 nand: %d" sprintf eval ;
-: meshnand - use-mesh - false to already-go? - " boot rom:nb_rx ,,239.255.1.2" eval -; +\ This sender is for multicast operation over a wired network. +\ It is rarely used, because the wired multicast mode is primarily +\ used in the factory with a big server as the sender. +\ Example: wired-nb-tx: u:\os201.zd 224.0.0.2 +: wired-nb-tx: ( "filename" "multicast-ip-address" -- ) + false to already-go? + safe-parse-word safe-parse-word + " boot rom:nb_tx udp:%s %s 20 131072" sprintf eval +; + +\ This sends to XO-1.5 receivers, but the sender itself can run on either XO-1 or XO-1.5. +\ On XO-1, you must load the special "thin" firmware from a USB stick. +: nb15-tx: ( "filename" "channel" "redundancy" -- ) + " /wlan" find-package 0= abort" No /wlan device" ( phandle ) + + " thin" rot get-package-property if ( ) + \ Absence of "thin" property means we need to get special firmware + " u:\usb8388t.bin" " wlan-fw" $setenv + else ( adr len ) + \ Presence of "thin" property means we are good to go + 2drop + then
-: nb-xx false to already-go? - boot-as-call( - " boot rom:nb_rx ,,239.255.1.2" eval - )boot-as-call -; -: $nb-rx ( multicast-ip$ -- ) - false to already-go? - boot-as-call( - ( multicast-ip$ ) " boot rom:nb_rx mcast:%s" sprintf eval - )boot-as-call -; -: nb-rx: ( "multicast-ip" -- ) - safe-parse-word $nb-rx -; -: nb-rx ( -- ) " 224.0.0.100" $nb-rx ;
-: ucastnand - false to already-go? - " boot rom:nb_rx 10.20.0.16,,10.20.0.44" eval -; -: nbit ( "filename" -- ) - false to already-go? - safe-parse-word - " boot rom:nb_tx udp:239.255.1.2 %s 20 131072" sprintf eval + safe-parse-word ( filename$ ) + safe-parse-word 2>r ( filename$ r: channel$ ) + parse-word ( filename$ redundancy$ r: channel$ ) + dup 0= if 2drop " 20" then ( filename$ redundancy$' r: channel$ ) + 2swap 2r> ( redundancy$ filename$ channel$ ) + + " boot rom:nb_tx thinmac:OLPC-NANDblaster,%s %s %s 131072" sprintf eval +; + +[ifdef] use-nb15-precomputed +\ NANDblaster sender using thin firmware on XO-1.5, with precomputed +\ packet data. This turns out to be useless because the packets can +\ be computed on-the-fly faster than the module can send. +: nb15-precomputed: ( "filename" ["delay"]-- ) + false to already-go? + safe-parse-word ( name$ ) + safe-parse-word 2>r ( name$ r: channel$ ) + parse-word 2swap ( delay$ name$ r: channel$ ) + 2r> + " u:\usb8388t.bin" " wlan-fw" $setenv + " boot rom:blaster thinmac:OLPC-NANDblaster,%s %s %s" sprintf eval ; +[then]
\ LICENSE_BEGIN \ Copyright (c) 2008 FirmWorks
Added: cpu/x86/pc/olpc/nbrx.fth ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ cpu/x86/pc/olpc/nbrx.fth Fri Jun 25 01:23:28 2010 (r1832) @@ -0,0 +1,53 @@ +purpose: User interface for NAND multicast updater - reception +\ See license at end of file + +: #nb ( channel# -- ) + depth 1 < abort" Usage: channel# #nb" + secure$ rot + " rom:nb_rx ether:%d %s" sprintf boot-load go +; +: meshnand + use-mesh + false to already-go? + " boot rom:nb_rx ,,239.255.1.2" eval +; + +: ucastnand + false to already-go? + " boot rom:nb_rx 10.20.0.16,,10.20.0.44" eval +; + +: nb1 ( -- ) 1 #nb ; +: nb6 ( -- ) 6 #nb ; +: nb11 ( -- ) d# 11 #nb ; + +: nandblaster ( -- ) + find-multinand-server abort" No multicast NAND server" ( chan# ) + #nb +; +alias nb nandblaster + + +\ 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
Modified: cpu/x86/pc/olpc/versions.fth ============================================================================== --- cpu/x86/pc/olpc/versions.fth Fri Jun 25 01:01:24 2010 (r1831) +++ cpu/x86/pc/olpc/versions.fth Fri Jun 25 01:23:28 2010 (r1832) @@ -2,7 +2,7 @@
\ The overall firmware revision macro: FW_MAJOR E -macro: FW_MINOR 44 +macro: FW_MINOR 44b
\ The EC microcode macro: EC_VERSION e34
Modified: cpu/x86/pc/olpc/via/fsupdate.fth ============================================================================== --- cpu/x86/pc/olpc/via/fsupdate.fth Fri Jun 25 01:01:24 2010 (r1831) +++ cpu/x86/pc/olpc/via/fsupdate.fth Fri Jun 25 01:23:28 2010 (r1832) @@ -216,12 +216,12 @@ : fs-update ( "devspec" -- ) load-crypto abort" Can't load hash routines"
- false to secure-fsupdate? ( ) - safe-parse-word r/o open-file ( fd ) - abort" Can't open file" ( fd ) - open-nand ( )
+ false to secure-fsupdate? ( ) + safe-parse-word r/o open-file ( fd error? ) + " Can't open file" ?nand-abort ( fd ) + linefeed over force-line-delimiter ( fd )
t( ( fd ) @@ -291,11 +291,9 @@ : try-fs-update ( -- ) ." Searching for a NAND file system update image." cr " disk: ext:" fs-update-from-list -[ifdef] Later ." Trying NANDblaster" cr ['] nandblaster catch 0= if exit then " http:\172.18.0.1" fs-update-from-list -[then] ;
: $update-nand ( devspec$ -- )
Modified: cpu/x86/pc/olpc/via/fw-version.fth ============================================================================== --- cpu/x86/pc/olpc/via/fw-version.fth Fri Jun 25 01:01:24 2010 (r1831) +++ cpu/x86/pc/olpc/via/fw-version.fth Fri Jun 25 01:23:28 2010 (r1832) @@ -1,3 +1,3 @@ \ The overall firmware revision macro: FW_MAJOR A -macro: FW_MINOR 40 +macro: FW_MINOR 40b
Modified: cpu/x86/pc/olpc/via/fw.bth ============================================================================== --- cpu/x86/pc/olpc/via/fw.bth Fri Jun 25 01:01:24 2010 (r1831) +++ cpu/x86/pc/olpc/via/fw.bth Fri Jun 25 01:23:28 2010 (r1832) @@ -81,7 +81,6 @@ fload ${BP}/ofw/core/showlist.fth \ Linked list display tool fload ${BP}/ofw/core/allocph1.fth \ S Physical memory allocator fload ${BP}/ofw/core/availpm.fth \ Available memory list -fload ${BP}/ofw/core/allocmor.fth \ Secondary allocator
fload ${BP}/cpu/x86/pc/rootnode.fth \ Platform-specific root node changes
@@ -517,7 +516,7 @@
fload ${BP}/cpu/x86/bootascall.fth fload ${BP}/cpu/x86/pc/olpc/nandcastui.fth -fload ${BP}/cpu/x86/pc/olpc/wifichannel.fth +fload ${BP}/cpu/x86/pc/olpc/via/nbrx.fth fload ${BP}/cpu/x86/pc/olpc/via/blockfifo.fth fload ${BP}/cpu/x86/pc/olpc/via/fsupdate.fth fload ${BP}/cpu/x86/pc/olpc/via/fsverify.fth
Modified: cpu/x86/pc/olpc/via/mcastnand.bth ============================================================================== --- cpu/x86/pc/olpc/via/mcastnand.bth Fri Jun 25 01:01:24 2010 (r1831) +++ cpu/x86/pc/olpc/via/mcastnand.bth Fri Jun 25 01:23:28 2010 (r1832) @@ -21,7 +21,7 @@ " (cd multicast-nand; make BPDIR=../../../../../../.. nandblaster15_rx.bin nandblaster_tx.bin; cp nandblaster15_rx.bin nandblaster_tx.bin ..)" expand$ $sh [else] " (cd /home/wmb/Git/multicast-nand; make BPDIR=/home/wmb/ofw.test nandblaster15_rx.bin nandblaster_tx.bin;)" $sh -" cp /home/wmb/Git/multicast-nand/nandblaster*.bin ." expand$ $sh +" cp /home/wmb/Git/multicast-nand/*blaster*.bin ." expand$ $sh [then]
\ This forces the creation of a .log file, so we don't re-fetch
Modified: cpu/x86/pc/olpc/via/mcnand-version.fth ============================================================================== --- cpu/x86/pc/olpc/via/mcnand-version.fth Fri Jun 25 01:01:24 2010 (r1831) +++ cpu/x86/pc/olpc/via/mcnand-version.fth Fri Jun 25 01:23:28 2010 (r1832) @@ -3,6 +3,6 @@ \ With a specific ID, mcastnand.bth will download a tarball without .git stuff. \ With "test", mcastnand.bth will clone the git head if build/multicast-nand/ \ is not already present, then you can modify the git subtree as needed. -macro: MCNAND_VERSION 1eaa6e5822104b58cd933d33724a550ee1778943 +macro: MCNAND_VERSION d1b388bcdf01f98a7b94bb62d0d3f1403fd27d1a \ macro: MCNAND_VERSION test \ macro: MCNAND_VERSION HEAD
Added: cpu/x86/pc/olpc/via/nbrx.fth ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ cpu/x86/pc/olpc/via/nbrx.fth Fri Jun 25 01:23:28 2010 (r1832) @@ -0,0 +1,99 @@ +purpose: User interface for NAND multicast updater - reception +\ See license at end of file + +\ nb-zd-#sectors is the number of blocks that NANDblaster read in zdata mode +\ nb15_rx calls set-nb-zd-#sectors via the interpret client service. +-1 value nb-zd-#sectors +: set-nb-zd-#sectors ( n -- ) to nb-zd-#sectors ; + +\ This is the wireless version +: nandblaster ( -- ) + false to already-go? + -1 to nb-zd-#sectors + " boot rom:nb15_rx ssid:OLPC-NANDblaster" sprintf eval +; +alias nb nandblaster + + +\ This is the wired version that is used in the factory with big Ethernet switches. +: $nb-rx ( multicast-ip$ -- ) + false to already-go? + boot-as-call( + ( multicast-ip$ ) " boot rom:nb15_rx mcast:%s" sprintf eval + )boot-as-call +; +: nb-rx: ( "multicast-ip" -- ) + safe-parse-word $nb-rx +; +: nb-rx ( -- ) " 224.0.0.100" $nb-rx ; + +[ifdef] adhoc-NANDblaster +\ The adhoc version doesn't work well +: nba ( "filename" -- ) + false to already-go? + safe-parse-word + " boot rom:nb_tx adhoc:OLPC-NANDblaster,239.255.1.2,1 %s 20 131072" sprintf eval +; +: rnba ( -- ) + false to already-go? + -1 to nb-zd-#sectors + " boot rom:nb15_rx adhoc:OLPC-NANDblaster,239.255.1.2" sprintf eval +; +: lnba ( "filename" -- ) + false to already-go? + safe-parse-word + " load rom:nb_tx adhoc:OLPC-NANDblaster,239.255.1.2,1 %s 20 131072" sprintf eval +; +[then] + +create NB-sniffing +[ifdef] NB-sniffing +\ nbcount tests whether the receiver can keep up with the sender +0 value nb-ih +0 value #frames +: mcopen + " net:force" open-dev to nb-ih + nb-ih 0= abort" Can't open net" + " OLPC-NANDblaster" $essid + " do-associate" nb-ih $call-method drop + " "(01 00 5e 7f 01 02)" " set-multicast" nb-ih $call-method +; +: mcclose ( -- ) nb-ih close-dev 0 to nb-ih ; +: nbcount ( -- ) + mcopen cr + begin + load-base d# 2000 " read" nb-ih $call-method + -2 <> if + 1 #frames +! + #frames @ d# 100 /mod drop 0= if + #frames @ .d (cr + then + then + key? until key drop + mcclose +; +[then] + +\ LICENSE_BEGIN +\ Copyright (c) 2010 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: cpu/x86/pc/olpc/via/olpc.bth ============================================================================== --- cpu/x86/pc/olpc/via/olpc.bth Fri Jun 25 01:01:24 2010 (r1831) +++ cpu/x86/pc/olpc/via/olpc.bth Fri Jun 25 01:23:28 2010 (r1832) @@ -186,7 +186,7 @@ " ${BP}/cpu/x86/pc/olpc/images/leds.di" $add-file " ${BP}/cpu/x86/pc/olpc/images/ebook.di" $add-file
- " ${BP}/cpu/x86/pc/olpc/via/build/nandblaster15_rx.bin" " nb_rx" $add-deflated-dropin + " ${BP}/cpu/x86/pc/olpc/via/build/nandblaster15_rx.bin" " nb15_rx" $add-deflated-dropin " ${BP}/cpu/x86/pc/olpc/via/build/nandblaster_tx.bin" " nb_tx" $add-deflated-dropin
.( Dropin top is ) ofd @ fsize .x cr
Modified: cpu/x86/pc/olpc/via/wlan-version.fth ============================================================================== --- cpu/x86/pc/olpc/via/wlan-version.fth Fri Jun 25 01:01:24 2010 (r1831) +++ cpu/x86/pc/olpc/via/wlan-version.fth Fri Jun 25 01:23:28 2010 (r1832) @@ -4,3 +4,4 @@ \ Alternate command for getting WLAN firmware, for testing new versions. \ Temporarily uncomment the line and modify the path as necessary \ macro: GET_WLAN cp "/c/Documents and Settings/Mitch Bradley/My Documents/OLPC/DiskImages/sd8686-9.70.7.p0.bin" sd8686.bin; cp "/c/Documents and Settings/Mitch Bradley/My Documents/OLPC/DiskImages/sd8686_helper.bin" sd8686_helper.bin +\ macro: GET_WLAN wget http://dev.laptop.org/pub/firmware/libertas/thinfirm/lbtf_sdio-9.0.7.p1.bin -O sd8686.bin
Modified: cpu/x86/pc/olpc/wifichannel.fth ============================================================================== --- cpu/x86/pc/olpc/wifichannel.fth Fri Jun 25 01:01:24 2010 (r1831) +++ cpu/x86/pc/olpc/wifichannel.fth Fri Jun 25 01:23:28 2010 (r1832) @@ -176,11 +176,6 @@ search-channels close-wlan ; -: nandblaster ( -- ) - find-multinand-server abort" No multicast NAND server" ( chan# ) - #nb -; -alias nb nandblaster
d# 1514 buffer: mesh-test-buf
Modified: dev/libertas.fth ============================================================================== --- dev/libertas.fth Fri Jun 25 01:01:24 2010 (r1831) +++ dev/libertas.fth Fri Jun 25 01:23:28 2010 (r1832) @@ -196,6 +196,8 @@ 1 field >tx-pwr 1 field >tx-delay \ in 2ms 1+ + 0 field >tx-pkt-no-mesh +dup constant /tx-hdr-no-mesh 1+ \ tx-mesh must be 0 1+ \ tx-mesh must be 0 1 field >tx-mesh-ttl @@ -204,6 +206,7 @@ constant /tx-hdr
0 constant tx-ctrl \ Tx rates, etc +: set-tx-ctrl ( n -- ) to tx-ctrl ;
\ The Libertas FW is currently abusing the WDS flag to mean "send on the mesh". \ At some point a separate mesh flag might be defined ... @@ -211,19 +214,32 @@
: mesh-on? ( -- flag ) tx-ctrl TX_WDS and 0<> ;
-: wrap-msg ( adr len -- adr' len' ) - outbuf /tx-hdr erase ( adr len ) - over outbuf >tx-mac /mac-adr move ( adr len ) +: (wrap-msg-thin) ( adr len dst-mac-adr -- adr' len' ) + outbuf /tx-hdr erase ( adr len dst-mac-adr ) + outbuf >tx-mac /mac-adr move ( adr len ) + dup outbuf >tx-len le-w! ( adr len ) + tuck outbuf >tx-pkt-no-mesh swap move ( len ) + + /tx-hdr-no-mesh 4 - outbuf >tx-offset le-l! ( len ) \ Offset from >tx-ctrl field + tx-ctrl outbuf >tx-ctrl le-l! ( len ) + + outbuf swap /tx-hdr-no-mesh + ( adr' len' ) +; +: (wrap-msg) ( adr len dst-mac-adr -- adr' len' ) + outbuf /tx-hdr erase ( adr len dst-mac-adr ) + outbuf >tx-mac /mac-adr move ( adr len ) dup outbuf >tx-len le-w! ( adr len ) tuck outbuf >tx-pkt swap move ( len )
- /tx-hdr 4 - outbuf >tx-offset le-l! ( len ) \ Offset from >tx-ctrl field + /tx-hdr 4 - outbuf >tx-offset le-l! ( len ) \ Offset from >tx-ctrl field tx-ctrl outbuf >tx-ctrl le-l! ( len )
mesh-on? if 1 outbuf >tx-mesh-ttl c! then ( len )
outbuf swap /tx-hdr + ( adr' len' ) ; +: wrap-802.11 ( adr len -- adr' len' ) over 4 + (wrap-msg-thin) ; +: wrap-msg ( adr len -- adr' len' ) over (wrap-msg) ;
\ ========================================================================= \ Receive Packet Descriptor @@ -388,6 +404,10 @@ 0075 of ." CMD_802_11_SUBSCRIBE_EVENT" endof 0076 of ." CMD_802_11_RATE_ADAPT_RATESET" endof 007f of ." CMD_TX_RATE_QUERY" endof + 00a5 of ." CMD_SET_BOOT2_VER" endof \ Thin firmware only + 00b0 of ." CMD_802_11_BEACON_CTRL" endof \ Thin firmware only + 00cb of ." CMD_802_11_BEACON_SET" endof \ Thin firmware only + 00cc of ." CMD_802_11_SET_MODE" endof \ Thin firmware only ( default ) ." Unknown command: " dup u. endcase cr @@ -421,11 +441,27 @@
: .event ?cr ." Event: " type cr ; 0 instance value last-event +0 instance value backlog : process-ind ( adr len -- ) drop true to got-indicator? 4 + le-l@ dup to last-event + dup h# 10000 u>= if ( event-code ) + \ TX feedback from thin firmware + backlog 1- 0 max to backlog ( event-code ) + \ Cozybit asked for this test to help debug the thin firmware + lbsplit 2swap 2drop ( retrycnt failure ) + ?dup if ( retrycnt failure ) + cr ." Failure code 0x" base @ hex swap . base ! cr + then ( retrycnt ) + dup d# 10 <> if ( retrycnt ) + cr ." Retry count (decimal) " base @ decimal over . base ! cr + then ( retrycnt ) + drop + exit + then case + h# 37 of endof \ Beacon sent - Handle this silently h# 00 of " Tx PPA Free" .event endof \ n h# 01 of " Tx DMA Done" .event endof \ n h# 02 of " Link Loss with scan" .event process-disconnect endof @@ -608,7 +644,7 @@ 8 h# 4d ( CMD_802_11_MAC_ADDRESS ) prepare-cmd ACTION_SET +xw mac-adr$ +x$ - outbuf-wait if exit then + outbuf-wait drop ;
: marvel-get-mc-address ( -- ) @@ -626,7 +662,7 @@ to #mc-adr ( adr len ) 2dup +x$ \ Multicast addresses mc-adrs swap move - outbuf-wait if exit then + outbuf-wait drop ;
\ ========================================================================= @@ -663,11 +699,77 @@ \ Miscellaneous control settings \ =========================================================================
+: set-boot2-version ( version -- ) \ Thin firmware only + 4 h# a5 ( CMD_SET_BOOT2_VER ) prepare-cmd + 0 +xw ( version ) + +xw ( ) + outbuf-wait drop +; +: set-boot2-from-usb ( -- ) \ Thin firmware only + " release" get-my-property 0= if + decode-int nip nip set-boot2-version + then +; +: set-mode ( mode -- ) \ Thin firmware only - 0 is passive, 1 is sta, 2 is ap + 2 h# cc ( CMD_SET_MODE ) prepare-cmd + +xw + outbuf-wait drop +; +: set-ap-mode ( -- ) 2 set-mode ; \ Thin firmware only + +: broadcast-mac$ ( -- adr len ) " "(ff ff ff ff ff ff)" ; + +: make-beacon ( -- ) + h# cb ( CMD_802_11_BEACON_SET ) start-cmd ( ) + ssid$ nip d# 66 + +xw \ Length of the following, including SSID len + + h# 0080 +xw \ Frame type/subtype - management, beacon + 0 +xw \ duration + broadcast-mac$ +x$ \ destination MAC + mac-adr$ +x$ \ source MAC + mac-adr$ +x$ \ BSS MAC + 0 +xw \ Sequence number + 0 +xl 0 +xl \ 8-byte timestamp + d# 100 +xw \ Beacon interval + cap +xw \ Capability mask + + 0 +xb \ element ID = SSID + ssid$ dup +xb \ length ( adr len ) + ( adr len ) +x$ \ SSID + + 1 +xb \ element ID = Supported rates + 8 +xb \ length + 2 +xb 4 +xb d# 11 +xb d# 22 +xb \ 1 2 5.5 11 Mb/sec + d# 12 +xb d# 18 +xb d# 24 +xb d# 36 +xb \ 6 9 12 18 Mb/sec + + 3 +xb \ element ID = DS parameter set + 1 +xb \ length + channel +xb \ Channel number + + 5 +xb \ element ID = TIM (Traffic Indicator Map) parameter set + 4 +xb \ length + 1 +xb \ DTIM Count + 2 +xb \ DTIM Period + 0 +xb \ Bitmap control + 0 +xb \ Bitmap + + d# 42 +xb \ element ID = ERP info + 1 +xb \ length + 0 +xb \ no non-ERP stations, do not use protection, short or long preambles + + d# 50 +xb \ element ID = Extended supported rates + 4 +xb \ length + d# 48 +xb d# 72 +xb d# 96 +xb d# 108 +xb \ 24 36 48 54 Mb/sec + finish-cmd + + outbuf-wait drop +; + : set-radio-control ( -- ) 4 h# 1c ( CMD_802_11_RADIO_CONTROL ) prepare-cmd ACTION_SET +xw preamble 1 or +xw \ Preamble, RF on - outbuf-wait if exit then + outbuf-wait drop ;
: (set-bss-type) ( bsstype -- ok? ) @@ -701,7 +803,7 @@ 7 +xw \ Type = MrvlIETypes_DomainParam_t ( len ) dup +xw \ Length of payload ( adr len ) +x$ \ Country IE - outbuf-wait if exit then + outbuf-wait drop ;
: enable-11d ( -- ) @@ -710,7 +812,7 @@ 9 +xw \ Object = enable 11D 2 +xw \ Size of object 1 +xw \ Enable 11D - outbuf-wait if exit then + outbuf-wait drop ;
external @@ -748,7 +850,7 @@ mac-ctrl h# 20 invert and to mac-ctrl set-mac-control ; -: set-multicast ( adr len -- ) marvel-set-mc-address enable-multicast ; +: set-multicast ( adr len -- ) enable-multicast marvel-set-mc-address ;
: mac-off ( -- ) 0 to mac-ctrl set-mac-control 3 to mac-ctrl @@ -1014,7 +1116,7 @@ ( kinfo ) +xw \ Key info dup +xw \ Key length ( key$ ) +x$ \ key$ - finish-cmd outbuf-wait if exit then + finish-cmd outbuf-wait drop ;
external @@ -1132,7 +1234,7 @@ dup 1+ h# 11 ( CMD_802_11_AUTHENTICATE ) prepare-cmd ( target-mac$ ) +x$ \ Peer MAC address auth-mode +xb \ Authentication mode - outbuf-wait if exit then + outbuf-wait drop ;
: deauthenticate ( mac$ -- ) @@ -1149,7 +1251,7 @@ h# 82 h# 9b ( CMD_MESH_ACCESS ) prepare-cmd ( value cmd ) +xw +xl ( )
- outbuf-wait if exit then + outbuf-wait drop ; : mesh-access@ ( cmd -- value ) h# 82 h# 9b ( CMD_MESH_ACCESS ) prepare-cmd ( value cmd ) @@ -1182,7 +1284,7 @@ : mesh-stop ( -- error? ) mesh-on? if " " 0 0 0 mesh-config-set ( error? ) - tx-ctrl TX_WDS invert and to tx-ctrl ( error? ) + tx-ctrl TX_WDS invert and set-tx-ctrl ( error? ) ds-associated reset-driver-state ( error? ) else false ( error? ) @@ -1200,7 +1302,7 @@ then
dup 0= if ( error? ) - tx-ctrl TX_WDS or to tx-ctrl ( error? ) + tx-ctrl TX_WDS or set-tx-ctrl ( error? ) ds-associated set-driver-state ( error? ) then ( error? ) ; @@ -1263,7 +1365,7 @@
( target-mac$ ) +x$ \ Peer MAC address cap +xw \ Capability info: ESS, short slot, WEP - d# 10 +xw \ Listen interval + d# 300 +xw \ Listen interval d# 100 +xw \ Beacon period 1 +xb \ DTIM period
@@ -1352,7 +1454,11 @@ ?set-wep \ Set WEP keys again, if ktype is WEP set-mac-control 2dup authenticate - bss-type bss-type-managed = if (associate) else (join) then + d# 10 0 do + bss-type bss-type-managed = if (associate) else (join) then ( ok? ) + if true unloop exit then + loop + false ; headers
@@ -1390,6 +1496,16 @@ ." Current channel = " respbuf >fw-data 2 + le-w@ .d cr ;
+: set-rf-channel ( -- ) + d# 40 h# 1d ( CMD_802_11_RF_CHANNEL ) prepare-cmd + ACTION_SET +xw + channel +xw + 0 +xw \ rftype + 0 +xw \ reserved + " "(00 88 cc cb 20 8c 6d cc 60 40 25 cc 44 ce 76 cc 29 8e 42 c0 f2 ff ff ff 00 00 00 00 4c ce 76 cc)" +x$ \ channel list + outbuf-wait drop +; + : get-beacon ( -- interval enabled? ) 6 h# b0 ( CMD_802_11_BEACON_CTRL ) prepare-cmd ACTION_GET +xw @@ -1399,11 +1515,91 @@
: set-beacon ( interval enabled? -- ) 6 h# b0 ( CMD_802_11_BEACON_CTRL ) prepare-cmd - ACTION_SET +xw ( interval enabled? ) - +xw +xw + ACTION_SET +xw ( interval enabled? ) + 0<> 1 and +xw +xw ( ) outbuf-wait drop ;
+d# 24 constant /802.11-header +d# 1600 constant /packet-buf +/packet-buf buffer: packet-buf +0 instance value seq# + +\ The low byte of the frame type word is: +\ ssssTTpp +\ pp is protocol, always 00 +\ TT is type, 00 for management, 01 (i.e. 4) control, 10 (i.e. 8) data, 11 reserved +\ ssss is subtype +\ Management subtypes are: +\ 0000 (00) Association request +\ 0001 (10) Association response +\ 0010 (20) Reassociation request +\ 0011 (30) Reassociation response +\ 0100 (40) Probe request +\ 0101 (50) Probe response +\ 0110-0111 (60-70) Reserved +\ 1000 (80) Beacon +\ 1001 (90) ATIM +\ 1010 (a0) Disassociation +\ 1011 (b0) Authentication +\ 1100 (c0) Deauthentication +\ 1101-1111 (d0-f0) Reserved +\ Control subtypes are (other codes are reserved): +\ 1010 (a4) PS-Poll +\ 1011 (b4) RTS +\ 1100 (c4) CTS +\ 1101 (d4) ACK +\ 1110 (e4) CF End +\ 1111 (f4) CF End-ACK +\ Data subtypes are (other codes are reserved): +\ 0000 (08) Data +\ 0001 (18) Data+CF-ACK +\ 0010 (28) Data+CF-Poll +\ 0011 (38) Data+CF-ACK+CF-Poll +\ 0100 (48) Null (no data) +\ 0101 (58) CF-ACK (no data) +\ 0110 (68) CF-Poll (no data), +\ 0111 (78) CF-ACK+CF-Poll (no-data) + +: set-802.11-header ( adr3$ adr2$ adr1$ duration frame-type -- ) + packet-buf le-w! ( adr3$ adr2$ adr1$ duration ) + packet-buf 2+ le-w! ( adr3$ adr2$ adr1$ ) + packet-buf 4 + swap move ( adr3$ adr2$ ) + packet-buf d# 10 + swap move ( adr3$ ) + packet-buf d# 16 + swap move ( ) + seq# packet-buf d# 22 + le-w! ( ) + seq# h# 10 + to seq# ( ) \ The 4 LSBs are the fragment number +; +: +pkt-data ( offset -- adr ) packet-buf + /802.11-header + ; +: send-deauth ( -- ) + tx-ctrl >r h# 10 set-tx-ctrl + mac-adr$ mac-adr$ broadcast-mac$ 0 h# c0 set-802.11-header + h# 0002 0 +pkt-data le-w! \ Reason code: auth no longer valid + packet-buf /802.11-header 2 + wrap-802.11 ( adr len ) + data-out + r> set-tx-ctrl +; + +\ Howto set up access point: +\ ok setenv wlan-fw u:\usb8388t.bin \ Thin firmware +\ ok select /wlan:force +\ ok 1 " xoAP" start-ap + +: start-ap ( channel ssid$ -- ) + rot to channel ( ssid$ ) + to /ssid ( ssid-adr ) + ssid /ssid move ( ) + set-boot2-from-usb + marvel-get-mac-address drop + set-mac-control + 4 set-preamble set-radio-control \ auto preamble + set-rf-channel + set-ap-mode + marvel-set-mac-address + send-deauth + make-beacon + d# 100 1 set-beacon +;
: get-log ( -- ) 0 h# b ( CMD_802_11_GET_LOG ) prepare-cmd @@ -1738,6 +1934,108 @@ throw ;
+0 instance value /packet +: find-tag ( tag-id #fixed-params -- false | tag-adr tag-len true ) + +pkt-data ( tag-id adr ) + /packet over packet-buf - - ( tag-id adr len ) + begin dup while ( tag-id adr len ) + 2 pick 2 pick c@ = if ( tag-id adr len ) + drop nip ( adr ) + dup 2+ swap 1+ c@ ( tag-adr tag-len ) + true exit ( -- tag-adr tag-len true ) + then ( tag-id adr len ) + over 1+ c@ 2+ /string ( tag-id adr' len' ) + repeat ( tag-id adr len ) + 3drop false +; + +1 value association-id# +: associate-reply ( -- ) + cr ." S" cr + 0 4 find-tag 0= if exit then ( adr len ) \ Exit if SSID parameter is missing + ssid$ $= 0= if exit then ( ) \ Exit if SSID is wrong + + mac-adr$ mac-adr$ packet-buf d# 10 + 6 d# 314 h# 10 set-802.11-header + + cap 0 +pkt-data le-w! \ Capability mask + 0 2 +pkt-data le-w! \ Status - okay + association-id# h# 3fff and h# c000 or 4 +pkt-data le-w! \ + association-id# 1+ to association-id# + + " "(01 08 02 04 0b 16 0c 12 18 24 32 04 30 48 e0 ec)" ( tags-adr tags-len ) + tuck 6 +pkt-data swap move ( tags-size ) + packet-buf swap /802.11-header + 6 + wrap-802.11 ( adr len ) + data-out +; + +: authenticate-reply ( -- ) + cr ." U" cr + mac-adr$ mac-adr$ packet-buf d# 10 + 6 d# 314 h# b0 set-802.11-header + 0 0 +pkt-data le-w! \ Open system auth code + 2 +pkt-data le-w@ 1+ 2 +pkt-data le-w! \ auth seq# + 0 4 +pkt-data le-w! \ Status - okay + + packet-buf /802.11-header 6 + wrap-802.11 ( adr len ) + data-out +; + +defer handle-data ' noop is handle-data +: process-mgmt-frame ( -- ) + packet-buf /packet-buf read-force ( len ) + dup -2 = if drop exit then ( len ) + to /packet ( ) + + packet-buf c@ case ( type ) + h# 0 of associate-reply exit endof \ Association + h# 40 of exit endof \ Probe request + h# 48 of exit endof \ Null function + h# 50 of exit endof \ Probe response + h# b0 of authenticate-reply exit endof \ Authenticate + h# c0 of exit endof \ Deauthenticate + h# d4 of exit endof \ Acknowledgment + endcase + + handle-data +; +: dump-pkt ( -- ) + packet-buf /packet " no-page dump" evaluate +; +: run-ap ( -- ) + begin process-mgmt-frame key? until +; +: do-ap ( -- ) + ['] dump-pkt to handle-data + 1 " xxAP" start-ap + run-ap +; + +1 value delay +: throttle delay ms ; +\ Convert an 802.3 frame to an 802.11 frame and send it +: thin-send-data-frame ( adr len -- len ) + begin backlog 8 >= while process-mgmt-frame repeat + backlog 1+ to backlog + tuck over >r ( len adr len r: adr ) + \ In 208, 200 is the fromDS bit, indicating that the frame is ostensibly coming + \ from an AP, and 8 is the code for a non-acked Data frame. + mac-adr$ r@ 6 + 6 r> 6 0 h# 208 set-802.11-header ( len adr len ) + d# 12 /string ( len adr' elen ) + " "(aa aa 03 00 00 00)" 0 +pkt-data swap move ( len adr' elen ) + tuck 6 +pkt-data swap move ( len elen ) + packet-buf swap /802.11-header + 6 + wrap-802.11 ( len padr plen ) + data-out ( len ) + throttle +; + +d# 1600 buffer: test-buf +: send-test-pkt ( -- ) + h# 1c set-tx-ctrl + " "(01 00 5e 7f 01 02)" test-buf swap move + mac-adr$ test-buf 6 + swap move + " XO" test-buf d# 12 + swap move + test-buf d# 1440 thin-send-data-frame drop +; + : reset ( -- flag ) reset-nic ;
: (scan-wifi) ( -- error? )
Modified: dev/mmc/sdhci/mv8686/mv8686.bth ============================================================================== --- dev/mmc/sdhci/mv8686/mv8686.bth Fri Jun 25 01:01:24 2010 (r1831) +++ dev/mmc/sdhci/mv8686/mv8686.bth Fri Jun 25 01:23:28 2010 (r1832) @@ -11,7 +11,7 @@ FCode-version2
fload ${BP}/dev/mmc/sdhci/mv8686/common.fth \ Ethernet common variables and routines -fload ${BP}/dev/mmc/sdhci/mv8686/queue.fth \ Receive queue management +fload ${BP}/dev/mmc/sdhci/mv8686/ring.fth \ Receive ring management fload ${BP}/dev/mmc/sdhci/mv8686/sdio.fth \ SDIO interface routines fload ${BP}/dev/mmc/sdhci/mv8686/mv8686.fth \ SDIO I/O interface for Marvell 8686 fload ${BP}/dev/libertas.fth \ Marvell "Libertas" common code
Modified: dev/mmc/sdhci/mv8686/mv8686.fth ============================================================================== --- dev/mmc/sdhci/mv8686/mv8686.fth Fri Jun 25 01:01:24 2010 (r1831) +++ dev/mmc/sdhci/mv8686/mv8686.fth Fri Jun 25 01:23:28 2010 (r1832) @@ -4,6 +4,14 @@ headers hex
+" mv8686" encode-string " module-type" property + +\ This really depends on the firmware that we load, but we don't want +\ to load the firmware in advance, so we hardcode this, assuming that +\ the firmware we include with OFW has both thin and fullmac capability. +0 0 encode-bytes " thin" property +0 0 encode-bytes " fullmac" property + \ ======================================================================= \ Wireless environment variables \ wlan-fw e.g., rom:mv8686.bin, disk:\mv8686.bin
Added: dev/mmc/sdhci/mv8686/ring.fth ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ dev/mmc/sdhci/mv8686/ring.fth Fri Jun 25 01:23:28 2010 (r1832) @@ -0,0 +1,86 @@ +\ See license at end of file +purpose: Packet queue routines + +\ Maintain a ring of packets that were received while transmitting. + +\ Since the firmware mostly uses request/response protocols, the expected +\ queue length is either 0 or 1. But for NANDblaster, the queue can +\ get pretty large, because the incoming data rate is rather high. + +\ To avoid expensive dma-alloc and dma-free operations during reception, +\ we pre-allocate all the DMA space and manage it as a ring buffer. +\ Each slot in the ring is fixed length. The first word is the packet +\ length, followed by the data. + +\ The ring is empty when next-put == next-get . It is full when +\ advance(next-put) == next-get . The "wasted" ring slot is used +\ to handle the ring-full condition gracefully. When new-buffer is +\ called with the ring full, the empty slot at next-put is returned, +\ but when enque-buffer is subsequently called, if the ring is still +\ full, next-put is not updated, so that slot will be overwritten +\ the next time. + +d# 32 constant max#queued \ Toss old packets after this number +d# 1600 constant /packet-max +max#queued /packet-max * constant /ring + +0 instance value next-put +0 instance value next-get + +0 instance value rx-ring + +: init-queue ( -- ) + /ring dma-alloc to rx-ring + rx-ring to next-put + rx-ring to next-get +; + +: advance ( adr -- adr' ) + /packet-max + ( adr' ) + dup rx-ring /ring + = if ( adr ) + drop rx-ring ( adr' ) + then ( adr ) +; + +: drain-queue ( -- ) rx-ring /ring dma-free ; + +: new-buffer ( packet-length -- handle adr len ) + next-put ( packet-length handle ) + dup na1+ ( packet-length handle adr ) + rot /packet-max /n - min ( handle adr len ) + dup 3 pick ! ( handle adr len ) +; + +: enque-buffer ( handle -- ) + advance dup next-get <> if to next-put then +; + +: get-queued? ( -- false | adr len true ) + next-put next-get = if false exit then ( ) + next-get na1+ next-get @ true ( adr len true ) +; +: recycle-queued ( -- ) next-get advance to next-get ; + +\ LICENSE_BEGIN +\ Copyright (c) 2010 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/mmc/sdhci/sdhci.fth ============================================================================== --- dev/mmc/sdhci/sdhci.fth Fri Jun 25 01:01:24 2010 (r1831) +++ dev/mmc/sdhci/sdhci.fth Fri Jun 25 01:23:28 2010 (r1832) @@ -443,7 +443,6 @@ h# 211a 0 cmd ( ) \ CMD33 - R1 0 h# 261b 0 cmd \ CMD38 - R1b (wait for busy) intstat-off - true to writing? ;
\ CMD40 is MMC
Modified: dev/mmc/sdhci/sdmmc.fth ============================================================================== --- dev/mmc/sdhci/sdmmc.fth Fri Jun 25 01:01:24 2010 (r1831) +++ dev/mmc/sdhci/sdmmc.fth Fri Jun 25 01:23:28 2010 (r1832) @@ -70,7 +70,7 @@ label-package if 0 0 " offset" label-package $call-method to offset-high to offset-low else - ." Can't open disk label package" cr +\ ." Can't open disk label package" cr open-count 0= if deblocker close-package then
Modified: dev/usb2/device/wlan/usb8388.fth ============================================================================== --- dev/usb2/device/wlan/usb8388.fth Fri Jun 25 01:01:24 2010 (r1831) +++ dev/usb2/device/wlan/usb8388.fth Fri Jun 25 01:23:28 2010 (r1832) @@ -19,6 +19,13 @@ \ wlan-fw e.g., rom:usb8388.bin, disk:\usb8388.bin \ =======================================================================
+" mv8388" encode-string " module-type" property + +\ This really depends on the firmware that we load, but we don't want +\ to load the firmware in advance, so we hardcode this. It will need +\ to be changed if we bundle thin-capable firmware in OFW. +0 0 encode-bytes " fullmac" property + : wlan-fw ( -- $ ) " wlan-fw" " $getenv" evaluate if " rom:usb8388.bin" then ;
openfirmware@openfirmware.info