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