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
print_decode_pgm_prot(union teid teid)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
print_decode_teid(uint64_t raw_teid)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