@@ -234,11 +234,83 @@ static void print_ecfg(unsigned long x)
234234 pr_cont (" VS=%d)\n" , (int ) FIELD_GET (CSR_ECFG_VS , x ));
235235}
236236
237+ static const char * humanize_exc_name (unsigned int ecode , unsigned int esubcode )
238+ {
239+ /*
240+ * LoongArch users and developers are probably more familiar with
241+ * those names found in the ISA manual, so we are going to print out
242+ * the latter. This will require some mapping.
243+ */
244+ switch (ecode ) {
245+ case EXCCODE_RSV : return "INT" ;
246+ case EXCCODE_TLBL : return "PIL" ;
247+ case EXCCODE_TLBS : return "PIS" ;
248+ case EXCCODE_TLBI : return "PIF" ;
249+ case EXCCODE_TLBM : return "PME" ;
250+ case EXCCODE_TLBNR : return "PNR" ;
251+ case EXCCODE_TLBNX : return "PNX" ;
252+ case EXCCODE_TLBPE : return "PPI" ;
253+ case EXCCODE_ADE :
254+ switch (esubcode ) {
255+ case EXSUBCODE_ADEF : return "ADEF" ;
256+ case EXSUBCODE_ADEM : return "ADEM" ;
257+ }
258+ break ;
259+ case EXCCODE_ALE : return "ALE" ;
260+ case EXCCODE_BCE : return "BCE" ;
261+ case EXCCODE_SYS : return "SYS" ;
262+ case EXCCODE_BP : return "BRK" ;
263+ case EXCCODE_INE : return "INE" ;
264+ case EXCCODE_IPE : return "IPE" ;
265+ case EXCCODE_FPDIS : return "FPD" ;
266+ case EXCCODE_LSXDIS : return "SXD" ;
267+ case EXCCODE_LASXDIS : return "ASXD" ;
268+ case EXCCODE_FPE :
269+ switch (esubcode ) {
270+ case EXCSUBCODE_FPE : return "FPE" ;
271+ case EXCSUBCODE_VFPE : return "VFPE" ;
272+ }
273+ break ;
274+ case EXCCODE_WATCH :
275+ switch (esubcode ) {
276+ case EXCSUBCODE_WPEF : return "WPEF" ;
277+ case EXCSUBCODE_WPEM : return "WPEM" ;
278+ }
279+ break ;
280+ case EXCCODE_BTDIS : return "BTD" ;
281+ case EXCCODE_BTE : return "BTE" ;
282+ case EXCCODE_GSPR : return "GSPR" ;
283+ case EXCCODE_HVC : return "HVC" ;
284+ case EXCCODE_GCM :
285+ switch (esubcode ) {
286+ case EXCSUBCODE_GCSC : return "GCSC" ;
287+ case EXCSUBCODE_GCHC : return "GCHC" ;
288+ }
289+ break ;
290+ /*
291+ * The manual did not mention the EXCCODE_SE case, but print out it
292+ * nevertheless.
293+ */
294+ case EXCCODE_SE : return "SE" ;
295+ }
296+
297+ return "???" ;
298+ }
299+
300+ static void print_estat (unsigned long x )
301+ {
302+ unsigned int ecode = FIELD_GET (CSR_ESTAT_EXC , x );
303+ unsigned int esubcode = FIELD_GET (CSR_ESTAT_ESUBCODE , x );
304+
305+ printk ("ESTAT: %08lx [%s] (" , x , humanize_exc_name (ecode , esubcode ));
306+ print_intr_fragment ("IS" , FIELD_GET (CSR_ESTAT_IS , x ));
307+ pr_cont (" ECode=%d EsubCode=%d)\n" , (int ) ecode , (int ) esubcode );
308+ }
309+
237310static void __show_regs (const struct pt_regs * regs )
238311{
239312 const int field = 2 * sizeof (unsigned long );
240- unsigned int excsubcode ;
241- unsigned int exccode ;
313+ unsigned int exccode = FIELD_GET (CSR_ESTAT_EXC , regs -> csr_estat );
242314
243315 show_regs_print_info (KERN_DEFAULT );
244316
@@ -279,11 +351,7 @@ static void __show_regs(const struct pt_regs *regs)
279351 print_prmd (regs -> csr_prmd );
280352 print_euen (regs -> csr_euen );
281353 print_ecfg (regs -> csr_ecfg );
282- printk ("ESTAT: %08lx\n" , regs -> csr_estat );
283-
284- exccode = ((regs -> csr_estat ) & CSR_ESTAT_EXC ) >> CSR_ESTAT_EXC_SHIFT ;
285- excsubcode = ((regs -> csr_estat ) & CSR_ESTAT_ESUBCODE ) >> CSR_ESTAT_ESUBCODE_SHIFT ;
286- printk ("ExcCode : %x (SubCode %x)\n" , exccode , excsubcode );
354+ print_estat (regs -> csr_estat );
287355
288356 if (exccode >= EXCCODE_TLBL && exccode <= EXCCODE_ALE )
289357 printk ("BadVA : %0*lx\n" , field , regs -> csr_badvaddr );
0 commit comments