/*
 * 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.
 */

#pragma once

#include <stdbool.h>
#include <stddef.h>

#include "hf/addr.h"

/*
 * Our fake architecture has page tables rather similar to aarch64, but not
 * quite.
 * - The highest level table is always 2, lowest level is 0.
 * - Blocks are allowed at all levels.
 * There are four types of entries:
 * - Absent: 0
 * - Page, at level 0: <page-aligned address> | <attrs> | 0x3
 * - Block, at level 2 or 1: <block-aligned address> | <attrs> | 0x1
 * - Subtable, at level 2 or 1: <subtable address> | 0x3
 * <attrs> are always 0 for now.
 */

/** A page table entry. */
typedef uint64_t pte_t;

#define PAGE_LEVEL_BITS 9

/**
 * Returns the encoding of a page table entry that isn't present.
 */
static inline pte_t arch_mm_absent_pte(int level)
{
	return 0;
}

/**
 * Converts a physical address to a table PTE.
 *
 * The spec says that 'Table descriptors for stage 2 translations do not
 * include any attribute field', so we don't take any attributes as arguments.
 */
static inline pte_t arch_mm_table_pte(int level, paddr_t pa)
{
	/* This is the same for all levels on aarch64. */
	(void)level;
	return pa_addr(pa) | 0x3;
}

/**
 * Converts a physical address to a block PTE.
 *
 * The level must allow block entries.
 */
static inline pte_t arch_mm_block_pte(int level, paddr_t pa, uint64_t attrs)
{
	pte_t pte = pa_addr(pa) | attrs | 0x1;
	if (level == 0) {
		pte |= 0x2;
	}
	return pte;
}

/**
 * Specifies whether block mappings are acceptable at the given level.
 *
 * Level 0 must allow block entries.
 */
static inline bool arch_mm_is_block_allowed(int level)
{
	return level <= 2;
}

/**
 * Determines if the given pte is present, i.e., if it points to another table,
 * to a page, or a block of pages.
 */
static inline bool arch_mm_pte_is_present(pte_t pte, int level)
{
	return (pte & 0x1) != 0;
}

/**
 * Determines if the given pte references another table.
 */
static inline bool arch_mm_pte_is_table(pte_t pte, int level)
{
	return level != 0 && (pte & 0x3) == 0x3;
}

/**
 * Determines if the given pte references a block of pages.
 */
static inline bool arch_mm_pte_is_block(pte_t pte, int level)
{
	return arch_mm_is_block_allowed(level) &&
	       (pte & 0x3) == (level == 0 ? 0x3 : 0x1);
}

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

/**
 * Clears the given physical address, i.e., sets the ignored bits (from a page
 * table perspective) to zero.
 */
static inline 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));
}

/**
 * Extracts the physical address of the block referred to by the given page
 * table entry.
 */
static inline paddr_t arch_mm_block_from_pte(pte_t pte)
{
	return pa_init(hf_arch_fake_mm_clear_pte_attrs(pte));
}

/**
 * Extracts the physical address of the page table referred to by the given page
 * table entry.
 */
static inline paddr_t arch_mm_table_from_pte(pte_t pte)
{
	return pa_init(hf_arch_fake_mm_clear_pte_attrs(pte));
}

/**
 * Extracts the architecture specific attributes applies to the given page table
 * entry.
 */
static inline uint64_t arch_mm_pte_attrs(pte_t pte)
{
	return 0;
}

/**
 * Given the attrs from a table at some level and the attrs from all the blocks
 * in that table, return equivalent attrs to use for a block which will replace
 * the entire table.
 */
static inline uint64_t arch_mm_combine_table_entry_attrs(uint64_t table_attrs,
							 uint64_t block_attrs)
{
	return table_attrs | block_attrs;
}

/**
 * Invalidates stage-1 TLB entries referring to the given virtual address range.
 */
static inline void arch_mm_invalidate_stage1_range(vaddr_t va_begin,
						   vaddr_t va_end)
{
}

/**
 * Invalidates stage-2 TLB entries referring to the given intermediate physical
 * address range.
 */
static inline void arch_mm_invalidate_stage2_range(ipaddr_t va_begin,
						   ipaddr_t va_end)
{
}

/**
 * Determines the maximum level supported by the given mode.
 */
static inline uint8_t arch_mm_max_level(int mode)
{
	(void)mode;
	return 2;
}

static inline uint64_t arch_mm_mode_to_attrs(int mode)
{
	(void)mode;
	return 0;
}

static inline bool arch_mm_init(paddr_t table, bool first)
{
	(void)table;
	(void)first;
	return true;
}
