u-boot/lib/fdtdec_test.c
Tom Rini 83d290c56f SPDX: Convert all of our single license tags to Linux Kernel style
When U-Boot started using SPDX tags we were among the early adopters and
there weren't a lot of other examples to borrow from.  So we picked the
area of the file that usually had a full license text and replaced it
with an appropriate SPDX-License-Identifier: entry.  Since then, the
Linux Kernel has adopted SPDX tags and they place it as the very first
line in a file (except where shebangs are used, then it's second line)
and with slightly different comment styles than us.

In part due to community overlap, in part due to better tag visibility
and in part for other minor reasons, switch over to that style.

This commit changes all instances where we have a single declared
license in the tag as both the before and after are identical in tag
contents.  There's also a few places where I found we did not have a tag
and have introduced one.

Signed-off-by: Tom Rini <trini@konsulko.com>
2018-05-07 09:34:12 -04:00

211 lines
5.1 KiB
C

// SPDX-License-Identifier: GPL-2.0+
/*
* Some very basic tests for fdtdec, accessed through test_fdtdec command.
* They are easiest to use with sandbox.
*
* Copyright (c) 2011 The Chromium OS Authors.
*/
#include <common.h>
#include <fdtdec.h>
#include <linux/libfdt.h>
#include <malloc.h>
#include <os.h>
/* The size of our test fdt blob */
#define FDT_SIZE (16 * 1024)
/**
* Check if an operation failed, and if so, print an error
*
* @param oper_name Name of operation
* @param err Error code to check
*
* @return 0 if ok, -1 if there was an error
*/
static int fdt_checkerr(const char *oper_name, int err)
{
if (err) {
printf("%s: %s: %s\n", __func__, oper_name, fdt_strerror(err));
return -1;
}
return 0;
}
/**
* Check the result of an operation and if incorrect, print an error
*
* @param oper_name Name of operation
* @param expected Expected value
* @param value Actual value
*
* @return 0 if ok, -1 if there was an error
*/
static int checkval(const char *oper_name, int expected, int value)
{
if (expected != value) {
printf("%s: %s: expected %d, but returned %d\n", __func__,
oper_name, expected, value);
return -1;
}
return 0;
}
#define CHECK(op) if (fdt_checkerr(#op, op)) return -1
#define CHECKVAL(op, expected) \
if (checkval(#op, expected, op)) \
return -1
#define CHECKOK(op) CHECKVAL(op, 0)
/* maximum number of nodes / aliases to generate */
#define MAX_NODES 20
/*
* Make a test fdt
*
* @param fdt Device tree pointer
* @param size Size of device tree blob
* @param aliases Specifies alias assignments. Format is a list of items
* separated by space. Items are #a where
* # is the alias number
* a is the node to point to
* @param nodes Specifies nodes to generate (a=0, b=1), upper case
* means to create a disabled node
*/
static int make_fdt(void *fdt, int size, const char *aliases,
const char *nodes)
{
char name[20], value[20];
const char *s;
int fd;
CHECK(fdt_create(fdt, size));
CHECK(fdt_finish_reservemap(fdt));
CHECK(fdt_begin_node(fdt, ""));
CHECK(fdt_begin_node(fdt, "aliases"));
for (s = aliases; *s;) {
sprintf(name, "i2c%c", *s);
sprintf(value, "/i2c%d@0", s[1] - 'a');
CHECK(fdt_property_string(fdt, name, value));
s += 2 + (s[2] != '\0');
}
CHECK(fdt_end_node(fdt));
for (s = nodes; *s; s++) {
sprintf(value, "i2c%d@0", (*s & 0xdf) - 'A');
CHECK(fdt_begin_node(fdt, value));
CHECK(fdt_property_string(fdt, "compatible",
fdtdec_get_compatible(COMPAT_UNKNOWN)));
if (*s <= 'Z')
CHECK(fdt_property_string(fdt, "status", "disabled"));
CHECK(fdt_end_node(fdt));
}
CHECK(fdt_end_node(fdt));
CHECK(fdt_finish(fdt));
CHECK(fdt_pack(fdt));
#if defined(DEBUG) && defined(CONFIG_SANDBOX)
fd = os_open("/tmp/fdtdec-text.dtb", OS_O_CREAT | OS_O_WRONLY);
if (fd == -1) {
printf("Could not open .dtb file to write\n");
return -1;
}
os_write(fd, fdt, size);
os_close(fd);
#endif
return 0;
}
static int run_test(const char *aliases, const char *nodes, const char *expect)
{
int list[MAX_NODES];
const char *s;
void *blob;
int i;
blob = malloc(FDT_SIZE);
if (!blob) {
printf("%s: out of memory\n", __func__);
return 1;
}
printf("aliases=%s, nodes=%s, expect=%s: ", aliases, nodes, expect);
CHECKVAL(make_fdt(blob, FDT_SIZE, aliases, nodes), 0);
CHECKVAL(fdtdec_find_aliases_for_id(blob, "i2c",
COMPAT_UNKNOWN,
list, ARRAY_SIZE(list)), strlen(expect));
/* Check we got the right ones */
for (i = 0, s = expect; *s; s++, i++) {
int want = *s;
const char *name;
int got = ' ';
name = list[i] ? fdt_get_name(blob, list[i], NULL) : NULL;
if (name)
got = name[3] + 'a' - '0';
if (got != want) {
printf("Position %d: Expected '%c', got '%c' ('%s')\n",
i, want, got, name);
return 1;
}
}
printf("pass\n");
return 0;
}
static int do_test_fdtdec(cmd_tbl_t *cmdtp, int flag, int argc,
char * const argv[])
{
/* basic tests */
CHECKOK(run_test("", "", ""));
CHECKOK(run_test("1e 3d", "", ""));
/*
* 'a' represents 0, 'b' represents 1, etc.
* The first character is the alias number, the second is the node
* number. So the params mean:
* 0a 1b : point alias 0 to node 0 (a), alias 1 to node 1(b)
* ab : to create nodes 0 and 1 (a and b)
* ab : we expect the function to return two nodes, in
* the order 0, 1
*/
CHECKOK(run_test("0a 1b", "ab", "ab"));
CHECKOK(run_test("0a 1c", "ab", "ab"));
CHECKOK(run_test("1c", "ab", "ab"));
CHECKOK(run_test("1b", "ab", "ab"));
CHECKOK(run_test("0b", "ab", "ba"));
CHECKOK(run_test("0b 2d", "dbc", "bcd"));
CHECKOK(run_test("0d 3a 1c 2b", "dbac", "dcba"));
/* things with holes */
CHECKOK(run_test("1b 3d", "dbc", "cb d"));
CHECKOK(run_test("1e 3d", "dbc", "bc d"));
/* no aliases */
CHECKOK(run_test("", "dbac", "dbac"));
/* disabled nodes */
CHECKOK(run_test("0d 3a 1c 2b", "dBac", "dc a"));
CHECKOK(run_test("0b 2d", "DBc", "c"));
CHECKOK(run_test("0b 4d 2c", "DBc", " c"));
/* conflicting aliases - first one gets it */
CHECKOK(run_test("2a 1a 0a", "a", " a"));
CHECKOK(run_test("0a 1a 2a", "a", "a"));
printf("Test passed\n");
return 0;
}
U_BOOT_CMD(
test_fdtdec, 3, 1, do_test_fdtdec,
"test_fdtdec",
"Run tests for fdtdec library");