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;
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 */
alt_debug_setup(char * str)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