Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / obp / obp / dev / sun4v-devices / vpci / methods.fth
CommitLineData
920dae64
AT
1\ ========== Copyright Header Begin ==========================================
2\
3\ Hypervisor Software File: methods.fth
4\
5\ Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
6\
7\ - Do no alter or remove copyright notices
8\
9\ - Redistribution and use of this software in source and binary forms, with
10\ or without modification, are permitted provided that the following
11\ conditions are met:
12\
13\ - Redistribution of source code must retain the above copyright notice,
14\ this list of conditions and the following disclaimer.
15\
16\ - Redistribution in binary form must reproduce the above copyright notice,
17\ this list of conditions and the following disclaimer in the
18\ documentation and/or other materials provided with the distribution.
19\
20\ Neither the name of Sun Microsystems, Inc. or the names of contributors
21\ may be used to endorse or promote products derived from this software
22\ without specific prior written permission.
23\
24\ This software is provided "AS IS," without a warranty of any kind.
25\ ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
26\ INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
27\ PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
28\ MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
29\ ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
30\ DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN
31\ OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR
32\ FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
33\ DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
34\ ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
35\ SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
36\
37\ You acknowledge that this software is not designed, licensed or
38\ intended for use in the design, construction, operation or maintenance of
39\ any nuclear facility.
40\
41\ ========== Copyright Header End ============================================
42id: @(#)methods.fth 1.6 07/06/22
43purpose:
44copyright: Copyright 2007 Sun Microsystems, Inc. All rights reserved.
45copyright: Use is subject to license terms.
46
47headerless
48
49h# ff.ff00 constant pci-device-mask \ pci device is 00000000.bbbbbbbb.dddddfff.00000000
50h# fff constant pci-reg-mask \ pci register is 00000000.00000000.0000rrrr.rrrrrrrr
51
52: config-@ ( phys.hi size -- data )
53 dup rot dup pci-device-mask and swap ( size size pci-device phys.hi )
54 phys.hi>cfg-offset pci-reg-mask and rot ( size pci-device offset size )
55 pci-config-get 0<> if ( size data )
56 drop ( size )
57 \ 1 -> 0xff, 2 -> 0xffff, 4 -> 0xffff.ffff
58 0 swap 8 * 0 do h# ff i << or 8 +loop ( data )
59 else ( size data )
60 nip ( data )
61 then ( data )
62;
63
64: config-! ( data phys.hi size -- )
65 rot >r >r dup pci-device-mask and swap ( pci-device phys.hi )( R: data size )
66 phys.hi>cfg-offset pci-reg-mask and r> r> ( pci-device offset size data )
67 pci-config-put drop ( )
68;
69
70external
71
72: config-b@ ( phys.hi -- b ) 1 config-@ ;
73: config-b! ( b phys.hi -- ) 1 config-! ;
74: config-w@ ( phys.hi -- w ) 2 config-@ ;
75: config-w! ( w phys.hi -- ) 2 config-! ;
76: config-l@ ( phys.hi -- l ) 4 config-@ ;
77: config-l! ( l phys.hi -- ) 4 config-! ;
78
79: decode-unit ( adr len -- phys.lo phys.mid phys.hi )
80 pci-decode-unit lwsplit drop my-pci-bus wljoin
81;
82
83: encode-unit ( phys.lo phys.mid phys.hi -- adr len ) pci-encode-unit ;
84
85: map-in ( p.low p.mid p.hi len -- vaddr ) pci-map-in ;
86: map-out ( va len -- ) " map-out" $call-parent ;
87
88variable my-memlist my-memlist off
89variable my-mem64list my-mem64list off
90variable my-io-list my-io-list off
91
92\ get-package-property for boolean property in
93\ /options node returns value instead of adr,len
94\ as defined by IEEE.
95" /options" find-package drop ( phandle )
96" pci-mem64?" rot get-package-property if
97 false
98then ( flag )
99to mem64-support? \ This flag needs to be set true for
100 \ host-bridge that support mem64 space.
101
102: allocate-bus# ( n mem-aln mem-sz mem64-aln mem64-sz io-aln io-sz -- . . . . . . . )
103 ( . . . . . -- mem-l mem64-l io-l dma-l mem-h mem64-h io-h dma-h bus# )
104 pci-allocate-bus#
105;
106: assign-int-line ( int phys.hi -- false ) 2drop false ;
107: prober ( adr len -- ) pci-prober ;
108
1090 value current-md-node
110
111\ 0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f,10,11,12,13,14,15,16,17,18,19,1a,1b,1c,1d,1e,1f
112\ is 0x50 bytes
113h# 50 constant /pci-probe-path-buffer
114
115: get-node-dev-fcn ( nptr -- dev fcn true | false )
116 dup " device-number" ascii v md-find-prop ( nptr prop | false )
117 dup if ( nptr prop | false )
118 md-decode-prop drop swap ( dev nptr )
119 " function-number" ascii v md-find-prop ( dev prop|false )
120 dup if ( dev prop| false )
121 md-decode-prop drop true ( dev fcn true )
122 else ( dev false )
123 nip ( false )
124 then ( dev fcn true | false )
125 else ( nptr false )
126 nip ( false )
127 then ( dev fcn true | false )
128;
129
130\ find-my-md-node is a recursive function that parses the MD starting at
131\ the node pointed to by nptr2 looking for a node that matches the child
132\ device string found in '$path'. The resulting node will be returned in
133\ nptr1.
134: find-my-md-node ( nptr1 $path nptr2 -- nptr1 $path )
135 recursive
136 >r 2dup ascii / left-parse-string 2swap 2drop ( nptr1 $path $path' )( R: nptr2 )
137 ascii @ left-parse-string 2drop ( nptr1 $path $unit )
138 decode-unit nip nip ( nptr1 $path phys.hi )
139 dup cfg>dev# swap cfg>fcn# ( nptr1 $path dev fcn )
140 r@ get-node-dev-fcn if ( nptr1 $path dev fcn [dev' fcn' | ] )
141 rot = -rot = and if ( nptr1 $path )
142 ascii / left-parse-string 2drop ( nptr1 $path' )
143 dup if ( nptr1 $path' )
144 ['] find-my-md-node r> md-applyto-fwds ( nptr1 $path'' )
145 else ( nptr1 $path' )
146 \ Found it!
147 rot drop r> -rot ( nptr1' $path )
148 then
149 else ( nptr1 $path )
150 \ Keep looking
151 r> drop ( nptr1 $path )
152 then ( nptr1 $path )
153 else ( nptr1 $path dev fcn )
154 \ No device/function number in the MD node
155 r> 3drop ( nptr1 $path )
156 then ( nptr1 $path )
157;
158
159\ If the 'node' has a 'device-number' property, pushd it on the stack
160\ and increase the #dev counter.
161: find-child-dev# ( #devs node -- dev #devs+1 )
162 " device-number" ascii v md-find-prop ?dup if ( #devs prop )
163 md-decode-prop drop swap 1+ ( dev #devs+1 )
164 then ( dev #devs+1 )
165;
166
167: (make-probe-list) ( ...#devs -- $probe-list)
168 <# ( ... x3 x2 x1 #devs )
169 begin ( ... x3 x2 x1 #devs )
170 swap u#s drop ( ... x3 x2 #devs )
171 1- dup ( ... x3 x2 #devs' #devs' )
172 while ( ... x3 x2 #devs' )
173 ascii , hold ( ... x3 x2 #devs' )
174 repeat ( ... x3 x2 #devs' )
175 u#> ( $probe-list )
176;
177
178\ For each device number on the stack, add it to the probe list.
179\ For example,
180\ 1 1 --> One device -- > " 1"
181\ 1 4 7 3 -- > Three devices --> " 1,4,7"
182: make-probe-list ( ... #devs buffer -- $probe-list )
183 >r (make-probe-list) ( $probe-list )( R: buffer )
184 tuck r@ swap move ( len )( R: buffer )
185 r> swap ( $probe-list )
186;
187
188
189\ Use a simple bit mask to remove duplicate device numbers.
190\ Kind of like a zipper down and up the stack.
1910 value dev-mask
192: rm-duplicates ( ... #dev -- ... #dev' )
193 -1 to dev-mask ( ... x3 x2 x1 #dev )
194 0 ?do ( ... x3 x2 x1 )
195 1 swap << invert dev-mask and ( ... x3 x2 mask )
196 to dev-mask ( ... x3 x2 )
197 loop ( ... x3 x2 )
198 0 d# 32 0 do ( #dev )
199 1 i << dev-mask and 0= if ( #dev )
200 i swap 1+ ( ... #dev' )
201 then ( ... #dev' )
202 loop ( ... #dev' )
203;
204
205: sun4v-pci-prober ( $probe-list -- )
206 make-path$ 0= if ( $probe-list )
207 cmn-error[ " Could not create device path" ]cmn-end 2drop exit
208 then ( $probe-list )
209 pci-path count ( $probe-list $current-path )
210
211 \ Trim the '/pci@X,Y/' from the upper characters of the current device path
212 ascii / left-parse-string 2drop ( $probe-list $current-path' )
213 ascii / left-parse-string 2drop ( $probe-list $child-path )
214
215 \ Put a zero on the stack for symmetry. This will become the child
216 \ node pointer (nptr).
217 0 -rot ( $probe-list nptr $child-path )
218 ['] find-my-md-node my-node md-applyto-fwds ( $probe-list nptr $child-path )
219
220 \ Save current node pointer for later.
221 2drop current-md-node >r ( $probe-list nptr )( R: current )
222
223 ?dup if ( $probe-list nptr| )
224 \ We found an MD node for this PCI device
225 >r r@ to current-md-node ( $probe-list )( R: current nptr )
226 r@ " slot-present" ascii v md-find-prop if
227 \ This is a PCI slot, so there won't be any child device ndoes in the MD.
228 \ Use method argument $probe-list
229 r> drop pci-prober ( )
230 else ( $probe-list )( R: current nptr )
231 \ This is an onboard PCI device node, so there had better be an MD node for it.
232 \ Use the fwd links to create the proper probe list.
233 2drop ( )
234 0 ['] find-child-dev# r> md-applyto-fwds ( ... #dev )
235 ?dup if ( ... #dev | 0 )
236 \ Multi-function devices will show up twice. Remove them.
237 rm-duplicates ( ... #dev' )
238
239 /pci-probe-path-buffer alloc-mem ( ... #dev' buffer )
240 dup >r make-probe-list ( $probe-list )( R: buffer )
241 pci-prober ( )
242 r> /pci-probe-path-buffer free-mem ( )
243 then ( )
244 then ( )
245 else ( $probe-list )
246 \ Could not find MD node; Use method argument 'probe-list'
247 pci-prober ( )
248 then ( )
249 r> to current-md-node ( )( R: )
250;
251
252\ The 'NON-MD-IODEVICE' flag can be turned on to probe an unknown hardware
253\ IO topology. The MD will not be checked, so all devices on every pci bus
254\ will be probed.
255: prober-xt ( -- adr )
256[ifdef] NON-MD-IODEVICE
257 ['] pci-prober
258[else]
259 ['] sun4v-pci-prober
260[then]
261;
262
263: master-probe ( -- )
264 my-node
265 dup to current-md-node
266
267 \ We need the hotplug slot count properties before probing since the
268 \ pci bridge code inherits this property.
269 dup " level2-hotplug-slot-count" ascii v md-find-prop ?dup if
270 md-decode-prop drop encode-int " level2-hotplug-slot-count" property
271 then
272 " level1-hotplug-slot-count" ascii v md-find-prop ?dup if
273 md-decode-prop drop encode-int " level1-hotplug-slot-count" property
274 then
275
276 bar-struct-addr my-memlist @ my-mem64list @ my-io-list @ ( reg mem mem64 io )
277 set-pointers ( -- )
278 setup-swapped-fcodes
279 pci-master-probe
280 make-available-property ( -- )
281 get-pointers ( reg mem mem64 io )
282 my-io-list ! my-mem64list ! my-memlist ! drop ( -- )
283 restore-fcodes
284;
285
286: open true ;
287: close ;
288
289headerless