/*
 * SPDX-License-Identifier: BSD-2-Clause
 *
 * Copyright (c) 2019 Western Digital Corporation or its affiliates.
 *
 * Authors:
 *   Anup Patel <anup.patel@wdc.com>
 */

#include <sbi/riscv_asm.h>
#include <sbi/riscv_encoding.h>
#include <sbi/sbi_bits.h>
#include <sbi/sbi_console.h>
#include <sbi/sbi_emulate_csr.h>
#include <sbi/sbi_error.h>
#include <sbi/sbi_timer.h>

int sbi_emulate_csr_read(int csr_num,
			 u32 hartid, ulong mstatus,
			 struct sbi_scratch *scratch,
			 ulong *csr_val)
{
	ulong cen = -1UL;

	if (EXTRACT_FIELD(mstatus, MSTATUS_MPP) == PRV_U)
		cen = csr_read(scounteren);

	switch (csr_num) {
	case CSR_CYCLE:
		if (!((cen >> (CSR_CYCLE - CSR_CYCLE)) & 1))
			return -1;
		*csr_val = csr_read(mcycle);
		break;
	case CSR_TIME:
		if (!((cen >> (CSR_TIME - CSR_CYCLE)) & 1))
			return -1;
		*csr_val = sbi_timer_value(scratch);
		break;
	case CSR_INSTRET:
		if (!((cen >> (CSR_INSTRET - CSR_CYCLE)) & 1))
			return -1;
		*csr_val = csr_read(minstret);
		break;
	case CSR_MHPMCOUNTER3:
		if (!((cen >> (3 + CSR_MHPMCOUNTER3 - CSR_MHPMCOUNTER3)) & 1))
			return -1;
		*csr_val = csr_read(mhpmcounter3);
		break;
	case CSR_MHPMCOUNTER4:
		if (!((cen >> (3 + CSR_MHPMCOUNTER4 - CSR_MHPMCOUNTER3)) & 1))
			return -1;
		*csr_val = csr_read(mhpmcounter4);
		break;
#if __riscv_xlen == 32
	case CSR_CYCLEH:
		if (!((cen >> (CSR_CYCLE - CSR_CYCLE)) & 1))
			return -1;
		*csr_val = csr_read(mcycleh);
		break;
	case CSR_TIMEH:
		if (!((cen >> (CSR_TIME - CSR_CYCLE)) & 1))
			return -1;
		*csr_val = sbi_timer_value(scratch);
		*csr_val = *csr_val >> 32;
		break;
	case CSR_INSTRETH:
		if (!((cen >> (CSR_INSTRET - CSR_CYCLE)) & 1))
			return -1;
		*csr_val = csr_read(minstreth);
		break;
	case CSR_MHPMCOUNTER3H:
		if (!((cen >> (3 + CSR_MHPMCOUNTER3 - CSR_MHPMCOUNTER3)) & 1))
			return -1;
		*csr_val = csr_read(mhpmcounter3h);
		break;
	case CSR_MHPMCOUNTER4H:
		if (!((cen >> (3 + CSR_MHPMCOUNTER4 - CSR_MHPMCOUNTER3)) & 1))
			return -1;
		*csr_val = csr_read(mhpmcounter4h);
		break;
#endif
	case CSR_MHPMEVENT3:
		*csr_val = csr_read(mhpmevent3);
		break;
	case CSR_MHPMEVENT4:
		*csr_val = csr_read(mhpmevent4);
		break;
	default:
		sbi_printf("%s: hartid%d: invalid csr_num=0x%x\n",
			   __func__, hartid, csr_num);
		return SBI_ENOTSUPP;
	};

	return 0;
}

int sbi_emulate_csr_write(int csr_num,
			  u32 hartid, ulong mstatus,
			  struct sbi_scratch *scratch,
			  ulong csr_val)
{
	switch (csr_num) {
	case CSR_CYCLE:
		csr_write(mcycle, csr_val);
		break;
	case CSR_INSTRET:
		csr_write(minstret, csr_val);
		break;
	case CSR_MHPMCOUNTER3:
		csr_write(mhpmcounter3, csr_val);
		break;
	case CSR_MHPMCOUNTER4:
		csr_write(mhpmcounter4, csr_val);
		break;
#if __riscv_xlen == 32
	case CSR_CYCLEH:
		csr_write(mcycleh, csr_val);
		break;
	case CSR_INSTRETH:
		csr_write(minstreth, csr_val);
		break;
	case CSR_MHPMCOUNTER3H:
		csr_write(mhpmcounter3h, csr_val);
		break;
	case CSR_MHPMCOUNTER4H:
		csr_write(mhpmcounter4h, csr_val);
		break;
#endif
	case CSR_MHPMEVENT3:
		csr_write(mhpmevent3, csr_val);
		break;
	case CSR_MHPMEVENT4:
		csr_write(mhpmevent4, csr_val);
		break;
	default:
		sbi_printf("%s: hartid%d: invalid csr_num=0x%x\n",
			   __func__, hartid, csr_num);
		return SBI_ENOTSUPP;
	};

	return 0;
}
