/*
 * (C) Copyright 2014 Google, Inc
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <common.h>
#include <asm/msr.h>
#include <asm/mtrr.h>

static const char *const mtrr_type_name[MTRR_TYPE_COUNT] = {
	"Uncacheable",
	"Combine",
	"2",
	"3",
	"Through",
	"Protect",
	"Back",
};

static int do_mtrr_list(void)
{
	int i;

	printf("Reg Valid Write-type   %-16s %-16s %-16s\n", "Base   ||",
	       "Mask   ||", "Size   ||");
	for (i = 0; i < MTRR_COUNT; i++) {
		const char *type = "Invalid";
		uint64_t base, mask, size;
		bool valid;

		base = native_read_msr(MTRR_PHYS_BASE_MSR(i));
		mask = native_read_msr(MTRR_PHYS_MASK_MSR(i));
		size = ~mask & ((1ULL << CONFIG_CPU_ADDR_BITS) - 1);
		size |= (1 << 12) - 1;
		size += 1;
		valid = mask & MTRR_PHYS_MASK_VALID;
		type = mtrr_type_name[base & MTRR_BASE_TYPE_MASK];
		printf("%d   %-5s %-12s %016llx %016llx %016llx\n", i,
		       valid ? "Y" : "N", type, base, mask, size);
	}

	return 0;
}

static int do_mtrr_set(uint reg, int argc, char * const argv[])
{
	const char *typename = argv[0];
	struct mtrr_state state;
	uint32_t start, size;
	uint64_t base, mask;
	int i, type = -1;
	bool valid;

	if (argc < 3)
		return CMD_RET_USAGE;
	for (i = 0; i < MTRR_TYPE_COUNT; i++) {
		if (*typename == *mtrr_type_name[i])
			type = i;
	}
	if (type == -1) {
		printf("Invalid type name %s\n", typename);
		return CMD_RET_USAGE;
	}
	start = simple_strtoul(argv[1], NULL, 16);
	size = simple_strtoul(argv[2], NULL, 16);

	base = start | type;
	valid = native_read_msr(MTRR_PHYS_MASK_MSR(reg)) & MTRR_PHYS_MASK_VALID;
	mask = ~((uint64_t)size - 1);
	mask &= (1ULL << CONFIG_CPU_ADDR_BITS) - 1;
	if (valid)
		mask |= MTRR_PHYS_MASK_VALID;

	printf("base=%llx, mask=%llx\n", base, mask);
	mtrr_open(&state);
	wrmsrl(MTRR_PHYS_BASE_MSR(reg), base);
	wrmsrl(MTRR_PHYS_MASK_MSR(reg), mask);
	mtrr_close(&state);

	return 0;
}

static int mtrr_set_valid(int reg, bool valid)
{
	struct mtrr_state state;
	uint64_t mask;

	mtrr_open(&state);
	mask = native_read_msr(MTRR_PHYS_MASK_MSR(reg));
	if (valid)
		mask |= MTRR_PHYS_MASK_VALID;
	else
		mask &= ~MTRR_PHYS_MASK_VALID;
	wrmsrl(MTRR_PHYS_MASK_MSR(reg), mask);
	mtrr_close(&state);

	return 0;
}

static int do_mtrr(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	const char *cmd;
	uint reg;

	cmd = argv[1];
	if (argc < 2 || *cmd == 'l')
		return do_mtrr_list();
	argc -= 2;
	argv += 2;
	if (argc <= 0)
		return CMD_RET_USAGE;
	reg = simple_strtoul(argv[0], NULL, 16);
	if (reg >= MTRR_COUNT) {
		printf("Invalid register number\n");
		return CMD_RET_USAGE;
	}
	if (*cmd == 'e')
		return mtrr_set_valid(reg, true);
	else if (*cmd == 'd')
		return mtrr_set_valid(reg, false);
	else if (*cmd == 's')
		return do_mtrr_set(reg, argc - 1, argv + 1);
	else
		return CMD_RET_USAGE;

	return 0;
}

U_BOOT_CMD(
	mtrr,	6,	1,	do_mtrr,
	"Use x86 memory type range registers (32-bit only)",
	"[list]        - list current registers\n"
	"set <reg> <type> <start> <size>   - set a register\n"
	"\t<type> is Uncacheable, Combine, Through, Protect, Back\n"
	"disable <reg>      - disable a register\n"
	"ensable <reg>      - enable a register"
);
