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
|