1/*
2 * Verify MCA grading engine against some examples.
3 */
4#include <sys/types.h>
5#include <stdio.h>
6#define __KERNEL__ 1
7#include <asm/types.h>
8#include <asm/mce.h>
9#include <errno.h>
10
11#define ARRAY_SIZE(x) (sizeof(x)/sizeof(*(x)))
12
13typedef unsigned long long u64;
14
15#define MCI_STATUS_S	 (1ULL<<56)  /* Signaled machine check */
16#define MCI_STATUS_AR	 (1ULL<<55)  /* Action required */
17
18int mce_ser = 1;
19int tolerant = 1;
20int panic_on_oops = 0;
21
22#include "mce-severity.c"
23
24char *resname[] = {
25#define R(x) [MCE_ ## x ## _SEVERITY] = #x
26	R(NO),
27	R(KEEP),
28	R(SOME),
29	R(AO),
30	R(AR),
31	R(PANIC),
32};
33#define VAL MCI_STATUS_VAL
34#define EN MCI_STATUS_EN
35#define PCC MCI_STATUS_PCC
36#define S MCI_STATUS_S
37#define AR MCI_STATUS_AR
38#define UC MCI_STATUS_UC
39
40int ring = 3;
41int fail;
42
43void test2(u64 flag, char *flagname, u64 mcg, char *mcgname, int result)
44{
45	struct mce m = {
46		.ip = 1,
47		.cs = ring,
48		.status = flag,
49		.mcgstatus = mcg,
50	};
51	int r;
52	char *msg;
53
54	if ((r = mce_severity(&m, tolerant, &msg)) != result) {
55		printf("%s %s expected %s got %s msg %s\n",
56		       flagname, mcgname, resname[result], resname[r], msg);
57		fail++;
58	}
59}
60
61
62#define TEST(flag, result) \
63	test2(flag, #flag, MCG_STATUS_MCIP|MCG_STATUS_RIPV, "mcip,ripv", \
64		MCE_ ## result ## _SEVERITY)
65
66void test(void)
67{
68	// corrected
69	TEST(VAL|EN, KEEP);
70
71	// uncorrected fatal
72	TEST(VAL|UC|PCC|EN|S|AR, PANIC);
73	TEST(VAL|UC|PCC|EN|S, PANIC);
74	TEST(VAL|UC|PCC|EN, PANIC);
75
76	// SW recoverable action required
77	// unknown mcacod -> panic
78	TEST(VAL|UC|EN|S|AR, PANIC);
79
80	// SW recoverable action optional
81	TEST(VAL|UC|EN|S|0xc0, AO);
82	// unknown mcacod
83	TEST(VAL|UC|EN|S|1, SOME);
84
85	// UCNA
86	TEST(VAL|UC|EN, KEEP);
87	TEST(VAL|UC, NO);	// linux clears. correct?
88}
89
90int main(void)
91{
92	ring = 3;
93	test();
94	ring = 0;
95	test();
96	if (fail == 0)
97		printf("SUCCESS\n");
98	else
99		printf("%d FAILURES\n", fail);
100	return fail;
101}
102