/*
 * Copyright (c) 2021 Andes Technology Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <init.h>
#include <kernel.h>
#include <arch/cpu.h>
#include <linker/linker-defs.h>

/* Programmable PMA mechanism is supported */
#define MMSC_CFG_PPMA		(1 << 30)

/*
 * PMA Configuration (PMACFG) bitfields
 */

/* ETYPE: Entry address matching mode */
#define PMACFG_ETYPE_MASK	3
#define PMACFG_ETYPE_OFF	0
#define PMACFG_ETYPE_TOR	1
#define PMACFG_ETYPE_NA4	2
#define PMACFG_ETYPE_NAPOT	3

/* MTYPE: Memory type attribute */
#define PMACFG_MTYPE_MASK			(0xF << 2)
/* non-cacheable attributes (bufferable or not) */
#define PMACFG_MTYPE_MEMORY_NOCACHE_BUFFERABLE	(3 << 2)
/* cacheable attributes (write-through/back, no/read/write/RW-allocate) */
#define PMACFG_MTYPE_MEMORY_WBCACHE_RWALLOC	(11 << 2)

/* pmaaddr is 4-byte granularity in each mode */
#define TO_PMA_ADDR(addr)		((addr) >> 2)

/* The base address is aligned to size */
#define NAPOT_BASE(start, size)		TO_PMA_ADDR((start) & ~((size) - 1))
/* The encoding of size is 0b01...1
 * (change the leading bit of bitmask to 0)
 */
#define NAPOT_SIZE(size)		TO_PMA_ADDR(((size) - 1) >> 1)

#define NA4_ENCODING(start)		TO_PMA_ADDR(start)
#define NAPOT_ENCODING(start, size)	(NAPOT_BASE(start, size) \
					 | NAPOT_SIZE(size))

#ifdef CONFIG_64BIT
/* In riscv64, CSR pmacfg number are even number (0, 2, ...) */
# define PMACFG_NUM(index)		((index / RV_REGSIZE) * 2)
#else
# define PMACFG_NUM(index)		(index / RV_REGSIZE)
#endif
#define PMACFG_SHIFT(index)		((index % RV_REGSIZE) * 8)

/* Wrappers of inline assembly */
#define read_csr(var, csr) \
	__asm__ volatile ("csrr %0, %1" : "=r" (var) : "i" (csr))
#define write_csr(csr, val) \
	__asm__ volatile ("csrw %0, %1" :: "i" (csr), "r" (val))

struct pma_region_attr {
	/* Attributes belonging to pmacfg{i} */
	uint8_t pmacfg;
};

struct pma_region {
	ulong_t start;
	ulong_t size;
	struct pma_region_attr attr;
};

/*
 * Write value to CSRs pmaaddr{i}
 */
static void write_pmaaddr_csr(const uint32_t index, ulong_t value)
{
	switch (index) {
	case 0:
		write_csr(NDS_PMAADDR0,  value); break;
	case 1:
		write_csr(NDS_PMAADDR1,  value); break;
	case 2:
		write_csr(NDS_PMAADDR2,  value); break;
	case 3:
		write_csr(NDS_PMAADDR3,  value); break;
	case 4:
		write_csr(NDS_PMAADDR4,  value); break;
	case 5:
		write_csr(NDS_PMAADDR5,  value); break;
	case 6:
		write_csr(NDS_PMAADDR6,  value); break;
	case 7:
		write_csr(NDS_PMAADDR7,  value); break;
	case 8:
		write_csr(NDS_PMAADDR8,  value); break;
	case 9:
		write_csr(NDS_PMAADDR9,  value); break;
	case 10:
		write_csr(NDS_PMAADDR10, value); break;
	case 11:
		write_csr(NDS_PMAADDR11, value); break;
	case 12:
		write_csr(NDS_PMAADDR12, value); break;
	case 13:
		write_csr(NDS_PMAADDR13, value); break;
	case 14:
		write_csr(NDS_PMAADDR14, value); break;
	case 15:
		write_csr(NDS_PMAADDR15, value); break;
	}
}

/*
 * Write value to pma{i}cfg entry which are packed into CSRs pmacfg{j}
 */
