blob: 8f818a825745e01b6b97d3b36d73f1fe4642b4b7 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
|
\ *****************************************************************************
\ * Copyright (c) 2004, 2008 IBM Corporation
\ * All rights reserved.
\ * This program and the accompanying materials
\ * are made available under the terms of the BSD License
\ * which accompanies this distribution, and is available at
\ * http://www.opensource.org/licenses/bsd-license.php
\ *
\ * Contributors:
\ * IBM Corporation - initial implementation
\ ****************************************************************************/
\ Hypertransport.
\ See the PCI OF binding document.
new-device
s" ht" 2dup device-name device-type
s" u3-ht" compatible
s" U3" encode-string s" model" property
3 encode-int s" #address-cells" property
2 encode-int s" #size-cells" property
s" /mpic" find-node encode-int s" interrupt-parent" property
4000 encode-int 0 encode-int+ 0 encode-int+
1 encode-int+ s" /mpic" find-node encode-int+
10 encode-int+ 0 encode-int+
s" interrupt-map" property
f800 encode-int 0 encode-int+ 0 encode-int+
7 encode-int+ s" interrupt-map-mask" property
: decode-unit 2 hex-decode-unit 3 lshift or
8 lshift 0 0 rot ;
: encode-unit nip nip ff00 and 8 rshift dup 7 and swap 3 rshift
over IF 2 ELSE nip 1 THEN hex-encode-unit ;
f2000000 CONSTANT my-puid
\ Configuration space accesses.
: >config dup ffff > IF 1000000 + THEN f2000000 + ;
\ : config-l! >config cr ." config-l! " 2dup . space . rl!-le ;
\ : config-l@ >config cr ." config-l@ " dup . rl@-le space dup . ;
\ : config-w! >config cr ." config-w! " 2dup . space . rw!-le ;
\ : config-w@ >config cr ." config-w@ " dup . rw@-le space dup . ;
\ : config-b! >config cr ." config-b! " 2dup . space . rb! ;
\ : config-b@ >config cr ." config-b@ " dup . rb@ space dup . ;
: config-l! >config rl!-le ;
: config-l@ >config rl@-le ;
: config-w! >config rw!-le ;
: config-w@ >config rw@-le ;
: config-b! >config rb! ;
: config-b@ >config rb@ ;
: config-dump ( addr size -- ) ['] config-l@ 4 (dump) ;
\ 16MB of configuration space, separate for type 0 and type 1.
00000000 encode-int f2000000 encode-int+
00000000 encode-int+ 02000000 encode-int+ s" reg" property
\ 4MB of I/O space.
01000000 encode-int 00000000 encode-int+ 00000000 encode-int+
00000000 encode-int+ f4000000 encode-int+
00000000 encode-int+ 00400000 encode-int+
\ 1 GB of memory space @ 80000000
02000000 encode-int+ 00000000 encode-int+ 80000000 encode-int+
00000000 encode-int+ 80000000 encode-int+
00000000 encode-int+ 40000000 encode-int+ s" ranges" property
\ Host bridge, so full bus range.
0 encode-int ff encode-int+ s" bus-range" property
: enable-ht-apic-space 3c0300fe f8070200 rl! ;
enable-ht-apic-space
\ spare out 0xc0000000-0xefffffff for pcie
f8070200 rl@ fffffff0 and f8070200 rl!
\ enable io memory for pcie @ c0000000-efffffff
70000003 f80903f0 rl!-le
\ Workaround for "takeover" boot on JS20: the top 8131 is programmed to be
\ device #1f, while it should be #01.
u3? IF f800 config-l@ 74501022 = IF 41 f8c2 config-w! THEN THEN
\ Assign BUIDs.
: find-ht-primary
34 BEGIN config-b@ dup 0= ABORT" No HT capability block found!"
dup config-l@ e00000ff and 8 = IF 2 + EXIT THEN 1 + AGAIN ;
: assign-buid ( this -- next )
find-ht-primary dup >r config-w@ 5 rshift 1f and over r> config-b! + ;
: assign-buids ( -- )
1 BEGIN 0 config-l@ ffffffff <> WHILE assign-buid REPEAT drop ;
assign-buids
: ldtstop f8000840 rl@ 40000 or f8000840 rl! ;
: delay 100000 0 DO LOOP ;
: wait-for-done BEGIN f8070110 rl@ 30 and UNTIL
BEGIN 8b4 config-l@ 30 and UNTIL ;
: ldtstop1 f8000840 rl@ dup 20000 or f8000840 rl! delay
f8000840 rl! wait-for-done ;
: warm 400000 f8070300 rl! 0 f8070300 rl! ;
: dumpht cr f8070110 rl@ 8 0.r space 8b4 config-l@ 8 0.r
space f8070122 rb@ 2 0.r space 8bd config-b@ 2 0.r ;
: clearht f8070110 dup rl@ swap rl!
f8070120 dup rl@ swap rl!
08b4 dup config-l@ swap config-l!
08bc dup config-l@ swap config-l! ;
: setwidth dup f8070110 rb! 8b7 config-b! ;
: set8 00 setwidth ;
: set16 11 setwidth ;
: setfreq dup f8070122 rb! 8bd config-b! ;
: set200 0 setfreq ;
: set300 1 setfreq ;
: set400 2 setfreq ;
: set500 3 setfreq ;
: set600 4 setfreq ;
: set800 5 setfreq ;
: set1000 6 setfreq ;
: set1200 7 setfreq ;
: set1400 8 setfreq ;
: set1600 9 setfreq ;
: ht>freq 2 + dup 6 > IF 2* 6 - THEN d# 100 * ;
\ XXX: looks only at the U3/U4 side for max. link speed and width.
clearht f8070111 rb@ setwidth
f8070120 rw@ 2log dup .( Switching top HT bus to ) ht>freq 0 d# .r .( MHz...) cr
setfreq u3? IF ldtstop THEN u4? IF ldtstop1 THEN
: open true ;
: close ;
\ : probe-pci-host-bridge ( bus-max bus-min mmio-max mmio-base mem-max mem-base io-max io-base my-puid -- )
s" /mpic" find-node my-puid pci-irq-init drop
1f 0 c0000000 b8000000 b8000000 80000000 100000000 10000
my-puid probe-pci-host-bridge
: msi
f80040f0 010854 config-l! 0 010858 config-l!
ffff 01085c config-w! 81 010852 config-b!
;
\ This works. Needs cleaning up though; and we need to communicate the
\ MSI address range to the client program. (We keep the default range
\ at fee00000 for now).
: msi-on 7 1 DO 10000 i 800 * a0 + config-l! LOOP ;
msi-on
\ PCIe debug / fixup
: find-pcie-cap ( devfn -- offset | 0 )
>r 34 BEGIN r@ + config-b@ dup ff <> over and WHILE
dup r@ + config-b@ 10 = IF
r> drop EXIT
THEN 1+
REPEAT r> 2drop 0
;
: (set-ps) ( ps addr -- )
8 + >r 5 lshift r@ config-w@ ff1f and or r> config-w! ;
: set-ps ( ps -- )
log2 7 -
10000 0 DO i 8 lshift dup find-pcie-cap ?dup IF
+ 2dup (set-ps) THEN drop LOOP drop ;
: (set-rr) ( rr addr -- )
8 + >r c lshift r@ config-w@ 8fff and or r> config-w! ;
: set-rr ( rr -- )
log2 7 -
10000 0 DO i 8 lshift dup find-pcie-cap ?dup IF
+ 2dup (set-rr) THEN drop LOOP drop ;
100 set-ps 200 set-rr
100 set-ps 200 set-rr
finish-device
|