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,
53 min(numlines
, getmaxy(inner_w
) - line
), 68, 0);
54 wmove(w
, y
+ 1 - line
, x
+ 1);
58 /* determine number of options, and maximum option name length */
59 static int count_cmos_options(struct cb_cmos_entries
*option
, int *numopts
,
66 if ((option
->config
!= 'r') &&
67 (strcmp("check_sum", (char *)option
->name
) != 0)) {
68 max_l
= max(max_l
, strlen((char *)option
->name
));
72 option
= next_cmos_entry(option
);
76 printf("NO CMOS OPTIONS FOUND. EXITING!!!");
87 /* walk over options, fetch details */
88 static void cmos_walk_options(struct cb_cmos_option_table
*opttbl
,
89 FIELD
**fields
, int numopts
, int maxlength
)
91 struct cb_cmos_entries
*option
= first_cmos_entry(opttbl
);
94 for (i
= 0; i
< numopts
; i
++) {
95 while ((option
->config
== 'r') ||
96 (strcmp("check_sum", (char *)option
->name
) == 0)) {
97 option
= next_cmos_entry(option
);
100 new_field(1, strlen((char *)option
->name
), i
* 2, 1, 0, 0);
101 set_field_buffer(fields
[2 * i
], 0, (char *)option
->name
);
102 field_opts_off(fields
[2 * i
], O_ACTIVE
);
105 new_field(1, 40, i
* 2, maxlength
+ 2, 0, 0);
108 get_option_as_string(use_nvram
, opttbl
, &buf
, (char *)option
->name
);
109 switch (option
->config
) {
111 set_field_type(fields
[2 * i
+ 1], TYPE_INTEGER
, 0, 0,
112 (1 << option
->length
) - 1);
113 field_opts_on(fields
[2 * i
+ 1], O_BLANK
);
117 set_max_field(fields
[2 * i
+ 1], option
->length
/ 8);
118 field_opts_off(fields
[2 * i
+ 1], O_STATIC
);
123 struct cb_cmos_enums
*cmos_enum
=
124 first_cmos_enum_of_id(opttbl
, option
->config_id
);
126 /* if invalid data in CMOS, set buf to first enum */
127 if (fail
&& cmos_enum
) {
128 buf
= (char *)cmos_enum
->text
;
133 cmos_enum
= next_cmos_enum_of_id(
134 cmos_enum
, option
->config_id
);
137 char **values
= malloc(sizeof(char *) * (numvals
+ 1));
141 first_cmos_enum_of_id(opttbl
, option
->config_id
);
143 values
[cnt
] = (char *)cmos_enum
->text
;
145 cmos_enum
= next_cmos_enum_of_id(
146 cmos_enum
, option
->config_id
);
149 field_opts_off(fields
[2 * i
+ 1], O_EDIT
);
150 set_field_type(fields
[2 * i
+ 1], TYPE_ENUM
, values
, 1,
152 free(values
); // copied by set_field_type
159 set_field_buffer(fields
[2 * i
+ 1], 0, buf
);
161 // underline is non-trivial on VGA text
162 set_field_back(fields
[2 * i
+ 1], A_UNDERLINE
);
164 field_opts_off(fields
[2 * i
+ 1],
165 O_BLANK
| O_AUTOSKIP
| O_NULLOK
);
167 option
= next_cmos_entry(option
);
170 fields
[2 * numopts
] = NULL
;
181 /* coreboot data structures */
184 struct cb_cmos_option_table
*opttbl
= get_system_option_table();
186 if (opttbl
== NULL
) {
187 printf("Could not find coreboot option table.\n");
191 /* prep CMOS layout into libcurses data structures */
193 struct cb_cmos_entries
*option
= first_cmos_entry(opttbl
);
197 count_cmos_options(option
, &numopts
, &maxlength
);
199 FIELD
**fields
= malloc(sizeof(FIELD
*) * (2 * numopts
+ 1));
201 cmos_walk_options(opttbl
, fields
, numopts
, maxlength
);
203 /* display initialization */
205 keypad(stdscr
, TRUE
);
210 assume_default_colors(COLOR_BLUE
, COLOR_CYAN
);
212 leaveok(stdscr
, TRUE
);
217 mvaddstr(0, 2, "coreboot configuration utility");
220 FORM
*form
= new_form(fields
);
221 int numlines
= min(numopts
* 2, 16);
222 WINDOW
*w
= newwin(numlines
+ 2, 70, 2, 1);
223 WINDOW
*inner_w
= newpad(numopts
* 2, 68);
225 mvwaddstr(w
, 0, 2, "Press F1 when done");
226 set_form_win(form
, w
);
227 set_form_sub(form
, inner_w
);
238 form_driver(form
, REQ_NEXT_FIELD
);
241 form_driver(form
, REQ_PREV_FIELD
);
244 if (field_type(current_field(form
)) == TYPE_ENUM
) {
245 form_driver(form
, REQ_PREV_CHOICE
);
247 form_driver(form
, REQ_LEFT_CHAR
);
251 if (field_type(current_field(form
)) == TYPE_ENUM
) {
252 form_driver(form
, REQ_NEXT_CHOICE
);
254 form_driver(form
, REQ_RIGHT_CHAR
);
259 form_driver(form
, REQ_DEL_PREV
);
262 form_driver(form
, REQ_DEL_CHAR
);
268 form_driver(form
, ch
);
275 for (i
= 0; i
< numopts
; i
++) {
276 char *name
= field_buffer(fields
[2 * i
], 0);
277 char *value
= field_buffer(fields
[2 * i
+ 1], 0);
279 for (ptr
= value
+ strlen(value
) - 1;
280 ptr
>= value
&& *ptr
== ' '; ptr
--)
283 set_option_from_string(use_nvram
, opttbl
, value
, name
);