platform_external_dtc/tests/overlay.c
Andre Przywara d966f08fcd tests: Fix signedness comparisons warnings
With -Wsign-compare, compilers warn about a mismatching signedness in
comparisons in various files in the tests/ directory.

For about half of the cases we can simply change the signed variable to
be of an unsigned type, because they will never need to store negative
values (which is the best fix of the problem).

In the remaining cases we can cast the signed variable to an unsigned
type, provided we know for sure it is not negative.
We see two different scenarios here:
- We either just explicitly checked for this variable to be positive
  (if (rc < 0) FAIL();), or
- We rely on a function returning only positive values in the "length"
  pointer if the function returned successfully: which we just checked.

At two occassions we compare with a constant "-1" (even though the
variable is unsigned), so we just change this to ~0U to create an
unsigned comparison value.

Since this is about the tests, let's also add explicit tests for those
values really not being negative.

This fixes "make tests" (but not "make check" yet), when compiled
with -Wsign-compare.

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Message-Id: <20210618172030.9684-2-andre.przywara@arm.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2021-06-21 15:25:44 +10:00

224 lines
4.7 KiB
C

// SPDX-License-Identifier: LGPL-2.1-or-later
/*
* libfdt - Flat Device Tree manipulation
* Testcase for DT overlays()
* Copyright (C) 2016 Free Electrons
* Copyright (C) 2016 NextThing Co.
*/
#include <stdio.h>
#include <libfdt.h>
#include "tests.h"
#define CHECK(code) \
{ \
int err = (code); \
if (err) \
FAIL(#code ": %s", fdt_strerror(err)); \
}
/* 4k ought to be enough for anybody */
#define FDT_COPY_SIZE (4 * 1024)
static int fdt_getprop_u32_by_poffset(void *fdt, const char *path,
const char *name, int poffset,
unsigned long *out)
{
const fdt32_t *val;
int node_off;
int len;
node_off = fdt_path_offset(fdt, path);
if (node_off < 0)
return node_off;
val = fdt_getprop(fdt, node_off, name, &len);
if (val && len < 0)
FAIL("fdt_getprop() returns negative length");
if (!val && len < 0)
return len;
if (!val || ((unsigned)len < (sizeof(uint32_t) * (poffset + 1))))
return -FDT_ERR_NOTFOUND;
*out = fdt32_to_cpu(*(val + poffset));
return 0;
}
static int check_getprop_string_by_name(void *fdt, const char *path,
const char *name, const char *val)
{
int node_off;
node_off = fdt_path_offset(fdt, path);
if (node_off < 0)
return node_off;
check_getprop_string(fdt, node_off, name, val);
return 0;
}
static int check_getprop_u32_by_name(void *fdt, const char *path,
const char *name, uint32_t val)
{
int node_off;
node_off = fdt_path_offset(fdt, path);
CHECK(node_off < 0);
check_getprop_cell(fdt, node_off, name, val);
return 0;
}
static int check_getprop_null_by_name(void *fdt, const char *path,
const char *name)
{
int node_off;
node_off = fdt_path_offset(fdt, path);
CHECK(node_off < 0);
check_property(fdt, node_off, name, 0, NULL);
return 0;
}
static int fdt_overlay_change_int_property(void *fdt)
{
return check_getprop_u32_by_name(fdt, "/test-node", "test-int-property",
43);
}
static int fdt_overlay_change_str_property(void *fdt)
{
return check_getprop_string_by_name(fdt, "/test-node",
"test-str-property", "foobar");
}
static int fdt_overlay_add_str_property(void *fdt)
{
return check_getprop_string_by_name(fdt, "/test-node",
"test-str-property-2", "foobar2");
}
static int fdt_overlay_add_node(void *fdt)
{
return check_getprop_null_by_name(fdt, "/test-node/new-node",
"new-property");
}
static int fdt_overlay_add_subnode_property(void *fdt)
{
check_getprop_null_by_name(fdt, "/test-node/sub-test-node",
"sub-test-property");
check_getprop_null_by_name(fdt, "/test-node/sub-test-node",
"new-sub-test-property");
return 0;
}
static int fdt_overlay_local_phandle(void *fdt)
{
uint32_t local_phandle;
unsigned long val = 0;
int off;
off = fdt_path_offset(fdt, "/test-node/new-local-node");
CHECK(off < 0);
local_phandle = fdt_get_phandle(fdt, off);
CHECK(!local_phandle);
CHECK(fdt_getprop_u32_by_poffset(fdt, "/test-node",
"test-several-phandle",
0, &val));
CHECK(val != local_phandle);
CHECK(fdt_getprop_u32_by_poffset(fdt, "/test-node",
"test-several-phandle",
1, &val));
CHECK(val != local_phandle);
return 0;
}
static int fdt_overlay_local_phandles(void *fdt)
{
uint32_t local_phandle, test_phandle;
unsigned long val = 0;
int off;
off = fdt_path_offset(fdt, "/test-node/new-local-node");
CHECK(off < 0);
local_phandle = fdt_get_phandle(fdt, off);
CHECK(!local_phandle);
off = fdt_path_offset(fdt, "/test-node");
CHECK(off < 0);
test_phandle = fdt_get_phandle(fdt, off);
CHECK(!test_phandle);
CHECK(fdt_getprop_u32_by_poffset(fdt, "/test-node",
"test-phandle", 0, &val));
CHECK(test_phandle != val);
CHECK(fdt_getprop_u32_by_poffset(fdt, "/test-node",
"test-phandle", 1, &val));
CHECK(local_phandle != val);
return 0;
}
static void *open_dt(char *path)
{
void *dt, *copy;
dt = load_blob(path);
copy = xmalloc(FDT_COPY_SIZE);
/*
* Resize our DTs to 4k so that we have room to operate on
*/
CHECK(fdt_open_into(dt, copy, FDT_COPY_SIZE));
return copy;
}
int main(int argc, char *argv[])
{
void *fdt_base, *fdt_overlay;
test_init(argc, argv);
if (argc != 3)
CONFIG("Usage: %s <base dtb> <overlay dtb>", argv[0]);
fdt_base = open_dt(argv[1]);
fdt_overlay = open_dt(argv[2]);
/* Apply the overlay */
CHECK(fdt_overlay_apply(fdt_base, fdt_overlay));
fdt_overlay_change_int_property(fdt_base);
fdt_overlay_change_str_property(fdt_base);
fdt_overlay_add_str_property(fdt_base);
fdt_overlay_add_node(fdt_base);
fdt_overlay_add_subnode_property(fdt_base);
/*
* If the base tree has a __symbols__ node, do the tests that
* are only successful with a proper phandle support, and thus
* dtc -@
*/
if (fdt_path_offset(fdt_base, "/__symbols__") >= 0) {
fdt_overlay_local_phandle(fdt_base);
fdt_overlay_local_phandles(fdt_base);
}
PASS();
}