14e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass/*
24e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass * libfdt - Flat Device Tree manipulation
34e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass *	Tests that fdt_next_subnode() works as expected
44e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass *
54e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass * Copyright (C) 2013 Google, Inc
64e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass *
74e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass * Copyright (C) 2007 David Gibson, IBM Corporation.
84e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass *
94e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass * This library is free software; you can redistribute it and/or
104e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass * modify it under the terms of the GNU Lesser General Public License
114e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass * as published by the Free Software Foundation; either version 2.1 of
124e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass * the License, or (at your option) any later version.
134e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass *
144e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass * This library is distributed in the hope that it will be useful, but
154e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass * WITHOUT ANY WARRANTY; without even the implied warranty of
164e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
174e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass * Lesser General Public License for more details.
184e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass *
194e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass * You should have received a copy of the GNU Lesser General Public
204e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass * License along with this library; if not, write to the Free Software
214e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
224e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass */
234e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass
244e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass#include <stdlib.h>
254e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass#include <stdio.h>
264e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass#include <string.h>
274e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass#include <stdint.h>
284e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass
294e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass#include <libfdt.h>
304e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass
314e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass#include "tests.h"
324e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass#include "testdata.h"
334e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass
344e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glassstatic void test_node(void *fdt, int parent_offset)
354e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass{
36bad5b28049e5e0562a8ad91797fb77953a53fa20David Gibson	uint32_t subnodes;
374e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass	const fdt32_t *prop;
384e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass	int offset;
394e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass	int count;
404e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass	int len;
414e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass
424e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass	/* This property indicates the number of subnodes to expect */
434e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass	prop = fdt_getprop(fdt, parent_offset, "subnodes", &len);
444e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass	if (!prop || len != sizeof(fdt32_t)) {
454e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass		FAIL("Missing/invalid subnodes property at '%s'",
464e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass		     fdt_get_name(fdt, parent_offset, NULL));
474e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass	}
48bad5b28049e5e0562a8ad91797fb77953a53fa20David Gibson	subnodes = fdt32_to_cpu(*prop);
494e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass
504e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass	count = 0;
51902d0f0953d0074b329a2780a4b637fae0d776daThierry Reding	fdt_for_each_subnode(offset, fdt, parent_offset)
524e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass		count++;
534e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass
544e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass	if (count != subnodes) {
554e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass		FAIL("Node '%s': Expected %d subnodes, got %d\n",
564e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass		     fdt_get_name(fdt, parent_offset, NULL), subnodes,
574e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass		     count);
584e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass	}
594e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass}
604e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass
614e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glassstatic void check_fdt_next_subnode(void *fdt)
624e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass{
634e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass	int offset;
644e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass	int count = 0;
654e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass
66902d0f0953d0074b329a2780a4b637fae0d776daThierry Reding	fdt_for_each_subnode(offset, fdt, 0) {
674e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass		test_node(fdt, offset);
684e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass		count++;
694e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass	}
704e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass
714e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass	if (count != 2)
724e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass		FAIL("Expected %d tests, got %d\n", 2, count);
734e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass}
744e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass
754e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glassint main(int argc, char *argv[])
764e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass{
774e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass	void *fdt;
784e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass
794e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass	test_init(argc, argv);
804e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass	if (argc != 2)
814e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass		CONFIG("Usage: %s <dtb file>", argv[0]);
824e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass
834e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass	fdt = load_blob(argv[1]);
844e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass	if (!fdt)
854e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass		FAIL("No device tree available");
864e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass
874e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass	check_fdt_next_subnode(fdt);
884e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass
894e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass	PASS();
904e76ec796c90d44d417f82d9db2d67cfe575f8edSimon Glass}
91