Files
u-boot/boot/bootctl/util.c
Simon Glass 4eaef8aa12 bootctl: Enhance the UI to support a TKey
When unlocking an encrypted disk with a TKey we need a few more UI
operations:

- allow the password-entry textline to be shown/hidden
- allow showing instructions to the user, as well as unlock result
- obtain the password entered by the user

Add these to the API and implement them in the multi UI.

Signed-off-by: Simon Glass <simon.glass@canonical.com>
2025-12-07 17:18:57 -07:00

385 lines
6.9 KiB
C

// SPDX-License-Identifier: GPL-2.0+
/*
* Utility functions
*
* Copyright 2025 Canonical Ltd
* Written by Simon Glass <simon.glass@canonical.com>
*/
#define LOG_CATEGORY UCLASS_BOOTCTL
#include <alist.h>
#include <bootctl.h>
#include <dm.h>
#include <log.h>
#include <stdarg.h>
#include <vsprintf.h>
#include <bootctl/logic.h>
#include <bootctl/measure.h>
#include <bootctl/oslist.h>
#include <bootctl/state.h>
#include <bootctl/ui.h>
#include <bootctl/util.h>
/**
* bc_printf() - Print a string to the display
*
* @fmt: printf() format string for log record
* @...: Optional parameters, according to the format string @fmt
* Return: Number of characters emitted
*/
int bc_printf(struct udevice *disp, const char *fmt, ...)
{
struct bc_ui_ops *ops = bc_ui_get_ops(disp);
char buf[CONFIG_SYS_CBSIZE];
va_list args;
int count;
int ret;
va_start(args, fmt);
count = vsnprintf(buf, sizeof(buf), fmt, args);
va_end(args);
ret = ops->print(disp, buf);
if (ret)
return log_msg_ret("bpp", ret);
return count;
}
int bc_ui_show(struct udevice *disp)
{
struct bc_ui_ops *ops = bc_ui_get_ops(disp);
int ret;
ret = ops->show(disp);
if (ret)
return log_msg_ret("bds", ret);
return 0;
}
int bc_ui_add(struct udevice *dev, struct osinfo *info)
{
struct bc_ui_ops *ops = bc_ui_get_ops(dev);
int ret;
ret = ops->add(dev, info);
if (ret)
return log_msg_ret("bda", ret);
return 0;
}
int bc_ui_render(struct udevice *disp)
{
struct bc_ui_ops *ops = bc_ui_get_ops(disp);
int ret;
ret = ops->render(disp);
if (ret)
return log_msg_ret("bds", ret);
return 0;
}
int bc_ui_poll(struct udevice *disp, int *seqp, bool *selectedp)
{
struct bc_ui_ops *ops = bc_ui_get_ops(disp);
int ret;
ret = ops->poll(disp, seqp, selectedp);
if (ret)
return log_msg_ret("bdp", ret);
return ret;
}
int bc_ui_switch_layout(struct udevice *dev)
{
struct bc_ui_ops *ops = bc_ui_get_ops(dev);
int ret;
if (!ops->switch_layout)
return -ENOSYS;
ret = ops->switch_layout(dev);
if (ret)
return log_msg_ret("bsl", ret);
return 0;
}
int bc_ui_show_pass(struct udevice *dev, int seq, bool show)
{
struct bc_ui_ops *ops = bc_ui_get_ops(dev);
int ret;
if (!ops->show_pass)
return -ENOSYS;
ret = ops->show_pass(dev, seq, show);
if (ret)
return log_msg_ret("bsp", ret);
return 0;
}
int bc_ui_get_pass(struct udevice *dev, int seq, const char **passp)
{
struct bc_ui_ops *ops = bc_ui_get_ops(dev);
int ret;
if (!ops->get_pass)
return -ENOSYS;
ret = ops->get_pass(dev, seq, passp);
if (ret)
return log_msg_ret("bgp", ret);
return 0;
}
int bc_ui_show_pass_msg(struct udevice *dev, int seq, bool show)
{
struct bc_ui_ops *ops = bc_ui_get_ops(dev);
int ret;
if (!ops->show_pass_msg)
return -ENOSYS;
ret = ops->show_pass_msg(dev, seq, show);
if (ret)
return log_msg_ret("bse", ret);
return 0;
}
int bc_ui_set_pass_msg(struct udevice *dev, int seq, const char *msg)
{
struct bc_ui_ops *ops = bc_ui_get_ops(dev);
int ret;
if (!ops->set_pass_msg)
return -ENOSYS;
ret = ops->set_pass_msg(dev, seq, msg);
if (ret)
return log_msg_ret("bsm", ret);
return 0;
}
void bc_oslist_setup_iter(struct oslist_iter *iter)
{
memset(iter, '\0', sizeof(struct oslist_iter));
}
int bc_oslist_next(struct udevice *dev, struct oslist_iter *iter,
struct osinfo *info)
{
struct bc_oslist_ops *ops = bc_oslist_get_ops(dev);
int ret;
log_debug("oslist flags %x\n", iter->bf_iter.flags);
ret = ops->next(dev, iter, info);
if (ret)
return log_msg_ret("bon", ret);
return 0;
}
int bc_state_load(struct udevice *dev)
{
struct bc_state_ops *ops = bc_state_get_ops(dev);
int ret;
ret = ops->load(dev);
if (ret)
return log_msg_ret("bsl", ret);
return 0;
}
int bc_state_save(struct udevice *dev)
{
struct bc_state_ops *ops = bc_state_get_ops(dev);
int ret;
ret = ops->save(dev);
if (ret)
return log_msg_ret("bss", ret);
return 0;
}
int bc_state_save_to_buf(struct udevice *dev, struct abuf *buf)
{
struct bc_state_ops *ops = bc_state_get_ops(dev);
int ret;
ret = ops->save_to_buf(dev, buf);
if (ret)
return log_msg_ret("bsb", ret);
return 0;
}
int bc_state_clear(struct udevice *dev)
{
struct bc_state_ops *ops = bc_state_get_ops(dev);
int ret;
ret = ops->clear(dev);
if (ret)
return log_msg_ret("bsc", ret);
return 0;
}
int bc_state_read_bool(struct udevice *dev, const char *key, bool *valp)
{
struct bc_state_ops *ops = bc_state_get_ops(dev);
int ret;
ret = ops->read_bool(dev, key, valp);
if (ret)
return log_msg_ret("srb", ret);
return 0;
}
int bc_state_write_bool(struct udevice *dev, const char *key, bool val)
{
struct bc_state_ops *ops = bc_state_get_ops(dev);
int ret;
ret = ops->write_bool(dev, key, val);
if (ret)
return log_msg_ret("swb", ret);
return 0;
}
int bc_state_read_int(struct udevice *dev, const char *key, long *valp)
{
struct bc_state_ops *ops = bc_state_get_ops(dev);
int ret;
ret = ops->read_int(dev, key, valp);
if (ret)
return log_msg_ret("sri", ret);
return 0;
}
int bc_state_write_int(struct udevice *dev, const char *key, long val)
{
struct bc_state_ops *ops = bc_state_get_ops(dev);
int ret;
ret = ops->write_int(dev, key, val);
if (ret)
return log_msg_ret("swi", ret);
return 0;
}
int bc_state_read_str(struct udevice *dev, const char *key, const char **valp)
{
struct bc_state_ops *ops = bc_state_get_ops(dev);
int ret;
ret = ops->read_str(dev, key, valp);
if (ret)
return log_msg_ret("srs", ret);
return 0;
}
int bc_state_write_str(struct udevice *dev, const char *key, const char *val)
{
struct bc_state_ops *ops = bc_state_get_ops(dev);
int ret;
ret = ops->write_str(dev, key, val);
if (ret)
return log_msg_ret("sws", ret);
return 0;
}
int bc_logic_prepare(struct udevice *dev)
{
struct bc_logic_ops *ops = bc_logic_get_ops(dev);
int ret;
ret = ops->prepare(dev);
if (ret)
return log_msg_ret("blp", ret);
return 0;
}
int bc_logic_start(struct udevice *dev)
{
struct bc_logic_ops *ops = bc_logic_get_ops(dev);
int ret;
ret = ops->start(dev);
if (ret)
return log_msg_ret("bls", ret);
return 0;
}
int bc_logic_poll(struct udevice *dev)
{
struct bc_logic_ops *ops = bc_logic_get_ops(dev);
int ret;
ret = ops->poll(dev);
if (ret)
return log_msg_ret("blP", ret);
return 0;
}
int bc_measure_start(struct udevice *dev)
{
struct bc_measure_ops *ops = bc_measure_get_ops(dev);
int ret;
ret = ops->start(dev);
if (ret)
return log_msg_ret("blM", ret);
return 0;
}
int bc_measure_process(struct udevice *dev, const struct osinfo *osinfo,
struct alist *result)
{
struct bc_measure_ops *ops = bc_measure_get_ops(dev);
int ret;
alist_init_struct(result, struct measure_info);
ret = ops->process(dev, osinfo, result);
if (ret)
return log_msg_ret("blm", ret);
return 0;
}
void show_measures(struct alist *result)
{
struct measure_info *res;
/* TODO: expand to show more info? */
printf("Measurement report:");
alist_for_each(res, result)
printf(" %s", bootflow_img_type_name(res->img->type));
printf("\n");
}