1#include "arch_traps.h"
2
3#include <KernelExport.h>
4#include <arch_cpu_defs.h>
5
6
7void
8WriteMode(int mode)
9{
10	switch (mode) {
11		case modeU: dprintf("u"); break;
12		case modeS: dprintf("s"); break;
13		case modeM: dprintf("m"); break;
14		default: dprintf("%d", mode);
15	}
16}
17
18
19void
20WriteModeSet(uint32_t val)
21{
22	bool first = true;
23	dprintf("{");
24	for (int i = 0; i < 32; i++) {
25		if (((1LL << i) & val) != 0) {
26			if (first) first = false; else dprintf(", ");
27			WriteMode(i);
28		}
29	}
30	dprintf("}");
31}
32
33
34void
35WriteExt(uint64_t val)
36{
37	switch (val) {
38		case 0: dprintf("off"); break;
39		case 1: dprintf("initial"); break;
40		case 2: dprintf("clean"); break;
41		case 3: dprintf("dirty"); break;
42		default: dprintf("%" B_PRId64, val);
43	}
44}
45
46
47void
48WriteSstatus(uint64_t val)
49{
50	SstatusReg status{.val = val};
51	dprintf("%#" B_PRIx64, val);
52	dprintf(" (");
53	dprintf("ie: "); WriteModeSet(status.ie);
54	dprintf(", pie: "); WriteModeSet(status.pie);
55	dprintf(", spp: "); WriteMode(status.spp);
56	dprintf(", fs: "); WriteExt(status.fs);
57	dprintf(", xs: "); WriteExt(status.xs);
58	dprintf(", sum: %d", (int)status.sum);
59	dprintf(", mxr: %d", (int)status.mxr);
60	dprintf(", uxl: %d", (int)status.uxl);
61	dprintf(", sd: %d", (int)status.sd);
62	dprintf(")");
63}
64
65
66void
67WriteInterrupt(uint64_t val)
68{
69	switch (val) {
70		case 0 + modeU: dprintf("uSoft"); break;
71		case 0 + modeS: dprintf("sSoft"); break;
72		case 0 + modeM: dprintf("mSoft"); break;
73		case 4 + modeU: dprintf("uTimer"); break;
74		case 4 + modeS: dprintf("sTimer"); break;
75		case 4 + modeM: dprintf("mTimer"); break;
76		case 8 + modeU: dprintf("uExtern"); break;
77		case 8 + modeS: dprintf("sExtern"); break;
78		case 8 + modeM: dprintf("mExtern"); break;
79		default: dprintf("%" B_PRId64, val);
80	}
81}
82
83
84void
85WriteInterruptSet(uint64_t val)
86{
87	bool first = true;
88	dprintf("{");
89	for (int i = 0; i < 64; i++) {
90		if (((1LL << i) & val) != 0) {
91			if (first) first = false; else dprintf(", ");
92			WriteInterrupt(i);
93		}
94	}
95	dprintf("}");
96}
97
98
99void
100WriteCause(uint64_t cause)
101{
102	if ((cause & causeInterrupt) == 0) {
103		dprintf("exception ");
104		switch (cause) {
105			case causeExecMisalign: dprintf("execMisalign"); break;
106			case causeExecAccessFault: dprintf("execAccessFault"); break;
107			case causeIllegalInst: dprintf("illegalInst"); break;
108			case causeBreakpoint: dprintf("breakpoint"); break;
109			case causeLoadMisalign: dprintf("loadMisalign"); break;
110			case causeLoadAccessFault: dprintf("loadAccessFault"); break;
111			case causeStoreMisalign: dprintf("storeMisalign"); break;
112			case causeStoreAccessFault: dprintf("storeAccessFault"); break;
113			case causeUEcall: dprintf("uEcall"); break;
114			case causeSEcall: dprintf("sEcall"); break;
115			case causeMEcall: dprintf("mEcall"); break;
116			case causeExecPageFault: dprintf("execPageFault"); break;
117			case causeLoadPageFault: dprintf("loadPageFault"); break;
118			case causeStorePageFault: dprintf("storePageFault"); break;
119			default: dprintf("%" B_PRId64, cause);
120			}
121	} else {
122		dprintf("interrupt "); WriteInterrupt(cause & ~causeInterrupt);
123	}
124}
125
126
127void
128WritePC(addr_t pc)
129{
130	dprintf("0x%" B_PRIxADDR, pc);
131}
132
133
134void
135DoStackTrace(addr_t fp, addr_t pc)
136{
137	dprintf("Stack:\n");
138	dprintf("FP: 0x%" B_PRIxADDR, fp);
139	if (pc != 0) {
140		dprintf(", PC: "); WritePC(pc);
141	}
142	dprintf("\n");
143	while (fp != 0) {
144		pc = *((uint64*)fp - 1);
145		fp = *((uint64*)fp - 2);
146		dprintf("FP: 0x%" B_PRIxADDR, fp);
147		dprintf(", PC: "); WritePC(pc);
148		dprintf("\n");
149		if (pc == 0) break;
150	}
151}
152
153
154void
155STrap(iframe* frame)
156{
157	uint64 cause = Scause();
158
159	dprintf("STrap("); WriteCause(Scause()); dprintf(")\n");
160	dprintf("  sstatus: "); WriteSstatus(Sstatus()); dprintf("\n");
161	dprintf("  sie: "); WriteInterruptSet(Sie()); dprintf("\n");
162	dprintf("  sip: "); WriteInterruptSet(Sip()); dprintf("\n");
163	dprintf("  sepc: 0x%" B_PRIxADDR "\n", Sepc());
164	dprintf("  stval: 0x%" B_PRIxADDR "\n", Stval());
165	dprintf("  sscratch: 0x%" B_PRIxADDR "\n", Sscratch());
166	DoStackTrace(Fp(), Sepc());
167	for (;;) Wfi();
168}
169
170
171void
172arch_traps_init()
173{
174	dprintf("init_arch_traps()\n");
175	SetStvec((uint64)SVec);
176}
177