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>
27 static int min(int x
, int y
)
34 static int max(int x
, int y
)
41 void render_form(FORM
*form
)
44 WINDOW
*w
= form_win(form
);
45 WINDOW
*inner_w
= form_sub(form
);
46 int numlines
= getmaxy(w
) - 2;
48 line
= y
- (y
% numlines
);
49 WINDOW
*der
= derwin(w
, getmaxy(w
) - 2, getmaxx(w
) - 2, 1, 1);
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);
59 /* determine number of options, and maximum option name length */
60 static int count_cmos_options(struct cb_cmos_entries
*option
, int *numopts
,
67 if ((option
->config
!= 'r') &&
68 (strcmp("check_sum", (char *)option
->name
) != 0)) {
69 max_l
= max(max_l
, strlen((char *)option
->name
));
73 option
= next_cmos_entry(option
);
77 printf("NO CMOS OPTIONS FOUND. EXITING!!!");
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
);
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
);
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
);
106 new_field(1, 40, i
* 2, maxlength
+ 2, 0, 0);
109 get_option_as_string(use_nvram
, opttbl
, &buf
, (char *)option
->name
);
110 switch (option
->config
) {
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
);
118 set_max_field(fields
[2 * i
+ 1], option
->length
/ 8);
119 field_opts_off(fields
[2 * i
+ 1], O_STATIC
);
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
;
134 cmos_enum
= next_cmos_enum_of_id(
135 cmos_enum
, option
->config_id
);
138 char **values
= malloc(sizeof(char *) * (numvals
+ 1));
142 first_cmos_enum_of_id(opttbl
, option
->config_id
);
144 values
[cnt
] = (char *)cmos_enum
->text
;
146 cmos_enum
= next_cmos_enum_of_id(
147 cmos_enum
, option
->config_id
);
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
160 set_field_buffer(fields
[2 * i
+ 1], 0, buf
);
162 // underline is non-trivial on VGA text
163 set_field_back(fields
[2 * i
+ 1], A_UNDERLINE
);
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
;
179 if (IS_ENABLED(CONFIG_LP_USB
))
182 /* coreboot data structures */
185 struct cb_cmos_option_table
*opttbl
= get_system_option_table();
187 if (opttbl
== NULL
) {
188 printf("Could not find coreboot option table.\n");
192 /* prep CMOS layout into libcurses data structures */
194 struct cb_cmos_entries
*option
= first_cmos_entry(opttbl
);
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 */
206 keypad(stdscr
, TRUE
);
211 assume_default_colors(COLOR_BLUE
, COLOR_CYAN
);
213 leaveok(stdscr
, TRUE
);
218 mvaddstr(0, 2, "coreboot configuration utility");
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);
226 mvwaddstr(w
, 0, 2, "Press F1 when done");
227 set_form_win(form
, w
);
228 set_form_sub(form
, inner_w
);
239 form_driver(form
, REQ_NEXT_FIELD
);
242 form_driver(form
, REQ_PREV_FIELD
);
245 if (field_type(current_field(form
)) == TYPE_ENUM
) {
246 form_driver(form
, REQ_PREV_CHOICE
);
248 form_driver(form
, REQ_LEFT_CHAR
);
252 if (field_type(current_field(form
)) == TYPE_ENUM
) {
253 form_driver(form
, REQ_NEXT_CHOICE
);
255 form_driver(form
, REQ_RIGHT_CHAR
);
260 form_driver(form
, REQ_DEL_PREV
);
263 form_driver(form
, REQ_DEL_CHAR
);
269 form_driver(form
, ch
);
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);
280 for (ptr
= value
+ strlen(value
) - 1;
281 ptr
>= value
&& *ptr
== ' '; ptr
--)
284 set_option_from_string(use_nvram
, opttbl
, value
, name
);