1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 /* 3 * Library to decode addressing related exceptions 4 * 5 * Copyright 2021 IBM Corp. 6 * 7 * Authors: 8 * Janosch Frank <frankja@linux.ibm.com> 9 */ 10 #include <libcflat.h> 11 #include <bitops.h> 12 #include <util.h> 13 #include <asm/arch_def.h> 14 #include <asm/page.h> 15 #include <fault.h> 16 17 18 static void print_decode_pgm_prot(union teid teid) 19 { 20 switch (get_supp_on_prot_facility()) { 21 case SOP_NONE: 22 case SOP_BASIC: 23 printf("Type: ?\n"); /* modern/relevant machines have ESOP */ 24 break; 25 case SOP_ENHANCED_1: 26 if (teid.sop_teid_predictable) {/* implies access list or DAT */ 27 if (teid.sop_acc_list) 28 printf("Type: ACC\n"); 29 else 30 printf("Type: DAT\n"); 31 } else { 32 printf("Type: KEY or LAP\n"); 33 } 34 break; 35 case SOP_ENHANCED_2: { 36 static const char * const prot_str[] = { 37 "KEY or LAP", 38 "DAT", 39 "KEY", 40 "ACC", 41 "LAP", 42 "IEP", 43 }; 44 static_assert(ARRAY_SIZE(prot_str) == PROT_NUM_CODES); 45 int prot_code = teid_esop2_prot_code(teid); 46 47 printf("Type: %s\n", prot_str[prot_code]); 48 } 49 } 50 } 51 52 void print_decode_teid(uint64_t raw_teid) 53 { 54 union teid teid = { .val = raw_teid }; 55 bool dat = lowcore.pgm_old_psw.mask & PSW_MASK_DAT; 56 57 printf("Memory exception information:\n"); 58 printf("DAT: %s\n", dat ? "on" : "off"); 59 60 printf("AS: "); 61 switch (teid.asce_id) { 62 case AS_PRIM: 63 printf("Primary\n"); 64 break; 65 case AS_ACCR: 66 printf("Access Register\n"); 67 break; 68 case AS_SECN: 69 printf("Secondary\n"); 70 break; 71 case AS_HOME: 72 printf("Home\n"); 73 break; 74 } 75 76 if (lowcore.pgm_int_code == PGM_INT_CODE_PROTECTION) 77 print_decode_pgm_prot(teid); 78 79 /* 80 * If teid bit 61 is off for these two exception the reported 81 * address is unpredictable. 82 */ 83 if ((lowcore.pgm_int_code == PGM_INT_CODE_SECURE_STOR_ACCESS || 84 lowcore.pgm_int_code == PGM_INT_CODE_SECURE_STOR_VIOLATION) && 85 !teid.sop_teid_predictable) { 86 printf("Address: %lx, unpredictable\n ", raw_teid & PAGE_MASK); 87 return; 88 } 89 printf("TEID: %lx\n", raw_teid); 90 printf("Address: %lx\n\n", raw_teid & PAGE_MASK); 91 } 92