/*
 * Copyright (c) 2020 Intel Corporation.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/**
 * @file
 * x86-specific tests for MMU features and page tables
 */

#include <zephyr.h>
#include <ztest.h>
#include <tc_util.h>
#include <arch/x86/mmustructs.h>
#include <x86_mmu.h>
#include <linker/linker-defs.h>
#include <mmu.h>
#include "main.h"

#ifdef CONFIG_X86_64
#define PT_LEVEL	3
#elif CONFIG_X86_PAE
#define PT_LEVEL	2
#else
#define PT_LEVEL	1
#endif

/* Set of flags whose state we will check. Ignore Accessed/Dirty
 * At leaf level PS bit indicates PAT, but regardless we don't set it
 */
#define FLAGS_MASK	(MMU_P | MMU_RW | MMU_US | MMU_PWT | MMU_PCD | \
			 MMU_G | MMU_PS | MMU_XD)

#define LPTR(name, suffix)	((uint8_t *)&_CONCAT(name, suffix))
#define LSIZE(name, suffix)	((size_t)&_CONCAT(name, suffix))
#define IN_REGION(name, virt) \
	(virt >= LPTR(name, _start) && \
	 virt < (LPTR(name, _start) + LSIZE(name, _size)))

#ifdef CONFIG_X86_64
extern char _locore_start[];
extern char _locore_size[];
extern char _lorodata_start[];
extern char _lorodata_size[];
extern char _lodata_end[];

#define LOCORE_START	((uint8_t *)&_locore_start)
#define LOCORE_END	((uint8_t *)&_lodata_end)
#endif

#ifdef CONFIG_COVERAGE_GCOV
extern char __gcov_bss_start[];
extern char __gcov_bss_size[];
#endif

static pentry_t get_entry(pentry_t *flags, void *addr)
{
	int level;
	pentry_t entry;

	z_x86_pentry_get(&level, &entry, z_x86_page_tables_get(), addr);

	zassert_true((entry & MMU_P) != 0,
		     "non-present RAM entry");
	zassert_equal(level, PT_LEVEL, "bigpage found");
	*flags = entry & FLAGS_MASK;

	return entry;
}

/**
 * Test that MMU flags on RAM virtual address range are set properly
 *
 * @ingroup kernel_memprotect_tests
 */
