Merge patch series "global_data: Reduce size of struct global_data"

Simon Glass <sjg@chromium.org> says:

The global data structure has grown quite a lot over the years, being
the best place to put an important pointer or something that must be
accessed before and after relocation.

This series attempts to reduce the size a little, by moving some things
out and shrinking and aligning some fields.

Some fields are needed during init but not afterwards. To deal with this
a new 'boardf' structure is created, which sits on the stack and is only
present during board_init_f(). It is possible that more fields could
move to this struct, but for now only 4 are moved.

An assumption is made that an int is 32-bits wide on all architectures,
which seems to be true, but maintainers should be able to confirm.

Mostly the code-size impact is neutral, but the patch
'Use less space for environment fields' does increase U-Boot's size by
about 30 bytes on aarch64.

For firefly-rk3399 (64-bit) the size of global reduces from 456 to 368
bytes. For SPL it reduces from 416 to 272 bytes.

There are other things which could be attempted, for example:
- Using hlist instead of list for some lists
- Checking that only necessary fields are present in SPL
This commit is contained in:
Tom Rini 2024-08-26 14:06:16 -06:00
commit 02d587a447
52 changed files with 379 additions and 337 deletions

View file

@ -117,7 +117,7 @@ static void mxs_spl_console_init(void)
gd->bd = &bdata;
gd->baudrate = CONFIG_BAUDRATE;
serial_init();
gd->have_console = 1;
gd->flags |= GD_FLG_HAVE_CONSOLE;
#endif
}

View file

@ -58,7 +58,7 @@ void arch_print_bdinfo(void)
printf("Board Type = %ld\n", gd->board_type);
#endif
#if CONFIG_IS_ENABLED(SYS_MALLOC_F)
printf("Early malloc usage: %lx / %x\n", gd->malloc_ptr,
printf("Early malloc usage: %x / %x\n", gd->malloc_ptr,
CONFIG_VAL(SYS_MALLOC_F_LEN));
#endif
}

View file

@ -312,7 +312,7 @@ static void setup_global_data(gd_t *gdp)
memzero((void *)gd, sizeof(gd_t));
gd->flags |= GD_FLG_RELOC;
gd->baudrate = CONFIG_BAUDRATE;
gd->have_console = 1;
gd->flags |= GD_FLG_HAVE_CONSOLE;
}
void board_init_f(unsigned long bootflag)

View file

@ -104,7 +104,7 @@ int early_console_init(void)
gd->cur_serial_dev = dev;
gd->flags |= GD_FLG_SERIAL_READY;
gd->have_console = 1;
gd->flags |= GD_FLG_HAVE_CONSOLE;
return 0;
}

View file

@ -451,7 +451,7 @@ void k3_sysfw_loader(bool rom_loaded_sysfw,
* the case when continuing to boot serially from the same
* UART that the ROM loaded the initial bootloader from.
*/
if (!gd->have_console)
if (!(gd->flags & GD_FLG_HAVE_CONSOLE))
early_console_init();
#endif
ret = spl_ymodem_load_image(&spl_image, &bootdev);

View file

@ -423,10 +423,6 @@ int dram_init_banksize(void)
gd->bd->bi_dram[0].start = CFG_SYS_SDRAM_BASE;
gd->bd->bi_dram[0].size = usable_ram_size_below_4g();
#ifdef CONFIG_PCI
gd->pci_ram_top = gd->bd->bi_dram[0].start + gd->bd->bi_dram[0].size;
#endif
#ifdef CONFIG_PHYS_64BIT
if (gd->ram_size > SZ_2G) {
gd->bd->bi_dram[1].start = 0x100000000;

View file

@ -189,10 +189,6 @@ int cboot_dram_init_banksize(void)
gd->bd->bi_dram[i].size = tegra_mem_map[1 + i].size;
}
#ifdef CONFIG_PCI
gd->pci_ram_top = ram_top;
#endif
return 0;
}

View file

@ -92,7 +92,7 @@ int print_cpuinfo(void)
strmhz(buf3, gd->arch.flb_clk));
#ifdef CONFIG_PCI
printf(" PCI CLK %s MHz INP CLK %s MHz VCO CLK %s MHz\n",
strmhz(buf1, gd->pci_clk),
strmhz(buf1, gd->arch.pci_clk),
strmhz(buf2, gd->arch.inp_clk),
strmhz(buf3, gd->arch.vco_clk));
#else

View file

@ -26,6 +26,8 @@ struct arch_global_data {
#if defined(CONFIG_FSL_ESDHC)
unsigned long sdhc_per_clk;
#endif
/** @pci_clk: PCI clock rate in Hz */
unsigned long pci_clk;
};
#include <asm-generic/global_data.h>

View file

@ -22,7 +22,7 @@ int arch_setup_bdinfo(void)
bd->bi_busfreq = gd->bus_clk; /* Bus Freq, in Hz */
if (IS_ENABLED(CONFIG_PCI))
bd->bi_pcifreq = gd->pci_clk;
bd->bi_pcifreq = gd->arch.pci_clk;
#if defined(CONFIG_EXTRA_CLOCK)
bd->bi_inpfreq = gd->arch.inp_clk; /* input Freq in Hz */

View file

@ -327,8 +327,8 @@ int do_ar934x_showclk(struct cmd_tbl *cmdtp, int flag, int argc,
{
ar934x_update_clock();
printf("CPU: %8ld MHz\n", gd->cpu_clk / 1000000);
printf("Memory: %8ld MHz\n", gd->mem_clk / 1000000);
printf("AHB: %8ld MHz\n", gd->bus_clk / 1000000);
printf("Memory: %8d MHz\n", gd->mem_clk / 1000000);
printf("AHB: %8d MHz\n", gd->bus_clk / 1000000);
return 0;
}

View file

@ -67,7 +67,7 @@ static int get_clocks(void)
gd->cpu_clk = ref_clock * FIELD_GET(RST_BOOT_C_MUL, val);
gd->bus_clk = ref_clock * FIELD_GET(RST_BOOT_PNR_MUL, val);
debug("%s: cpu: %lu, bus: %lu\n", __func__, gd->cpu_clk, gd->bus_clk);
debug("%s: cpu: %lu, bus: %u\n", __func__, gd->cpu_clk, gd->bus_clk);
return 0;
}

View file

