4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
27 #include <sys/machtrap.h>
28 #include <sys/machsystm.h>
29 #include <sys/cpu_module.h>
30 #include <sys/panic.h>
31 #include <sys/uadmin.h>
33 #include <vm/hat_sfmmu.h>
34 #include <sys/reboot.h>
37 #include <sys/traptrace.h>
40 void showregs(unsigned, struct regs
*, caddr_t
, uint_t
);
45 mmu_print_sfsr(uint_t sfsr
)
47 printf("MMU sfsr=%x:", sfsr
);
48 switch (X_FAULT_TYPE(sfsr
)) {
53 printf(" Privilege violation");
56 printf(" Speculative load on E-bit page");
59 printf(" Atomic to uncacheable page");
62 printf(" Illegal lda or sta");
65 printf(" Normal access to NFO page");
68 printf(" Data or instruction address out of range");
71 printf(" Jump to register out of range");
74 printf(" Unknown error");
78 printf(" on ASI 0x%x E %d CID %d PRIV %d W %d OW %d FV %d",
79 (sfsr
& SFSR_ASI
) >> SFSR_ASI_SHIFT
,
81 (sfsr
& SFSR_CTX
) >> SFSR_CT_SHIFT
,
82 (sfsr
& SFSR_PR
) != 0,
84 (sfsr
& SFSR_OW
) != 0,
85 (sfsr
& SFSR_FV
) != 0);
92 #endif /* TRAPWINDOW */
95 * Print out debugging info.
99 showregs(uint_t type
, struct regs
*rp
, caddr_t addr
, uint_t mmu_fsr
)
105 printf("%s: ", PTOU(curproc
)->u_comm
);
108 case T_SYS_RTT_ALIGN
:
110 printf("alignment error:\n");
112 case T_INSTR_EXCEPTION
:
113 printf("text access exception:\n");
115 case T_DATA_EXCEPTION
:
116 printf("data access exception:\n");
119 printf("privileged instruction fault:\n");
122 printf("illegal instruction fault:\n");
125 printf("integer divide zero trap:\n");
128 printf("zero divide trap:\n");
131 printf("integer overflow:\n");
134 printf("breakpoint trap:\n");
137 printf("tag overflow:\n");
140 if (type
>= T_SOFTWARE_TRAP
&& type
<= T_ESOFTWARE_TRAP
)
141 printf("software trap 0x%x\n", type
- T_SOFTWARE_TRAP
);
143 printf("trap type = 0x%x\n", type
);
146 if (type
== T_DATA_EXCEPTION
|| type
== T_INSTR_EXCEPTION
) {
147 mmu_print_sfsr(mmu_fsr
);
149 printf("addr=0x%p\n", (void *)addr
);
152 printf("pid=%d, pc=0x%lx, sp=0x%llx, tstate=0x%llx, context=0x%x\n",
153 (ttoproc(curthread
) && ttoproc(curthread
)->p_pidp
) ?
154 (ttoproc(curthread
)->p_pid
) : 0, rp
->r_pc
, rp
->r_sp
,
155 rp
->r_tstate
, sfmmu_getctx_sec());
156 if (USERMODE(rp
->r_tstate
)) {
157 printf("o0-o7: %llx, %llx, %llx, %llx, %llx, %llx, "
158 "%llx, %llx\n", rp
->r_o0
, rp
->r_o1
, rp
->r_o2
, rp
->r_o3
,
159 rp
->r_o4
, rp
->r_o5
, rp
->r_o6
, rp
->r_o7
);
161 printf("g1-g7: %llx, %llx, %llx, %llx, %llx, %llx, %llx\n",
162 rp
->r_g1
, rp
->r_g2
, rp
->r_g3
,
163 rp
->r_g4
, rp
->r_g5
, rp
->r_g6
, rp
->r_g7
);
166 printf("trap_window: wim=%x\n", trap_window
[24]);
167 printf("o0-o7: %x, %x, %x, %x, %x, %x, %x, %x\n",
168 trap_window
[0], trap_window
[1], trap_window
[2], trap_window
[3],
169 trap_window
[4], trap_window
[5], trap_window
[6], trap_window
[7]);
170 printf("l0-l7: %x, %x, %x, %x, %x, %x, %x, %x\n",
171 trap_window
[8], trap_window
[9], trap_window
[10], trap_window
[11],
172 trap_window
[12], trap_window
[13], trap_window
[14], trap_window
[15]);
173 printf("i0-i7: %x, %x, %x, %x, %x, %x, %x, %x\n",
174 trap_window
[16], trap_window
[17], trap_window
[18], trap_window
[19],
175 trap_window
[20], trap_window
[21], trap_window
[22], trap_window
[23]);
176 #endif /* TRAPWINDOW */
177 if (tudebug
> 1 && (boothowto
& RB_DEBUG
)) {
178 debug_enter((char *)NULL
);
184 ptl1_showtrap(ptl1_state_t
*pstate
)
186 ptl1_regs_t
*rp
= &pstate
->ptl1_regs
;
187 short i
, j
, maxtl
= rp
->ptl1_trap_regs
[0].ptl1_tl
;
189 printf("%%tl %%tpc %%tnpc %%tstate"
192 for (i
= maxtl
- 1; i
>= 0; i
--) {
193 ptl1_trapregs_t
*ptp
= &rp
->ptl1_trap_regs
[i
];
194 uint64_t tstate
= ptp
->ptl1_tstate
;
195 uint32_t ccr
, asi
, cwp
, pstate
;
197 cwp
= (tstate
>> TSTATE_CWP_SHIFT
) & TSTATE_CWP_MASK
;
198 pstate
= (tstate
>> TSTATE_PSTATE_SHIFT
) & TSTATE_PSTATE_MASK
;
199 asi
= (tstate
>> TSTATE_ASI_SHIFT
) & TSTATE_ASI_MASK
;
200 ccr
= (tstate
>> TSTATE_CCR_SHIFT
) & TSTATE_CCR_MASK
;
202 printf(" %d %016" PRIx64
" %016" PRIx64
" %010" PRIx64
203 " %03x\n", ptp
->ptl1_tl
, ptp
->ptl1_tpc
,
204 ptp
->ptl1_tnpc
, tstate
, ptp
->ptl1_tt
);
205 printf(" %%ccr: %02x %%asi: %02x %%cwp: %x "
206 "%%pstate: %b\n", ccr
, asi
, cwp
, pstate
, PSTATE_BITS
);
209 printf("%%g0-3: %016x %016" PRIx64
" %016" PRIx64
" %016"
210 PRIx64
"\n", 0, rp
->ptl1_g1
, rp
->ptl1_g2
, rp
->ptl1_g3
);
211 printf("%%g4-7: %016" PRIx64
" %016" PRIx64
" %016" PRIx64
" %016"
212 PRIx64
"\n", rp
->ptl1_g4
, rp
->ptl1_g5
, rp
->ptl1_g6
, rp
->ptl1_g7
);
215 j
= rp
->ptl1_canrestore
;
216 for (; j
>= 0; i
--, j
--) {
224 wp
= &rp
->ptl1_rwindow
[i
];
226 if ((sym
= kobj_getsymname(wp
->rw_in
[7], &off
)) != NULL
) {
227 printf("Register window %d, caller %s+%lx\n",
230 printf("Register window %d, caller %lx\n",
234 if (i
== rp
->ptl1_cwp
) {
238 nwp
= &rp
->ptl1_rwindow
[0];
240 nwp
= &rp
->ptl1_rwindow
[i
+1];
241 printf("%%o0-3: %016lx %016lx %016lx %016lx\n"
242 "%%o4-7: %016lx %016lx %016lx %016lx\n",
243 nwp
->rw_in
[0], nwp
->rw_in
[1], nwp
->rw_in
[2],
244 nwp
->rw_in
[3], nwp
->rw_in
[4], nwp
->rw_in
[5],
245 nwp
->rw_in
[6], nwp
->rw_in
[7]);
247 printf("%%l0-3: %016lx %016lx %016lx %016lx\n"
248 "%%l4-7: %016lx %016lx %016lx %016lx\n",
249 wp
->rw_local
[0], wp
->rw_local
[1], wp
->rw_local
[2],
250 wp
->rw_local
[3], wp
->rw_local
[4], wp
->rw_local
[5],
251 wp
->rw_local
[6], wp
->rw_local
[7]);
253 printf("%%i0-3: %016lx %016lx %016lx %016lx\n"
254 "%%i4-7: %016lx %016lx %016lx %016lx\n",
255 wp
->rw_in
[0], wp
->rw_in
[1], wp
->rw_in
[2], wp
->rw_in
[3],
256 wp
->rw_in
[4], wp
->rw_in
[5], wp
->rw_in
[6], wp
->rw_in
[7]);
261 panic_showtrap(struct panic_trap_info
*tip
)
263 ptl1_state_t
*pstate
= &CPU
->cpu_m
.ptl1_state
;
265 * If ptl1_panic() was called, print out the information
266 * saved in the ptl1_state struture.
268 if (pstate
->ptl1_entry_count
) {
269 ptl1_showtrap(pstate
);
273 showregs(tip
->trap_type
, tip
->trap_regs
, tip
->trap_addr
,
278 ptl1_savetrap(panic_data_t
*pdp
, ptl1_state_t
*pstate
)
280 ptl1_regs_t
*rp
= &pstate
->ptl1_regs
;
281 short i
, maxtl
= rp
->ptl1_trap_regs
[0].ptl1_tl
;
282 panic_nv_t
*pnv
= PANICNVGET(pdp
);
283 char name
[PANICNVNAMELEN
];
285 for (i
= maxtl
- 1; i
>= 0; i
--) {
286 ptl1_trapregs_t
*ptp
= &rp
->ptl1_trap_regs
[i
];
288 (void) snprintf(name
, sizeof (name
), "tl[%d]", i
);
289 PANICNVADD(pnv
, name
, ptp
->ptl1_tl
);
290 (void) snprintf(name
, sizeof (name
), "tt[%d]", i
);
291 PANICNVADD(pnv
, name
, ptp
->ptl1_tt
);
292 (void) snprintf(name
, sizeof (name
), "tpc[%d]", i
);
293 PANICNVADD(pnv
, name
, ptp
->ptl1_tpc
);
294 (void) snprintf(name
, sizeof (name
), "tnpc[%d]", i
);
295 PANICNVADD(pnv
, name
, ptp
->ptl1_tnpc
);
296 (void) snprintf(name
, sizeof (name
), "tstate[%d]", i
);
297 PANICNVADD(pnv
, name
, ptp
->ptl1_tstate
);
300 PANICNVSET(pdp
, pnv
);
304 panic_savetrap(panic_data_t
*pdp
, struct panic_trap_info
*tip
)
307 ptl1_state_t
*pstate
= &CPU
->cpu_m
.ptl1_state
;
309 * If ptl1_panic() was called, save the trap registers
310 * stored in the ptl1_state struture.
312 if (pstate
->ptl1_entry_count
) {
313 ptl1_savetrap(pdp
, pstate
);
317 panic_saveregs(pdp
, tip
->trap_regs
);
318 pnv
= PANICNVGET(pdp
);
320 PANICNVADD(pnv
, "sfsr", tip
->trap_mmu_fsr
);
321 PANICNVADD(pnv
, "sfar", tip
->trap_addr
);
322 PANICNVADD(pnv
, "tt", tip
->trap_type
);
324 PANICNVSET(pdp
, pnv
);