/*
 * Copyright Meta Platforms, Inc. and its affiliates.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/ztest.h>
#include <zephyr/arch/cpu.h>
#include <cmsis_core.h>
#include <zephyr/sys/barrier.h>

unsigned int sw_irq_number = (unsigned int)(-1);
static volatile bool custom_init_called;
static volatile bool custom_enable_called;
static volatile bool custom_disable_called;
static volatile bool custom_set_priority_called;
static volatile bool custom_eoi_called;
static volatile bool irq_handler_called;

/* Define out custom SoC interrupt controller interface methods.
 * These closely match the normal Cortex-M implementations.
 */

#define NUM_IRQS_PER_REG  32
#define REG_FROM_IRQ(irq) (irq / NUM_IRQS_PER_REG)
#define BIT_FROM_IRQ(irq) (irq % NUM_IRQS_PER_REG)

void z_soc_irq_init(void)
{
	int irq = 0;

	for (; irq < CONFIG_NUM_IRQS; irq++) {
		NVIC_SetPriority((IRQn_Type)irq, _IRQ_PRIO_OFFSET);
	}

	custom_init_called = true;
}

void z_soc_irq_enable(unsigned int irq)
{
	if (irq == sw_irq_number) {
		custom_enable_called = true;
	}
	NVIC_EnableIRQ((IRQn_Type)irq);
}

void z_soc_irq_disable(unsigned int irq)
{
	if (irq == sw_irq_number) {
		custom_disable_called = true;
	}
	NVIC_DisableIRQ((IRQn_Type)irq);
}

int z_soc_irq_is_enabled(unsigned int irq)
{
	return NVIC->ISER[REG_FROM_IRQ(irq)] & BIT(BIT_FROM_IRQ(irq));
}

void z_soc_irq_eoi(unsigned int irq)
{
	if (irq == sw_irq_number) {
		custom_eoi_called = true;
	}
}

inline __attribute__((always_inline)) unsigned int z_soc_irq_get_active(void)
{
	return __get_IPSR();
}

void z_soc_irq_priority_set(unsigned int irq, unsigned int prio, uint32_t flags)
{
	if (irq == sw_irq_number) {
		custom_set_priority_called = true;
	}

	if (IS_ENABLED(CONFIG_ZERO_LATENCY_IRQS) && (flags & IRQ_ZERO_LATENCY)) {
		prio = _EXC_ZERO_LATENCY_IRQS_PRIO;
	} else {
		prio += _IRQ_PRIO_OFFSET;
	}

	NVIC_SetPriority((IRQn_Type)irq, prio);
}

void arm_isr_handler(const void *args)
{
	ARG_UNUSED(args);

#if defined(CONFIG_CPU_CORTEX_M) && defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING)
	/* Clear Floating Point Status and Control Register (FPSCR),
	 * to prevent from having the interrupt line set to pending again,
	 * in case FPU IRQ is selected by the test as "Available IRQ line"
	 */
#if defined(CONFIG_ARMV8_1_M_MAINLINE)
	/*
	 * For ARMv8.1-M with FPU, the FPSCR[18:16] LTPSIZE field must be set
	 * to 0b100 for "Tail predication not applied" as it's reset value
	 */
	__set_FPSCR(4 << FPU_FPDSCR_LTPSIZE_Pos);
#else
	__set_FPSCR(0);
#endif
#endif

	/* IRQ numbers are offset by 16 on Cortex-M. */
	unsigned int this_irq = z_soc_irq_get_active() - 16;

	TC_PRINT("Got IRQ: %u\n", this_irq);

	zassert_equal(this_irq, sw_irq_number, "Unexpected active IRQ\n");
	irq_handler_called = true;
}

/**
 * @brief Test custom interrupt controller handling with CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER.
 * @addtogroup kernel_interrupt_tests
 * @ingroup all_tests
 * @{
 */

ZTEST(arm_custom_interrupt, test_arm_interrupt)
{
	zassert_true(custom_init_called, "Custom IRQ init not called\n");

	/* Determine an NVIC IRQ line that is not currently in use. */
	int i;

	for (i = CONFIG_NUM_IRQS - 1; i >= 0; i--) {
		if (NVIC_GetEnableIRQ(i) == 0) {
			/*
			 * Interrupts configured statically with IRQ_CONNECT(.)
			 * are automatically enabled. NVIC_GetEnableIRQ()
			 * returning false, here, implies that the IRQ line is
			 * either not implemented or it is not enabled, thus,
			 * currently not in use by Zephyr.
			 */

			/* Set the NVIC line to pending. */
			NVIC_SetPendingIRQ(i);

			if (NVIC_GetPendingIRQ(i)) {
				/* If the NVIC line is pending, it is
				 * guaranteed that it is implemented; clear the
				 * line.
				 */
				NVIC_ClearPendingIRQ(i);

				if (!NVIC_GetPendingIRQ(i)) {
					/*
					 * If the NVIC line can be successfully
					 * un-pended, it is guaranteed that it
					 * can be used for software interrupt
					 * triggering.
					 */
					break;
				}
			}
		}
	}

	zassert_true(i >= 0, "No available IRQ line to use in the test\n");

	TC_PRINT("Available IRQ line: %u\n", i);
	sw_irq_number = i;

	zassert_false(custom_set_priority_called, "Custom set priority flag set\n");
	arch_irq_connect_dynamic(sw_irq_number, 0 /* highest priority */, arm_isr_handler, NULL, 0);
	zassert_true(custom_set_priority_called, "Custom set priority not called\n");

	NVIC_ClearPendingIRQ(i);

	zassert_false(arch_irq_is_enabled(sw_irq_number), "SW IRQ already enabled\n");
	zassert_false(custom_enable_called, "Custom IRQ enable flag is set\n");
	irq_enable(sw_irq_number);
	zassert_true(custom_enable_called, "Custom IRQ enable not called\n");
	zassert_true(arch_irq_is_enabled(sw_irq_number), "SW IRQ is not enabled\n");

	for (int j = 1; j <= 3; j++) {
		custom_eoi_called = false;
		irq_handler_called = false;
		custom_set_priority_called = false;

		/* Set the dynamic IRQ to pending state. */
		NVIC_SetPendingIRQ(i);

		/*
		 * Instruction barriers to make sure the NVIC IRQ is
		 * set to pending state before 'test_flag' is checked.
		 */
		barrier_dsync_fence_full();
		barrier_isync_fence_full();

		/* Returning here implies the thread was not aborted. */

		/* Confirm test flag is set by the ISR handler. */
		zassert_true(custom_eoi_called, "Custom EOI handler not called\n");
		zassert_true(irq_handler_called, "ISR handler not called\n");
	}

	zassert_false(custom_disable_called, "Custom IRQ disable flag is set\n");
	irq_disable(sw_irq_number);
	zassert_true(custom_disable_called, "Custom IRQ disable not called\n");
}

/**
 * @}
 */
