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

/**
 * @file
 * @brief ARM Cortex-M debug monitor functions interface based on DWT
 *
 */

#include <device.h>
#include <aarch32/cortex_m/dwt.h>

/**
 * @brief Assess whether a debug monitor event should be treated as an error
 *
 * This routine checks the status of a debug monitor ()exception, and
 * evaluates whether this needs to be considered as a processor error.
 *
 * @return true if the DM exception is a processor error, otherwise false
 */
bool z_arm_debug_monitor_event_error_check(void)
{
#if defined(CONFIG_NULL_POINTER_EXCEPTION_DETECTION_DWT)
	/* Assess whether this debug exception was triggered
	 * as a result of a null pointer (R/W) dereferencing.
	 */
	if (SCB->DFSR & SCB_DFSR_DWTTRAP_Msk) {
		/* Debug event generated by the DWT unit */
		if (DWT->FUNCTION0 & DWT_FUNCTION_MATCHED_Msk) {
			/* DWT Comparator match used for */
			printk("Null-pointer exception?\n");
		}
		__ASSERT((DWT->FUNCTION0 & DWT_FUNCTION_MATCHED_Msk) == 0,
			"MATCHED flag should have been cleared on read.");

		return true;
	}
	if (SCB->DFSR & SCB_DFSR_BKPT_Msk) {
		/* Treat BKPT events as an error as well (since they
		 * would mean the system would be stuck in an infinite loop).
		 */
		return true;
	}
#endif /* CONFIG_NULL_POINTER_EXCEPTION_DETECTION_DWT */
	return false;
}

#if defined(CONFIG_NULL_POINTER_EXCEPTION_DETECTION_DWT)

/* The area (0x0 - <size>) monitored by DWT needs to be a power of 2,
 * so we add a build assert that catches it.
 */
BUILD_ASSERT(!(CONFIG_CORTEX_M_NULL_POINTER_EXCEPTION_PAGE_SIZE &
	(CONFIG_CORTEX_M_NULL_POINTER_EXCEPTION_PAGE_SIZE - 1)),
	"the size of the partition must be power of 2");

static int z_arm_debug_enable_null_pointer_detection(const struct device *arg)
{
	ARG_UNUSED(arg);

	z_arm_dwt_init();
	z_arm_dwt_enable_debug_monitor();

	/* Enable null pointer detection by monitoring R/W access to the
	 * memory area 0x0 - <size> that is (or was intentionally left)
	 * unused by the system.
	 */

#if defined(CONFIG_ARMV8_M_MAINLINE)

	/* ASSERT that we have the comparators needed for the implementation */
	if (((DWT->CTRL & DWT_CTRL_NUMCOMP_Msk) >> DWT_CTRL_NUMCOMP_Pos) < 2) {
		__ASSERT(0, "on board DWT does not support the feature\n");
		return -EINVAL;
	}

	/* Use comparators 0, 1, R/W access check */
	DWT->COMP0 = 0;
	DWT->COMP1 = CONFIG_CORTEX_M_NULL_POINTER_EXCEPTION_PAGE_SIZE - 1;

	DWT->FUNCTION0 =
		((0x4 << DWT_FUNCTION_MATCH_Pos) & DWT_FUNCTION_MATCH_Msk)
		|
		((0x1 << DWT_FUNCTION_ACTION_Pos) & DWT_FUNCTION_ACTION_Msk)
		|
		((0x0 << DWT_FUNCTION_DATAVSIZE_Pos) & DWT_FUNCTION_DATAVSIZE_Msk)
		;
	DWT->FUNCTION1 =
		((0x7 << DWT_FUNCTION_MATCH_Pos) & DWT_FUNCTION_MATCH_Msk)
		|
		((0x1 << DWT_FUNCTION_ACTION_Pos) & DWT_FUNCTION_ACTION_Msk)
		|
		((0x0 << DWT_FUNCTION_DATAVSIZE_Pos) & DWT_FUNCTION_DATAVSIZE_Msk)
		;
#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE)

	/* ASSERT that we have the comparator needed for the implementation */
	if (((DWT->CTRL & DWT_CTRL_NUMCOMP_Msk) >> DWT_CTRL_NUMCOMP_Pos) < 1) {
		__ASSERT(0, "on board DWT does not support the feature\n");
		return -EINVAL;
	}

	/* Use comparator 0, R/W access check */
	DWT->COMP0 = 0;

	DWT->FUNCTION0 = (0x7 << DWT_FUNCTION_FUNCTION_Pos) &
		DWT_FUNCTION_FUNCTION_Msk;


	/* Set mask according to the desired size */
	DWT->MASK0 = 32 - __builtin_clzl(
		CONFIG_CORTEX_M_NULL_POINTER_EXCEPTION_PAGE_SIZE - 1);
#endif

	return 0;
}

SYS_INIT(z_arm_debug_enable_null_pointer_detection, PRE_KERNEL_1,
	 CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);

#endif /* CONFIG_NULL_POINTER_EXCEPTION_DETECTION_DWT */
