Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | \ ========== Copyright Header Begin ========================================== |
2 | \ | |
3 | \ Hypervisor Software File: probe-reg.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: @(#)probe-reg.fth 1.16 06/11/01 | |
43 | purpose: PCI/UPA bus mapping | |
44 | copyright: Copyright 2006 Sun Microsystems, Inc. All Rights Reserved | |
45 | copyright: Use is subject to license terms. | |
46 | ||
47 | headerless | |
48 | ||
49 | \ Tokenizer extends bit[31] all the way to bit[63]. | |
50 | \ To create numbers with bit[31] set, but not extended to bit[63], | |
51 | \ we need to mask out the upper 32 bits | |
52 | : num-32 ( n -- l ) 0 lxjoin ; | |
53 | ||
54 | h# 0000.1fff invert constant pci-pagemask | |
55 | ||
56 | \ This struct has to be 64-bit aligned. | |
57 | struct | |
58 | /n field >bar.phys.hi \ encoded phys.hi | |
59 | /n + \ alignment padding | |
60 | /x field >bar.size \ current allocated size | |
61 | /x field >bar.value \ current PA | |
62 | /n field >bar.implemented? | |
63 | /n field >bar.assigned? | |
64 | constant /bar-struct | |
65 | ||
66 | d# 7 /bar-struct * constant /bar-data | |
67 | ||
68 | : alloc-bar-struct ( -- ptr ) /bar-data alloc-mem ; | |
69 | : free-bar-struct ( ptr -- ) /bar-data free-mem ; | |
70 | ||
71 | \ We always need at least one of these. | |
72 | alloc-bar-struct to bar-struct-addr | |
73 | ||
74 | \ this returns an effective bar# which may be used to index into bar.struct | |
75 | : get-bar# ( phys.hi -- bar# ) | |
76 | h# ff and ( cfg-offset ) | |
77 | h# 10 - 4 / ( bar# ) | |
78 | \ BARs 0-5 are normal. 6 is either at offset 30 or 38 (ROMBAR) | |
79 | dup h# 6 > if drop 6 then ( bar# ) | |
80 | ; | |
81 | ||
82 | : >bar-struct ( bar# -- struct ) /bar-struct * bar-struct-addr + ; | |
83 | ||
84 | : probe-l@ ( physhi -- n ) $config-l@ $call-parent ; | |
85 | : probe-l! ( n physhi -- ) $config-l! $call-parent ; | |
86 | ||
87 | : bar64? ( physhi -- flag ) cfg>ss# h# 3 and h# 3 = ; | |
88 | : 64bit-pref? ( physhi -- flag ) cfg>ss# h# 43 and h# 43 = ; | |
89 | : 64bit-assigned? ( ptr -- flag ) >bar.value x@ xlsplit nip 0<> ; | |
90 | false value mem64-support? | |
91 | ||
92 | \ | |
93 | \ This used to be clean.. now it is polluted with a BAR check! | |
94 | \ This is there because certain PLX devices violate the PCI SPEC by | |
95 | \ permitting thier IO/MEM bit to be *WRITEABLE*, so probing with -2 | |
96 | \ which should be safe for all BARs screws them up.. | |
97 | \ Wintel has a lot to answer for! | |
98 | \ | |
99 | : probe-reg ( physhi -- size ) | |
100 | dup bar64? if ( physhi ) | |
101 | dup >r probe-l@ ( old.lo ) ( R: physhi ) | |
102 | r@ 4 + probe-l@ ( old.lo old.hi ) ( R: physhi ) | |
103 | -1 r@ 2dup probe-l! 4 + probe-l! ( old.lo old.hi ) ( R: physhi ) | |
104 | r@ probe-l@ r@ 4 + probe-l@ 2swap ( new.lo new.hi old.lo old.hi ) ( R: physhi ) | |
105 | r@ 4 + probe-l! r> probe-l! lxjoin ( new-64value ) | |
106 | else | |
107 | dup >r probe-l@ ( old-value ) | |
108 | -1 r@ get-bar# 6 = if 1- then r@ probe-l! ( old-value ) | |
109 | r@ probe-l@ ( old-value new-value ) | |
110 | swap r> probe-l! ( new-value ) | |
111 | then | |
112 | ; | |
113 | ||
114 | : probe-base-reg ( offset -- offset implemented? ) | |
115 | my-space + ( phys.hi ) | |
116 | dup get-bar# dup >r 5 > if ( phys.hi ) | |
117 | \ This is a ROMBAR ( phys.hi ) | |
118 | 2 ss#>cfg or dup probe-reg ( phys.hi bits ) | |
119 | pci-pagemask and ( phys.hi size' ) | |
120 | 4 -rot ( #bytes phys.hi size' ) | |
121 | else ( phys.hi ) | |
122 | dup probe-l@ ( phys.hi bar-bits ) | |
123 | dup 1 and if ( phys.hi bar-bits ) | |
124 | \ I/O register ( phys.hi ) | |
125 | drop dup probe-reg ( phys.hi bits ) | |
126 | 3 invert and ( phys.hi bits ) | |
127 | dup h# 1.8000 and h# 0.8000 = if ( phys.hi bits ) | |
128 | \ Some cards don't implement the | |
129 | \ high bits in the I/O decoder. | |
130 | h# ffff d# 16 lshift or ( phys.hi bits' ) | |
131 | then ( phys.hi bits ) | |
132 | swap 1 ss#>cfg or swap ( phys.hi size ) | |
133 | 4 -rot ( 4 phys.hi size ) | |
134 | else ( phys.hi bar-bits ) | |
135 | \ Memory ( phys.hi bar-bits ) | |
136 | \ Save Bar contents for later use after this case | |
137 | tuck 1 >> 3 and case ( bar-bits phys.hi ) | |
138 | 0 of 2 ss#>cfg or 4 endof ( bar-bits phys.hi #bytes ) | |
139 | 1 of h# 82 ss#>cfg or 4 endof ( bar-bits phys.hi #bytes ) | |
140 | 2 of 3 ss#>cfg or 8 endof ( bar-bits phys.hi #bytes ) | |
141 | 3 of ." BAR has reserved bits set" abort endof | |
142 | endcase ( bar-bits phys.hi #bytes ) | |
143 | -rot ( #bytes bar-bits phys.hi ) | |
144 | \ If prefetchable bar, propagate into REG. | |
145 | \ prefetch bit is bit 3, from the pci local bus spec | |
146 | swap h# 8 and if 40 ss#>cfg or then ( #bytes phys.hi ) | |
147 | dup probe-reg ( #bytes phys.hi bits ) | |
148 | pci-pagemask and ( #bytes phys.hi bits' ) | |
149 | then ( #bytes phys.hi bits' ) | |
150 | then ( #bytes phys.hi bits' ) | |
151 | over bar64? if | |
152 | dup invert 1+ and ( #bytes phys.hi size ) | |
153 | else | |
154 | dup invert 1+ and32 ( #bytes phys.hi size ) | |
155 | then | |
156 | r> ( #bytes phys.hi size bar# ) | |
157 | >bar-struct ( #bytes phys.hi size adr ) | |
158 | over x0<> dup >r over >bar.implemented? ! ( #bytes phys.hi size adr ) | |
159 | debug-probe-bar? if ." ( " over .x ." )" then | |
160 | tuck >bar.size x! ( #bytes phys.hi adr ) | |
161 | >bar.phys.hi ! ( #bytes phys.hi adr ) | |
162 | r> ( #bytes implemented? ) | |
163 | ; | |
164 | ||
165 | : make-power-of-2 ( n -- n' ) | |
166 | d# 64 0 do ( n ) | |
167 | 1 i lshift ( n p2 ) | |
168 | 2dup x<= if ( n p2 ) | |
169 | nip leave ( p2 ) | |
170 | else ( n p2 ) | |
171 | drop ( n ) | |
172 | then ( n ) | |
173 | loop ( p2 ) | |
174 | ; | |
175 | ||
176 | \ How we assign physical resource to a BAR | |
177 | \ | |
178 | \ Note the defer.. | |
179 | \ It is unfortunate that this routine can be called in 2 different | |
180 | \ contexts. | |
181 | \ 1. (the normal path) As a result of normal BAR probing in which case | |
182 | \ the code is executing in the child instance and we need to | |
183 | \ $call-parent to do config accesses. | |
184 | \ 2. (the abnormal path) As a result of a map-in at probe time that | |
185 | \ exceeds the allocated resource sizes of the BAR. In which case | |
186 | \ we were called by $call-parent and now need to $call-self to do | |
187 | \ config accesses. | |
188 | \ | |
189 | \ By duplicating the $config-X $call-who I attempted to reduce the | |
190 | \ chances of someone accidently refering to the either uninitialised | |
191 | \ defer or the more likely incorrectly initialised defer. | |
192 | \ | |
193 | defer $call-who | |
194 | : (assign-bar-resources) ( phys.hi acf -- ) | |
195 | to $call-who ( phys.hi ) | |
196 | get-bar# >bar-struct >r ( -- ) | |
197 | r@ >bar.size dup x@ ( addr size ) | |
198 | make-power-of-2 tuck swap x! ( size ) | |
199 | r@ >bar.phys.hi @ ( size phys.hi ) | |
200 | cfg>ss# h# 3 and case ( -- ) | |
201 | 0 of 3drop true endof ( true ) | |
202 | 1 of dup pci-io-list allocate-memrange ( pa,0 | true ) | |
203 | dup 0= if ( pa,0 | true ) | |
204 | swap num-32 swap ( pa,0 ) | |
205 | over r@ >bar.phys.hi @ ( pa,0 pa phys.hi ) | |
206 | $config-l! $call-who ( pa,0 ) | |
207 | then ( pa,0 | true ) | |
208 | endof ( pa,0 | true ) | |
209 | 2 of dup pci-memlist allocate-memrange ( pa,0 | true ) | |
210 | dup 0= if ( pa,0 | true ) | |
211 | swap num-32 swap ( pa,0 ) | |
212 | over r@ >bar.phys.hi @ ( pa,0 pa phys.hi ) | |
213 | $config-l! $call-who ( pa,0 ) | |
214 | then ( pa,0 | true ) | |
215 | endof ( pa,0 | true ) | |
216 | 3 of ( size ) | |
217 | r@ >bar.phys.hi @ 64bit-pref? ( size 64bit-pref? ) | |
218 | mem64-support? and if ( size ) | |
219 | \ allocate from mem64 space | |
220 | dup pci-mem64list allocate-memrange ( pa,0 | true ) | |
221 | dup 0= if ( pa,0 | true ) | |
222 | r@ >bar.phys.hi @ >r ( pa 0 ) | |
223 | over xlsplit ( pa,0 pa.lo pa.hi ) | |
224 | r@ 4 + $config-l! $call-who ( pa,0 pa.lo ) | |
225 | r> $config-l! $call-who ( pa,0 ) | |
226 | then ( pa,0 | true ) | |
227 | else | |
228 | \ allocate from mem32 space | |
229 | dup pci-memlist allocate-memrange ( pa,0 | true ) | |
230 | dup 0= if ( pa,0 | true ) | |
231 | swap num-32 swap ( pa,0 ) | |
232 | r@ >bar.phys.hi @ >r ( pa 0 ) | |
233 | over r@ $config-l! $call-who ( pa,0 ) | |
234 | 0 r> 4 + $config-l! $call-who ( pa,0 ) | |
235 | then ( pa,0 | true ) | |
236 | then ( pa,0 | true ) | |
237 | endof ( pa,0 | true ) | |
238 | endcase ( pa,0 | true ) | |
239 | r> swap if ( ptr ) | |
240 | \ Resource allocation problem.. | |
241 | ." Unable to assign resources for device " | |
242 | " name" my-self ihandle>phandle get-package-property | |
243 | if ." <unnamed>" else type then cr | |
244 | drop abort ( -- ) | |
245 | else ( pa ptr ) | |
246 | debug-probe-bar? if ." Reg: " dup >bar.phys.hi @ .x ." = " over .x cr then | |
247 | true over >bar.assigned? ! ( pa ptr ) | |
248 | >bar.value x! ( -- ) | |
249 | then ( -- ) | |
250 | ; | |
251 | ||
252 | \ Called when probing, executing in child instance | |
253 | : assign-bar-resources ( phys.hi -- ) | |
254 | ['] $call-parent (assign-bar-resources) | |
255 | ; | |
256 | ||
257 | \ Called at probe time from map-in via a $call-parent | |
258 | : reassign-bar-resources ( phys.hi -- ) | |
259 | ['] $call-self (assign-bar-resources) | |
260 | ; | |
261 | ||
262 | \ | |
263 | \ How we release resources a BAR has been using. | |
264 | \ | |
265 | : release-bar-resources ( phys.hi -- ) | |
266 | dup get-bar# >bar-struct >r ( phys.hi -- ) | |
267 | r@ >bar.assigned? @ 0= if ( phys.hi ) | |
268 | r> 2drop ( -- ) | |
269 | then ( phys.hi ) | |
270 | 0 r@ >bar.assigned? ! ( phys.hi ) | |
271 | debug-probe-bar? if ." Releasing: BAR " dup .x ." = " then | |
272 | r@ >bar.value dup x@ ( phys.hi addr pa ) | |
273 | 0 rot x! ( phys.hi pa ) | |
274 | r> >bar.size x@ ( phys.hi pa len ) | |
275 | debug-probe-bar? if over .x dup .x cr then | |
276 | rot dup >r cfg>ss# 3 and ( pa len ss' ) ( R: phy.hi ) | |
277 | case ( pa len ) ( R: phy.hi ) | |
278 | 1 of pci-io-list endof ( pa len list ) ( R: phy.hi ) | |
279 | 2 of pci-memlist endof ( pa len list ) ( R: phy.hi ) | |
280 | 3 of | |
281 | r@ 64bit-pref? mem64-support? and if ( pa len ) ( R: phy.hi ) | |
282 | pci-mem64list ( pa len list ) ( R: phy.hi ) | |
283 | else | |
284 | pci-memlist ( pa len list ) ( R: phy.hi ) | |
285 | then | |
286 | endof | |
287 | endcase ( pa len list ) ( R: phy.hi ) | |
288 | free-memrange r> drop ( -- ) ( R: ) | |
289 | ; | |
290 | ||
291 | : read-bar-resources ( offset -- incr implemented ) | |
292 | debug-probe-bar? if ." read-bar-resources: " dup .x then | |
293 | \ This is called for devices that are currently enabled. | |
294 | \ We are much cruder here.. We set the size to the first multiple of | |
295 | \ 2 that the current register address is at. | |
296 | \ This is not optimal but is safe, probing an active device isn't. | |
297 | dup get-bar# >bar-struct >r ( offset ) | |
298 | my-space + ( phys.hi ) | |
299 | dup $config-l@ $call-parent ( phys.hi size ) | |
300 | over get-bar# 5 > if ( phys.hi size ) | |
301 | h# f ( phys.hi size mask ) | |
302 | else ( phys.hi size ) | |
303 | dup 1 and if 3 else h# f then ( phys.hi size mask ) | |
304 | then ( phys.hi size mask ) | |
305 | invert over and ( phys.hi size size' ) | |
306 | 0= if ( phys.hi size ) | |
307 | drop ( phys.hi ) | |
308 | my-space - ( offset ) | |
309 | dup probe-base-reg if ( phys.hi next ) | |
310 | swap assign-bar-resources true ( next true ) | |
311 | else ( phys.hi next ) | |
312 | nip false ( next 0 ) | |
313 | then ( offset implemented? ) | |
314 | r> drop ( offset implemented? ) | |
315 | else ( phys.hi size ) | |
316 | >r ( phys.hi ) | |
317 | r@ 1 and if ( phys.hi ) | |
318 | h# 81 ss#>cfg or 4 ( phsy.hi' size ) | |
319 | else ( phys.hi ) | |
320 | r@ 1 rshift 3 and 2 = ( phys.hi mem64? ) | |
321 | if 8 3 else 4 2 then ( phys.hi size type ) | |
322 | r@ 8 and if h# 40 or then swap ( phys.hi type' size ) | |
323 | >r h# 80 or ss#>cfg or r> ( phys.hi' size ) | |
324 | then ( phys.hi' size ) | |
325 | swap r> ( size phys.hi value ) | |
326 | debug-probe-bar? if over .x ." @ " dup .x then | |
327 | over cfg>mask and ( size phys.hi value' ) | |
328 | dup dup invert 1+ and ( size phys.hi value' decode ) | |
329 | debug-probe-bar? if ." ( " dup .x ." )" cr then | |
330 | r@ >bar.size x! ( size phys.hi value' ) | |
331 | dup r@ >bar.value x! ( size phys.hi value' ) | |
332 | 0<> ( size phys.hi 0? ) | |
333 | dup r@ >bar.assigned? ! ( size phys.hi 0? ) | |
334 | dup r@ >bar.implemented? ! ( size phys.hi 0? ) | |
335 | swap ( size 0? phys.hi ) | |
336 | r> >bar.phys.hi ! ( size 0? ) | |
337 | then | |
338 | ; | |
339 | ||
340 | : probe-and-assign-bar ( offset -- incr implemented? ) | |
341 | debug-probe-bar? if ." probe-and-assign-bar: " dup .x then | |
342 | dup probe-base-reg if ( phys.hi next ) | |
343 | swap assign-bar-resources true ( next true ) | |
344 | else ( phys.hi next ) | |
345 | debug-probe-bar? if cr then ( phys.hi next ) | |
346 | nip false ( next 0 ) | |
347 | then ( offset implemented? ) | |
348 | ; | |
349 | ||
350 | : device-enabled? ( -- flag? ) 4 parent-w@ 7 and ; | |
351 | ||
352 | defer build-bar-resources ( offset -- ) | |
353 | ||
354 | \ page 347 top para of PCI System Architecture | |
355 | \ 3rd edition (ISBN 0-201-40993-3) states: | |
356 | \ ... the configuration software will stop looking for base | |
357 | \ registers in a devices header when it detects the first | |
358 | \ unimplemented base register ... | |
359 | \ | |
360 | \ However the PCI spec states: | |
361 | \ The PCI specification Revision 2.2 states in section 6.2.5.1: | |
362 | \ A type 00h predefined header has six DWORD locations allocated | |
363 | \ for Base Address registers starting at offset 10h in Configuration | |
364 | \ Space. A device may use any of the locations to implement | |
365 | \ Base Address registers. An implemented 64-bit Base Address | |
366 | \ register consumes two consecutive DWORD locations. Software looking | |
367 | \ for implemented Base Address registers must start at offset 10h | |
368 | \ and continue upwards through offset 24h. | |
369 | \ | |
370 | ||
371 | : assign-addresses ( -- ) | |
372 | bar-struct-addr /bar-data erase ( -- ) | |
373 | device-enabled? if ( -- ) | |
374 | ['] read-bar-resources ( acf ) | |
375 | else ( -- ) | |
376 | ['] probe-and-assign-bar ( acf ) | |
377 | then to build-bar-resources ( -- ) | |
378 | base-register-bounds do ( -- ) | |
379 | i build-bar-resources drop ( next ) | |
380 | +loop ( ) | |
381 | card-bus? 0= if | |
382 | expansion-rom build-bar-resources 2drop ( ) | |
383 | then | |
384 | ; | |
385 | ||
386 | ||
387 | 0 value make-assigned? | |
388 | ||
389 | \ | |
390 | \ This routine is used to construct the "assigned-addresses" and the "reg" | |
391 | \ property. The code path was so similar it wasn't worth factoring. | |
392 | \ | |
393 | : make-reg-type-property ( assigned? -- xdr,len ) | |
394 | if h# 80 else 0 then to make-assigned? ( -- ) | |
395 | 0 0 encode-bytes ( xdr,len ) | |
396 | make-assigned? 0= if ( xdr,len ) | |
397 | my-space en+ 0 en+ 0 en+ ( xdr,len ) | |
398 | 0 en+ 0 en+ ( xdr,len ) | |
399 | then ( xdr,len ) | |
400 | 7 0 do ( xdr,len ) | |
401 | i >bar-struct ( xdr,len ptr ) | |
402 | dup >bar.implemented? @ if ( xdr,len ptr ) | |
403 | dup >bar.size x@ xlsplit swap >r >r ( xdr,len ptr ) | |
404 | dup >bar.phys.hi @ ( xdr,len ptr phys.hi ) | |
405 | [ifdef] 64BIT-ASSIGNED? | |
406 | \ If phys.hi has ss#=3, but the bar has been actually assigned | |
407 | \ 32-bit value because either the platform did not support | |
408 | \ mem64 space or the bar was not prefetchable, we should | |
409 | \ indicate ss#=2 in assigned-address property. | |
410 | make-assigned? if ( xdr,len ptr phys.hi ) | |
411 | dup cfg>ss# 3 and 3 = if ( xdr,len ptr phys.hi ) | |
412 | over 64bit-assigned? not if ( xdr,len ptr phys.hi ) | |
413 | 1 ss#>cfg xor ( xdr,len ptr phys.hi' ) | |
414 | then ( xdr,len ptr phys.hi' ) | |
415 | then ( xdr,len ptr phys.hi' ) | |
416 | then ( xdr,len ptr phys.hi' ) | |
417 | [then] | |
418 | dup not-relocatable? make-assigned? or if ( xdr,len ptr phys.hi ) | |
419 | over >bar.value x@ xlsplit swap ( xdr,len ptr phys.hi phys.mid phys.lo ) | |
420 | else ( xdr,len ptr phys.hi ) | |
421 | 0 0 ( xdr,len ptr phys.hi phys.mid phys.lo ) | |
422 | then >r >r ( xdr,len ptr phys.hi ) | |
423 | make-assigned? ss#>cfg or >r ( xdr,len ptr ) | |
424 | -rot r> r> r> r> r> encode5 rot ( xdr,len ptr ) | |
425 | >bar.phys.hi @ cfg>ss# ( xdr,len SS ) | |
426 | h# 3 and 3 <> if 1 else 2 then ( xdr,len incr ) | |
427 | else ( xdr,len ) | |
428 | drop 1 ( xdr,len incr ) | |
429 | then ( xdr,len incr ) | |
430 | +loop ( xdr,len ) | |
431 | ; | |
432 | ||
433 | : make-reg-property ( -- ) 0 make-reg-type-property " reg" property ; | |
434 | ||
435 | \ | |
436 | \ We only need to decode the "reg" property if we evaluated some fcode | |
437 | \ because that is the only way the reg property could be made to differ | |
438 | \ from the h/w. | |
439 | \ | |
440 | \ We pull this stunt to permit cards that lie about thier decode ability | |
441 | \ in h/w to be corrected in s/w. Certain Diamond cards are guilty of this. | |
442 | \ | |
443 | : make-assigned-property ( parse? -- ) | |
444 | " reg" my-self ihandle>phandle ( parse? reg$ phandle ) | |
445 | get-package-property if drop exit then ( parse? xdr,len ) | |
446 | rot 0= if drop 0 then ( xdr,len' ) | |
447 | begin ( xdr,len ) | |
448 | dup 0> while ( xdr,len ) | |
449 | decode-int ( xdr,len phys.hi ) | |
450 | >r decode-int drop decode-int drop ( xdr,len ) | |
451 | decode-int >r decode-int r> lxjoin ( xdr,len len ) | |
452 | r> dup cfg>ss# 3 and if ( xdr,len len phys.hi ) | |
453 | dup get-bar# >bar-struct >r ( xdr,len len phys.hi ) | |
454 | r@ >bar.implemented? @ if ( xdr,len len phys.hi ) | |
455 | drop r@ >bar.size x@ over x< if ( xdr,len len reg-bigger? ) | |
456 | r@ >bar.phys.hi @ ( xdr,len len phys.hi ) | |
457 | dup release-bar-resources ( xdr,len len phys.hi ) | |
458 | swap r@ >bar.size x! ( xdr,len phys.hi ) | |
459 | assign-bar-resources ( xdr,len ) | |
460 | 0 ( xdr,len 0 ) | |
461 | then ( xdr,len ? ) | |
462 | else ( xdr,len len phys.hi ) | |
463 | -1 r@ >bar.implemented? ! ( xdr,len len phys.hi ) | |
464 | r@ >bar.phys.hi ! ( xdr,len len ) | |
465 | r@ >bar.size x! ( xdr,len ) | |
466 | 0 ( xdr,len 0 ) | |
467 | then ( xdr,len ? ) | |
468 | r> ( xdr,len ? ? ) | |
469 | then ( xdr,len ? ? ) | |
470 | 2drop ( xdr,len ) | |
471 | repeat 2drop ( -- ) | |
472 | 1 make-reg-type-property dup if | |
473 | " assigned-addresses" property | |
474 | else | |
475 | 2drop | |
476 | then | |
477 | ; | |
478 | ||
479 | : .dump-assigned-addr ( -- ) | |
480 | ." Assigned BARs:" cr | |
481 | 7 0 do | |
482 | i >bar-struct >r | |
483 | r@ >bar.implemented? @ r@ >bar.assigned? @ and if | |
484 | r@ >bar.phys.hi @ ." Phys.hi: " .x | |
485 | r@ >bar.size x@ ." size: " .x | |
486 | r@ >bar.value x@ ." located: " .x cr | |
487 | r> >bar.phys.hi @ cfg>ss# 3 = if 2 else 1 then | |
488 | else | |
489 | r> drop 1 | |
490 | then | |
491 | +loop cr | |
492 | ; | |
493 | ||
494 | : list>property ( xdr,len list ss -- xdr,len ) | |
495 | over if | |
496 | swap begin ( xdr,len ss node ) | |
497 | dup while ( xdr,len ss node ) | |
498 | dup >mem.size x@ xlsplit swap >r >r ( xdr,len ss node ) | |
499 | dup >mem.adr x@ xlsplit swap >r >r ( xdr,len ss node ) | |
500 | over ss#>cfg >r ( xdr,len ss node ) | |
501 | >next-node @ 2swap r> r> r> r> r> encode5 2swap ( xdr,len ss node ) | |
502 | repeat 2drop ( xdr,len ) | |
503 | else | |
504 | 2drop ( xdr,len ) | |
505 | then | |
506 | ; | |
507 | ||
508 | : make-available-property ( -- ) | |
509 | 0 0 encode-bytes ( xdr,len ) | |
510 | pci-io-list @ h# 81 list>property ( xdr,len ) | |
511 | pci-memlist @ h# 82 list>property ( xdr,len ) | |
512 | pci-mem64list @ h# c3 list>property ( xdr,len ) | |
513 | ?dup if " available" property else drop then ( ) | |
514 | ; |