/*
 * Copyright 2018 Google LLC
 *
 * 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/arch/mm.h"

#include "hf/mm.h"

/*
 * Our fake architecture has page tables base on those of aarch64:
 *
 *  - The highest level table is always 2, lowest level is 0.
 *  - Blocks are allowed at all levels.
 *
 * There are four kinds of entry:
 *
 *  1. Absent: 0
 *  2. Page, at level 0: <page-aligned address> | <attrs> | 0x3
 *  3. Block, at level 2 or 1: <block-aligned address> | <attrs> | 0x1
 *  4. Subtable, at level 2 or 1: <subtable address> | 0x3
 *
 * <attrs> are always 0 for now.
 */

pte_t arch_mm_absent_pte(int level)
{
	(void)level;
	return 0;
}

pte_t arch_mm_table_pte(int level, paddr_t pa)
{
	/* This is the same for all levels. */
	(void)level;
	return pa_addr(pa) | 0x3;
}

pte_t arch_mm_block_pte(int level, paddr_t pa, uint64_t attrs)
{
	/* Single pages are encoded differently to larger blocks. */
	pte_t pte = pa_addr(pa) | attrs;
	if (level == 0) {
		pte |= 0x2;
	}
	return pte;
}

bool arch_mm_is_block_allowed(int level)
{
	/* All levels can have blocks. */
	(void)level;
	return true;
}

bool arch_mm_pte_is_present(pte_t pte, int level)
{
	/* TODO: model attributes. */
	return arch_mm_pte_is_valid(pte, level);
}

bool arch_mm_pte_is_valid(pte_t pte, int level)
{
	(void)level;
	return (pte & 0x1) != 0;
}

bool arch_mm_pte_is_table(pte_t pte, int level)
{
	/* Level 0 only contains pages so cannot be a table. */
	return level != 0 && (pte & 0x3) == 0x3;
}

bool arch_mm_pte_is_block(pte_t pte, int level)
{
	/* Single pages are encoded differently to larger blocks. */
	return (level == 0 ? (pte & 0x2) != 0
			   : arch_mm_pte_is_present(pte, level) &&
				     !arch_mm_pte_is_table(pte, level));
}

static uint64_t hf_arch_fake_mm_clear_pte_attrs(pte_t pte)
{
	return pte & ~0x3;
}

paddr_t arch_mm_clear_pa(paddr_t pa)
{
	/* This is assumed to round down to the page boundary. */
	return pa_init(hf_arch_fake_mm_clear_pte_attrs(pa_addr(pa)) &
		       ~((1 << PAGE_BITS) - 1));
}

paddr_t arch_mm_block_from_pte(pte_t pte)
{
	return pa_init(hf_arch_fake_mm_clear_pte_attrs(pte));
}

paddr_t arch_mm_table_from_pte(pte_t pte)
{
	return pa_init(hf_arch_fake_mm_clear_pte_attrs(pte));
}

uint64_t arch_mm_pte_attrs(pte_t pte)
{
	/* Attributes are not modelled fully. */
	return pte & 0x1;
}

uint64_t arch_mm_combine_table_entry_attrs(uint64_t table_attrs,
					   uint64_t block_attrs)
{
	return table_attrs | block_attrs;
}

void arch_mm_invalidate_stage1_range(vaddr_t va_begin, vaddr_t va_end)
{
	/* There's no modelling of the stage-1 TLB. */
}

void arch_mm_invalidate_stage2_range(ipaddr_t va_begin, ipaddr_t va_end)
{
	/* There's no modelling of the stage-2 TLB. */
}

uint8_t arch_mm_max_level(int mode)
{
	/* All modes have 3 levels in the page table. */
	(void)mode;
	return 2;
}

uint8_t arch_mm_root_table_count(int mode)
{
	/* Stage 1 has no concatenated tables but stage 2 has 4 of them. */
	return (mode & MM_MODE_STAGE1) ? 1 : 4;
}

uint64_t arch_mm_mode_to_attrs(int mode)
{
	/* Attributes are not modelled fully. */
	return mode & MM_MODE_INVALID ? 0 : 0x1;
}

bool arch_mm_init(paddr_t table, bool first)
{
	/* No initialization required. */
	(void)table;
	(void)first;
	return true;
}
