binop.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  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 = hextoul(varname, NULL);
  50. buf = map_sysmem(addr, len);
  51. memcpy(buf, result, len);
  52. unmap_sysmem(buf);
  53. }
  54. static int do_binop(struct cmd_tbl *cmdtp, int flag, int argc,
  55. char *const argv[])
  56. {
  57. ulong len;
  58. u8 *result, *src1, *src2;
  59. char *oparg, *lenarg, *src1arg, *src2arg, *destarg;
  60. int i, op;
  61. if (argc < 5)
  62. return CMD_RET_USAGE;
  63. oparg = argv[1];
  64. lenarg = argv[2];
  65. src1arg = argv[3];
  66. src2arg = argv[4];
  67. if (!strcmp(oparg, "xor"))
  68. op = OP_ID_XOR;
  69. else if (!strcmp(oparg, "or"))
  70. op = OP_ID_OR;
  71. else if (!strcmp(oparg, "and"))
  72. op = OP_ID_AND;
  73. else
  74. return CMD_RET_USAGE;
  75. len = dectoul(lenarg, NULL);
  76. src1 = malloc(len);
  77. src2 = malloc(len);
  78. if (*src1arg == '*')
  79. read_from_mem(hextoul(src1arg + 1, NULL), src1, len);
  80. else
  81. read_from_env_var(src1arg, src1);
  82. if (*src2arg == '*')
  83. read_from_mem(hextoul(src2arg + 1, NULL), src2, len);
  84. else
  85. read_from_env_var(src2arg, src2);
  86. result = malloc(len);
  87. switch (op) {
  88. case OP_ID_XOR:
  89. for (i = 0; i < len; i++)
  90. result[i] = src1[i] ^ src2[i];
  91. break;
  92. case OP_ID_OR:
  93. for (i = 0; i < len; i++)
  94. result[i] = src1[i] | src2[i];
  95. break;
  96. case OP_ID_AND:
  97. for (i = 0; i < len; i++)
  98. result[i] = src1[i] & src2[i];
  99. break;
  100. }
  101. if (argc == 5) {
  102. for (i = 0; i < len; i++) {
  103. printf("%02x ", result[i]);
  104. if (i % 16 == 15)
  105. puts("\n");
  106. }
  107. puts("\n");
  108. goto exit;
  109. }
  110. destarg = argv[5];
  111. if (*destarg == '*')
  112. write_to_mem(destarg + 1, result, len); /* Skip asterisk */
  113. else
  114. write_to_env_var(destarg, result, len);
  115. exit:
  116. free(result);
  117. free(src2);
  118. free(src1);
  119. return 0;
  120. }
  121. U_BOOT_CMD(
  122. binop, 6, 1, do_binop,
  123. "compute binary operation",
  124. "op count [*]src1 [*]src2 [[*]dest]\n"
  125. " - 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."
  126. );