Sun Java Solaris Communities My SDN Account Join SDN
 
Documentation

Code Sample: PCI-FCode

 id: @(#)pci-fcode.html 1.6 00/08/30
purpose: A sample PCI FCode to show creation of properties, use of Vital
 Product Data and access to ROM.
Copyright Sun Microsystems, Inc.  All Rights Reserved

\ Each Fresh Choice PCI card will define one hme device node:
\
\   pci
\    |
\    |
\    |
\   hme
\
\ The general pathname (after pci) for a hme node is
\       hme@D,1
\ where D is Device#.
\
\ name            hme
\                 Phys.hi    Phys.mid   Phys.lo    Size.hi    Size.lo
\                 -------    ---------  ---------  ---------  ---------
\ reg             0000.0S00  0000.0000  0000.0000  0000.0000  0000.0000  \ PCI Cfg
\                 0200.0S10  0000.0000  0000.0000  0000.0000  0000.7020  \ HME space
\
\                 where "S" = PCI Device | Function 1 (h# 100)
\

Fcode-version1
 

hex
: copyright ( -- )
   " Copyright Sun Microsystems, Inc.  All Rights Reserved"
;

\ 3.x token interpreter extends bit[31] all the way to bit[63].
\ To create numbers with bit[31] set, but not extended to bit[63],
\ we need to use x-num
ff ff ff ff bljoin constant num-32
: x-num ( n -- l )  num-32 and ;
: and ( a b -- a-and-b ) and    x-num  ;
: or ( a b -- a-or-b )   or     x-num  ;
: lshift ( x n -- x' )   lshift x-num  ;
: rshift ( x n -- x' )   rshift x-num  ;

f200.0000 x-num constant xreg-mask
\ my-address gives two 32 bit numbers for PCI case.
my-address      constant my-bus-addr-mid  constant my-bus-addr-low
my-space        constant my-bus-space
2  constant pci-hme-intr       \ for PCI card

: my-bus-addr (  --  paddr.low paddr.mid )
   my-bus-addr-low  my-bus-addr-mid
;
 

\ for mac id on the fcode prom itself
h# 24 constant vpdp-loc
h# c000 value vpd-base
0 value cheer-rombase
external
0 value vpd-addr
headerless
h# 1.0000 value /cheer-rom

\ HappyMeal Enet Address Map
hex
   000.0000 constant global-regs-offset
       7020 constant        /total-reg-space

h# 4000     constant max-frame-size  ( d# 1536 for le )
d# 48       constant address-bits
h# 10       constant cfg-bar0
h# 4        constant cfg-cmd-reg
h# 30       constant cfg-rom-base
h# 200.0000 constant 32-bit-mem-ss
 

: encode-ints  ( nn .. n1 n -- adr len ) \ XXX
   0 0 encode-bytes   rot  0  ?do  rot encode-int encode+  loop
;

: xdrreg  ( addr space size -- adr len )
   >r encode-phys  r> 0 2 encode-ints  encode+
;

: offset>physical-addr  ( offset -- paddr.lo paddr.mid paddr.hi )
   my-bus-addr >r + r> my-bus-space
   32-bit-mem-ss or cfg-bar0  or  \ OR in "ss" = memory, base reg=10
;

headers
: create-hme-attributes  ( -- )

   " SUNW,hme"      name  
   " SUNW,cheerio" encode-string  " model" property

   my-bus-addr my-bus-space 0  xdrreg
   global-regs-offset offset>physical-addr  /total-reg-space
   xdrreg encode+
   " reg" property

   max-frame-size encode-int " max-frame-size" property
   address-bits encode-int " address-bits" property
   pci-hme-intr  encode-int  " interrupts"  property
   " network" device-type
   " 1.6" encode-string " version" property \ FCode PROM version
;

: enable-cheer-cmd-reg ( -- )
   \ PCI Command Register Settings
   \ h# 100  = SERR# Enable
   \ h#  40  = Parity Error Enable
   \ h#   4  = Mastering Enable
   \ h#   2  = Memory Access Enable
   my-bus-space cfg-cmd-reg +  " config-w@" $call-parent   ( cmd-reg )
   \ Set PCI Command bits
   h# 146  or
   my-bus-space cfg-cmd-reg +  " config-w!" $call-parent
;

: enable-cheer-rom ( -- )
   my-bus-space cfg-rom-base +  " config-l@" $call-parent   ( cmd-reg )
   \ enable rom accesses
   h# 1  or
   my-bus-space cfg-rom-base +  " config-l!" $call-parent
;

: disable-cheer-rom ( -- )
   my-bus-space cfg-rom-base +  " config-l@" $call-parent   ( cmd-reg )
   \ disable rom accesses
   h# 1 invert and
   my-bus-space cfg-rom-base +  " config-l!" $call-parent
;
: map-cheer-rom ( --  )
   0 0 my-bus-space 32-bit-mem-ss or cfg-rom-base or /cheer-rom
   " map-in" $call-parent to cheer-rombase
;

: unmap-cheer-rom ( --  )
   cheer-rombase /cheer-rom " map-out" $call-parent
   0 to cheer-rombase
;
 

\ the Vital Product Data for Fresh Choice ethernet looks like this:
\
\ (Offsets are in decimal.)
\ Offset   Item                            Value
\   0      Large Resource Type VPD Tag     (0x10) 0x90
\   1      Length                          0x0009
\   3      VPD Keyword                     "NA"
\   5      Length                          6
\   6      Ethernet Address                0x080020.??????
\  12      Small Resource Type End Tag     (0xf) 0x79
\  13      Data (nominally checksum)       0
\
\

: uw@ ( adr -- w )  dup c@ swap 1+ c@ swap bwjoin ;

: set-vpdp-value ( -- )  \ set pointer to vpd
   enable-cheer-cmd-reg
   map-cheer-rom
   enable-cheer-rom  
   cheer-rombase vpdp-loc +  rw@ cheer-rombase + to vpd-addr
;

: unset-vpdp-value ( -- )
   disable-cheer-rom
   unmap-cheer-rom
   0 to vpd-addr
;
: get-macid-header   (  -- tag len1 keyword len2  )
   vpd-addr  dup c@  ( tag )
   swap 1+ dup uw@   ( tag len1 )
   swap 2+ dup uw@   ( tag len1 keyword )
   swap 2+ c@        ( tag len1 keyword len2 )
;

: verify-macid-header-ok?   ( tag len1 keyword len2 -- ok? )
   h# 6 <>  if 2drop drop false exit then
   ( tag len1 keyword )
   ( "NA" ) h# 4e41  <>  if  2drop false exit then
   ( tag len1 )
   h# 9  <>  if  drop false exit then
   h# 90  <>  if  false else  true  then
;
6 buffer: my-loc-mac-addr

: loc-mac-prop ( addr -- )
   6 encode-bytes " local-mac-address" property
;
: make-loc-mac ( -- )    my-loc-mac-addr  loc-mac-prop  ;
: get-macid ( -- valid? )
   get-macid-header
   verify-macid-header-ok?  if
     vpd-addr 6 + my-loc-mac-addr 6 cmove
     true
   else
     diagnostic-mode?  if
       ." Wrong Vital Product Data/Network Address header" cr
     then
     false
   then
;
: make-macid ( -- )
   get-macid  if
     make-loc-mac
   then
;

: create-macid ( -- )
   set-vpdp-value
   make-macid
   unset-vpdp-value
;
create-hme-attributes   \ Create ENET port device node.
create-macid
 

end0