Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / obp / obp / arch / sun4v / cpustruct.fth
CommitLineData
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 ============================================
42id: @(#)cpustruct.fth 1.5 07/07/12
43purpose:
44copyright: Copyright 2007 Sun Microsystems, Inc. All Rights Reserved
45copyright: Use is subject to license terms.
46
47hex
48headers
49
50fload ${BP}/cpu/sparc/mutex.fth
51
52mutex-create prom-lock
53
54label cif-owner -1 l, end-code
55label release-slaves? 0 , end-code
56
570 value mp-cpu-state
580 value cpu-table
59h# ff constant CPU-IN-MD
60
61\ compute the offsets
62struct
63 /x field >tsb-allocation
64 /x field >tsb-saved-size
65 /x field >tsb-buffer-addr
66 /x field >tsb-reserved
67constant /tsb-data
68
69transient
70
71window-registers h# 10 round-up is window-registers
72window-registers d# 24 /x * + constant /min-cpu-save
73/min-cpu-save #windows 1- d# 16 * /x * + constant /full-cpu-save
74
75h# 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
83d# 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 >
87abort" CPU STRUCT ISNT LARGE ENOUGH TO HOLD A STATE SAVE"
88
89resident
90headers
91
92struct
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
123constant /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
162headerless
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
1884 actions
189action: ( apf -- ??? ) aligned l@ (cpu-state + token@ execute ;
190action: ( xt apf -- ) aligned l@ (cpu-state + token! ;
191action: ( apf -- addr ) aligned l@ (cpu-state + ;
192action: ( 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
200headers
201
202: per-cpu-defer: ( offset -- ) \ name
203 create align l, use-actions
204;
205
206inline-struct? on
207h# 04 constant CPU-INIT \ Starting INIT
208h# 10 constant CPU-OBP-COLD \ exec OBP, never started
209h# 11 constant CPU-IDLING \ prom idle, never started
210h# 20 constant CPU-PARKED \ Parked by mondo (bp)
211h# 21 constant CPU-ENTERFORTH \ Waiting to enter FORTH
212h# 22 constant CPU-WAIT-RESTART \ Waiting to restart
213h# 30 constant CPU-OBP-WARM \ CPU is running OBP (started)
214h# 31 constant CPU-PROM-CIF \ CPU is in the CIF
215h# 32 constant CPU-ACCUMULATING \ Waiting for cpus to arrive
216h# 33 constant CPU-RELEASED \ restarted.
217h# 40 constant CPU-STARTED \ cpu in client.
218inline-struct? off
219
220headers transient \ transient
221
222also assembler definitions \ Assembler transient
223hex
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
263resident previous definitions
264
265headerless
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
281headerless
282\
283\ WATCHOUT!!
284\ we come in on the (temporary) global stack and return on the per-cpu
285\ ones.
286\
287code 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
325c;
326
327stand-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
3420 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
408headers
409
410: .cpu-state ( -- ) ['] (.cpu-state) do-foreach-cpu ;
411
412also 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;
426previous definitions
427
428headerless