Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | \ ========== Copyright Header Begin ========================================== |
2 | \ | |
3 | \ Hypervisor Software File: pkg.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: @(#)pkg.fth 1.5 07/06/22 | |
43 | purpose: Intel Ophir/82571 external interface | |
44 | copyright: Copyright 2007 Sun Microsystems, Inc. All rights reserved. | |
45 | copyright: Use is subject to license terms. | |
46 | ||
47 | headerless | |
48 | 0 instance value obp-tftp | |
49 | ||
50 | : init-obp-tftp ( tftp-args$ -- okay? ) | |
51 | " obp-tftp" find-package if | |
52 | open-package | |
53 | else | |
54 | ." Can't open OBP standard TFTP package" cr | |
55 | 2drop 0 | |
56 | then | |
57 | dup to obp-tftp | |
58 | ; | |
59 | ||
60 | : (setup-link) ( -- link-up? ) | |
61 | net-on if | |
62 | setup-transceiver ( link-up? ) | |
63 | else | |
64 | false ( link-up? ) | |
65 | then | |
66 | ; | |
67 | ||
68 | \ Needed? | |
69 | : (restart-net) ( -- link-up? ) | |
70 | false to restart? | |
71 | (setup-link) | |
72 | ; | |
73 | ||
74 | ['] (restart-net) to restart-net | |
75 | ||
76 | : setup-link ( -- [ link-status ] error? ) | |
77 | ['] (setup-link) catch | |
78 | ; | |
79 | ||
80 | : bringup-link ( -- ok? ) | |
81 | d# 20000 get-msecs + false | |
82 | begin | |
83 | over timed-out? 0= over 0= and | |
84 | while | |
85 | setup-link if 2drop false exit then ( link-up? ) | |
86 | if | |
87 | drop true | |
88 | else | |
89 | " Retrying network initialization" diag-type-cr | |
90 | then | |
91 | repeat nip | |
92 | ; | |
93 | ||
94 | external | |
95 | ||
96 | : close ( -- ) | |
97 | obp-tftp ?dup if close-package then | |
98 | reg-base if net-off unmap-resources then | |
99 | ; | |
100 | ||
101 | : open ( -- flag ) | |
102 | map-resources | |
103 | my-args parse-devargs | |
104 | init-obp-tftp 0= if close false exit then | |
105 | bringup-link ?dup 0= if close false exit then | |
106 | publish-properties | |
107 | mac-address encode-bytes " mac-address" property | |
108 | ; | |
109 | ||
110 | headers | |
111 | ||
112 | depend-load SUN4V ${BP}/dev/sun4v-devices/utilities/md-parse.fth | |
113 | depend-load SUN4V ${BP}/dev/pci/cfgio.fth | |
114 | depend-load SUN4V ${BP}/dev/utilities/strings.fth | |
115 | ||
116 | [ifdef] SUN4V | |
117 | defer package-to-path 0 " package-to-path" do-cif is package-to-path | |
118 | ||
119 | d# 256 buffer: path-buf | |
120 | ||
121 | \ create a packed string that contains the current node's device-path | |
122 | \ the unit address must me manually added because it's not available | |
123 | \ at probe time. | |
124 | : make-path ( -- ) | |
125 | path-buf 0 over c! ( buf ) | |
126 | d# 255 over 1+ ( buf len buf' ) | |
127 | my-self ihandle>phandle package-to-path ( buf len' ) | |
128 | \ then add unit address | |
129 | 1+ 2dup + ascii @ swap c! ( buf len'' ) | |
130 | 0 0 my-space " encode-unit" $call-parent ( buf len'' $unit ) | |
131 | 2over + 1+ swap dup >r move r> + ( buf len''' ) | |
132 | swap c! ( ) | |
133 | ; | |
134 | ||
135 | : $path ( -- str,len ) path-buf count ; | |
136 | ||
137 | 6 constant /lcl-mac-buf | |
138 | /lcl-mac-buf buffer: lcl-mac-buf | |
139 | ||
140 | 0 value done? | |
141 | ||
142 | \ convert the mac-address (if available) to a byte stream | |
143 | : get-mac-address ( node -- ) | |
144 | " mac-addresses" ascii d md-find-prop ?dup if ( prop| ) | |
145 | md-decode-prop 2drop ( mac-addr ) | |
146 | lcl-mac-buf /lcl-mac-buf move true to done? ( ) | |
147 | then ( ) | |
148 | ; | |
149 | ||
150 | h# 256 buffer: pci-string | |
151 | ||
152 | : $pci ( -- str,len ) " /pci@" ; | |
153 | : $network ( -- str,len ) " /network@" ; | |
154 | ||
155 | : make-root-pci-string ( cfg-handle -- $device-path ) | |
156 | $pci pci-string 0 $strcat | |
157 | rot (u.) 2swap $strcat | |
158 | ; | |
159 | ||
160 | : (make-pci-string) ( device function $device-path $suffix -- $device-path' ) | |
161 | 2swap $strcat 2swap ( $device-path device function ) | |
162 | >r (u.) 2swap $strcat ( $device-path )( R: function ) | |
163 | r> ?dup if ( $device-path function| ) | |
164 | -rot " ," 2swap $strcat ( function $device-path ) | |
165 | rot (u.) 2swap $strcat ( $device-path ) | |
166 | then ( $device-path ) | |
167 | ; | |
168 | ||
169 | : make-pci-string ( $device-path device function -- $device-path' ) | |
170 | 2swap $pci (make-pci-string) | |
171 | ; | |
172 | ||
173 | : make-network-string ( $device-path device function -- $device-path' ) | |
174 | 2swap $network (make-pci-string) | |
175 | ; | |
176 | ||
177 | : $compare ( flag str1,len1 str2,len2 -- flag str1,len1 ) | |
178 | 2over $= -rot 2swap or -rot | |
179 | ; | |
180 | ||
181 | \ Flag to determine if the input MD node is a PCI bus type device. | |
182 | : pcibus? ( node -- flag ) | |
183 | " device-type" ascii s md-find-prop dup if ( prop|0 ) | |
184 | md-decode-prop drop ( $device-type ) | |
185 | 0 -rot ( flag $device-type ) | |
186 | " pcie-switch-upstream" $compare ( flag $device-type ) | |
187 | " pcie-switch-downstream" $compare ( flag $device-type ) | |
188 | " pcie-pcix-bridge" $compare ( flag $device-type ) | |
189 | " pcix-pcix-bridge" $compare ( flag $device-type ) | |
190 | 2drop ( flag ) | |
191 | then ( flag ) | |
192 | ; | |
193 | ||
194 | \ Flag to determine if the input MD node is a network device. | |
195 | : network-device? ( node -- flag ) | |
196 | " device-type" ascii s md-find-prop dup if ( prop|0 ) | |
197 | md-decode-prop drop ( $device-type ) | |
198 | " pci-network" $= ( flag ) | |
199 | then ( flag ) | |
200 | ; | |
201 | ||
202 | \ Returns the device and function number of the input MD node | |
203 | : get-md-dev-fcn ( node -- dev# fcn# ) | |
204 | dup " device-number" md-get-required-prop drop ( node dev# ) | |
205 | swap " function-number" md-get-required-prop drop ( dev# fcn# ) | |
206 | ; | |
207 | ||
208 | \ (fill-mac-buf) is a recursive function that parses the MD looking for the correct | |
209 | \ node associated with this device tree node instance. Once it finds the MD node, | |
210 | \ the method extracts the 'mac-addresses' property and fills the mac buffer with the | |
211 | \ first entry (which will become the local-mac-address for this node). | |
212 | : (fill-mac-buf) ( $device-path node -- $device-path ) | |
213 | recursive | |
214 | >r r@ pcibus? done? 0= and if ( $device-path )( R: node ) | |
215 | 2dup ( $device-path $device-path ) | |
216 | r@ get-md-dev-fcn ( $device-path $device-path dev# fcn# ) | |
217 | make-pci-string ( $device-path $device-path' ) | |
218 | ['] (fill-mac-buf) ( $device-path $device-path' acf ) | |
219 | r@ md-applyto-fwds ( $device-path $device-path' )( R: ) | |
220 | 2drop ( $device-path ) | |
221 | then ( $device-path ) | |
222 | r@ network-device? if ( $device-path ) | |
223 | 2dup ( $device-path $device-path ) | |
224 | r@ get-md-dev-fcn ( $device-path $device-path dev# func# ) | |
225 | make-network-string ( $device-path $device-path' ) | |
226 | $path ( $device-path $device-path' $device-path'' ) | |
227 | $= if ( $device-path flag ) | |
228 | r@ get-mac-address ( $device-path ) | |
229 | then ( $device-path ) | |
230 | then ( $device-path ) | |
231 | r> drop ( $device-path )( R: ) | |
232 | ; | |
233 | ||
234 | \ 'node' should point to the phys_io node in the MD. This function will scan | |
235 | \ through all children looking for the local-mac-address to fill the mac buffer | |
236 | : fill-mac-buf ( node -- ) | |
237 | dup " device-type" ascii s md-find-prop ?dup if ( node prop| ) | |
238 | md-decode-prop drop ( node $dev-type ) | |
239 | " pciex" $= if ( node ) | |
240 | dup " cfg-handle" ascii v md-find-prop ( node prop ) | |
241 | md-decode-prop drop ( node cfg-handle ) | |
242 | make-root-pci-string ( node $device-path ) | |
243 | rot ['] (fill-mac-buf) swap md-applyto-fwds ( $device-path ) | |
244 | 2drop ( ) | |
245 | else ( node ) | |
246 | drop ( ) | |
247 | then ( ) | |
248 | else ( node ) | |
249 | drop ( ) | |
250 | then ( ) | |
251 | ; | |
252 | ||
253 | \ Returns a buffer that contains the local-mac-address for this node | |
254 | : find-my-mac-addr ( -- buf | 0 ) | |
255 | make-path | |
256 | lcl-mac-buf /lcl-mac-buf erase | |
257 | 0 to done? | |
258 | 0 " phys_io" md-find-node ?dup if ( node|false ) | |
259 | ['] fill-mac-buf swap ( acf node ) | |
260 | md-applyto-fwds ( ) | |
261 | then ( ) | |
262 | done? if ( ) | |
263 | lcl-mac-buf ( buf ) | |
264 | else ( ) | |
265 | false ( 0 ) | |
266 | then ( ) | |
267 | ; | |
268 | ||
269 | \ The following code compares the MAC address assigned by the system | |
270 | \ to the MAC address programmed in the Ophir EEPROM. This step is | |
271 | \ required because Intel reloads the MAC addresses from the EEPROM | |
272 | \ when the controler is reset (going into loopback mode during SunVTS | |
273 | \ for example) so we have to make sure the EEPROM matches what we | |
274 | \ assign the device | |
275 | : update-mac-address ( -- ) | |
276 | find-my-mac-addr ?dup if | |
277 | map-resources ( mac-adr-ptr ) | |
278 | dup w@ wbflip >r ( mac-adr-ptr )( R: mac0 ) | |
279 | dup 2 + w@ wbflip >r ( mac-adr-ptr )( R: mac0 mac1 ) | |
280 | 4 + w@ 1 invert and wbflip r> r> ( mac2' mac1 mac0 ) | |
281 | 3dup false ( mac2' mac1 mac0 mac2' mac1 mac0 flg ) | |
282 | swap 0 eeprom-w@ <> or ( mac2' mac1 mac0 mac'2 mac1 flag ) | |
283 | swap 1 eeprom-w@ <> or ( mac2' mac1 mac0 mac2' flag ) | |
284 | swap 2 eeprom-w@ <> or if ( mac2' mac1 mac0 ) | |
285 | 0 eeprom-w! 1 eeprom-w! ( mac2' ) | |
286 | 2 eeprom-w! checksum ( checksum ) | |
287 | h# 3f eeprom-w! ( ) | |
288 | else ( mac2' mac1 mac0 ) | |
289 | 3drop ( ) | |
290 | then ( ) | |
291 | unmap-resources ( ) | |
292 | else | |
293 | cmn-warn[ " Missing network-vpd MD node " ]cmn-end | |
294 | then | |
295 | ; | |
296 | ||
297 | update-mac-address | |
298 | ||
299 | [else] | |
300 | \ The following code compares the MAC address assigned by the system | |
301 | \ to the MAC address programmed in the Ophir EEPROM. This step is | |
302 | \ required because Intel reloads the MAC addresses from the EEPROM | |
303 | \ when the controler is reset (going into loopback mode during SunVTS | |
304 | \ for example) so we have to make sure the EEPROM matches what we | |
305 | \ assign the device | |
306 | : update-mac-address ( -- ) | |
307 | map-resources ( ) | |
308 | " local-mac-address" ( propstr,len ) | |
309 | get-my-property 2drop ( mac-adr-ptr ) | |
310 | dup w@ wbflip >r ( mac-adr-ptr )( R: mac0 ) | |
311 | dup 2 + w@ wbflip >r ( mac-adr-ptr )( R: mac0 mac1 ) | |
312 | 4 + w@ 1 invert and wbflip r> r> ( mac2' mac1 mac0 ) | |
313 | 3dup false ( mac2' mac1 mac0 mac2' mac1 mac0 flag ) | |
314 | swap 0 eeprom-w@ <> or ( mac2' mac1 mac0 mac'2 mac1 flag ) | |
315 | swap 1 eeprom-w@ <> or ( mac2' mac1 mac0 mac2' flag ) | |
316 | swap 2 eeprom-w@ <> or if ( mac2' mac1 mac0 ) | |
317 | 0 eeprom-w! 1 eeprom-w! ( mac2' ) | |
318 | 2 eeprom-w! checksum ( checksum ) | |
319 | h# 3f eeprom-w! ( ) | |
320 | else ( mac2' mac1 mac0 ) | |
321 | 3drop ( ) | |
322 | then ( ) | |
323 | unmap-resources ( ) | |
324 | ; | |
325 | ||
326 | update-mac-address | |
327 | ||
328 | [then] | |
329 | ||
330 | : xmit ( buffer length -- #sent ) | |
331 | link-up? 0= if | |
332 | \ >>> cmn-xxx | |
333 | " Link is down. Restarting network initialization" diag-type-cr | |
334 | restart-net if | |
335 | 2drop 0 exit | |
336 | then | |
337 | then ( buffer len ) | |
338 | get-tx-buffer swap ( buffer txbuf len ) | |
339 | 2dup >r >r cmove r> r> ( txbuf len ) | |
340 | tuck ( len txbuf len ) | |
341 | d# 64 max ( len txbuf len' ) | |
342 | transmit 0= if drop 0 then ( #sent ) | |
343 | ; | |
344 | ||
345 | : poll ( buffer len -- #rcvd ) | |
346 | receive-ready? 0= if | |
347 | 2drop 0 exit | |
348 | then | |
349 | receive ?dup if ( buffer len handle pkt pktlen ) | |
350 | rot >r rot min >r swap r@ cmove r> r> ( #rcvd handle ) | |
351 | else ( buffer len handle pkt ) | |
352 | drop nip nip 0 swap ( 0 handle ) | |
353 | then | |
354 | return-buffer | |
355 | ; | |
356 | ||
357 | external | |
358 | ||
359 | : read ( buf len -- -2 | actual-len ) | |
360 | poll ?dup 0= if -2 then | |
361 | ; | |
362 | ||
363 | : write ( adr len -- len' ) | |
364 | xmit | |
365 | ; | |
366 | ||
367 | : load ( adr -- size ) | |
368 | " load" obp-tftp $call-method | |
369 | ; | |
370 | ||
371 | : watch-net ( -- ) | |
372 | map-resources | |
373 | my-args parse-devargs 2drop ( ) | |
374 | promiscuous to mac-mode | |
375 | bringup-link ( ok? ) | |
376 | if watch-test then | |
377 | net-off | |
378 | unmap-resources | |
379 | ; | |
380 | ||
381 | headers | |
382 | ||
383 | : reset ( -- ) | |
384 | reg-base if | |
385 | net-off unmap-resources | |
386 | else | |
387 | map-regs net-off unmap-regs | |
388 | then | |
389 | ; |