1 #ifndef _XEN_PARAM_H
2 #define _XEN_PARAM_H
3
4 #include <xen/hypfs.h>
5 #include <xen/init.h>
6 #include <xen/lib.h>
7 #include <xen/stdbool.h>
8
9 /*
10 * Used for kernel command line parameter setup
11 */
12 struct kernel_param {
13 const char *name;
14 enum {
15 OPT_STR,
16 OPT_UINT,
17 OPT_BOOL,
18 OPT_SIZE,
19 OPT_CUSTOM,
20 OPT_IGNORE,
21 } type;
22 unsigned int len;
23 union {
24 void *var;
25 int (*func)(const char *);
26 } par;
27 };
28
29 /* Maximum length of a single parameter string. */
30 #define MAX_PARAM_SIZE 128
31
32 extern const struct kernel_param __setup_start[], __setup_end[];
33
34 #define __param(att) static const att \
35 __attribute__((__aligned__(sizeof(void *)))) struct kernel_param
36
37 #define __setup_str static const __initconst \
38 __attribute__((__aligned__(1))) char
39 #define __kparam __param(__initsetup)
40
41 #define custom_param(_name, _var) \
42 __setup_str __setup_str_##_var[] = _name; \
43 __kparam __setup_##_var = \
44 { .name = __setup_str_##_var, \
45 .type = OPT_CUSTOM, \
46 .par.func = _var }
47 #define boolean_param(_name, _var) \
48 __setup_str __setup_str_##_var[] = _name; \
49 __kparam __setup_##_var = \
50 { .name = __setup_str_##_var, \
51 .type = OPT_BOOL, \
52 .len = sizeof(_var) + \
53 BUILD_BUG_ON_ZERO(sizeof(_var) != sizeof(bool)), \
54 .par.var = &_var }
55 #define integer_param(_name, _var) \
56 __setup_str __setup_str_##_var[] = _name; \
57 __kparam __setup_##_var = \
58 { .name = __setup_str_##_var, \
59 .type = OPT_UINT, \
60 .len = sizeof(_var), \
61 .par.var = &_var }
62 #define size_param(_name, _var) \
63 __setup_str __setup_str_##_var[] = _name; \
64 __kparam __setup_##_var = \
65 { .name = __setup_str_##_var, \
66 .type = OPT_SIZE, \
67 .len = sizeof(_var), \
68 .par.var = &_var }
69 #define string_param(_name, _var) \
70 __setup_str __setup_str_##_var[] = _name; \
71 __kparam __setup_##_var = \
72 { .name = __setup_str_##_var, \
73 .type = OPT_STR, \
74 .len = sizeof(_var), \
75 .par.var = &_var }
76 #define ignore_param(_name) \
77 __setup_str setup_str_ign[] = _name; \
78 __kparam setup_ign = \
79 { .name = setup_str_ign, \
80 .type = OPT_IGNORE }
81
82 #ifdef CONFIG_HYPFS
83
84 struct param_hypfs {
85 struct hypfs_entry_leaf hypfs;
86 void (*init_leaf)(struct param_hypfs *par);
87 int (*func)(const char *);
88 };
89
90 extern struct param_hypfs __paramhypfs_start[], __paramhypfs_end[];
91
92 #define __paramhypfs __used_section(".data.paramhypfs")
93
94 #define __paramfs static __paramhypfs \
95 __attribute__((__aligned__(sizeof(void *)))) struct param_hypfs
96
97 #define custom_runtime_set_var_sz(parfs, var, sz) \
98 { \
99 (parfs)->hypfs.u.content = var; \
100 (parfs)->hypfs.e.max_size = sz; \
101 (parfs)->hypfs.e.size = strlen(var) + 1; \
102 }
103 #define custom_runtime_set_var(parfs, var) \
104 custom_runtime_set_var_sz(parfs, var, sizeof(var))
105
106 #define param_2_parfs(par) &__parfs_##par
107
108 /* initfunc needs to set size and content, e.g. via custom_runtime_set_var(). */
109 #define custom_runtime_only_param(nam, variable, initfunc) \
110 __paramfs __parfs_##variable = \
111 { .hypfs.e.type = XEN_HYPFS_TYPE_STRING, \
112 .hypfs.e.encoding = XEN_HYPFS_ENC_PLAIN, \
113 .hypfs.e.name = (nam), \
114 .hypfs.e.read = hypfs_read_leaf, \
115 .hypfs.e.write = hypfs_write_custom, \
116 .init_leaf = (initfunc), \
117 .func = (variable) }
118 #define boolean_runtime_only_param(nam, variable) \
119 __paramfs __parfs_##variable = \
120 { .hypfs.e.type = XEN_HYPFS_TYPE_BOOL, \
121 .hypfs.e.encoding = XEN_HYPFS_ENC_PLAIN, \
122 .hypfs.e.name = (nam), \
123 .hypfs.e.size = sizeof(variable), \
124 .hypfs.e.max_size = sizeof(variable), \
125 .hypfs.e.read = hypfs_read_leaf, \
126 .hypfs.e.write = hypfs_write_bool, \
127 .hypfs.u.content = &(variable) }
128 #define integer_runtime_only_param(nam, variable) \
129 __paramfs __parfs_##variable = \
130 { .hypfs.e.type = XEN_HYPFS_TYPE_UINT, \
131 .hypfs.e.encoding = XEN_HYPFS_ENC_PLAIN, \
132 .hypfs.e.name = (nam), \
133 .hypfs.e.size = sizeof(variable), \
134 .hypfs.e.max_size = sizeof(variable), \
135 .hypfs.e.read = hypfs_read_leaf, \
136 .hypfs.e.write = hypfs_write_leaf, \
137 .hypfs.u.content = &(variable) }
138 #define size_runtime_only_param(nam, variable) \
139 __paramfs __parfs_##variable = \
140 { .hypfs.e.type = XEN_HYPFS_TYPE_UINT, \
141 .hypfs.e.encoding = XEN_HYPFS_ENC_PLAIN, \
142 .hypfs.e.name = (nam), \
143 .hypfs.e.size = sizeof(variable), \
144 .hypfs.e.max_size = sizeof(variable), \
145 .hypfs.e.read = hypfs_read_leaf, \
146 .hypfs.e.write = hypfs_write_leaf, \
147 .hypfs.u.content = &(variable) }
148 #define string_runtime_only_param(nam, variable) \
149 __paramfs __parfs_##variable = \
150 { .hypfs.e.type = XEN_HYPFS_TYPE_STRING, \
151 .hypfs.e.encoding = XEN_HYPFS_ENC_PLAIN, \
152 .hypfs.e.name = (nam), \
153 .hypfs.e.size = 0, \
154 .hypfs.e.max_size = sizeof(variable), \
155 .hypfs.e.read = hypfs_read_leaf, \
156 .hypfs.e.write = hypfs_write_leaf, \
157 .hypfs.u.content = &(variable) }
158
159 #else
160
161 #define custom_runtime_only_param(nam, var, initfunc)
162 #define boolean_runtime_only_param(nam, var)
163 #define integer_runtime_only_param(nam, var)
164 #define size_runtime_only_param(nam, var)
165 #define string_runtime_only_param(nam, var)
166
167 #define custom_runtime_set_var(parfs, var)
168
169 #endif
170
171 #define custom_runtime_param(_name, _var, initfunc) \
172 custom_param(_name, _var); \
173 custom_runtime_only_param(_name, _var, initfunc)
174 #define boolean_runtime_param(_name, _var) \
175 boolean_param(_name, _var); \
176 boolean_runtime_only_param(_name, _var)
177 #define integer_runtime_param(_name, _var) \
178 integer_param(_name, _var); \
179 integer_runtime_only_param(_name, _var)
180 #define size_runtime_param(_name, _var) \
181 size_param(_name, _var); \
182 size_runtime_only_param(_name, _var)
183 #define string_runtime_param(_name, _var) \
184 string_param(_name, _var); \
185 string_runtime_only_param(_name, _var)
186
no_config_param(const char * cfg,const char * param,const char * s,const char * e)187 static inline void no_config_param(const char *cfg, const char *param,
188 const char *s, const char *e)
189 {
190 int len = e ? ({ ASSERT(e >= s); e - s; }) : strlen(s);
191
192 printk(XENLOG_INFO "CONFIG_%s disabled - ignoring '%s=%*s' setting\n",
193 cfg, param, len, s);
194 }
195
196 #endif /* _XEN_PARAM_H */
197