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
alt_debug_all(int type)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
alt_debug_modify(int type,unsigned int nr,bool clear)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
alt_debug_parse(int type,char * str)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 */
alt_debug_setup(char * str)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