/*
 * Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
 *
 * SPDX-License-Identifier: MIT
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include "n200_func.h"
#include "register.h"
#include "common.h"
#include "n200_timer.h"
#include "gcc_compiler_attributes.h"
#include "riscv_encoding.h"

// Configure PMP to make all the address space accesable and executable
void pmp_open_all_space(void)
{
	// Config entry0 addr to all 1s to make the range cover all space
	asm volatile("li x6, 0xffffffff" ::: "x6");
	asm volatile("csrw pmpaddr0, x6" :::);
	// Config entry0 cfg to make it NAPOT address mode, and R/W/X okay
	asm volatile("li x6, 0x7f" ::: "x6");
	asm volatile("csrw pmpcfg0, x6" :::);
}

void switch_m2u_mode(void)
{
	clear_csr(mstatus, MSTATUS_MPP);
	//printf("\nIn the m2u function, the mstatus is 0x%x\n", read_csr(mstatus));
	//printf("\nIn the m2u function, the mepc is 0x%x\n", read_csr(mepc));
	asm volatile("la x6, 1f    " ::: "x6");
	asm volatile("csrw mepc, x6" :::);
	asm volatile("mret" :::);
	asm volatile("1:" :::);
}

uint32_t mtime_lo(void)
{
#ifdef configSOC_TIMER_AS_TICK
	return *(volatile uint32_t *)TIMERE_LOW_REG;
#else
	return *(volatile uint32_t *)(TIMER_CTRL_ADDR + TIMER_MTIME);
#endif
}

uint32_t mtime_hi(void)
{
#ifdef configSOC_TIMER_AS_TICK
	return *(volatile uint32_t *)TIMERE_HIG_REG;
#else
	return *(volatile uint32_t *)(TIMER_CTRL_ADDR + TIMER_MTIME + 4);
#endif
}

uint64_t get_timer_value(void)
{
	while (1) {
		uint32_t hi = mtime_hi();
		uint32_t lo = mtime_lo();

		if (hi == mtime_hi())
			return ((uint64_t)hi << 32) | lo;
	}
}

uint32_t get_timer_freq(void)
{
	return TIMER_FREQ;
}

uint64_t get_instret_value(void)
{
	while (1) {
		uint32_t hi = read_csr(minstreth);
		uint32_t lo = read_csr(minstret);

		if (hi == read_csr(minstreth))
			return ((uint64_t)hi << 32) | lo;
	}
}

uint64_t get_cycle_value(void)
{
	while (1) {
		uint32_t hi = read_csr(mcycleh);
		uint32_t lo = read_csr(mcycle);

		if (hi == read_csr(mcycleh))
			return ((uint64_t)hi << 32) | lo;
	}
}

unsigned long interrupt_status_get(void)
{
	return read_csr(mstatus) >> 0x3;
}

void interrupt_disable(void)
{
	clear_csr(mstatus, MSTATUS_MIE);
}

void interrupt_enable(void)
{
	set_csr(mstatus, MSTATUS_MIE);
}

#ifndef CONFIG_N200_REVA

uint32_t __noinline measure_cpu_freq(size_t n)
{
	uint32_t start_mtime, delta_mtime;
	uint32_t mtime_freq = get_timer_freq();
	// Don't start measuruing until we see an mtime tick
	uint32_t tmp = mtime_lo();

	do {
		start_mtime = mtime_lo();
	} while (start_mtime == tmp);

	uint32_t start_mcycle = read_csr(mcycle);

	do {
		delta_mtime = mtime_lo() - start_mtime;
	} while (delta_mtime < n);

	uint32_t delta_mcycle = read_csr(mcycle) - start_mcycle;

	return (delta_mcycle / delta_mtime) * mtime_freq +
	       ((delta_mcycle % delta_mtime) * mtime_freq) / delta_mtime;
}

uint32_t get_cpu_freq(void)
{
	uint32_t cpu_freq;

	// warm up
	measure_cpu_freq(1);
	// measure for real
	cpu_freq = measure_cpu_freq(100);

	return cpu_freq;
}

unsigned int xPortIsIsrContext(void)
{
	return (read_csr_msubmode & 0xff);
}

#else

unsigned int xPortIsIsrContext(void)
{
	return read_csr_msubmode;
}

#endif
