Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / obp / obp / dev / pci-bridge / dec21152 / pcibridg.fth
CommitLineData
920dae64
AT
1\ ========== Copyright Header Begin ==========================================
2\
3\ Hypervisor Software File: pcibridg.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: @(#)pcibridg.fth 1.39 07/03/08 15:49:36
43purpose: PCI bridge probe code
44copyright: Copyright 2007 Sun Microsystems, Inc. All rights reserved
45copyright: Use is subject to license terms.
46
47hex
48headerless
49
50\ These are 64 bit arithmetic operation needed to support
51\ pci 64 bit memory address handling on the data stack.
52
53\ Compare two 64 bit number and determine if they are not equal
54: x<> ( x1 x2 -- ne? ) xlsplit rot xlsplit rot <> -rot <> or ;
55\ Find out if the 64 bit number is non-zero
56: x0<> ( x -- 0<>? ) 0 x<> ;
57\ Conditional dup of 64 bit number on the stack
58: ?xdup ( x -- ?? ) dup x0<> if dup then ;
59
60fload ${BP}/dev/pci-bridge/dec21152/config.fth
61fload ${BP}/dev/pci/compatible.fth
62fload ${BP}/dev/pci-bridge/pcinode.fth
63
64: make-physical-slot#-prop ( -- )
65 \ Check if the device is a PCI Express device.
66 pcie-capability-regs ?dup if ( pointer| )
67 \ Check if the device is a Root Port or Downstream Port
68 dup 2 + my-w@ dup 4 >> h# f and ( pointer capabilities type )
69 dup 6 = swap 4 = or if ( pointer capabilities )
70 \ Check if the device implements a slot
71 1 8 << and if ( pointer )
72 \ If so, extract the physical slot number
73 h# 14 + my-l@ d# 19 >> ( slot-num )
74 encode-int ( propaddr,len )
75 " physical-slot#" property ( )
76 else ( pointer )
77 drop ( )
78 then ( )
79 else ( pointer capabilities )
80 2drop ( )
81 then ( )
82 then ( )
83;
84
85make-physical-slot#-prop
86
870 0 my-space encode-phys 0 encode-int encode+ 0 encode-int encode+
88" reg" property
89
90make-compatible-property
91
92headers
93
94: valid-prefetch-range? ( -- flag ) h# 28 my-l@ h# ffffffff = h# 2c my-l@ 0= or not ;
95: prefetch-limit! ( limit -- ) xlsplit h# 2c my-l! d# 20 >> 4 << 1 or h# 26 my-w! ;
96: prefetch-base! ( base -- ) xlsplit h# 28 my-l! d# 20 >> 4 << 1 or h# 24 my-w! ;
97: prefetch-limit@ ( -- limit ) h# 26 my-w@ h# f or h# ffff swap wljoin h# 2c my-l@ lxjoin ;
98: prefetch-base@ ( -- base ) h# 24 my-w@ h# f invert and d# 16 << h# 28 my-l@ lxjoin ;
99\ Bits [3:0] of prefetchable memory base register is 1 if MEM64 is supported
100: support-prefetchable? ( -- flag ) h# 24 my-w@ h# f and 1 = ;
101
102: prefetch-ranges-off ( -- )
103 \ Turn off prefetchable memory forwarding range
104 h# 0000ffff h# 24 my-l! \ Prefetchable Limit,Base
105 h# ffffffff h# 28 my-l! \ Prefetchable Base upper 32 bits
106 h# 0 h# 2c my-l! \ Prefetchable Limit upper 32 bits
107;
108
109: set-bases ( mem-base mem64-base io-base -- )
110[ifdef] bridge-debug?
111 3dup
112 cr ." Bridge Base Addresses : "
113 rot cr ." mem-base : " u.
114 swap cr ." mem64-base : " u.
115 cr ." io-base : " u.
116[then] ( mem-base mem64-base io-base )
117 \ Set I/O forwarding base
118 lwsplit h# 30 my-w! wbsplit h# 1c my-b! drop ( mem-base mem64-base )
119
120 \ Set prefetchable memory forwarding base (use mem64, so [63:32] cannot be zero)
121 dup x0<> if ( mem-base mem64-base )
122 prefetch-base! ( mem-base )
123 else
124 drop prefetch-ranges-off ( mem-base )
125 then
126
127 \ Set non-prefetchable memory forwarding base
128 lwsplit h# 20 my-w! drop ( )
129;
130
131: set-limits ( mem-limit+1 mem64-limit+1 io-limit+1 -- )
132[ifdef] bridge-debug?
133 3dup
134 cr ." Bridge Limit Addresses : "
135 rot cr ." mem-limit : " u.
136 swap cr ." mem64-limit : " u.
137 cr ." io-limit : " u.
138[then] ( mem-limit+1 mem64-limit+1 io-limit+1 )
139 \ Set I/O forwarding limit
140 ?dup if
141 1- lwsplit h# 32 my-w! wbsplit h# 1d my-b! \ Write I/O Limit
142 drop
143 then ( mem-limit+1 mem64-limit+1 )
144
145 \ Set prefetchable memory forwarding limit (use mem64, so [63:32] cannot be zero)
146 \ Also make sure prefetch-base is not same as prefetch-limit value.
147 dup x0<> over prefetch-base@ x<> and if ( mem-limit+1 mem64-limit+1 )
148 1- prefetch-limit! ( mem32-limit+1 )
149 else
150 drop prefetch-ranges-off ( mem32-limit+1 )
151 then
152
153 \ Set non-prefetchable memory forwarding range
154 ?dup if 1- lwsplit h# 22 my-w! drop then ( )
155;
156
157: restore-limits ( mem-limit+1 mem64-limit+1 io-limit+1 -- )
158 \ Set I/O forwarding limit
159 ?dup if
160 1- lwsplit h# 32 my-w! wbsplit h# 1d my-b! \ Write I/O Limit
161 drop
162 else
163 \ If the I/O limit is zero, set base and limit registers to
164 \ disable I/O forwarding
165 0 h# 1d my-b! 10 h# 1c my-b!
166 0 h# 30 my-l!
167 then ( mem-limit+1 mem64-limit+1 )
168
169 \ Set prefetchable memory forwarding limit (use mem64, so [63:32] cannot be zero)
170 \ Also make sure prefetch-base is not same as prefetch-limit value.
171 dup x0<> over prefetch-base@ x<> and if ( mem-limit+1 mem64-limit+1 )
172 1- prefetch-limit! ( mem-limit+1 )
173 else
174 drop prefetch-ranges-off ( mem-limit+1 )
175 then
176
177 \ Set non-prefetchable memory forwarding range
178 \ To disable forwarding we hardcode a negative range... same as Windows
179 \ NOTE: this is a change from the legacy algorithm (setting limit = base-1)
180 \ due to problems seen on the PLX 8532 switch.
181 \ See CR 6397497 for more details.
182
183 h# 20 my-w@ d# 16 << ( limit+1 base )
184 over >= if
185 drop \ base >= limit --> disable memory forwarding
186 h# fff0 h# 20 my-w! \ set base = large (both bytes > limit)
187 0 h# 22 my-w! \ set limit = 0
188 else
189 1- d# 16 >> h# 22 my-w! \ base < limit --> enable memory forwarding
190 then
191;
192
193
194fload ${BP}/dev/pci-bridge/range.fth
195
196\ Create the ranges property needed by hot-plug. Derive information
197\ directly from config-space, to ensure property reflects what the
198\ chip actually responds to.
199
200: io.lo,hi-join ( iox.lo iox.hi -- iox )
201 d# 16 lshift swap ( hi' lo )
202 h# f0 and d# 8 lshift ( hi' lo' )
203 + ( hi+lo )
204;
205
206: encode-io-range ( propaddr,len -- propaddr,len' )
207 1 ( propaddr,len type )
208 \ Fetch io-base and limits (split across two BARs)
209 h# 30 my-l@ lwsplit ( propaddr,len type iob.hi iol.hi )
210 h# 1c my-w@ wbsplit ( propaddr,len type iob.hi iol.hi iob.lo iol.lo )
211 rot io.lo,hi-join ( propaddr,len type iob.hi iob.lo iolimit' )
212 h# 1000 + ( propaddr,len type iob.hi iob.lo iolimit )
213 -rot swap io.lo,hi-join ( propaddr,len type iolimit iobase )
214 tuck - ( propaddr,len type iobase iosize )
215 encode-range ( propaddr,len' )
216;
217
218: encode-mem-range ( propaddr,len -- propaddr,len' )
219 2 ( propaddr,len type )
220 \ Fetch memory base and limit. Single BAR.
221 h# 20 my-l@ lwsplit ( propaddr,len type memb.hi meml.hi )
222 d# 16 lshift h# 10.0000 + ( propaddr,len type memb.hi memlimit )
223 swap d# 16 lshift ( propaddr,len type memlimit membase )
224 tuck - ( propaddr,len type membase memsize )
225 encode-range ( propaddr,len )
226;
227
228
229: encode-mem64-range ( propaddr,len -- propaddr,len' )
230 h# 43 ( propaddr,len type )
231 \ Fetch prefetchable memory base and limit (split across two BARs).
232 prefetch-base@ ( propaddr,len type mem64base )
233 prefetch-limit@ ( propaddr,len type mem64base mem64limit )
234 ?dup if ( propaddr,len type mem64base mem64limit )
235 1+ over - ( propaddr,len type mem64base mem64size )
236 encode-range ( propaddr,len )
237 else ( propaddr,len type mem64base )
238 2drop ( propaddr,len )
239 then ( propaddr,len )
240;
241
242: create-ranges ( -- )
243 0 0 encode-bytes ( propaddr,len )
244 encode-io-range ( propaddr,len' )
245 encode-mem-range ( propaddr,len'' )
246 valid-prefetch-range? if
247 encode-mem64-range ( propaddr,len''' )
248 then
249 ?dup if " ranges" property else drop then
250;
251
252: "hotplug-capable" ( -- $adr,len ) " hotplug-capable" ;
253
254false value hotplug-capable?
255
256: hotplug-capable-prop ( -- )
257 0 0 "hotplug-capable" property
258 true to hotplug-capable?
259;
260
261\ Generate the common parameters for,
262\ and make the call to, allocate-bus#
263: allocate-bridge-resources ( acquire? -- . . . . . . . )
264 ( .. -- mem-lo mem64-lo io-lo dma-lo mem-hi mem64-hi io-hi dma-hi bus# )
265 h# 10.0000 0 h# 1000.0000 0 h# 1000 0 allocate-bus#
266;
267
268fload ${BP}/dev/pci-bridge/hotplugalloc.fth
269
270\ This is renamed from claim-pci-resource to (claim-pci-resource.
271\ Acquire the maximum amount of memory and IO address space for
272\ this bridge, in advance of probing it. For a "normal" bridge,
273\ i.e., one that is not hotplug-capable, we need only claim one
274\ bus number (our own).
275\
276\ For a hotplug-capable bridge, we need to claim a large number
277\ of subordinate busses: a generous enough allotment to cover
278\ all conceivable hotplug needs, but not so many as to interfere
279\ with expansion by devices already attached; let's say, half
280\ the possible range, less one for our own.
281\
282\ Secondary Bus# is returned as a side-effect.
283\
284: (claim-pci-resource ( -- mem-lo mem64-lo io-lo dma-lo mem-hi mem64-hi io-hi dma-hi bus# )
285 hotplug-capable? if
286 h# 7f allocate-bridge-resources ( . . . . . . bus# )
287 else
288 1 allocate-bridge-resources ( . . . . . . bus# )
289 then
290;
291
292\ This routine calls the legacy allocation routine
293\ "(claim-pci-resource" or the newer hotplug enabled allocation
294\ routine "hp-claim-pci-resource" based on the presence or absence of
295\ the two slot count properties,
296\
297\ "level1-hotplug-slot-count"
298\ "level2-hotplug-slot-count"
299\
300\ in the host bridge node.
301\
302: claim-pci-resource ( -- mem-lo mem64-lo io-lo dma-lo mem-hi mem64-hi io-hi dma-hi bus# )
303 slot-count-inherited-property? dup is preallocation-scheme?
304 if
305 hp-claim-pci-resource ( mem-lo mem64-lo io-lo dma-lo mem-hi mem64-hi io-hi dma-hi bus# )
306 else
307 \ This platform implements legacy allocation scheme.
308 (claim-pci-resource ( mem-lo mem64-lo io-lo dma-lo mem-hi mem64-hi io-hi dma-hi bus# )
309 then
310;
311
312\ Initialize the Primary Bus# reg
313: init-primary-bus# ( -- )
314 my-space d# 16 rshift h# ff and
315 h# 18 my-b! \ Primary bus#
316;
317
318\ Assign the Secondary Bus# that was returned by
319\ the claim-pci-resource function;
320\ Clean up the stack before returning.
321: init-secondary-bus# ( mem-lo mem64-lo io-lo dma-lo mem-hi mem64-hi io-hi dma-hi bus# -- .... )
322 ( . . . . . . . -- mem-lo mem64-lo io-lo mem-hi mem64-hi io-hi )
323 dup to my-bus#
324 h# 19 my-b! \ Write to Secondary Bus# reg
325 ( mem-lo mem64-lo io-lo dma-lo mem-hi mem64-hi io-hi dma-hi )
326 drop 3 roll drop ( mem-lo mem64-lo io-lo mem-hi mem64-hi io-hi )
327;
328
329\ Set the subordinate bus number to ff in order to pass through any
330\ type 1 cycle with a bus number higher than the secondary bus#
331: init-subordinate-bus# ( -- )
332 h# ff h# 1a my-b!
333;
334
335
336\ Clean up the resources of the bridge, but leave the full allocation.
337\ Reduce the subordinate bus# to the maximum bus number of any of our
338\ children, but keep memory and IO forwarding limits as pre-configured.
339\
340: retain-pci-resource ( -- )
341 \ Params for allocate-bus# are ( n m-aln m-sz m64-aln m64-sz io-aln io-sz )
342 0 \ Release (rather than acquire) resources.
343 0 -1 \ Mem-alignment irrelevant, non-zero mem-size
344 0 -1 \ Mem64-alignment irrelevant, non-zero mem64-size
345 0 -1 \ I/O-alignment irrelevant, non-zero i/o-size
346
347 allocate-bus# ( mem-lo mem64-lo io-lo dma-lo mem-hi mem64-hi io-hi dma-hi bus# )
348
349 \ Subordinate Bus Number register:
350 h# 1a my-b! ( mem-lo mem64-lo io-lo dma-lo mem-hi mem64-hi io-hi dma-hi )
351 3drop 3drop 2drop
352;
353
354\ Reduce the subordinate bus# to the maximum bus number of any
355\ of our children, and the memory and IO forwarding limits to
356\ the limits of the address space actually allocated. ...
357: (free-unused-pci-resource) ( -- )
358 0 allocate-bridge-resources
359 h# 1a my-b! ( mem-lo mem64-lo io-lo dma-lo mem-hi mem64-hi io-hi dma-hi )
360 drop ( mem-lo mem64-lo io-lo dma-lo mem-hi mem64-hi io-hi )
361 restore-limits 3drop drop ( )
362;
363
364\ ...
365\ Unless this bridge supports hotplug, in which case we want
366\ to leave it with a full allocation.
367: free-unused-pci-resource ( -- )
368 preallocation-scheme? if
369 hotplug-capable? if
370 hp-retain-pci-resource
371 else
372 (hp-free-unused-pci-resource)
373 then
374 else
375 hotplug-capable? if
376 retain-pci-resource
377 else
378 (free-unused-pci-resource)
379 then
380 then
381;
382
383: clear-status-bits ( -- )
384 h# ffff h# 1e my-w!
385;
386
387: clear-pcie-errors ( -- )
388 pci-express? 0= if exit then
389 aer-capability-regs ?dup if
390 get-port-type dup >r 7 = r@ 8 = or if \ bridges have secondary errors
391 -1 over h# 2c + my-l! \ secondary UEs
392 -1 over h# 34 + my-l! \ secondary CEs
393 then
394 r> h# c and if \ Switches and bridges have primary errors
395 -1 over 04 + my-l! \ UEs
396 -1 swap h# 10 + my-l! \ CEs
397 else
398 drop
399 then
400 then
401 pcie-capability-regs h# a + dup \ Clear all errors in
402 my-w@ h# f or swap my-w! \ pci-express device status
403;
404
405\ Disable memory, IO, and bus mastership;
406\ leave everything else as is.
407: disable-mem,io&bus-mastr ( -- )
408 4 my-w@ h# fff8 and 4 my-w! ( )
409;
410
411
412\ Enable memory, IO, and bus mastership
413: enable-mem,io&bus-mastr ( -- )
414 \ XXX should we enable parity, SERR#, fast back-to-back, and addr. stepping?
415 \ In case of pci-express bridge, disable INTx ( bit 10 ) before solaris boot
416 \ to get rid of storm of INTx assertions from the numberous virtual pci-pci bridges.
417 4 my-w@ ( value )
418[ifdef] DISABLE-INTx
419 pci-express? if h# 407 else 7 then ( value enable-mask )
420[else]
421 7 ( value enable-mask )
422[then]
423 or 4 my-w! ( )
424;
425
426\ The IBM bridge is somewhat funny
427: ?ibm-bridge-hack ( -- )
428 0 my-l@ h# 221014 = if h# 22 h# 3e my-b! then
429;
430
431\ This intel bridge requires certain performance bits be set
432: ?intel-restream-enable ( -- )
433 0 my-l@ dup h# 3408086 = swap h# 3418086 = or if
434 h# 174 my-l@ h# 40 invert and h# 174 my-l!
435 then
436;
437
438: probe-children ( -- )
439 " 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" ( $ )
440 pci-express? if
441 pcie-capability-regs 2+ my-w@ 4 rshift h# f and h# 6 = if
442 2drop " 0"
443 then
444 then ( probelist$ )
445 " my-probe-list" get-my-property 0= if ( probelist$ prop$ )
446 2swap 2drop decode-string 2swap 2drop ( probelist$ )
447 then prober-xt execute ( )
448;
449
450: create-bus-range ( -- )
451 my-bus# encode-int h# 1a my-b@ encode-int encode+
452 " bus-range" property
453;
454
455[ifndef] starcat-xmits
456
457\ Paranoia, perhaps justified
458: disable-children ( -- )
459 my-bus# d# 16 lshift 4 + ( space+reg-template )
460 h# 1.0000 bounds do \ For all the children 0-1f
461 h# 800 0 do \ For each function
462 0 j i + config-w! \ Clear command register
463 h# 100 +loop \ Next function
464 h# 800 +loop \ Next device
465;
466
467[else] \ It IS StarCat-XMITS
468
469\ Special section for XMITS builtin subordinate bridge
470
471: get-parent-int-prop? ( $adr,len -- n true | false )
472 my-self >r
473 my-parent is my-self \ And I'm my own grandpa...
474 get-my-property ( xdr,len false | true )
475 r> is my-self
476 if false
477 else decode-int true 2swap 2drop
478 then
479;
480
481\ The earlier self-styled "Paranoia, perhaps justified" has become
482\ an issue for certain devices (in particular, the "Golden I/O-SRam"
483\ on the subsidiary bridge of XMITS) that need to remain enabled.
484\
485\ To get around that, we are unilaterally inventing a private
486\ interface: an integer-valued property, named don't-disable ,
487\ whose value is a bit-mask with the semantics that, if bit N is
488\ set, that is an indication not to disable the descendant device
489\ corresponding to N.
490\
491\ If the property is absent, then all descendant devices get disabled,
492\ rendering the interface completely backwards compatible.
493
494: "don't-disable" ( -- $addr,len ) " don't-disable" ;
495
496\ Return the mask of descendant devices *TO* disable.
497\ This will be the inverse of the don't-disable integer
498\ mask value, or -1 if the property was not found.
499: get-disable-mask ( -- mask)
500 "don't-disable" get-parent-int-prop? if
501 invert
502 else
503 -1
504 then
505;
506
507\ Paranoia, perhaps justified, rev 2
508: disable-children ( -- )
509 get-disable-mask ( mask )
510 my-bus# d# 16 lshift 4 + ( mask space+reg-template )
511 h# 1.0000 bounds do ( mask )
512 dup 1 and if
513 h# 800 0 do \ For each function
514 0 j i + config-w! \ Clear command register
515 h# 100 +loop \ Next function
516 then u2/ ( mask' )
517 h# 800 +loop
518 drop
519;
520
521\ END Special section for StarCat-XMITS builtin subordinate bridge
522[then] \ starcat-xmits
523
524
525\ NEC bridge earlier than rev 4.4 have a bug that if Upper Limit
526\ register is programmed to non-zero value, it generates a master
527\ abort as soon as we touch the FCode PROM of LSI1064 device.
528\ This problem has been fixed in NEC bridge rev 4.4 and later
529\ The workaround it not to touch the FCode PROM on LSI1064 if
530\ earlier revision of NEC bridge is detected.
531\ NEC 4.4 chip revision=6, NEC 4.3, chip revision=5
532[ifdef] NEC-master-abort-wa
533
534: "nec-brg-pre-v4.4" ( -- str,len ) " nec-brg-pre-v4.4" ;
535
536\ Detect if it is older revision of NEC bridge
537: old-nec-brg? ( -- flag )
538 vid,did h# 125 = swap h# 1033 = and ( nec-brg? )
539 rev-id 6 < and ( bug? )
540;
541\ If older revision NEC bridge is detected, populate a
542\ temporary property that will be deleted later
543: ?old-nec-brg-wa ( -- )
544 old-nec-brg? if
545 0 0 encode-bytes "nec-brg-pre-v4.4" property
546 then
547;
548\ Remove the temporary property
549: cleanup-old-nec-brg-wa ( -- )
550 "nec-brg-pre-v4.4" get-my-property 0= if
551 2drop "nec-brg-pre-v4.4" delete-property
552 then
553;
554[then]
555
556\ Initialize a bridge from scratch...
557
558: setup-generic-bridge ( -- )
559
560 \ Turn off memory and I/O response and bus mastership while setting up
561 disable-mem,io&bus-mastr
562
563 init-primary-bus# ( ) \ Primary bus#
564 \ Secondary bus#
565 claim-pci-resource ( mem-lo mem64-lo io-lo dma-lo mem-hi mem64-hi io-hi dma-hi bus# )
566
567 init-secondary-bus# ( mem-lo mem64-lo io-lo mem-hi mem64-hi io-hi )
568
569 init-subordinate-bus# ( mem-lo mem64-lo io-lo mem-hi mem64-hi io-hi )
570
571 disable-children ( mem-lo mem64-lo io-lo mem-hi mem64-hi io-hi )
572
573 \ Initially set the limits to encompassing the rest of the address space
574 set-limits ( mem-lo mem64-lo io-lo )
575
576 set-bases ( )
577
578 clear-status-bits ( )
579
580
581 enable-mem,io&bus-mastr ( )
582
583 ?ibm-bridge-hack ( )
584
585 ?intel-restream-enable ( )
586
587[ifdef] NEC-master-abort-wa
588 ?old-nec-brg-wa ( )
589[then]
590
591 \ XXX set cache line size in the register at 0c
592 \ XXX latency timer in the register at 0d
593 \ XXX set secondary latency timer in the register at 1b
594
595 probe-children ( )
596
597[ifdef] NEC-master-abort-wa
598 cleanup-old-nec-brg-wa ( )
599[then]
600
601 clear-status-bits ( )
602
603 clear-pcie-errors ( )
604
605 free-unused-pci-resource ( )
606
607 create-bus-range
608
609 create-ranges ( )
610;
611
612[ifdef] starcat-xmits
613
614\ The following code is specific to the StarCat XMITS I/O board,
615\ which has a PCI-Bridge on one of its leaves, with several
616\ built-in devices and a slot below it.
617\
618\ The code to support those devices and the slot has to be invoked
619\ from the PCI-Bridge creation because this is where those devices
620\ reside.
621
622\ Create the slot-names property for the builtin
623\ subsidiary pci-bridge on StarCat XMITS
624: create-xmits-bridge-slot-names ( -- )
625 \ +---> dev-sel 3 RIO
626 \ |+---> dev-sel 2 SBBC
627 \ ||+---> dev-sel 1 plugin slot <--------
628 \ |||+---> dev-sel 0 onboard PBM
629 \ ||||
630 \ vvVv
631 b# 0010 \ Mask of implemented slots
632 encode-int
633 " C5V0" \ Leaf B Port-ID 0
634 encode-string encode+ \ Slot 1 Label
635 " slot-names" property
636;
637
638
639\ Probe the SBBC first; claim its pre-configured addresses.
640: create-my-probe-list-prop ( -- )
641 " 2,1,3" ( probelist$ )
642 encode-string
643 " my-probe-list" property
644;
645
646\ An elaborate interrupt-map property applies to the XMITS builtin
647\ subordinate bridge, where the built-in devices are attached.
648
649: en+ ( xdr,len n -- xdr,len' ) encode-int encode+ ;
650
651\ Similar to <schizo> except instead of a unit$ of " N,0"
652\ where N is 1, 2, or 3, use an integer space equal to
653\ the decoding of N as a pci subsidiary-device number.
654\
655\ That number is a combination of N and the bridge's bus number, thus:
656: unit#>pa.hi ( unit# -- pa.hi )
657 d# 11 << my-bus# d# 16 << or
658;
659
660\ Don't call this until after my-bus# is established by the
661\ call to init-xmits-secondary-bus#
662: <xmits> ( xdr,len unit# intr -- xdr,len' )
663 >r ( xdr,len unit# ) ( R: intr )
664 \ Convert unit# to pa.hi
665 unit#>pa.hi ( xdr,len pa.hi ) ( R: intr )
666 en+ ( xdr,len""' ) ( R: intr ) \ Encode pa.hi
667 \ Both pa.mid and pa.lo are zero
668 0 en+ 0 en+ ( xdr,len"' ) ( R: intr ) \ Encode pa.mid,lo
669 r> en+ ( xdr,len" ) ( R: ) \ Encode intr
670 my-self ihandle>phandle ( xdr,len" phandle )
671 en+ ( xdr,len' ) \ Encode phandle
672;
673
674\ When the interrupt-map encoding is complete, create the property.
675\ The interrupt-map-mask and #interrupt-cells properties go
676\ with it as well...
677: int-map-prop ( xdr-addr,len -- )
678 " interrupt-map" property
679 0 0 fff800 encode-phys
680 7 en+ " interrupt-map-mask" property
681 1 encode-int " #interrupt-cells" property
682;
683
684: create-xmits-int-map-prop
685 \ NOTE: Interrupt slots for RIO and SBBC don't co-relate to their device#
686 \ PCI BUS B dev # 1 (plug in slot) = Int. slot 1
687 \ PCI BUS B dev # 2 (SBBC) = Int. slot 4
688 \ PCI BUS B dev # 3 (RIO) = Int. slot 2
689 \ HUB = Int. slot 3
690 \ HUB is not a PCI device and
691 \ interrupt generated from here will be spurious??
692
693 0 0 encode-bytes
694 4 0 do 1 i 1+ <xmits> 4 i + en+ loop \ Slot 1
695 4 0 do 2 i 1+ <xmits> 10 i + en+ loop \ SBBC
696 4 0 do 3 i 1+ <xmits> 8 i + en+ loop \ RIO
697 int-map-prop
698;
699
700
701\ We will count on the bus# that was returned by
702\ the claim-full-pci-resource function to match the
703\ pre-configured (POST-configured?) Secondary Bus#
704\ register.
705\
706\ Clean up the stack before returning.
707: init-xmits-secondary-bus#
708 ( mem-lo mem64-lo io-lo dma-lo mem-hi mem64-hi io-hi dma-hi bus# -- )
709 to my-bus# ( mem-lo mem64-lo io-lo dma-lo mem-hi mem64-hi io-hi dma-hi )
710 3drop 3drop 2drop ( )
711;
712
713\ Create the static properties that can be created early, and,
714\ in the case of the hotplug-capable property, have to.
715: create-xmits-bridge-props ( -- )
716
717 create-xmits-bridge-slot-names
718 hotplug-capable-prop
719
720 create-my-probe-list-prop
721;
722
723
724: setup-xmits-bridge ( -- )
725
726 create-xmits-bridge-props
727
728 \ For the special XMITS bridge, do not turn off
729 \ memory, I/O response and bus mastership
730
731 \ Primary bus# is pre-configured. Do not touch.
732
733 \ Secondary bus#
734 claim-pci-resource ( mem-lo mem64-lo io-lo dma-lo mem-hi mem64-hi io-hi dma-hi bus# )
735
736 init-xmits-secondary-bus# ( )
737
738 \ The interrupt-map property can only be created after
739 \ my-bus# has been set. See note near def'n of <xmits>
740 create-xmits-int-map-prop
741
742 \ Subordinate bus# is pre-configured. Do not touch.
743
744 disable-children
745
746 \ Limit and base registers are pre-configured.
747
748 clear-status-bits
749
750 \ For the special XMITS bridge, do not turn off
751 \ prefetchable memory forwarding range.
752
753
754 enable-mem,io&bus-mastr
755
756 \ We know the XMITS bridge is not the IBM bridge
757
758 \ XXX set cache line size in the register at 0c
759 \ XXX latency timer in the register at 0d
760 \ XXX set secondary latency timer in the register at 1b
761
762 probe-children
763
764 free-unused-pci-resource
765
766 create-bus-range
767
768 create-ranges
769;
770
771: get-xmits-bridge? ( -- flag )
772 " xmits-builtin-pci-bridge"
773 get-parent-int-prop? dup if drop my-space = then
774;
775
776
777get-xmits-bridge?
778
779dup constant xmits-bridge? \ Leave a residue we can check later...
780 if setup-xmits-bridge
781else setup-generic-bridge
782then
783
784[else] \ It's NOT StarCat-XMITS
785
786setup-generic-bridge
787
788[then] \ starcat-xmits