Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | \ ========== Copyright Header Begin ========================================== |
2 | \ | |
3 | \ Hypervisor Software File: cpustruct.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: @(#)cpustruct.fth 1.5 07/07/12 | |
43 | purpose: | |
44 | copyright: Copyright 2007 Sun Microsystems, Inc. All Rights Reserved | |
45 | copyright: Use is subject to license terms. | |
46 | ||
47 | hex | |
48 | headers | |
49 | ||
50 | fload ${BP}/cpu/sparc/mutex.fth | |
51 | ||
52 | mutex-create prom-lock | |
53 | ||
54 | label cif-owner -1 l, end-code | |
55 | label release-slaves? 0 , end-code | |
56 | ||
57 | 0 value mp-cpu-state | |
58 | 0 value cpu-table | |
59 | h# ff constant CPU-IN-MD | |
60 | ||
61 | \ compute the offsets | |
62 | struct | |
63 | /x field >tsb-allocation | |
64 | /x field >tsb-saved-size | |
65 | /x field >tsb-buffer-addr | |
66 | /x field >tsb-reserved | |
67 | constant /tsb-data | |
68 | ||
69 | transient | |
70 | ||
71 | window-registers h# 10 round-up is window-registers | |
72 | window-registers d# 24 /x * + constant /min-cpu-save | |
73 | /min-cpu-save #windows 1- d# 16 * /x * + constant /full-cpu-save | |
74 | ||
75 | h# 800 constant /cpu-state | |
76 | ||
77 | \ Note that the fth-exception-stack exists in four different incarnations, | |
78 | \ immu-miss, dmmu-miss, fp-int and intr. The first three are perfectly | |
79 | \ happy with a stack depth of 64. The intr stack, since it has to run | |
80 | \ USB code at Alarm level, needs more depth, depending on how many levels | |
81 | \ of PCI bridges and USB hubs cause additional $call-parent. See bug 6381064. | |
82 | ||
83 | d# 128 2* /x * constant /fth-exception-stack | |
84 | /min-cpu-save /fth-exception-stack + constant /min-exec-state | |
85 | ||
86 | /full-cpu-save /cpu-state > | |
87 | abort" CPU STRUCT ISNT LARGE ENOUGH TO HOLD A STATE SAVE" | |
88 | ||
89 | resident | |
90 | headers | |
91 | ||
92 | struct | |
93 | /cpu-state field >cpu-state | |
94 | h# 800 round-up | |
95 | ps-size field >data-stack | |
96 | h# 800 round-up | |
97 | rs-size field >return-stack | |
98 | h# 800 round-up | |
99 | /min-exec-state field >immu-miss-state | |
100 | /min-exec-state field >dmmu-miss-state | |
101 | /min-exec-state field >fpu-int-state | |
102 | /min-exec-state field >intr-state | |
103 | /n field >mmu-defer | |
104 | /n field >debugger-hook | |
105 | /n field >cpu-status | |
106 | /n field >cpu-node | |
107 | /n field >cpu-rp0 | |
108 | /n field >cpu-sp0 | |
109 | /n field >cpu-rp0-fence | |
110 | /n field >cpu-sp0-fence | |
111 | /n field >stack-fence? | |
112 | /n field >guarded-pc \ used by | |
113 | /n field >guarded-ip \ guarded-execute | |
114 | ua-size field >user-save | |
115 | /tsb-data 1 << field >cpu-tsb-ctrl-area | |
116 | /n field >cpu-devmondo-ptr | |
117 | /n field >nonreserr-bflag | |
118 | /n field >reserr-count | |
119 | /n field >nonreserr-count | |
120 | /queue-entry field >nonreserr-shadowbuf | |
121 | ||
122 | pagesize round-up \ Round up to pagesize | |
123 | constant /cpu-struct | |
124 | ||
125 | /cpu-struct h# 6000 > if cr ." Warning: cpu-struct is getting large!" cr then | |
126 | ||
127 | \ | |
128 | \ WATCHOUT.. these will adjust what the register display words show! | |
129 | \ and NOT ALL that they show will be valid. | |
130 | \ | |
131 | \ If you shift the cpu-reg-offset | |
132 | \ be sure to put it back using select-cpu-state | |
133 | \ | |
134 | : select-cpu-state ( -- ) 0 is cpu-reg-offset ; | |
135 | : select-immu-state ( -- ) 0 >immu-miss-state is cpu-reg-offset ; | |
136 | : select-dmmu-state ( -- ) 0 >dmmu-miss-state is cpu-reg-offset ; | |
137 | : select-intr-state ( -- ) 0 >intr-state is cpu-reg-offset ; | |
138 | ||
139 | : >cpu-struct ( n -- addr ) /cpu-struct * mp-cpu-state + ; | |
140 | ||
141 | \ Is given mid present in MD? | |
142 | : mid-ok? ( mid -- ok? ) | |
143 | dup 0 max-#cpus within if ( mid ) \ mid should be within 0 and max-#cpus | |
144 | cpu-table + c@ CPU-IN-MD = ( ok? ) \ then check to see if it is in MD | |
145 | else ( mid ) \ else return not-ok | |
146 | drop false ( not-ok ) | |
147 | then | |
148 | ; | |
149 | ||
150 | : (cpu-state ( -- adr ) mid@ >cpu-struct ; | |
151 | : >cpu-status! ( n -- ) (cpu-state >cpu-status ! ; | |
152 | ||
153 | \ Is given mid present in OpenBoot? | |
154 | : mid-present? ( mid -- present? ) | |
155 | dup mid@ = if | |
156 | drop true | |
157 | else | |
158 | >cpu-struct >cpu-status @ | |
159 | then | |
160 | ; | |
161 | ||
162 | headerless | |
163 | ||
164 | \ Allocate and update cpu-table, if CPU is present in MD then set the table | |
165 | \ entry to 0xff or else leave it at 0 | |
166 | : update-cpu-table ( -- ) | |
167 | max-#cpus alloc-mem to cpu-table | |
168 | 0 | |
169 | begin ( 0 ) | |
170 | " cpu" md-find-node ( cpunode | 0 ) | |
171 | ?dup while ( cpunode ) | |
172 | dup " id" ascii v md-find-prop ( cpunode entry|0 ) | |
173 | ?dup if ( cpunode pdentry ) | |
174 | md-decode-prop drop ( cpudnode id ) | |
175 | \ "id" must be within 0 and max-#cpus | |
176 | dup 0 max-#cpus within if ( cpunode id ) | |
177 | \ Mark this CPU present in the table | |
178 | CPU-IN-MD swap cpu-table + c! ( cpudnode ) | |
179 | else | |
180 | drop ( cpudnode ) | |
181 | then | |
182 | then | |
183 | repeat | |
184 | ; | |
185 | ||
186 | ' (cpu-state is cpu-state | |
187 | ||
188 | 4 actions | |
189 | action: ( apf -- ??? ) aligned l@ (cpu-state + token@ execute ; | |
190 | action: ( xt apf -- ) aligned l@ (cpu-state + token! ; | |
191 | action: ( apf -- addr ) aligned l@ (cpu-state + ; | |
192 | action: ( xt apf -- ) | |
193 | max-mondo-target# 0 ?do | |
194 | i mid-ok? if | |
195 | 2dup aligned l@ i >cpu-struct + token! | |
196 | then | |
197 | loop 2drop | |
198 | ; | |
199 | ||
200 | headers | |
201 | ||
202 | : per-cpu-defer: ( offset -- ) \ name | |
203 | create align l, use-actions | |
204 | ; | |
205 | ||
206 | inline-struct? on | |
207 | h# 04 constant CPU-INIT \ Starting INIT | |
208 | h# 10 constant CPU-OBP-COLD \ exec OBP, never started | |
209 | h# 11 constant CPU-IDLING \ prom idle, never started | |
210 | h# 20 constant CPU-PARKED \ Parked by mondo (bp) | |
211 | h# 21 constant CPU-ENTERFORTH \ Waiting to enter FORTH | |
212 | h# 22 constant CPU-WAIT-RESTART \ Waiting to restart | |
213 | h# 30 constant CPU-OBP-WARM \ CPU is running OBP (started) | |
214 | h# 31 constant CPU-PROM-CIF \ CPU is in the CIF | |
215 | h# 32 constant CPU-ACCUMULATING \ Waiting for cpus to arrive | |
216 | h# 33 constant CPU-RELEASED \ restarted. | |
217 | h# 40 constant CPU-STARTED \ cpu in client. | |
218 | inline-struct? off | |
219 | ||
220 | headers transient \ transient | |
221 | ||
222 | also assembler definitions \ Assembler transient | |
223 | hex | |
224 | ||
225 | : get-cpu-struct ( up scr reg -- ) | |
226 | >r r@ get-mid ( up scr ) | |
227 | /cpu-struct over set ( up scr ) \ scr = /cpu-struct | |
228 | r@ over r@ mulx ( up scr ) \ reg = offset | |
229 | >r ['] mp-cpu-state >user# r@ set ( up ) \ scr = user# | |
230 | r@ r@ nget ( ) \ scr = cpu-struct-base | |
231 | r> r@ r> add ( ) | |
232 | ; | |
233 | ||
234 | : get-rp0 ( cpu-struct-ptr reg -- ) | |
235 | 0 >return-stack rs-size + over set | |
236 | dup add | |
237 | ; | |
238 | ||
239 | : set-rp0 ( cpu-struct-ptr scr sc1 -- ) | |
240 | >r 2dup get-rp0 | |
241 | 0 >cpu-rp0 r@ set | |
242 | swap r> stx | |
243 | ; | |
244 | ||
245 | : get-sp0 ( cpu-struct-ptr reg -- ) | |
246 | 0 >data-stack ps-size + over set | |
247 | dup add | |
248 | ; | |
249 | ||
250 | : set-sp0 ( cpu-struct-ptr scr sc1 -- ) | |
251 | >r 2dup get-sp0 | |
252 | 0 >cpu-sp0 r@ set | |
253 | swap r> stx | |
254 | ; | |
255 | ||
256 | : mark-cpu-state ( val scr sc1 state-ptr -- ) | |
257 | >r >r ( val scr ) | |
258 | tuck set ( scr ) | |
259 | r> 0 >cpu-status over set ( scr sc1 ) | |
260 | r> stx ( ) | |
261 | ; | |
262 | ||
263 | resident previous definitions | |
264 | ||
265 | headerless | |
266 | ||
267 | : init-cpu-state ( -- ) | |
268 | cpu-state >data-stack to pssave ( ) | |
269 | cpu-state >return-stack to rssave ( ) | |
270 | cpu-state >cpu-status @ ( n ) | |
271 | CPU-OBP-WARM tuck < if ( s ) | |
272 | drop CPU-OBP-COLD ( s ) | |
273 | then >cpu-status! ( ) | |
274 | 0w ( ) | |
275 | ; | |
276 | ||
277 | : use-fence? ( -- ? ) (cpu-state dup >stack-fence? @ state-valid @ 0 < and ; | |
278 | : cpu-rp0 ( -- n ) use-fence? if >cpu-rp0-fence else >cpu-rp0 then ; | |
279 | : cpu-sp0 ( -- n ) use-fence? if >cpu-sp0-fence else >cpu-sp0 then ; | |
280 | ||
281 | headerless | |
282 | \ | |
283 | \ WATCHOUT!! | |
284 | \ we come in on the (temporary) global stack and return on the per-cpu | |
285 | \ ones. | |
286 | \ | |
287 | code switch-to-private-stacks | |
288 | up sc1 scr get-cpu-struct | |
289 | CPU-OBP-COLD sc1 sc2 scr mark-cpu-state | |
290 | scr sc1 sc2 set-rp0 | |
291 | scr sc1 sc2 set-sp0 | |
292 | ||
293 | 'user .rp0 sc1 nget | |
294 | rp sc2 move \ Src | |
295 | scr sc4 get-rp0 | |
296 | sc1 sc2 sc3 subcc \ depth | |
297 | 0> if | |
298 | sc4 sc3 rp sub \ adjust stack ptr. | |
299 | sc4 sc3 sc4 sub | |
300 | begin | |
301 | sc2 %g0 sc5 ldx | |
302 | sc5 sc4 %g0 stx | |
303 | sc4 /n sc4 add | |
304 | sc2 /n sc2 add | |
305 | sc3 /n sc3 subcc | |
306 | 0= until nop | |
307 | then | |
308 | ||
309 | 'user .sp0 sc1 nget | |
310 | sp sc2 move \ Src | |
311 | scr sc4 get-sp0 | |
312 | sc1 sc2 sc3 subcc \ depth | |
313 | 0> if | |
314 | sc4 sc3 sp sub \ adjust stack ptr. | |
315 | sc4 sc3 sc4 sub | |
316 | sc2 %g0 sc5 ldx | |
317 | begin | |
318 | sc5 sc4 %g0 stx | |
319 | sc4 /n sc4 add | |
320 | sc2 /n sc2 add | |
321 | sc3 /n sc3 subcc | |
322 | 0< until | |
323 | sc2 %g0 sc5 ldx | |
324 | then | |
325 | c; | |
326 | ||
327 | stand-init: allocate cpu structs | |
328 | update-cpu-table | |
329 | /cpu-struct max-#cpus over * ( align size ) | |
330 | tuck 0 cif-claim ( size va ) | |
331 | dup to mp-cpu-state ( size va ) | |
332 | >physical ( size ra 0 ) | |
333 | over scratch7! rot ( ra 0 size ) | |
334 | hv-mem-scrub ( ) | |
335 | ['] cpu-rp0 to rp0 ( ) | |
336 | ['] cpu-sp0 to sp0 ( ) | |
337 | switch-to-private-stacks ( ) | |
338 | CPU-OBP-COLD >cpu-status! ( ) | |
339 | -1 release-slaves? l! ( ) | |
340 | ; | |
341 | ||
342 | 0 3 h# 14 0 hypercall: cpu-queue-config ( size ra queue -- ) | |
343 | : init-per-cpu-data ( -- ) | |
344 | cpu-state >r ( ) ( r: adr ) | |
345 | ||
346 | \ Register cpu mondo queue buffer to hypervisor | |
347 | max-#cpumondo-queue-entries /cpumondo-queue ( n qsiz ) | |
348 | dup 0 cif-claim >physical drop h# 3c cpu-queue-config ( ) | |
349 | ||
350 | \ Register resumable queue buffer to hypervisor | |
351 | max-#res-queue-entries /resumable-queue ( n qsiz ) | |
352 | dup 0 cif-claim >physical drop h# 3e cpu-queue-config ( ) | |
353 | ||
354 | \ Register non-resumable queue buffer to hypervisor | |
355 | max-#nonres-queue-entries /nonresumable-queue ( n qsiz ) | |
356 | dup 0 cif-claim >physical drop h# 3f cpu-queue-config ( ) | |
357 | ||
358 | \ Allocate tsb buffer areas for CTX0 and CTX NON0 | |
359 | max-#tsb-entries r> >cpu-tsb-ctrl-area tuck ( v n v ) \ CTX0 | |
360 | >tsb-allocation x! ( v ) \ size | |
361 | /tsb-buffer-size dup 0 cif-claim >physical drop ( v ra ) | |
362 | over >tsb-buffer-addr x! ( v ) \ buffer ra | |
363 | /tsb-data + ( v' ) \ CTX NON 0 | |
364 | max-#tsb-entries over >tsb-allocation x! ( v' ) \ size | |
365 | /tsb-buffer-size dup 0 cif-claim >physical drop ( v' ra ) | |
366 | swap >tsb-buffer-addr x! ( ) \ buffer ra | |
367 | ||
368 | \ Save the address of the cpu struct | |
369 | cpu-state >physical drop scratch7! ( ) | |
370 | ; | |
371 | ||
372 | \ This routine will iterate over each cpu present in the system, | |
373 | \ calling the acf with the mid on the top of the stack. The routine could | |
374 | \ be called with additional args underneath the acf - the subroutine would | |
375 | \ have to ensure the stack remained intact though. | |
376 | : do-foreach-cpu ( acf -- ) | |
377 | max-mondo-target# 0 ?do ( acf ) | |
378 | i mid-ok? if ( acf ) | |
379 | i mid-present? if ( acf ) | |
380 | i swap >r r@ catch if drop then ( ) | |
381 | r> ( acf ) | |
382 | then ( acf ) | |
383 | then ( ) | |
384 | loop drop ( ) | |
385 | ; | |
386 | ||
387 | : (.cpu-state) ( mid -- ) | |
388 | dup >cpu-struct >cpu-status @ ( mid status ) | |
389 | ." CPU: " over .x | |
390 | ." Node: " swap >cpu-struct >cpu-node @ .x | |
391 | case | |
392 | 0 of ." Not Present (offline)" endof | |
393 | CPU-INIT of ." init completed" endof | |
394 | CPU-IDLING of ." idling (not started)" endof | |
395 | CPU-OBP-COLD of ." running OBP (not started)" endof | |
396 | CPU-PARKED of ." parked" endof | |
397 | CPU-ENTERFORTH of ." waiting to enterforth" endof | |
398 | CPU-WAIT-RESTART of ." waiting to restart" endof | |
399 | CPU-OBP-WARM of ." executing OBP (started)." endof | |
400 | CPU-PROM-CIF of ." executing in the CIF" endof | |
401 | CPU-ACCUMULATING of ." awaiting total release" endof | |
402 | CPU-RELEASED of ." released to reenter client" endof | |
403 | CPU-STARTED of ." cpu in client" endof | |
404 | ." Unknown! " dup .x | |
405 | endcase cr | |
406 | ; | |
407 | ||
408 | headers | |
409 | ||
410 | : .cpu-state ( -- ) ['] (.cpu-state) do-foreach-cpu ; | |
411 | ||
412 | also magic-device-types definitions | |
413 | : cpu ( ?? -- ?? ) | |
414 | " reg" get-property if | |
415 | [ifndef] RELEASE | |
416 | cmn-fatal[ " CPU node is missing reg property" ]cmn-end | |
417 | [then] | |
418 | exit | |
419 | then | |
420 | decode-int nip nip | |
421 | \ strip the upper 4 'type' bits to get cpu#. | |
422 | 4 << xlsplit drop 4 >> ( cpu# ) | |
423 | >cpu-struct >cpu-node ( adr' ) | |
424 | current-device swap ! ( ) | |
425 | ; | |
426 | previous definitions | |
427 | ||
428 | headerless |