blob: cc324b237c08e2c7502cf3fc3c43367c533bf204 [file] [log] [blame]
/* Copyright (c) 2008 by Intel Corp.
Scanner for the machine check grammar.
mce-inject 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; version
2.
mce-inject 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 find a copy of v2 of the GNU General Public License somewhere
on your Linux system; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Authors:
Andi Kleen
Ying Huang
*/
%{
#define _GNU_SOURCE 1
#include <stdlib.h>
#include <string.h>
#include "mce.h"
#include "parser.h"
#include "mce.tab.h"
#include "util.h"
#include "inject.h"
int yylineno;
static int lookup_symbol(const char *);
#define YY_NO_INPUT 1
%}
%option nounput
%%
#.*\n /* comment */;
\n ++yylineno;
0x[0-9a-fA-F]+ |
0[0-7]+ |
[0-9]+ yylval = strtoull(yytext, NULL, 0); return NUMBER;
[:{}<>] return yytext[0];
[_a-zA-Z][_a-zA-Z0-9]* return lookup_symbol(yytext);
[ \t]+ /* white space */;
. yyerror("Unrecognized character '%s'", yytext);
%%
/* Keyword handling */
static struct key {
const char *name;
int tok;
u64 val;
} keys[] = {
#define KEY(x) { #x, x }
#define KEYVAL(x,v) { #x, x, v }
KEY(MCE),
KEY(STATUS),
KEY(RIP),
KEY(TSC),
KEY(TIME),
KEY(SOCKETID),
KEY(APICID),
KEY(MCGCAP),
KEY(ADDR),
KEY(MISC),
KEY(CPU),
KEY(BANK),
KEY(MCGSTATUS),
KEY(PROCESSOR),
KEY(NOBROADCAST),
KEY(HOLD),
KEY(IN_IRQ),
KEY(IN_PROC),
KEY(POLL),
KEY(EXCP),
KEYVAL(CORRECTED, MCI_STATUS_VAL|MCI_STATUS_EN), // checkme
KEYVAL(UNCORRECTED, MCI_STATUS_VAL|MCI_STATUS_UC|MCI_STATUS_EN),
KEYVAL(FATAL, MCI_STATUS_VAL|MCI_STATUS_UC|MCI_STATUS_EN
|MCI_STATUS_PCC),
KEY(MACHINE),
KEY(CHECK),
KEY(EXCEPTION),
KEYVAL(RIPV, MCG_STATUS_RIPV),
KEYVAL(EIPV, MCG_STATUS_EIPV),
KEYVAL(MCIP, MCG_STATUS_MCIP),
KEYVAL(VAL, MCI_STATUS_VAL),
KEYVAL(OVER, MCI_STATUS_OVER),
KEYVAL(UC, MCI_STATUS_UC),
KEYVAL(EN, MCI_STATUS_EN),
KEYVAL(PCC, MCI_STATUS_PCC),
KEYVAL(S, MCI_STATUS_S),
KEYVAL(AR, MCI_STATUS_AR),
KEYVAL(UCNA, 0),
KEYVAL(SRAO, MCI_STATUS_S),
KEYVAL(SRAR, MCI_STATUS_S|MCI_STATUS_AR),
};
static int cmp_key(const void *av, const void *bv)
{
const struct key *a = av;
const struct key *b = bv;
return strcasecmp(a->name, b->name);
}
static int lookup_symbol(const char *name)
{
struct key *k;
struct key key;
key.name = name;
k = bsearch(&key, keys, ARRAY_SIZE(keys), sizeof(struct key), cmp_key);
if (k != NULL) {
yylval = k->val;
return k->tok;
}
return SYMBOL;
}
static void init_lex(void)
{
qsort(keys, ARRAY_SIZE(keys), sizeof(struct key), cmp_key);
}
int do_dump;
int no_random;
static char **argv;
char *filename = "<stdin>";
int yywrap(void)
{
if (*argv == NULL)
return 1;
filename = *argv;
yyin = fopen(filename, "r");
if (!yyin)
err(filename);
argv++;
return 0;
}
int main(int ac, char **av)
{
int rc = 0;
init_lex();
argv = ++av;
if (*argv && !strcmp(*argv, "--dump")) {
do_dump = 1;
argv++;
}
if (*argv && !strcmp(*argv, "--no-random")) {
no_random = 1;
argv++;
}
init_cpu_info();
init_inject();
if (*argv)
yywrap();
rc = yyparse();
clean_inject();
return rc;
}