3 * Copyright (C) 2012 secunet Security Networks AG
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; version 2 of the License.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
15 #include <coreboot_tables.h>
16 #include <libpayload.h>
26 static int min(int x
, int y
)
33 static int max(int x
, int y
)
40 static void render_form(FORM
*form
)
43 WINDOW
*w
= form_win(form
);
44 WINDOW
*inner_w
= form_sub(form
);
45 int numlines
= getmaxy(w
) - 2;
47 line
= y
- (y
% numlines
);
48 WINDOW
*der
= derwin(w
, getmaxy(w
) - 2, getmaxx(w
) - 2, 1, 1);
52 copywin(inner_w
, w
, line
, 0, 1, 1, min(numlines
, getmaxy(inner_w
) - line
), 68, 0);
53 wmove(w
, y
+ 1 - line
, x
+ 1);
57 /* determine number of options, and maximum option name length */
58 static int count_cmos_options(struct cb_cmos_entries
*option
, int *numopts
, int *maxlength
)
64 if ((option
->config
!= 'r') && (strcmp("check_sum", (char *)option
->name
) != 0)) {
65 max_l
= max(max_l
, strlen((char *)option
->name
));
69 option
= next_cmos_entry(option
);
73 printf("NO CMOS OPTIONS FOUND. EXITING!!!");
83 /* walk over options, fetch details */
84 static void cmos_walk_options(struct cb_cmos_option_table
*opttbl
, FIELD
**fields
, int numopts
,
87 struct cb_cmos_entries
*option
= first_cmos_entry(opttbl
);
90 for (i
= 0; i
< numopts
; i
++) {
91 while ((option
->config
== 'r') ||
92 (strcmp("check_sum", (char *)option
->name
) == 0)) {
93 option
= next_cmos_entry(option
);
95 fields
[2 * i
] = new_field(1, strlen((char *)option
->name
), i
* 2, 1, 0, 0);
96 set_field_buffer(fields
[2 * i
], 0, (char *)option
->name
);
97 field_opts_off(fields
[2 * i
], O_ACTIVE
);
99 fields
[2 * i
+ 1] = new_field(1, 40, i
* 2, maxlength
+ 2, 0, 0);
101 int fail
= get_option_as_string(use_nvram
, opttbl
, &buf
, (char *)option
->name
);
102 switch (option
->config
) {
104 set_field_type(fields
[2 * i
+ 1], TYPE_INTEGER
, 0, 0,
105 (1 << option
->length
) - 1);
106 field_opts_on(fields
[2 * i
+ 1], O_BLANK
);
110 set_max_field(fields
[2 * i
+ 1], option
->length
/ 8);
111 field_opts_off(fields
[2 * i
+ 1], O_STATIC
);
116 struct cb_cmos_enums
*cmos_enum
=
117 first_cmos_enum_of_id(opttbl
, option
->config_id
);
119 /* if invalid data in CMOS, set buf to first enum */
120 if (fail
&& cmos_enum
) {
121 buf
= (char *)cmos_enum
->text
;
126 cmos_enum
= next_cmos_enum_of_id(cmos_enum
, option
->config_id
);
129 char **values
= malloc(sizeof(char *) * (numvals
+ 1));
133 first_cmos_enum_of_id(opttbl
, option
->config_id
);
135 values
[cnt
] = (char *)cmos_enum
->text
;
137 cmos_enum
= next_cmos_enum_of_id(cmos_enum
, option
->config_id
);
140 field_opts_off(fields
[2 * i
+ 1], O_EDIT
);
141 set_field_type(fields
[2 * i
+ 1], TYPE_ENUM
, values
, 1, 1);
142 free(values
); // copied by set_field_type
149 set_field_buffer(fields
[2 * i
+ 1], 0, buf
);
151 // underline is non-trivial on VGA text
152 set_field_back(fields
[2 * i
+ 1], A_UNDERLINE
);
154 field_opts_off(fields
[2 * i
+ 1], O_BLANK
| O_AUTOSKIP
| O_NULLOK
);
156 option
= next_cmos_entry(option
);
159 fields
[2 * numopts
] = NULL
;
170 /* coreboot data structures */
173 struct cb_cmos_option_table
*opttbl
= get_system_option_table();
175 if (opttbl
== NULL
) {
176 printf("Could not find coreboot option table.\n");
180 /* prep CMOS layout into libcurses data structures */
182 struct cb_cmos_entries
*option
= first_cmos_entry(opttbl
);
186 count_cmos_options(option
, &numopts
, &maxlength
);
188 FIELD
**fields
= malloc(sizeof(FIELD
*) * (2 * numopts
+ 1));
190 cmos_walk_options(opttbl
, fields
, numopts
, maxlength
);
192 /* display initialization */
194 keypad(stdscr
, TRUE
);
199 assume_default_colors(COLOR_BLUE
, COLOR_CYAN
);
201 leaveok(stdscr
, TRUE
);
206 mvaddstr(0, 2, "coreboot configuration utility");
209 FORM
*form
= new_form(fields
);
210 int numlines
= min(numopts
* 2, 16);
211 WINDOW
*w
= newwin(numlines
+ 2, 70, 2, 1);
212 WINDOW
*inner_w
= newpad(numopts
* 2, 68);
214 mvwaddstr(w
, 0, 2, "Press F1 when done");
215 set_form_win(form
, w
);
216 set_form_sub(form
, inner_w
);
227 form_driver(form
, REQ_NEXT_FIELD
);
230 form_driver(form
, REQ_PREV_FIELD
);
233 if (field_type(current_field(form
)) == TYPE_ENUM
) {
234 form_driver(form
, REQ_PREV_CHOICE
);
236 form_driver(form
, REQ_LEFT_CHAR
);
240 if (field_type(current_field(form
)) == TYPE_ENUM
) {
241 form_driver(form
, REQ_NEXT_CHOICE
);
243 form_driver(form
, REQ_RIGHT_CHAR
);
248 form_driver(form
, REQ_DEL_PREV
);
251 form_driver(form
, REQ_DEL_CHAR
);
257 form_driver(form
, ch
);
264 for (i
= 0; i
< numopts
; i
++) {
265 char *name
= field_buffer(fields
[2 * i
], 0);
266 char *value
= field_buffer(fields
[2 * i
+ 1], 0);
268 for (ptr
= value
+ strlen(value
) - 1;
269 ptr
>= value
&& *ptr
== ' '; ptr
--)
272 set_option_from_string(use_nvram
, opttbl
, value
, name
);