
Sughosh Ganu <sughosh.ganu@linaro.org> says: This is a follow-up from an earlier RFC series [1] for making the LMB and EFI memory allocations work together. This is a non-rfc version with only the LMB part of the patches, for making the LMB memory map global and persistent. This is part one of a set of patches which aim to have the LMB and EFI memory allocations work together. This requires making the LMB memory map global and persistent, instead of having local, caller specific maps. This is being done keeping in mind the usage of LMB memory by platforms where the same memory region can be used to load multiple different images. What is not allowed is to overwrite memory that has been allocated by the other module, currently the EFI memory module. This is being achieved by introducing a new flag, LMB_NOOVERWRITE, which represents memory which cannot be re-requested once allocated. The data structures (alloced lists) required for maintaining the LMB map are initialised during board init. The LMB module is enabled by default for the main U-Boot image, while it needs to be enabled for SPL. This version also uses a stack implementation, as suggested by Simon Glass to temporarily store the lmb structure instance which is used during normal operation when running lmb tests. This does away with the need to run the lmb tests separately. The tests have been tweaked where needed because of these changes. The second part of the patches, to be sent subsequently, would work on having the EFI allocations work with the LMB API's. [1] - https://lore.kernel.org/u-boot/20240704073544.670249-1-sughosh.ganu@linaro.org/T/#t Notes: 1) These patches are on next, as the alist patches have been applied to that branch. 2) I have tested the boot on the ST DK2 board, but it would be good to get a T-b/R-b from the ST maintainers. 3) It will be good to test these changes on a PowerPC platform (ideally an 85xx, as I do not have one).
293 lines
7.6 KiB
C
293 lines
7.6 KiB
C
// SPDX-License-Identifier: GPL-2.0+
|
|
/*
|
|
* Tests for bdinfo command
|
|
*
|
|
* Copyright 2023 Marek Vasut <marek.vasut+renesas@mailbox.org>
|
|
*/
|
|
|
|
#include <alist.h>
|
|
#include <console.h>
|
|
#include <mapmem.h>
|
|
#include <asm/global_data.h>
|
|
#include <dm/uclass.h>
|
|
#include <test/suites.h>
|
|
#include <test/ut.h>
|
|
#include <dm.h>
|
|
#include <env.h>
|
|
#include <lmb.h>
|
|
#include <net.h>
|
|
#include <serial.h>
|
|
#include <video.h>
|
|
#include <vsprintf.h>
|
|
#include <asm/cache.h>
|
|
#include <asm/global_data.h>
|
|
#include <display_options.h>
|
|
|
|
DECLARE_GLOBAL_DATA_PTR;
|
|
|
|
/* Declare a new bdinfo test */
|
|
#define BDINFO_TEST(_name, _flags) UNIT_TEST(_name, _flags, bdinfo_test)
|
|
|
|
static int test_num_l(struct unit_test_state *uts, const char *name,
|
|
ulong value)
|
|
{
|
|
ut_assert_nextline("%-12s= 0x%0*lx", name, 2 * (int)sizeof(value),
|
|
value);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int test_num_ll(struct unit_test_state *uts, const char *name,
|
|
unsigned long long value)
|
|
{
|
|
ut_assert_nextline("%-12s= 0x%.*llx", name, 2 * (int)sizeof(ulong),
|
|
value);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int test_eth(struct unit_test_state *uts)
|
|
{
|
|
const int idx = eth_get_dev_index();
|
|
uchar enetaddr[6];
|
|
char name[10];
|
|
int ret;
|
|
|
|
if (idx)
|
|
sprintf(name, "eth%iaddr", idx);
|
|
else
|
|
strcpy(name, "ethaddr");
|
|
|
|
ret = eth_env_get_enetaddr_by_index("eth", idx, enetaddr);
|
|
|
|
ut_assert_nextline("current eth = %s", eth_get_name());
|
|
if (!ret)
|
|
ut_assert_nextline("%-12s= (not set)", name);
|
|
else
|
|
ut_assert_nextline("%-12s= %pM", name, enetaddr);
|
|
ut_assert_nextline("IP addr = %s", env_get("ipaddr"));
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int test_video_info(struct unit_test_state *uts)
|
|
{
|
|
const struct udevice *dev;
|
|
struct uclass *uc;
|
|
|
|
uclass_id_foreach_dev(UCLASS_VIDEO, dev, uc) {
|
|
ut_assert_nextline("%-12s= %s %sactive", "Video", dev->name,
|
|
device_active(dev) ? "" : "in");
|
|
if (device_active(dev)) {
|
|
struct video_priv *upriv = dev_get_uclass_priv(dev);
|
|
struct video_uc_plat *plat = dev_get_uclass_plat(dev);
|
|
|
|
ut_assertok(test_num_ll(uts, "FB base",
|
|
(ulong)upriv->fb));
|
|
if (upriv->copy_fb) {
|
|
ut_assertok(test_num_ll(uts, "FB copy",
|
|
(ulong)upriv->copy_fb));
|
|
ut_assertok(test_num_l(uts, " copy size",
|
|
plat->copy_size));
|
|
}
|
|
ut_assert_nextline("%-12s= %dx%dx%d", "FB size",
|
|
upriv->xsize, upriv->ysize,
|
|
1 << upriv->bpix);
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int lmb_test_dump_region(struct unit_test_state *uts,
|
|
struct alist *lmb_rgn_lst, char *name)
|
|
{
|
|
struct lmb_region *rgn = lmb_rgn_lst->data;
|
|
unsigned long long base, size, end;
|
|
enum lmb_flags flags;
|
|
int i;
|
|
|
|
ut_assert_nextline(" %s.count = 0x%hx", name, lmb_rgn_lst->count);
|
|
|
|
for (i = 0; i < lmb_rgn_lst->count; i++) {
|
|
base = rgn[i].base;
|
|
size = rgn[i].size;
|
|
end = base + size - 1;
|
|
flags = rgn[i].flags;
|
|
|
|
if (!IS_ENABLED(CONFIG_SANDBOX) && i == 3) {
|
|
ut_assert_nextlinen(" %s[%d]\t[", name, i);
|
|
continue;
|
|
}
|
|
ut_assert_nextlinen(" %s[%d]\t[0x%llx-0x%llx], 0x%08llx bytes flags: ",
|
|
name, i, base, end, size);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int lmb_test_dump_all(struct unit_test_state *uts)
|
|
{
|
|
struct lmb *lmb = lmb_get();
|
|
|
|
ut_assert_nextline("lmb_dump_all:");
|
|
ut_assertok(lmb_test_dump_region(uts, &lmb->free_mem, "memory"));
|
|
ut_assertok(lmb_test_dump_region(uts, &lmb->used_mem, "reserved"));
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int bdinfo_check_mem(struct unit_test_state *uts)
|
|
{
|
|
struct bd_info *bd = gd->bd;
|
|
int i;
|
|
|
|
for (i = 0; i < CONFIG_NR_DRAM_BANKS; ++i) {
|
|
if (bd->bi_dram[i].size) {
|
|
ut_assertok(test_num_l(uts, "DRAM bank", i));
|
|
ut_assertok(test_num_ll(uts, "-> start",
|
|
bd->bi_dram[i].start));
|
|
ut_assertok(test_num_ll(uts, "-> size",
|
|
bd->bi_dram[i].size));
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int bdinfo_test_all(struct unit_test_state *uts)
|
|
{
|
|
ut_assertok(test_num_l(uts, "boot_params", 0));
|
|
|
|
ut_assertok(bdinfo_check_mem(uts));
|
|
|
|
/* CONFIG_SYS_HAS_SRAM testing not supported */
|
|
ut_assertok(test_num_l(uts, "flashstart", 0));
|
|
ut_assertok(test_num_l(uts, "flashsize", 0));
|
|
ut_assertok(test_num_l(uts, "flashoffset", 0));
|
|
ut_assert_nextline("baudrate = %lu bps",
|
|
env_get_ulong("baudrate", 10, 1234));
|
|
ut_assertok(test_num_l(uts, "relocaddr", gd->relocaddr));
|
|
ut_assertok(test_num_l(uts, "reloc off", gd->reloc_off));
|
|
ut_assert_nextline("%-12s= %u-bit", "Build", (uint)sizeof(void *) * 8);
|
|
|
|
if (IS_ENABLED(CONFIG_CMD_NET))
|
|
ut_assertok(test_eth(uts));
|
|
|
|
/*
|
|
* Make sure environment variable "fdtcontroladdr" address
|
|
* matches mapped control DT address.
|
|
*/
|
|
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)));
|
|
|
|
if (IS_ENABLED(CONFIG_VIDEO))
|
|
ut_assertok(test_video_info(uts));
|
|
|
|
/* The gd->multi_dtb_fit may not be available, hence, #if below. */
|
|
#if CONFIG_IS_ENABLED(MULTI_DTB_FIT)
|
|
ut_assertok(test_num_l(uts, "multi_dtb_fit", (ulong)gd->multi_dtb_fit));
|
|
#endif
|
|
|
|
if (IS_ENABLED(CONFIG_LMB) && gd->fdt_blob) {
|
|
ut_assertok(lmb_test_dump_all(uts));
|
|
if (IS_ENABLED(CONFIG_OF_REAL))
|
|
ut_assert_nextline("devicetree = %s", fdtdec_get_srcname());
|
|
}
|
|
|
|
if (IS_ENABLED(CONFIG_DM_SERIAL)) {
|
|
struct serial_device_info info;
|
|
|
|
ut_assertnonnull(gd->cur_serial_dev);
|
|
ut_assertok(serial_getinfo(gd->cur_serial_dev, &info));
|
|
|
|
ut_assertok(test_num_l(uts, "serial addr", info.addr));
|
|
ut_assertok(test_num_l(uts, " width", info.reg_width));
|
|
ut_assertok(test_num_l(uts, " shift", info.reg_shift));
|
|
ut_assertok(test_num_l(uts, " offset", info.reg_offset));
|
|
ut_assertok(test_num_l(uts, " clock", info.clock));
|
|
}
|
|
|
|
if (IS_ENABLED(CONFIG_CMD_BDINFO_EXTRA)) {
|
|
ut_assert_nextlinen("stack ptr");
|
|
ut_assertok(test_num_ll(uts, "ram_top ptr",
|
|
(unsigned long long)gd->ram_top));
|
|
ut_assertok(test_num_l(uts, "malloc base", gd_malloc_start()));
|
|
}
|
|
|
|
if (IS_ENABLED(CONFIG_X86))
|
|
ut_check_skip_to_linen(uts, " high end =");
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int bdinfo_test_full(struct unit_test_state *uts)
|
|
{
|
|
/* Test BDINFO full print */
|
|
ut_assertok(run_commandf("bdinfo"));
|
|
ut_assertok(bdinfo_test_all(uts));
|
|
ut_assertok(run_commandf("bdinfo -a"));
|
|
ut_assertok(bdinfo_test_all(uts));
|
|
ut_assert_console_end();
|
|
|
|
return 0;
|
|
}
|
|
BDINFO_TEST(bdinfo_test_full, UTF_CONSOLE);
|
|
|
|
static int bdinfo_test_help(struct unit_test_state *uts)
|
|
{
|
|
/* Test BDINFO unknown option help text print */
|
|
if (!CONFIG_IS_ENABLED(GETOPT)) {
|
|
ut_asserteq(0, run_commandf("bdinfo -h"));
|
|
ut_assertok(bdinfo_test_all(uts));
|
|
} else {
|
|
ut_asserteq(1, run_commandf("bdinfo -h"));
|
|
ut_assert_nextlinen("bdinfo: invalid option -- h");
|
|
ut_assert_nextlinen("bdinfo - print Board Info structure");
|
|
ut_assert_nextline_empty();
|
|
ut_assert_nextlinen("Usage:");
|
|
ut_assert_nextlinen("bdinfo");
|
|
}
|
|
ut_assert_console_end();
|
|
|
|
return 0;
|
|
}
|
|
BDINFO_TEST(bdinfo_test_help, UTF_CONSOLE);
|
|
|
|
static int bdinfo_test_memory(struct unit_test_state *uts)
|
|
{
|
|
/* Test BDINFO memory layout only print */
|
|
ut_assertok(run_commandf("bdinfo -m"));
|
|
if (!CONFIG_IS_ENABLED(GETOPT))
|
|
ut_assertok(bdinfo_test_all(uts));
|
|
else
|
|
ut_assertok(bdinfo_check_mem(uts));
|
|
ut_assert_console_end();
|
|
|
|
return 0;
|
|
}
|
|
BDINFO_TEST(bdinfo_test_memory, UTF_CONSOLE);
|
|
|
|
static int bdinfo_test_eth(struct unit_test_state *uts)
|
|
{
|
|
/* Test BDINFO ethernet settings only print */
|
|
ut_assertok(run_commandf("bdinfo -e"));
|
|
if (!CONFIG_IS_ENABLED(GETOPT))
|
|
ut_assertok(bdinfo_test_all(uts));
|
|
else if (IS_ENABLED(CONFIG_CMD_NET))
|
|
ut_assertok(test_eth(uts));
|
|
ut_assert_console_end();
|
|
|
|
return 0;
|
|
}
|
|
BDINFO_TEST(bdinfo_test_eth, UTF_CONSOLE);
|
|
|
|
int do_ut_bdinfo(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
|
|
{
|
|
struct unit_test *tests = UNIT_TEST_SUITE_START(bdinfo_test);
|
|
const int n_ents = UNIT_TEST_SUITE_COUNT(bdinfo_test);
|
|
|
|
return cmd_ut_category("bdinfo", "bdinfo_test_", tests, n_ents, argc, argv);
|
|
}
|