Commit | Line | Data |
---|---|---|
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 ============================================ | |
42 | id: @(#)pcibridg.fth 1.39 07/03/08 15:49:36 | |
43 | purpose: PCI bridge probe code | |
44 | copyright: Copyright 2007 Sun Microsystems, Inc. All rights reserved | |
45 | copyright: Use is subject to license terms. | |
46 | ||
47 | hex | |
48 | headerless | |
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 | ||
60 | fload ${BP}/dev/pci-bridge/dec21152/config.fth | |
61 | fload ${BP}/dev/pci/compatible.fth | |
62 | fload ${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 | ||
85 | make-physical-slot#-prop | |
86 | ||
87 | 0 0 my-space encode-phys 0 encode-int encode+ 0 encode-int encode+ | |
88 | " reg" property | |
89 | ||
90 | make-compatible-property | |
91 | ||
92 | headers | |
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 | ||
194 | fload ${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 | ||
254 | false 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 | ||
268 | fload ${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 | ||
777 | get-xmits-bridge? | |
778 | ||
779 | dup constant xmits-bridge? \ Leave a residue we can check later... | |
780 | if setup-xmits-bridge | |
781 | else setup-generic-bridge | |
782 | then | |
783 | ||
784 | [else] \ It's NOT StarCat-XMITS | |
785 | ||
786 | setup-generic-bridge | |
787 | ||
788 | [then] \ starcat-xmits |