Blame view
lib/fdtdec_test.c
8.5 KB
83d290c56 SPDX: Convert all... |
1 |
// SPDX-License-Identifier: GPL-2.0+ |
dc254f382 fdt: Add tests fo... |
2 3 4 5 6 |
/* * 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. |
dc254f382 fdt: Add tests fo... |
7 8 9 10 |
*/ #include <common.h> #include <fdtdec.h> |
b08c8c487 libfdt: move head... |
11 |
#include <linux/libfdt.h> |
dc254f382 fdt: Add tests fo... |
12 13 14 15 16 |
#include <malloc.h> #include <os.h> /* The size of our test fdt blob */ #define FDT_SIZE (16 * 1024) |
a95460a45 fdtdec: test: Use... |
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
#define CHECK(op) ({ \ int err = op; \ if (err < 0) { \ printf("%s: %s: %s ", __func__, #op, \ fdt_strerror(err)); \ return err; \ } \ \ err; \ }) #define CHECKVAL(op, expected) ({ \ int err = op; \ if (err != expected) { \ printf("%s: %s: expected %d, but returned %d ",\ __func__, #op, expected, err); \ return err; \ } \ \ err; \ }) |
dc254f382 fdt: Add tests fo... |
40 |
|
dc254f382 fdt: Add tests fo... |
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
#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; |
3db600c3e fdtdec: test: Fix... |
63 |
#if defined(DEBUG) && defined(CONFIG_SANDBOX) |
dc254f382 fdt: Add tests fo... |
64 |
int fd; |
3db600c3e fdtdec: test: Fix... |
65 |
#endif |
dc254f382 fdt: Add tests fo... |
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
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 "); 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 ", __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, |
a95460a45 fdtdec: test: Use... |
124 |
list, ARRAY_SIZE(list)), (int)strlen(expect)); |
dc254f382 fdt: Add tests fo... |
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
/* 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') ", i, want, got, name); return 1; } } printf("pass "); |
848e94d0b fdtdec: test: Fix... |
146 |
free(blob); |
dc254f382 fdt: Add tests fo... |
147 148 |
return 0; } |
4e4bde30c fdtdec: test: Add... |
149 150 151 152 153 154 155 156 157 158 159 160 161 162 |
static int make_fdt_carveout_device(void *fdt, uint32_t na, uint32_t ns) { const char *basename = "/display"; struct fdt_memory carveout = { #ifdef CONFIG_PHYS_64BIT .start = 0x180000000, .end = 0x18fffffff, #else .start = 0x80000000, .end = 0x8fffffff, #endif }; fdt32_t cells[4], *ptr = cells; uint32_t upper, lower; |
3bf2f1535 fdtdec: Remove fd... |
163 |
fdt_size_t size; |
4e4bde30c fdtdec: test: Add... |
164 165 166 167 |
char name[32]; int offset; /* store one or two address cells */ |
3bf2f1535 fdtdec: Remove fd... |
168 169 |
upper = upper_32_bits(carveout.start); lower = lower_32_bits(carveout.start); |
4e4bde30c fdtdec: test: Add... |
170 171 172 173 174 175 176 177 178 179 180 181 182 |
if (na > 1 && upper > 0) snprintf(name, sizeof(name), "%s@%x,%x", basename, upper, lower); else snprintf(name, sizeof(name), "%s@%x", basename, lower); if (na > 1) *ptr++ = cpu_to_fdt32(upper); *ptr++ = cpu_to_fdt32(lower); /* store one or two size cells */ |
3bf2f1535 fdtdec: Remove fd... |
183 184 185 |
size = carveout.end - carveout.start + 1; upper = upper_32_bits(size); lower = lower_32_bits(size); |
4e4bde30c fdtdec: test: Add... |
186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 |
if (ns > 1) *ptr++ = cpu_to_fdt32(upper); *ptr++ = cpu_to_fdt32(lower); offset = CHECK(fdt_add_subnode(fdt, 0, name + 1)); CHECK(fdt_setprop(fdt, offset, "reg", cells, (na + ns) * sizeof(*cells))); return fdtdec_set_carveout(fdt, name, "memory-region", 0, "framebuffer", &carveout); } static int check_fdt_carveout(void *fdt, uint32_t address_cells, uint32_t size_cells) { #ifdef CONFIG_PHYS_64BIT const char *name = "/display@1,80000000"; const struct fdt_memory expected = { .start = 0x180000000, .end = 0x18fffffff, }; #else const char *name = "/display@80000000"; const struct fdt_memory expected = { .start = 0x80000000, .end = 0x8fffffff, }; #endif struct fdt_memory carveout; printf("carveout: %pap-%pap na=%u ns=%u: ", &expected.start, &expected.end, address_cells, size_cells); CHECK(fdtdec_get_carveout(fdt, name, "memory-region", 0, &carveout)); if ((carveout.start != expected.start) || (carveout.end != expected.end)) { printf("carveout: %pap-%pap, expected %pap-%pap ", &carveout.start, &carveout.end, &expected.start, &expected.end); return 1; } printf("pass "); return 0; } static int make_fdt_carveout(void *fdt, int size, uint32_t address_cells, uint32_t size_cells) { fdt32_t na = cpu_to_fdt32(address_cells); fdt32_t ns = cpu_to_fdt32(size_cells); #if defined(DEBUG) && defined(CONFIG_SANDBOX) char filename[512]; int fd; #endif int err; CHECK(fdt_create(fdt, size)); CHECK(fdt_finish_reservemap(fdt)); CHECK(fdt_begin_node(fdt, "")); CHECK(fdt_property(fdt, "#address-cells", &na, sizeof(na))); CHECK(fdt_property(fdt, "#size-cells", &ns, sizeof(ns))); CHECK(fdt_end_node(fdt)); CHECK(fdt_finish(fdt)); CHECK(fdt_pack(fdt)); CHECK(fdt_open_into(fdt, fdt, FDT_SIZE)); err = make_fdt_carveout_device(fdt, address_cells, size_cells); #if defined(DEBUG) && defined(CONFIG_SANDBOX) snprintf(filename, sizeof(filename), "/tmp/fdtdec-carveout-%u-%u.dtb", address_cells, size_cells); fd = os_open(filename, OS_O_CREAT | OS_O_WRONLY); if (fd < 0) { printf("could not open .dtb file to write "); goto out; } os_write(fd, fdt, size); os_close(fd); out: #endif return err; } static int check_carveout(void) { void *fdt; fdt = malloc(FDT_SIZE); if (!fdt) { printf("%s: out of memory ", __func__); return 1; } #ifndef CONFIG_PHYS_64BIT CHECKVAL(make_fdt_carveout(fdt, FDT_SIZE, 1, 1), 0); CHECKOK(check_fdt_carveout(fdt, 1, 1)); CHECKVAL(make_fdt_carveout(fdt, FDT_SIZE, 1, 2), 0); CHECKOK(check_fdt_carveout(fdt, 1, 2)); #else CHECKVAL(make_fdt_carveout(fdt, FDT_SIZE, 1, 1), -FDT_ERR_BADVALUE); CHECKVAL(make_fdt_carveout(fdt, FDT_SIZE, 1, 2), -FDT_ERR_BADVALUE); #endif CHECKVAL(make_fdt_carveout(fdt, FDT_SIZE, 2, 1), 0); CHECKOK(check_fdt_carveout(fdt, 2, 1)); CHECKVAL(make_fdt_carveout(fdt, FDT_SIZE, 2, 2), 0); CHECKOK(check_fdt_carveout(fdt, 2, 2)); |
848e94d0b fdtdec: test: Fix... |
303 |
free(fdt); |
4e4bde30c fdtdec: test: Add... |
304 305 |
return 0; } |
dc254f382 fdt: Add tests fo... |
306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 |
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")); |
4e4bde30c fdtdec: test: Add... |
346 |
CHECKOK(check_carveout()); |
dc254f382 fdt: Add tests fo... |
347 348 349 350 351 352 353 354 355 |
printf("Test passed "); return 0; } U_BOOT_CMD( test_fdtdec, 3, 1, do_test_fdtdec, "test_fdtdec", "Run tests for fdtdec library"); |