// SPDX-License-Identifier: GPL-2.0+
/*
 * (C) Copyright 2014 Google, Inc
 *
 * Memory Type Range Regsters - these are used to tell the CPU whether
 * memory is cacheable and if so the cache write mode to use.
 *
 * These can speed up booting. See the mtrr command.
 *
 * Reference: Intel Architecture Software Developer's Manual, Volume 3:
 * System Programming
 */

/*
 * Note that any console output (e.g. debug()) in this file will likely fail
 * since the MTRR registers are sometimes in flux.
 */

#include <common.h>
#include <cpu_func.h>
#include <log.h>
#include <sort.h>
#include <asm/cache.h>
#include <asm/io.h>
#include <asm/mp.h>
#include <asm/msr.h>
#include <asm/mtrr.h>

DECLARE_GLOBAL_DATA_PTR;

/* Prepare to adjust MTRRs */
void mtrr_open(struct mtrr_state *state, bool do_caches)
{
	if (!gd->arch.has_mtrr)
		return;

	if (do_caches) {
		state->enable_cache = dcache_status();

		if (state->enable_cache)
			disable_caches();
	}
	state->deftype = native_read_msr(MTRR_DEF_TYPE_MSR);
	wrmsrl(MTRR_DEF_TYPE_MSR, state->deftype & ~MTRR_DEF_TYPE_EN);
}

/* Clean up after adjusting MTRRs, and enable them */
void mtrr_close(struct mtrr_state *state, bool do_caches)
{
	if (!gd->arch.has_mtrr)
		return;

	wrmsrl(MTRR_DEF_TYPE_MSR, state->deftype | MTRR_DEF_TYPE_EN);
	if (do_caches && state->enable_cache)
		enable_caches();
}

static void set_var_mtrr(uint reg, uint type, uint64_t start, uint64_t size)
{
	u64 mask;

	wrmsrl(MTRR_PHYS_BASE_MSR(reg), start | type);
	mask = ~(size - 1);
	mask &= (1ULL << CONFIG_CPU_ADDR_BITS) - 1;
	wrmsrl(MTRR_PHYS_MASK_MSR(reg), mask | MTRR_PHYS_MASK_VALID);
}

void mtrr_read_all(struct mtrr_info *info)
{
	int reg_count = mtrr_get_var_count();
	int i;

	for (i = 0; i < reg_count; i++) {
		info->mtrr[i].base = native_read_msr(MTRR_PHYS_BASE_MSR(i));
		info->mtrr[i].mask = native_read_msr(MTRR_PHYS_MASK_MSR(i));
	}
}

void mtrr_write_all(struct mtrr_info *info)
{
	int reg_count = mtrr_get_var_count();
	struct mtrr_state state;
	int i;

	for (i = 0; i < reg_count; i++) {
		mtrr_open(&state, true);
		wrmsrl(MTRR_PHYS_BASE_MSR(i), info->mtrr[i].base);
		wrmsrl(MTRR_PHYS_MASK_MSR(i), info->mtrr[i].mask);
		mtrr_close(&state, true);
	}
}

static void write_mtrrs(void *arg)
{
	struct mtrr_info *info = arg;

	mtrr_write_all(info);
}

static void read_mtrrs(void *arg)
{
	struct mtrr_info *info = arg;

	mtrr_read_all(info);
}

/**
 * mtrr_copy_to_aps() - Copy the MTRRs from the boot CPU to other CPUs
 *
 * @return 0 on success, -ve on failure
 */
static int mtrr_copy_to_aps(void)
{
	struct mtrr_info info;
	int ret;

	ret = mp_run_on_cpus(MP_SELECT_BSP, read_mtrrs, &info);
	if (ret == -ENXIO)
		return 0;
	else if (ret)
		return log_msg_ret("bsp", ret);

	ret = mp_run_on_cpus(MP_SELECT_APS, write_mtrrs, &info);
	if (ret)
		return log_msg_ret("bsp", ret);

	return 0;
}

static int h_comp_mtrr(const void *p1, const void *p2)
{
	const struct mtrr_request *req1 = p1;
	const struct mtrr_request *req2 = p2;

	s64 diff = req1->start - req2->start;

	return diff < 0 ? -1 : diff > 0 ? 1 : 0;
}

int mtrr_commit(bool do_caches)
{
	struct mtrr_request *req = gd->arch.mtrr_req;
	struct mtrr_state state;
	int ret;
	int i;

	debug("%s: enabled=%d, count=%d\n", __func__, gd->arch.has_mtrr,
	      gd->arch.mtrr_req_count);
	if (!gd->arch.has_mtrr)
		return -ENOSYS;

	debug("open\n");
	mtrr_open(&state, do_caches);
	debug("open done\n");
	qsort(req, gd->arch.mtrr_req_count, sizeof(*req), h_comp_mtrr);
	for (i = 0; i < gd->arch.mtrr_req_count; i++, req++)
		set_var_mtrr(i, req->type, req->start, req->size);

	/* Clear the ones that are unused */
	debug("clear\n");
	for (; i < mtrr_get_var_count(); i++)
		wrmsrl(MTRR_PHYS_MASK_MSR(i), 0);
	debug("close\n");
	mtrr_close(&state, do_caches);
	debug("mtrr done\n");

	if (gd->flags & GD_FLG_RELOC) {
		ret = mtrr_copy_to_aps();
		if (ret)
			return log_msg_ret("copy", ret);
	}

	return 0;
}

