mirror of
https://github.com/u-boot/u-boot.git
synced 2025-04-22 12:54:37 +00:00
x86: coreboot: Allow building an expo for editing CMOS config
Coreboot provides the CMOS layout in the tables it passes to U-Boot. Use that to build an editor for the CMOS settings. Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
parent
e25c34ddb5
commit
ae3b5928d6
9 changed files with 405 additions and 1 deletions
|
@ -59,6 +59,9 @@ obj-$(CONFIG_$(PHASE_)LOAD_FIT) += common_fit.o
|
||||||
|
|
||||||
obj-$(CONFIG_$(PHASE_)EXPO) += expo.o scene.o expo_build.o
|
obj-$(CONFIG_$(PHASE_)EXPO) += expo.o scene.o expo_build.o
|
||||||
obj-$(CONFIG_$(PHASE_)EXPO) += scene_menu.o scene_textline.o
|
obj-$(CONFIG_$(PHASE_)EXPO) += scene_menu.o scene_textline.o
|
||||||
|
ifdef CONFIG_COREBOOT_SYSINFO
|
||||||
|
obj-$(CONFIG_$(SPL_TPL_)EXPO) += expo_build_cb.o
|
||||||
|
endif
|
||||||
|
|
||||||
obj-$(CONFIG_$(PHASE_)BOOTMETH_VBE) += vbe.o
|
obj-$(CONFIG_$(PHASE_)BOOTMETH_VBE) += vbe.o
|
||||||
obj-$(CONFIG_$(PHASE_)BOOTMETH_VBE_REQUEST) += vbe_request.o
|
obj-$(CONFIG_$(PHASE_)BOOTMETH_VBE_REQUEST) += vbe_request.o
|
||||||
|
|
245
boot/expo_build_cb.c
Normal file
245
boot/expo_build_cb.c
Normal file
|
@ -0,0 +1,245 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0+
|
||||||
|
/*
|
||||||
|
* Building an expo from an FDT description
|
||||||
|
*
|
||||||
|
* Copyright 2022 Google LLC
|
||||||
|
* Written by Simon Glass <sjg@chromium.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define LOG_CATEGORY LOGC_EXPO
|
||||||
|
|
||||||
|
#include <cedit.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <expo.h>
|
||||||
|
#include <log.h>
|
||||||
|
#include <malloc.h>
|
||||||
|
#include <vsprintf.h>
|
||||||
|
#include <asm/cb_sysinfo.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct build_info - Information to use when building
|
||||||
|
*/
|
||||||
|
struct build_info {
|
||||||
|
const struct cb_cmos_option_table *tab;
|
||||||
|
struct cedit_priv *priv;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* convert_to_title() - Convert text to 'title' format and allocate a string
|
||||||
|
*
|
||||||
|
* Converts "this_is_a_test" to "This is a test" so it looks better
|
||||||
|
*
|
||||||
|
* @text: Text to convert
|
||||||
|
* Return: Allocated string, or NULL if out of memory
|
||||||
|
*/
|
||||||
|
static char *convert_to_title(const char *text)
|
||||||
|
{
|
||||||
|
int len = strlen(text);
|
||||||
|
char *buf, *s;
|
||||||
|
|
||||||
|
buf = malloc(len + 1);
|
||||||
|
if (!buf)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
for (s = buf; *text; s++, text++) {
|
||||||
|
if (s == buf)
|
||||||
|
*s = toupper(*text);
|
||||||
|
else if (*text == '_')
|
||||||
|
*s = ' ';
|
||||||
|
else
|
||||||
|
*s = *text;
|
||||||
|
}
|
||||||
|
*s = '\0';
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* menu_build() - Build a menu and add it to a scene
|
||||||
|
*
|
||||||
|
* See doc/developer/expo.rst for a description of the format
|
||||||
|
*
|
||||||
|
* @info: Build information
|
||||||
|
* @entry: CMOS entry to build a menu for
|
||||||
|
* @scn: Scene to add the menu to
|
||||||
|
* @objp: Returns the object pointer
|
||||||
|
* Returns: 0 if OK, -ENOMEM if out of memory, -EINVAL if there is a format
|
||||||
|
* error, -ENOENT if there is a references to a non-existent string
|
||||||
|
*/
|
||||||
|
static int menu_build(struct build_info *info,
|
||||||
|
const struct cb_cmos_entries *entry, struct scene *scn,
|
||||||
|
struct scene_obj **objp)
|
||||||
|
{
|
||||||
|
struct scene_obj_menu *menu;
|
||||||
|
const void *ptr, *end;
|
||||||
|
uint menu_id;
|
||||||
|
char *title;
|
||||||
|
int ret, i;
|
||||||
|
|
||||||
|
ret = scene_menu(scn, entry->name, 0, &menu);
|
||||||
|
if (ret < 0)
|
||||||
|
return log_msg_ret("men", ret);
|
||||||
|
menu_id = ret;
|
||||||
|
|
||||||
|
title = convert_to_title(entry->name);
|
||||||
|
if (!title)
|
||||||
|
return log_msg_ret("con", -ENOMEM);
|
||||||
|
|
||||||
|
/* Set the title */
|
||||||
|
ret = scene_txt_str(scn, "title", 0, 0, title, NULL);
|
||||||
|
if (ret < 0)
|
||||||
|
return log_msg_ret("tit", ret);
|
||||||
|
menu->title_id = ret;
|
||||||
|
|
||||||
|
end = (void *)info->tab + info->tab->size;
|
||||||
|
for (ptr = (void *)info->tab + info->tab->header_length, i = 0;
|
||||||
|
ptr < end; i++) {
|
||||||
|
const struct cb_cmos_enums *enums = ptr;
|
||||||
|
struct scene_menitem *item;
|
||||||
|
uint label;
|
||||||
|
|
||||||
|
ptr += enums->size;
|
||||||
|
if (enums->tag != CB_TAG_OPTION_ENUM ||
|
||||||
|
enums->config_id != entry->config_id)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ret = scene_txt_str(scn, enums->text, 0, 0, enums->text, NULL);
|
||||||
|
if (ret < 0)
|
||||||
|
return log_msg_ret("tit", ret);
|
||||||
|
label = ret;
|
||||||
|
|
||||||
|
ret = scene_menuitem(scn, menu_id, simple_xtoa(i), 0, 0, label,
|
||||||
|
0, 0, 0, &item);
|
||||||
|
if (ret < 0)
|
||||||
|
return log_msg_ret("mi", ret);
|
||||||
|
item->value = enums->value;
|
||||||
|
}
|
||||||
|
*objp = &menu->obj;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* scene_build() - Build a scene and all its objects
|
||||||
|
*
|
||||||
|
* See doc/developer/expo.rst for a description of the format
|
||||||
|
*
|
||||||
|
* @info: Build information
|
||||||
|
* @scn: Scene to add the object to
|
||||||
|
* Returns: 0 if OK, -ENOMEM if out of memory, -EINVAL if there is a format
|
||||||
|
* error, -ENOENT if there is a references to a non-existent string
|
||||||
|
*/
|
||||||
|
static int scene_build(struct build_info *info, struct expo *exp)
|
||||||
|
{
|
||||||
|
struct scene_obj_menu *menu;
|
||||||
|
const void *ptr, *end;
|
||||||
|
struct scene_obj *obj;
|
||||||
|
struct scene *scn;
|
||||||
|
uint label, menu_id;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = scene_new(exp, "cmos", 0, &scn);
|
||||||
|
if (ret < 0)
|
||||||
|
return log_msg_ret("scn", ret);
|
||||||
|
|
||||||
|
ret = scene_txt_str(scn, "title", 0, 0, "CMOS RAM settings", NULL);
|
||||||
|
if (ret < 0)
|
||||||
|
return log_msg_ret("add", ret);
|
||||||
|
scn->title_id = ret;
|
||||||
|
|
||||||
|
ret = scene_txt_str(scn, "prompt", 0, 0,
|
||||||
|
"UP and DOWN to choose, ENTER to select", NULL);
|
||||||
|
if (ret < 0)
|
||||||
|
return log_msg_ret("add", ret);
|
||||||
|
|
||||||
|
end = (void *)info->tab + info->tab->size;
|
||||||
|
for (ptr = (void *)info->tab + info->tab->header_length; ptr < end;) {
|
||||||
|
const struct cb_cmos_entries *entry;
|
||||||
|
const struct cb_record *rec = ptr;
|
||||||
|
|
||||||
|
entry = ptr;
|
||||||
|
ptr += rec->size;
|
||||||
|
if (rec->tag != CB_TAG_OPTION)
|
||||||
|
continue;
|
||||||
|
switch (entry->config) {
|
||||||
|
case 'e':
|
||||||
|
ret = menu_build(info, entry, scn, &obj);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (ret < 0)
|
||||||
|
return log_msg_ret("add", ret);
|
||||||
|
|
||||||
|
obj->start_bit = entry->bit;
|
||||||
|
obj->bit_length = entry->length;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = scene_menu(scn, "save", EXPOID_SAVE, &menu);
|
||||||
|
if (ret < 0)
|
||||||
|
return log_msg_ret("men", ret);
|
||||||
|
menu_id = ret;
|
||||||
|
|
||||||
|
ret = scene_txt_str(scn, "save", 0, 0, "Save and exit", NULL);
|
||||||
|
if (ret < 0)
|
||||||
|
return log_msg_ret("sav", ret);
|
||||||
|
label = ret;
|
||||||
|
ret = scene_menuitem(scn, menu_id, "save", 0, 0, label,
|
||||||
|
0, 0, 0, NULL);
|
||||||
|
if (ret < 0)
|
||||||
|
return log_msg_ret("mi", ret);
|
||||||
|
|
||||||
|
ret = scene_menu(scn, "nosave", EXPOID_DISCARD, &menu);
|
||||||
|
if (ret < 0)
|
||||||
|
return log_msg_ret("men", ret);
|
||||||
|
menu_id = ret;
|
||||||
|
|
||||||
|
ret = scene_txt_str(scn, "nosave", 0, 0, "Exit without saving", NULL);
|
||||||
|
if (ret < 0)
|
||||||
|
return log_msg_ret("nos", ret);
|
||||||
|
label = ret;
|
||||||
|
ret = scene_menuitem(scn, menu_id, "exit", 0, 0, label,
|
||||||
|
0, 0, 0, NULL);
|
||||||
|
if (ret < 0)
|
||||||
|
return log_msg_ret("mi", ret);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int build_it(struct build_info *info, struct expo **expp)
|
||||||
|
{
|
||||||
|
struct expo *exp;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = expo_new("coreboot", NULL, &exp);
|
||||||
|
if (ret)
|
||||||
|
return log_msg_ret("exp", ret);
|
||||||
|
expo_set_dynamic_start(exp, EXPOID_BASE_ID);
|
||||||
|
|
||||||
|
ret = scene_build(info, exp);
|
||||||
|
if (ret < 0)
|
||||||
|
return log_msg_ret("scn", ret);
|
||||||
|
|
||||||
|
*expp = exp;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cb_expo_build(struct expo **expp)
|
||||||
|
{
|
||||||
|
struct build_info info;
|
||||||
|
struct expo *exp;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
info.tab = lib_sysinfo.option_table;
|
||||||
|
if (!info.tab)
|
||||||
|
return log_msg_ret("tab", -ENOENT);
|
||||||
|
|
||||||
|
ret = build_it(&info, &exp);
|
||||||
|
if (ret)
|
||||||
|
return log_msg_ret("bui", ret);
|
||||||
|
*expp = exp;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
28
cmd/cedit.c
28
cmd/cedit.c
|
@ -67,6 +67,28 @@ static int do_cedit_load(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_COREBOOT_SYSINFO
|
||||||
|
static int do_cedit_cb_load(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||||
|
char *const argv[])
|
||||||
|
{
|
||||||
|
struct expo *exp;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (argc > 1)
|
||||||
|
return CMD_RET_USAGE;
|
||||||
|
|
||||||
|
ret = cb_expo_build(&exp);
|
||||||
|
if (ret) {
|
||||||
|
printf("Failed to build expo: %dE\n", ret);
|
||||||
|
return CMD_RET_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
cur_exp = exp;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_COREBOOT_SYSINFO */
|
||||||
|
|
||||||
static int do_cedit_write_fdt(struct cmd_tbl *cmdtp, int flag, int argc,
|
static int do_cedit_write_fdt(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||||
char *const argv[])
|
char *const argv[])
|
||||||
{
|
{
|
||||||
|
@ -271,6 +293,9 @@ static int do_cedit_run(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||||
|
|
||||||
U_BOOT_LONGHELP(cedit,
|
U_BOOT_LONGHELP(cedit,
|
||||||
"load <interface> <dev[:part]> <filename> - load config editor\n"
|
"load <interface> <dev[:part]> <filename> - load config editor\n"
|
||||||
|
#ifdef CONFIG_COREBOOT_SYSINFO
|
||||||
|
"cb_load - load coreboot CMOS editor\n"
|
||||||
|
#endif
|
||||||
"cedit read_fdt <i/f> <dev[:part]> <filename> - read settings\n"
|
"cedit read_fdt <i/f> <dev[:part]> <filename> - read settings\n"
|
||||||
"cedit write_fdt <i/f> <dev[:part]> <filename> - write settings\n"
|
"cedit write_fdt <i/f> <dev[:part]> <filename> - write settings\n"
|
||||||
"cedit read_env [-v] - read settings from env vars\n"
|
"cedit read_env [-v] - read settings from env vars\n"
|
||||||
|
@ -281,6 +306,9 @@ U_BOOT_LONGHELP(cedit,
|
||||||
|
|
||||||
U_BOOT_CMD_WITH_SUBCMDS(cedit, "Configuration editor", cedit_help_text,
|
U_BOOT_CMD_WITH_SUBCMDS(cedit, "Configuration editor", cedit_help_text,
|
||||||
U_BOOT_SUBCMD_MKENT(load, 5, 1, do_cedit_load),
|
U_BOOT_SUBCMD_MKENT(load, 5, 1, do_cedit_load),
|
||||||
|
#ifdef CONFIG_COREBOOT_SYSINFO
|
||||||
|
U_BOOT_SUBCMD_MKENT(cb_load, 5, 1, do_cedit_cb_load),
|
||||||
|
#endif
|
||||||
U_BOOT_SUBCMD_MKENT(read_fdt, 5, 1, do_cedit_read_fdt),
|
U_BOOT_SUBCMD_MKENT(read_fdt, 5, 1, do_cedit_read_fdt),
|
||||||
U_BOOT_SUBCMD_MKENT(write_fdt, 5, 1, do_cedit_write_fdt),
|
U_BOOT_SUBCMD_MKENT(write_fdt, 5, 1, do_cedit_write_fdt),
|
||||||
U_BOOT_SUBCMD_MKENT(read_env, 2, 1, do_cedit_read_env),
|
U_BOOT_SUBCMD_MKENT(read_env, 2, 1, do_cedit_read_env),
|
||||||
|
|
|
@ -182,3 +182,9 @@ CI runs tests using a pre-built coreboot image. This ensures that U-Boot can
|
||||||
boot as a coreboot payload, based on a known-good build of coreboot.
|
boot as a coreboot payload, based on a known-good build of coreboot.
|
||||||
|
|
||||||
To update the `coreboot.rom` file which is used, see ``tools/Dockerfile``
|
To update the `coreboot.rom` file which is used, see ``tools/Dockerfile``
|
||||||
|
|
||||||
|
Editing CMOS RAM settings
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
U-Boot supports creating a configuration editor to edit coreboot CMOS-RAM
|
||||||
|
settings. See :ref:`cedit_cb_load`.
|
||||||
|
|
|
@ -172,4 +172,4 @@ Cedit provides several options for persistent settings:
|
||||||
|
|
||||||
For now, reading and writing settings is not automatic. See the
|
For now, reading and writing settings is not automatic. See the
|
||||||
:doc:`../usage/cmd/cedit` for how to do this on the command line or in a
|
:doc:`../usage/cmd/cedit` for how to do this on the command line or in a
|
||||||
script.
|
script. For x86 devices, see :ref:`cedit_cb_load`.
|
||||||
|
|
|
@ -40,3 +40,6 @@ CMOS RAM::
|
||||||
Checksum 6600 written
|
Checksum 6600 written
|
||||||
=> cbc check
|
=> cbc check
|
||||||
=>
|
=>
|
||||||
|
|
||||||
|
See also :ref:`cedit_cb_load` which shows an example that includes the
|
||||||
|
configuration editor.
|
||||||
|
|
|
@ -18,6 +18,7 @@ Synopsis
|
||||||
cedit write_env [-v]
|
cedit write_env [-v]
|
||||||
cedit read_env [-v]
|
cedit read_env [-v]
|
||||||
cedit write_cmos [-v] [dev]
|
cedit write_cmos [-v] [dev]
|
||||||
|
cedit cb_load
|
||||||
|
|
||||||
Description
|
Description
|
||||||
-----------
|
-----------
|
||||||
|
@ -92,6 +93,13 @@ updated.
|
||||||
Normally the first RTC device is used to hold the data. You can specify a
|
Normally the first RTC device is used to hold the data. You can specify a
|
||||||
different device by name using the `dev` parameter.
|
different device by name using the `dev` parameter.
|
||||||
|
|
||||||
|
.. _cedit_cb_load:
|
||||||
|
|
||||||
|
cedit cb_load
|
||||||
|
~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
This is supported only on x86 devices booted from coreboot. It creates a new
|
||||||
|
configuration editor which can be used to edit CMOS settings.
|
||||||
|
|
||||||
Example
|
Example
|
||||||
-------
|
-------
|
||||||
|
@ -158,3 +166,71 @@ Here is an example with the device specified::
|
||||||
|
|
||||||
=> cedit write_cmos rtc@43
|
=> cedit write_cmos rtc@43
|
||||||
=>
|
=>
|
||||||
|
|
||||||
|
This example shows editing coreboot CMOS-RAM settings. A script could be used
|
||||||
|
to automate this::
|
||||||
|
|
||||||
|
=> cbsysinfo
|
||||||
|
Coreboot table at 500, size 5c4, records 1d (dec 29), decoded to 000000007dce3f40, forwarded to 000000007ff9a000
|
||||||
|
|
||||||
|
CPU KHz : 0
|
||||||
|
Serial I/O port: 00000000
|
||||||
|
base : 00000000
|
||||||
|
pointer : 000000007ff9a370
|
||||||
|
type : 1
|
||||||
|
base : 000003f8
|
||||||
|
baud : 0d115200
|
||||||
|
regwidth : 1
|
||||||
|
input_hz : 0d1843200
|
||||||
|
PCI addr : 00000010
|
||||||
|
Mem ranges : 7
|
||||||
|
id: type || base || size
|
||||||
|
0: 10:table 0000000000000000 0000000000001000
|
||||||
|
1: 01:ram 0000000000001000 000000000009f000
|
||||||
|
2: 02:reserved 00000000000a0000 0000000000060000
|
||||||
|
3: 01:ram 0000000000100000 000000007fe6d000
|
||||||
|
4: 10:table 000000007ff6d000 0000000000093000
|
||||||
|
5: 02:reserved 00000000fec00000 0000000000001000
|
||||||
|
6: 02:reserved 00000000ff800000 0000000000800000
|
||||||
|
option_table: 000000007ff9a018
|
||||||
|
Bit Len Cfg ID Name
|
||||||
|
0 180 r 0 reserved_memory
|
||||||
|
180 1 e 4 boot_option 0:Fallback 1:Normal
|
||||||
|
184 4 h 0 reboot_counter
|
||||||
|
190 8 r 0 reserved_century
|
||||||
|
1b8 8 r 0 reserved_ibm_ps2_century
|
||||||
|
1c0 1 e 1 power_on_after_fail 0:Disable 1:Enable
|
||||||
|
1c4 4 e 6 debug_level 5:Notice 6:Info 7:Debug 8:Spew
|
||||||
|
1d0 80 r 0 vbnv
|
||||||
|
3f0 10 h 0 check_sum
|
||||||
|
CMOS start : 1c0
|
||||||
|
CMOS end : 1cf
|
||||||
|
CMOS csum loc: 3f0
|
||||||
|
VBNV start : ffffffff
|
||||||
|
VBNV size : ffffffff
|
||||||
|
...
|
||||||
|
Unimpl. : 10 37 40
|
||||||
|
|
||||||
|
Check that the CMOS RAM checksum is correct, then create a configuration editor
|
||||||
|
and load the settings from CMOS RAM::
|
||||||
|
|
||||||
|
=> cbcmos check
|
||||||
|
=> cedit cb
|
||||||
|
=> cedit read_cmos
|
||||||
|
|
||||||
|
Now run the cedit. In this case the user selected 'save' so `cedit run` returns
|
||||||
|
success::
|
||||||
|
|
||||||
|
=> if cedit run; then cedit write_cmos -v; fi
|
||||||
|
Write 2 bytes from offset 30 to 38
|
||||||
|
=> echo $?
|
||||||
|
0
|
||||||
|
|
||||||
|
Update the checksum in CMOS RAM::
|
||||||
|
|
||||||
|
=> cbcmos check
|
||||||
|
Checksum 6100 error: calculated 7100
|
||||||
|
=> cbcmos update
|
||||||
|
Checksum 7100 written
|
||||||
|
=> cbcmos check
|
||||||
|
=>
|
||||||
|
|
|
@ -762,4 +762,12 @@ int expo_apply_theme(struct expo *exp, ofnode node);
|
||||||
*/
|
*/
|
||||||
int expo_build(ofnode root, struct expo **expp);
|
int expo_build(ofnode root, struct expo **expp);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cb_expo_build() - Build an expo for coreboot CMOS RAM
|
||||||
|
*
|
||||||
|
* @expp: Returns the expo created
|
||||||
|
* Return: 0 if OK, -ve on error
|
||||||
|
*/
|
||||||
|
int cb_expo_build(struct expo **expp);
|
||||||
|
|
||||||
#endif /*__EXPO_H */
|
#endif /*__EXPO_H */
|
||||||
|
|
|
@ -6,12 +6,16 @@
|
||||||
* Written by Simon Glass <sjg@chromium.org>
|
* Written by Simon Glass <sjg@chromium.org>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <cedit.h>
|
||||||
#include <command.h>
|
#include <command.h>
|
||||||
#include <dm.h>
|
#include <dm.h>
|
||||||
|
#include <expo.h>
|
||||||
#include <rtc.h>
|
#include <rtc.h>
|
||||||
|
#include <test/cedit-test.h>
|
||||||
#include <test/cmd.h>
|
#include <test/cmd.h>
|
||||||
#include <test/test.h>
|
#include <test/test.h>
|
||||||
#include <test/ut.h>
|
#include <test/ut.h>
|
||||||
|
#include "../../boot/scene_internal.h"
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
CSUM_LOC = 0x3f0 / 8,
|
CSUM_LOC = 0x3f0 / 8,
|
||||||
|
@ -82,3 +86,34 @@ static int test_cmd_cbcmos(struct unit_test_state *uts)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
CMD_TEST(test_cmd_cbcmos, UTF_CONSOLE);
|
CMD_TEST(test_cmd_cbcmos, UTF_CONSOLE);
|
||||||
|
|
||||||
|
/* test 'cedit cb_load' command */
|
||||||
|
static int test_cmd_cedit_cb_load(struct unit_test_state *uts)
|
||||||
|
{
|
||||||
|
struct scene_obj_menu *menu;
|
||||||
|
struct video_priv *vid_priv;
|
||||||
|
struct scene_obj_txt *txt;
|
||||||
|
struct scene *scn;
|
||||||
|
struct expo *exp;
|
||||||
|
int scn_id;
|
||||||
|
|
||||||
|
ut_assertok(run_command("cedit cb_load", 0));
|
||||||
|
ut_assertok(run_command("cedit read_cmos", 0));
|
||||||
|
ut_assert_console_end();
|
||||||
|
|
||||||
|
exp = cur_exp;
|
||||||
|
scn_id = cedit_prepare(exp, &vid_priv, &scn);
|
||||||
|
ut_assert(scn_id > 0);
|
||||||
|
ut_assertnonnull(scn);
|
||||||
|
|
||||||
|
/* just do a very basic test that the first menu is present */
|
||||||
|
menu = scene_obj_find(scn, scn->highlight_id, SCENEOBJT_NONE);
|
||||||
|
ut_assertnonnull(menu);
|
||||||
|
|
||||||
|
txt = scene_obj_find(scn, menu->title_id, SCENEOBJT_NONE);
|
||||||
|
ut_assertnonnull(txt);
|
||||||
|
ut_asserteq_str("Boot option", expo_get_str(exp, txt->str_id));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
CMD_TEST(test_cmd_cedit_cb_load, UTF_CONSOLE);
|
||||||
|
|
Loading…
Add table
Reference in a new issue