Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / obp / obp / dev / pci / pcibus.fth
CommitLineData
920dae64
AT
1\ ========== Copyright Header Begin ==========================================
2\
3\ Hypervisor Software File: pcibus.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: @(#)pcibus.fth 1.20 06/11/01 08:58:38
43purpose:
44copyright: Copyright 2006 Sun Microsystems, Inc. All Rights Reserved
45copyright: Use is subject to license terms.
46
47hex
48
49h# 40 buffer: function-reg-string
500 value pci-depth
51
52headerless
53 0 value current-bus#
54false value probe-state?
55
56: $config-b@ ( -- str$ ) " config-b@" ;
57: $config-b! ( -- str$ ) " config-b!" ;
58: $config-w@ ( -- str$ ) " config-w@" ;
59: $config-w! ( -- str$ ) " config-w!" ;
60: $config-l@ ( -- str$ ) " config-l@" ;
61: $config-l! ( -- str$ ) " config-l!" ;
62
63fload ${BP}/dev/pci/make-device.fth
64fload ${BP}/dev/pci/make-path.fth
65
66[ifdef] OBERON?
67fload ${BP}/dev/oberon/opl/hwd.fth
68fload ${BP}/dev/oberon/opl/slot-names.fth
69[then]
70
71\
72\ bridges need to be able to create some properties after the device
73\ has completed probing (available for example) this allows well-known
74\ devices to hook code into the point after any fcode will have completed.
75\
76defer extra-device-function-hook
77
78: make-function-node ( arg$ reg$ -- )
79 new-device set-args ( )
80 populate-device-node ( )
81 extra-device-function-hook ( )
82 ['] noop to extra-device-function-hook ( )
83[ifdef] OBERON?
84 " okay" create-status-prop ( )
85[then]
86 finish-device ( )
87;
88
89\
90\ ---------------------------------------------------------------------
91\ From here down all accesses are in the 'parents' instance, so we
92\ need to use self-X type words. Ie these routines are executing in
93\ a host adapter context (pci/pci bridge or host/pci device).
94
95: self-b@ ( phys.hi -- b ) $config-b@ $call-self ;
96: self-b! ( b phys.hi -- ) $config-b! $call-self ;
97: self-w@ ( phys.hi -- b ) $config-w@ $call-self ;
98: self-w! ( w phys.hi -- ) $config-w! $call-self ;
99: self-l@ ( phys.hi -- l ) $config-l@ $call-self ;
100: self-l! ( l phys.hi -- ) $config-l! $call-self ;
101
102: amend-reg$ ( reg$ func# -- reg$' )
103 push-hex
104 >r ascii , left-parse-string ( rem$ head$ )
105 2swap 2drop $hnumber if 0 then r> ( dev# func# )
106 <# u# drop ascii , hold u#s u#> function-reg-string $save
107 pop-base
108;
109
110\ Returns true if the card implements a function at the indicated
111\ configuration address.
112\
113: function-present? ( phys.hi -- flag ) self-w@ h# ffff <> ;
114
115headers
116\ Create a string of the form "D,F" where D is the device number portion
117\ of the string "reg$" and F is the hexadecimal representation of "func#"
118\ Probe the card function func#
119: probe-function ( arg$ reg$ phys.hi fn# -- arg$ reg$ phys.hi )
120 2dup fcn#>cfg + function-present? if ( arg$ reg$ phys.hi fn# )
121 2>r 2over 2over ( arg$ reg$ arg$ reg$ )
122 r@ amend-reg$ ( arg$ reg$ arg$ reg$ )
123 make-function-node ( arg$ reg$ )
124 2r> ( arg$ reg$ phys.hi fn# )
125 then drop ( arg$ reg$ phys.hi )
126;
127
128\ Returns 0 if the card isn't present, 8 for a multifunction card, 1 otherwise
129: max#functions ( phys.hi -- phys.hi n )
130 dup function-present? if ( phys.hi )
131 dup h# e + self-b@ ( phys.hi field )
132 h# 80 and if 8 else 1 then ( phys.hi n )
133 else ( phys.hi )
134 0 ( phys.hi n )
135 then
136;
137headerless
138
139\ Probe the card at the address given by fcode$, setting my-address,
140\ my-space in the resulting device node to the address given by reg$.
141\
142\ probe-self is meant to handle one PCI device (= 1 physical slot)
143\ at a time. Up to 8 functions are checked per device. Each can have
144\ a separate piece of FCode controlling it.
145
146: clear-pci-errs ( phys.hi -- )
147 6 + dup self-w@ ( stat-reg-addr data )
148 h# f900 and ( stat-reg-addr clr-err-bits )
149 swap self-w! ( -- )
150;
151
152: .nothing-there diagnostic-mode? if " Nothing there" cmn-append then ;
153
154\ This is the entry point into the ASR framework.
155\ Leave the dev#$ alone and return a flag of true
156\ if the device is disabled, otherwise false.
157\ If necessary, in the disabled? case, the dev#$
158\ may be modified for printability.
159defer device-disabled? ( dev#$ -- dev#$' disabled? )
160' false is device-disabled?
161
162: .probing-path ( dev#$' flag -- dev#$' flag )
163 diagnostic-mode? if
164 " Device " cmn-append 3dup drop cmn-append " " cmn-append
165 then
166;
167
168\ Defer word to be redefined differently at platform level
169defer pci-function-present?
170' function-present? is pci-function-present?
171
172\
173\ The pci-pci bridge probing code.
174\
175: pci-probe-self ( args$ dev#$ -- )
176 ['] noop
177 debug-bar-assignment? if drop ['] .dump-assigned-addr then
178 to extra-device-function-hook
179 true to probe-state?
180
181 device-disabled? ( arg$ dev#$' flag )
182 .probing-path
183 if 2drop 2drop ( )
184 diagnostic-mode? if " <Device/Slot Disabled>" cmn-append then
185 exit
186 then ( args$ dev#$ )
187
188 2dup (decode-unit) nip nip ( args$ dev#$ phys.hi.dev )
189 dup pci-function-present? if ( args$ dev#$ phys.hi.dev )
190 max#functions ?dup if
191 0 do i probe-function loop ( args$ dev#$ phys.hi.dev )
192 else
193 .nothing-there
194 then
195 else ( args$ dev#$ phys.hi.dev )
196 .nothing-there
197 then ( args$ dev#$ phys.hi.dev )
198
199 3drop 2drop ( )
200 false to probe-state?
201;
202
203\ This is the top level prober.
204\ The maximum depth of 9 is to ensure that we don't overflow the
205\ return stack as we recurse. Better to not probe devices than
206\ to crash in some spectacular way.
207\
208
209[ifdef] OBERON?
210
211: pci-prober-pass ( args$ dev#$ -- )
212 diagnostic-mode? if cmn-msg[ then
213 pci-probe-self
214 diagnostic-mode? if " " ]cmn-end then
215;
216
217: pci-prober ( probe-list$adr,len -- )
218 \ Increase pci-depth to support iobox.
219 pci-depth 9 > if
220 ." Maximum PCI probe depth " pci-depth . ." exceeded; "
221 ." No further PCI bridge devices can be probed" cr
222 2drop exit
223 then
224 oberon-debug? if cr ." pci-prober: pci-depth=" pci-depth .d cr then
225
226 make-path$ if
227 oberon-debug? if ." devpath=" .path$ then
228 else
229 cmn-warn[ " make-path$ failed" ]cmn-end
230 2drop exit
231 then ( $adr,len )
232
233 pci-path count make-pcipath-id if
234 cmn-warn[ " make-pcipath-id failed" ]cmn-end
235 2drop exit
236 else
237 oberon-debug? if ." (id=" dup 64.x ." ): " cr then
238 -rot ( id $adr,len )
239 then
240 oberon-debug? if ." probe-list$=" 2dup type cr then
241 2 pick create-pci-slot-names-prop ( id $adr,len )
242 select-hwdtab&get-hwdstat
243 pci-depth dup >r 1+ to pci-depth ( id $adr,len ) ( R: old-pci-dpth )
244 begin dup while ( id $adr,len ) ( R: old-depth )
245 ascii , left-parse-string ( id rem$ dev#$ ) ( R: old-depth )
246 " " 2swap ( id rem$ arg$ dev#$ ) ( R: old-d )
247
248 push-hex 2dup $number drop pop-base ( id rem$ arg$ dev#$ dev# )
249 7 pick ( id rem$ arg$ dev#$ dev# id )
250 get-hwd-status if HWDESC-STAT-UNKNOWN then ( id rem$ arg$ dev#$ hwd-stat )
251 case
252 HWDESC-STAT-PASS of pci-prober-pass endof
253 dup of 2drop 2drop endof
254 endcase ( id rem$ )
255 repeat ( id null$ ) ( R: old-depth )
256 3drop
257 r> to pci-depth
258 oberon-debug? if cr then
259;
260
261[else]
262
263: pci-prober ( probe-list$adr,len -- )
264 pci-depth 9 > if
265 ." Maximum PCI probe depth " pci-depth . ." exceeded;"
266 ." No further PCI bridge devices can be probed" cr
267 2drop exit
268 then
269 pci-depth dup >r 1+ to pci-depth ( $adr,len ) ( R: old-pci-dpth )
270
271 begin dup while ( $adr,len ) ( R: old-depth )
272 ascii , left-parse-string ( rem$ dev#$ ) ( R: old-depth )
273 " " 2swap ( rem$ arg$ dev#$ ) ( R: old-d )
274
275 diagnostic-mode? if cmn-msg[ then
276
277 pci-probe-self
278
279 diagnostic-mode? if " " ]cmn-end then
280
281 repeat ( null$ ) ( R: old-depth )
282
283 2drop
284 r> to pci-depth
285;
286
287[then]
288
289: get-my-pci-bus# ( -- n ) " my-pci-bus" $call-self ;
290
291: pci-master-probe ( adr,len -- )
292 0 to pci-depth
293
294 \ If previously probed, we need to update current-bus#
295 " bus-range" get-my-property 0= if
296 decode-int nip nip to current-bus#
297 else
298 get-my-pci-bus# to current-bus#
299 then
300
301 " prober" $call-self
302 get-my-pci-bus# bus#>cfg clear-pci-errs
303
304 get-my-pci-bus# encode-int
305 current-bus# encode-int encode+ " bus-range" property
306;
307
308\ This is called twice for each PCI-PCI bridge,
309\ It is called with n=1 at the beginning of the bridge probing sequence,
310\ in order to allocate a new bus number and establish base address values.
311\ It is called with n=0 at the end of the bridge probing sequence,
312\ in order to determine the "high water marks" of the bus numbers and
313\ address ranges that were assigned during the (possibly recursive)
314\ bridge probing process.
315
316: trim-node ( node memlist align -- )
317 >r ( node memlist )
318 2dup remove-selected-node drop ( node memlist )
319 2dup r@ swap round-node-up ( node memlist )
320 r> swap round-node-down ( -- )
321;
322
323: .no-resource ( -- )
324 cmn-error[ " No resource available for bridge" ]cmn-end
325;
326
327: allocate-biggest-resources ( list align -- node )
328 over get-biggest-node ( list align node )
329 dup 0= if ( list align node )
330 3drop .no-resource abort
331 then
332 dup >r -rot trim-node r> ( node )
333;
334
335: allocate-actual-resources ( list align size -- node )
336 dup >r rot allocate-memrange if
337 r> drop .no-resource abort
338 else
339 r> swap set-node ( node )
340 then ( node)
341;
342
343: get-ranges ( mem-n mem64-n io-n -- mem-l mem64-l io-l mem-h mem64-h io-h )
344 3dup >r >r >r alloc-bar-struct r> r> r> push-stack
345 ( mem-n mem64-n io-n )
346 >r >r node-range over + ( mem-l mem-h )
347 ( R: io-n mem64-n )
348 r> ?dup if node-range over + else 0 0 then rot swap
349 ( mem-l mem64-l mem-h mem64-h )
350 ( R: io-n )
351 r> node-range over + ( mem-l mem64-l mem-h mem64-h io-l io-h )
352 >r -rot r> ( mem-l mem64-l io-l mem-h mem64-h io-h )
353;
354
355\ If size is zero, acquire the largest available piece of the resource.
356: acquire-bridge-resources ( list align size -- node )
357 ?dup if
358 allocate-actual-resources
359 else
360 allocate-biggest-resources
361 then
362;
363
364
365external
366
367\
368\ This routine allows allocation of resources from the current IO/MEM lists.
369\
370: resource-alloc ( physhi align size -- addr|0 )
371 rot cfg>ss# 7 and case
372 0 of 2drop false exit endof \ cannot claim cfg space
373 1 of pci-io-list endof
374 2 of pci-memlist endof
375 3 of mem64-support? if pci-mem64list else pci-memlist then endof
376 endcase ( list )
377 allocate-memrange if false then ( addr|0 )
378;
379
380\ This routine returns a range to the relevant list.
381\ Be CAREFUL no checking is done to verify that an allocation from one
382\ pool is not returned to the other, nor that you are freeing more than
383\ you alloc'd.
384: resource-free ( physhi addr len -- )
385 rot cfg>ss# 7 and case
386 0 of 2drop exit endof \ cannot claim cfg space
387 1 of pci-io-list endof
388 2 of pci-memlist endof
389 3 of mem64-support? if pci-mem64list else pci-memlist then endof
390 endcase ( list )
391 free-memrange ( )
392;
393
394headerless
395
396/n 3 * buffer: pci-alloc-lists
397: 3@ ( a-addr -- x1 x2 x3 ) dup >r @ r@ /n + @ r> /n 2* + @ ;
398: 3! ( x1 x2 x3 a-addr -- ) tuck /n 2* + ! tuck /n + ! ! ;
399
400: make-bridge-extra-properties ( -- )
401 \ Called after the bridge has been probed completely.
402 \ The purpose of this routine is to create the 'available' property and
403 \ then free the nodes.
404 get-pointers >r >r >r >r ( ) ( R: io mem64 mem reg )
405 r@ pci-alloc-lists 3@ set-pointers ( ) ( R: io mem64 mem reg )
406 make-available-property ( ) ( R: io mem64 mem reg )
407 pci-alloc-lists 3@ debug-keep-mem-lists? if ( mem mem64 io )
408 ( R: io mem64 mem reg )
409 \ Some useful bridge debug properties.
410 " io-list" integer-property ( mem mem64 )
411 ( R: io mem64 mem reg )
412 " mem64-list" integer-property ( mem ) ( R: io mem64 mem reg )
413 " mem-list" integer-property ( ) ( R: io mem64 mem reg )
414 else ( mem mem64 io )
415 ( R: io mem64 mem reg )
416 free-list free-list free-list ( ) ( R: io mem64 mem reg )
417 then ( ) ( R: io mem64 mem reg )
418 r> r> r> r> set-pointers ( ) ( R: )
419;
420
421: align-resource-list ( align list -- node )
422 dup get-last-node nip ( align list node )
423 dup if ( align list node )
424 tuck over remove-selected-node drop ( align node list )
425 swap dup >r -rot round-node-up r> ( node )
426 else ( align list node )
427 3drop 0 ( 0 )
428 then
429;
430
431\ If either of the node parameters is zero, this function will
432\ bypass the clause that "hands the resource back to the parent";
433\ this behavior may be required for hotplug-capable bridges.
434: free-resources ( mem-n mem64-n io-n -- mem-l mem64-l io-l mem-h mem64-h io-h )
435 pop-stack ( mem-n mem64-n io-n reg mem mem64 io )
436 pci-alloc-lists 3! ( mem-n mem64-n io-n reg )
437 free-bar-struct ( mem-n mem64-n io-n )
438 ['] make-bridge-extra-properties ( mem-n mem64-n io-n acf )
439 to extra-device-function-hook ( mem-n mem64-n io-n )
440 \ When we get here we have removed the trailing resources
441 \ from the bridge. Now we need to hand the resources back
442 \ to the parent bridge.
443 dup if ( mem-n mem64-n io-n )
444 dup node-range ( mem-n mem64-n io-n adr len )
445 2dup pci-io-list free-memrange ( mem-n mem64-n io-n adr len )
446 drop swap free-node ( mem-n mem64-n io-h )
447 then ( mem-n mem64-n io-h )
448 >r dup if ( mem-n mem64-n ) ( R: io-h )
449 dup node-range ( mem-n mem64-n adr len ) ( R: io-h )
450 2dup pci-mem64list free-memrange ( mem-n mem64-n adr len ) ( R: io-h )
451 drop swap free-node ( mem-n mem64-h ) ( R: io-h )
452 then ( mem-n mem64-h ) ( R: io-h )
453 >r dup if ( mem-n ) ( R: io-h mem64-h )
454 dup node-range ( mem-n adr len ) ( R: io-h mem64-h )
455 2dup pci-memlist free-memrange ( mem-n adr len ) ( R: io-h mem64-h )
456 drop swap free-node ( mem-h ) ( R: io-h mem64-h )
457 then ( mem-h ) ( R: io-h mem64-h )
458 >r 0 0 0 r> r> r> ( mem-l mem64-l io-l mem-h mem64-h io-h )
459;
460
461[ifndef] PCIHOTPLUG?
462\ If the "size" element of the I/O- or Memory- parameter-pair is zero,
463\ the I/O or Memory resource will be aligned as given and the unused
464\ resource will be "handed back to the parent".
465\
466\ If "size" is non-zero, then drop the alignment and bypass the call
467\ to the align-resource-list routine; instead, pass a node-pointer
468\ of zero to the free-resources routine, so that it will bypass
469\ the clause that "hands the resource back to the parent", which is
470\ a behavior that may be required for hotplug-capable bridges.
471\
472\ The "io-n" and "mem-n" notations in the stack-diagrams refer to
473\ nodes from the pci-io-list or pci-memlist , respectively.
474\
475: release-bridge-resources
476( mem-aln mem-sz mem64-aln mem64-sz io-aln io-sz -- mem-l mem64-l io-l mem-h mem64-h io-h )
477 if ( mem-aln mem-sz mem64-aln mem64-sz io-aln )
478 drop 0 ( mem-aln mem-sz mem64-aln mem64-sz 0 )
479 else ( mem-aln mem-sz mem64-aln mem64-sz io-aln )
480 pci-io-list align-resource-list
481 ( mem-aln mem-sz mem64-aln mem64-sz io-n )
482 then ( mem-aln mem-sz mem64-aln mem64-sz io-n )
483 >r ( mem-aln mem-sz mem64-aln mem64-sz )
484 ( R: io-n )
485 mem64-support? if ( mem-aln mem-sz mem64-aln mem64-sz ) ( R: io-n )
486 x0<> if ( mem-aln mem-sz mem64-aln ) ( R: io-n )
487 drop 0 ( mem-aln mem-sz 0 ) ( R: io-n )
488 else ( mem-aln mem-sz mem64-aln ) ( R: io-n )
489 pci-mem64list align-resource-list
490 ( mem-aln mem-sz mem64-n ) ( R: io-n )
491 then ( mem-aln mem-sz mem64-n ) ( R: io-n )
492 else ( mem-aln mem-sz mem64-aln mem64-sz ) ( R: io-n )
493 2drop 0 ( mem-aln mem-sz 0 ) ( R: io-n )
494 then
495 >r ( mem-aln mem-sz ) ( R: io-n mem64-n )
496 if ( mem-aln ) ( R: io-n mem64-n )
497 drop 0 ( 0 ) ( R: io-n mem64-n )
498 else ( mem-aln ) ( R: io-n mem64-n )
499 pci-memlist align-resource-list
500 ( mem-n ) ( R: io-n mem64-n )
501 then ( mem-n ) ( R: io-n mem64-n )
502 r> r> free-resources ( mem-l mem64-l io-l mem-hi mem64-hi io-hi )
503;
504
505[else]
506\ Extend bridge upper range.
507\ upper-limit : bridge upper range
508\ node : last node in the bridge resource list
509\ list : bridge resource list
510: extend-bridge-range ( upper-limit node list -- node )
511 >r split-node ( prev next )
512 2dup <> if ( prev next )
513 swap node-range r> free-memrange ( next )
514 else
515 r> 2drop ( prev )
516 then
517;
518\ This is a hotplug enabled release resource routine. Here
519\ if the "size" element of the I/O- or Memory- parameter-pair is zero,
520\ the I/O or Memory resource will be aligned as given and the unused
521\ resource will be "handed back to the parent".
522\
523\ If "size" is non-zero, then that gives the upper limit
524\ to which the bridge range needs to be extended to handle
525\ hotplug resource requirement. For hotplug-capable bridges
526\ "size" passed is non-zero. In this case, the upper address
527\ range is extended to what is specified in "size" and the
528\ rest of what is left is returned to the parent.
529\
530\ The "io-n" and "mem-n" notations in the stack-diagrams refer to
531\ nodes from the pci-io-list or pci-memlist , respectively.
532\
533: release-bridge-resources
534( mem-aln mem-sz mem64-aln mem64-sz io-aln io-sz -- mem-l mem64-l io-l mem-h mem64-h io-h )
535 ?dup if ( mem-aln mem-sz mem64-aln mem64-sz io-aln io-sz )
536 swap pci-io-list align-resource-list
537 ( mem-aln mem-sz mem64-aln mem64-sz io-sz io-n )
538 pci-io-list extend-bridge-range
539 ( mem-aln mem-sz mem64-aln mem64-sz io-n' )
540 else ( mem-aln mem-sz mem64-aln mem64-sz io-aln )
541 pci-io-list align-resource-list
542 ( mem-aln mem-sz mem64-aln mem64-sz io-n )
543 then ( mem-aln mem-sz mem64-aln mem64-sz io-n )
544 >r ( mem-aln mem-sz mem64-aln mem64-sz ) ( R: io-n )
545 mem64-support? if \ host-bridge supports mem64 space
546 ?dup x0<> if ( mem-aln mem-sz mem64-aln mem64-sz ) ( R: io-n )
547 swap pci-mem64list align-resource-list
548 ( mem-aln mem-sz mem64-sz mem64-n ) ( R: io-n )
549 pci-mem64list extend-bridge-range
550 ( mem-aln mem-sz mem64-n' ) ( R: io-n )
551 else
552 ( mem-aln mem-sz mem64-aln ) ( R: io-n )
553 pci-mem64list align-resource-list
554 ( mem-aln mem-sz mem64-n ) ( R: io-n )
555 then ( mem-aln mem-sz mem64-n ) ( R: io-n )
556 else \ host-bridge does not support mem64 space
557 2drop 0 ( mem-aln mem-sz mem64-n ) ( R: io-n )
558 then
559 >r ( mem-aln mem-sz ) ( R: io-n mem64-n )
560 ?dup if ( mem-aln mem-sz ) ( R: io-n mem64-n )
561 swap pci-memlist align-resource-list
562 ( mem-sz mem-n ) ( R: io-n mem64-n )
563 pci-memlist extend-bridge-range
564 ( mem-n' ) ( R: io-n mem64-n )
565 else ( mem-aln ) ( R: io-n mem64-n )
566 pci-memlist align-resource-list
567 ( mem-n ) ( R: io-n mem64-n )
568 then ( mem-n ) ( R: io-n mem64-n )
569 r> r> ( mem-n mem64-n io-n ) ( R: )
570 free-resources ( mem-l mem64-l io-l mem-h mem64-h io-h )
571;
572[then]
573
574: get-dma-range ( -- dma-l dma-h )
575 " virtual-dma" get-inherited-property 0= if
576 decode-int -rot decode-int nip nip ( dma-l dma-size )
577 over + ( dma-l dma-h )
578 else ( )
579 h# 8000.0000 dup h# 7fff.ffff + ( dma-l dma-h )
580 then ( dma-l dma-h )
581;
582
583[ifndef] PCIHOTPLUG?
584\ The behavior of this routine changes significantly with variations
585\ in its parameters:
586\
587\ A non-zero n specifies the acquire-bridge-resources path.
588\ This means:
589\ (A)
590\ A non-zero "size" element of the I/O- or Memory- parameter-pair
591\ specifies the size of the I/O or Memory resource to acquire;
592\ a zero "size" specifies acquiring the largest available piece
593\ of the I/O or Memory resource.
594\ (B)
595\ The bus# returned should be one more than current-bus# at
596\ the time this routine was entered, and current-bus# should
597\ be incremented by n for the next time 'round.
598\
599\ An n of zero specifies the release-bridge-resources path.
600\ This means:
601\ (A)
602\ The I/O- and Memory- parameter-pairs are passed directly to
603\ the release-bridge-resources routine (which see).
604\ (B)
605\ The bus# returned should be current-bus# , and current-bus#
606\ should remain unchanged.
607\
608: pci-allocate-bus# ( n m-aln m-sz m64-aln m64-sz io-aln io-sz -- ...... )
609 ( ..... -- mem-lo mem64-lo io-lo dma-lo mem-hi mem64-hi io-hi dma-hi bus# )
610 current-bus# >r ( n m-aln m-sz m64-aln m64-sz io-aln io-sz )
611 ( R: cbus )
612 2>r 2>r 2>r ( n )
613 ( R: cbus io-aln io-sz m64-aln m64-sz m-aln m-sz )
614 ?dup if ( n ) ( R: cbus io-aln io-sz m64-aln m64-sz m-aln m-sz )
615 current-bus# + to current-bus#
616 ( ) ( R: cbus io-aln io-sz m64-aln m64-sz m-aln m-sz )
617 pci-memlist 2r> acquire-bridge-resources
618 ( mem-n ) ( R: cb io-aln io-sz m64-aln m64-sz )
619 mem64-support? if \ host-bridge supports mem64 space
620 ( mem-n ) ( R: cb io-aln io-sz m64-aln m64-sz )
621 pci-mem64list 2r> acquire-bridge-resources
622 ( mem-n mem64-n ) ( R: cb io-aln io-sz )
623 else \ host-bridge does not support mem64 space
624 ( mem-n ) ( R: cb io-aln io-sz m64-aln m64-sz )
625 2r> 2drop 0
626 ( mem-n mem64-n ) ( R: cb io-aln io-sz )
627 then
628 pci-io-list 2r> acquire-bridge-resources
629 ( mem-node mem64-node io-node ) ( R: cbus )
630 get-ranges
631 ( mem-lo mem64-lo io-lo mem-hi mem64-hi io-hi ) ( R: cbus )
632 r> 1+ >r ( mem-lo mem64-lo io-lo mem-hi mem64-hi io-hi ) ( R: bus# )
633 else ( ) ( R: bus# io-aln io-sz m64-aln m64-sz m-aln m-sz )
634 2r> 2r> 2r>
635 ( m-aln m-sz m64-aln m64-sz io-aln io-sz ) ( R: bus# )
636 release-bridge-resources
637 ( mem-lo mem64-lo io-lo mem-hi mem64-hi io-hi ) ( R: bus# )
638 then ( mem-lo mem64-lo io-lo mem-hi mem64-hi io-hi ) ( R: bus# )
639 get-dma-range
640 ( mem-lo mem64-lo io-lo mem-hi mem64-hi io-hi dma-lo dma-hi )
641 ( R: bus# )
642 >r swap >r swap >r swap r> r> r>
643 ( mem-lo mem64-lo io-lo dma-lo mem-hi mem64-hi io-hi dma-hi )
644 ( R: bus# )
645 r> ( mem-lo mem64-lo io-lo dma-lo mem-hi mem64-hi io-hi dma-hi bus# )
646;
647
648[else]
649\ This is a hotplug enabled allocation routine.
650\ Here a non-zero n specifies the release-bridge-resource path.
651\ if n = -1, it implies non hotplug bridge and hence all the resources
652\ are returned to the parent node.
653\ if n <> -1, then it implies the request is coming from a hotplug capable
654\ bridge and "n" represents the minimum upper limit of the bus-range
655\ for this bridge. Note that in this case mem-hi and io-hi
656\ represent the upper watermark for memory window and io space
657\ window for this bridge.
658\
659\ A zero value of n specifies the allocate-bridge-resource path here.
660\ And there is no change as compared to legacy code here. It still allocates
661\ a large resource window for the bridge which is needed when pci code
662\ starts probing the children of the bridge.
663\
664: pci-allocate-bus# ( n m-aln m-sz mem64-aln mem64-sz io-aln io-sz -- ...... )
665( ..... -- mem-lo mem64-lo io-lo dma-lo mem-hi mem64-hi io-hi dma-hi bus# )
666 current-bus# >r ( n m-aln m-sz io-aln io-sz ) ( R: cbus )
667 2>r 2>r 2>r ( n )
668 ( R: cbus io-aln io-sz mem64-aln mem64-sz m-aln m-sz )
669 ?dup 0= if ( )
670 ( R: cbus io-aln io-sz mem64-aln mem64-sz m-aln m-sz )
671 current-bus# 1+ to current-bus#
672 ( )
673 ( R: cbus io-aln io-sz mem64-aln mem64-sz m-aln m-sz )
674 pci-memlist 2r> acquire-bridge-resources
675 ( mem-n ) ( R: cb io-aln io-sz mem64-aln mem64-sz )
676 mem64-support? if \ host-bridge supports mem64 space
677 ( mem-n ) ( R: cb io-aln io-sz m64-aln m64-sz )
678 pci-mem64list 2r> acquire-bridge-resources
679 ( mem-n mem64-n ) ( R: cb io-aln io-sz )
680 else \ host-bridge does not support mem64 space
681 ( mem-n ) ( R: cb io-aln io-sz m64-aln m64-sz )
682 2r> 2drop 0
683 ( mem-n mem64-n ) ( R: cb io-aln io-sz )
684 then
685 pci-io-list 2r> acquire-bridge-resources
686 ( mem-node mem64-node io-node ) ( R: cbus )
687 get-ranges ( mem-lo mem64-lo io-lo mem-hi mem64-hi io-hi )
688 ( R: cbus )
689 r> 1+ >r ( mem-lo mem64-lo io-lo mem-hi mem64-hi io-hi )
690 ( R: bus# )
691 else ( n ) ( R: bus# io-aln io-sz m-aln m-sz )
692 2r> 2r> 2r> ( n m-aln m-sz m64-aln m64-sz io-aln io-sz )
693 ( R: bus# )
694 release-bridge-resources
695 ( n mem-lo mem64-lo io-lo mem-hi mem64-hi io-hi )
696 ( R: bus# )
697 6 roll ( mem-lo mem64-lo io-lo mem-hi mem64-hi io-hi n )
698 ( R: bus# )
699 dup -1 = if ( mem-lo mem64-lo io-lo mem-hi mem64-hi io-hi n )
700 ( R: bus# )
701 drop ( mem-lo mem64-lo io-lo mem-hi mem64-hi io-hi )
702 ( R: bus# )
703 else ( mem-lo mem64-lo io-lo mem-hi mem64-hi io-hi n )
704 ( R: bus# )
705 \ if <> -1, then n is upper bus number for the hotplug capable bridge
706 r> max dup >r is current-bus#
707 ( mem-lo mem64-lo io-lo mem-hi mem64-hi io-hi )
708 ( R: bus# )
709 then ( mem-lo mem64-lo io-lo mem-hi mem64-hi io-hi )
710 ( R: bus# )
711 then ( mem-lo mem64-lo io-lo mem-hi mem64-hi io-hi )
712 ( R: bus# )
713 get-dma-range ( mem-lo mem64-lo io-lo mem-hi mem64-hi io-hi dma-lo dma-hi )
714 ( r: bus# )
715 >r swap >r swap >r swap >r ( mem-lo mem64-lo io-lo dma-lo )
716 ( r: bus# dma-hi io-hi mem64-hi mem-hi )
717 r> r> r> r> r> ( mem-lo mem64-lo io-lo dma-lo mem-hi mem64-hi io-hi dma-hi bus# )
718 ( r: )
719;
720[then]
721
722fload ${BP}/dev/pci/map.fth
723fload ${BP}/dev/pci/unit.fth
724