Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / obp / obp / dev / network / neptune / mif.fth
\ ========== Copyright Header Begin ==========================================
\
\ Hypervisor Software File: mif.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: @(#)mif.fth 1.1 07/01/23
purpose:
copyright: Copyright 2007 Sun Microsystems, Inc. All Rights Reserved
copyright: Use is subject to license terms.
headerless
h# 1.0000 constant data-valid-bit \ bit 16 of Clause 45 frame
\ TA field of IEEE802.3ae clause45 frame has two bits. When a clause45
\ frame operation is done, the lower bit of TA (named data-valid)
\ changes from 0 to 1. We poll this bit for the completion of the
\ operation.
\ Note that the low 16 bits returned by mif-frame-output-reg@
\ are the register value if mdio-wait is called by mdio-read.
\ If mdio-wait is called by mdio-write, then the value
\ returned by mif-frame-output-reg@ will only be used
\ by mdio-write for error checking purpose. (See mdio-write)
\
: mdio-wait ( -- [ value true ] | false )
d# 2000 get-msecs + false ( end-time flag)
h# abcd -rot ( abcd end-time flag )
\ abcd is a place holder, to be replaced
\ by read back value.
\ abcd and f below are value of the first loop
begin ( abcd end-time flag )
over ( abcd end-time flag end-time )
timed-out? ( abcd end-time flag flag )
0= ( abcd end-time flag flag )
over ( abcd end-time flag flag flag )
0= ( abcd end-time flag flag flag )
and ( abcd end-time flag flag )
while
mif-frame-output-reg@ ( abcd end-time flag data )
dup data-valid-bit ( abcd end-time flag data data valid-bit-mask )
and ( abcd end-time flag data valid? )
0<> if ( abcd end-time flag data )
h# ffff and ( abcd end-time flag val )
nip -rot ( val abcd end-time )
nip true ( val end-time flag )
else ( abcd end-time flag data )
drop ( abcd end-time flag )
then ( abcd end-time flag )
repeat ( abcd end-time flag )
nip dup 0= if nip then ( val true | false )
;
\ mdio-write is used to write an address or a data to a MDIO
\ Manageable Device (MMD).
\
\ When it is used to write an address, the OP field of the clause45
\ frame is b'00, the data field (low 16bits) are the register addr.
\ When it is used to write a data, the OP field of the frame is
\ b'10, the data field contains the 16 bit data.
\
\ mdio-write calls mif-frame-outout-reg! to tell the serdes
\ the register address or data, then it calls mdio-wait which
\ in turn calls mif-frame-output-reg@ to check the data-valid bit
\ to see if the write operation has succeeded (and also get the
\ written data back for checking)
\
: mdio-write ( frame -- )
dup ( frame frame )
mif-frame-output-reg! ( frame )
mdio-wait ( frame [[value true] | false] )
0= if ( frame [value | ] )
cmn-error[ " mdio-write timed out." ]cmn-end
drop ( )
else ( frame value )
\ When we call mdio-wait to check the data-valid bit, the
\ data portion (lower 16bit of the frame) should contain
\ the same data we just wrote to the device. Here we check
\ they indeed match, print an error message if not.
h# ffff and ( frame value&0xFFFF )
swap h# ffff and ( value&0xFFFF frame&0xFFFF )
<> if cmn-error[ " mdio-write failed." ]cmn-end then
then
;
\ mdio-read calls mif-frame-outout-reg! to tell the serdes
\ the address of the register which we will read data from,
\ then it calls mdio-wait which in turn calls mif-frame-output-reg@
\ to check the data-valid bit and get the data from the serdes
\
: mdio-read ( frame -- value )
mif-frame-output-reg! ( )
mdio-wait ( value true | false )
0= if cmn-error[ " mdio-read timed out." ]cmn-end false then
;
\ --------------------Clause45 Frame------------------------------
\ IEEE 802.3 Clause45 MDIO Frame Reg Fields
\ ST: Start of Frame, ST=00 for Clause45, ST=01 for Clause22
\ OP: Operation Code,
\ PRTAD: Port Addr
\ DEVAD: Device Addr
\ TA: Turnaround(time)
\
\ Frame ST OP PRTAD DEVAD TA ADDRESS/DATA
\ [31:30] [29:28] [27:23] [22:18] [17:16] [15:0]
\ Address 00 00 PPPPP EEEEE 10 aaaaaaaaaaaaaaaa
\ Write 00 01 PPPPP EEEEE 10 dddddddddddddddd
\ Read 00 11 PPPPP EEEEE Z0 dddddddddddddddd
\ Post-read 00 10 PPPPP EEEEE Z0 dddddddddddddddd
\
\ DEVAD for LSIL serdes is 0x1E
\ PRTAD for LSIL serdes is 8 for port0 and 9 for port1
\ So
\ ST OP PRTAD DEVAD
\ Addr-P0 00 00 01000 11110 10 = 047a.AAAA
\ Addr-P1 00 00 01001 11110 10 = 04Fa.AAAA
\ Write-P0 00 01 01000 11110 10 = 147a.DDDD
\ Write-P1 00 01 01001 11110 10 = 14Fa.DDDD
\ Read-P0 00 11 01000 11110 10 = 347a.DDDD
\ Read-P1 00 11 01001 11110 10 = 34Fa.DDDD
\
\ clause45-write assembles two clause45 frames based on the 4
\ arguments on the stack and calls mdio-write twice, first for
\ specifying reg address and second for actual data writing.
\
: clause45-write ( data reg-addr PRTAD DEVAD -- )
d# 18 lshift swap ( data reg-addr DEVAD' PRTAD )
d# 23 lshift ta=10 ( data reg-addr DEVAD' PRTAD' TA )
or or tuck or ( data frame frame' )
mdio-write ( data frame )
or op=write or ( frame'')
mdio-write ( )
;
\ clause45-read assembles two clause45 frames based on the 3
\ arguments on the stack and calls mdio-write to specify the register
\ address and calls mdio-read to read the register data.
\
: clause45-read ( PRTAD DEVAD reg-addr -- value )
-rot ( reg-addr PRTAD DEVAD )
d# 18 lshift swap ( reg-addr DEVAD' PRTAD )
d# 23 lshift TA=10 ( reg-addr DEVAD' PRTAD' TA )
or or swap ( frame[27:16]=PRTAD'|DEVAD'|TA reg-addr )
or dup ( frame[27:0] frame[27:0] ) \ OP=WR is implied
mdio-write ( frame[27:0] )
op=read45 or ( frame[29:0] ) \ bits[15:0] are don't care
mdio-read ( value )
;