void test_ram_perms(void)
{
	uint8_t *pos;

	pentry_t entry, flags, expected;

	for (pos = Z_KERNEL_VIRT_START; pos < Z_KERNEL_VIRT_END;
	     pos += CONFIG_MMU_PAGE_SIZE) {
		if (pos == NULL) {
			/* We have another test specifically for NULL page */
			continue;
		}

		entry = get_entry(&flags, pos);

		if (!IS_ENABLED(CONFIG_SRAM_REGION_PERMISSIONS)) {
			expected = MMU_P | MMU_RW;
		} else if (IN_REGION(_image_text, pos)) {
			expected = MMU_P | MMU_US;
		} else if (IN_REGION(_image_rodata, pos)) {
			expected = MMU_P | MMU_US | MMU_XD;
#ifdef CONFIG_COVERAGE_GCOV
		} else if (IN_REGION(__gcov_bss, pos)) {
			expected = MMU_P | MMU_RW | MMU_US | MMU_XD;
#endif
#if !defined(CONFIG_X86_KPTI) && !defined(CONFIG_X86_COMMON_PAGE_TABLE) && \
				  defined(CONFIG_USERSPACE)
		} else if (IN_REGION(_app_smem, pos)) {
			/* If KPTI is not enabled, then the default memory
			 * domain affects our page tables even though we are
			 * in supervisor mode. We'd expect everything in
			 * the _app_smem region to have US set since all the
			 * partitions within it would be active in
			 * k_mem_domain_default (ztest_partition and any libc
			 * partitions)
			 *
			 * If we have a common page table, no thread has
			 * entered user mode yet and no domain regions
			 * will be programmed.
			 */
			expected = MMU_P | MMU_US | MMU_RW | MMU_XD;
#endif /* CONFIG_X86_KPTI */
#ifdef CONFIG_LINKER_USE_BOOT_SECTION
		} else if (IN_REGION(lnkr_boot_text, pos)) {
			expected = MMU_P | MMU_US;
		} else if (IN_REGION(lnkr_boot_rodata, pos)) {
			expected = MMU_P | MMU_US | MMU_XD;
#endif
#ifdef CONFIG_LINKER_USE_PINNED_SECTION
		} else if (IN_REGION(lnkr_pinned_text, pos)) {
			expected = MMU_P | MMU_US;
		} else if (IN_REGION(lnkr_pinned_rodata, pos)) {
			expected = MMU_P | MMU_US | MMU_XD;
#endif
		} else {
			/* We forced CONFIG_HW_STACK_PROTECTION off otherwise
			 * guard pages will have RW cleared. We can relax this
			 * once we start memory-mapping stacks.
			 */
			expected = MMU_P | MMU_RW | MMU_XD;
		}
		zassert_equal(flags, expected,
			      "bad flags " PRI_ENTRY " at %p, expected "
			      PRI_ENTRY, flags, pos, expected);
	}

#ifdef CONFIG_X86_64
	/* Check the locore too */
	for (pos = LOCORE_START; pos < LOCORE_END;
	     pos += CONFIG_MMU_PAGE_SIZE) {
		if (pos == NULL) {
			/* We have another test specifically for NULL page */
			continue;
		}

		entry = get_entry(&flags, pos);

		if (IN_REGION(_locore, pos)) {
			if (IS_ENABLED(CONFIG_X86_KPTI)) {
				expected = MMU_P | MMU_US;
			} else {
				expected = MMU_P;
			}
		} else if (IN_REGION(_lorodata, pos)) {
			if (IS_ENABLED(CONFIG_X86_KPTI)) {
				expected = MMU_P | MMU_US | MMU_XD;
			} else {
				expected = MMU_P | MMU_XD;
			}
		} else {
			expected = MMU_P | MMU_RW | MMU_XD;
		}
		zassert_equal(flags, expected,
			      "bad flags " PRI_ENTRY " at %p, expected "
			      PRI_ENTRY, flags, pos, expected);
	}
#endif /* CONFIG_X86_64 */

#ifdef CONFIG_ARCH_MAPS_ALL_RAM
	/* All RAM page frame entries aside from 0x0 must have a mapping.
	 * We currently identity-map on x86, no conversion necessary other than a cast
	 */
	for (pos = (uint8_t *)Z_PHYS_RAM_START; pos < (uint8_t *)Z_PHYS_RAM_END;
	     pos += CONFIG_MMU_PAGE_SIZE) {
		if (pos == NULL) {
			continue;
		}

		entry = get_entry(&flags, pos);
		zassert_true((flags & MMU_P) != 0,
			     "address %p isn't mapped", pos);
	}
#endif
}

/**
 * Test that the NULL virtual page is always non-present
 *
 * @ingroup kernel_memprotect_tests
 */
void test_null_map(void)
{
	int level;
	pentry_t entry;

	/* The NULL page must always be non-present */
	z_x86_pentry_get(&level, &entry, z_x86_page_tables_get(), NULL);
	zassert_true((entry & MMU_P) == 0, "present NULL entry");
}

void z_impl_dump_my_ptables(void)
{
	struct k_thread *cur = k_current_get();

	printk("Page tables for thread %p\n", cur);
	z_x86_dump_page_tables(z_x86_thread_page_tables_get(cur));
}

#ifdef CONFIG_USERSPACE
void z_vrfy_dump_my_ptables(void)
{
	z_impl_dump_my_ptables();
}
#include <syscalls/dump_my_ptables_mrsh.c>
#endif /* CONFIG_USERSPACE */

/**
 * Dump kernel's page tables to console
 *
 * We don't verify any specific output, but this shouldn't crash
 *
 * @ingroup kernel_memprotect_tests
 */
void test_dump_ptables(void)
{
#if CONFIG_SRAM_SIZE > (32 << 10)
	/*
	 * Takes too long to dump page table, so skip dumping
	 * if memory size is larger than 32MB.
	 */
	ztest_test_skip();
#else
	dump_my_ptables();
#endif
}

void test_main(void)
{
	ztest_test_suite(x86_pagetables,
			 ztest_unit_test(test_ram_perms),
			 ztest_unit_test(test_null_map),
			 ztest_unit_test(test_dump_ptables),
			 ztest_user_unit_test(test_dump_ptables)
			 );
	ztest_run_test_suite(x86_pagetables);
}
