binop.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. // SPDX-License-Identifier: GPL-2.0+
  2. #include <common.h>
  3. #include <command.h>
  4. #include <malloc.h>
  5. #include <mapmem.h>
  6. #include <linux/ctype.h>
  7. enum {
  8. OP_ID_XOR,
  9. OP_ID_AND,
  10. OP_ID_OR,
  11. };
  12. void write_to_env_var(char *varname, u8 *result, ulong len)
  13. {
  14. char *str_output;
  15. char *str_ptr;
  16. int i;
  17. str_output = malloc(len * 2 + 1);
  18. str_ptr = str_output;
  19. for (i = 0; i < len; i++) {
  20. sprintf(str_ptr, "%02x", result[i]);
  21. str_ptr += 2;
  22. }
  23. *str_ptr = '\0';
  24. setenv(varname, str_output);
  25. free(str_output);
  26. }
  27. void decode_hexstring(char *hexstr, u8 *result)
  28. {
  29. int i;
  30. int acc = 0;
  31. for (i = 0; i < strlen(hexstr); ++i) {
  32. char d = hexstr[i];
  33. int value;
  34. if (isdigit(d))
  35. value = (d - '0');
  36. else
  37. value = (islower(d) ? toupper(d) : d) - 'A' + 10;
  38. if (i % 2 == 0) {
  39. acc = value * 16;
  40. } else {
  41. result[i / 2] = acc + value;
  42. acc = 0;
  43. }
  44. }
  45. }
  46. void read_from_env_var(char *varname, u8 *result)
  47. {
  48. char *str_value;
  49. str_value = getenv(varname);
  50. if (str_value)
  51. decode_hexstring(str_value, result);
  52. else
  53. decode_hexstring(varname, result);
  54. }
  55. void read_from_mem(ulong addr, u8 *result, ulong len)
  56. {
  57. u8 *src;
  58. src = map_sysmem(addr, len);
  59. memcpy(result, src, len);
  60. unmap_sysmem(src);
  61. }
  62. void write_to_mem(char *varname, u8 *result, ulong len)
  63. {
  64. ulong addr;
  65. u8 *buf;
  66. addr = simple_strtoul(varname, NULL, 16);
  67. buf = map_sysmem(addr, len);
  68. memcpy(buf, result, len);
  69. unmap_sysmem(buf);
  70. }
  71. static int do_binop(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
  72. {
  73. ulong len;
  74. u8 *result, *src1, *src2;
  75. char *oparg, *lenarg, *src1arg, *src2arg, *destarg;
  76. int i, op;
  77. if (argc < 5)
  78. return CMD_RET_USAGE;
  79. oparg = argv[1];
  80. lenarg = argv[2];
  81. src1arg = argv[3];
  82. src2arg = argv[4];
  83. if (!strcmp(oparg, "xor"))
  84. op = OP_ID_XOR;
  85. else if (!strcmp(oparg, "or"))
  86. op = OP_ID_OR;
  87. else if (!strcmp(oparg, "and"))
  88. op = OP_ID_AND;
  89. else
  90. return CMD_RET_USAGE;
  91. len = simple_strtoul(lenarg, NULL, 10);
  92. src1 = malloc(len);
  93. src2 = malloc(len);
  94. if (*src1arg == '*')
  95. read_from_mem(simple_strtoul(src1arg + 1, NULL, 16), src1, len);
  96. else
  97. read_from_env_var(src1arg, src1);
  98. if (*src2arg == '*')
  99. read_from_mem(simple_strtoul(src2arg + 1, NULL, 16), src2, len);
  100. else
  101. read_from_env_var(src2arg, src2);
  102. result = malloc(len);
  103. switch (op) {
  104. case OP_ID_XOR:
  105. for (i = 0; i < len; i++)
  106. result[i] = src1[i] ^ src2[i];
  107. break;
  108. case OP_ID_OR:
  109. for (i = 0; i < len; i++)
  110. result[i] = src1[i] | src2[i];
  111. break;
  112. case OP_ID_AND:
  113. for (i = 0; i < len; i++)
  114. result[i] = src1[i] & src2[i];
  115. break;
  116. }
  117. if (argc == 5) {
  118. for (i = 0; i < len; i++) {
  119. printf("%02x ", result[i]);
  120. if (i % 16 == 15)
  121. puts("\n");
  122. }
  123. puts("\n");
  124. goto exit;
  125. }
  126. destarg = argv[5];
  127. if (*destarg == '*')
  128. write_to_mem(destarg + 1, result, len); /* Skip asterisk */
  129. else
  130. write_to_env_var(destarg, result, len);
  131. exit:
  132. free(result);
  133. free(src2);
  134. free(src1);
  135. return 0;
  136. }
  137. U_BOOT_CMD(
  138. binop, 6, 1, do_binop,
  139. "compute binary operation",
  140. "op count [*]src1 [*]src2 [[*]dest]\n"
  141. " - compute binary operation of data at/in src1 and\n src2 (either *memaddr, env var name or hex string)\n and store result in/at dest, where op is one of\n xor, or, and."
  142. );