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