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, limit; 49 char *endp; 50 bool clear; 51 int i; 52 53 limit = type == ALT_TYPE_FACILITY ? MAX_FACILITY_BIT : MAX_MFEATURE_BIT; 54 if (*str == ':') { 55 str++; 56 } else { 57 alt_debug_all(type); 58 return str; 59 } 60 clear = false; 61 if (*str == '!') { 62 alt_debug_all(type); 63 clear = true; 64 str++; 65 } 66 while (*str) { 67 val = simple_strtoull(str, &endp, 0); 68 if (str == endp) 69 break; 70 str = endp; 71 if (*str == '-') { 72 str++; 73 endval = simple_strtoull(str, &endp, 0); 74 if (str == endp) 75 break; 76 str = endp; 77 while (val <= endval && val < limit) { 78 alt_debug_modify(type, val, clear); 79 val++; 80 } 81 } else { 82 alt_debug_modify(type, val, clear); 83 } 84 if (*str != ',') 85 break; 86 str++; 87 } 88 return str; 89 } 90 91 /* 92 * Use debug-alternative command line parameter for debugging: 93 * "debug-alternative" 94 * -> print debug message for every single alternative 95 * 96 * "debug-alternative=0;2" 97 * -> print debug message for all alternatives with type 0 and 2 98 * 99 * "debug-alternative=0:0-7" 100 * -> print debug message for all alternatives with type 0 and with 101 * facility numbers within the range of 0-7 102 * (if type 0 is ALT_TYPE_FACILITY) 103 * 104 * "debug-alternative=0:!8;1" 105 * -> print debug message for all alternatives with type 0, for all 106 * facility number, except facility 8, and in addition print all 107 * alternatives with type 1 108 */ 109 void alt_debug_setup(char *str) 110 { 111 unsigned long type; 112 char *endp; 113 int i; 114 115 if (!str) { 116 alt_debug_all(ALT_TYPE_FACILITY); 117 alt_debug_all(ALT_TYPE_FEATURE); 118 alt_debug_all(ALT_TYPE_SPEC); 119 return; 120 } 121 while (*str) { 122 type = simple_strtoull(str, &endp, 0); 123 if (str == endp) 124 break; 125 str = endp; 126 switch (type) { 127 case ALT_TYPE_FACILITY: 128 case ALT_TYPE_FEATURE: 129 str = alt_debug_parse(type, str); 130 break; 131 case ALT_TYPE_SPEC: 132 alt_debug_all(ALT_TYPE_SPEC); 133 break; 134 } 135 if (*str != ';') 136 break; 137 str++; 138 } 139 } 140