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

#include <zephyr.h>
#include <misc/printk.h>
#include <mmustructs.h>
#include <ztest.h>
#include "boot_page_table.h"

#define MEMORY_REG_NUM 4

MMU_BOOT_REGION(START_ADDR_RANGE1, ADDR_SIZE, REGION_PERM);
MMU_BOOT_REGION(START_ADDR_RANGE2, ADDR_SIZE, REGION_PERM);
MMU_BOOT_REGION(START_ADDR_RANGE3, ADDR_SIZE, REGION_PERM);
MMU_BOOT_REGION(START_ADDR_RANGE4, ADDR_SIZE, REGION_PERM);

static int check_param(union x86_mmu_pae_pte *value, uint32_t perm)
{
	u32_t status = (value->rw  == ((perm & MMU_PTE_RW_MASK) >> 0x1));

	status &= (value->us == ((perm & MMU_PTE_US_MASK) >> 0x2));
	status &= value->p;
	return status;
}

static int check_param_nonset_region(union x86_mmu_pae_pte *value,
				     uint32_t perm)
{
	u32_t status = (value->rw  == 0);

	status &= (value->us == 0);
	status &= (value->p == 0);
	return status;
}

static void starting_addr_range(u32_t start_addr_range)
{

	u32_t addr_range, status = true;
	union x86_mmu_pae_pte *value;

	for (addr_range = start_addr_range; addr_range <=
	     (start_addr_range + STARTING_ADDR_RANGE_LMT);
	     addr_range += 0x1000) {
		value = X86_MMU_GET_PTE(addr_range);
		status &= check_param(value, REGION_PERM);
		zassert_false((status == 0), "error at %d permissions %d\n",
			      addr_range, REGION_PERM);
	}
}

static void before_start_addr_range(u32_t start_addr_range)
{
	u32_t addr_range, status = true;
	union x86_mmu_pae_pte *value;

	for (addr_range = start_addr_range - 0x7000;
	     addr_range < (start_addr_range); addr_range += 0x1000) {

		value = X86_MMU_GET_PTE(addr_range);
		status &= check_param_nonset_region(value, REGION_PERM);

		zassert_false((status == 0), "error at %d permissions %d\n",
			      addr_range, REGION_PERM);
	}
}

static void ending_start_addr_range(u32_t start_addr_range)
{
	u32_t addr_range, status = true;
	union x86_mmu_pae_pte *value;

	for (addr_range = start_addr_range + ADDR_SIZE; addr_range <
	     (start_addr_range + ADDR_SIZE + 0x10000);
	     addr_range += 0x1000) {
		value = X86_MMU_GET_PTE(addr_range);
		status &= check_param_nonset_region(value, REGION_PERM);
		zassert_false((status == 0), "error at %d permissions %d\n",
			      addr_range, REGION_PERM);
	}
}

void test_boot_page_table(void)
{
	u32_t start_addr_range;
	int iterator = 0;

	for (iterator = 0; iterator < MEMORY_REG_NUM; iterator++) {
		switch (iterator) {

		case 0:
			start_addr_range = START_ADDR_RANGE1;
			break;

		case 1:
			start_addr_range = START_ADDR_RANGE2;
			break;

		case 2:
			start_addr_range = START_ADDR_RANGE3;
			break;

		case 3:
			start_addr_range = START_ADDR_RANGE4;
			break;
		default:
			break;
		}
		starting_addr_range(start_addr_range);
		before_start_addr_range(start_addr_range);
		ending_start_addr_range(start_addr_range);

	}
}