@ -45,7 +45,7 @@ void ft_pci_setup(void *blob, struct bd_info *bd)
do_fixup_by_path(blob, path, "bus-range",
&tmp, sizeof(tmp), 1);
tmp[0] = cpu_to_be32(gd->pci_clk);
tmp[0] = cpu_to_be32(gd->arch.pci_clk);
do_fixup_by_path(blob, path, "clock-frequency",
&tmp, sizeof(tmp[0]), 1);
}
@ -60,7 +60,7 @@ void ft_pci_setup(void *blob, struct bd_info *bd)
do_fixup_by_path(blob, path, "bus-range",
&tmp, sizeof(tmp), 1);
tmp[0] = cpu_to_be32(gd->pci_clk);
tmp[0] = cpu_to_be32(gd->arch.pci_clk);
do_fixup_by_path(blob, path, "clock-frequency",
&tmp, sizeof(tmp[0]), 1);
}

View file

@ -456,7 +456,7 @@ int get_clocks(void)
#if defined(CONFIG_ARCH_MPC837X)
gd->arch.sata_clk = sata_clk;
#endif
gd->pci_clk = pci_sync_in;
gd->arch.pci_clk = pci_sync_in;
gd->cpu_clk = gd->arch.core_clk;
gd->bus_clk = gd->arch.csb_clk;
return 0;

View file

@ -87,6 +87,8 @@ struct arch_global_data {
#if defined(CONFIG_LWMON5)
unsigned long kbd_status;
#endif
/** @pci_clk: PCI clock rate in Hz */
unsigned long pci_clk;
};
#include <asm-generic/global_data.h>

View file

