Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / obp / obp / dev / sun4v-devices / vcommon / vio-methods.fth
\ ========== Copyright Header Begin ==========================================
\
\ Hypervisor Software File: vio-methods.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: @(#)vio-methods.fth 1.3 06/12/21
purpose: This file contains methods shared by VIO devices
copyright: Copyright 2006 Sun Microsystems, Inc. All Rights Reserved
copyright: Use is subject to license terms.
headerless
fload ${BP}/dev/utilities/cif.fth
headerless
0 value nego-good?
0 value current-vio-dev
defer claim ( align size virt -- base ) 0 " claim" do-cif is claim
defer release ( size virt -- ) 0 " release" do-cif is release
defer send-vio-ver-msg ( -- ok? ) ' false is send-vio-ver-msg
defer send-vio-ack-msg ( buf ack -- ok? ) ' drop is send-vio-ack-msg
defer vio-compatible-ver? ( buf - yes? ) ' noop is vio-compatible-ver?
defer retrieve-packet ( buf len -- #bytes ) ' drop is retrieve-packet
defer send-vio-attr ( -- ok? ) ' false is send-vio-attr
defer send-vio-rdx ( -- ok? ) ' false is send-vio-rdx
defer update-vd-disk-type ( buf -- ) ' drop is update-vd-disk-type
\ Fill in buffer with VIO msg tag information
: set-vio-msg-tag ( type subtype env buf -- )
tuck >vio-subtype-env w! ( type subtype buf )
tuck >vio-subtype c! ( type buf )
>vio-msgtype c! ( )
;
\ Get VIO msg tags
: get-vio-msg-tag ( buf -- env subtype type )
dup >vio-subtype-env w@ ( buf env )
swap dup >vio-subtype c@ ( env buf subtype )
swap >vio-msgtype c@
;
\ Check if the tags match each other
: vio-tag-match? ( env' stype' type' env stype type -- match? )
3 pick = >r 3 pick = r> and >r 3 pick = r> and nip nip nip
;
\ Fill in version numbers
: set-vio-msg-ver ( devt minor major buf -- )
tuck >vio-ver-major w! ( devt minor buf )
tuck >vio-ver-minor w! ( devt buf )
>vio-dev-type c! ( )
;
: round-up ( value mod -- value' ) 1- tuck + swap invert and ;
\ This word is called by version-negotiation
\ Return different status for different pkts received
: handle-ver-response ( buf subtype -- ok? done? )
case ( buf subtype )
vio-subtype-info of ( buf )
nego-good? if
vio-subtype-ack send-vio-ack-msg ( ok )
drop true true exit ( true true )
then
dup vio-compatible-ver? if ( buf )
vio-subtype-ack send-vio-ack-msg ( ok )
drop true true
else cmn-warn[ " Version incompatible!" ]cmn-end
vio-subtype-nack send-vio-ack-msg ( ok )
drop false true ( false true )
then
endof
vio-subtype-ack of ( buf )
true to nego-good?
drop true true ( true true )
endof
vio-subtype-nack of
drop false true ( false true )
endof
( default )
\ Unknown subtype, skip
nip false false rot ( false false subtype )
endcase
;
\ Read from LDC channel
\ ACK -> set good version, continue
\ NACK -> exit with error status
\ VER-INFO ->
\ good version -> ack, exit with good status, otherwise:
\ = our version -> ack, exit with good status
\ <> our version -> nack back msg, continue
\ no more msg -> exit with error status
: version-negotiation ( buf -- ok? )
send-vio-ver-msg 0= if
cmn-warn[ " Version-negotiation: Can't send version message!"
]cmn-end
drop false exit ( false )
then
0 to nego-good?
begin ( buf )
dup /vio-ver-msg retrieve-packet ( buf alen )
dup /vio-ver-msg = if ( buf alen )
drop dup >vio-msgtype c@ ( buf type )
vio-msg-type-ctrl = if ( buf )
dup dup >vio-subtype c@ ( buf buf subtype )
handle-ver-response ( buf ok? done? )
if nip exit then ( ok? )
\ Not control type of message, skip to next one
else ( buf )
false ( buf false )
then
else \ received data len not good ( buf alen )
\ Garbage, skip
if ( buf )
false ( buf false )
\ No more pkts to receive
else ( buf )
drop false exit ( !ok )
then ( ok? )
then ( buf alen )
until ( buf )
;
0 value received-rdx? \ received RDX from server
0 value received-rdx-ack? \ recieved ACK for our own RDX message
\ A full duplex channel is established when two conditions have been met:
\ 1. We've received and RDX from the server and sent an ACK.
\ 2. We're recieved an ACK for our own RDX packet.
\ VSW requires that both 1 and 2 be completed.
\ VDS requires only step 2 (in fact early versions do not send an RDX at all)
\ In order to support both old and new versions of VDS we set the recieved-rdx?
\ flag to true for VDS so that if we don't receive an RDX we will fall through
\ the begin-until loop once we've received our RDX-ACK and continue on.
\ Newer versions of VDS that require a full-duplex channel will hold off on
\ issuing an RDX-ACK until they've sent their own RDX and received an ACK thus
\ keeping OBP in this loop until the negotiation is complete.
: complete-rdx-handshake ( buf -- yes? )
0 to received-rdx?
0 to received-rdx-ack?
current-vio-dev vdev-disk-client = if ( buf )
true to received-rdx? ( buf )
then ( buf )
begin ( buf )
dup /vio-msg-tag retrieve-packet if ( buf )
dup get-vio-msg-tag ( buf env stype type )
vio-rdx vio-subtype-ack vio-msg-type-ctrl
vio-tag-match? if ( buf )
true to received-rdx-ack? ( buf )
then ( buf )
dup get-vio-msg-tag ( buf env stype type )
vio-rdx vio-subtype-info vio-msg-type-ctrl
vio-tag-match? if ( buf )
dup vio-subtype-ack send-vio-ack-msg drop ( buf )
true to received-rdx? ( buf )
then
else \ retrieve-packet returns 0, no more packets
drop false exit ( false )
then ( buf )
received-rdx? received-rdx-ack? and ( buf done? )
until ( buf )
drop true ( true )
;
\ Send RDX and expect server side RDX
: handle-vio-rdx ( buf -- ok? done? )
dup send-vio-rdx if ( buf )
complete-rdx-handshake if ( )
true true ( true true )
else
false true ( false true )
then
else
cmn-warn[ " Can't send RDX message!" ]cmn-end
drop false true ( false true )
then
;
\ Read from LDC channel
\ ACK -> continue
\ NACK -> exit with error status
\ ATTR-INFO -> ack
\ -> send RDX, wait for responding RDX
\ -> Arrived: exit with good status
\ -> Not arrived: exit with error status
\ no more msg -> exit with error status
: handle-attr-response ( buf subtype -- ok? done? )
case ( buf subtype )
vio-subtype-info of ( buf )
dup vio-subtype-ack send-vio-ack-msg drop ( buf )
dup >vio-subtype-env w@ ( buf env )
vio-attr-info = if ( buf )
current-vio-dev vdev-disk-client = if
dup update-vd-disk-type ( buf )
then
then
handle-vio-rdx ( ok? done? )
true to nego-good?
endof
vio-subtype-ack of ( buf )
dup >vio-subtype-env w@ ( buf env )
vio-attr-info = if ( buf )
current-vio-dev vdev-disk-client = if
dup update-vd-disk-type ( buf )
then
\ Check if RDX not sent, send now
nego-good? if ( buf )
drop true true ( true true )
else ( buf )
handle-vio-rdx
then
else ( buf )
drop false false ( false false )
then
endof
vio-subtype-nack of ( buf )
drop false true ( false true )
endof
( default ) \ skip unexpected types
nip false false rot ( false false subtype )
endcase
;
\ Send attr packet, handle responses
: vio-exchange-attr ( buf len -- ok? )
send-vio-attr 0= if ( buf len )
cmn-warn[ " Can't send attribute message!" ]cmn-end
2drop false exit ( false )
then
0 to nego-good?
begin ( buf len )
2dup retrieve-packet 2dup ( buf len alen len alen )
= if ( buf len alen )
drop over >vio-msgtype c@ ( buf len type )
vio-msg-type-ctrl = if ( buf len )
over dup >vio-subtype c@ ( buf len buf subtype )
handle-attr-response ( buf len ok? done? )
if nip nip exit then ( ok? )
\ Not CTRL type of msg, skip to next one
else ( buf len )
false ( buf len false )
then
else \ received data len not good ( buf len alen )
\ Garbage, skip
if ( buf len )
false ( buf len false )
\ No more pkts to receive, alen = 0
else ( buf len )
2drop false exit ( !ok )
then
then
until
;
: fill-in-vio-cookie ( cadr #ck len buf -- )
2swap 0 do ( len buf cadr )
swap dup rot ( len buf buf cadr )
dup x@ ( len buf buf cadr cookie )
rot >ldc-mem-caddr x! ( len buf cadr )
over >ldc-mem-csize ( len buf cadr buf' )
3 pick pagesize min 8 round-up ( len buf cadr buf' len' )
dup >r ( len buf cadr buf' len' ) ( R: len' )
swap x! ( len buf cadr ) ( R: len' )
rot r> - -rot ( len'' buf cadr )
8 + swap /ldc-mem-cookie + ( len'' cadr' buf'' )
swap ( len'' buf'' cadr' )
loop 2drop drop
;