Pull request efi-2025-04-rc1-2

Documentation:
 
 * describe creating a pflash file for qemu-system-riscv64
 
 UEFI:
 
 * correct logging StartImage()
 * use LOGC_EFI consistently
 * reduce UEFI size if HAS_BOARD_SIZE_LIMIT=y
 * Update efi_run_image() to accept image and device path
 * Add a version of efi_binary_run() with more parameters
 * Move the fallback code from efi_run_image()
 * Pass in the required parameters from EFI bootmeth
 * bootmeth_efi: Support PXE booting
 
 Other:
 
 * Enable log filtering by function name
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEEK7wKXt3/btL6/yA+hO4vgnE3U0sFAmeWCwgACgkQhO4vgnE3
 U0u7qRAAusk/HO9ICJRm/BPnOsRim8dB58kZ/WTTzmxAIpLST4FKXGtvv+SHCJNA
 l/zFQ0Tijeh4mrEKurNvJWQ2LDMRDDO5czSfQG4OjfEq1RISASuIkI31yTKi9bZn
 AmvTkotg0XR7SbUQxdCBN1MCxecvPVrfASor1OGb64NN1EXdJybAhtAZ9XUEH/VX
 1tOnkSFXzFqVkNVlC0o1vanTRlV8VfAWHFE/pxiZzbsAca2ZGxht82d2WFios+Ri
 PAVnAhUEFWId49N62slFq6jqBbCwbKVeA5/2L7ntvZY1BxugIEw0qaCmSiTlWAFE
 J1lrjUUrvH0bJLdGBZcSWLneXqEcQCnlLTMl42YPfvCyxXcdbEDoiVlkMpMVgmfd
 10dJVzsaumbTsQus/UIFDY5b2aUp4n9peULS1iSc5KLIpS2xPmY6trOwNvFi6GXU
 Z4QF9mHNn6zfN3rFfw8IpyqN2n7ixVQdbgdhkaYyTUoLmwt9Y5oMfbbJ9uP2U38H
 GnXDRoMWSq50u3q/y7KwB989yA9OjNfijKy5cuR2MaHtRL+FNlvpK9kvRHh6n2pz
 CZfSqvCZP/35WwSqGoxMa96zDmQrMTXr1Cjgo2l+Jutwv+sx7ZTtiasYWul5ovWQ
 GMO2NCFgHP25AYuY6rYYg5JmP1S85z7Y5Tcmy7Onb/3cuyzqGrk=
 =cFni
 -----END PGP SIGNATURE-----

Merge tag 'efi-2025-04-rc1-2' of https://source.denx.de/u-boot/custodians/u-boot-efi

Pull request efi-2025-04-rc1-2

Documentation:

* describe creating a pflash file for qemu-system-riscv64

UEFI:

* correct logging StartImage()
* use LOGC_EFI consistently
* reduce UEFI size if HAS_BOARD_SIZE_LIMIT=y
* Update efi_run_image() to accept image and device path
* Add a version of efi_binary_run() with more parameters
* Move the fallback code from efi_run_image()
* Pass in the required parameters from EFI bootmeth
* bootmeth_efi: Support PXE booting

Other:

* Enable log filtering by function name
This commit is contained in:
Tom Rini 2025-01-26 08:10:28 -06:00
commit 8a2a71a4ee
41 changed files with 372 additions and 175 deletions

View file

@ -52,40 +52,6 @@ static bool bootmeth_uses_network(struct bootflow *bflow)
device_get_uclass_id(media) == UCLASS_ETH; device_get_uclass_id(media) == UCLASS_ETH;
} }
static void set_efi_bootdev(struct blk_desc *desc, struct bootflow *bflow)
{
const struct udevice *media_dev;
int size = bflow->size;
const char *dev_name;
char devnum_str[9];
char dirname[200];
char *last_slash;
/*
* This is a horrible hack to tell EFI about this boot device. Once we
* unify EFI with the rest of U-Boot we can clean this up. The same hack
* exists in multiple places, e.g. in the fs, tftp and load commands.
*
* Once we can clean up the EFI code to make proper use of driver model,
* this can go away.
*/
media_dev = dev_get_parent(bflow->dev);
snprintf(devnum_str, sizeof(devnum_str), "%x:%x",
desc ? desc->devnum : dev_seq(media_dev),
bflow->part);
strlcpy(dirname, bflow->fname, sizeof(dirname));
last_slash = strrchr(dirname, '/');
if (last_slash)
*last_slash = '\0';
dev_name = device_get_uclass_id(media_dev) == UCLASS_MASS_STORAGE ?
"usb" : blk_get_uclass_name(device_get_uclass_id(media_dev));
log_debug("setting bootdev %s, %s, %s, %p, %x\n",
dev_name, devnum_str, bflow->fname, bflow->buf, size);
efi_set_bootdev(dev_name, devnum_str, bflow->fname, bflow->buf, size);
}
static int efiload_read_file(struct bootflow *bflow, ulong addr) static int efiload_read_file(struct bootflow *bflow, ulong addr)
{ {
struct blk_desc *desc = NULL; struct blk_desc *desc = NULL;
@ -102,8 +68,6 @@ static int efiload_read_file(struct bootflow *bflow, ulong addr)
return log_msg_ret("rdf", ret); return log_msg_ret("rdf", ret);
bflow->buf = map_sysmem(addr, bflow->size); bflow->buf = map_sysmem(addr, bflow->size);
set_efi_bootdev(desc, bflow);
return 0; return 0;
} }
@ -246,6 +210,7 @@ static int distro_efi_read_bootflow_net(struct bootflow *bflow)
if (size <= 0) if (size <= 0)
return log_msg_ret("sz", -EINVAL); return log_msg_ret("sz", -EINVAL);
bflow->size = size; bflow->size = size;
bflow->buf = map_sysmem(addr, size);
/* bootfile should be setup by dhcp */ /* bootfile should be setup by dhcp */
bootfile_name = env_get("bootfile"); bootfile_name = env_get("bootfile");
@ -255,10 +220,6 @@ static int distro_efi_read_bootflow_net(struct bootflow *bflow)
if (!bflow->fname) if (!bflow->fname)
return log_msg_ret("fi0", -ENOMEM); return log_msg_ret("fi0", -ENOMEM);
/* do the hideous EFI hack */
efi_set_bootdev("Net", "", bflow->fname, map_sysmem(addr, 0),
bflow->size);
/* read the DT file also */ /* read the DT file also */
fdt_addr_str = env_get("fdt_addr_r"); fdt_addr_str = env_get("fdt_addr_r");
if (!fdt_addr_str) if (!fdt_addr_str)
@ -332,29 +293,10 @@ static int distro_efi_boot(struct udevice *dev, struct bootflow *bflow)
if (bflow->flags & ~BOOTFLOWF_USE_BUILTIN_FDT) if (bflow->flags & ~BOOTFLOWF_USE_BUILTIN_FDT)
fdt = bflow->fdt_addr; fdt = bflow->fdt_addr;
} else {
/*
* This doesn't actually work for network devices:
*
* do_bootefi_image() No UEFI binary known at 0x02080000
*
* But this is the same behaviour for distro boot, so it can be
* fixed here.
*/
fdt = env_get_hex("fdt_addr_r", 0);
} }
if (bflow->flags & BOOTFLOWF_USE_BUILTIN_FDT) { if (efi_bootflow_run(bflow))
log_debug("Booting with built-in fdt\n"); return log_msg_ret("run", -EINVAL);
if (efi_binary_run(map_sysmem(kernel, 0), bflow->size,
EFI_FDT_USE_INTERNAL))
return log_msg_ret("run", -EINVAL);
} else {
log_debug("Booting with external fdt\n");
if (efi_binary_run(map_sysmem(kernel, 0), bflow->size,
map_sysmem(fdt, 0)))
return log_msg_ret("run", -EINVAL);
}
return 0; return 0;
} }

