| /* SPDX-License-Identifier: GPL-2.0-only */ | |
| /* | |
| * Library to decode addressing related exceptions | |
| * | |
| * Copyright 2021 IBM Corp. | |
| * | |
| * Authors: | |
| * Janosch Frank <frankja@linux.ibm.com> | |
| */ | |
| #include <libcflat.h> | |
| #include <bitops.h> | |
| #include <util.h> | |
| #include <asm/arch_def.h> | |
| #include <asm/page.h> | |
| #include <fault.h> | |
| static void print_decode_pgm_prot(union teid teid) | |
| { | |
| switch (get_supp_on_prot_facility()) { | |
| case SOP_NONE: | |
| case SOP_BASIC: | |
| printf("Type: ?\n"); /* modern/relevant machines have ESOP */ | |
| break; | |
| case SOP_ENHANCED_1: | |
| if (teid.sop_teid_predictable) {/* implies access list or DAT */ | |
| if (teid.sop_acc_list) | |
| printf("Type: ACC\n"); | |
| else | |
| printf("Type: DAT\n"); | |
| } else { | |
| printf("Type: KEY or LAP\n"); | |
| } | |
| break; | |
| case SOP_ENHANCED_2: { | |
| static const char * const prot_str[] = { | |
| "KEY or LAP", | |
| "DAT", | |
| "KEY", | |
| "ACC", | |
| "LAP", | |
| "IEP", | |
| }; | |
| static_assert(ARRAY_SIZE(prot_str) == PROT_NUM_CODES); | |
| int prot_code = teid_esop2_prot_code(teid); | |
| printf("Type: %s\n", prot_str[prot_code]); | |
| } | |
| } | |
| } | |
| void print_decode_teid(uint64_t raw_teid) | |
| { | |
| union teid teid = { .val = raw_teid }; | |
| bool dat = lowcore.pgm_old_psw.mask & PSW_MASK_DAT; | |
| printf("Memory exception information:\n"); | |
| printf("DAT: %s\n", dat ? "on" : "off"); | |
| printf("AS: "); | |
| switch (teid.asce_id) { | |
| case AS_PRIM: | |
| printf("Primary\n"); | |
| break; | |
| case AS_ACCR: | |
| printf("Access Register\n"); | |
| break; | |
| case AS_SECN: | |
| printf("Secondary\n"); | |
| break; | |
| case AS_HOME: | |
| printf("Home\n"); | |
| break; | |
| } | |
| if (lowcore.pgm_int_code == PGM_INT_CODE_PROTECTION) | |
| print_decode_pgm_prot(teid); | |
| /* | |
| * If teid bit 61 is off for these two exception the reported | |
| * address is unpredictable. | |
| */ | |
| if ((lowcore.pgm_int_code == PGM_INT_CODE_SECURE_STOR_ACCESS || | |
| lowcore.pgm_int_code == PGM_INT_CODE_SECURE_STOR_VIOLATION) && | |
| !teid.sop_teid_predictable) { | |
| printf("Address: %lx, unpredictable\n ", raw_teid & PAGE_MASK); | |
| return; | |
| } | |
| printf("TEID: %lx\n", raw_teid); | |
| printf("Address: %lx\n\n", raw_teid & PAGE_MASK); | |
| } |