selftests/powerpc/dexcr: Add DEXCR status utility lsdexcr
[linux-block.git] / tools / testing / selftests / powerpc / dexcr / lsdexcr.c
1 // SPDX-License-Identifier: GPL-2.0+
2
3 #include <errno.h>
4 #include <stddef.h>
5 #include <stdio.h>
6 #include <string.h>
7
8 #include "dexcr.h"
9 #include "utils.h"
10
11 static unsigned int dexcr;
12 static unsigned int hdexcr;
13 static unsigned int effective;
14
15 struct dexcr_aspect {
16         const char *name;
17         const char *desc;
18         unsigned int index;
19 };
20
21 static const struct dexcr_aspect aspects[] = {
22         {
23                 .name = "SBHE",
24                 .desc = "Speculative branch hint enable",
25                 .index = 0,
26         },
27         {
28                 .name = "IBRTPD",
29                 .desc = "Indirect branch recurrent target prediction disable",
30                 .index = 3,
31         },
32         {
33                 .name = "SRAPD",
34                 .desc = "Subroutine return address prediction disable",
35                 .index = 4,
36         },
37         {
38                 .name = "NPHIE",
39                 .desc = "Non-privileged hash instruction enable",
40                 .index = 5,
41         },
42         {
43                 .name = "PHIE",
44                 .desc = "Privileged hash instruction enable",
45                 .index = 6,
46         },
47 };
48
49 static void print_list(const char *list[], size_t len)
50 {
51         for (size_t i = 0; i < len; i++) {
52                 printf("%s", list[i]);
53                 if (i + 1 < len)
54                         printf(", ");
55         }
56 }
57
58 static void print_dexcr(char *name, unsigned int bits)
59 {
60         const char *enabled_aspects[ARRAY_SIZE(aspects) + 1] = {NULL};
61         size_t j = 0;
62
63         printf("%s: %08x", name, bits);
64
65         if (bits == 0) {
66                 printf("\n");
67                 return;
68         }
69
70         for (size_t i = 0; i < ARRAY_SIZE(aspects); i++) {
71                 unsigned int mask = DEXCR_PR_BIT(aspects[i].index);
72
73                 if (bits & mask) {
74                         enabled_aspects[j++] = aspects[i].name;
75                         bits &= ~mask;
76                 }
77         }
78
79         if (bits)
80                 enabled_aspects[j++] = "unknown";
81
82         printf(" (");
83         print_list(enabled_aspects, j);
84         printf(")\n");
85 }
86
87 static void print_aspect(const struct dexcr_aspect *aspect)
88 {
89         const char *attributes[8] = {NULL};
90         size_t j = 0;
91         unsigned long mask;
92
93         mask = DEXCR_PR_BIT(aspect->index);
94         if (dexcr & mask)
95                 attributes[j++] = "set";
96         if (hdexcr & mask)
97                 attributes[j++] = "set (hypervisor)";
98         if (!(effective & mask))
99                 attributes[j++] = "clear";
100
101         printf("%12s %c (%d): ", aspect->name, effective & mask ? '*' : ' ', aspect->index);
102         print_list(attributes, j);
103         printf("  \t(%s)\n", aspect->desc);
104 }
105
106 int main(int argc, char *argv[])
107 {
108         if (!dexcr_exists()) {
109                 printf("DEXCR not detected on this hardware\n");
110                 return 1;
111         }
112
113         dexcr = get_dexcr(DEXCR);
114         hdexcr = get_dexcr(HDEXCR);
115         effective = dexcr | hdexcr;
116
117         print_dexcr("    DEXCR", dexcr);
118         print_dexcr("   HDEXCR", hdexcr);
119         print_dexcr("Effective", effective);
120         printf("\n");
121
122         for (size_t i = 0; i < ARRAY_SIZE(aspects); i++)
123                 print_aspect(&aspects[i]);
124         printf("\n");
125
126         if (effective & DEXCR_PR_NPHIE) {
127                 printf("DEXCR[NPHIE] enabled: hashst/hashchk ");
128                 if (hashchk_triggers())
129                         printf("working\n");
130                 else
131                         printf("failed to trigger\n");
132         } else {
133                 printf("DEXCR[NPHIE] disabled: hashst/hashchk ");
134                 if (hashchk_triggers())
135                         printf("unexpectedly triggered\n");
136                 else
137                         printf("ignored\n");
138         }
139
140         return 0;
141 }