int mtrr_add_request(int type, uint64_t start, uint64_t size)
{
	struct mtrr_request *req;
	uint64_t mask;

	debug("%s: count=%d\n", __func__, gd->arch.mtrr_req_count);
	if (!gd->arch.has_mtrr)
		return -ENOSYS;

	if (gd->arch.mtrr_req_count == MAX_MTRR_REQUESTS)
		return -ENOSPC;
	req = &gd->arch.mtrr_req[gd->arch.mtrr_req_count++];
	req->type = type;
	req->start = start;
	req->size = size;
	debug("%d: type=%d, %08llx  %08llx\n", gd->arch.mtrr_req_count - 1,
	      req->type, req->start, req->size);
	mask = ~(req->size - 1);
	mask &= (1ULL << CONFIG_CPU_ADDR_BITS) - 1;
	mask |= MTRR_PHYS_MASK_VALID;
	debug("   %016llx %016llx\n", req->start | req->type, mask);

	return 0;
}

int mtrr_get_var_count(void)
{
	return msr_read(MSR_MTRR_CAP_MSR).lo & MSR_MTRR_CAP_VCNT;
}

static int get_free_var_mtrr(void)
{
	struct msr_t maskm;
	int vcnt;
	int i;

	vcnt = mtrr_get_var_count();

	/* Identify the first var mtrr which is not valid */
	for (i = 0; i < vcnt; i++) {
		maskm = msr_read(MTRR_PHYS_MASK_MSR(i));
		if ((maskm.lo & MTRR_PHYS_MASK_VALID) == 0)
			return i;
	}

	/* No free var mtrr */
	return -ENOSPC;
}

int mtrr_set_next_var(uint type, uint64_t start, uint64_t size)
{
	int mtrr;

	mtrr = get_free_var_mtrr();
	if (mtrr < 0)
		return mtrr;

	set_var_mtrr(mtrr, type, start, size);
	debug("MTRR %x: start=%x, size=%x\n", mtrr, (uint)start, (uint)size);

	return 0;
}

/** enum mtrr_opcode - supported operations for mtrr_do_oper() */
enum mtrr_opcode {
	MTRR_OP_SET,
	MTRR_OP_SET_VALID,
};

/**
 * struct mtrr_oper - An MTRR operation to perform on a CPU
 *
 * @opcode: Indicates operation to perform
 * @reg: MTRR reg number to select (0-7, -1 = all)
 * @valid: Valid value to write for MTRR_OP_SET_VALID
 * @base: Base value to write for MTRR_OP_SET
 * @mask: Mask value to write for MTRR_OP_SET
 */
struct mtrr_oper {
	enum mtrr_opcode opcode;
	int reg;
	bool valid;
	u64 base;
	u64 mask;
};

static void mtrr_do_oper(void *arg)
{
	struct mtrr_oper *oper = arg;
	u64 mask;

	switch (oper->opcode) {
	case MTRR_OP_SET_VALID:
		mask = native_read_msr(MTRR_PHYS_MASK_MSR(oper->reg));
		if (oper->valid)
			mask |= MTRR_PHYS_MASK_VALID;
		else
			mask &= ~MTRR_PHYS_MASK_VALID;
		wrmsrl(MTRR_PHYS_MASK_MSR(oper->reg), mask);
		break;
	case MTRR_OP_SET:
		wrmsrl(MTRR_PHYS_BASE_MSR(oper->reg), oper->base);
		wrmsrl(MTRR_PHYS_MASK_MSR(oper->reg), oper->mask);
		break;
	}
}

static int mtrr_start_op(int cpu_select, struct mtrr_oper *oper)
{
	struct mtrr_state state;
	int ret;

	mtrr_open(&state, true);
	ret = mp_run_on_cpus(cpu_select, mtrr_do_oper, oper);
	mtrr_close(&state, true);
	if (ret)
		return log_msg_ret("run", ret);

	return 0;
}

int mtrr_set_valid(int cpu_select, int reg, bool valid)
{
	struct mtrr_oper oper;

	oper.opcode = MTRR_OP_SET_VALID;
	oper.reg = reg;
	oper.valid = valid;

	return mtrr_start_op(cpu_select, &oper);
}

int mtrr_set(int cpu_select, int reg, u64 base, u64 mask)
{
	struct mtrr_oper oper;

	oper.opcode = MTRR_OP_SET;
	oper.reg = reg;
	oper.base = base;
	oper.mask = mask;

	return mtrr_start_op(cpu_select, &oper);
}
