xref: /haiku/src/system/boot/platform/efi/arch/riscv64/arch_traps.cpp (revision 17889a8c70dbb3d59c1412f6431968753c767bab)
1 #include "arch_traps.h"
2 
3 #include <KernelExport.h>
4 #include <arch_cpu_defs.h>
5 
6 
7 void
8 WriteMode(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 
19 void
20 WriteModeSet(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 
34 void
35 WriteExt(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 
47 void
48 WriteSstatus(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 
66 void
67 WriteInterrupt(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 
84 void
85 WriteInterruptSet(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 
99 void
100 WriteCause(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 
127 void
128 WritePC(addr_t pc)
129 {
130 	dprintf("0x%" B_PRIxADDR, pc);
131 }
132 
133 
134 void
135 DoStackTrace(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 
154 void
155 STrap(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 
171 void
172 arch_traps_init()
173 {
174 	dprintf("init_arch_traps()\n");
175 	SetStvec((uint64)SVec);
176 }
177