Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / obp / obp / os / bootprom / instance.fth
CommitLineData
920dae64
AT
1\ ========== Copyright Header Begin ==========================================
2\
3\ Hypervisor Software File: instance.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: @(#)instance.fth 2.60 07/01/22
43purpose: Create, destroy, and call package instances
44copyright: Copyright 2007 Sun Microsystems, Inc. All Rights Reserved
45copyright: Use is subject to license terms.
46
47\ Creation and destruction of device instances. Also package interface words.
48
49defer fm-hook ( adr len phandle -- adr len phandle )
50' noop is fm-hook
51: find-method ( adr len phandle -- false | acf true )
52 fm-hook (search-wordlist)
53;
54
55: "open" " open" ;
56: $call-self ( adr len -- )
57 my-voc setup-method$ fm-hook $vexecute? if no-proc throw then
58;
59
60[ifndef] package(
61transient
62: )package-macro ( -- ) r> is my-self ;
63: package(-macro ( ihandle -- ) my-self >r is my-self ;
64resident
65macro: package( package(-macro
66macro: )package )package-macro
67[then]
68
69: call-package ( ??? acf ihandle -- ??? ) package( execute )package ;
70: $call-method ( ??? adr len ihandle -- ??? ) package( $call-self )package ;
71: $call-parent ( adr len -- ) my-parent package( $call-self )package ;
72: (skip-interposed) ( -- )
73 begin interposed? while my-parent is my-self repeat
74;
75
76: ihandle>phandle ( ihandle -- phandle )
77 package( (skip-interposed) my-voc )package
78;
79
80: $call-static-method ( ??? adr len phandle -- ??? )
81 setup-method$ find-method 0= if no-proc throw then execute
82;
83
84\ set-args is executed only during probing, at which time the active package
85\ corresponds to the current instance, thus '#adr-cells can be executed
86\ directly.
87
88: set-args ( arg-str reg-str -- )
89 current-device >r pop-device (decode-unit) r> push-device
90 '#adr-cells @ ( arg-str phys .. #cells )
91 dup if swap to my-space 1- then ( arg-str phys .. #cells' )
92 addr my-adr0 swap /n* bounds ?do i ! /n +loop ( arg-str )
93 copy-args
94;
95
96: get-package-property ( adr len phandle -- true | adr' len' false )
97 also execute get-property previous
98;
99
100\ Used when executing from an open package instance. Finds a property
101\ associated with the current package.
102: get-my-property ( adr len -- true | adr' len' false )
103 my-voc get-package-property
104;
105
106headerless
1070 value interposer \ phandle of interposing package, if any
1080 value ip-arg-adr \ arguments for interposing package
1090 value ip-arg-len
110
111\ Internal factor of get-inherited-property. This factoring is necessary
112\ because we use "exit" to make the control flow easier.
113: (get-any) ( adr len -- true | adr' len' false )
114 begin my-self while ( adr len ) \ Search up parent chain
115 my-voc current token! ( adr len )
116 2dup get-my-property 0= if ( adr len adr' len' )
117 2swap 2drop false exit ( adr' len' false ) \ Found
118 then ( adr len )
119 my-parent is my-self ( adr len )
120 repeat ( adr len )
121 2drop true ( true ) \ Not found
122;
123
124headers
125\ Finds a property associated with the current package or with one of
126\ its parents.
127: get-inherited-property ( adr len -- true | adr' len' false )
128 current token@ >r my-self >r
129 (get-any)
130 r> is my-self r> current token!
131;
132
133headerless
134: try-close ( -- ) " close" ['] $call-self catch if 2drop then ;
135headers
136: close-package ( ihandle -- )
137 package( try-close destroy-instance )package
138;
139headerless
140: close-parents ( -- )
141 begin my-self while try-close destroy-instance repeat
142;
143: close-chain ( -- ) destroy-instance close-parents ;
144headers
145: close-dev ( ihandle -- ) package( close-parents )package ;
146
147\ Extract the next (leftmost) component from the path name, updating the
148\ path variable to reflect the remainder of the path after the extracted
149\ component.
150: parse-component ( path$ -- path$ args$ devname$ )
151 ascii / left-parse-string ( path$' component$ )
152 ascii : left-parse-string ( path$ args$ devname$ )
153 dup 0= if 2drop " /" then ( path$ args$ devname$' )
154;
155
156: apply-method ( adr len -- no-such-method? )
157 my-voc setup-method$
158 fm-hook ['] $vexecute? catch ?dup if ( x x x errno )
159 \ executing method caused an error
160 nip nip nip ( errno )
161 then ( ??? false | true | errno )
162;
163
164headerless
165
166d# 64 buffer: package-name-buf
167
168headers
169
170: my-unit-bounds ( -- end-adr start-adr )
171 addr my-unit-low '#adr-cells @ /n* bounds
172;
173: set-my-unit ( phys.hi .. phys.lo -- )
174 my-unit-bounds ?do i ! /n +loop
175;
176
177: set-default-unit ( -- )
178 get-unit 0= if unit-str>phys- set-my-unit then
179;
180\ Set the my-unit fields in the instance record:
181\ If an address was given in path component, use it
182\ If not, use address in "reg" property of package
183\ Otherwise, use 0,0
184: set-instance-address ( -- )
185 unit#-valid? if
186 unit-bounds ?do i @ /n +loop set-my-unit
187 else
188 set-default-unit
189 then
190;
191
192headerless
193: (apply-method) ( adr len -- ??? )
194 apply-method if close-chain no-proc throw then ( )
195;
196: (open-node) ( -- )
197 "open" (apply-method) 0= if ( okay? )
198 close-chain p" open failed" throw ( )
199 then
200;
201
202: encode-bytes+ ( adr1 len1 adr2 len2 -- adr1 len1+len2 )
203 encode-bytes encode+
204;
205
206: encode-number+ ( u adr,len -- adr,len' )
207 base @ >r hex
208 rot (u.) encode-bytes+
209 r> base !
210;
211
212: make-node-alias ( nodeid name-str -- )
213 current-device >r ( nodeid name-str )
214 rot push-device ( name-str )
215 pwd$ ( name-str expansion-str )
216 r> push-device ( name-str expansion-str )
217 $devalias ( )
218;
219
220: (append-args) ( arg$ base$ -- base$' )
221 2 pick if ( arg$ base$ )
222 " :" 2swap $add ( arg$ base$' )
223 then ( arg$ base$ )
224 $add ( base$ )
225;
226
227: (ihandle>path) ( no-interpose? str,len -- allow-interpose? str,len' )
228 recursive
229 2 pick if (skip-interposed) then ( flag str,len )
230 my-parent if ( flag str,len )
231 my-parent package( (ihandle>path) )package ( flag str,len )
232 my-voc push-device ( flag str,len )
233 interposed? if " %" else " /" then ( flag str,len' sep$ )
234 2swap $add ( flag str,len' )
235 (append-name) ( flag str,len' )
236 support-node? @ if exit then ( flag str,len )
237 2>r my-unit 2r> (append-unit) ( flag str,len' )
238 my-args 2swap (append-args) ( flag str,len' )
239 then ( flag str,len )
240;
241
242overload: (ihandle>path) ( ihandle flag -- str,len )
243 current-device my-self 2>r ( ihandle flag )
244 swap is my-self ( flag )
245 "temp 0 (ihandle>path) ( flag str,len )
246 2r> is my-self push-device rot drop ( str,len )
247;
248
249headers
250\ ihandle>devname returns the device tree nodes for this ihandle
251: ihandle>devname ( ihandle -- adr,len ) 1 (ihandle>path) ;
252
253\ ihandle>devpath returns the full instance path, including interposed packages
254: ihandle>devpath ( ihandle -- adr,len ) 0 (ihandle>path) ;
255
256: phandle>devname ( phandle -- adr,len )
257 current-device >r ( phandle ) ( r: phandle' )
258 push-device pwd$ ( adr,len ) ( r: phandle' )
259 r> push-device ( adr,len )
260;
261
262: open-node ( -- ) recursive
263 (open-node)
264 interposer if
265 interposer 0 to interposer push-package
266 ip-arg-adr ip-arg-len new-instance true is interposed? open-node
267 pop-package
268 then
269;
270
271: interpose ( args$ phandle -- )
272 to interposer to ip-arg-len to ip-arg-adr
273;
274
275headerless
276
277: (no-proc) ( -- )
278 " Unimplemented procedure '" "temp pack >r ( )
279 saved-method$ 2@ r@ $cat ( )
280 saved-method-package @ dup if ( )
281 " ' in " r@ $cat phandle>devname ( str,len )
282 else ( )
283 drop " '" ( str,len )
284 then r@ $cat ( )
285 r> count ( str,len )
286 set-abort-message -2 ( -2 )
287;
288\ Resolve the forward references to no-proc
289' (no-proc) is no-proc
290
291: open-parents ( parent-phandle end-phandle -- ) recursive
292 \ Exit at null "parent" of root node
293 2dup = if 2drop exit then
294
295 over >parent swap open-parents ( phandle )
296
297 push-device ( )
298 " " new-instance ( )
299 set-default-unit ( )
300 open-node ( )
301;
302
303\ Open packages between, but not including, "phandle" and the active package
304: select-node ( path$ -- path$' )
305 current-device >r
306 parse-component ( path$ args$ devname$ )
307 noa-find-device ( path$ args$ )
308 current-device dup >parent r> open-parents ( path$ args$ my-phandle )
309 push-device ( path$ args$ )
310 new-instance ( path$ )
311 set-instance-address ( path$ )
312;
313
314\ Open pathname components until the last one, and then apply the indicated
315\ method to the last component.
316: open-path ( path$ -- )
317 ?dup if ( path$ )
318 \ Establish the initial parent
319 null to current-device ( path$ )
320 0 to interposer
321 ?expand-alias select-node ( path$ )
322 begin dup while open-node select-node repeat ( path$' )
323 2drop ( )
324 else ( adr )
325 not-found throw ( )
326 then ( )
327;
328
329headers
330: open-package ( args$ phandle -- ihandle )
331 push-package ( args$ )
332 new-instance ( )
333 "open" apply-method if false then if ( )
334 my-self my-parent is my-self ( ihandle )
335 else ( )
336 destroy-instance 0 ( 0 )
337 then ( ihandle )
338 pop-package ( ihandle )
339;
340
341: find-package ( name$ -- false | phandle true )
342 dup 0= if true else over c@ ascii / <> then ( name$ relative? )
343 if ( name$ )
344 " /packages/" package-name-buf pack $cat ( )
345 package-name-buf count ( name$' )
346 then ( name$' )
347 locate-device 0= ( false | phandle true )
348;
349
350: $open-package ( arg$ name$ -- ihandle )
351 find-package if open-package else 2drop 0 then
352;
353
354headers
355
356: begin-open-dev ( path$ -- ihandle )
357 0 package( current-device >r
358
359 \ Since "catch/throw" saves and restores my-self,
360 \ my-self will be 0 if a throw occurred.
361
362 ['] open-path catch if 2drop then
363 my-self ( ihandle )
364
365 r> push-device )package ( ihandle )
366;
367
368headerless
369
370: (open-dev) ( path$ -- ) open-path open-node ;
371
372headers
373
374: open-dev ( adr len -- ihandle | 0 )
375 0 package( current-device >r
376
377 \ Since "catch/throw" saves and restores my-self,
378 \ my-self will be 0 if a throw occurred.
379
380 ['] (open-dev) catch if 2drop then
381 my-self ( ihandle )
382
383 r> push-device )package ( ihandle )
384;
385
386headerless
387
388: (execute-method) ( path$ method$ -- false | ??? true )
389 2swap open-path (apply-method)
390;
391
392\ Same as (execute-method), but use (open-dev) instead of open-path
393: (execute-method-opened) ( path$ method$ -- false | ??? true )
394 2swap (open-dev) (apply-method)
395;
396
397headers
398
399: execute-device-method ( path$ method$ -- false | ??? true )
400 0 package( current-device >r ( path$ method$ )
401 ['] (execute-method) catch if ( x x x x )
402 2drop 2drop false ( false )
403 else ( ??? )
404 close-chain true ( ??? true )
405 then ( false | ??? true )
406 device-end ( false | ??? true )
407 r> push-device )package ( false | ??? true )
408;
409
410\ Same as execute-device-method, but open device before calling method
411: execute-method-opened ( path$ method$ -- false | ??? true )
412 0 package( current-device >r ( path$ method$ )
413 ['] (execute-method-opened) catch if ( x x x x )
414 2drop 2drop false ( false )
415 else ( ??? )
416 close-parents true ( ??? true )
417 then ( false | ??? true )
418 device-end ( false | ??? true )
419 r> push-device )package ( false | ??? true )
420;
421
422\ Easier to use version of execute-device-method
423\
424\ ex: apply selftest net
425\
426: apply ( -- ??? ) \ method { devpath | alias }
427 safe-parse-word safe-parse-word ( method$ devpath$ )
428 2swap execute-device-method ( ??? success? )
429 0= abort" apply failed." ( ??? )
430;
431
432
433h# 10 circular-stack: istack
434
435\ select-dev opens a package, sets my-self to that ihandle, pushes the
436\ old my-self on the instance stack, and pushes that package's vocabulary
437\ on the search order. unselect-dev undoes select-dev .
438
439: iselect ( ihandle -- )
440 dup 0= abort" Can't open device" ( ihandle )
441 my-self istack push is my-self
442 also my-voc push-device
443;
444: select-dev ( adr,len -- ) open-dev iselect ;
445: begin-select-dev ( adr,len -- ) begin-open-dev iselect ;
446: end-select-dev ( -- )
447 previous definitions
448 my-parent istack pop is my-self close-dev
449;
450
451: select ( "name" -- ) safe-parse-word select-dev ;
452: begin-select ( "name" -- ) safe-parse-word begin-select-dev ;
453
454: unselect-dev ( -- )
455 previous definitions
456 my-self istack pop is my-self close-dev
457;
458
459: begin-package ( arg-str reg-str parent-str -- )
460 select-dev new-device set-args
461;
462
463: end-package ( -- ) finish-device unselect-dev ;
464
465: (execute-phandle-method) ( method-adr,len phandle -- ??? )
466 0 to unit#-valid? ( method-adr,len phandle )
467 dup >parent null open-parents ( method-adr,len phandle )
468 push-device ( method-adr,len )
469 " " new-instance ( method-adr,len )
470 set-default-unit ( method-adr,len )
471 (apply-method) ( ???? )
472;
473
474headers
475: open-phandle ( phandle -- ihandle | 0 )
476 0 package( ( phandle )
477 current-device >r ( phandle )
478 0 to unit#-valid? ( phandle )
479 null ['] open-parents catch if ( x x error-code )
480 3drop 0 ( 0 )
481 else ( )
482 my-self ( ihandle )
483 then ( ihandle | 0 )
484 r> push-device ( ihandle | 0 )
485 )package ( ihandle | 0 )
486;
487
488: execute-phandle-method ( method-adr,len phandle -- false | ??? true )
489 0 package( ( method-adr,len phandle )
490 current-device >r ( method-adr,len phandle )
491 ['] (execute-phandle-method) catch if ( method-adr,len phandle err-code )
492 3drop false ( false )
493 else ( ??? )
494 close-chain true ( ??? true )
495 then ( false | ??? true )
496 r> push-device ( false | ??? true )
497 )package ( false | ??? true )
498;
499
500: create-dev-instance ( arg$ phandle -- ihandle )
501 my-self >r ( arg$ phandle )
502 dup >parent open-phandle to my-self ( )
503 push-package new-instance set-instance-address pop-package ( )
504 my-self r> to my-self ( ihandle )
505;
506
507: destroy-dev-instance ( ihandle -- )
508 my-self >r to my-self ( )
509 destroy-instance my-self close-dev ( )
510 r> to my-self ( )
511;
512
513: .path ( ihandle -- ) dup if ihandle>devname type cr else drop then ;
514
515headerless