@ -412,12 +412,6 @@ int cpu_phys_address_size(void)
return 32;
}
/* Don't allow PCI region 3 to use memory in the 2-4GB memory hole */
static void setup_pci_ram_top(void)
{
gd_set_pci_ram_top(0x80000000U);
}
static void setup_mtrr(void)
{
u64 mtrr_cap;
@ -469,7 +463,6 @@ int x86_cpu_init_f(void)
setup_cpu_features();
setup_identity();
setup_mtrr();
setup_pci_ram_top();
/* Set up the i8254 timer if required */
if (IS_ENABLED(CONFIG_I8254_TIMER))
@ -483,7 +476,6 @@ int x86_cpu_reinit_f(void)
long addr;
setup_identity();
setup_pci_ram_top();
addr = locate_coreboot_table();
if (addr >= 0) {
gd->arch.coreboot_table = addr;

View file

@ -24,9 +24,7 @@ int arch_cpu_init(void)
int ret;
#if CONFIG_IS_ENABLED(HANDOFF) && IS_ENABLED(CONFIG_USE_HOB)
struct spl_handoff *ho = gd->spl_handoff;
gd->arch.hob_list = ho->arch.hob_list;
gd->arch.hob_list = handoff_get();
#endif
ret = x86_cpu_reinit_f();

View file

@ -55,7 +55,6 @@ int arch_cpu_init(void)
static int ivybridge_cpu_init(void)
{
struct pci_controller *hose;
struct udevice *bus, *dev;
int ret;
@ -65,10 +64,6 @@ static int ivybridge_cpu_init(void)
if (ret)
return ret;
post_code(0x72);
hose = dev_get_uclass_priv(bus);
/* TODO(sjg@chromium.org): Get rid of gd->hose */
gd->hose = hose;
ret = uclass_first_device_err(UCLASS_LPC, &dev);
if (ret)

View file

@ -103,7 +103,6 @@ static int fsp_video_probe(struct udevice *dev)
* For IGD, it seems to be always on BAR2.
*/
vesa->phys_base_ptr = dm_pci_read_bar32(dev, 2);
gd->fb_base = vesa->phys_base_ptr;
ret = vesa_setup_video_priv(vesa, vesa->phys_base_ptr, uc_priv, plat);
if (ret)

View file

@ -59,7 +59,7 @@ int dram_init(void)
#endif
} else {
#if CONFIG_IS_ENABLED(HANDOFF)
struct spl_handoff *ho = gd->spl_handoff;
struct spl_handoff *ho = handoff_get();
if (!ho) {
log_debug("No SPL handoff found\n");
@ -82,7 +82,7 @@ phys_addr_t board_get_usable_ram_top(phys_size_t total_size)
return gd->ram_size;
#if CONFIG_IS_ENABLED(HANDOFF)
struct spl_handoff *ho = gd->spl_handoff;
struct spl_handoff *ho = handoff_get();
log_debug("usable_ram_top = %lx\n", ho->arch.usable_ram_top);

View file

@ -12,7 +12,7 @@ DECLARE_GLOBAL_DATA_PTR;
int board_eth_init(struct bd_info *bis)
{
#ifdef CONFIG_PHY_AQUANTIA
#if defined(CONFIG_PHY_AQUANTIA) && !defined(CONFIG_SPL_BUILD)
/*
* Export functions to be used by AQ firmware
* upload application

View file

@ -11,6 +11,7 @@
#ifdef CONFIG_PWM_NX
#include <pwm.h>
#endif
#include <video.h>
#include <asm/global_data.h>
#include <asm/io.h>
@ -492,12 +493,8 @@ int splash_screen_prepare(void)
ARRAY_SIZE(splash_locations));
}
if (!err) {
char addr[64];
sprintf(addr, "0x%lx", gd->fb_base);
env_set("fb_addr", addr);
}
if (!err)
env_set_hex("fb_addr", video_get_fb());
return err;
}

View file

@ -9,6 +9,7 @@
#include <config.h>
#include <init.h>
#include <video.h>
#include <asm/global_data.h>
#include <linux/sizes.h>
#include <asm/io.h>
@ -110,11 +111,12 @@ int dram_init_banksize(void)
#ifdef CONFIG_DISPLAY_BOARDINFO
int checkboard (void)
{
ulong fb_base = video_get_fb();
char *ss;
printf ("Board : Ronetix PM9263\n");
switch (gd->fb_base) {
switch (fb_base) {
case PHYS_PSRAM:
ss = "(PSRAM)";
break;
@ -127,7 +129,7 @@ int checkboard (void)
ss = "";
break;
}
printf("Video memory : 0x%08lX %s\n", gd->fb_base, ss );
printf("Video memory : 0x%08lX %s\n", fb_base, ss);
printf ("\n");
return 0;

View file

@ -36,7 +36,7 @@ void set_mux_conf_regs(void)
/* enable early the console */
gd->baudrate = CONFIG_BAUDRATE;
serial_init();
gd->have_console = 1;
gd->flags |= GD_FLG_HAVE_CONSOLE;
siemens_ee_setup();
if (draco_read_eeprom() < 0)

View file

@ -154,8 +154,6 @@ static int bdinfo_print_all(struct bd_info *bd)
if (IS_ENABLED(CONFIG_CMD_NET))
print_eth();
bdinfo_print_num_l("fdt_blob", (ulong)map_to_sysmem(gd->fdt_blob));
bdinfo_print_num_l("new_fdt", (ulong)map_to_sysmem(gd->new_fdt));
bdinfo_print_num_l("fdt_size", (ulong)gd->fdt_size);
if (IS_ENABLED(CONFIG_VIDEO))
show_video_info();
#if CONFIG_IS_ENABLED(MULTI_DTB_FIT)

View file

@ -14,8 +14,10 @@ static int do_sb_handoff(struct cmd_tbl *cmdtp, int flag, int argc,
char *const argv[])
{
#if CONFIG_IS_ENABLED(HANDOFF)
if (gd->spl_handoff)
printf("SPL handoff magic %lx\n", gd->spl_handoff->arch.magic);
struct spl_handoff *handoff = handoff_get();
if (handoff)
printf("SPL handoff magic %lx\n", handoff->arch.magic);
else
printf("SPL handoff info not received\n");

View file

@ -305,17 +305,6 @@ static int setup_mon_len(void)
return 0;
}
static int setup_spl_handoff(void)
{
#if CONFIG_IS_ENABLED(HANDOFF)
gd->spl_handoff = bloblist_find(BLOBLISTT_U_BOOT_SPL_HANDOFF,
sizeof(struct spl_handoff));
debug("Found SPL hand-off info %p\n", gd->spl_handoff);
#endif
return 0;
}
__weak int arch_cpu_init(void)
{
return 0;
@ -351,7 +340,7 @@ __weak int arch_setup_dest_addr(void)
static int setup_dest_addr(void)
{
debug("Monitor len: %08lX\n", gd->mon_len);
debug("Monitor len: %08x\n", gd->mon_len);
/*
* Ram is setup, size stored in gd !!
*/
@ -488,7 +477,7 @@ static int reserve_uboot(void)
gd->relocaddr &= ~(65536 - 1);
#endif
debug("Reserving %ldk for U-Boot at: %08lx\n",
debug("Reserving %dk for U-Boot at: %08lx\n",
gd->mon_len >> 10, gd->relocaddr);
}
@ -575,12 +564,15 @@ static int reserve_fdt(void)
* section, then it will be relocated with other data.
*/
if (gd->fdt_blob) {
gd->fdt_size = ALIGN(fdt_totalsize(gd->fdt_blob), 32);
gd->boardf->fdt_size =
ALIGN(fdt_totalsize(gd->fdt_blob), 32);
gd->start_addr_sp = reserve_stack_aligned(gd->fdt_size);
gd->new_fdt = map_sysmem(gd->start_addr_sp, gd->fdt_size);
gd->start_addr_sp = reserve_stack_aligned(
gd->boardf->fdt_size);
gd->boardf->new_fdt = map_sysmem(gd->start_addr_sp,
gd->boardf->fdt_size);
debug("Reserving %lu Bytes for FDT at: %08lx\n",
gd->fdt_size, gd->start_addr_sp);
gd->boardf->fdt_size, gd->start_addr_sp);
}
}
@ -593,7 +585,7 @@ static int reserve_bootstage(void)
int size = bootstage_get_size();
gd->start_addr_sp = reserve_stack_aligned(size);
gd->new_bootstage = map_sysmem(gd->start_addr_sp, size);
gd->boardf->new_bootstage = map_sysmem(gd->start_addr_sp, size);
debug("Reserving %#x Bytes for bootstage at: %08lx\n", size,
gd->start_addr_sp);
#endif
@ -624,7 +616,7 @@ static int reserve_bloblist(void)
/* Align to a 4KB boundary for easier reading of addresses */
gd->start_addr_sp = ALIGN_DOWN(gd->start_addr_sp -
CONFIG_BLOBLIST_SIZE_RELOC, 0x1000);
gd->new_bloblist = map_sysmem(gd->start_addr_sp,
gd->boardf->new_bloblist = map_sysmem(gd->start_addr_sp,
CONFIG_BLOBLIST_SIZE_RELOC);
#endif
@ -668,10 +660,10 @@ static int init_post(void)
static int reloc_fdt(void)
{
if (!IS_ENABLED(CONFIG_OF_EMBED)) {
if (gd->new_fdt) {
memcpy(gd->new_fdt, gd->fdt_blob,
if (gd->boardf->new_fdt) {
memcpy(gd->boardf->new_fdt, gd->fdt_blob,
fdt_totalsize(gd->fdt_blob));
gd->fdt_blob = gd->new_fdt;
gd->fdt_blob = gd->boardf->new_fdt;
}
}
@ -683,9 +675,8 @@ static int reloc_bootstage(void)
#ifdef CONFIG_BOOTSTAGE
if (gd->flags & GD_FLG_SKIP_RELOC)
return 0;
if (gd->new_bootstage) {
bootstage_relocate(gd->new_bootstage);
}
if (gd->boardf->new_bootstage)
bootstage_relocate(gd->boardf->new_bootstage);
#endif
return 0;
@ -702,10 +693,11 @@ static int reloc_bloblist(void)
debug("Not relocating bloblist\n");
return 0;
}
if (gd->new_bloblist) {
if (gd->boardf->new_bloblist) {
debug("Copying bloblist from %p to %p, size %x\n",
gd->bloblist, gd->new_bloblist, gd->bloblist->total_size);
return bloblist_reloc(gd->new_bloblist,
gd->bloblist, gd->boardf->new_bloblist,
gd->bloblist->total_size);
return bloblist_reloc(gd->boardf->new_bloblist,
CONFIG_BLOBLIST_SIZE_RELOC);
}
#endif
@ -888,7 +880,6 @@ static const init_fnc_t init_sequence_f[] = {
initf_bootstage, /* uses its own timer, so does not need DM */
event_init,
bloblist_maybe_init,
setup_spl_handoff,
#if defined(CONFIG_CONSOLE_RECORD_INIT_F)
console_record_init,
#endif
@ -1021,8 +1012,11 @@ static const init_fnc_t init_sequence_f[] = {
void board_init_f(ulong boot_flags)
{
struct board_f boardf;
gd->flags = boot_flags;
gd->have_console = 0;
gd->flags &= ~GD_FLG_HAVE_CONSOLE;
gd->boardf = &boardf;
if (initcall_run_list(init_sequence_f))
hang();

View file

@ -192,7 +192,7 @@ static int initr_malloc(void)
ulong start;
#if CONFIG_IS_ENABLED(SYS_MALLOC_F)
debug("Pre-reloc malloc() used %#lx bytes (%ld KB)\n", gd->malloc_ptr,
debug("Pre-reloc malloc() used %#x bytes (%d KB)\n", gd->malloc_ptr,
gd->malloc_ptr / 1024);
#endif
/* The malloc area is immediately below the monitor copy in DRAM */

View file

@ -189,6 +189,7 @@ static int console_setfile(int file, struct stdio_dev * dev)
/* Assign the new device (leaving the existing one started) */
stdio_devices[file] = dev;
#ifndef CONFIG_SPL_BUILD
/*
* Update monitor functions
* (to use the console stuff by other applications)
@ -206,7 +207,7 @@ static int console_setfile(int file, struct stdio_dev * dev)
break;
}
break;
#endif
default: /* Invalid file ID */
error = -1;
}
@ -586,7 +587,7 @@ int getchar(void)
if (IS_ENABLED(CONFIG_DISABLE_CONSOLE) && (gd->flags & GD_FLG_DISABLE_CONSOLE))
return 0;
if (!gd->have_console)
if (!(gd->flags & GD_FLG_HAVE_CONSOLE))
return 0;
ch = console_record_getc();
@ -607,7 +608,7 @@ int tstc(void)
if (IS_ENABLED(CONFIG_DISABLE_CONSOLE) && (gd->flags & GD_FLG_DISABLE_CONSOLE))
return 0;
if (!gd->have_console)
if (!(gd->flags & GD_FLG_HAVE_CONSOLE))
return 0;
if (console_record_tstc())
@ -715,7 +716,7 @@ void putc(const char c)
if (IS_ENABLED(CONFIG_DISABLE_CONSOLE) && (gd->flags & GD_FLG_DISABLE_CONSOLE))
return;
if (!gd->have_console)
if (!(gd->flags & GD_FLG_HAVE_CONSOLE))
return pre_console_putc(c);
if (gd->flags & GD_FLG_DEVINIT) {
@ -759,7 +760,7 @@ void puts(const char *s)
if (IS_ENABLED(CONFIG_DISABLE_CONSOLE) && (gd->flags & GD_FLG_DISABLE_CONSOLE))
return;
if (!gd->have_console)
if (!(gd->flags & GD_FLG_HAVE_CONSOLE))
return pre_console_puts(s);
if (gd->flags & GD_FLG_DEVINIT) {
@ -793,7 +794,7 @@ void flush(void)
if (IS_ENABLED(CONFIG_DISABLE_CONSOLE) && (gd->flags & GD_FLG_DISABLE_CONSOLE))
return;
if (!gd->have_console)
if (!(gd->flags & GD_FLG_HAVE_CONSOLE))
return;
if (gd->flags & GD_FLG_DEVINIT) {
@ -872,7 +873,7 @@ static int ctrlc_disabled = 0; /* see disable_ctrl() */
static int ctrlc_was_pressed = 0;
int ctrlc(void)
{
if (!ctrlc_disabled && gd->have_console) {
if (!ctrlc_disabled && (gd->flags & GD_FLG_HAVE_CONSOLE)) {
if (tstc()) {
switch (getchar()) {
case 0x03: /* ^C - Control C */
@ -1011,7 +1012,7 @@ int console_announce_r(void)
/* Called before relocation - use serial functions */
int console_init_f(void)
{
gd->have_console = 1;
gd->flags |= GD_FLG_HAVE_CONSOLE;
console_update_silent();

View file

@ -77,7 +77,13 @@ static const char *__hwconfig(const char *opt, size_t *arglen,
/* if we are passed a buffer use it, otherwise try the environment */
if (!env_hwconfig) {
if (!(gd->flags & GD_FLG_ENV_READY) && gd->env_valid != ENV_VALID) {
#if CONFIG_IS_ENABLED(ENV_SUPPORT)
if (!(gd->flags & GD_FLG_ENV_READY) &&
gd->env_valid != ENV_VALID)
#else
if (true)
#endif
{
printf("WARNING: Calling __hwconfig without a buffer "
"and before environment is ready\n");
return NULL;

View file

@ -5,6 +5,7 @@
* Copyright 2018 Google, Inc
*/
#include <bloblist.h>
#include <handoff.h>
#include <asm/global_data.h>
@ -38,3 +39,14 @@ void handoff_load_dram_banks(struct spl_handoff *ho)
bd->bi_dram[i].size = ho->ram_bank[i].size;
}
}
struct spl_handoff *handoff_get(void)
{
struct spl_handoff *handoff;
handoff = bloblist_find(BLOBLISTT_U_BOOT_SPL_HANDOFF,
sizeof(struct spl_handoff));
debug("Found SPL hand-off info %p\n", handoff);
return handoff;
}

View file

@ -23,7 +23,7 @@ static void *alloc_simple(size_t bytes, int align)
addr = ALIGN(gd->malloc_base + gd->malloc_ptr, align);
new_ptr = addr + bytes - gd->malloc_base;
log_debug("size=%lx, ptr=%lx, limit=%lx: ", (ulong)bytes, new_ptr,
log_debug("size=%lx, ptr=%lx, limit=%x: ", (ulong)bytes, new_ptr,
gd->malloc_limit);
if (new_ptr > gd->malloc_limit) {
log_err("alloc space exhausted\n");
@ -87,6 +87,6 @@ void free_simple(void *ptr)
void malloc_simple_info(void)
{
log_info("malloc_simple: %lx bytes used, %lx remain\n", gd->malloc_ptr,
log_info("malloc_simple: %x bytes used, %x remain\n", gd->malloc_ptr,
CONFIG_VAL(SYS_MALLOC_F_LEN) - gd->malloc_ptr);
}

View file

@ -782,7 +782,7 @@ void board_init_r(gd_t *dummy1, ulong dummy2)
}
if (CONFIG_IS_ENABLED(SYS_MALLOC_F) &&
!IS_ENABLED(CONFIG_SPL_SYS_MALLOC_SIZE))
debug("SPL malloc() used 0x%lx bytes (%ld KB)\n",
debug("SPL malloc() used 0x%x bytes (%d KB)\n",
gd_malloc_ptr(), gd_malloc_ptr() / 1024);
bootstage_mark_name(get_bootstage_id(false), "end phase");
@ -838,7 +838,7 @@ void preloader_console_init(void)
serial_init(); /* serial communications setup */
gd->have_console = 1;
gd->flags |= GD_FLG_HAVE_CONSOLE;
#if CONFIG_IS_ENABLED(BANNER_PRINT)
puts("\nU-Boot " SPL_TPL_NAME " " PLAIN_VERSION " (" U_BOOT_DATE " - "
@ -901,7 +901,7 @@ ulong spl_relocate_stack_gd(void)
#if defined(CONFIG_SPL_SYS_MALLOC_SIMPLE) && CONFIG_IS_ENABLED(SYS_MALLOC_F)
if (CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN) {
debug("SPL malloc() before relocation used 0x%lx bytes (%ld KB)\n",
debug("SPL malloc() before relocation used 0x%x bytes (%d KB)\n",
gd->malloc_ptr, gd->malloc_ptr / 1024);
ptr -= CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN;
gd->malloc_base = ptr;

View file

@ -51,6 +51,31 @@ U-Boot. The value of gd has to be saved every time U-Boot is left and restored
whenever U-Boot is reentered. This is also relevant for the implementation of
function tracing. For setting the value of gd function set_gd() can be used.
Guidelines
----------
The global_data structure is placed in some memory which is available very early
after boot to allow for a minimum set of global variables during system
initialisation (until the memory controller is set up and RAM can be used). It
is the primary data structure passed from pre-relocation U-Boot to
post-relocation, i.e. ``from board_init_f()`` ``to board_init_r()``.
The global_data struct exists for the lifetime of U-Boot. Since the struct is
used by all architectures, fields added should be useful for most architectures.
Fields which are only needed on one or two architectures can be placed in the
architecture-specific ``struct arch_global_data``.
In any case the struct should be kept small, since it uses precious SRAM on
many boards.
SPL also uses global data, as well as U-Boot proper, so take care to avoid
adding fields to SPL which are not actually used by SPL. You can create
access functions or macros in the header file to avoid filling the C code with
#ifdefs.
A flags word is available, which provides a convenient means to track the state
of various initialisation phases within U-Boot.
Global data structure
---------------------

View file

@ -1,10 +1,9 @@
# SPDX-License-Identifier: GPL-2.0+
#
# (C) Copyright 2014 Google, Inc
# Simon Glass <sjg@chromium.org>
.. SPDX-License-Identifier: GPL-2.0+
.. (C) Copyright 2014 Google, Inc
.. sectionauthor:: Simon Glass <sjg@chromium.org>
Background
----------
Generic board
-------------
U-Boot traditionally had a board.c file for each architecture. This introduced
quite a lot of duplication, with each architecture tending to do
@ -16,7 +15,7 @@ All boards and architectures have moved to this as of mid 2016.
What has changed?
-----------------
~~~~~~~~~~~~~~~~~
The main change is that the arch/<arch>/lib/board.c file is removed in
favour of common/board_f.c (for pre-relocation init) and common/board_r.c
@ -28,7 +27,7 @@ have been moved to separate structures.
Further Background
------------------
~~~~~~~~~~~~~~~~~~
The full text of the original generic board series is reproduced below.
@ -132,4 +131,6 @@ convenience.
Simon Glass, sjg@chromium.org
March 2014
Updated after final removal, May 2016

View file

@ -0,0 +1,12 @@
.. SPDX-License-Identifier: GPL-2.0+
Historical Documents
====================
This section provides documentation about major changes in U-Boot over the
years.
.. toctree::
:maxdepth: 1
generic_board

View file

@ -99,3 +99,11 @@ Code quality
:maxdepth: 1
python_cq
Historical documentation
------------------------
.. toctree::
:maxdepth: 2
historical/index

View file

@ -358,7 +358,7 @@ static int mpc83xx_clk_probe(struct udevice *dev)
gd->mem_clk = priv->speed[MPC83XX_CLK_MEM];
if (mpc83xx_has_pci(type))
gd->pci_clk = priv->speed[MPC83XX_CLK_PCI];
gd->arch.pci_clk = priv->speed[MPC83XX_CLK_PCI];
gd->cpu_clk = priv->speed[MPC83XX_CLK_CORE];
gd->bus_clk = priv->speed[MPC83XX_CLK_CSB];

View file

@ -8,6 +8,7 @@
#include <dm.h>
#include <dt-structs.h>
#include <errno.h>
#include <handoff.h>
#include <log.h>
#include <malloc.h>
#include <mapmem.h>
@ -1467,7 +1468,7 @@ static int rk3399_clk_probe(struct udevice *dev)
init_clocks = true;
#elif CONFIG_IS_ENABLED(HANDOFF)
if (!(gd->flags & GD_FLG_RELOC)) {
if (!(gd->spl_handoff))
if (!handoff_get())
init_clocks = true;
}
#endif

View file

@ -403,7 +403,6 @@ static int mxcfb_map_video_memory(struct fb_info *fbi)
(uint32_t) fbi->fix.smem_start, fbi->fix.smem_len);
fbi->screen_size = fbi->fix.smem_len;
gd->fb_base = fbi->fix.smem_start;
/* Clear the screen */
memset((char *)fbi->screen_base, 0, fbi->fix.smem_len);
@ -633,7 +632,6 @@ static int ipuv3_video_probe(struct udevice *dev)
mmu_set_region_dcache_behaviour(fb_start, fb_end - fb_start,
DCACHE_WRITEBACK);
video_set_flush_dcache(dev, true);
gd->fb_base = fb_start;
return 0;
}

View file

@ -335,7 +335,6 @@ static int mxs_video_probe(struct udevice *dev)
mmu_set_region_dcache_behaviour(fb_start, fb_end - fb_start,
DCACHE_WRITEBACK);
video_set_flush_dcache(dev, true);
gd->fb_base = plat->base;
return ret;
}

View file

@ -145,13 +145,26 @@ int video_reserve(ulong *addrp)
*addrp -= CONFIG_VAL(VIDEO_PCI_DEFAULT_FB_SIZE);
gd->video_bottom = *addrp;
gd->fb_base = *addrp;
debug("Video frame buffers from %lx to %lx\n", gd->video_bottom,
gd->video_top);
return 0;
}
ulong video_get_fb(void)
{
struct udevice *dev;
uclass_find_first_device(UCLASS_VIDEO, &dev);
if (dev) {
const struct video_uc_plat *uc_plat = dev_get_uclass_plat(dev);
return uc_plat->base;
}
return 0;
}
int video_fill_part(struct udevice *dev, int xstart, int ystart, int xend,
int yend, u32 colour)
{
@ -210,7 +223,6 @@ int video_reserve_from_bloblist(struct video_handoff *ho)
return -ENOENT;
gd->video_bottom = ho->fb;
gd->fb_base = ho->fb;
gd->video_top = ho->fb + ho->size;
debug("%s: Reserving %lx bytes at %08x as per bloblist received\n",
__func__, (unsigned long)ho->size, (u32)ho->fb);

View file

@ -49,7 +49,7 @@ static void dma_init_video_descriptor(struct udevice *dev)
DPDMA_DESCRIPTOR_ADDR_EXT_SRC_ADDR_EXT_SHIFT) |
(upper_32_bits((u64)&cur_desc)));
cur_desc.next_desr = lower_32_bits((u64)&cur_desc);
cur_desc.src_addr = lower_32_bits((u64)gd->fb_base);
cur_desc.src_addr = lower_32_bits((u64)video_get_fb());
}
static void dma_set_descriptor_address(struct udevice *dev)
@ -2134,7 +2134,6 @@ static int zynqmp_dpsub_probe(struct udevice *dev)
dev_dbg(dev, "BPP in bits %d, bpix %d\n",
priv->non_live_graphics->bpp, uc_priv->bpix);
uc_priv->fb = (void *)gd->fb_base;
uc_priv->xsize = vidc_video_timing_modes[priv->video_mode].video_timing.h_active;
uc_priv->ysize = vidc_video_timing_modes[priv->video_mode].video_timing.v_active;
/* Calculated by core but need it for my own setup */

View file

@ -20,6 +20,7 @@
*/
#ifndef __ASSEMBLY__
#include <board_f.h>
#include <cyclic.h>
#include <event_internal.h>
#include <fdtdec.h>
@ -42,39 +43,141 @@ struct global_data {
* @bd: board information
*/
struct bd_info *bd;
/**
* @new_gd: pointer to relocated global data
*/
struct global_data *new_gd;
/**
* @fdt_blob: U-Boot's own device tree, NULL if none
*/
const void *fdt_blob;
/**
* @cur_serial_dev: current serial device
*/
struct udevice *cur_serial_dev;
#ifndef CONFIG_SPL_BUILD
/**
* @jt: jump table
*
* The jump table contains pointers to exported functions. A pointer to
* the jump table is passed to standalone applications.
*/
struct jt_funcs *jt;
/**
* @boardf: information only used before relocation
*/
struct board_f *boardf;
#endif
/**
* @ram_size: RAM size in bytes
*/
phys_size_t ram_size;
/**
* @ram_top: top address of RAM used by U-Boot
*/
phys_addr_t ram_top;
/**
* @flags: global data flags
*
* See &enum gd_flags
*/
unsigned long flags;
/**
* @baudrate: baud rate of the serial interface
*/
unsigned int baudrate;
/**
* @cpu_clk: CPU clock rate in Hz
*/
unsigned long cpu_clk;
#if CONFIG_IS_ENABLED(ENV_SUPPORT)
/**
* @env_addr: address of environment structure
*
* @env_addr contains the address of the structure holding the
* environment variables.
*/
unsigned long env_addr;
#endif /* ENV_SUPPORT */
/**
* @ram_base: base address of RAM used by U-Boot
*/
unsigned long ram_base;
/**
* @relocaddr: start address of U-Boot in RAM
*
* After relocation this field indicates the address to which U-Boot
* has been relocated. It can be displayed using the bdinfo command.
* Its value is needed to display the source code when debugging with
* GDB using the 'add-symbol-file u-boot <relocaddr>' command.
*/
unsigned long relocaddr;
/**
* @irq_sp: IRQ stack pointer
*/
unsigned long irq_sp;
/**
* @start_addr_sp: initial stack pointer address
*/
unsigned long start_addr_sp;
/**
* @reloc_off: relocation offset
*/
unsigned long reloc_off;
/**
* @bus_clk: platform clock rate in Hz
*/
unsigned long bus_clk;
/**
* @pci_clk: PCI clock rate in Hz
*/
/* We cannot bracket this with CONFIG_PCI due to mpc5xxx */
unsigned long pci_clk;
unsigned int bus_clk;
/**
* @mem_clk: memory clock rate in Hz
*/
unsigned long mem_clk;
#if CONFIG_IS_ENABLED(VIDEO)
unsigned int mem_clk;
/**
* @fb_base: base address of frame buffer memory
* @mon_len: monitor length in bytes
*/
unsigned long fb_base;
#endif
unsigned int mon_len;
/**
* @baudrate: baud rate of the serial interface
*/
unsigned int baudrate;
#if CONFIG_IS_ENABLED(ENV_SUPPORT)
/**
* @env_has_init: bit mask indicating environment locations
*
* &enum env_location defines which bit relates to which location
*/
unsigned short env_has_init;
/**
* @env_valid: environment is valid
*
* See &enum env_valid
*/
unsigned char env_valid;
/**
* @env_load_prio: priority of the loaded environment
*/
char env_load_prio;
/**
* @env_buf: buffer for env_get() before reloc
*/
char env_buf[32];
#endif /* ENV_SUPPORT */
/**
* @fdt_src: Source of FDT
*/
enum fdt_source_t fdt_src;
/**
* @arch: architecture-specific data
*/
struct arch_global_data arch;
/**
* @dmtag_list: List of DM tags
*/
struct list_head dmtag_list;
/**
* @timebase_h: high 32 bits of timer
*/
unsigned int timebase_h;
/**
* @timebase_l: low 32 bits of timer
*/
unsigned int timebase_l;
#if defined(CONFIG_POST)
/**
* @post_log_word: active POST tests
@ -104,15 +207,6 @@ struct global_data {
*/
unsigned long board_type;
#endif
/**
* @have_console: console is available
*
* A value of 1 indicates that serial_init() was called and a console
* is available.
* A value of 0 indicates that console input and output drivers shall
* not be called.
*/
unsigned long have_console;
#if CONFIG_IS_ENABLED(PRE_CONSOLE_BUFFER)
/**
* @precon_buf_idx: pre-console buffer index
@ -126,71 +220,6 @@ struct global_data {
*/
long precon_buf_idx;
#endif
/**
* @env_addr: address of environment structure
*
* @env_addr contains the address of the structure holding the
* environment variables.
*/
unsigned long env_addr;
/**
* @env_valid: environment is valid
*
* See &enum env_valid
*/
unsigned long env_valid;
/**
* @env_has_init: bit mask indicating environment locations
*
* &enum env_location defines which bit relates to which location
*/
unsigned long env_has_init;
/**
* @env_load_prio: priority of the loaded environment
*/
int env_load_prio;
/**
* @ram_base: base address of RAM used by U-Boot
*/
unsigned long ram_base;
/**
* @ram_top: top address of RAM used by U-Boot
*/
phys_addr_t ram_top;
/**
* @relocaddr: start address of U-Boot in RAM
*
* After relocation this field indicates the address to which U-Boot
* has been relocated. It can be displayed using the bdinfo command.
* Its value is needed to display the source code when debugging with
* GDB using the 'add-symbol-file u-boot <relocaddr>' command.
*/
unsigned long relocaddr;
/**
* @ram_size: RAM size in bytes
*/
phys_size_t ram_size;
/**
* @mon_len: monitor length in bytes
*/
unsigned long mon_len;
/**
* @irq_sp: IRQ stack pointer
*/
unsigned long irq_sp;
/**
* @start_addr_sp: initial stack pointer address
*/
unsigned long start_addr_sp;
/**
* @reloc_off: relocation offset
*/
unsigned long reloc_off;
/**
* @new_gd: pointer to relocated global data
*/
struct global_data *new_gd;
#ifdef CONFIG_DM
/**
* @dm_root: root instance for Driver Model
@ -235,46 +264,18 @@ struct global_data {
*/
struct udevice *timer;
#endif
/**
* @fdt_blob: U-Boot's own device tree, NULL if none
*/
const void *fdt_blob;
/**
* @new_fdt: relocated device tree
*/
void *new_fdt;
/**
* @fdt_size: space reserved for relocated device space
*/
unsigned long fdt_size;
/**
* @fdt_src: Source of FDT
*/
enum fdt_source_t fdt_src;
#if CONFIG_IS_ENABLED(OF_LIVE)
/**
* @of_root: root node of the live tree
*/
struct device_node *of_root;
#endif
#if CONFIG_IS_ENABLED(MULTI_DTB_FIT)
/**
* @multi_dtb_fit: pointer to uncompressed multi-dtb FIT image
*/
const void *multi_dtb_fit;
#endif
/**
* @jt: jump table
*
* The jump table contains pointers to exported functions. A pointer to
* the jump table is passed to standalone applications.
*/
struct jt_funcs *jt;
/**
* @env_buf: buffer for env_get() before reloc
*/
char env_buf[32];
#ifdef CONFIG_TRACE
/**
* @trace_buff: trace buffer
@ -290,18 +291,10 @@ struct global_data {
*/
int cur_i2c_bus;
#endif
/**
* @timebase_h: high 32 bits of timer
*/
unsigned int timebase_h;
/**
* @timebase_l: low 32 bits of timer
*/
unsigned int timebase_l;
#if CONFIG_IS_ENABLED(CMD_BDINFO_EXTRA)
/**
* @malloc_start: start of malloc() region
*/
#if CONFIG_IS_ENABLED(CMD_BDINFO_EXTRA)
unsigned long malloc_start;
#endif
#if CONFIG_IS_ENABLED(SYS_MALLOC_F)
@ -310,43 +303,14 @@ struct global_data {
*/
unsigned long malloc_base;
/**
* @malloc_limit: limit address of early malloc()
* @malloc_limit: maximum size of early malloc()
*/
unsigned long malloc_limit;
unsigned int malloc_limit;
/**
* @malloc_ptr: current address of early malloc()
* @malloc_ptr: currently used bytes of early malloc()
*/
unsigned long malloc_ptr;
unsigned int malloc_ptr;
#endif
#ifdef CONFIG_PCI
/**
* @hose: PCI hose for early use
*/
struct pci_controller *hose;
/**
* @pci_ram_top: top of region accessible to PCI
*/
phys_addr_t pci_ram_top;
#endif
#ifdef CONFIG_PCI_BOOTDELAY
/**
* @pcidelay_done: delay time before scanning of PIC hose expired
*
* If CONFIG_PCI_BOOTDELAY=y, pci_hose_scan() waits for the number of
* milliseconds defined by environment variable pcidelay before
* scanning. Once this delay has expired the flag @pcidelay_done
* is set to 1.
*/
int pcidelay_done;
#endif
/**
* @cur_serial_dev: current serial device
*/
struct udevice *cur_serial_dev;
/**
* @arch: architecture-specific data
*/
struct arch_global_data arch;
#ifdef CONFIG_CONSOLE_RECORD
/**
* @console_out: output buffer for console recording
@ -377,12 +341,18 @@ struct global_data {
* @bootstage: boot stage information
*/
struct bootstage_data *bootstage;
/**
* @new_bootstage: relocated boot stage information
*/
struct bootstage_data *new_bootstage;
#endif
#ifdef CONFIG_LOG
/**
* @log_head: list of logging devices
*/
struct list_head log_head;
/**
* @log_fmt: bit mask for logging format
*
* The @log_fmt bit mask selects the fields to be shown in log messages.
* &enum log_fmt defines the bits of the bit mask.
*/
/**
* @log_drop_count: number of dropped log messages
*
@ -397,19 +367,26 @@ struct global_data {
* For logging devices without filters @default_log_level defines the
* logging level, cf. &enum log_level_t.
*/
int default_log_level;
char default_log_level;
char log_fmt;
/**
* @log_head: list of logging devices
*/
struct list_head log_head;
/**
* @log_fmt: bit mask for logging format
* @logc_prev: logging category of previous message
*
* The @log_fmt bit mask selects the fields to be shown in log messages.
* &enum log_fmt defines the bits of the bit mask.
* This value is used as logging category for continuation messages.
*/
int log_fmt;
unsigned char logc_prev;
/**
* @logl_prev: logging level of the previous message
*
* This value is used as logging level for continuation messages.
*/
unsigned char logl_prev;
/**
* @log_cont: Previous log line did not finished wtih \n
*
* This allows for chained log messages on the same line
*/
bool log_cont;
/**
* @processing_msg: a log message is being processed
*
@ -417,40 +394,12 @@ struct global_data {
* while another message is being processed.
*/
bool processing_msg;
/**
* @logc_prev: logging category of previous message
*
* This value is used as logging category for continuation messages.
*/
int logc_prev;
/**
* @logl_prev: logging level of the previous message
*
* This value is used as logging level for continuation messages.
*/
int logl_prev;
/**
* @log_cont: Previous log line did not finished wtih \n
*
* This allows for chained log messages on the same line
*/
bool log_cont;
#endif
#if CONFIG_IS_ENABLED(BLOBLIST)
/**
* @bloblist: blob list information
*/
struct bloblist_hdr *bloblist;
/**
* @new_bloblist: relocated blob list information
*/
struct bloblist_hdr *new_bloblist;
#endif
#if CONFIG_IS_ENABLED(HANDOFF)
/**
* @spl_handoff: SPL hand-off information
*/
struct spl_handoff *spl_handoff;
#endif
#if defined(CONFIG_TRANSLATION_OFFSET)
/**
@ -488,10 +437,6 @@ struct global_data {
*/
struct hlist_head cyclic_list;
#endif
/**
* @dmtag_list: List of DM tags
*/
struct list_head dmtag_list;
#if CONFIG_IS_ENABLED(UPL)
/**
* @upl: Universal Payload-handoff information
@ -585,12 +530,6 @@ static_assert(sizeof(struct global_data) == GD_SIZE);
#define gd_set_malloc_start(val)
#endif
#if CONFIG_IS_ENABLED(PCI)
#define gd_set_pci_ram_top(val) gd->pci_ram_top = val
#else
#define gd_set_pci_ram_top(val)
#endif
#if CONFIG_VAL(SYS_MALLOC_F_LEN)
#define gd_malloc_ptr() gd->malloc_ptr
#else
@ -720,6 +659,12 @@ enum gd_flags {
* @GD_FLG_UPL: Read/write a Universal Payload (UPL) handoff
*/
GD_FLG_UPL = 0x4000000,
/**
* @GD_FLG_HAVE_CONSOLE: serial_init() was called and a console
* is available. When not set, indicates that console input and output
* drivers shall not be called.
*/
GD_FLG_HAVE_CONSOLE = 0x8000000,
};
#endif /* __ASSEMBLY__ */

35
include/board_f.h Normal file
View file

@ -0,0 +1,35 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright 2024 Google LLC
* Written by: Simon Glass <sjg@chromeium.org>
*/
#ifndef __BOARD_F
#define __BOARD_F
/**
* struct board_f: Information used only before relocation
*
* This struct is set up in board_init_f() and used to deal with relocation. It
* is not available after relocation.
*/
struct board_f {
/**
* @new_fdt: relocated device tree
*/
void *new_fdt;
/**
* @fdt_size: space reserved for relocated device space
*/
unsigned long fdt_size;
/**
* @new_bootstage: relocated boot stage information
*/
struct bootstage_data *new_bootstage;
/**
* @new_bloblist: relocated blob list information
*/
struct bloblist_hdr *new_bloblist;
};
#endif

View file

@ -82,9 +82,6 @@ const char default_environment[] = {
#ifdef CONFIG_SYS_LOAD_ADDR
"loadaddr=" __stringify(CONFIG_SYS_LOAD_ADDR)"\0"
#endif
#if defined(CONFIG_PCI_BOOTDELAY) && (CONFIG_PCI_BOOTDELAY > 0)
"pcidelay=" __stringify(CONFIG_PCI_BOOTDELAY)"\0"
#endif
#ifdef CONFIG_ENV_VARS_UBOOT_CONFIG
"arch=" CONFIG_SYS_ARCH "\0"
#ifdef CONFIG_SYS_CPU

View file

@ -100,6 +100,7 @@ extern const char default_environment[];
#include <env_flags.h>
#include <search.h>
/* this is stored as bits in gd->env_has_init so is limited to 16 entries */
enum env_location {
ENVL_UNKNOWN,
ENVL_EEPROM,

View file

@ -31,6 +31,13 @@ void handoff_save_dram(struct spl_handoff *ho);
void handoff_load_dram_size(struct spl_handoff *ho);
void handoff_load_dram_banks(struct spl_handoff *ho);
/**
* handoff_get() - Get the SPL handoff information
*
* Return: Pointer to SPL handoff if received, else NULL
*/
struct spl_handoff *handoff_get(void);
/**
* handoff_arch_save() - Save arch-specific info into the handoff area
*

View file

@ -420,4 +420,15 @@ int bmp_info(ulong addr);
*/
int video_reserve_from_bloblist(struct video_handoff *ho);
/**
* video_get_fb() - Get the first framebuffer address
*
* This function does not probe video devices, so can only be used after a video
* device has been activated.
*
* Return: address of the framebuffer of the first video device found, or 0 if
* there is no device
*/
ulong video_get_fb(void);
#endif

View file

@ -44,7 +44,9 @@ int main(void)
DEFINE(GD_NEW_GD, offsetof(struct global_data, new_gd));
#if CONFIG_IS_ENABLED(ENV_SUPPORT)
DEFINE(GD_ENV_ADDR, offsetof(struct global_data, env_addr));
#endif
return 0;
}

View file

@ -185,9 +185,6 @@ static int bdinfo_test_all(struct unit_test_state *uts)
ut_assert(map_to_sysmem(gd->fdt_blob) == env_get_hex("fdtcontroladdr", 0x1234));
ut_assertok(test_num_l(uts, "fdt_blob",
(ulong)map_to_sysmem(gd->fdt_blob)));
ut_assertok(test_num_l(uts, "new_fdt",
(ulong)map_to_sysmem(gd->new_fdt)));
ut_assertok(test_num_l(uts, "fdt_size", (ulong)gd->fdt_size));
if (IS_ENABLED(CONFIG_VIDEO))
ut_assertok(test_video_info(uts));

View file

@ -379,9 +379,9 @@ int log_test_level_deny(struct unit_test_state *uts)
ut_assertok(console_record_reset_enable());
log_run();
check_log_entries_flags_levels(EXPECT_LOG | EXPECT_DIRECT | EXPECT_FORCE,
LOGL_WARNING + 1,
min(gd->default_log_level, LOGL_INFO));
check_log_entries_flags_levels(
EXPECT_LOG | EXPECT_DIRECT | EXPECT_FORCE,
LOGL_WARNING + 1, min((int)gd->default_log_level, LOGL_INFO));
ut_assertok(log_remove_filter("console", filt1));
ut_assertok(log_remove_filter("console", filt2));