Blame view
cmd/itest.c
4.16 KB
83d290c56 SPDX: Convert all... |
1 |
// SPDX-License-Identifier: GPL-2.0+ |
2d1a537d8 * Patch by Thomas... |
2 3 4 |
/* * (C) Copyright 2003 * Tait Electronics Limited, Christchurch, New Zealand |
2d1a537d8 * Patch by Thomas... |
5 6 7 8 9 10 11 12 13 14 15 16 |
*/ /* * This file provides a shell like 'test' function to return * true/false from an integer or string compare of two memory * locations or a location and a scalar/literal. * A few parts were lifted from bash 'test' command */ #include <common.h> #include <config.h> #include <command.h> |
7b51b576d env: Move env_get... |
17 |
#include <env.h> |
7861204c9 itest: make memor... |
18 19 20 |
#include <mapmem.h> #include <asm/io.h> |
2d1a537d8 * Patch by Thomas... |
21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
#define EQ 0 #define NE 1 #define LT 2 #define GT 3 #define LE 4 #define GE 5 struct op_tbl_s { char *op; /* operator string */ int opcode; /* internal representation of opcode */ }; typedef struct op_tbl_s op_tbl_t; |
fc9903f38 cmd_itest: consti... |
35 |
static const op_tbl_t op_table [] = { |
2d1a537d8 * Patch by Thomas... |
36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
{ "-lt", LT }, { "<" , LT }, { "-gt", GT }, { ">" , GT }, { "-eq", EQ }, { "==" , EQ }, { "-ne", NE }, { "!=" , NE }, { "<>" , NE }, { "-ge", GE }, { ">=" , GE }, { "-le", LE }, { "<=" , LE }, }; |
2d1a537d8 * Patch by Thomas... |
50 51 |
static long evalexp(char *s, int w) { |
f3651764e cmd_itest.c: fix ... |
52 |
long l = 0; |
7861204c9 itest: make memor... |
53 54 |
unsigned long addr; void *buf; |
2d1a537d8 * Patch by Thomas... |
55 56 57 |
/* if the parameter starts with a * then assume is a pointer to the value we want */ if (s[0] == '*') { |
7861204c9 itest: make memor... |
58 59 |
addr = simple_strtoul(&s[1], NULL, 16); buf = map_physmem(addr, w, MAP_WRBACK); |
986fe3781 itest: allow map_... |
60 |
if (!buf && addr) { |
7861204c9 itest: make memor... |
61 62 63 64 |
puts("Failed to map physical memory "); return 0; } |
f3651764e cmd_itest.c: fix ... |
65 |
switch (w) { |
736d1746f itest: add missin... |
66 |
case 1: |
dafd64888 cmd: replace the ... |
67 |
l = (long)(*(u8 *)buf); |
736d1746f itest: add missin... |
68 69 |
break; case 2: |
dafd64888 cmd: replace the ... |
70 |
l = (long)(*(u16 *)buf); |
736d1746f itest: add missin... |
71 72 |
break; case 4: |
dafd64888 cmd: replace the ... |
73 |
l = (long)(*(u32 *)buf); |
736d1746f itest: add missin... |
74 |
break; |
7d2dc6af5 cmd: itest: add s... |
75 76 77 78 79 |
#ifdef CONFIG_PHYS_64BIT case 8: l = (long)(*(unsigned long *)buf); break; #endif |
f3651764e cmd_itest.c: fix ... |
80 |
} |
7861204c9 itest: make memor... |
81 82 |
unmap_physmem(buf, w); return l; |
2d1a537d8 * Patch by Thomas... |
83 84 85 |
} else { l = simple_strtoul(s, NULL, 16); } |
2c79fd401 cmd: itest: corre... |
86 87 |
/* avoid overflow on mask calculus */ return (w >= sizeof(long)) ? l : (l & ((1UL << (w * 8)) - 1)); |
2d1a537d8 * Patch by Thomas... |
88 89 90 91 92 93 94 |
} static char * evalstr(char *s) { /* if the parameter starts with a * then assume a string pointer else its a literal */ if (s[0] == '*') { return (char *)simple_strtoul(&s[1], NULL, 16); |
06109f498 common, itest: pa... |
95 96 97 98 99 100 101 102 103 104 105 106 |
} else if (s[0] == '$') { int i = 2; if (s[1] != '{') return NULL; while (s[i] != '}') { if (s[i] == 0) return NULL; i++; } s[i] = 0; |
00caae6d4 env: Rename geten... |
107 |
return env_get((const char *)&s[2]); |
2d1a537d8 * Patch by Thomas... |
108 109 110 111 112 113 114 |
} else { return s; } } static int stringcomp(char *s, char *t, int op) { |
cc22b795f itest: fix result... |
115 |
int p; |
2d1a537d8 * Patch by Thomas... |
116 117 118 119 |
char *l, *r; l = evalstr(s); r = evalstr(t); |
cc22b795f itest: fix result... |
120 |
p = strcmp(l, r); |
2d1a537d8 * Patch by Thomas... |
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
switch (op) { case EQ: return (p == 0); case NE: return (p != 0); case LT: return (p < 0); case GT: return (p > 0); case LE: return (p <= 0); case GE: return (p >= 0); } return (0); } static int arithcomp (char *s, char *t, int op, int w) { long l, r; l = evalexp (s, w); r = evalexp (t, w); switch (op) { case EQ: return (l == r); case NE: return (l != r); case LT: return (l < r); case GT: return (l > r); case LE: return (l <= r); case GE: return (l >= r); } return (0); } |
088f1b199 common/cmd_*.c: s... |
149 |
static int binary_test(char *op, char *arg1, char *arg2, int w) |
2d1a537d8 * Patch by Thomas... |
150 151 |
{ int len, i; |
fc9903f38 cmd_itest: consti... |
152 |
const op_tbl_t *optp; |
2d1a537d8 * Patch by Thomas... |
153 154 155 156 |
len = strlen(op); for (optp = (op_tbl_t *)&op_table, i = 0; |
fc9903f38 cmd_itest: consti... |
157 |
i < ARRAY_SIZE(op_table); |
2d1a537d8 * Patch by Thomas... |
158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 |
optp++, i++) { if ((strncmp (op, optp->op, len) == 0) && (len == strlen (optp->op))) { if (w == 0) { return (stringcomp(arg1, arg2, optp->opcode)); } else { return (arithcomp (arg1, arg2, optp->opcode, w)); } } } printf("Unknown operator '%s' ", op); return 0; /* op code not found */ } /* command line interface to the shell test */ |
088f1b199 common/cmd_*.c: s... |
175 |
static int do_itest(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) |
2d1a537d8 * Patch by Thomas... |
176 |
{ |
cd0a9de68 * Patch by Lauren... |
177 |
int value, w; |
2d1a537d8 * Patch by Thomas... |
178 |
|
cd0a9de68 * Patch by Lauren... |
179 |
/* Validate arguments */ |
47e26b1bf cmd_usage(): simp... |
180 |
if ((argc != 4)) |
4c12eeb8b Convert cmd_usage... |
181 |
return CMD_RET_USAGE; |
2d1a537d8 * Patch by Thomas... |
182 183 184 185 186 187 188 189 190 |
/* Check for a data width specification. * Defaults to long (4) if no specification. * Uses -2 as 'width' for .s (string) so as not to upset existing code */ switch (w = cmd_get_data_size(argv[0], 4)) { case 1: case 2: case 4: |
7d2dc6af5 cmd: itest: add s... |
191 192 193 |
#ifdef CONFIG_PHYS_64BIT case 8: #endif |
2d1a537d8 * Patch by Thomas... |
194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 |
value = binary_test (argv[2], argv[1], argv[3], w); break; case -2: value = binary_test (argv[2], argv[1], argv[3], 0); break; case -1: default: puts("Invalid data width specifier "); value = 0; break; } return !value; } U_BOOT_CMD( itest, 4, 0, do_itest, |
2fb2604d5 Command usage cle... |
212 |
"return true/false on integer compare", |
7d2dc6af5 cmd: itest: add s... |
213 214 215 |
#ifdef CONFIG_PHYS_64BIT "[.b, .w, .l, .q, .s] [*]value1 <op> [*]value2" #else |
a89c33db9 General help mess... |
216 |
"[.b, .w, .l, .s] [*]value1 <op> [*]value2" |
7d2dc6af5 cmd: itest: add s... |
217 |
#endif |
2d1a537d8 * Patch by Thomas... |
218 |
); |