Print this page
restore sparc comments
de-linting of .s files
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/sun4u/ml/mach_locore.s
+++ new/usr/src/uts/sun4u/ml/mach_locore.s
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
↓ open down ↓ |
15 lines elided |
↑ open up ↑ |
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 */
25 25
26 -#pragma ident "%Z%%M% %I% %E% SMI"
27 -
28 -#if defined(lint)
29 -#include <sys/types.h>
30 -#include <sys/t_lock.h>
31 -#include <sys/promif.h>
32 -#include <sys/prom_isa.h>
33 -#endif /* lint */
34 -
35 26 #include <sys/asm_linkage.h>
36 27 #include <sys/intreg.h>
37 28 #include <sys/ivintr.h>
38 29 #include <sys/mmu.h>
39 30 #include <sys/machpcb.h>
40 31 #include <sys/machtrap.h>
41 32 #include <sys/machlock.h>
42 33 #include <sys/fdreg.h>
43 34 #include <sys/vis.h>
44 35 #include <sys/traptrace.h>
45 36 #include <sys/panic.h>
46 37 #include <sys/machasi.h>
47 38 #include <sys/clock.h>
48 39 #include <vm/hat_sfmmu.h>
49 -#if defined(lint)
50 40
51 -#include <sys/thread.h>
52 -#include <sys/time.h>
53 -
54 -#else /* lint */
55 -
56 41 #include "assym.h"
57 42
58 43
59 44 !
60 45 ! REGOFF must add up to allow double word access to r_tstate.
61 46 ! PCB_WBUF must also be aligned.
62 47 !
63 48 #if (REGOFF & 7) != 0
64 49 #error "struct regs not aligned"
65 50 #endif
66 51
67 52 /*
68 53 * Absolute external symbols.
69 54 * On the sun4u we put the panic buffer in the third and fourth pages.
70 55 * We set things up so that the first 2 pages of KERNELBASE is illegal
71 56 * to act as a redzone during copyin/copyout type operations. One of
72 57 * the reasons the panic buffer is allocated in low memory to
73 58 * prevent being overwritten during booting operations (besides
74 59 * the fact that it is small enough to share pages with others).
75 60 */
76 61
77 62 .seg ".data"
78 63 .global panicbuf
79 64
80 65 PROM = 0xFFE00000 ! address of prom virtual area
81 66 panicbuf = SYSBASE32 + PAGESIZE ! address of panic buffer
82 67
83 68 .type panicbuf, #object
84 69 .size panicbuf, PANICBUFSIZE
85 70
86 71 /*
87 72 * Absolute external symbol - intr_vec_table.
88 73 *
89 74 * With new bus structures supporting a larger number of interrupt
90 75 * numbers, the interrupt vector table, intr_vec_table[] has been
91 76 * moved out of kernel nucleus and allocated after panicbuf.
92 77 */
93 78 .global intr_vec_table
94 79
95 80 intr_vec_table = SYSBASE32 + PAGESIZE + PANICBUFSIZE ! address of interrupt table
96 81
97 82 .type intr_vec_table, #object
98 83 .size intr_vec_table, MAXIVNUM * CPTRSIZE + MAX_RSVD_IV * IV_SIZE + MAX_RSVD_IVX * (IV_SIZE + CPTRSIZE * (NCPU - 1))
99 84
100 85 /*
101 86 * The thread 0 stack. This must be the first thing in the data
102 87 * segment (other than an sccs string) so that we don't stomp
103 88 * on anything important if the stack overflows. We get a
104 89 * red zone below this stack for free when the kernel text is
105 90 * write protected.
106 91 */
107 92
108 93 .global t0stack
109 94 .align 16
110 95 .type t0stack, #object
111 96 t0stack:
112 97 .skip T0STKSZ ! thread 0 stack
113 98 t0stacktop:
114 99 .size t0stack, T0STKSZ
115 100
116 101 /*
117 102 * cpu0 and its ptl1_panic stack. The cpu structure must be allocated
118 103 * on a single page for ptl1_panic's physical address accesses.
119 104 */
120 105 .global cpu0
121 106 .align MMU_PAGESIZE
122 107 cpu0:
123 108 .type cpu0, #object
124 109 .skip CPU_ALLOC_SIZE
125 110 .size cpu0, CPU_ALLOC_SIZE
126 111
127 112 .global t0
128 113 .align PTR24_ALIGN ! alignment for mutex.
129 114 .type t0, #object
130 115 t0:
131 116 .skip THREAD_SIZE ! thread 0
132 117 .size t0, THREAD_SIZE
133 118
134 119 #ifdef TRAPTRACE
135 120 .global trap_trace_ctl
136 121 .global trap_tr0
137 122 .global trap_trace_bufsize
138 123 .global trap_freeze
139 124 .global trap_freeze_pc
140 125
141 126 .align 4
142 127 trap_trace_bufsize:
143 128 .word TRAP_TSIZE ! default trap buffer size
144 129 trap_freeze:
145 130 .word 0
146 131
147 132 .align 64
148 133 trap_trace_ctl:
149 134 .skip NCPU * TRAPTR_SIZE ! NCPU control headers
150 135
151 136 .align 16
152 137 trap_tr0:
153 138 .skip TRAP_TSIZE ! one buffer for the boot cpu
154 139
155 140 /*
156 141 * When an assertion in TRACE_PTR was failed, %pc is saved in trap_freeze_pc to
157 142 * show in which TRACE_PTR the assertion failure happened.
158 143 */
159 144 .align 8
160 145 trap_freeze_pc:
161 146 .nword 0
162 147 #endif /* TRAPTRACE */
163 148
164 149 .align 4
165 150 .seg ".text"
166 151
↓ open down ↓ |
101 lines elided |
↑ open up ↑ |
167 152 #ifdef NOPROM
168 153 .global availmem
169 154 availmem:
170 155 .word 0
171 156 #endif /* NOPROM */
172 157
173 158 .align 8
174 159 _local_p1275cis:
175 160 .nword 0
176 161
177 -#endif /* lint */
178 -
179 -#if defined(lint)
180 -
181 -void
182 -_start(void)
183 -{}
184 -
185 -#else /* lint */
186 -
187 162 .seg ".data"
188 163
189 164 .global nwindows, nwin_minus_one, winmask
190 165 nwindows:
191 166 .word 8
192 167 nwin_minus_one:
193 168 .word 7
194 169 winmask:
195 170 .word 8
196 171
197 172 .global afsrbuf
198 173 afsrbuf:
199 174 .word 0,0,0,0
200 175
201 176 /*
202 177 * System initialization
203 178 *
204 179 * Our contract with the boot prom specifies that the MMU is on and the
205 180 * first 16 meg of memory is mapped with a level-1 pte. We are called
206 181 * with p1275cis ptr in %o0 and kdi_dvec in %o1; we start execution
207 182 * directly from physical memory, so we need to get up into our proper
208 183 * addresses quickly: all code before we do this must be position
209 184 * independent.
210 185 *
211 186 * NB: Above is not true for boot/stick kernel, the only thing mapped is
212 187 * the text+data+bss. The kernel is loaded directly into KERNELBASE.
213 188 *
214 189 * entry, the romvec pointer (romp) is the first argument;
215 190 * i.e., %o0.
216 191 * the bootops vector is in the third argument (%o1)
217 192 *
218 193 * Our tasks are:
219 194 * save parameters
220 195 * construct mappings for KERNELBASE (not needed for boot/stick kernel)
221 196 * hop up into high memory (not needed for boot/stick kernel)
222 197 * initialize stack pointer
223 198 * initialize trap base register
224 199 * initialize window invalid mask
225 200 * initialize psr (with traps enabled)
226 201 * figure out all the module type stuff
227 202 * tear down the 1-1 mappings
228 203 * dive into main()
229 204 */
230 205 ENTRY_NP(_start)
231 206 !
232 207 ! Stash away our arguments in memory.
233 208 !
234 209 sethi %hi(_local_p1275cis), %g1
235 210 stn %o4, [%g1 + %lo(_local_p1275cis)]
236 211
237 212 !
238 213 ! Initialize CPU state registers
239 214 !
240 215 wrpr %g0, PSTATE_KERN, %pstate
241 216 wr %g0, %g0, %fprs
242 217
243 218 !
244 219 ! call krtld to link the world together
245 220 !
246 221 call kobj_start
247 222 mov %o4, %o0
248 223
249 224 CLEARTICKNPT ! allow user rdtick
250 225 !
251 226 ! Get maxwin from %ver
252 227 !
253 228 rdpr %ver, %g1
254 229 and %g1, VER_MAXWIN, %g1
255 230
256 231 !
257 232 ! Stuff some memory cells related to numbers of windows.
258 233 !
259 234 sethi %hi(nwin_minus_one), %g2
260 235 st %g1, [%g2 + %lo(nwin_minus_one)]
261 236 inc %g1
262 237 sethi %hi(nwindows), %g2
263 238 st %g1, [%g2 + %lo(nwindows)]
264 239 dec %g1
265 240 mov -2, %g2
266 241 sll %g2, %g1, %g2
267 242 sethi %hi(winmask), %g4
268 243 st %g2, [%g4 + %lo(winmask)]
269 244
270 245 !
271 246 ! save a pointer to obp's tba for later use by kmdb
272 247 !
273 248 rdpr %tba, %g1
274 249 set boot_tba, %g2
275 250 stx %g1, [%g2]
276 251
277 252 !
278 253 ! copy obp's breakpoint trap entry to obp_bpt
279 254 !
280 255 rdpr %tba, %g1
281 256 set T_SOFTWARE_TRAP | ST_MON_BREAKPOINT, %g2
282 257 sll %g2, 5, %g2
283 258 or %g1, %g2, %g1
284 259 set obp_bpt, %g2
285 260 ldx [%g1], %g3
286 261 stx %g3, [%g2]
287 262 flush %g2
288 263 ldx [%g1 + 8], %g3
289 264 stx %g3, [%g2 + 8]
290 265 flush %g2 + 8
291 266 ldx [%g1 + 16], %g3
292 267 stx %g3, [%g2 + 16]
293 268 flush %g2 + 16
294 269 ldx [%g1 + 24], %g3
295 270 stx %g3, [%g2 + 24]
296 271 flush %g2 + 24
297 272
298 273 !
299 274 ! Initialize thread 0's stack.
300 275 !
301 276 set t0stacktop, %g1 ! setup kernel stack pointer
302 277 sub %g1, SA(KFPUSIZE+GSR_SIZE), %g2
303 278 and %g2, 0x3f, %g3
304 279 sub %g2, %g3, %o1
305 280 sub %o1, SA(MPCBSIZE) + STACK_BIAS, %sp
306 281
307 282 !
308 283 ! Initialize global thread register.
309 284 !
310 285 set t0, THREAD_REG
311 286
312 287 !
313 288 ! Fill in enough of the cpu structure so that
314 289 ! the wbuf management code works. Make sure the
315 290 ! boot cpu is inserted in cpu[] based on cpuid.
316 291 !
317 292 CPU_INDEX(%g2, %g1)
318 293 sll %g2, CPTRSHIFT, %g2 ! convert cpuid to cpu[] offset
319 294 set cpu0, %o0 ! &cpu0
320 295 set cpu, %g1 ! &cpu[]
321 296 stn %o0, [%g1 + %g2] ! cpu[cpuid] = &cpu0
322 297
323 298 stn %o0, [THREAD_REG + T_CPU] ! threadp()->t_cpu = cpu[cpuid]
324 299 stn THREAD_REG, [%o0 + CPU_THREAD] ! cpu[cpuid]->cpu_thread = threadp()
325 300
326 301
327 302 ! We do NOT need to bzero our BSS...boot has already done it for us.
328 303 ! Just need to reference edata so that we don't break /dev/ksyms
329 304 set edata, %g0
330 305
331 306 !
332 307 ! Call mlsetup with address of prototype user registers.
333 308 !
334 309 call mlsetup
335 310 add %sp, REGOFF + STACK_BIAS, %o0
336 311
337 312 #if (REGOFF != MPCB_REGS)
338 313 #error "hole in struct machpcb between frame and regs?"
339 314 #endif
340 315
341 316 !
342 317 ! Now call main. We will return as process 1 (init).
343 318 !
344 319 call main
345 320 nop
346 321
347 322 !
348 323 ! Main should never return.
↓ open down ↓ |
152 lines elided |
↑ open up ↑ |
349 324 !
350 325 set .mainretmsg, %o0
351 326 call panic
352 327 nop
353 328 SET_SIZE(_start)
354 329
355 330 .mainretmsg:
356 331 .asciz "main returned"
357 332 .align 4
358 333
359 -#endif /* lint */
360 334
361 -
362 335 /*
363 336 * Generic system trap handler.
364 337 *
365 338 * Some kernel trap handlers save themselves from buying a window by
366 339 * borrowing some of sys_trap's unused locals. %l0 thru %l3 may be used
367 340 * for this purpose, as user_rtt and priv_rtt do not depend on them.
368 341 * %l4 thru %l7 should NOT be used this way.
369 342 *
370 343 * Entry Conditions:
371 344 * %pstate am:0 priv:1 ie:0
372 345 * globals are either ag or ig (not mg!)
373 346 *
374 347 * Register Inputs:
375 348 * %g1 pc of trap handler
376 349 * %g2, %g3 args for handler
377 350 * %g4 desired %pil (-1 means current %pil)
378 351 * %g5, %g6 destroyed
379 352 * %g7 saved
380 353 *
381 354 * Register Usage:
382 355 * %l0, %l1 temps
383 356 * %l3 saved %g1
384 357 * %l6 curthread for user traps, %pil for priv traps
385 358 * %l7 regs
386 359 *
↓ open down ↓ |
15 lines elided |
↑ open up ↑ |
387 360 * Called function prototype variants:
388 361 *
389 362 * func(struct regs *rp);
390 363 * func(struct regs *rp, uintptr_t arg1 [%g2], uintptr_t arg2 [%g3])
391 364 * func(struct regs *rp, uintptr_t arg1 [%g2],
392 365 * uint32_t arg2 [%g3.l], uint32_t arg3 [%g3.h])
393 366 * func(struct regs *rp, uint32_t arg1 [%g2.l],
394 367 * uint32_t arg2 [%g3.l], uint32_t arg3 [%g3.h], uint32_t [%g2.h])
395 368 */
396 369
397 -#if defined(lint)
398 -
399 -void
400 -sys_trap(void)
401 -{}
402 -
403 -#else /* lint */
404 -
405 370 ENTRY_NP(sys_trap)
406 371 !
407 372 ! force tl=1, update %cwp, branch to correct handler
408 373 !
409 374 wrpr %g0, 1, %tl
410 375 rdpr %tstate, %g5
411 376 btst TSTATE_PRIV, %g5
412 377 and %g5, TSTATE_CWP, %g6
413 378 bnz,pn %xcc, priv_trap
414 379 wrpr %g0, %g6, %cwp
415 380
416 381 ALTENTRY(user_trap)
417 382 !
418 383 ! user trap
419 384 !
420 385 ! make all windows clean for kernel
421 386 ! buy a window using the current thread's stack
422 387 !
423 388 sethi %hi(nwin_minus_one), %g5
424 389 ld [%g5 + %lo(nwin_minus_one)], %g5
425 390 wrpr %g0, %g5, %cleanwin
426 391 CPU_ADDR(%g5, %g6)
427 392 ldn [%g5 + CPU_THREAD], %g5
428 393 ldn [%g5 + T_STACK], %g6
429 394 sub %g6, STACK_BIAS, %g6
430 395 save %g6, 0, %sp
431 396 !
432 397 ! set window registers so that current windows are "other" windows
433 398 !
434 399 rdpr %canrestore, %l0
435 400 rdpr %wstate, %l1
436 401 wrpr %g0, 0, %canrestore
437 402 sllx %l1, WSTATE_SHIFT, %l1
438 403 wrpr %l1, WSTATE_K64, %wstate
439 404 wrpr %g0, %l0, %otherwin
440 405 !
441 406 ! set pcontext to run kernel
442 407 !
443 408 sethi %hi(kcontextreg), %l0
444 409 ldx [%l0 + %lo(kcontextreg)], %l0
445 410 mov MMU_PCONTEXT, %l1 ! if kcontextreg==PCONTEXT, do nothing
446 411 ldxa [%l1]ASI_MMU_CTX, %l2
447 412 xor %l0, %l2, %l2
448 413 srlx %l2, CTXREG_NEXT_SHIFT, %l2
449 414 brz %l2, 2f ! if N_pgsz0/1 changed, need demap
450 415 sethi %hi(FLUSH_ADDR), %l3
451 416 mov DEMAP_ALL_TYPE, %l2
452 417 stxa %g0, [%l2]ASI_DTLB_DEMAP
453 418 stxa %g0, [%l2]ASI_ITLB_DEMAP
454 419 2:
455 420 stxa %l0, [%l1]ASI_MMU_CTX
456 421 flush %l3 ! flush required by immu
457 422 1:
458 423
459 424 set utl0, %g6 ! bounce to utl0
460 425 have_win:
461 426 SYSTRAP_TRACE(%o1, %o2, %o3)
462 427
463 428
464 429 !
465 430 ! at this point we have a new window we can play in,
466 431 ! and %g6 is the label we want done to bounce to
467 432 !
468 433 ! save needed current globals
469 434 !
470 435 mov %g1, %l3 ! pc
471 436 mov %g2, %o1 ! arg #1
472 437 mov %g3, %o2 ! arg #2
473 438 srlx %g3, 32, %o3 ! pseudo arg #3
474 439 srlx %g2, 32, %o4 ! pseudo arg #4
475 440 mov %g5, %l6 ! curthread if user trap, %pil if priv trap
476 441 !
477 442 ! save trap state on stack
478 443 !
479 444 add %sp, REGOFF + STACK_BIAS, %l7
480 445 rdpr %tpc, %l0
481 446 rdpr %tnpc, %l1
482 447 rdpr %tstate, %l2
483 448 stn %l0, [%l7 + PC_OFF]
484 449 stn %l1, [%l7 + nPC_OFF]
485 450 stx %l2, [%l7 + TSTATE_OFF]
486 451 !
487 452 ! setup pil
488 453 !
489 454 brlz,pt %g4, 1f
490 455 nop
491 456 #ifdef DEBUG
492 457 !
493 458 ! ASSERT(%g4 >= %pil).
494 459 !
495 460 rdpr %pil, %l0
496 461 cmp %g4, %l0
497 462 bge,pt %xcc, 0f
498 463 nop ! yes, nop; to avoid anull
499 464 set bad_g4_called, %l3
500 465 mov 1, %o1
501 466 st %o1, [%l3]
502 467 set bad_g4, %l3 ! pc
503 468 set sys_trap_wrong_pil, %o1 ! arg #1
504 469 mov %g4, %o2 ! arg #2
505 470 ba 1f ! stay at the current %pil
506 471 mov %l0, %o3 ! arg #3
507 472 0:
508 473 #endif /* DEBUG */
509 474 wrpr %g0, %g4, %pil
510 475 1:
511 476 !
512 477 ! set trap regs to execute in kernel at %g6
513 478 ! done resumes execution there
514 479 !
515 480 wrpr %g0, %g6, %tnpc
516 481 rdpr %cwp, %l0
517 482 set TSTATE_KERN, %l1
518 483 wrpr %l1, %l0, %tstate
519 484 done
520 485 /* NOTREACHED */
521 486 SET_SIZE(user_trap)
522 487 SET_SIZE(sys_trap)
523 488
524 489
525 490 ENTRY_NP(prom_trap)
526 491 !
527 492 ! prom trap switches the stack to 32-bit
528 493 ! if we took a trap from a 64-bit window
529 494 ! Then buys a window on the current stack.
530 495 !
531 496 save %sp, -SA64(REGOFF + REGSIZE), %sp
532 497 /* 32 bit frame, 64 bit sized */
533 498 set ptl0, %g6
534 499 ba,a,pt %xcc, have_win
535 500 SET_SIZE(prom_trap)
536 501
537 502 ENTRY_NP(priv_trap)
538 503 !
539 504 ! kernel trap
540 505 ! buy a window on the current stack
541 506 !
542 507 ! is the trap PC in the range allocated to Open Firmware?
543 508 rdpr %tpc, %g5
544 509 set OFW_END_ADDR, %g6
545 510 cmp %g5, %g6
546 511 bgu,a,pn %xcc, 1f
547 512 rdpr %pil, %g5
548 513 set OFW_START_ADDR, %g6
549 514 cmp %g5, %g6
550 515 bgeu,pn %xcc, prom_trap
551 516 rdpr %pil, %g5
552 517 1:
553 518 !
554 519 ! check if the primary context is of kernel.
555 520 !
556 521 mov MMU_PCONTEXT, %g6
557 522 ldxa [%g6]ASI_MMU_CTX, %g5
558 523 sllx %g5, CTXREG_CTX_SHIFT, %g5 ! keep just the ctx bits
559 524 brnz,pn %g5, 2f ! assumes KCONTEXT == 0
560 525 rdpr %pil, %g5
561 526 !
562 527 ! primary context is of kernel.
563 528 !
564 529 set ktl0, %g6
565 530 save %sp, -SA(REGOFF + REGSIZE), %sp
566 531 ba,a,pt %xcc, have_win
567 532 2:
568 533 !
569 534 ! primary context is of user. caller of sys_trap()
570 535 ! or priv_trap() did not set kernel context. raise
571 536 ! trap level to MAXTL-1 so that ptl1_panic() prints
572 537 ! out all levels of trap data.
573 538 !
574 539 rdpr %ver, %g5
575 540 srlx %g5, VER_MAXTL_SHIFT, %g5
576 541 and %g5, VER_MAXTL_MASK, %g5 ! %g5 = MAXTL
577 542 sub %g5, 1, %g5
578 543 wrpr %g0, %g5, %tl
579 544 mov PTL1_BAD_CTX, %g1
580 545 ba,a,pt %xcc, ptl1_panic
581 546 SET_SIZE(priv_trap)
582 547
583 548 ENTRY_NP(utl0)
584 549 SAVE_GLOBALS(%l7)
585 550 SAVE_OUTS(%l7)
586 551 mov %l6, THREAD_REG
587 552 wrpr %g0, PSTATE_KERN, %pstate ! enable ints
588 553 jmpl %l3, %o7 ! call trap handler
589 554 mov %l7, %o0
590 555 !
591 556 ALTENTRY(user_rtt)
592 557 !
593 558 ! Register inputs
594 559 ! %l7 - regs
595 560 !
596 561 ! disable interrupts and check for ASTs and wbuf restores
597 562 ! keep cpu_base_spl in %l4 and THREAD_REG in %l6 (needed
598 563 ! in wbuf.s when globals have already been restored).
599 564 !
600 565 wrpr %g0, PIL_MAX, %pil
601 566 ldn [THREAD_REG + T_CPU], %l0
602 567 ld [%l0 + CPU_BASE_SPL], %l4
603 568
604 569 ldub [THREAD_REG + T_ASTFLAG], %l2
605 570 brz,pt %l2, 1f
606 571 ld [%sp + STACK_BIAS + MPCB_WBCNT], %l3
607 572 !
608 573 ! call trap to do ast processing
609 574 !
610 575 wrpr %g0, %l4, %pil ! pil = cpu_base_spl
611 576 mov %l7, %o0
612 577 call trap
613 578 mov T_AST, %o2
614 579 ba,a,pt %xcc, user_rtt
615 580 1:
616 581 brz,pt %l3, 2f
617 582 mov THREAD_REG, %l6
618 583 !
619 584 ! call restore_wbuf to push wbuf windows to stack
620 585 !
621 586 wrpr %g0, %l4, %pil ! pil = cpu_base_spl
622 587 mov %l7, %o0
623 588 call trap
624 589 mov T_FLUSH_PCB, %o2
625 590 ba,a,pt %xcc, user_rtt
626 591 2:
627 592 #ifdef TRAPTRACE
628 593 TRACE_RTT(TT_SYS_RTT_USER, %l0, %l1, %l2, %l3)
629 594 #endif /* TRAPTRACE */
630 595 ld [%sp + STACK_BIAS + MPCB_WSTATE], %l3 ! get wstate
631 596
632 597 !
633 598 ! restore user globals and outs
634 599 !
635 600 rdpr %pstate, %l1
636 601 wrpr %l1, PSTATE_IE, %pstate
637 602 RESTORE_GLOBALS(%l7)
638 603 ! switch to alternate globals, saving THREAD_REG in %l6
639 604 wrpr %l1, PSTATE_IE | PSTATE_AG, %pstate
640 605 mov %sp, %g6 ! remember the mpcb pointer in %g6
641 606 RESTORE_OUTS(%l7)
642 607 !
643 608 ! set %pil from cpu_base_spl
644 609 !
645 610 wrpr %g0, %l4, %pil
646 611 !
647 612 ! raise tl (now using nucleus context)
648 613 !
649 614 wrpr %g0, 1, %tl
650 615
651 616 ! switch "other" windows back to "normal" windows.
652 617 rdpr %otherwin, %g1
653 618 wrpr %g0, 0, %otherwin
654 619 add %l3, WSTATE_CLEAN_OFFSET, %l3 ! convert to "clean" wstate
655 620 wrpr %g0, %l3, %wstate
656 621 wrpr %g0, %g1, %canrestore
657 622
658 623 ! set pcontext to scontext for user execution
659 624 mov MMU_SCONTEXT, %g3
660 625 ldxa [%g3]ASI_MMU_CTX, %g2
661 626
662 627 mov MMU_PCONTEXT, %g3
663 628 ldxa [%g3]ASI_MMU_CTX, %g4 ! need N_pgsz0/1 bits
664 629 srlx %g4, CTXREG_NEXT_SHIFT, %g4
665 630 sllx %g4, CTXREG_NEXT_SHIFT, %g4
666 631 or %g4, %g2, %g2 ! Or in Nuc pgsz bits
667 632
668 633 sethi %hi(FLUSH_ADDR), %g4
669 634 stxa %g2, [%g3]ASI_MMU_CTX
670 635 flush %g4 ! flush required by immu
671 636 !
672 637 ! Within the code segment [rtt_ctx_start - rtt_ctx_end],
673 638 ! PCONTEXT is set to run user code. If a trap happens in this
674 639 ! window, and the trap needs to be handled at TL=0, the handler
675 640 ! must make sure to set PCONTEXT to run kernel. A convenience
676 641 ! macro, RESET_USER_RTT_REGS(scr1, scr2, label) is available to
677 642 ! TL>1 handlers for this purpose.
678 643 !
679 644 ! %g1 = %canrestore
680 645 ! %l7 = regs
681 646 ! %g6 = mpcb
682 647 !
683 648 .global rtt_ctx_start
684 649 rtt_ctx_start:
685 650 !
686 651 ! setup trap regs
687 652 !
688 653 ldn [%l7 + PC_OFF], %g3
689 654 ldn [%l7 + nPC_OFF], %g2
690 655 ldx [%l7 + TSTATE_OFF], %l0
691 656 andn %l0, TSTATE_CWP, %g7
692 657 wrpr %g3, %tpc
693 658 wrpr %g2, %tnpc
694 659
695 660 !
696 661 ! Restore to window we originally trapped in.
697 662 ! First attempt to restore from the watchpoint saved register window
698 663 !
699 664 tst %g1
700 665 bne,a 1f
701 666 clrn [%g6 + STACK_BIAS + MPCB_RSP0]
702 667 tst %fp
703 668 be,a 1f
704 669 clrn [%g6 + STACK_BIAS + MPCB_RSP0]
705 670 ! test for user return window in pcb
706 671 ldn [%g6 + STACK_BIAS + MPCB_RSP0], %g1
707 672 cmp %fp, %g1
708 673 bne 1f
709 674 clrn [%g6 + STACK_BIAS + MPCB_RSP0]
710 675 restored
711 676 restore
712 677 ! restore from user return window
713 678 RESTORE_V9WINDOW(%g6 + STACK_BIAS + MPCB_RWIN0)
714 679 !
715 680 ! Attempt to restore from the scond watchpoint saved register window
716 681 tst %fp
717 682 be,a 2f
718 683 clrn [%g6 + STACK_BIAS + MPCB_RSP1]
719 684 ldn [%g6 + STACK_BIAS + MPCB_RSP1], %g1
720 685 cmp %fp, %g1
721 686 bne 2f
722 687 clrn [%g6 + STACK_BIAS + MPCB_RSP1]
723 688 restored
724 689 restore
725 690 RESTORE_V9WINDOW(%g6 + STACK_BIAS + MPCB_RWIN1)
726 691 save
727 692 b,a 2f
728 693 1:
729 694 restore ! should not trap
730 695 2:
731 696 !
732 697 ! set %cleanwin to %canrestore
733 698 ! set %tstate to the correct %cwp
734 699 ! retry resumes user execution
735 700 !
736 701 rdpr %canrestore, %g1
737 702 wrpr %g0, %g1, %cleanwin
738 703 rdpr %cwp, %g1
739 704 wrpr %g1, %g7, %tstate
740 705 retry
741 706 .global rtt_ctx_end
742 707 rtt_ctx_end:
743 708 /* NOTREACHED */
744 709 SET_SIZE(user_rtt)
745 710 SET_SIZE(utl0)
746 711
747 712 ENTRY_NP(ptl0)
748 713 SAVE_GLOBALS(%l7)
749 714 SAVE_OUTS(%l7)
750 715 CPU_ADDR(%g5, %g6)
751 716 ldn [%g5 + CPU_THREAD], THREAD_REG
752 717 wrpr %g0, PSTATE_KERN, %pstate ! enable ints
753 718 jmpl %l3, %o7 ! call trap handler
754 719 mov %l7, %o0
755 720 !
756 721 ALTENTRY(prom_rtt)
757 722 #ifdef TRAPTRACE
758 723 TRACE_RTT(TT_SYS_RTT_PROM, %l0, %l1, %l2, %l3)
759 724 #endif /* TRAPTRACE */
760 725 ba,pt %xcc, common_rtt
761 726 mov THREAD_REG, %l0
762 727 SET_SIZE(prom_rtt)
763 728 SET_SIZE(ptl0)
764 729
765 730 ENTRY_NP(ktl0)
766 731 SAVE_GLOBALS(%l7)
767 732 SAVE_OUTS(%l7) ! for the call bug workaround
768 733 wrpr %g0, PSTATE_KERN, %pstate ! enable ints
769 734 jmpl %l3, %o7 ! call trap handler
770 735 mov %l7, %o0
771 736 !
772 737 ALTENTRY(priv_rtt)
773 738 #ifdef TRAPTRACE
774 739 TRACE_RTT(TT_SYS_RTT_PRIV, %l0, %l1, %l2, %l3)
775 740 #endif /* TRAPTRACE */
776 741 !
777 742 ! Register inputs
778 743 ! %l7 - regs
779 744 ! %l6 - trap %pil
780 745 !
781 746 ! Check for a kernel preemption request
782 747 !
783 748 ldn [THREAD_REG + T_CPU], %l0
784 749 ldub [%l0 + CPU_KPRUNRUN], %l0
785 750 brz,pt %l0, 1f
786 751 nop
787 752
788 753 !
789 754 ! Attempt to preempt
790 755 !
791 756 ldstub [THREAD_REG + T_PREEMPT_LK], %l0 ! load preempt lock
792 757 brnz,pn %l0, 1f ! can't call kpreempt if this thread is
793 758 nop ! already in it...
794 759
795 760 call kpreempt
796 761 mov %l6, %o0 ! pass original interrupt level
797 762
798 763 stub %g0, [THREAD_REG + T_PREEMPT_LK] ! nuke the lock
799 764
800 765 rdpr %pil, %o0 ! compare old pil level
801 766 cmp %l6, %o0 ! with current pil level
802 767 movg %xcc, %o0, %l6 ! if current is lower, drop old pil
803 768 1:
804 769 !
805 770 ! If we interrupted the mutex_owner_running() critical region we
806 771 ! must reset the PC and nPC back to the beginning to prevent missed
807 772 ! wakeups. See the comments in mutex_owner_running() for details.
808 773 !
809 774 ldn [%l7 + PC_OFF], %l0
810 775 set mutex_owner_running_critical_start, %l1
811 776 sub %l0, %l1, %l0
812 777 cmp %l0, mutex_owner_running_critical_size
813 778 bgeu,pt %xcc, 2f
814 779 mov THREAD_REG, %l0
815 780 stn %l1, [%l7 + PC_OFF] ! restart mutex_owner_running()
816 781 add %l1, 4, %l1
817 782 ba,pt %xcc, common_rtt
818 783 stn %l1, [%l7 + nPC_OFF]
819 784
820 785 2:
821 786 !
822 787 ! If we interrupted the mutex_exit() critical region we must reset
823 788 ! the PC and nPC back to the beginning to prevent missed wakeups.
824 789 ! See the comments in mutex_exit() for details.
825 790 !
826 791 ldn [%l7 + PC_OFF], %l0
827 792 set mutex_exit_critical_start, %l1
828 793 sub %l0, %l1, %l0
829 794 cmp %l0, mutex_exit_critical_size
830 795 bgeu,pt %xcc, common_rtt
831 796 mov THREAD_REG, %l0
832 797 stn %l1, [%l7 + PC_OFF] ! restart mutex_exit()
833 798 add %l1, 4, %l1
834 799 stn %l1, [%l7 + nPC_OFF]
835 800
836 801 common_rtt:
837 802 !
838 803 ! restore globals and outs
839 804 !
840 805 rdpr %pstate, %l1
841 806 wrpr %l1, PSTATE_IE, %pstate
842 807 RESTORE_GLOBALS(%l7)
843 808 ! switch to alternate globals
844 809 wrpr %l1, PSTATE_IE | PSTATE_AG, %pstate
845 810 RESTORE_OUTS(%l7)
846 811 !
847 812 ! set %pil from max(old pil, cpu_base_spl)
848 813 !
849 814 ldn [%l0 + T_CPU], %l0
850 815 ld [%l0 + CPU_BASE_SPL], %l0
851 816 cmp %l6, %l0
852 817 movg %xcc, %l6, %l0
853 818 wrpr %g0, %l0, %pil
854 819 !
855 820 ! raise tl
856 821 ! setup trap regs
857 822 ! restore to window we originally trapped in
858 823 !
859 824 wrpr %g0, 1, %tl
860 825 ldn [%l7 + PC_OFF], %g1
861 826 ldn [%l7 + nPC_OFF], %g2
862 827 ldx [%l7 + TSTATE_OFF], %l0
863 828 andn %l0, TSTATE_CWP, %g7
864 829 wrpr %g1, %tpc
865 830 wrpr %g2, %tnpc
866 831 restore
867 832 !
↓ open down ↓ |
453 lines elided |
↑ open up ↑ |
868 833 ! set %tstate to the correct %cwp
869 834 ! retry resumes prom execution
870 835 !
871 836 rdpr %cwp, %g1
872 837 wrpr %g1, %g7, %tstate
873 838 retry
874 839 /* NOTREACHED */
875 840 SET_SIZE(priv_rtt)
876 841 SET_SIZE(ktl0)
877 842
878 -#endif /* lint */
879 -
880 -#ifndef lint
881 -
882 843 #ifdef DEBUG
883 844 .seg ".data"
884 845 .align 4
885 846
886 847 .global bad_g4_called
887 848 bad_g4_called:
888 849 .word 0
889 850
890 851 sys_trap_wrong_pil:
891 852 .asciz "sys_trap: %g4(%d) is lower than %pil(%d)"
892 853 .align 4
893 854 .seg ".text"
894 855
895 856 ENTRY_NP(bad_g4)
896 857 mov %o1, %o0
897 858 mov %o2, %o1
898 859 call panic
899 860 mov %o3, %o2
900 861 SET_SIZE(bad_g4)
901 862 #endif /* DEBUG */
902 -#endif /* lint */
903 863
904 864 /*
905 865 * sys_tl1_panic can be called by traps at tl1 which
906 866 * really want to panic, but need the rearrangement of
907 867 * the args as provided by this wrapper routine.
908 868 */
909 -#if defined(lint)
910 -
911 -void
912 -sys_tl1_panic(void)
913 -{}
914 -
915 -#else /* lint */
916 869 ENTRY_NP(sys_tl1_panic)
917 870 mov %o1, %o0
918 871 mov %o2, %o1
919 872 call panic
920 873 mov %o3, %o2
921 874 SET_SIZE(sys_tl1_panic)
922 -#endif /* lint */
923 875
924 876 /*
925 877 * Turn on or off bits in the auxiliary i/o register.
926 878 *
927 879 * set_auxioreg(bit, flag)
928 880 * int bit; bit mask in aux i/o reg
929 881 * int flag; 0 = off, otherwise on
930 882 *
931 883 * This is intrinsicly ugly but is used by the floppy driver. It is also
932 884 * used to turn on/off the led.
933 885 */
934 886
935 -#if defined(lint)
936 -
937 -/* ARGSUSED */
938 -void
939 -set_auxioreg(int bit, int flag)
940 -{}
941 -
942 -#else /* lint */
943 -
944 887 .seg ".data"
945 888 .align 4
946 889 auxio_panic:
947 890 .asciz "set_auxioreg: interrupts already disabled on entry"
948 891 .align 4
949 892 .seg ".text"
950 893
951 894 ENTRY_NP(set_auxioreg)
952 895 /*
953 896 * o0 = bit mask
954 897 * o1 = flag: 0 = off, otherwise on
955 898 *
956 899 * disable interrupts while updating auxioreg
957 900 */
958 901 rdpr %pstate, %o2
959 902 #ifdef DEBUG
960 903 andcc %o2, PSTATE_IE, %g0 /* if interrupts already */
961 904 bnz,a,pt %icc, 1f /* disabled, panic */
962 905 nop
963 906 sethi %hi(auxio_panic), %o0
964 907 call panic
965 908 or %o0, %lo(auxio_panic), %o0
966 909 1:
967 910 #endif /* DEBUG */
968 911 wrpr %o2, PSTATE_IE, %pstate /* disable interrupts */
969 912 sethi %hi(v_auxio_addr), %o3
970 913 ldn [%o3 + %lo(v_auxio_addr)], %o4
971 914 ldub [%o4], %g1 /* read aux i/o register */
972 915 tst %o1
↓ open down ↓ |
19 lines elided |
↑ open up ↑ |
973 916 bnz,a 2f
974 917 bset %o0, %g1 /* on */
975 918 bclr %o0, %g1 /* off */
976 919 2:
977 920 or %g1, AUX_MBO, %g1 /* Must Be Ones */
978 921 stb %g1, [%o4] /* write aux i/o register */
979 922 retl
980 923 wrpr %g0, %o2, %pstate /* enable interrupt */
981 924 SET_SIZE(set_auxioreg)
982 925
983 -#endif /* lint */
984 -
985 926 /*
986 927 * Flush all windows to memory, except for the one we entered in.
987 928 * We do this by doing NWINDOW-2 saves then the same number of restores.
988 929 * This leaves the WIM immediately before window entered in.
989 930 * This is used for context switching.
990 931 */
991 932
992 -#if defined(lint)
993 -
994 -void
995 -flush_windows(void)
996 -{}
997 -
998 -#else /* lint */
999 -
1000 933 ENTRY_NP(flush_windows)
1001 934 retl
1002 935 flushw
1003 936 SET_SIZE(flush_windows)
1004 937
1005 -#endif /* lint */
1006 -
1007 -#if defined(lint)
1008 -
1009 -void
1010 -debug_flush_windows(void)
1011 -{}
1012 -
1013 -#else /* lint */
1014 -
1015 938 ENTRY_NP(debug_flush_windows)
1016 939 set nwindows, %g1
1017 940 ld [%g1], %g1
1018 941 mov %g1, %g2
1019 942
1020 943 1:
1021 944 save %sp, -WINDOWSIZE, %sp
1022 945 brnz %g2, 1b
1023 946 dec %g2
1024 947
1025 948 mov %g1, %g2
↓ open down ↓ |
1 lines elided |
↑ open up ↑ |
1026 949 2:
1027 950 restore
1028 951 brnz %g2, 2b
1029 952 dec %g2
1030 953
1031 954 retl
1032 955 nop
1033 956
1034 957 SET_SIZE(debug_flush_windows)
1035 958
1036 -#endif /* lint */
1037 -
1038 959 /*
1039 960 * flush user windows to memory.
1040 961 */
1041 962
1042 -#if defined(lint)
1043 -
1044 -void
1045 -flush_user_windows(void)
1046 -{}
1047 -
1048 -#else /* lint */
1049 -
1050 963 ENTRY_NP(flush_user_windows)
1051 964 rdpr %otherwin, %g1
1052 965 brz %g1, 3f
1053 966 clr %g2
1054 967 1:
1055 968 save %sp, -WINDOWSIZE, %sp
1056 969 rdpr %otherwin, %g1
1057 970 brnz %g1, 1b
1058 971 add %g2, 1, %g2
1059 972 2:
1060 973 sub %g2, 1, %g2 ! restore back to orig window
1061 974 brnz %g2, 2b
1062 975 restore
1063 976 3:
1064 977 retl
1065 978 nop
1066 979 SET_SIZE(flush_user_windows)
1067 980
1068 -#endif /* lint */
1069 -
1070 981 /*
1071 982 * Throw out any user windows in the register file.
1072 983 * Used by setregs (exec) to clean out old user.
1073 984 * Used by sigcleanup to remove extraneous windows when returning from a
1074 985 * signal.
1075 986 */
1076 987
1077 -#if defined(lint)
1078 -
1079 -void
1080 -trash_user_windows(void)
1081 -{}
1082 -
1083 -#else /* lint */
1084 -
1085 988 ENTRY_NP(trash_user_windows)
1086 989 rdpr %otherwin, %g1
1087 990 brz %g1, 3f ! no user windows?
1088 991 ldn [THREAD_REG + T_STACK], %g5
1089 992
1090 993 !
1091 994 ! There are old user windows in the register file. We disable ints
1092 995 ! and increment cansave so that we don't overflow on these windows.
1093 996 ! Also, this sets up a nice underflow when first returning to the
1094 997 ! new user.
1095 998 !
1096 999 rdpr %pstate, %g2
1097 1000 wrpr %g2, PSTATE_IE, %pstate
1098 1001 rdpr %cansave, %g3
1099 1002 rdpr %otherwin, %g1 ! re-read in case of interrupt
↓ open down ↓ |
5 lines elided |
↑ open up ↑ |
1100 1003 add %g3, %g1, %g3
1101 1004 wrpr %g0, 0, %otherwin
1102 1005 wrpr %g0, %g3, %cansave
1103 1006 wrpr %g0, %g2, %pstate
1104 1007 3:
1105 1008 retl
1106 1009 clr [%g5 + MPCB_WBCNT] ! zero window buffer cnt
1107 1010 SET_SIZE(trash_user_windows)
1108 1011
1109 1012
1110 -#endif /* lint */
1111 -
1112 1013 /*
1113 1014 * Setup g7 via the CPU data structure.
1114 1015 */
1115 -#if defined(lint)
1116 1016
1117 -struct scb *
1118 -set_tbr(struct scb *s)
1119 -{ return (s); }
1120 -
1121 -#else /* lint */
1122 -
1123 1017 ENTRY_NP(set_tbr)
1124 1018 retl
1125 1019 ta 72 ! no tbr, stop simulation
1126 1020 SET_SIZE(set_tbr)
1127 1021
1128 -#endif /* lint */
1129 1022
1130 -
1131 -#if defined(lint)
1132 -/*
1133 - * These need to be defined somewhere to lint and there is no "hicore.s"...
1134 - */
1135 -char etext[1], end[1];
1136 -#endif /* lint*/
1137 -
1138 -#if defined (lint)
1139 -
1140 -/* ARGSUSED */
1141 -void
1142 -ptl1_panic(u_int reason)
1143 -{}
1144 -
1145 -#else /* lint */
1146 -
1147 1023 #define PTL1_SAVE_WINDOW(RP) \
1148 1024 stxa %l0, [RP + RW64_LOCAL + (0 * RW64_LOCAL_INCR)] %asi; \
1149 1025 stxa %l1, [RP + RW64_LOCAL + (1 * RW64_LOCAL_INCR)] %asi; \
1150 1026 stxa %l2, [RP + RW64_LOCAL + (2 * RW64_LOCAL_INCR)] %asi; \
1151 1027 stxa %l3, [RP + RW64_LOCAL + (3 * RW64_LOCAL_INCR)] %asi; \
1152 1028 stxa %l4, [RP + RW64_LOCAL + (4 * RW64_LOCAL_INCR)] %asi; \
1153 1029 stxa %l5, [RP + RW64_LOCAL + (5 * RW64_LOCAL_INCR)] %asi; \
1154 1030 stxa %l6, [RP + RW64_LOCAL + (6 * RW64_LOCAL_INCR)] %asi; \
1155 1031 stxa %l7, [RP + RW64_LOCAL + (7 * RW64_LOCAL_INCR)] %asi; \
1156 1032 stxa %i0, [RP + RW64_IN + (0 * RW64_IN_INCR)] %asi; \
1157 1033 stxa %i1, [RP + RW64_IN + (1 * RW64_IN_INCR)] %asi; \
1158 1034 stxa %i2, [RP + RW64_IN + (2 * RW64_IN_INCR)] %asi; \
1159 1035 stxa %i3, [RP + RW64_IN + (3 * RW64_IN_INCR)] %asi; \
1160 1036 stxa %i4, [RP + RW64_IN + (4 * RW64_IN_INCR)] %asi; \
1161 1037 stxa %i5, [RP + RW64_IN + (5 * RW64_IN_INCR)] %asi; \
1162 1038 stxa %i6, [RP + RW64_IN + (6 * RW64_IN_INCR)] %asi; \
1163 1039 stxa %i7, [RP + RW64_IN + (7 * RW64_IN_INCR)] %asi
1164 1040 #define PTL1_NEXT_WINDOW(scr) \
1165 1041 add scr, RWIN64SIZE, scr
1166 1042
1167 1043 #define PTL1_RESET_RWINDOWS(scr) \
1168 1044 sethi %hi(nwin_minus_one), scr; \
1169 1045 ld [scr + %lo(nwin_minus_one)], scr; \
1170 1046 wrpr scr, %cleanwin; \
1171 1047 dec scr; \
1172 1048 wrpr scr, %cansave; \
1173 1049 wrpr %g0, %canrestore; \
1174 1050 wrpr %g0, %otherwin
1175 1051
1176 1052 #define PTL1_DCACHE_LINE_SIZE 4 /* small enough for all CPUs */
1177 1053
1178 1054 /*
1179 1055 * ptl1_panic is called when the kernel detects that it is in an invalid state
1180 1056 * and the trap level is greater than 0. ptl1_panic is responsible to save the
1181 1057 * current CPU state, to restore the CPU state to normal, and to call panic.
1182 1058 * The CPU state must be saved reliably without causing traps. ptl1_panic saves
1183 1059 * it in the ptl1_state structure, which is a member of the machcpu structure.
1184 1060 * In order to access the ptl1_state structure without causing traps, physical
1185 1061 * addresses are used so that we can avoid MMU miss traps. The restriction of
1186 1062 * physical memory accesses is that the ptl1_state structure must be on a single
1187 1063 * physical page. This is because (1) a single physical address for each
1188 1064 * ptl1_state structure is needed and (2) it simplifies physical address
1189 1065 * calculation for each member of the structure.
1190 1066 * ptl1_panic is a likely spot for stack overflows to wind up; thus, the current
1191 1067 * stack may not be usable. In order to call panic reliably in such a state,
1192 1068 * each CPU needs a dedicated ptl1 panic stack.
1193 1069 * CPU_ALLOC_SIZE, which is defined to be MMU_PAGESIZE, is used to allocate the
1194 1070 * cpu structure and a ptl1 panic stack. They are put together on the same page
1195 1071 * for memory space efficiency. The low address part is used for the cpu
1196 1072 * structure, and the high address part is for a ptl1 panic stack.
1197 1073 * The cpu_pa array holds the physical addresses of the allocated cpu structures,
1198 1074 * as the cpu array holds their virtual addresses.
1199 1075 *
1200 1076 * %g1 reason to be called
1201 1077 * %g2 broken
1202 1078 * %g3 broken
1203 1079 */
1204 1080 ENTRY_NP(ptl1_panic)
1205 1081 !
1206 1082 ! flush D$ first, so that stale data will not be accessed later.
1207 1083 ! Data written via ASI_MEM bypasses D$. If D$ contains data at the same
1208 1084 ! address, where data was written via ASI_MEM, a load from that address
1209 1085 ! using a virtual address and the default ASI still takes the old data.
1210 1086 ! Flushing D$ erases old data in D$, so that it will not be loaded.
1211 1087 ! Since we can afford only 2 registers (%g2 and %g3) for this job, we
1212 1088 ! flush entire D$.
1213 1089 ! For FJ OPL processors (IMPL values < SPITFIRE_IMPL), DC flushing
1214 1090 ! is not needed.
1215 1091 !
1216 1092 GET_CPU_IMPL(%g2)
1217 1093 cmp %g2, SPITFIRE_IMPL
1218 1094 blt,pn %icc, 1f ! Skip flushing for OPL processors
1219 1095 nop
1220 1096 sethi %hi(dcache_size), %g2
1221 1097 ld [%g2 + %lo(dcache_size)], %g2
1222 1098 sethi %hi(dcache_linesize), %g3
1223 1099 ld [%g3 + %lo(dcache_linesize)], %g3
1224 1100 sub %g2, %g3, %g2
1225 1101 0: stxa %g0, [%g2] ASI_DC_TAG
1226 1102 membar #Sync
1227 1103 brnz,pt %g2, 0b
1228 1104 sub %g2, %g3, %g2
1229 1105 1:
1230 1106 !
1231 1107 ! increment the entry counter.
1232 1108 ! save CPU state if this is the first entry.
1233 1109 !
1234 1110 CPU_PADDR(%g2, %g3);
1235 1111 add %g2, CPU_PTL1, %g2 ! pstate = &CPU->mcpu.ptl1_state
1236 1112 wr %g0, ASI_MEM, %asi ! physical address access
1237 1113 !
1238 1114 ! pstate->ptl1_entry_count++
1239 1115 !
1240 1116 lduwa [%g2 + PTL1_ENTRY_COUNT] %asi, %g3
1241 1117 add %g3, 1, %g3
1242 1118 stuwa %g3, [%g2 + PTL1_ENTRY_COUNT] %asi
1243 1119 !
1244 1120 ! CPU state saving is skipped from the 2nd entry to ptl1_panic since we
1245 1121 ! do not want to clobber the state from the original failure. panic()
1246 1122 ! is responsible for handling multiple or recursive panics.
1247 1123 !
1248 1124 cmp %g3, 2 ! if (ptl1_entry_count >= 2)
1249 1125 bge,pn %icc, state_saved ! goto state_saved
1250 1126 add %g2, PTL1_REGS, %g3 ! %g3 = &pstate->ptl1_regs[0]
1251 1127 !
1252 1128 ! save CPU state
1253 1129 !
1254 1130 save_cpu_state:
1255 1131 ! save current global registers
1256 1132 ! so that all them become available for use
1257 1133 !
1258 1134 stxa %g1, [%g3 + PTL1_G1] %asi
1259 1135 stxa %g2, [%g3 + PTL1_G2] %asi
1260 1136 stxa %g3, [%g3 + PTL1_G3] %asi
1261 1137 stxa %g4, [%g3 + PTL1_G4] %asi
1262 1138 stxa %g5, [%g3 + PTL1_G5] %asi
1263 1139 stxa %g6, [%g3 + PTL1_G6] %asi
1264 1140 stxa %g7, [%g3 + PTL1_G7] %asi
1265 1141 !
1266 1142 ! %tl, %tt, %tstate, %tpc, %tnpc for each TL
1267 1143 !
1268 1144 rdpr %tl, %g1
1269 1145 brz %g1, 1f ! if(trap_level == 0) -------+
1270 1146 add %g3, PTL1_TRAP_REGS, %g4 ! %g4 = &ptl1_trap_regs[0]; !
1271 1147 0: ! -----------<----------+ !
1272 1148 stwa %g1, [%g4 + PTL1_TL] %asi ! !
1273 1149 rdpr %tt, %g5 ! !
1274 1150 stwa %g5, [%g4 + PTL1_TT] %asi ! !
1275 1151 rdpr %tstate, %g5 ! !
1276 1152 stxa %g5, [%g4 + PTL1_TSTATE] %asi ! !
1277 1153 rdpr %tpc, %g5 ! !
1278 1154 stxa %g5, [%g4 + PTL1_TPC] %asi ! !
1279 1155 rdpr %tnpc, %g5 ! !
1280 1156 stxa %g5, [%g4 + PTL1_TNPC] %asi ! !
1281 1157 add %g4, PTL1_TRAP_REGS_INCR, %g4 ! !
1282 1158 deccc %g1 ! !
1283 1159 bnz,a,pt %icc, 0b ! if(trap_level != 0) --+ !
1284 1160 wrpr %g1, %tl !
1285 1161 1: ! ----------<----------------+
1286 1162 !
1287 1163 ! %pstate, %pil, SOFTINT, (S)TICK
1288 1164 ! Pending interrupts is also cleared in order to avoid a recursive call
1289 1165 ! to ptl1_panic in case the interrupt handler causes a panic.
1290 1166 !
1291 1167 rdpr %pil, %g1
1292 1168 stba %g1, [%g3 + PTL1_PIL] %asi
1293 1169 rdpr %pstate, %g1
1294 1170 stha %g1, [%g3 + PTL1_PSTATE] %asi
1295 1171 rd SOFTINT, %g1
1296 1172 sta %g1, [%g3 + PTL1_SOFTINT] %asi
1297 1173 wr %g1, CLEAR_SOFTINT
1298 1174 sethi %hi(traptrace_use_stick), %g1
1299 1175 ld [%g1 + %lo(traptrace_use_stick)], %g1
1300 1176 brz,a,pn %g1, 2f
1301 1177 rdpr %tick, %g1
1302 1178 rd STICK, %g1
1303 1179 2: stxa %g1, [%g3 + PTL1_TICK] %asi
1304 1180
1305 1181 !
1306 1182 ! MMU registers because ptl1_panic may be called from
1307 1183 ! the MMU trap handlers.
1308 1184 !
1309 1185 mov MMU_SFAR, %g1
1310 1186 ldxa [%g1]ASI_DMMU, %g4
1311 1187 stxa %g4, [%g3 + PTL1_DMMU_SFAR]%asi
1312 1188 mov MMU_SFSR, %g1
1313 1189 ldxa [%g1]ASI_DMMU, %g4
1314 1190 stxa %g4, [%g3 + PTL1_DMMU_SFSR]%asi
1315 1191 ldxa [%g1]ASI_IMMU, %g4
1316 1192 stxa %g4, [%g3 + PTL1_IMMU_SFSR]%asi
1317 1193 mov MMU_TAG_ACCESS, %g1
1318 1194 ldxa [%g1]ASI_DMMU, %g4
1319 1195 stxa %g4, [%g3 + PTL1_DMMU_TAG_ACCESS]%asi
1320 1196 ldxa [%g1]ASI_IMMU, %g4
1321 1197 stxa %g4, [%g3 + PTL1_IMMU_TAG_ACCESS]%asi
1322 1198
1323 1199 !
1324 1200 ! Save register window state and register windows.
1325 1201 !
1326 1202 rdpr %cwp, %g1
1327 1203 stba %g1, [%g3 + PTL1_CWP] %asi
1328 1204 rdpr %wstate, %g1
1329 1205 stba %g1, [%g3 + PTL1_WSTATE] %asi
1330 1206 rdpr %otherwin, %g1
1331 1207 stba %g1, [%g3 + PTL1_OTHERWIN] %asi
1332 1208 rdpr %cleanwin, %g1
1333 1209 stba %g1, [%g3 + PTL1_CLEANWIN] %asi
1334 1210 rdpr %cansave, %g1
1335 1211 stba %g1, [%g3 + PTL1_CANSAVE] %asi
1336 1212 rdpr %canrestore, %g1
1337 1213 stba %g1, [%g3 + PTL1_CANRESTORE] %asi
1338 1214
1339 1215 PTL1_RESET_RWINDOWS(%g1)
1340 1216 clr %g1
1341 1217 wrpr %g1, %cwp
1342 1218 add %g3, PTL1_RWINDOW, %g4 ! %g4 = &ptl1_rwindow[0];
1343 1219
1344 1220 3: PTL1_SAVE_WINDOW(%g4) ! <-------------+
1345 1221 inc %g1 !
1346 1222 cmp %g1, MAXWIN !
1347 1223 bgeu,pn %icc, 5f !
1348 1224 wrpr %g1, %cwp !
1349 1225 rdpr %cwp, %g2 !
1350 1226 cmp %g1, %g2 ! saturation check
1351 1227 be,pt %icc, 3b !
1352 1228 PTL1_NEXT_WINDOW(%g4) ! ------+
1353 1229 5:
1354 1230 !
1355 1231 ! most crucial CPU state was saved.
1356 1232 ! Proceed to go back to TL = 0.
1357 1233 !
1358 1234 state_saved:
1359 1235 wrpr %g0, 1, %tl
1360 1236 wrpr %g0, PIL_MAX, %pil
1361 1237 !
1362 1238 PTL1_RESET_RWINDOWS(%g1)
1363 1239 wrpr %g0, %cwp
1364 1240 wrpr %g0, %cleanwin
1365 1241 wrpr %g0, WSTATE_KERN, %wstate
1366 1242 !
1367 1243 ! Set pcontext to run kernel.
1368 1244 !
1369 1245 ! For OPL, load kcontexreg instead of clearing primary
1370 1246 ! context register. This is to avoid changing nucleus page
1371 1247 ! size bits after boot initialization.
1372 1248 !
1373 1249 #ifdef _OPL
1374 1250 sethi %hi(kcontextreg), %g4
1375 1251 ldx [%g4 + %lo(kcontextreg)], %g4
1376 1252 #endif /* _OPL */
1377 1253
1378 1254 set DEMAP_ALL_TYPE, %g1
1379 1255 sethi %hi(FLUSH_ADDR), %g3
1380 1256 set MMU_PCONTEXT, %g2
1381 1257
1382 1258 stxa %g0, [%g1]ASI_DTLB_DEMAP
1383 1259 stxa %g0, [%g1]ASI_ITLB_DEMAP
1384 1260
1385 1261 #ifdef _OPL
1386 1262 stxa %g4, [%g2]ASI_MMU_CTX
1387 1263 #else /* _OPL */
1388 1264 stxa %g0, [%g2]ASI_MMU_CTX
1389 1265 #endif /* _OPL */
1390 1266
1391 1267 flush %g3
1392 1268
1393 1269 rdpr %cwp, %g1
1394 1270 set TSTATE_KERN, %g3
1395 1271 wrpr %g3, %g1, %tstate
1396 1272 set ptl1_panic_tl0, %g3
1397 1273 wrpr %g0, %g3, %tnpc
1398 1274 done ! go to -->-+ TL:1
1399 1275 !
1400 1276 ptl1_panic_tl0: ! ----<-----+ TL:0
1401 1277 CPU_ADDR(%l0, %l1) ! %l0 = cpu[cpuid]
1402 1278 add %l0, CPU_PTL1, %l1 ! %l1 = &CPU->mcpu.ptl1_state
1403 1279 !
1404 1280 ! prepare to call panic()
1405 1281 !
1406 1282 ldn [%l0 + CPU_THREAD], THREAD_REG ! restore %g7
1407 1283 ldn [%l1 + PTL1_STKTOP], %l2 ! %sp = ptl1_stktop
1408 1284 sub %l2, SA(MINFRAME) + STACK_BIAS, %sp
1409 1285 clr %fp ! no frame below this window
1410 1286 clr %i7
↓ open down ↓ |
254 lines elided |
↑ open up ↑ |
1411 1287 !
1412 1288 ! enable limited interrupts
1413 1289 !
1414 1290 wrpr %g0, CLOCK_LEVEL, %pil
1415 1291 wrpr %g0, PSTATE_KERN, %pstate
1416 1292 !
1417 1293 ba,pt %xcc, ptl1_panic_handler
1418 1294 mov %l1, %o0
1419 1295 /*NOTREACHED*/
1420 1296 SET_SIZE(ptl1_panic)
1421 -#endif /* lint */
1422 1297
1423 1298 #ifdef PTL1_PANIC_DEBUG
1424 -#if defined (lint)
1299 +
1425 1300 /*
1426 1301 * ptl1_recurse() calls itself a number of times to either set up a known
1427 - * stack or to cause a kernel stack overflow. It decrements the arguments
1302 + * stack or to cause a kernel stack overflow. It decrements the arguments
1428 1303 * on each recursion.
1429 1304 * It's called by #ifdef PTL1_PANIC_DEBUG code in startup.c to set the
1430 1305 * registers to a known state to facilitate debugging.
1431 1306 */
1432 -
1433 -/* ARGSUSED */
1434 -void
1435 -ptl1_recurse(int count_threshold, int trap_threshold)
1436 -{}
1437 -
1438 -#else /* lint */
1439 -
1440 1307 ENTRY_NP(ptl1_recurse)
1441 1308 save %sp, -SA(MINFRAME), %sp
1442 1309
1443 1310 set ptl1_recurse_call, %o7
1444 1311 cmp %o7, %i7 ! if ptl1_recurse is called
1445 1312 be,pt %icc, 0f ! by itself, then skip
1446 1313 nop ! register initialization
1447 1314
1448 1315 /*
1449 1316 * Initialize Out Registers to Known Values
1450 1317 */
1451 1318 set 0x01000, %l0 ! %i0 is the ...
1452 1319 ! recursion_depth_count
1453 1320 sub %i0, 1, %o0;
1454 1321 sub %i1, 1, %o1;
1455 1322 add %l0, %o0, %o2;
1456 1323 add %l0, %o2, %o3;
1457 1324 add %l0, %o3, %o4;
1458 1325 add %l0, %o4, %o5;
1459 1326 ba,a 1f
1460 1327 nop
1461 1328
1462 1329 0: /* Outs = Ins - 1 */
1463 1330 sub %i0, 1, %o0;
1464 1331 sub %i1, 1, %o1;
1465 1332 sub %i2, 1, %o2;
1466 1333 sub %i3, 1, %o3;
1467 1334 sub %i4, 1, %o4;
1468 1335 sub %i5, 1, %o5;
1469 1336
1470 1337 /* Locals = Ins + 1 */
1471 1338 1: add %i0, 1, %l0;
1472 1339 add %i1, 1, %l1;
1473 1340 add %i2, 1, %l2;
1474 1341 add %i3, 1, %l3;
1475 1342 add %i4, 1, %l4;
1476 1343 add %i5, 1, %l5;
1477 1344
1478 1345 set 0x0100000, %g5
1479 1346 add %g5, %g0, %g1
1480 1347 add %g5, %g1, %g2
1481 1348 add %g5, %g2, %g3
1482 1349 add %g5, %g3, %g4
1483 1350 add %g5, %g4, %g5
1484 1351
1485 1352 brz,pn %i1, ptl1_recurse_trap ! if trpp_count == 0) {
1486 1353 nop ! trap to ptl1_panic
1487 1354 !
1488 1355 brz,pn %i0, ptl1_recure_exit ! if(depth_count == 0) {
1489 1356 nop ! skip recursive call
1490 1357 ! }
1491 1358 ptl1_recurse_call:
1492 1359 call ptl1_recurse
1493 1360 nop
↓ open down ↓ |
44 lines elided |
↑ open up ↑ |
1494 1361
1495 1362 ptl1_recure_exit:
1496 1363 ret
1497 1364 restore
1498 1365
1499 1366 ptl1_recurse_trap:
1500 1367 ta PTL1_DEBUG_TRAP; ! Trap Always to ptl1_panic()
1501 1368 nop ! NOTREACHED
1502 1369 SET_SIZE(ptl1_recurse)
1503 1370
1504 -#endif /* lint */
1505 -
1506 -#if defined (lint)
1507 -
1508 -/* ARGSUSED */
1509 -void
1510 -ptl1_panic_xt(int arg1, int arg2)
1511 -{}
1512 -
1513 -#else /* lint */
1514 1371 /*
1515 1372 * Asm function to handle a cross trap to call ptl1_panic()
1516 1373 */
1517 1374 ENTRY_NP(ptl1_panic_xt)
1518 1375 ba ptl1_panic
1519 1376 mov PTL1_BAD_DEBUG, %g1
1520 1377 SET_SIZE(ptl1_panic_xt)
1521 1378
1522 -#endif /* lint */
1523 -
1524 1379 #endif /* PTL1_PANIC_DEBUG */
1525 1380
1526 1381 #ifdef TRAPTRACE
1527 -#if defined (lint)
1528 1382
1529 -void
1530 -trace_ptr_panic(void)
1531 -{
1532 -}
1533 -
1534 -#else /* lint */
1535 -
1536 1383 ENTRY_NP(trace_ptr_panic)
1537 1384 !
1538 1385 ! freeze the trap trace to disable the assertions. Otherwise,
1539 1386 ! ptl1_panic is likely to be repeatedly called from there.
1540 1387 ! %g2 and %g3 are used as scratch registers in ptl1_panic.
1541 1388 !
1542 1389 mov 1, %g3
1543 1390 sethi %hi(trap_freeze), %g2
1544 1391 st %g3, [%g2 + %lo(trap_freeze)]
1545 1392 !
1546 1393 ! %g1 contains the %pc address where an assertion was failed.
↓ open down ↓ |
1 lines elided |
↑ open up ↑ |
1547 1394 ! save it in trap_freeze_pc for a debugging hint if there is
1548 1395 ! no value saved in it.
1549 1396 !
1550 1397 set trap_freeze_pc, %g2
1551 1398 casn [%g2], %g0, %g1
1552 1399
1553 1400 ba ptl1_panic
1554 1401 mov PTL1_BAD_TRACE_PTR, %g1
1555 1402 SET_SIZE(trace_ptr_panic)
1556 1403
1557 -#endif /* lint */
1558 1404 #endif /* TRAPTRACE */
1559 -
1560 -#if defined (lint)
1561 1405 /*
1562 1406 * set_kcontextreg() sets PCONTEXT to kctx
1563 1407 * if PCONTEXT==kctx, do nothing
1564 1408 * if N_pgsz0|N_pgsz1 differ, do demap all first
1565 1409 */
1566 -
1567 -/* ARGSUSED */
1568 -void
1569 -set_kcontextreg()
1570 -{
1571 -}
1572 -
1573 -#else /* lint */
1574 -
1575 1410 ENTRY_NP(set_kcontextreg)
1576 1411 ! SET_KCONTEXTREG(reg0, reg1, reg2, reg3, reg4, label1, label2, label3)
1577 1412 SET_KCONTEXTREG(%o0, %o1, %o2, %o3, %o4, l1, l2, l3)
1578 1413 retl
1579 1414 nop
1580 1415 SET_SIZE(set_kcontextreg)
1581 -
1582 -#endif /* lint */
1583 -
1584 1416
1585 1417 /*
1586 1418 * The interface for a 32-bit client program that takes over the TBA
1587 1419 * calling the 64-bit romvec OBP.
1588 1420 */
1589 1421
1590 -#if defined(lint)
1591 -
1592 -/* ARGSUSED */
1593 -int
1594 -client_handler(void *cif_handler, void *arg_array)
1595 -{ return 0; }
1596 -
1597 -#else /* lint */
1598 -
1599 1422 ENTRY(client_handler)
1600 1423 save %sp, -SA64(MINFRAME64), %sp ! 32 bit frame, 64 bit sized
1601 1424 sethi %hi(tba_taken_over), %l2
1602 1425 ld [%l2+%lo(tba_taken_over)], %l3
1603 1426 brz %l3, 1f ! is the tba_taken_over = 1 ?
1604 1427 rdpr %wstate, %l5 ! save %wstate
1605 1428 andn %l5, WSTATE_MASK, %l6
1606 1429 wrpr %l6, WSTATE_KMIX, %wstate
1607 1430
1608 1431 !
1609 1432 ! switch to PCONTEXT=0
1610 1433 !
1611 1434 #ifndef _OPL
1612 1435 mov MMU_PCONTEXT, %o2
1613 1436 ldxa [%o2]ASI_DMMU, %o2
1614 1437 srlx %o2, CTXREG_NEXT_SHIFT, %o2
1615 1438 brz,pt %o2, 1f ! nucleus pgsz is 0, no problem
1616 1439 nop
1617 1440 rdpr %pstate, %l4 ! disable interrupts
1618 1441 andn %l4, PSTATE_IE, %o2
1619 1442 wrpr %g0, %o2, %pstate
1620 1443 mov DEMAP_ALL_TYPE, %o2 ! set PCONTEXT=0
1621 1444 stxa %g0, [%o2]ASI_DTLB_DEMAP
1622 1445 stxa %g0, [%o2]ASI_ITLB_DEMAP
1623 1446 mov MMU_PCONTEXT, %o2
1624 1447 stxa %g0, [%o2]ASI_DMMU
1625 1448 membar #Sync
1626 1449 sethi %hi(FLUSH_ADDR), %o2
1627 1450 flush %o2 ! flush required by immu
1628 1451 wrpr %g0, %l4, %pstate ! restore interrupt state
1629 1452 #endif /* _OPL */
1630 1453
1631 1454 1: mov %i1, %o0
1632 1455 rdpr %pstate, %l4 ! Get the present pstate value
1633 1456 andn %l4, PSTATE_AM, %l6
1634 1457 wrpr %l6, 0, %pstate ! Set PSTATE_AM = 0
1635 1458 jmpl %i0, %o7 ! Call cif handler
1636 1459 nop
1637 1460 wrpr %l4, 0, %pstate ! restore pstate
1638 1461 brz %l3, 1f ! is the tba_taken_over = 1
1639 1462 nop
1640 1463 wrpr %g0, %l5, %wstate ! restore wstate
1641 1464
1642 1465 !
1643 1466 ! switch to PCONTEXT=kcontexreg
1644 1467 !
1645 1468 #ifndef _OPL
1646 1469 sethi %hi(kcontextreg), %o3
1647 1470 ldx [%o3 + %lo(kcontextreg)], %o3
1648 1471 brz %o3, 1f
1649 1472 nop
1650 1473 rdpr %pstate, %l4 ! disable interrupts
1651 1474 andn %l4, PSTATE_IE, %o2
1652 1475 wrpr %g0, %o2, %pstate
1653 1476 mov DEMAP_ALL_TYPE, %o2
1654 1477 stxa %g0, [%o2]ASI_DTLB_DEMAP
1655 1478 stxa %g0, [%o2]ASI_ITLB_DEMAP
1656 1479 mov MMU_PCONTEXT, %o2
1657 1480 stxa %o3, [%o2]ASI_DMMU
↓ open down ↓ |
49 lines elided |
↑ open up ↑ |
1658 1481 membar #Sync
1659 1482 sethi %hi(FLUSH_ADDR), %o2
1660 1483 flush %o2 ! flush required by immu
1661 1484 wrpr %g0, %l4, %pstate ! restore interrupt state
1662 1485 #endif /* _OPL */
1663 1486
1664 1487 1: ret ! Return result ...
1665 1488 restore %o0, %g0, %o0 ! delay; result in %o0
1666 1489 SET_SIZE(client_handler)
1667 1490
1668 -#endif /* lint */
1669 -
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX