blob: 19ea7934b9184ae4e1f482fb549b189b2abf20a4 [file] [log] [blame]
// SPDX-License-Identifier: GPL-2.0
#define boot_fmt(fmt) "alt: " fmt
#include "boot.h"
#define a_debug boot_debug
#include "../kernel/alternative.c"
static void alt_debug_all(int type)
{
int i;
switch (type) {
case ALT_TYPE_FACILITY:
for (i = 0; i < ARRAY_SIZE(alt_debug.facilities); i++)
alt_debug.facilities[i] = -1UL;
break;
case ALT_TYPE_FEATURE:
for (i = 0; i < ARRAY_SIZE(alt_debug.mfeatures); i++)
alt_debug.mfeatures[i] = -1UL;
break;
case ALT_TYPE_SPEC:
alt_debug.spec = 1;
break;
}
}
static void alt_debug_modify(int type, unsigned int nr, bool clear)
{
switch (type) {
case ALT_TYPE_FACILITY:
if (clear)
__clear_facility(nr, alt_debug.facilities);
else
__set_facility(nr, alt_debug.facilities);
break;
case ALT_TYPE_FEATURE:
if (clear)
__clear_machine_feature(nr, alt_debug.mfeatures);
else
__set_machine_feature(nr, alt_debug.mfeatures);
break;
}
}
static char *alt_debug_parse(int type, char *str)
{
unsigned long val, endval;
char *endp;
bool clear;
int i;
if (*str == ':') {
str++;
} else {
alt_debug_all(type);
return str;
}
clear = false;
if (*str == '!') {
alt_debug_all(type);
clear = true;
str++;
}
while (*str) {
val = simple_strtoull(str, &endp, 0);
if (str == endp)
break;
str = endp;
if (*str == '-') {
str++;
endval = simple_strtoull(str, &endp, 0);
if (str == endp)
break;
str = endp;
while (val <= endval) {
alt_debug_modify(type, val, clear);
val++;
}
} else {
alt_debug_modify(type, val, clear);
}
if (*str != ',')
break;
str++;
}
return str;
}
/*
* Use debug-alternative command line parameter for debugging:
* "debug-alternative"
* -> print debug message for every single alternative
*
* "debug-alternative=0;2"
* -> print debug message for all alternatives with type 0 and 2
*
* "debug-alternative=0:0-7"
* -> print debug message for all alternatives with type 0 and with
* facility numbers within the range of 0-7
* (if type 0 is ALT_TYPE_FACILITY)
*
* "debug-alternative=0:!8;1"
* -> print debug message for all alternatives with type 0, for all
* facility number, except facility 8, and in addition print all
* alternatives with type 1
*/
void alt_debug_setup(char *str)
{
unsigned long type;
char *endp;
int i;
if (!str) {
alt_debug_all(ALT_TYPE_FACILITY);
alt_debug_all(ALT_TYPE_FEATURE);
alt_debug_all(ALT_TYPE_SPEC);
return;
}
while (*str) {
type = simple_strtoull(str, &endp, 0);
if (str == endp)
break;
str = endp;
switch (type) {
case ALT_TYPE_FACILITY:
case ALT_TYPE_FEATURE:
str = alt_debug_parse(type, str);
break;
case ALT_TYPE_SPEC:
alt_debug_all(ALT_TYPE_SPEC);
break;
}
if (*str != ';')
break;
str++;
}
}