[openfirmware] r1162 - dev/usb2/device
svn at openfirmware.info
svn at openfirmware.info
Wed Apr 29 19:50:29 CEST 2009
Author: wmb
Date: 2009-04-29 19:50:29 +0200 (Wed, 29 Apr 2009)
New Revision: 1162
Added:
dev/usb2/device/debugport.fth
Log:
Checked in debugport.fth
Added: dev/usb2/device/debugport.fth
===================================================================
--- dev/usb2/device/debugport.fth (rev 0)
+++ dev/usb2/device/debugport.fth 2009-04-29 17:50:29 UTC (rev 1162)
@@ -0,0 +1,291 @@
+purpose: Driver for USB 2.0 Debug Device via EHCI Debug Port
+
+\ USB PID values:
+\ Token: out e1 in 69 sof a5 setup 2d
+\ Data: data0 c3 data1 4b data2 87 mdata 0f
+\ Handshake: ack d2 nak 5a stall 1e nyet 96
+\ Special: pre/err 3c split 78 ping b4 reserved/unused f0
+
+0 value ehci-cfg \ Set to known value to skip search
+0 value dbgp-offset \ Set to known value to skip search
+0 value dbgp-bar \ Base address register that maps the DBGP
+
+0 value ebase
+0 value dbgp-base
+
+\ Only look on the main PCI host bridge ...
+: slot,fn> ( slot fn -- cfg-base ) swap d# 11 lshift swap 8 lshift or ;
+: find-ehci ( -- )
+ ehci-cfg if exit then
+ d# 32 0 do \ Scan all slot
+ i 0 slot,fn> config-l@ h# ffff.ffff <> if
+ 8 0 do
+ j i slot,fn> 8 + config-l@ ( class )
+ h# ffffff00 and h# 0c032000 = if ( )
+ j i slot,fn> to ehci-cfg ( )
+ unloop unloop exit
+ then
+ loop
+ then
+ loop
+ true abort" Can't find EHCI"
+;
+: find-dbgp-regs ( -- )
+ dbgp-offset if exit then \ Don't search if known
+ ehci-cfg h# 34 + config-l@ ( capability-ptr )
+ begin dup while ( cap-offset )
+ ehci-cfg + ( cfg-adr )
+ dup config-b@ h# 0a = if ( cfg-adr )
+ 2+ config-w@ ( dbgp-ptr )
+ dup h# 1fff and to dbgp-offset ( )
+ d# 13 rshift 7 and 1- /l* h# 10 + to dbgp-bar
+ exit
+ then ( cfg-adr )
+ 1+ config-b@ ( cap-offset' )
+ repeat ( cap-offset )
+ true abort" Can't find debug port registers"
+;
+
+: find-dbgp-controller ( -- )
+ find-ehci
+ find-dbgp-regs
+
+ ehci-cfg 4 + dup config-w@ 2 or swap config-w! \ Enable memory access
+ ebase 0= if
+ ehci-cfg dbgp-bar + config-l@ ( map-it ) to ebase \ Get the BAR
+ then
+ dbgp-base 0= if
+ ebase dbgp-offset + to dbgp-base
+ then
+;
+
+: pscbase ( port# -- adr ) /l* h# 44 + ebase c@ + ebase + ;
+: psc@ ( port# -- 0 ) pscbase l@ ; : psc! ( val port# -- ) pscbase l! ;
+: rstport ( port# -- )
+ dup psc@ h# 100 or 4 invert and over psc!
+ d# 100 ms
+ dup psc@ h# 100 invert and swap psc!
+ d# 10 ms
+;
+
+: +dbgp ( reg# -- adr ) dbgp-offset + ebase + ;
+: dbgp-l! dbgp-base + l! ; : dbgp-b! dbgp-base + c! ;
+: dbgp-l@ dbgp-base + l@ ; : dbgp-b@ dbgp-base + c@ ;
+
+: disable-dbgp ( -- ) \ Disable the debug port
+ dbgp-base if
+ 0 0 dbgp-l! d# 10 ms
+ then
+;
+
+: grab-dbgp ( -- )
+ find-dbgp-controller
+
+ disable-dbgp
+ 0 rstport \ Put the debug port in probe state
+ h# 5001.0400 0 dbgp-l! \ Enable the debug port
+ d# 10 ms
+ 0 dbgp-l@ h# 1000.0000 and 0= abort" Can't enable debug port"
+ 0 psc@ 4 invert and 0 psc! \ Detach the normal EHCI host controller
+;
+
+: wait-done ( -- finished? )
+ begin 2 dbgp-b@ 1 and until
+ 1 2 dbgp-b! \ Turn off the done bit
+ 0 dbgp-b@ h# 40 and if \ Error
+ 0 dbgp-l@ 7 rshift 7 and
+ case
+ 1 of ." DBGP USB hardware error" cr endof
+ 2 of ." DBGP transacation error" cr endof
+ endcase
+ abort
+ then
+;
+: data-toggle ( -- ) 5 dbgp-b@ h# 88 xor 5 dbgp-b! ;
+: acked? ( -- flag )
+ 6 dbgp-b@ ( received-PID )
+ case
+ \ Toggle DATA0 to DATA1 on an ACK
+ h# d2 of data-toggle true endof \ ACK
+ h# 96 of data-toggle true endof \ NYET (perhaps initiate slowdown)
+ h# 1e of true abort" DBGP stall" endof \ STALL
+ ( default ) false swap \ Probably NAK
+ endcase
+;
+
+: dbgp-rcv ( -- )
+ h# 69 4 dbgp-b! \ IN PID
+ h# 20 0 dbgp-b! \ Go, Read#
+ wait-done
+;
+
+: dbgp-send ( size -- )
+ h# 30 or
+ begin dup 0 dbgp-b! wait-done acked? until ( control-val )
+ drop
+;
+
+0 value dbgp-in
+0 value dbgp-out
+
+: set-dev ( device -- ) h# 11 dbgp-b! ;
+: set-endpoint ( ep -- ) h# 10 dbgp-b! ;
+: control-out ( data1 data0 -- )
+ 0 set-endpoint \ Control endpoint
+ 8 dbgp-l! \ wValue.bRequest.bRequestType
+ h# c dbgp-l! \ wSize.wIndex
+ h# c3.2d 4 dbgp-l! \ DATA0.SETUP
+ 8 dbgp-send \ Setup + Data
+ dbgp-rcv \ Status
+;
+: debug-mode ( -- )
+ 0 h# 0006.03.00 control-out \ size0.index0 DEBUG_MODE(6).SET_FEATURE(3).REQUESTTYPE_OUT(0)
+;
+: force-dbgp-adr ( -- error? )
+ 0 h# 007f.05.00 control-out \ size0.index0 NewAddress.SET_ADDRESS(5).REQUESTTYPE_OUT(0)
+ h# 7f set-dev
+;
+
+: get-dbgp-desc ( -- )
+ 0 set-endpoint \ Control endpoint
+ h# 0a00.06.80 8 dbgp-l! \ USB_DT_DEBUG<<8(a00).GET_DESCRIPTOR(6).REQUESTTYPE_IN(80)
+ h# 0004.0000 h# c dbgp-l! \ SIZE(4).Index(0)
+ h# c3.2d 4 dbgp-l! \ DATA0.SETUP
+ 8 dbgp-send \ Setup
+ dbgp-rcv \ In
+ h# 4b.e1 4 dbgp-l! \ Status (DATA1.OUT)
+ 0 dbgp-send \ Setup
+;
+: find-dbgp-device ( -- )
+ d# 80 0 do
+ i set-dev
+ ['] get-dbgp-desc catch 0= if
+ 8 dbgp-l@ lbsplit to dbgp-out to dbgp-in 2drop
+ unloop exit
+ then
+ loop
+ true abort" No Debug Device"
+;
+
+true value dbgp-off?
+: uemit ( char -- )
+ dbgp-off? if drop exit then
+ dbgp-out set-endpoint \ Bulk out endpoint
+ 8 dbgp-l! \ char
+ h# e1 4 dbgp-b! \ OUT
+ 1 dbgp-send
+;
+
+0 value nkeys
+0 value k0
+0 value k1
+: pullkey ( -- char )
+ nkeys 1- 0 max to nkeys
+ k0 lbsplit k1 lbsplit 0 bljoin to k1 bljoin to k0 ( char )
+;
+
+: ukey? ( -- flag )
+ dbgp-off? if false exit then
+ nkeys if true exit then
+ dbgp-in set-endpoint \ Bulk in endpoint
+ dbgp-rcv
+ 6 dbgp-b@ ( received-PID )
+ dup h# c3 = swap h# 4b = or if
+ 0 dbgp-b@ to nkeys
+ 8 dbgp-l@ to k0
+ h# c dbgp-l@ to k1
+ nkeys 0<>
+ else
+ false
+ then
+;
+: ukey ( -- char )
+ dbgp-off? if 0 exit then
+ nkeys if pullkey exit then
+ begin ukey? until
+ pullkey
+;
+
+: dbgp-io ( -- )
+ ['] uemit is (emit
+ ['] ukey is (key
+ ['] ukey? is key?
+ ['] default-type is (type
+ ['] emit1 is emit
+ ['] type1 is type
+;
+
+: init-dbgp ( -- )
+ grab-dbgp \ Attach the debug host controller
+ find-dbgp-device
+ force-dbgp-adr
+ debug-mode
+;
+: dbgp-off ( -- )
+ true to dbgp-off? \ Make the uemit routines do nothing
+ disable-dbgp
+;
+
+: inituarts
+ ['] init-dbgp catch to dbgp-off?
+ \ Leave the EHCI debug port off if a Debug Device wasn't attached
+ dbgp-off? dbgp-base 0<> and if disable-dbgp then
+;
+
+: start-dbgp ( -- )
+ init-dbgp
+ dbgp-io
+;
+
+[ifdef] notdef
+Sending bytes via debug port, assuming it's already inited.
+
+ ( char in al )
+ dbgp_adr # bp mov
+ al 8 [bp] mov \ char
+ OUT_ENDP # h# 10 [bp] byte mov \ endpoint
+ h# e1 # 4 [bp] byte mov \ OUT token
+ begin
+ h# 31 # 0 [bp] byte mov \ Go, write, 1 char
+ begin 1 # 2 [bp] byte tst 0<> until \ Wait for DONE
+ 1 # 2 [bp] byte mov \ Clear done bit
+ h# 40 # 0 [bp] byte tst \ Check error bit
+ 0<> if \ Error
+ al al cmp \ Force loop exit
+ else \ Not error
+ 6 [bp] al mov \ Get PID
+ h# d2 # al cmp \ Compare to ACK
+ 0<> if \ Not ACK
+ h# 96 # al cmp \ Compare to NYET
+ then
+ then \ Z will be set for exit
+ 0= until
+
+Receiving bytes via debug port, assuming it's already inited.
+
+ dbgp_adr # bp mov
+ IN_ENDP # h# 10 [bp] byte mov \ endpoint
+ h# 69 # 4 [bp] byte mov \ IN token
+ h# 20 # 0 [bp] byte mov \ Go, read
+ begin 1 # 2 [bp] byte tst 0<> until \ Wait for DONE
+ 1 # 2 [bp] byte mov \ Clear done bit
+ h# 40 # 0 [bp] byte tst \ Check error bit
+ 0<> if \ Error
+ clrc
+ else
+ 6 [bp] al mov \ Get PID
+ h# c3 # al cmp 0= if \ Compare to DATA0
+ 8 [bp] al mov
+ setc
+ else
+ h# c3 # al cmp 0= if \ Compare to DATA1
+ 8 [bp] al mov
+ setc
+ else
+ clrc
+ then
+ then
+ then
+ \ Carry set if got a char, and char in al
+
+[then]
More information about the openfirmware
mailing list