binop.c 2.9 KB

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