Commit | Line | Data |
---|---|---|
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 ============================================ | |
42 | id: @(#)methods.fth 1.6 07/06/22 | |
43 | purpose: | |
44 | copyright: Copyright 2007 Sun Microsystems, Inc. All rights reserved. | |
45 | copyright: Use is subject to license terms. | |
46 | ||
47 | headerless | |
48 | ||
49 | h# ff.ff00 constant pci-device-mask \ pci device is 00000000.bbbbbbbb.dddddfff.00000000 | |
50 | h# 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 | ||
70 | external | |
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 | ||
88 | variable my-memlist my-memlist off | |
89 | variable my-mem64list my-mem64list off | |
90 | variable 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 | |
98 | then ( flag ) | |
99 | to 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 | ||
109 | 0 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 | |
113 | h# 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. | |
191 | 0 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 | ||
289 | headerless |