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