forked from thockin/mcedaemon
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmce_decode.c
109 lines (95 loc) · 3.23 KB
/
mce_decode.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
/*
* mce_decode.c - simple MCE decoder
*
* Based on code from mcelog.
* Copyright (c) 2007 Tim Hockin ([email protected])
* Copyright (c) 2007 Google, Inc. ([email protected])
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <stdio.h>
#include <stdlib.h>
#include "mced.h"
#define BIT(x) (1ULL<<(x))
static char *progname;
static void
dump_mce(struct mce *mce)
{
printf("machine check:\n");
printf(" cpu: %d\n", mce->cpu);
printf(" bank: %d\n", mce->bank);
printf(" gstatus: 0x%016llx\n", (unsigned long long)mce->mcg_status);
if (mce->mcg_status & BIT(0))
printf(" [0] = restart IP is valid\n");
if (mce->mcg_status & BIT(1))
printf(" [1] = error IP is valid\n");
if (mce->mcg_status & BIT(2))
printf(" [2] = machine check in progress\n");
printf(" status: 0x%016llx\n", (unsigned long long)mce->mci_status);
if (mce->mci_status & BIT(63))
printf(" [63] = error is valid\n");
if (mce->mci_status & BIT(62))
printf(" [62] = errors overflowed\n");
if (mce->mci_status & BIT(61))
printf(" [61] = error is uncorrected\n");
else
printf(" [61] = error is corrected\n");
if (mce->mci_status & BIT(60))
printf(" [60] = error is enabled\n");
if (mce->mci_status & BIT(59))
printf(" [59] = misc field is valid\n");
if (mce->mci_status & BIT(58))
printf(" [58] = address field is valid\n");
if (mce->mci_status & BIT(57))
printf(" [57] = processor context may be corrupt\n");
printf(" [16:0] = MCA error code = 0x%04x\n",
(unsigned)(mce->mci_status & 0xffff));
printf(" [31:16] = model-specific error code = 0x%04x\n",
(unsigned)((mce->mci_status>>16) & 0xffff));
printf(" [56:32] = other information = 0x%06x\n",
(unsigned)((mce->mci_status>>32) & 0xffffff));
if (mce->mci_status & BIT(58))
printf(" address: 0x%016llx\n",
(unsigned long long)mce->mci_address);
if (mce->mci_status & BIT(59))
printf(" misc: 0x%016llx\n",
(unsigned long long)mce->mci_misc);
}
static void
usage()
{
fprintf(stderr,
"Usage:\n"
" %s <cpu> <bank> <mcgstatus> <status> <address> <misc>\n",
progname);
}
int
main(int argc, char **argv)
{
struct mce mce;
progname = argv[0];
if (argc != 7) {
usage();
return EXIT_FAILURE;
}
mce.cpu = strtoul(argv[1], NULL, 0);
mce.bank = strtoul(argv[2], NULL, 0);
mce.mcg_status = strtoull(argv[3], NULL, 0);
mce.mci_status = strtoull(argv[4], NULL, 0);
mce.mci_address = strtoull(argv[5], NULL, 0);
mce.mci_misc = strtoull(argv[6], NULL, 0);
dump_mce(&mce);
return EXIT_SUCCESS;
}