1 // SPDX-License-Identifier: GPL-2.0 2 #define boot_fmt(fmt) "alt: " fmt 3 #include "boot.h" 4 5 #define a_debug boot_debug 6 7 #include "../kernel/alternative.c" 8 9 static void alt_debug_all(int type) 10 { 11 int i; 12 13 switch (type) { 14 case ALT_TYPE_FACILITY: 15 for (i = 0; i < ARRAY_SIZE(alt_debug.facilities); i++) 16 alt_debug.facilities[i] = -1UL; 17 break; 18 case ALT_TYPE_FEATURE: 19 for (i = 0; i < ARRAY_SIZE(alt_debug.mfeatures); i++) 20 alt_debug.mfeatures[i] = -1UL; 21 break; 22 case ALT_TYPE_SPEC: 23 alt_debug.spec = 1; 24 break; 25 } 26 } 27 28 static void alt_debug_modify(int type, unsigned int nr, bool clear) 29 { 30 switch (type) { 31 case ALT_TYPE_FACILITY: 32 if (clear) 33 __clear_facility(nr, alt_debug.facilities); 34 else 35 __set_facility(nr, alt_debug.facilities); 36 break; 37 case ALT_TYPE_FEATURE: 38 if (clear) 39 __clear_machine_feature(nr, alt_debug.mfeatures); 40 else 41 __set_machine_feature(nr, alt_debug.mfeatures); 42 break; 43 } 44 } 45 46 static char *alt_debug_parse(int type, char *str) 47 { 48 unsigned long val, endval; 49 char *endp; 50 bool clear; 51 int i; 52 53 if (*str == ':') { 54 str++; 55 } else { 56 alt_debug_all(type); 57 return str; 58 } 59 clear = false; 60 if (*str == '!') { 61 alt_debug_all(type); 62 clear = true; 63 str++; 64 } 65 while (*str) { 66 val = simple_strtoull(str, &endp, 0); 67 if (str == endp) 68 break; 69 str = endp; 70 if (*str == '-') { 71 str++; 72 endval = simple_strtoull(str, &endp, 0); 73 if (str == endp) 74 break; 75 str = endp; 76 while (val <= endval) { 77 alt_debug_modify(type, val, clear); 78 val++; 79 } 80 } else { 81 alt_debug_modify(type, val, clear); 82 } 83 if (*str != ',') 84 break; 85 str++; 86 } 87 return str; 88 } 89 90 /* 91 * Use debug-alternative command line parameter for debugging: 92 * "debug-alternative" 93 * -> print debug message for every single alternative 94 * 95 * "debug-alternative=0;2" 96 * -> print debug message for all alternatives with type 0 and 2 97 * 98 * "debug-alternative=0:0-7" 99 * -> print debug message for all alternatives with type 0 and with 100 * facility numbers within the range of 0-7 101 * (if type 0 is ALT_TYPE_FACILITY) 102 * 103 * "debug-alternative=0:!8;1" 104 * -> print debug message for all alternatives with type 0, for all 105 * facility number, except facility 8, and in addition print all 106 * alternatives with type 1 107 */ 108 void alt_debug_setup(char *str) 109 { 110 unsigned long type; 111 char *endp; 112 int i; 113 114 if (!str) { 115 alt_debug_all(ALT_TYPE_FACILITY); 116 alt_debug_all(ALT_TYPE_FEATURE); 117 alt_debug_all(ALT_TYPE_SPEC); 118 return; 119 } 120 while (*str) { 121 type = simple_strtoull(str, &endp, 0); 122 if (str == endp) 123 break; 124 str = endp; 125 switch (type) { 126 case ALT_TYPE_FACILITY: 127 case ALT_TYPE_FEATURE: 128 str = alt_debug_parse(type, str); 129 break; 130 case ALT_TYPE_SPEC: 131 alt_debug_all(ALT_TYPE_SPEC); 132 break; 133 } 134 if (*str != ';') 135 break; 136 str++; 137 } 138 } 139