/*
 * Copyright 2019 The Hafnium Authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "hf/mm.h"

#include "hf/arch/barriers.h"
#include "hf/arch/vm/mm.h"

#include "hf/dlog.h"

#include "../msr.h"

#define STAGE1_DEVICEINDX UINT64_C(0)
#define STAGE1_NORMALINDX UINT64_C(1)

static uintreg_t mm_mair_el1;
static uintreg_t mm_tcr_el1;
static uintreg_t mm_sctlr_el1;

static uintreg_t mm_reset_ttbr0_el1;
static uintreg_t mm_reset_mair_el1;
static uintreg_t mm_reset_tcr_el1;
static uintreg_t mm_reset_sctlr_el1;

/**
 * Initialize MMU for a test running in EL1.
 */
bool arch_vm_mm_init(void)
{
	static const int pa_bits_table[16] = {32, 36, 40, 42, 44, 48};
	uint64_t features = read_msr(id_aa64mmfr0_el1);
	int pa_bits = pa_bits_table[features & 0xf];

	/* Check that 4KB granules are supported. */
	if ((features >> 28) & 0xf) {
		dlog_error("4KB granules are not supported\n");
		return false;
	}

	/* Check the physical address range. */
	if (!pa_bits) {
		dlog_error(
			"Unsupported value of id_aa64mmfr0_el1.PARange: %x\n",
			features & 0xf);
		return false;
	}

	/*
	 * Preserve initial values of the system registers in case we want to
	 * reset them.
	 */
	mm_reset_ttbr0_el1 = read_msr(ttbr0_el1);
	mm_reset_mair_el1 = read_msr(mair_el1);
	mm_reset_tcr_el1 = read_msr(tcr_el1);
	mm_reset_sctlr_el1 = read_msr(sctlr_el1);

	/*
	 * 0    -> Device-nGnRnE memory
	 * 0xff -> Normal memory, Inner/Outer Write-Back Non-transient,
	 *         Write-Alloc, Read-Alloc.
	 */
	mm_mair_el1 = (0 << (8 * STAGE1_DEVICEINDX)) |
		      (0xff << (8 * STAGE1_NORMALINDX));

	mm_tcr_el1 = (1 << 20) |		/* TBI, top byte ignored. */
		     ((features & 0xf) << 16) | /* PS. */
		     (0 << 14) |		/* TG0, granule size, 4KB. */
		     (3 << 12) |		/* SH0, inner shareable. */
		     (1 << 10) | /* ORGN0, normal mem, WB RA WA Cacheable. */
		     (1 << 8) |  /* IRGN0, normal mem, WB RA WA Cacheable. */
		     (25 << 0) | /* T0SZ, input address is 2^39 bytes. */
		     0;

	mm_sctlr_el1 = (1 << 0) |  /* M, enable stage 1 EL2 MMU. */
		       (1 << 1) |  /* A, enable alignment check faults. */
		       (1 << 2) |  /* C, data cache enable. */
		       (1 << 3) |  /* SA, enable stack alignment check. */
		       (3 << 4) |  /* RES1 bits. */
		       (1 << 11) | /* RES1 bit. */
		       (1 << 12) | /* I, instruction cache enable. */
		       (1 << 16) | /* RES1 bit. */
		       (1 << 18) | /* RES1 bit. */
		       (0 << 19) | /* WXN bit, writable execute never. */
		       (3 << 22) | /* RES1 bits. */
		       (3 << 28) | /* RES1 bits. */
		       0;

	return true;
}

void arch_vm_mm_enable(paddr_t table)
{
	/* Configure translation management registers. */
	write_msr(ttbr0_el1, pa_addr(table));
	write_msr(mair_el1, mm_mair_el1);
	write_msr(tcr_el1, mm_tcr_el1);

	/* Configure sctlr_el1 to enable MMU and cache. */
	dsb(sy);
	isb();
	write_msr(sctlr_el1, mm_sctlr_el1);
	isb();
}

void arch_vm_mm_reset(void)
{
	/* Set system registers to their reset values. */
	write_msr(ttbr0_el1, mm_reset_ttbr0_el1);
	write_msr(mair_el1, mm_reset_mair_el1);
	write_msr(tcr_el1, mm_reset_tcr_el1);

	dsb(sy);
	isb();
	write_msr(sctlr_el1, mm_reset_sctlr_el1);
	isb();
}
