/*
 * Copyright (c) 2018 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr.h>
#include <aarch32/cortex_m/cmse.h>

int arm_cmse_mpu_region_get(uint32_t addr)
{
	cmse_address_info_t addr_info =	cmse_TT((void *)addr);

	if (addr_info.flags.mpu_region_valid) {
		return addr_info.flags.mpu_region;
	}

	return -EINVAL;
}

static int arm_cmse_addr_read_write_ok(uint32_t addr, int force_npriv, int rw)
{
	cmse_address_info_t addr_info;
	if (force_npriv) {
		addr_info = cmse_TTT((void *)addr);
	} else {
		addr_info = cmse_TT((void *)addr);
	}

	return rw ? addr_info.flags.readwrite_ok : addr_info.flags.read_ok;
}

int arm_cmse_addr_read_ok(uint32_t addr, int force_npriv)
{
	return arm_cmse_addr_read_write_ok(addr, force_npriv, 0);
}

int arm_cmse_addr_readwrite_ok(uint32_t addr, int force_npriv)
{
	return arm_cmse_addr_read_write_ok(addr, force_npriv, 1);
}

static int arm_cmse_addr_range_read_write_ok(uint32_t addr, uint32_t size,
	int force_npriv, int rw)
{
	int flags = 0;

	if (force_npriv != 0) {
		flags |= CMSE_MPU_UNPRIV;
	}
	if (rw) {
		flags |= CMSE_MPU_READWRITE;
	} else {
		flags |= CMSE_MPU_READ;
	}
	if (cmse_check_address_range((void *)addr, size, flags) != NULL) {
		return 1;
	} else {
		return 0;
	}
}

int arm_cmse_addr_range_read_ok(uint32_t addr, uint32_t size, int force_npriv)
{
	return arm_cmse_addr_range_read_write_ok(addr, size, force_npriv, 0);
}

int arm_cmse_addr_range_readwrite_ok(uint32_t addr, uint32_t size, int force_npriv)
{
	return arm_cmse_addr_range_read_write_ok(addr, size, force_npriv, 1);
}

#if defined(CONFIG_ARM_SECURE_FIRMWARE)

int arm_cmse_mpu_nonsecure_region_get(uint32_t addr)
{
	cmse_address_info_t addr_info =	cmse_TTA((void *)addr);

	if (addr_info.flags.mpu_region_valid) {
		return  addr_info.flags.mpu_region;
	}

	return -EINVAL;
}

int arm_cmse_sau_region_get(uint32_t addr)
{
	cmse_address_info_t addr_info =	cmse_TT((void *)addr);

	if (addr_info.flags.sau_region_valid) {
		return addr_info.flags.sau_region;
	}

	return -EINVAL;
}

int arm_cmse_idau_region_get(uint32_t addr)
{
	cmse_address_info_t addr_info =	cmse_TT((void *)addr);

	if (addr_info.flags.idau_region_valid) {
		return addr_info.flags.idau_region;
	}

	return -EINVAL;
}

int arm_cmse_addr_is_secure(uint32_t addr)
{
	cmse_address_info_t addr_info =	cmse_TT((void *)addr);

	return addr_info.flags.secure;
}

static int arm_cmse_addr_nonsecure_read_write_ok(uint32_t addr,
	int force_npriv, int rw)
{
	cmse_address_info_t addr_info;
	if (force_npriv) {
		addr_info = cmse_TTAT((void *)addr);
	} else {
		addr_info = cmse_TTA((void *)addr);
	}

	return rw ? addr_info.flags.nonsecure_readwrite_ok :
		addr_info.flags.nonsecure_read_ok;
}

int arm_cmse_addr_nonsecure_read_ok(uint32_t addr, int force_npriv)
{
	return arm_cmse_addr_nonsecure_read_write_ok(addr, force_npriv, 0);
}

int arm_cmse_addr_nonsecure_readwrite_ok(uint32_t addr, int force_npriv)
{
	return arm_cmse_addr_nonsecure_read_write_ok(addr, force_npriv, 1);
}

static int arm_cmse_addr_range_nonsecure_read_write_ok(uint32_t addr, uint32_t size,
	int force_npriv, int rw)
{
	int flags = CMSE_NONSECURE;

	if (force_npriv != 0) {
		flags |= CMSE_MPU_UNPRIV;
	}
	if (rw) {
		flags |= CMSE_MPU_READWRITE;
	} else {
		flags |= CMSE_MPU_READ;
	}
	if (cmse_check_address_range((void *)addr, size, flags) != NULL) {
		return 1;
	} else {
		return 0;
	}
}

int arm_cmse_addr_range_nonsecure_read_ok(uint32_t addr, uint32_t size,
	int force_npriv)
{
	return arm_cmse_addr_range_nonsecure_read_write_ok(addr, size,
		force_npriv, 0);
}

int arm_cmse_addr_range_nonsecure_readwrite_ok(uint32_t addr, uint32_t size,
	int force_npriv)
{
	return arm_cmse_addr_range_nonsecure_read_write_ok(addr, size,
		force_npriv, 1);
}

#endif /* CONFIG_ARM_SECURE_FIRMWARE */
