nvramcui: Use regular `if` over `#if` for `IS_ENABLED`
[coreboot.git] / payloads / nvramcui / nvramcui.c
blob675e00292fc0f60605d9d11cebcc2edeef166d23
1 /*
2 * This file is part of the coreboot project.
4 * Copyright (C) 2012 secunet Security Networks AG
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
16 #include <coreboot_tables.h>
17 #include <libpayload.h>
19 #include <curses.h>
20 #include <form.h>
21 #include <menu.h>
23 #ifndef HOSTED
24 #define HOSTED 0
25 #endif
27 static int min(int x, int y)
29 if (x < y)
30 return x;
31 return y;
34 static int max(int x, int y)
36 if (x > y)
37 return x;
38 return y;
41 void render_form(FORM *form)
43 int y, x, line;
44 WINDOW *w = form_win(form);
45 WINDOW *inner_w = form_sub(form);
46 int numlines = getmaxy(w) - 2;
47 getyx(inner_w, y, x);
48 line = y - (y % numlines);
49 WINDOW *der = derwin(w, getmaxy(w) - 2, getmaxx(w) - 2, 1, 1);
50 wclear(der);
51 wrefresh(der);
52 delwin(der);
53 copywin(inner_w, w, line, 0, 1, 1,
54 min(numlines, getmaxy(inner_w) - line), 68, 0);
55 wmove(w, y + 1 - line, x + 1);
56 wrefresh(w);
59 /* determine number of options, and maximum option name length */
60 static int count_cmos_options(struct cb_cmos_entries *option, int *numopts,
61 int *maxlength)
63 int n_opts = 0;
64 int max_l = 0;
66 while (option) {
67 if ((option->config != 'r') &&
68 (strcmp("check_sum", (char *)option->name) != 0)) {
69 max_l = max(max_l, strlen((char *)option->name));
70 n_opts++;
73 option = next_cmos_entry(option);
76 if (n_opts == 0) {
77 printf("NO CMOS OPTIONS FOUND. EXITING!!!");
78 return -1;
81 *numopts = n_opts;
82 *maxlength = max_l;
84 return 0;
88 /* walk over options, fetch details */
89 static void cmos_walk_options(struct cb_cmos_option_table *opttbl,
90 FIELD **fields, int numopts, int maxlength)
92 struct cb_cmos_entries *option = first_cmos_entry(opttbl);
93 int i;
95 for (i = 0; i < numopts; i++) {
96 while ((option->config == 'r') ||
97 (strcmp("check_sum", (char *)option->name) == 0)) {
98 option = next_cmos_entry(option);
100 fields[2 * i] =
101 new_field(1, strlen((char *)option->name), i * 2, 1, 0, 0);
102 set_field_buffer(fields[2 * i], 0, (char *)option->name);
103 field_opts_off(fields[2 * i], O_ACTIVE);
105 fields[2 * i + 1] =
106 new_field(1, 40, i * 2, maxlength + 2, 0, 0);
107 char *buf = NULL;
108 int fail =
109 get_option_as_string(use_nvram, opttbl, &buf, (char *)option->name);
110 switch (option->config) {
111 case 'h': {
112 set_field_type(fields[2 * i + 1], TYPE_INTEGER, 0, 0,
113 (1 << option->length) - 1);
114 field_opts_on(fields[2 * i + 1], O_BLANK);
115 break;
117 case 's': {
118 set_max_field(fields[2 * i + 1], option->length / 8);
119 field_opts_off(fields[2 * i + 1], O_STATIC);
120 break;
122 case 'e': {
123 int numvals = 0;
124 struct cb_cmos_enums *cmos_enum =
125 first_cmos_enum_of_id(opttbl, option->config_id);
127 /* if invalid data in CMOS, set buf to first enum */
128 if (fail && cmos_enum) {
129 buf = (char *)cmos_enum->text;
132 while (cmos_enum) {
133 numvals++;
134 cmos_enum = next_cmos_enum_of_id(
135 cmos_enum, option->config_id);
138 char **values = malloc(sizeof(char *) * (numvals + 1));
139 int cnt = 0;
141 cmos_enum =
142 first_cmos_enum_of_id(opttbl, option->config_id);
143 while (cmos_enum) {
144 values[cnt] = (char *)cmos_enum->text;
145 cnt++;
146 cmos_enum = next_cmos_enum_of_id(
147 cmos_enum, option->config_id);
149 values[cnt] = NULL;
150 field_opts_off(fields[2 * i + 1], O_EDIT);
151 set_field_type(fields[2 * i + 1], TYPE_ENUM, values, 1,
153 free(values); // copied by set_field_type
154 break;
156 default:
157 break;
159 if (buf)
160 set_field_buffer(fields[2 * i + 1], 0, buf);
161 #if HOSTED
162 // underline is non-trivial on VGA text
163 set_field_back(fields[2 * i + 1], A_UNDERLINE);
164 #endif
165 field_opts_off(fields[2 * i + 1],
166 O_BLANK | O_AUTOSKIP | O_NULLOK);
168 option = next_cmos_entry(option);
171 fields[2 * numopts] = NULL;
174 int main(void)
176 int ch, done;
177 int i;
179 if (IS_ENABLED(CONFIG_LP_USB))
180 usb_initialize();
182 /* coreboot data structures */
183 lib_get_sysinfo();
185 struct cb_cmos_option_table *opttbl = get_system_option_table();
187 if (opttbl == NULL) {
188 printf("Could not find coreboot option table.\n");
189 halt();
192 /* prep CMOS layout into libcurses data structures */
194 struct cb_cmos_entries *option = first_cmos_entry(opttbl);
195 int numopts = 0;
196 int maxlength = 0;
198 count_cmos_options(option, &numopts, &maxlength);
200 FIELD **fields = malloc(sizeof(FIELD *) * (2 * numopts + 1));
202 cmos_walk_options(opttbl, fields, numopts, maxlength);
204 /* display initialization */
205 initscr();
206 keypad(stdscr, TRUE);
207 cbreak();
208 noecho();
210 if (start_color()) {
211 assume_default_colors(COLOR_BLUE, COLOR_CYAN);
213 leaveok(stdscr, TRUE);
214 curs_set(1);
216 erase();
217 box(stdscr, 0, 0);
218 mvaddstr(0, 2, "coreboot configuration utility");
219 refresh();
221 FORM *form = new_form(fields);
222 int numlines = min(numopts * 2, 16);
223 WINDOW *w = newwin(numlines + 2, 70, 2, 1);
224 WINDOW *inner_w = newpad(numopts * 2, 68);
225 box(w, 0, 0);
226 mvwaddstr(w, 0, 2, "Press F1 when done");
227 set_form_win(form, w);
228 set_form_sub(form, inner_w);
229 post_form(form);
231 done = 0;
232 while (!done) {
233 render_form(form);
234 ch = getch();
235 if (ch == ERR)
236 continue;
237 switch (ch) {
238 case KEY_DOWN:
239 form_driver(form, REQ_NEXT_FIELD);
240 break;
241 case KEY_UP:
242 form_driver(form, REQ_PREV_FIELD);
243 break;
244 case KEY_LEFT:
245 if (field_type(current_field(form)) == TYPE_ENUM) {
246 form_driver(form, REQ_PREV_CHOICE);
247 } else {
248 form_driver(form, REQ_LEFT_CHAR);
250 break;
251 case KEY_RIGHT:
252 if (field_type(current_field(form)) == TYPE_ENUM) {
253 form_driver(form, REQ_NEXT_CHOICE);
254 } else {
255 form_driver(form, REQ_RIGHT_CHAR);
257 break;
258 case KEY_BACKSPACE:
259 case '\b':
260 form_driver(form, REQ_DEL_PREV);
261 break;
262 case KEY_DC:
263 form_driver(form, REQ_DEL_CHAR);
264 break;
265 case KEY_F(1):
266 done = 1;
267 break;
268 default:
269 form_driver(form, ch);
270 break;
274 endwin();
276 for (i = 0; i < numopts; i++) {
277 char *name = field_buffer(fields[2 * i], 0);
278 char *value = field_buffer(fields[2 * i + 1], 0);
279 char *ptr;
280 for (ptr = value + strlen(value) - 1;
281 ptr >= value && *ptr == ' '; ptr--)
283 ptr[1] = '\0';
284 set_option_from_string(use_nvram, opttbl, value, name);
287 unpost_form(form);
288 free_form(form);
290 /* reboot */
291 outb(0x6, 0xcf9);
292 halt();