View file

@ -115,30 +115,27 @@ static int do_log_filter_list(struct cmd_tbl *cmdtp, int flag, int argc,
return CMD_RET_FAILURE; return CMD_RET_FAILURE;
} }
/* <3> < 6 > <2+1 + 7 > < 16 > < unbounded... */
printf("num policy level categories files\n");
list_for_each_entry(filt, &ldev->filter_head, sibling_node) { list_for_each_entry(filt, &ldev->filter_head, sibling_node) {
printf("%3d %6.6s %s %-7.7s ", filt->filter_num, printf("%-3d: %s %s %s\n", filt->filter_num,
filt->flags & LOGFF_DENY ? "deny" : "allow", filt->flags & LOGFF_DENY ? "DENY" : "ALLOW",
filt->flags & LOGFF_LEVEL_MIN ? ">=" : "<=", filt->flags & LOGFF_LEVEL_MIN ? ">=" : "<=",
log_get_level_name(filt->level)); log_get_level_name(filt->level));
if (filt->flags & LOGFF_HAS_CAT) { if (filt->flags & LOGFF_HAS_CAT) {
int i; printf(" Categories:");
for (int i = 0;
if (filt->cat_list[0] != LOGC_END) i < LOGF_MAX_CATEGORIES &&
printf("%16.16s %s\n", filt->cat_list[i] != LOGC_END;
log_get_cat_name(filt->cat_list[0]), ++i) {
filt->file_list ? filt->file_list : ""); printf(" %s",
for (i = 1; i < LOGF_MAX_CATEGORIES &&
filt->cat_list[i] != LOGC_END; i++)
printf("%21c %16.16s\n", ' ',
log_get_cat_name(filt->cat_list[i])); log_get_cat_name(filt->cat_list[i]));
} else { }
printf("%16c %s\n", ' ', printf("\n");
filt->file_list ? filt->file_list : "");
} }
if (filt->file_list)
printf(" Files: %s\n", filt->file_list);
if (filt->func_list)
printf(" Functions: %s\n", filt->func_list);
} }
return CMD_RET_SUCCESS; return CMD_RET_SUCCESS;
@ -151,6 +148,7 @@ static int do_log_filter_add(struct cmd_tbl *cmdtp, int flag, int argc,
bool print_num = false; bool print_num = false;
bool type_set = false; bool type_set = false;
char *file_list = NULL; char *file_list = NULL;
char *func_list = NULL;
const char *drv_name = "console"; const char *drv_name = "console";
int opt, err; int opt, err;
int cat_count = 0; int cat_count = 0;
@ -160,7 +158,7 @@ static int do_log_filter_add(struct cmd_tbl *cmdtp, int flag, int argc,
struct getopt_state gs; struct getopt_state gs;
getopt_init_state(&gs); getopt_init_state(&gs);
while ((opt = getopt(&gs, argc, argv, "Ac:d:Df:l:L:p")) > 0) { while ((opt = getopt(&gs, argc, argv, "Ac:d:Df:F:l:L:p")) > 0) {
switch (opt) { switch (opt) {
case 'A': case 'A':
#define do_type() do { \ #define do_type() do { \
@ -199,6 +197,9 @@ static int do_log_filter_add(struct cmd_tbl *cmdtp, int flag, int argc,
case 'f': case 'f':
file_list = gs.arg; file_list = gs.arg;
break; break;
case 'F':
func_list = gs.arg;
break;
case 'l': case 'l':
#define do_level() do { \ #define do_level() do { \
if (level_set) { \ if (level_set) { \
@ -229,7 +230,7 @@ static int do_log_filter_add(struct cmd_tbl *cmdtp, int flag, int argc,
cat_list[cat_count] = LOGC_END; cat_list[cat_count] = LOGC_END;
err = log_add_filter_flags(drv_name, cat_count ? cat_list : NULL, level, err = log_add_filter_flags(drv_name, cat_count ? cat_list : NULL, level,
file_list, flags); file_list, func_list, flags);
if (err < 0) { if (err < 0) {
printf("Could not add filter (err = %d)\n", err); printf("Could not add filter (err = %d)\n", err);
return CMD_RET_FAILURE; return CMD_RET_FAILURE;
@ -388,7 +389,8 @@ U_BOOT_LONGHELP(log,
"\t-d <driver> - Specify the log driver to add the filter to; defaults\n" "\t-d <driver> - Specify the log driver to add the filter to; defaults\n"
"\t to console\n" "\t to console\n"
"\t-D - Deny messages matching this filter; mutually exclusive with -A\n" "\t-D - Deny messages matching this filter; mutually exclusive with -A\n"
"\t-f <files_list> - A comma-separated list of files to match\n" "\t-f <file_list> - A comma-separated list of files to match\n"
"\t-F <func_list> - A comma-separated list of functions to match\n"
"\t-l <level> - Match log levels less than or equal to <level>;\n" "\t-l <level> - Match log levels less than or equal to <level>;\n"
"\t mutually-exclusive with -L\n" "\t mutually-exclusive with -L\n"
"\t-L <level> - Match log levels greather than or equal to <level>;\n" "\t-L <level> - Match log levels greather than or equal to <level>;\n"

View file

@ -130,17 +130,25 @@ bool log_has_cat(enum log_category_t cat_list[], enum log_category_t cat)
return false; return false;
} }
bool log_has_file(const char *file_list, const char *file) /**
* log_has_member() - check if a string is in a comma separated list
*
* @list: Comma separated list of strings
* @member: String to find
*
* Return: ``true`` if @member is in @list, else ``false``
*/
static bool log_has_member(const char *list, const char *member)
{ {
int file_len = strlen(file); int member_len = strlen(member);
const char *s, *p; const char *s, *p;
int substr_len; int substr_len;
for (s = file_list; *s; s = p + (*p != '\0')) { for (s = list; *s; s = p + (*p != '\0')) {
p = strchrnul(s, ','); p = strchrnul(s, ',');
substr_len = p - s; substr_len = p - s;
if (file_len >= substr_len && if (member_len >= substr_len &&
!strncmp(file + file_len - substr_len, s, substr_len)) !strncmp(member + member_len - substr_len, s, substr_len))
return true; return true;
} }
@ -181,7 +189,11 @@ static bool log_passes_filters(struct log_device *ldev, struct log_rec *rec)
continue; continue;
if (filt->file_list && if (filt->file_list &&
!log_has_file(filt->file_list, rec->file)) !log_has_member(filt->file_list, rec->file))
continue;
if (filt->func_list &&
!log_has_member(filt->func_list, rec->func))
continue; continue;
if (filt->flags & LOGFF_DENY) if (filt->flags & LOGFF_DENY)
@ -321,7 +333,7 @@ int _log_buffer(enum log_category_t cat, enum log_level_t level,
int log_add_filter_flags(const char *drv_name, enum log_category_t cat_list[], int log_add_filter_flags(const char *drv_name, enum log_category_t cat_list[],
enum log_level_t level, const char *file_list, enum log_level_t level, const char *file_list,
int flags) const char *func_list, int flags)
{ {
struct log_filter *filt; struct log_filter *filt;
struct log_device *ldev; struct log_device *ldev;
@ -356,6 +368,13 @@ int log_add_filter_flags(const char *drv_name, enum log_category_t cat_list[],
goto err; goto err;
} }
} }
if (func_list) {
filt->func_list = strdup(func_list);
if (!filt->func_list) {
ret = -ENOMEM;
goto err;
}
}
filt->filter_num = ldev->next_filter_num++; filt->filter_num = ldev->next_filter_num++;
/* Add deny filters to the beginning of the list */ /* Add deny filters to the beginning of the list */
if (flags & LOGFF_DENY) if (flags & LOGFF_DENY)

View file

@ -42,6 +42,23 @@ use the configurations qemu-riscv32_smode_defconfig and
qemu-riscv64_smode_defconfig instead. Note that U-Boot running in supervisor qemu-riscv64_smode_defconfig instead. Note that U-Boot running in supervisor
mode requires a supervisor binary interface (SBI), such as RISC-V OpenSBI. mode requires a supervisor binary interface (SBI), such as RISC-V OpenSBI.
To create a U-Boot binary that can be utilized with a pflash device in QEMU
apply these addtional settings to qemu-riscv64_smode_defconfig:
::
CONFIG_TEXT_BASE=0x20000000
CONFIG_XIP=y
# CONFIG_AVAILABLE_HARTS is not set
CONFIG_SYS_MONITOR_BASE=0x80200000
Truncate the resulting u-boot.bin to 32 MiB. Add the following to your
qemu-system-riscv64 command:
.. code-block:: bash
-drive if=pflash,format=raw,unit=0,file=u-boot.bin
Running U-Boot Running U-Boot
-------------- --------------
The minimal QEMU command line to get U-Boot up and running is: The minimal QEMU command line to get U-Boot up and running is:

View file

@ -20,6 +20,7 @@
#include <linux/oid_registry.h> #include <linux/oid_registry.h>
struct blk_desc; struct blk_desc;
struct bootflow;
struct jmp_buf_data; struct jmp_buf_data;
#if CONFIG_IS_ENABLED(EFI_LOADER) #if CONFIG_IS_ENABLED(EFI_LOADER)
@ -245,6 +246,18 @@ const char *__efi_nesting_dec(void);
_r; \ _r; \
}) })
/**
* define EFI_RETURN() - return from EFI_CALL in efi_start_image()
*
* @ret: status code
*/
#define EFI_RETURN(ret) ({ \
typeof(ret) _r = ret; \
assert(__efi_entry_check()); \
debug("%sEFI: %lu returned by started image", __efi_nesting_dec(), \
(unsigned long)((uintptr_t)_r & ~EFI_ERROR_MASK)); \
})
/* /*
* Call void UEFI function from u-boot: * Call void UEFI function from u-boot:
*/ */
@ -578,6 +591,15 @@ efi_status_t efi_install_fdt(void *fdt);
efi_status_t do_bootefi_exec(efi_handle_t handle, void *load_options); efi_status_t do_bootefi_exec(efi_handle_t handle, void *load_options);
/* Run loaded UEFI image with given fdt */ /* Run loaded UEFI image with given fdt */
efi_status_t efi_binary_run(void *image, size_t size, void *fdt); efi_status_t efi_binary_run(void *image, size_t size, void *fdt);
/**
* efi_bootflow_run() - Run a bootflow containing an EFI application
*
* @bootflow: Bootflow to run
* Return: Status code, something went wrong
*/
efi_status_t efi_bootflow_run(struct bootflow *bootflow);
/* Initialize variable services */ /* Initialize variable services */
efi_status_t efi_init_variables(void); efi_status_t efi_init_variables(void);
/* Notify ExitBootServices() is called */ /* Notify ExitBootServices() is called */

View file

@ -500,6 +500,7 @@ enum log_filter_flags {
* @level: Maximum (or minimum, if %LOGFF_MIN_LEVEL) log level to allow * @level: Maximum (or minimum, if %LOGFF_MIN_LEVEL) log level to allow
* @file_list: List of files to allow, separated by comma. If NULL then all * @file_list: List of files to allow, separated by comma. If NULL then all
* files are permitted * files are permitted
* @func_list: Comma separated list of functions or NULL.
* @sibling_node: Next filter in the list of filters for this log device * @sibling_node: Next filter in the list of filters for this log device
*/ */
struct log_filter { struct log_filter {
@ -508,6 +509,7 @@ struct log_filter {
enum log_category_t cat_list[LOGF_MAX_CATEGORIES]; enum log_category_t cat_list[LOGF_MAX_CATEGORIES];
enum log_level_t level; enum log_level_t level;
const char *file_list; const char *file_list;
const char *func_list;
struct list_head sibling_node; struct list_head sibling_node;
}; };
@ -571,18 +573,6 @@ struct log_device *log_device_find_by_name(const char *drv_name);
*/ */
bool log_has_cat(enum log_category_t cat_list[], enum log_category_t cat); bool log_has_cat(enum log_category_t cat_list[], enum log_category_t cat);
/**
* log_has_file() - check if a file is with a list
*
* @file_list: List of files to check, separated by comma
* @file: File to check for. This string is matched against the end of each
* file in the list, i.e. ignoring any preceding path. The list is
* intended to consist of relative pathnames, e.g. common/main.c,cmd/log.c
*
* Return: ``true`` if @file is in @file_list, else ``false``
*/
bool log_has_file(const char *file_list, const char *file);
/* Log format flags (bit numbers) for gd->log_fmt. See log_fmt_chars */ /* Log format flags (bit numbers) for gd->log_fmt. See log_fmt_chars */
enum log_fmt { enum log_fmt {
LOGF_CAT = 0, LOGF_CAT = 0,
@ -611,13 +601,14 @@ int do_log_test(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
* @level: Maximum (or minimum, if %LOGFF_LEVEL_MIN) log level to allow * @level: Maximum (or minimum, if %LOGFF_LEVEL_MIN) log level to allow
* @file_list: List of files to allow, separated by comma. If NULL then all * @file_list: List of files to allow, separated by comma. If NULL then all
* files are permitted * files are permitted
* @func_list: Comma separated list of functions or NULL.
* Return: * Return:
* the sequence number of the new filter (>=0) if the filter was added, or a * the sequence number of the new filter (>=0) if the filter was added, or a
* -ve value on error * -ve value on error
*/ */
int log_add_filter_flags(const char *drv_name, enum log_category_t cat_list[], int log_add_filter_flags(const char *drv_name, enum log_category_t cat_list[],
enum log_level_t level, const char *file_list, enum log_level_t level, const char *file_list,
int flags); const char *func_list, int flags);
/** /**
* log_add_filter() - Add a new filter to a log device * log_add_filter() - Add a new filter to a log device
@ -640,7 +631,7 @@ static inline int log_add_filter(const char *drv_name,
const char *file_list) const char *file_list)
{ {
return log_add_filter_flags(drv_name, cat_list, max_level, file_list, return log_add_filter_flags(drv_name, cat_list, max_level, file_list,
0); NULL, 0);
} }
/** /**

View file

@ -28,6 +28,8 @@
* iPXE uses the simple file protocol to load Grub or the Linux Kernel. * iPXE uses the simple file protocol to load Grub or the Linux Kernel.
*/ */
#define LOG_CATEGORY LOGC_EFI
#include <blk.h> #include <blk.h>
#include <dm.h> #include <dm.h>
#include <efi_driver.h> #include <efi_driver.h>

View file

@ -17,6 +17,8 @@
* controllers. * controllers.
*/ */
#define LOG_CATEGORY LOGC_EFI
#include <dm.h> #include <dm.h>
#include <efi_driver.h> #include <efi_driver.h>
#include <log.h> #include <log.h>

View file

@ -387,7 +387,7 @@ config EFI_DT_FIXUP
config EFI_LOADER_HII config EFI_LOADER_HII
bool "HII protocols" bool "HII protocols"
default y default y if !HAS_BOARD_SIZE_LIMIT
help help
The Human Interface Infrastructure is a complicated framework that The Human Interface Infrastructure is a complicated framework that
allows UEFI applications to draw fancy menus and hook strings using allows UEFI applications to draw fancy menus and hook strings using
@ -407,7 +407,7 @@ if EFI_UNICODE_COLLATION_PROTOCOL2
config EFI_UNICODE_CAPITALIZATION config EFI_UNICODE_CAPITALIZATION
bool "Support Unicode capitalization" bool "Support Unicode capitalization"
default y default y if !HAS_BOARD_SIZE_LIMIT
help help
Select this option to enable correct handling of the capitalization of Select this option to enable correct handling of the capitalization of
Unicode codepoints in the range 0x0000-0xffff. If this option is not Unicode codepoints in the range 0x0000-0xffff. If this option is not

View file

@ -5,6 +5,8 @@
* Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com> * Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com>
*/ */
#define LOG_CATEGORY LOGC_EFI
#include <efi_loader.h> #include <efi_loader.h>
#include <log.h> #include <log.h>
#include <mapmem.h> #include <mapmem.h>

View file

@ -6,13 +6,16 @@
#define LOG_CATEGORY LOGC_EFI #define LOG_CATEGORY LOGC_EFI
#include <bootflow.h>
#include <charset.h> #include <charset.h>
#include <dm.h>
#include <efi.h> #include <efi.h>
#include <efi_loader.h> #include <efi_loader.h>
#include <env.h> #include <env.h>
#include <image.h> #include <image.h>
#include <log.h> #include <log.h>
#include <malloc.h> #include <malloc.h>
#include <mapmem.h>
static struct efi_device_path *bootefi_image_path; static struct efi_device_path *bootefi_image_path;
static struct efi_device_path *bootefi_device_path; static struct efi_device_path *bootefi_device_path;
@ -157,42 +160,21 @@ void efi_set_bootdev(const char *dev, const char *devnr, const char *path,
* *
* @source_buffer: memory address of the UEFI image * @source_buffer: memory address of the UEFI image
* @source_size: size of the UEFI image * @source_size: size of the UEFI image
* @dp_dev: EFI device-path
* @dp_img: EFI image-path
* Return: status code * Return: status code
*/ */
static efi_status_t efi_run_image(void *source_buffer, efi_uintn_t source_size) static efi_status_t efi_run_image(void *source_buffer, efi_uintn_t source_size,
struct efi_device_path *dp_dev,
struct efi_device_path *dp_img)
{ {
efi_handle_t mem_handle = NULL, handle; efi_handle_t handle;
struct efi_device_path *file_path = NULL; struct efi_device_path *msg_path, *file_path;
struct efi_device_path *msg_path;
efi_status_t ret; efi_status_t ret;
u16 *load_options; u16 *load_options;
if (!bootefi_device_path || !bootefi_image_path) { file_path = efi_dp_concat(dp_dev, dp_img, 0);
log_debug("Not loaded from disk\n"); msg_path = dp_img;
/*
* Special case for efi payload not loaded from disk,
* such as 'bootefi hello' or for example payload
* loaded directly into memory via JTAG, etc:
*/
file_path = efi_dp_from_mem(EFI_RESERVED_MEMORY_TYPE,
(uintptr_t)source_buffer,
source_size);
/*
* Make sure that device for device_path exist
* in load_image(). Otherwise, shell and grub will fail.
*/
ret = efi_install_multiple_protocol_interfaces(&mem_handle,
&efi_guid_device_path,
file_path, NULL);
if (ret != EFI_SUCCESS)
goto out;
msg_path = file_path;
} else {
file_path = efi_dp_concat(bootefi_device_path,
bootefi_image_path, 0);
msg_path = bootefi_image_path;
log_debug("Loaded from disk\n");
}
log_info("Booting %pD\n", msg_path); log_info("Booting %pD\n", msg_path);
@ -211,19 +193,45 @@ static efi_status_t efi_run_image(void *source_buffer, efi_uintn_t source_size)
ret = do_bootefi_exec(handle, load_options); ret = do_bootefi_exec(handle, load_options);
out: out:
if (mem_handle) {
efi_status_t r;
r = efi_uninstall_multiple_protocol_interfaces(
mem_handle, &efi_guid_device_path, file_path, NULL);
if (r != EFI_SUCCESS)
log_err("Uninstalling protocol interfaces failed\n");
}
efi_free_pool(file_path);
return ret; return ret;
} }
/**
* efi_binary_run_dp() - run loaded UEFI image
*
* @image: memory address of the UEFI image
* @size: size of the UEFI image
* @fdt: device-tree
* @dp_dev: EFI device-path
* @dp_img: EFI image-path
*
* Execute an EFI binary image loaded at @image.
* @size may be zero if the binary is loaded with U-Boot load command.
*
* Return: status code
*/
static efi_status_t efi_binary_run_dp(void *image, size_t size, void *fdt,
struct efi_device_path *dp_dev,
struct efi_device_path *dp_img)
{
efi_status_t ret;
/* Initialize EFI drivers */
ret = efi_init_obj_list();
if (ret != EFI_SUCCESS) {
log_err("Error: Cannot initialize UEFI sub-system, r = %lu\n",
ret & ~EFI_ERROR_MASK);
return -1;
}
ret = efi_install_fdt(fdt);
if (ret != EFI_SUCCESS)
return ret;
return efi_run_image(image, size, dp_dev, dp_img);
}
/** /**
* efi_binary_run() - run loaded UEFI image * efi_binary_run() - run loaded UEFI image
* *
@ -238,19 +246,115 @@ out:
*/ */
efi_status_t efi_binary_run(void *image, size_t size, void *fdt) efi_status_t efi_binary_run(void *image, size_t size, void *fdt)
{ {
efi_handle_t mem_handle = NULL;
struct efi_device_path *file_path = NULL;
efi_status_t ret; efi_status_t ret;
/* Initialize EFI drivers */ if (!bootefi_device_path || !bootefi_image_path) {
ret = efi_init_obj_list(); log_debug("Not loaded from disk\n");
if (ret != EFI_SUCCESS) { /*
log_err("Error: Cannot initialize UEFI sub-system, r = %lu\n", * Special case for efi payload not loaded from disk,
ret & ~EFI_ERROR_MASK); * such as 'bootefi hello' or for example payload
return -1; * loaded directly into memory via JTAG, etc:
*/
file_path = efi_dp_from_mem(EFI_RESERVED_MEMORY_TYPE,
(uintptr_t)image, size);
/*
* Make sure that device for device_path exist
* in load_image(). Otherwise, shell and grub will fail.
*/
ret = efi_install_multiple_protocol_interfaces(&mem_handle,
&efi_guid_device_path,
file_path, NULL);
if (ret != EFI_SUCCESS)
goto out;
} else {
log_debug("Loaded from disk\n");
} }
ret = efi_install_fdt(fdt); ret = efi_binary_run_dp(image, size, fdt, bootefi_device_path,
if (ret != EFI_SUCCESS) bootefi_image_path);
return ret; out:
if (mem_handle) {
efi_status_t r;
return efi_run_image(image, size); r = efi_uninstall_multiple_protocol_interfaces(mem_handle,
&efi_guid_device_path, file_path, NULL);
if (r != EFI_SUCCESS)
log_err("Uninstalling protocol interfaces failed\n");
}
efi_free_pool(file_path);
return ret;
}
/**
* calc_dev_name() - Calculate the device name to give to EFI
*
* If not supported, this shows an error.
*
* Return name, or NULL if not supported
*/
static const char *calc_dev_name(struct bootflow *bflow)
{
const struct udevice *media_dev;
media_dev = dev_get_parent(bflow->dev);
if (!bflow->blk) {
if (device_get_uclass_id(media_dev) == UCLASS_ETH)
return "Net";
log_err("Cannot boot EFI app on media '%s'\n",
dev_get_uclass_name(media_dev));
return NULL;
}
if (device_get_uclass_id(media_dev) == UCLASS_MASS_STORAGE)
return "usb";
return blk_get_uclass_name(device_get_uclass_id(media_dev));
}
efi_status_t efi_bootflow_run(struct bootflow *bflow)
{
struct efi_device_path *device, *image;
const struct udevice *media_dev;
struct blk_desc *desc = NULL;
const char *dev_name;
char devnum_str[9];
efi_status_t ret;
void *fdt;
media_dev = dev_get_parent(bflow->dev);
if (bflow->blk) {
desc = dev_get_uclass_plat(bflow->blk);
snprintf(devnum_str, sizeof(devnum_str), "%x:%x",
desc ? desc->devnum : dev_seq(media_dev), bflow->part);
} else {
*devnum_str = '\0';
}
dev_name = calc_dev_name(bflow);
log_debug("dev_name '%s' devnum_str '%s' fname '%s' media_dev '%s'\n",
dev_name, devnum_str, bflow->fname, media_dev->name);
if (!dev_name)
return EFI_UNSUPPORTED;
ret = calculate_paths(dev_name, devnum_str, bflow->fname, &device,
&image);
if (ret)
return EFI_UNSUPPORTED;
if (bflow->flags & BOOTFLOWF_USE_BUILTIN_FDT) {
log_debug("Booting with built-in fdt\n");
fdt = EFI_FDT_USE_INTERNAL;
} else {
log_debug("Booting with external fdt\n");
fdt = map_sysmem(bflow->fdt_addr, 0);
}
ret = efi_binary_run_dp(bflow->buf, bflow->size, fdt, device, image);
return ret;
} }

View file

@ -5,6 +5,8 @@
* Copyright (c) 2016 Alexander Graf * Copyright (c) 2016 Alexander Graf
*/ */
#define LOG_CATEGORY LOGC_EFI
#include <bootm.h> #include <bootm.h>
#include <div64.h> #include <div64.h>
#include <dm/device.h> #include <dm/device.h>
@ -3256,11 +3258,10 @@ efi_status_t EFIAPI efi_start_image(efi_handle_t image_handle,
* To get ready to call EFI_EXIT below we have to execute the * To get ready to call EFI_EXIT below we have to execute the
* missed out steps of EFI_CALL. * missed out steps of EFI_CALL.
*/ */
assert(__efi_entry_check()); EFI_RETURN(exit_status);
EFI_PRINT("%lu returned by started image\n",
(unsigned long)((uintptr_t)exit_status &
~EFI_ERROR_MASK));
current_image = parent_image; current_image = parent_image;
return EFI_EXIT(exit_status); return EFI_EXIT(exit_status);
} }

View file

@ -5,6 +5,8 @@
* Copyright (C) 2022 Arm Ltd. * Copyright (C) 2022 Arm Ltd.
*/ */
#define LOG_CATEGORY LOGC_EFI
#include <efi_loader.h> #include <efi_loader.h>
#include <log.h> #include <log.h>
#include <efi_api.h> #include <efi_api.h>

View file

@ -5,6 +5,8 @@
* Copyright (c) 2017 Heinrich Schuchardt * Copyright (c) 2017 Heinrich Schuchardt
*/ */
#define LOG_CATEGORY LOGC_EFI
#include <blk.h> #include <blk.h>
#include <efi_loader.h> #include <efi_loader.h>
#include <malloc.h> #include <malloc.h>

View file

@ -5,6 +5,8 @@
* Copyright (c) 2017 Leif Lindholm * Copyright (c) 2017 Leif Lindholm
*/ */
#define LOG_CATEGORY LOGC_EFI
#include <efi_loader.h> #include <efi_loader.h>
const efi_guid_t efi_guid_device_path_utilities_protocol = const efi_guid_t efi_guid_device_path_utilities_protocol =

View file

@ -5,6 +5,8 @@
* Copyright (c) 2020 Heinrich Schuchardt * Copyright (c) 2020 Heinrich Schuchardt
*/ */
#define LOG_CATEGORY LOGC_EFI
#include <efi_dt_fixup.h> #include <efi_dt_fixup.h>
#include <efi_loader.h> #include <efi_loader.h>
#include <efi_rng.h> #include <efi_rng.h>

View file

@ -5,6 +5,8 @@
* Copyright (C) 2021 Arm Ltd. * Copyright (C) 2021 Arm Ltd.
*/ */
#define LOG_CATEGORY LOGC_EFI
#include <efi_loader.h> #include <efi_loader.h>
#include <log.h> #include <log.h>
#include <efi_api.h> #include <efi_api.h>

View file

@ -6,6 +6,8 @@
* Written by Simon Glass <sjg@chromium.org> * Written by Simon Glass <sjg@chromium.org>
*/ */
#define LOG_CATEGORY LOGC_EFI
#include <efi_loader.h> #include <efi_loader.h>
#include <env.h> #include <env.h>
#include <errno.h> #include <errno.h>

View file

@ -5,6 +5,8 @@
* Copyright (c) 2017 Rob Clark * Copyright (c) 2017 Rob Clark
*/ */
#define LOG_CATEGORY LOGC_EFI
#include <charset.h> #include <charset.h>
#include <efi_loader.h> #include <efi_loader.h>
#include <log.h> #include <log.h>

View file

@ -6,6 +6,8 @@
* Author: AKASHI Takahiro * Author: AKASHI Takahiro
*/ */
#define LOG_CATEGORY LOGC_EFI
#include <charset.h> #include <charset.h>
#include <dfu.h> #include <dfu.h>
#include <efi_loader.h> #include <efi_loader.h>

View file

@ -5,6 +5,8 @@
* Copyright (c) 2016 Alexander Graf * Copyright (c) 2016 Alexander Graf
*/ */
#define LOG_CATEGORY LOGC_EFI
#include <dm.h> #include <dm.h>
#include <efi_loader.h> #include <efi_loader.h>
#include <log.h> #include <log.h>

View file

@ -4,6 +4,7 @@
*/ */
#define LOG_CATEGORY LOGC_EFI #define LOG_CATEGORY LOGC_EFI
#include <bootm.h> #include <bootm.h>
#include <env.h> #include <env.h>
#include <image.h> #include <image.h>

View file

@ -6,6 +6,8 @@
* Copyright (c) 2018 AKASHI Takahiro, Linaro Limited * Copyright (c) 2018 AKASHI Takahiro, Linaro Limited
*/ */
#define LOG_CATEGORY LOGC_EFI
#include <efi_loader.h> #include <efi_loader.h>
#include <malloc.h> #include <malloc.h>
#include <asm/unaligned.h> #include <asm/unaligned.h>

View file

@ -10,6 +10,8 @@
* the Makefile. * the Makefile.
*/ */
#define LOG_CATEGORY LOGC_EFI
#include <efi_loader.h> #include <efi_loader.h>
const efi_guid_t efi_guid_hii_config_routing_protocol const efi_guid_t efi_guid_hii_config_routing_protocol

View file

@ -7,6 +7,8 @@
* IP4_CONFIG2_PROTOCOL * IP4_CONFIG2_PROTOCOL
*/ */
#define LOG_CATEGORY LOGC_EFI
#include <charset.h> #include <charset.h>
#include <efi_loader.h> #include <efi_loader.h>
#include <image.h> #include <image.h>

View file

@ -4,6 +4,8 @@
* *
*/ */
#define LOG_CATEGORY LOGC_EFI
#include <efi_loader.h> #include <efi_loader.h>
#include <image.h> #include <image.h>
#include <malloc.h> #include <malloc.h>

View file

@ -4,6 +4,7 @@
*/ */
#define LOG_CATEGORY LOGC_EFI #define LOG_CATEGORY LOGC_EFI
#include <efi_loader.h> #include <efi_loader.h>
#include <efi_load_initrd.h> #include <efi_load_initrd.h>
#include <efi_variable.h> #include <efi_variable.h>

View file

@ -15,6 +15,8 @@
* Reset(): EfiSimpleNetworkInitialized -> EfiSimpleNetworkInitialized * Reset(): EfiSimpleNetworkInitialized -> EfiSimpleNetworkInitialized
*/ */
#define LOG_CATEGORY LOGC_EFI
#include <efi_loader.h> #include <efi_loader.h>
#include <dm.h> #include <dm.h>
#include <linux/sizes.h> #include <linux/sizes.h>

View file

@ -7,6 +7,7 @@
*/ */
#define LOG_CATEGORY LOGC_EFI #define LOG_CATEGORY LOGC_EFI
#include <efi_loader.h> #include <efi_loader.h>
#include <efi_variable.h> #include <efi_variable.h>
#include <log.h> #include <log.h>

View file

@ -5,6 +5,8 @@
* Copyright (c) 2018 Heinrich Schuchardt * Copyright (c) 2018 Heinrich Schuchardt
*/ */
#define LOG_CATEGORY LOGC_EFI
#include <malloc.h> #include <malloc.h>
#include <efi_dt_fixup.h> #include <efi_dt_fixup.h>
#include <efi_loader.h> #include <efi_loader.h>

View file

@ -5,6 +5,8 @@
* Copyright (c) 2016 Alexander Graf * Copyright (c) 2016 Alexander Graf
*/ */
#define LOG_CATEGORY LOGC_EFI
#include <command.h> #include <command.h>
#include <cpu_func.h> #include <cpu_func.h>
#include <dm.h> #include <dm.h>

View file

@ -4,6 +4,8 @@
* Copyright (c) 2019 Linaro Limited, Author: AKASHI Takahiro * Copyright (c) 2019 Linaro Limited, Author: AKASHI Takahiro
*/ */
#define LOG_CATEGORY LOGC_EFI
#include <charset.h> #include <charset.h>
#include <efi_loader.h> #include <efi_loader.h>
#include <efi_variable.h> #include <efi_variable.h>

View file

@ -5,6 +5,8 @@
* Copyright (c) 2020 AKASHI Takahiro, Linaro Limited * Copyright (c) 2020 AKASHI Takahiro, Linaro Limited
*/ */
#define LOG_CATEGORY LOGC_EFI
#include <charset.h> #include <charset.h>
#include <efi_loader.h> #include <efi_loader.h>
#include <malloc.h> #include <malloc.h>

View file

@ -8,6 +8,7 @@
*/ */
#define LOG_CATEGORY LOGC_EFI #define LOG_CATEGORY LOGC_EFI
#include <dm.h> #include <dm.h>
#include <efi_loader.h> #include <efi_loader.h>
#include <efi_variable.h> #include <efi_variable.h>

View file

@ -5,6 +5,8 @@
* Copyright (c) 2018 Heinrich Schuchardt <xypron.glpk@gmx.de> * Copyright (c) 2018 Heinrich Schuchardt <xypron.glpk@gmx.de>
*/ */
#define LOG_CATEGORY LOGC_EFI
#include <charset.h> #include <charset.h>
#include <cp1250.h> #include <cp1250.h>
#include <cp437.h> #include <cp437.h>

View file

@ -5,6 +5,8 @@
* Copyright (c) 2020 Linaro Limited, Author: AKASHI Takahiro * Copyright (c) 2020 Linaro Limited, Author: AKASHI Takahiro
*/ */
#define LOG_CATEGORY LOGC_EFI
#include <efi_loader.h> #include <efi_loader.h>
#include <efi_variable.h> #include <efi_variable.h>
#include <stdlib.h> #include <stdlib.h>

View file

@ -5,6 +5,8 @@
* Copyright (c) 2020, Heinrich Schuchardt * Copyright (c) 2020, Heinrich Schuchardt
*/ */
#define LOG_CATEGORY LOGC_EFI
#include <efi_loader.h> #include <efi_loader.h>
#include <efi_variable.h> #include <efi_variable.h>
#include <u-boot/crc.h> #include <u-boot/crc.h>

View file

@ -10,6 +10,8 @@
* Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com> * Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
*/ */
#define LOG_CATEGORY LOGC_EFI
#if CONFIG_IS_ENABLED(ARM_FFA_TRANSPORT) #if CONFIG_IS_ENABLED(ARM_FFA_TRANSPORT)
#include <arm_ffa.h> #include <arm_ffa.h>
#endif #endif

View file

@ -5,6 +5,8 @@
* Copyright (c) 2017 Heinrich Schuchardt * Copyright (c) 2017 Heinrich Schuchardt
*/ */
#define LOG_CATEGORY LOGC_EFI
#include <efi_loader.h> #include <efi_loader.h>
/* Conversion factor from seconds to multiples of 100ns */ /* Conversion factor from seconds to multiples of 100ns */

View file

@ -39,7 +39,6 @@ static int log_test_filter(struct unit_test_state *uts)
#define create_filter(args, filter_num) do {\ #define create_filter(args, filter_num) do {\
ut_assertok(run_command("log filter-add -p " args, 0)); \ ut_assertok(run_command("log filter-add -p " args, 0)); \
ut_assert_skipline(); \
ut_assertok(strict_strtoul(uts->actual_str, 10, &(filter_num))); \ ut_assertok(strict_strtoul(uts->actual_str, 10, &(filter_num))); \
ut_assert_console_end(); \ ut_assert_console_end(); \
} while (0) } while (0)

View file

@ -15,7 +15,8 @@
DECLARE_GLOBAL_DATA_PTR; DECLARE_GLOBAL_DATA_PTR;
/* emit some sample log records in different ways, for testing */ /* emit some sample log records in different ways, for testing */
static int do_log_run(struct unit_test_state *uts, int cat, const char *file) static int do_log_run(struct unit_test_state *uts, int cat, const char *file,
const char *func)
{ {
int i; int i;
int ret, expected_ret; int ret, expected_ret;
@ -30,13 +31,13 @@ static int do_log_run(struct unit_test_state *uts, int cat, const char *file)
for (i = LOGL_FIRST; i < LOGL_COUNT; i++) { for (i = LOGL_FIRST; i < LOGL_COUNT; i++) {
log(cat, i, "log %d\n", i); log(cat, i, "log %d\n", i);
ret = _log(log_uc_cat(cat), i, file, 100 + i, ret = _log(log_uc_cat(cat), i, file, 100 + i,
"func", "_log %d\n", i); func, "_log %d\n", i);
ut_asserteq(ret, expected_ret); ut_asserteq(ret, expected_ret);
} }
/* test with LOGL_COUNT flag */ /* test with LOGL_COUNT flag */
for (i = LOGL_FIRST; i < LOGL_COUNT; i++) { for (i = LOGL_FIRST; i < LOGL_COUNT; i++) {
ret = _log(log_uc_cat(cat), i | LOGL_FORCE_DEBUG, file, 100 + i, ret = _log(log_uc_cat(cat), i | LOGL_FORCE_DEBUG, file, 100 + i,
"func", "_log force %d\n", i); func, "_log force %d\n", i);
ut_asserteq(ret, expected_ret); ut_asserteq(ret, expected_ret);
} }
@ -44,9 +45,10 @@ static int do_log_run(struct unit_test_state *uts, int cat, const char *file)
return 0; return 0;
} }
#define log_run_cat(cat) do_log_run(uts, cat, "file") #define log_run_cat(cat) do_log_run(uts, cat, "file", "func")
#define log_run_file(file) do_log_run(uts, UCLASS_SPI, file) #define log_run_file(file) do_log_run(uts, UCLASS_SPI, file, "func")
#define log_run() do_log_run(uts, UCLASS_SPI, "file") #define log_run_func(func) do_log_run(uts, UCLASS_SPI, "file", func)
#define log_run() do_log_run(uts, UCLASS_SPI, "file", "func")
#define EXPECT_LOG BIT(0) #define EXPECT_LOG BIT(0)
#define EXPECT_DIRECT BIT(1) #define EXPECT_DIRECT BIT(1)
@ -55,7 +57,7 @@ static int do_log_run(struct unit_test_state *uts, int cat, const char *file)
#define EXPECT_DEBUG BIT(4) #define EXPECT_DEBUG BIT(4)
static int do_check_log_entries(struct unit_test_state *uts, int flags, int min, static int do_check_log_entries(struct unit_test_state *uts, int flags, int min,
int max) int max, const char *func)
{ {
int i; int i;
@ -63,7 +65,8 @@ static int do_check_log_entries(struct unit_test_state *uts, int flags, int min,
if (flags & EXPECT_LOG) if (flags & EXPECT_LOG)
ut_assert_nextline(" do_log_run() log %d", i); ut_assert_nextline(" do_log_run() log %d", i);
if (flags & EXPECT_DIRECT) if (flags & EXPECT_DIRECT)
ut_assert_nextline(" func() _log %d", i); ut_assert_nextline(" %s() _log %d", func,
i);
if (flags & EXPECT_DEBUG) { if (flags & EXPECT_DEBUG) {
ut_assert_nextline("log %d", i); ut_assert_nextline("log %d", i);
ut_assert_nextline("_log %d", i); ut_assert_nextline("_log %d", i);
@ -71,12 +74,13 @@ static int do_check_log_entries(struct unit_test_state *uts, int flags, int min,
} }
if (flags & EXPECT_EXTRA) if (flags & EXPECT_EXTRA)
for (; i <= LOGL_MAX ; i++) for (; i <= LOGL_MAX ; i++)
ut_assert_nextline(" func() _log %d", i); ut_assert_nextline(" %s() _log %d", func,
i);
for (i = LOGL_FIRST; i < LOGL_COUNT; i++) { for (i = LOGL_FIRST; i < LOGL_COUNT; i++) {
if (flags & EXPECT_FORCE) if (flags & EXPECT_FORCE)
ut_assert_nextline(" func() _log force %d", ut_assert_nextline(" %s() _log force %d",
i); func, i);
if (flags & EXPECT_DEBUG) if (flags & EXPECT_DEBUG)
ut_assert_nextline("_log force %d", i); ut_assert_nextline("_log force %d", i);
} }
@ -86,7 +90,7 @@ static int do_check_log_entries(struct unit_test_state *uts, int flags, int min,
} }
#define check_log_entries_flags_levels(flags, min, max) do {\ #define check_log_entries_flags_levels(flags, min, max) do {\
int ret = do_check_log_entries(uts, flags, min, max); \ int ret = do_check_log_entries(uts, flags, min, max, "func"); \
if (ret) \ if (ret) \
return ret; \ return ret; \
} while (0) } while (0)
@ -192,6 +196,46 @@ int log_test_file_mid(struct unit_test_state *uts)
} }
LOG_TEST_FLAGS(log_test_file_mid, UTF_CONSOLE); LOG_TEST_FLAGS(log_test_file_mid, UTF_CONSOLE);
/* Check passing and failing function filters */
int log_test_func(struct unit_test_state *uts)
{
int filt;
filt = log_add_filter_flags("console", NULL, LOGL_MAX, "file", "func",
0);
ut_assert(filt >= 0);
log_run_func("func");
check_log_entries_flags(EXPECT_DIRECT | EXPECT_EXTRA | EXPECT_FORCE);
log_run_func("fnc2");
do_check_log_entries(uts, EXPECT_FORCE, LOGL_FIRST, _LOG_MAX_LEVEL,
"fnc2");
ut_assertok(log_remove_filter("console", filt));
return 0;
}
LOG_TEST_FLAGS(log_test_func, UTF_CONSOLE);
/* Check a passing function filter (middle of list) */
int log_test_func_mid(struct unit_test_state *uts)
{
int filt;
filt = log_add_filter_flags("console", NULL, LOGL_MAX, "file",
"bad1,func,bad2", 0);
ut_assert(filt >= 0);
log_run_func("func");
check_log_entries_flags(EXPECT_DIRECT | EXPECT_EXTRA | EXPECT_FORCE);
ut_assertok(log_remove_filter("console", filt));
return 0;
}
LOG_TEST_FLAGS(log_test_func_mid, UTF_CONSOLE);
/* Check a log level filter */ /* Check a log level filter */
int log_test_level(struct unit_test_state *uts) int log_test_level(struct unit_test_state *uts)
{ {
@ -320,7 +364,7 @@ int log_test_cat_deny(struct unit_test_state *uts)
filt1 = log_add_filter("console", cat_list, LOGL_MAX, NULL); filt1 = log_add_filter("console", cat_list, LOGL_MAX, NULL);
ut_assert(filt1 >= 0); ut_assert(filt1 >= 0);
filt2 = log_add_filter_flags("console", cat_list, LOGL_MAX, NULL, filt2 = log_add_filter_flags("console", cat_list, LOGL_MAX, NULL,
LOGFF_DENY); NULL, LOGFF_DENY);
ut_assert(filt2 >= 0); ut_assert(filt2 >= 0);
log_run_cat(UCLASS_SPI); log_run_cat(UCLASS_SPI);
@ -340,7 +384,7 @@ int log_test_file_deny(struct unit_test_state *uts)
filt1 = log_add_filter("console", NULL, LOGL_MAX, "file"); filt1 = log_add_filter("console", NULL, LOGL_MAX, "file");
ut_assert(filt1 >= 0); ut_assert(filt1 >= 0);
filt2 = log_add_filter_flags("console", NULL, LOGL_MAX, "file", filt2 = log_add_filter_flags("console", NULL, LOGL_MAX, "file",
LOGFF_DENY); NULL, LOGFF_DENY);
ut_assert(filt2 >= 0); ut_assert(filt2 >= 0);
log_run_file("file"); log_run_file("file");
@ -360,7 +404,7 @@ int log_test_level_deny(struct unit_test_state *uts)
filt1 = log_add_filter("console", NULL, LOGL_INFO, NULL); filt1 = log_add_filter("console", NULL, LOGL_INFO, NULL);
ut_assert(filt1 >= 0); ut_assert(filt1 >= 0);
filt2 = log_add_filter_flags("console", NULL, LOGL_WARNING, NULL, filt2 = log_add_filter_flags("console", NULL, LOGL_WARNING, NULL,
LOGFF_DENY); NULL, LOGFF_DENY);
ut_assert(filt2 >= 0); ut_assert(filt2 >= 0);
log_run(); log_run();
@ -380,10 +424,10 @@ int log_test_min(struct unit_test_state *uts)
int filt1, filt2; int filt1, filt2;
filt1 = log_add_filter_flags("console", NULL, LOGL_WARNING, NULL, filt1 = log_add_filter_flags("console", NULL, LOGL_WARNING, NULL,
LOGFF_LEVEL_MIN); NULL, LOGFF_LEVEL_MIN);
ut_assert(filt1 >= 0); ut_assert(filt1 >= 0);
filt2 = log_add_filter_flags("console", NULL, LOGL_INFO, NULL, filt2 = log_add_filter_flags("console", NULL, LOGL_INFO, NULL,
LOGFF_DENY | LOGFF_LEVEL_MIN); NULL, LOGFF_DENY | LOGFF_LEVEL_MIN);
ut_assert(filt2 >= 0); ut_assert(filt2 >= 0);
log_run(); log_run();