/*
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <common.h>
#include <command.h>
#include <malloc.h>
#include <mapmem.h>
#include <linux/ctype.h>

enum {
	OP_ID_XOR,
	OP_ID_AND,
	OP_ID_OR,
};

void write_to_env_var(char *varname, u8 *result, ulong len)
{
	char *str_output;
	char *str_ptr;
	int i;

	str_output = malloc(len * 2 + 1);
	str_ptr = str_output;

	for (i = 0; i < len; i++) {
		sprintf(str_ptr, "%02x", result[i]);
		str_ptr += 2;
	}
	*str_ptr = '\0';
	setenv(varname, str_output);

	free(str_output);
}

void decode_hexstring(char *hexstr, u8 *result)
{
	int i;
	int acc = 0;

	for (i = 0; i < strlen(hexstr); ++i) {
		char d = hexstr[i];
		int value;

		if (isdigit(d))
			value = (d - '0');
		else
			value = (islower(d) ? toupper(d) : d) - 'A' + 10;

		if (i % 2 == 0) {
			acc = value * 16;
		} else {
			result[i / 2] = acc + value;
			acc = 0;
		}
	}
}

void read_from_env_var(char *varname, u8 *result)
{
	char *str_value;

	str_value = getenv(varname);
	if (str_value)
		decode_hexstring(str_value, result);
	else
		decode_hexstring(varname, result);
}

void read_from_mem(ulong addr, u8 *result, ulong len)
{
	u8 *src;

	src = map_sysmem(addr, len);
	memcpy(result, src, len);
	unmap_sysmem(src);
}

void write_to_mem(char *varname, u8 *result, ulong len)
{
	ulong addr;
	u8 *buf;

	addr = simple_strtoul(varname, NULL, 16);
	buf = map_sysmem(addr, len);
	memcpy(buf, result, len);
	unmap_sysmem(buf);
}

static int do_binop(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	ulong len;
	u8 *result, *src1, *src2;
	char *oparg, *lenarg, *src1arg, *src2arg, *destarg;
	int i, op;

	if (argc < 5)
		return CMD_RET_USAGE;

	oparg = argv[1];
	lenarg = argv[2];
	src1arg = argv[3];
	src2arg = argv[4];

	if (!strcmp(oparg, "xor"))
		op = OP_ID_XOR;
	else if (!strcmp(oparg, "or"))
		op = OP_ID_OR;
	else if (!strcmp(oparg, "and"))
		op = OP_ID_AND;
	else
		return CMD_RET_USAGE;

	len = simple_strtoul(lenarg, NULL, 10);

	src1 = malloc(len);
	src2 = malloc(len);

	if (*src1arg == '*')
		read_from_mem(simple_strtoul(src1arg + 1, NULL, 16), src1, len);
	else
		read_from_env_var(src1arg, src1);

	if (*src2arg == '*')
		read_from_mem(simple_strtoul(src2arg + 1, NULL, 16), src2, len);
	else
		read_from_env_var(src2arg, src2);

	result = malloc(len);

	switch (op) {
	case OP_ID_XOR:
		for (i = 0; i < len; i++)
			result[i] = src1[i] ^ src2[i];
		break;
	case OP_ID_OR:
		for (i = 0; i < len; i++)
			result[i] = src1[i] | src2[i];
		break;
	case OP_ID_AND:
		for (i = 0; i < len; i++)
			result[i] = src1[i] & src2[i];
		break;
	}

	if (argc == 5) {
		for (i = 0; i < len; i++) {
			printf("%02x ", result[i]);
			if (i % 16 == 15)
				puts("\n");
		}
		puts("\n");

		goto exit;
	}

	destarg = argv[5];

	if (*destarg == '*')
		write_to_mem(destarg + 1, result, len); /* Skip asterisk */
	else
		write_to_env_var(destarg, result, len);
exit:
	free(result);
	free(src2);
	free(src1);

	return 0;
}

U_BOOT_CMD(
	binop,	6,	1,	do_binop,
	"compute binary operation",
	"op count [*]src1 [*]src2 [[*]dest]\n"
		"    - 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."
);
