/*
 * Copyright (c) 2021 Espressif Systems (Shanghai) Co., Ltd.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <soc/periph_defs.h>
#include <limits.h>
#include <assert.h>
#include "soc/soc.h"
#include <soc.h>
#include <zephyr.h>
#include <drivers/interrupt_controller/intc_esp32c3.h>
#include <sw_isr_table.h>

#include <logging/log.h>
LOG_MODULE_REGISTER(intc_esp32c3, CONFIG_LOG_DEFAULT_LEVEL);

/*
 * Define this to debug the choices made when allocating the interrupt. This leads to much debugging
 * output within a critical region, which can lead to weird effects like e.g. the interrupt watchdog
 * being triggered, that is why it is separate from the normal LOG* scheme.
 */
#ifdef CONFIG_INTC_ESP32C3_DECISIONS_LOG
# define INTC_LOG(...) LOG_INF(__VA_ARGS__)
#else
# define INTC_LOG(...) do {} while (0)
#endif

#define ESP32C3_INTC_DEFAULT_PRIORITY   15
#define ESP32C3_INTC_DEFAULT_THRESHOLD  1
#define ESP32C3_INTC_DISABLED_SLOT      31
#define ESP32C3_INTC_SRCS_PER_IRQ       2
#define ESP32C3_INTC_AVAILABLE_IRQS     30

static uint32_t esp_intr_enabled_mask[2] = {0, 0};

static void esp_intr_default_isr(const void *arg)
{
	ARG_UNUSED(arg);
	ulong_t mcause;

	__asm__ volatile("csrr %0, mcause" : "=r" (mcause));
	mcause &= SOC_MCAUSE_EXP_MASK;

	INTC_LOG("Spurious interrupt, mcause: %ld, source %d", mcause, soc_intr_get_next_source());
}

static uint32_t esp_intr_find_irq_for_source(uint32_t source)
{
	/* in general case, each 2 sources goes routed to
	 * 1 IRQ line.
	 */
	uint32_t irq = (source / ESP32C3_INTC_SRCS_PER_IRQ);

	if (irq > ESP32C3_INTC_AVAILABLE_IRQS) {
		INTC_LOG("Clamping the source: %d no more IRQs available", source);
		irq = ESP32C3_INTC_AVAILABLE_IRQS;
	} else if (irq == 0) {
		irq = 1;
	}

	INTC_LOG("Found IRQ: %d for source: %d", irq, source);

	return irq;
}

void esp_intr_initialize(void)
{
	/* IRQ 31 is reserved for disabled interrupts,
	 * so route all sources to it
	 */
	for (int i = 0 ; i < ESP32C3_INTC_AVAILABLE_IRQS + 2; i++) {
		irq_disable(i);
	}

	for (int i = 0; i < ETS_MAX_INTR_SOURCE; i++) {
		esp_rom_intr_matrix_set(0,
			i,
			ESP32C3_INTC_DISABLED_SLOT);

		irq_connect_dynamic(i,
			ESP32C3_INTC_DEFAULT_PRIORITY,
			esp_intr_default_isr,
			NULL,
			0);
	}

	/* set global esp32c3's INTC masking level */
	esprv_intc_int_set_threshold(ESP32C3_INTC_DEFAULT_THRESHOLD);
}

int esp_intr_alloc(int source,
		int flags,
		isr_handler_t handler,
		void *arg,
		void **ret_handle)
{
	ARG_UNUSED(flags);
	ARG_UNUSED(ret_handle);

	if (handler == NULL) {
		return -EINVAL;
	}

	if (source < 0 || source >= ETS_MAX_INTR_SOURCE) {
		return -EINVAL;
	}

	uint32_t key = irq_lock();
	uint32_t irq = esp_intr_find_irq_for_source(source);

	esp_rom_intr_matrix_set(0, source, irq);

	irq_connect_dynamic(source,
		ESP32C3_INTC_DEFAULT_PRIORITY,
		handler,
		arg,
		0);

	if (source < 32) {
		esp_intr_enabled_mask[0] |= (1 << source);
	} else {
		esp_intr_enabled_mask[1] |= (1 << (source - 32));
	}

	INTC_LOG("Enabled ISRs -- 0: 0x%X -- 1: 0x%X",
		esp_intr_enabled_mask[0], esp_intr_enabled_mask[1]);

	irq_unlock(key);
	irq_enable(irq);

	return 0;
}

int esp_intr_disable(int source)
{
	if (source < 0 || source >= ETS_MAX_INTR_SOURCE) {
		return -EINVAL;
	}

	uint32_t key = irq_lock();

	esp_rom_intr_matrix_set(source,
		source,
		ESP32C3_INTC_DISABLED_SLOT);

	if (source < 32) {
		esp_intr_enabled_mask[0] &= ~(1 << source);
	} else {
		esp_intr_enabled_mask[1] &= ~(1 << (source - 32));
	}

	INTC_LOG("Enabled ISRs -- 0: 0x%X -- 1: 0x%X",
		esp_intr_enabled_mask[0], esp_intr_enabled_mask[1]);

	irq_unlock(key);

	return 0;
}

int esp_intr_enable(int source)
{
	if (source < 0 || source >= ETS_MAX_INTR_SOURCE) {
		return -EINVAL;
	}

	uint32_t key = irq_lock();
	uint32_t irq = esp_intr_find_irq_for_source(source);

	irq_disable(irq);
	esp_rom_intr_matrix_set(0, source, irq);

	if (source < 32) {
		esp_intr_enabled_mask[0] |= (1 << source);
	} else {
		esp_intr_enabled_mask[1] |= (1 << (source - 32));
	}

	INTC_LOG("Enabled ISRs -- 0: 0x%X -- 1: 0x%X",
		esp_intr_enabled_mask[0], esp_intr_enabled_mask[1]);

	irq_enable(irq);
	irq_unlock(key);

	return 0;
}

uint32_t esp_intr_get_enabled_intmask(int status_mask_number)
{
	INTC_LOG("Enabled ISRs -- 0: 0x%X -- 1: 0x%X",
		esp_intr_enabled_mask[0], esp_intr_enabled_mask[1]);

	if (status_mask_number == 0) {
		return esp_intr_enabled_mask[0];
	} else {
		return esp_intr_enabled_mask[1];
	}
}
