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