mirror of
https://github.com/u-boot/u-boot.git
synced 2024-11-24 20:54:24 +08:00
expo: cedit: Support reading settings from CMOS RAM
Add a command to read edit settings from CMOS RAM, using the cedit definition to indicate which registers and bits are used. Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
parent
eb6c71b562
commit
cfc402db39
99
boot/cedit.c
99
boot/cedit.c
@ -39,6 +39,7 @@ enum {
|
||||
* @mask: Mask bits for the CMOS RAM. If a bit is set the byte containing it
|
||||
* will be written
|
||||
* @value: Value bits for CMOS RAM. This is the actual value written
|
||||
* @dev: RTC device to write to
|
||||
*/
|
||||
struct cedit_iter_priv {
|
||||
struct abuf *buf;
|
||||
@ -46,6 +47,7 @@ struct cedit_iter_priv {
|
||||
bool verbose;
|
||||
u8 *mask;
|
||||
u8 *value;
|
||||
struct udevice *dev;
|
||||
};
|
||||
|
||||
int cedit_arange(struct expo *exp, struct video_priv *vpriv, uint scene_id)
|
||||
@ -619,3 +621,100 @@ done:
|
||||
free(priv.value);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int h_read_settings_cmos(struct scene_obj *obj, void *vpriv)
|
||||
{
|
||||
struct cedit_iter_priv *priv = vpriv;
|
||||
const struct scene_menitem *mi;
|
||||
struct scene_obj_menu *menu;
|
||||
int val, ret;
|
||||
uint i;
|
||||
|
||||
if (obj->type != SCENEOBJT_MENU)
|
||||
return 0;
|
||||
|
||||
menu = (struct scene_obj_menu *)obj;
|
||||
|
||||
/* figure out where to place this item */
|
||||
if (!obj->bit_length)
|
||||
return log_msg_ret("len", -EINVAL);
|
||||
if (obj->start_bit + obj->bit_length > CMOS_MAX_BITS)
|
||||
return log_msg_ret("bit", -E2BIG);
|
||||
|
||||
val = 0;
|
||||
for (i = 0; i < obj->bit_length; i++) {
|
||||
uint bitnum = obj->start_bit + i;
|
||||
uint offset = CMOS_BYTE(bitnum);
|
||||
|
||||
/* read the byte if not already read */
|
||||
if (!priv->mask[offset]) {
|
||||
ret = rtc_read8(priv->dev, offset);
|
||||
if (ret < 0)
|
||||
return log_msg_ret("rea", ret);
|
||||
priv->value[offset] = ret;
|
||||
|
||||
/* mark it as read */
|
||||
priv->mask[offset] = 0xff;
|
||||
}
|
||||
|
||||
if (priv->value[offset] & BIT(CMOS_BIT(bitnum)))
|
||||
val |= BIT(i);
|
||||
log_debug("bit %x %x\n", bitnum, val);
|
||||
}
|
||||
|
||||
/* update the current item */
|
||||
mi = scene_menuitem_find_seq(menu, val);
|
||||
if (!mi)
|
||||
return log_msg_ret("seq", -ENOENT);
|
||||
|
||||
menu->cur_item_id = mi->id;
|
||||
log_debug("Update menu %d cur_item_id %d\n", menu->obj.id, mi->id);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cedit_read_settings_cmos(struct expo *exp, struct udevice *dev,
|
||||
bool verbose)
|
||||
{
|
||||
struct cedit_iter_priv priv;
|
||||
int ret, i, count, first, last;
|
||||
|
||||
/* read in the items */
|
||||
priv.mask = calloc(1, CMOS_MAX_BYTES);
|
||||
if (!priv.mask)
|
||||
return log_msg_ret("mas", -ENOMEM);
|
||||
priv.value = calloc(1, CMOS_MAX_BYTES);
|
||||
if (!priv.value) {
|
||||
free(priv.mask);
|
||||
return log_msg_ret("val", -ENOMEM);
|
||||
}
|
||||
priv.dev = dev;
|
||||
|
||||
ret = expo_iter_scene_objs(exp, h_read_settings_cmos, &priv);
|
||||
if (ret) {
|
||||
log_debug("Failed to read CMOS (err=%d)\n", ret);
|
||||
ret = log_msg_ret("set", ret);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* read the data to the RTC */
|
||||
first = CMOS_MAX_BYTES;
|
||||
last = -1;
|
||||
for (i = 0, count = 0; i < CMOS_MAX_BYTES; i++) {
|
||||
if (priv.mask[i]) {
|
||||
log_debug("Read byte %x: %x\n", i, priv.value[i]);
|
||||
count++;
|
||||
first = min(first, i);
|
||||
last = max(last, i);
|
||||
}
|
||||
}
|
||||
if (verbose) {
|
||||
printf("Read %d bytes from offset %x to %x\n", count, first,
|
||||
last);
|
||||
}
|
||||
|
||||
done:
|
||||
free(priv.mask);
|
||||
free(priv.value);
|
||||
return ret;
|
||||
}
|
||||
|
@ -234,4 +234,16 @@ int expo_iter_scene_objs(struct expo *exp, expo_scene_obj_iterator iter,
|
||||
struct scene_menitem *scene_menuitem_find(const struct scene_obj_menu *menu,
|
||||
int id);
|
||||
|
||||
/**
|
||||
* scene_menuitem_find_seq() - Find the menu item at a sequential position
|
||||
*
|
||||
* This numbers the items from 0 and returns the seq'th one
|
||||
*
|
||||
* @menu: Menu to check
|
||||
* @seq: Sequence number to look for
|
||||
* Return: menu item if found, else NULL
|
||||
*/
|
||||
struct scene_menitem *scene_menuitem_find_seq(const struct scene_obj_menu *menu,
|
||||
uint seq);
|
||||
|
||||
#endif /* __SCENE_INTERNAL_H */
|
||||
|
@ -46,6 +46,22 @@ struct scene_menitem *scene_menuitem_find(const struct scene_obj_menu *menu,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct scene_menitem *scene_menuitem_find_seq(const struct scene_obj_menu *menu,
|
||||
uint seq)
|
||||
{
|
||||
struct scene_menitem *item;
|
||||
uint i;
|
||||
|
||||
i = 0;
|
||||
list_for_each_entry(item, &menu->item_head, sibling) {
|
||||
if (i == seq)
|
||||
return item;
|
||||
i++;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* update_pointers() - Update the pointer object and handle highlights
|
||||
*
|
||||
|
36
cmd/cedit.c
36
cmd/cedit.c
@ -210,6 +210,40 @@ static int do_cedit_write_cmos(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_cedit_read_cmos(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||
char *const argv[])
|
||||
{
|
||||
struct udevice *dev;
|
||||
bool verbose = false;
|
||||
int ret;
|
||||
|
||||
if (check_cur_expo())
|
||||
return CMD_RET_FAILURE;
|
||||
|
||||
if (argc > 1 && !strcmp(argv[1], "-v")) {
|
||||
verbose = true;
|
||||
argc--;
|
||||
argv++;
|
||||
}
|
||||
|
||||
if (argc > 1)
|
||||
ret = uclass_get_device_by_name(UCLASS_RTC, argv[1], &dev);
|
||||
else
|
||||
ret = uclass_first_device_err(UCLASS_RTC, &dev);
|
||||
if (ret) {
|
||||
printf("Failed to get RTC device: %dE\n", ret);
|
||||
return CMD_RET_FAILURE;
|
||||
}
|
||||
|
||||
ret = cedit_read_settings_cmos(cur_exp, dev, verbose);
|
||||
if (ret) {
|
||||
printf("Failed to read settings from CMOS: %dE\n", ret);
|
||||
return CMD_RET_FAILURE;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_cedit_run(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||
char *const argv[])
|
||||
{
|
||||
@ -243,6 +277,7 @@ static char cedit_help_text[] =
|
||||
"cedit write_fdt <i/f> <dev[:part]> <filename> - write settings\n"
|
||||
"cedit read_env [-v] - read settings from env vars\n"
|
||||
"cedit write_env [-v] - write settings to env vars\n"
|
||||
"cedit read_cmos [-v] [dev] - read settings from CMOS RAM\n"
|
||||
"cedit write_cmos [-v] [dev] - write settings to CMOS RAM\n"
|
||||
"cedit run - run config editor";
|
||||
#endif /* CONFIG_SYS_LONGHELP */
|
||||
@ -253,6 +288,7 @@ U_BOOT_CMD_WITH_SUBCMDS(cedit, "Configuration editor", cedit_help_text,
|
||||
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(write_env, 2, 1, do_cedit_write_env),
|
||||
U_BOOT_SUBCMD_MKENT(read_cmos, 2, 1, do_cedit_read_cmos),
|
||||
U_BOOT_SUBCMD_MKENT(write_cmos, 2, 1, do_cedit_write_cmos),
|
||||
U_BOOT_SUBCMD_MKENT(run, 1, 1, do_cedit_run),
|
||||
);
|
||||
|
@ -135,7 +135,14 @@ This shows writing to CMOS RAM. Notice that the bytes at 80 and 84 change::
|
||||
|
||||
=> rtc read 80 8
|
||||
00000080: 00 00 00 00 00 2f 2a 08 ...../*.
|
||||
=> cedit write_cmos
|
||||
=> cedit write_cmos -v
|
||||
Write 2 bytes from offset 80 to 84
|
||||
=> rtc read 80 8
|
||||
00000080: 01 00 00 00 08 2f 2a 08 ...../*.
|
||||
=> cedit read_cmos -v
|
||||
Read 2 bytes from offset 80 to 84
|
||||
|
||||
Here is an example with the device specified::
|
||||
|
||||
=> cedit write_cmos rtc@43
|
||||
=>
|
||||
|
@ -110,4 +110,16 @@ int cedit_read_settings_env(struct expo *exp, bool verbose);
|
||||
int cedit_write_settings_cmos(struct expo *exp, struct udevice *dev,
|
||||
bool verbose);
|
||||
|
||||
/**
|
||||
* cedit_read_settings_cmos() - Read settings from CMOS RAM
|
||||
*
|
||||
* Read settings from the defined places in CMO RAM
|
||||
*
|
||||
* @exp: Expo to read settings into
|
||||
* @dev: RTC device to read settings from
|
||||
* @verbose: true to print a summary at the end
|
||||
*/
|
||||
int cedit_read_settings_cmos(struct expo *exp, struct udevice *dev,
|
||||
bool verbose);
|
||||
|
||||
#endif /* __CEDIT_H */
|
||||
|
@ -182,6 +182,17 @@ static int cedit_cmos(struct unit_test_state *uts)
|
||||
ut_assert_nextlinen("Write 2 bytes from offset 80 to 84");
|
||||
ut_assert_console_end();
|
||||
|
||||
/* reset the expo */
|
||||
menu->cur_item_id = ID_CPU_SPEED_1;
|
||||
menu2->cur_item_id = ID_AC_OFF;
|
||||
|
||||
ut_assertok(run_command("cedit read_cmos -v", 0));
|
||||
ut_assert_nextlinen("Read 2 bytes from offset 80 to 84");
|
||||
ut_assert_console_end();
|
||||
|
||||
ut_asserteq(ID_CPU_SPEED_2, menu->cur_item_id);
|
||||
ut_asserteq(ID_AC_MEMORY, menu2->cur_item_id);
|
||||
|
||||
return 0;
|
||||
}
|
||||
BOOTSTD_TEST(cedit_cmos, 0);
|
||||
|
Loading…
Reference in New Issue
Block a user