Contained Within
Find More Documentation
Featured Support Resources
| PDF로 이 문서 다운로드
PCI FCode Driver Example
13
- This example PCI FCode driver illustrates how to handle PCI-related registers in FCode.
-
id: %Z%%M% %I% %E%
purpose: A sample network PCI FCode driver showing use of Vital Product Data and
access to ROM.
copyright: Copyright 1994-1998 Sun Microsystems, Inc. All Rights Reserved
\ Each sample 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 00BB.XX00 0000.0000 0000.0000 0000.0000 0000.0000 (Cfg)
\ 02BB.XX10 0000.0000 0000.0000 0000.0000 0000.7020 (memory)
\
\ where "BB" = PCI Bus #
\ where "XX" = PCI Device # | Function #
\
Fcode-version3
hex
\ 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
0 value vpd-addr
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 )
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
;
: create-hme-attributes ( -- )
" SUNW,hme" name
" SUNW,cheerio" encode-string " model" property
" pci108e,1001" encode-string " pciclass,060000" encode-string
encode+ " compatible" 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
" %I%" 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 sample ethernet card 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
...
|
-
...
headers
: do-map-in ( offset slot# #bytes -- virtual ) " map-in" $call-parent ;
: do-map-out ( adr len -- ) " map-out" $call-parent ;
: do-dma-map-in ( vaddr n cache? -- devaddr ) " dma-map-in" $call-parent ;
: do-dma-map-out ( vaddr devaddr n -- ) " dma-map-out" $call-parent ;
: do-dma-alloc ( size -- addr ) " dma-alloc" $call-parent ;
: do-dma-free ( addr size -- ) " dma-free" $call-parent ;
: do-dma-sync ( virt-adr dev-adr size -- )
" dma-sync" ['] $call-parent catch if
3drop 2drop
then
;
...
...
0 instance value obp-tftp \ Contain ihandle of TFTP package.
: init-obp-tftp ( -- okay? )
" obp-tftp" find-package if ( phandle )
my-args rot open-package ( ihandle )
else 0
then
dup to obp-tftp ( ihandle | 0 )
dup 0= if
." Can't open OBP standard TFTP package" cr
then
;
...
...
external
: read ( buf len -- actual-len )
...
;
|
-
: write ( buf len -- actual-len )
...
...
;
: seek ( -- okay? )
." Unimplemented driver procedure: seek " cr 0
;
: selftest ( -- failed? ) \ Flag 0 if passes test.
...
...
;
: watch-net ( -- ) \ to watch network activity
...
...
;
: close ( -- )
...
...
obp-tftp ?dup if close-package then
...
...
;
: open ( -- okay? ) \ return true on successful open
...
...
init-obp-tftp 0= if close false exit then
true
;
: load ( adr -- len )
" load" obp-tftp $call-method
;
end0
|
|
|