Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / obp / obp / dev / usb-devices / hub / probe.fth
\ ========== Copyright Header Begin ==========================================
\
\ Hypervisor Software File: probe.fth
\
\ Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
\
\ - Do no alter or remove copyright notices
\
\ - Redistribution and use of this software in source and binary forms, with
\ or without modification, are permitted provided that the following
\ conditions are met:
\
\ - Redistribution of source code must retain the above copyright notice,
\ this list of conditions and the following disclaimer.
\
\ - Redistribution in binary form must reproduce the above copyright notice,
\ this list of conditions and the following disclaimer in the
\ documentation and/or other materials provided with the distribution.
\
\ Neither the name of Sun Microsystems, Inc. or the names of contributors
\ may be used to endorse or promote products derived from this software
\ without specific prior written permission.
\
\ This software is provided "AS IS," without a warranty of any kind.
\ ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
\ INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
\ PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
\ MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
\ ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
\ DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN
\ OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR
\ FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
\ DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
\ ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
\ SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
\
\ You acknowledge that this software is not designed, licensed or
\ intended for use in the design, construction, operation or maintenance of
\ any nuclear facility.
\
\ ========== Copyright Header End ============================================
id: @(#)probe.fth 1.25 05/09/30
purpose:
copyright: Copyright 2005 Sun Microsystems, Inc. All Rights Reserved
copyright: Use is subject to license terms.
\ must do dma-free on adr2 len2 after fcode is used:
: find-fcode ( adr1 len1 -- adr2 len2 true | false )
" sunw,find-fcode" get-inherited-property drop
decode-int nip nip
execute
;
: find-device-fcode ( -- addr len ) " device" find-fcode drop ;
: find-combined-fcode ( -- addr len ) " combined" find-fcode drop ;
: assign-address ( speed usb-addr -- hw-err? | stat 0 )
\ next-usb-address ?dup if
set-address-form >r \ uses request-blank
( speed ) 1 max-packet 0 0 r> /request 0 0 execute-control
\ else no-more-addresses
\ then
d# 10 ms \ allow assignment to take effect
\ should need only 2 ms
;
: set-configuration ( speed usb-addr config -- hw-err? | stat 0 )
1 max-packet 2swap 0 0 2swap
( speed dir max-pkt dat-adr dat-len usb-addr config )
0 -rot \ endpoint
clean-request-blank \ dma-free at end of probe or close
set-config-req over request-type w!
swap over req-value le-w!
/request 2swap ( speed dir max-pkt dat-adr dat-len req-adr req-len )
execute-control
;
\ dma-alloc because of get-descriptors
: get-dev-descrip ( speed usb-adr -- dev-descrip-addr dcnt hw-err? | stat 0 )
0 swap max-packet swap
/dev-descriptor dma-alloc \ only needed at probe time
dup >r swap
/dev-descriptor swap
/dev-descriptor get-dev-descript-form
swap
/request swap
0 swap execute-control
?dup
r> /dev-descriptor
2swap
0= if 0 then
;
\ dma-alloc data area because of get-descriptors
: get-config-descrip ( speed usb-adr n cnt
-- config-n-descrip-addr cnt hw-err? | stat 0 )
swap rot >r >r >r ( R: usb-addr n cnt )
0 max-packet
r@ dma-alloc ( speed in max c-d-addr ) \ only used at probe time
r> r> r> ( speed in max c-d-addr cnt n u-addr )
2over >r >r >r >r ( R: cnt c-d-addr u-addr n )
dup get-config-descript-form
r> over req-value c! ( speed in max c-d-addr cnt pak-adr )
( R: cnt c-d-addr usb-addr )
/request 0 r> execute-control
?dup
r> r>
2swap
0= if 0 then
;
: get-config1-descrip ( speed usb-adr
-- config1-descrip-addr ccnt hw-err? | stat 0 )
0 /config-descriptor get-config-descrip
;
: ?create-speed ( lo-speed? -- )
if 0 0 " low-speed" property then
;
: create-address ( usb-addr -- )
encode-int " assigned-address" property
;
: combined-node? ( config-desc dev-desc -- combined? )
dup d-descript-class c@
dup 9 = swap 0= or ( c-desc d-desc dev-ok? )
swap d-descript-#configs c@ 1 = and
swap c-descript-#interfaces c@ 1 = and
;
: make-child ( fcode-adr unit-str unit-len speed usb-adr -- )
child-max
new-device
( child-max ) encode-int " 0max-packet" property
create-address ?create-speed
" " 2swap set-args
1 byte-load
finish-device
;
: .usb ( stat -- )
case 2 of noop endof \ patchable
6 of cr ." usb-nak" endof
e of cr ." usb-stall" endof
cr ." usb-unknown"
endcase
;
: stall-or-nak? ( stat -- stall-or-nak? )
dup .usb
dup e = swap 6 = or
;
: idump ( adr len -- ) \ XXX debug
" dump" $find drop execute
;
: clean-port ( port -- ) \ acts on the hub
dup reset-port \ includes enable-port
dup clear-connect-change
dup clear-port-reset
dup clear-port-enable
clear-port-suspend
;
: set-default-max-packet ( speed -- )
if \ low speed
8 to child-max
8 to max-packet
else \ reg. speed
d# 64 to child-max
d# 64 to max-packet
then
;
defer complete-probe ( port speed )
' 2drop is complete-probe \ for a good node already created
\ Start with a new device at usb 0, port, and known speed (low or normal).
\ no-retry? (non-zero) if really fatal or succeeded. retry (zero) if want to
\ go back to reset-port
: probe-once ( port speed -- no-retry? )
['] 2drop is complete-probe \ default to good device node on each pass
dup set-default-max-packet
\ d# 150 ms \ for Microsoft device settling; only hot-plug?
" dev-descrip" diag-crtype
dup 0 get-dev-descrip ( port speed dev-d-adr dcnt hw-err? | stat 0 )
dup no-response-error = if \ wait for device that powers up slowly
drop dma-free
over clean-port
d# 2000 ms \ maybe only 500 needed?
dup 0 get-dev-descrip ( port speed dev-d-adr dcnt hw-err? | stat 0 )
then
?dup if
data-overrun-error <> if \ data-over benign here
dma-free
2drop
['] won't-send-descriptor is complete-probe
false exit ( retry )
then
else stall-or-nak? if
dma-free 2drop
['] won't-send-descriptor is complete-probe
false exit ( retry )
then
then ( port speed dev-d-adr dcnt )
over d-descript-maxpkt c@ to child-max
dma-free
over clean-port
" next-add" diag-crtype
child-max to max-packet
next-usb-address 2dup assign-address ( port speed usb-adr hw-err? | stat 0 )
?dup if
drop \ XXX the error code; already printed
drop \ XXX will use up usb-adrs
2drop
['] won't-take-address is complete-probe
false exit ( retry )
else stall-or-nak? if
drop \ XXX will use up usb-adrs
2drop
['] won't-take-address is complete-probe
false exit ( retry )
then
then ( port speed usb-adr )
" get-config1" diag-crtype
2dup get-config1-descrip
( port spd usb-addr cnfg-adr cnt hw-err? | stat 0 )
?dup if
drop \ XXX some hw-err; already printed
dma-free
drop \ XXX will use up usb-adrs
2drop
['] won't-send-config is complete-probe
false exit ( retry )
else stall-or-nak? if
dma-free
drop \ XXX will use up usb-adrs
2drop
['] won't-send-config is complete-probe
false exit ( retry )
then
then ( port spd usb-addr cnfg-adr cnt )
over c-descript-config-id c@ >r \ get bconfigvalue
dma-free
" set-config" diag-crtype
2dup r> set-configuration \ config index 1, using bconfigvalue
?dup if ( port spd usb-addr hw-err? )
drop \ XXX hw-err; already printed
drop 2drop
['] won't-take-config is complete-probe
true exit ( no-retry )
else stall-or-nak? if
drop 2drop
['] won't-take-config is complete-probe
true exit ( no-retry )
then
then ( port spd usb-adr )
" get-config1-descript" diag-crtype
2dup get-config1-descrip
( port speed usb-adr config-desc ccnt hw-err? | stat 0 )
?dup if
drop \ XXX some hw-err; already printed
dma-free
drop 2drop
['] won't-send-descriptor is complete-probe
true exit ( no-retry )
else stall-or-nak? if
dma-free
drop 2drop
['] won't-send-descriptor is complete-probe
true exit ( no-retry )
then
then ( port spd usb-adr cadr ccnt )
" get-dev-descrip" diag-crtype
2over get-dev-descrip
( port spd usb-adr cadr ccnt dadr dcnt hw-err? | stat 0 )
?dup if
drop \ XXX hw-err; already printed
dma-free dma-free
drop 2drop
['] won't-send-descriptor is complete-probe
true exit ( no-retry )
else stall-or-nak? if
dma-free dma-free
drop 2drop
['] won't-send-descriptor is complete-probe
true exit ( no-retry )
then
then
" descripts" diag-crtype
( port spd usb-adr config-desc ccnt dev-desc dcnt )
\ 2dup cr ." dev descrip" cr idump \ XXX debug
\ 2over cr ." con descrip" cr idump \ XXX debug
3 pick 2 pick combined-node? if
" finding combined" diag-crtype
find-combined-fcode
else
" finding device" diag-crtype
find-device-fcode
then
>r >r
dma-free dma-free
r@ ( port speed usb-adr fcode-adr ) ( R: f-len f-adr )
-rot >r >r swap
encode-unit r> r>
make-child
r> r> dma-free \ toss fcode; only at probe time
" node made" diag-crtype
true ( no-retry )
;
\ give a device two chances. if not enumerated ok after two tries, make a
\ bad device node. leave open the option for other actions, depending on the
\ precise failure.
: probe-port ( port -- )
2 0 do
dup clean-port
dup dup port-low-speed? \ bug 6261224, for Cypress hub chip
probe-once
if leave then
loop
dup port-low-speed?
complete-probe
;
: probe-ports ( -- )
#ports 1+ 1 do
i power-port \ leave port on -- possible hot-plug
i port-connected? if \ unpowered is not connected
i probe-port
then
loop
;
\ looks like not needed
: read-power-bits ( hub-descript -- ) drop ;
: read-my-data ( -- went-ok? ) \ read descriptors and figure out what's what
0max-packet to max-packet
speed my-usb-addr get-dev-descrip ( dadr dcnt hw-err? | stat 0 )
?dup if
drop
dma-free
" disabled" encode-string " status" property
false exit
else stall-or-nak? if
dma-free
" disabled" encode-string " status" property
false exit
then
then
over d-descript-maxpkt c@ to 0max-packet
\ would need endpt descriptor for max packet for endpt. <> 0
dma-free
0max-packet to max-packet
7 get-hub-descript \ get the real descript size
?dup if
drop
drop \ common-buffer; no dma-free here
" disabled" encode-string " status" property
false exit
else stall-or-nak? if
drop \ common-buffer; no dma-free here
" disabled" encode-string " status" property
false exit
then
then
h-descript-len c@ get-hub-descript
?dup if
drop
drop \ common-buffer; no dma-free here
" disabled" encode-string " status" property
false exit
else stall-or-nak? if
drop \ common-buffer; no dma-free here
" disabled" encode-string " status" property
false exit
then
then
dup h-descript-#ports c@ to #ports
dup read-power-bits
h-descript-power-on c@ 2* to power-on-time
true
;
\ XXX hub status data -- 32 bits or so
\ port status data -- 32 bits or so
\ probe deeper if recurse? is not 0. involves a dependency on main OBP.
\ this word works with max-recursion in the host adapter fcode, and with
\ onboard-usb-max-depth and onboard-usb-recurse? in SUNW,builtin-drivers.
: go-deeper? ( -- recurse? )
" onboard-usb-recurse?"
" SUNW,builtin-drivers" find-package drop \ must be present
find-method if
execute 0<>
else true \ default to go deeper
then
;
: power-on ( -- )
/request dma-alloc to request-blank \ get memory
/common-buffer dma-alloc to common-buffer
read-my-data go-deeper? and if
unpower-ports \ magic
probe-ports
then
common-buffer /common-buffer dma-free \ free memory
-1 to common-buffer
request-blank /request dma-free
-1 to request-blank
;
power-on