1 /* 2 * Some very basic tests for fdtdec, accessed through test_fdtdec command. 3 * They are easiest to use with sandbox. 4 * 5 * Copyright (c) 2011 The Chromium OS Authors. 6 * See file CREDITS for list of people who contributed to this 7 * project. 8 * 9 * This program is free software; you can redistribute it and/or 10 * modify it under the terms of the GNU General Public License as 11 * published by the Free Software Foundation; either version 2 of 12 * the License, or (at your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program; if not, write to the Free Software 21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 22 * MA 02111-1307 USA 23 */ 24 25 #include <common.h> 26 #include <fdtdec.h> 27 #include <libfdt.h> 28 #include <malloc.h> 29 #include <os.h> 30 31 /* The size of our test fdt blob */ 32 #define FDT_SIZE (16 * 1024) 33 34 /** 35 * Check if an operation failed, and if so, print an error 36 * 37 * @param oper_name Name of operation 38 * @param err Error code to check 39 * 40 * @return 0 if ok, -1 if there was an error 41 */ 42 static int fdt_checkerr(const char *oper_name, int err) 43 { 44 if (err) { 45 printf("%s: %s: %s\n", __func__, oper_name, fdt_strerror(err)); 46 return -1; 47 } 48 49 return 0; 50 } 51 52 /** 53 * Check the result of an operation and if incorrect, print an error 54 * 55 * @param oper_name Name of operation 56 * @param expected Expected value 57 * @param value Actual value 58 * 59 * @return 0 if ok, -1 if there was an error 60 */ 61 static int checkval(const char *oper_name, int expected, int value) 62 { 63 if (expected != value) { 64 printf("%s: %s: expected %d, but returned %d\n", __func__, 65 oper_name, expected, value); 66 return -1; 67 } 68 69 return 0; 70 } 71 72 #define CHECK(op) if (fdt_checkerr(#op, op)) return -1 73 #define CHECKVAL(op, expected) \ 74 if (checkval(#op, expected, op)) \ 75 return -1 76 #define CHECKOK(op) CHECKVAL(op, 0) 77 78 /* maximum number of nodes / aliases to generate */ 79 #define MAX_NODES 20 80 81 /* 82 * Make a test fdt 83 * 84 * @param fdt Device tree pointer 85 * @param size Size of device tree blob 86 * @param aliases Specifies alias assignments. Format is a list of items 87 * separated by space. Items are #a where 88 * # is the alias number 89 * a is the node to point to 90 * @param nodes Specifies nodes to generate (a=0, b=1), upper case 91 * means to create a disabled node 92 */ 93 static int make_fdt(void *fdt, int size, const char *aliases, 94 const char *nodes) 95 { 96 char name[20], value[20]; 97 const char *s; 98 int fd; 99 100 CHECK(fdt_create(fdt, size)); 101 CHECK(fdt_finish_reservemap(fdt)); 102 CHECK(fdt_begin_node(fdt, "")); 103 104 CHECK(fdt_begin_node(fdt, "aliases")); 105 for (s = aliases; *s;) { 106 sprintf(name, "i2c%c", *s); 107 sprintf(value, "/i2c%d@0", s[1] - 'a'); 108 CHECK(fdt_property_string(fdt, name, value)); 109 s += 2 + (s[2] != '\0'); 110 } 111 CHECK(fdt_end_node(fdt)); 112 113 for (s = nodes; *s; s++) { 114 sprintf(value, "i2c%d@0", (*s & 0xdf) - 'A'); 115 CHECK(fdt_begin_node(fdt, value)); 116 CHECK(fdt_property_string(fdt, "compatible", 117 fdtdec_get_compatible(COMPAT_UNKNOWN))); 118 if (*s <= 'Z') 119 CHECK(fdt_property_string(fdt, "status", "disabled")); 120 CHECK(fdt_end_node(fdt)); 121 } 122 123 CHECK(fdt_end_node(fdt)); 124 CHECK(fdt_finish(fdt)); 125 CHECK(fdt_pack(fdt)); 126 #if defined(DEBUG) && defined(CONFIG_SANDBOX) 127 fd = os_open("/tmp/fdtdec-text.dtb", OS_O_CREAT | OS_O_WRONLY); 128 if (fd == -1) { 129 printf("Could not open .dtb file to write\n"); 130 return -1; 131 } 132 os_write(fd, fdt, size); 133 os_close(fd); 134 #endif 135 return 0; 136 } 137 138 static int run_test(const char *aliases, const char *nodes, const char *expect) 139 { 140 int list[MAX_NODES]; 141 const char *s; 142 void *blob; 143 int i; 144 145 blob = malloc(FDT_SIZE); 146 if (!blob) { 147 printf("%s: out of memory\n", __func__); 148 return 1; 149 } 150 151 printf("aliases=%s, nodes=%s, expect=%s: ", aliases, nodes, expect); 152 CHECKVAL(make_fdt(blob, FDT_SIZE, aliases, nodes), 0); 153 CHECKVAL(fdtdec_find_aliases_for_id(blob, "i2c", 154 COMPAT_UNKNOWN, 155 list, ARRAY_SIZE(list)), strlen(expect)); 156 157 /* Check we got the right ones */ 158 for (i = 0, s = expect; *s; s++, i++) { 159 int want = *s; 160 const char *name; 161 int got = ' '; 162 163 name = list[i] ? fdt_get_name(blob, list[i], NULL) : NULL; 164 if (name) 165 got = name[3] + 'a' - '0'; 166 167 if (got != want) { 168 printf("Position %d: Expected '%c', got '%c' ('%s')\n", 169 i, want, got, name); 170 return 1; 171 } 172 } 173 174 printf("pass\n"); 175 return 0; 176 } 177 178 static int do_test_fdtdec(cmd_tbl_t *cmdtp, int flag, int argc, 179 char * const argv[]) 180 { 181 /* basic tests */ 182 CHECKOK(run_test("", "", "")); 183 CHECKOK(run_test("1e 3d", "", "")); 184 185 /* 186 * 'a' represents 0, 'b' represents 1, etc. 187 * The first character is the alias number, the second is the node 188 * number. So the params mean: 189 * 0a 1b : point alias 0 to node 0 (a), alias 1 to node 1(b) 190 * ab : to create nodes 0 and 1 (a and b) 191 * ab : we expect the function to return two nodes, in 192 * the order 0, 1 193 */ 194 CHECKOK(run_test("0a 1b", "ab", "ab")); 195 196 CHECKOK(run_test("0a 1c", "ab", "ab")); 197 CHECKOK(run_test("1c", "ab", "ab")); 198 CHECKOK(run_test("1b", "ab", "ab")); 199 CHECKOK(run_test("0b", "ab", "ba")); 200 CHECKOK(run_test("0b 2d", "dbc", "bcd")); 201 CHECKOK(run_test("0d 3a 1c 2b", "dbac", "dcba")); 202 203 /* things with holes */ 204 CHECKOK(run_test("1b 3d", "dbc", "cb d")); 205 CHECKOK(run_test("1e 3d", "dbc", "bc d")); 206 207 /* no aliases */ 208 CHECKOK(run_test("", "dbac", "dbac")); 209 210 /* disabled nodes */ 211 CHECKOK(run_test("0d 3a 1c 2b", "dBac", "dc a")); 212 CHECKOK(run_test("0b 2d", "DBc", "c")); 213 CHECKOK(run_test("0b 4d 2c", "DBc", " c")); 214 215 /* conflicting aliases - first one gets it */ 216 CHECKOK(run_test("2a 1a 0a", "a", " a")); 217 CHECKOK(run_test("0a 1a 2a", "a", "a")); 218 219 printf("Test passed\n"); 220 return 0; 221 } 222 223 U_BOOT_CMD( 224 test_fdtdec, 3, 1, do_test_fdtdec, 225 "test_fdtdec", 226 "Run tests for fdtdec library"); 227