static void write_pmacfg_entry(const uint32_t entry_index,
	uint8_t entry_value)
{
	/* 1-byte pma{i}cfg entries are packed into XLEN-byte CSRs pmacfg{j} */
	uint32_t index = PMACFG_NUM(entry_index);
	uint8_t shift = PMACFG_SHIFT(entry_index);
	ulong_t pmacfg = 0;

	switch (index) {
	case 0:
		read_csr(pmacfg, NDS_PMACFG0); break;
	case 1:
		read_csr(pmacfg, NDS_PMACFG1); break;
	case 2:
		read_csr(pmacfg, NDS_PMACFG2); break;
	case 3:
		read_csr(pmacfg, NDS_PMACFG3); break;
	}

	/* clear old value in pmacfg entry */
	pmacfg &= ~(0xFF << shift);
	/* set new value to pmacfg entry value */
	pmacfg |= entry_value << shift;

	switch (index) {
	case 0:
		write_csr(NDS_PMACFG0, pmacfg); break;
	case 1:
		write_csr(NDS_PMACFG1, pmacfg); break;
	case 2:
		write_csr(NDS_PMACFG2, pmacfg); break;
	case 3:
		write_csr(NDS_PMACFG3, pmacfg); break;
	}
}

/*
 * This internal function performs PMA region initialization.
 *
 * Note:
 *   The caller must provide a valid region index.
 */
static void region_init(const uint32_t index,
	const struct pma_region *region_conf)
{
	ulong_t pmaaddr;
	uint8_t pmacfg;

	if (region_conf->size == 4) {
		pmaaddr = NA4_ENCODING(region_conf->start);
		pmacfg = region_conf->attr.pmacfg | PMACFG_ETYPE_NA4;
	} else {
		pmaaddr = NAPOT_ENCODING(region_conf->start, region_conf->size);
		pmacfg = region_conf->attr.pmacfg | PMACFG_ETYPE_NAPOT;
	}

	write_pmaaddr_csr(index, pmaaddr);
	write_pmacfg_entry(index, pmacfg);
}

/*
 * This internal function performs run-time sanity check for
 * PMA region start address and size.
 */
static int pma_region_is_valid(const struct pma_region *region)
{
	/* Region size must be power-of-two,
	 * and greater or equal to the minimum
	 * PMA region size. Start address of the
	 * region must align with size.
	 */
	int region_is_valid =
		((region->size & (region->size - 1)) == 0U)
		&&
		(region->size >= CONFIG_SOC_ANDES_V5_PMA_REGION_MIN_ALIGN_AND_SIZE)
		&&
		((region->start & (region->size - 1)) == 0U);

	return region_is_valid;
}

#ifdef CONFIG_NOCACHE_MEMORY
static void configure_nocache_region(void)
{
	const struct pma_region nocache_region = {
		.start = (ulong_t)&_nocache_ram_start,
		.size = (ulong_t)&_nocache_ram_size,
		.attr = {PMACFG_MTYPE_MEMORY_NOCACHE_BUFFERABLE},
	};

	if (pma_region_is_valid(&nocache_region) == -EINVAL) {
		__ASSERT(0, "Configuring PMA region of nocache region failed\n");
	}

	/* Initialize nocache region at PMA region 0 */
	region_init(0, &nocache_region);
}
#endif /* CONFIG_NOCACHE_MEMORY */

/*
 * @brief Init PMA CSRs of each CPU core
 *
 * In SMP, each CPU has it's own PMA CSR and PMA CSR only affect one CPU.
 * We should configure CSRs of all CPUs to make memory attribute
 * (e.g. uncacheable) affects all CPUs.
 */
void pma_init_per_core(void)
{
#ifdef CONFIG_NOCACHE_MEMORY
	configure_nocache_region();
#endif /* CONFIG_NOCACHE_MEMORY */
}

static int pma_init(const struct device *arg)
{
	ulong_t mmsc_cfg;

	__asm__ volatile ("csrr %0, %1" : "=r" (mmsc_cfg) : "i" (NDS_MMSC_CFG));

	if (!(mmsc_cfg & MMSC_CFG_PPMA)) {
		/* This CPU doesn't support PMA */

		__ASSERT(0, "CPU doesn't support PMA. "
			    "Please disable CONFIG_SOC_ANDES_V5_PMA\n");
		return -1;
	}

	pma_init_per_core();

	return 0;
}

SYS_INIT(pma_init, PRE_KERNEL_2,
	CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);
