/*
 * Copyright (c) 2019, Arm Limited and Contributors. All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <stdint.h>
#include <stdbool.h>
#include <string.h>

#include <lib/debugfs.h>
#include <lib/smccc.h>
#include <lib/spinlock.h>
#include <lib/xlat_tables/xlat_tables_v2.h>
#include <smccc_helpers.h>

#define MAX_PATH_LEN	256

#define MOUNT		0
#define CREATE		1
#define OPEN		2
#define CLOSE		3
#define READ		4
#define WRITE		5
#define SEEK		6
#define BIND		7
#define STAT		8
#define INIT		10
#define VERSION		11

/* This is the virtual address to which we map the NS shared buffer */
#define DEBUGFS_SHARED_BUF_VIRT		((void *)0x81000000U)

static union debugfs_parms {
	struct {
		char fname[MAX_PATH_LEN];
	} open;

	struct {
		char srv[MAX_PATH_LEN];
		char where[MAX_PATH_LEN];
		char spec[MAX_PATH_LEN];
	} mount;

	struct {
		char path[MAX_PATH_LEN];
		dir_t dir;
	} stat;

	struct {
		char oldpath[MAX_PATH_LEN];
		char newpath[MAX_PATH_LEN];
	} bind;
} parms;

/* debugfs_access_lock protects shared buffer and internal */
/* FS functions from concurrent accesses.                 */
static spinlock_t debugfs_access_lock;

static bool debugfs_initialized;

uintptr_t debugfs_smc_handler(unsigned int smc_fid,
			      u_register_t cmd,
			      u_register_t arg2,
			      u_register_t arg3,
			      u_register_t arg4,
			      void *cookie,
			      void *handle,
			      u_register_t flags)
{
	int64_t smc_ret = DEBUGFS_E_INVALID_PARAMS, smc_resp = 0;
	int ret;

	/* Allow calls from non-secure only */
	if (is_caller_secure(flags)) {
		SMC_RET1(handle, DEBUGFS_E_DENIED);
	}

	/* Expect a SiP service fast call */
	if ((GET_SMC_TYPE(smc_fid) != SMC_TYPE_FAST) ||
		(GET_SMC_OEN(smc_fid) != OEN_SIP_START)) {
		SMC_RET1(handle, SMC_UNK);
	}

	/* Truncate parameters if 32b SMC convention call */
	if (GET_SMC_CC(smc_fid) == SMC_32) {
		arg2 &= 0xffffffff;
		arg3 &= 0xffffffff;
		arg4 &= 0xffffffff;
	}

	spin_lock(&debugfs_access_lock);

	if (debugfs_initialized == true) {
		/* Copy NS shared buffer to internal secure location */
		memcpy(&parms, (void *)DEBUGFS_SHARED_BUF_VIRT,
		       sizeof(union debugfs_parms));
	}

	switch (cmd) {
	case INIT:
		if (debugfs_initialized == false) {
			/* TODO: check PA validity e.g. whether */
			/* it is an NS region.                  */
			ret = mmap_add_dynamic_region(arg2,
				(uintptr_t)DEBUGFS_SHARED_BUF_VIRT,
				PAGE_SIZE_4KB,
				MT_MEMORY | MT_RW | MT_NS);
			if (ret == 0) {
				debugfs_initialized = true;
				smc_ret = SMC_OK;
				smc_resp = 0;
			}
		}
		break;

	case VERSION:
		smc_ret = SMC_OK;
		smc_resp = DEBUGFS_VERSION;
		break;

	case MOUNT:
		ret = mount(parms.mount.srv,
			    parms.mount.where,
			    parms.mount.spec);
		if (ret == 0) {
			smc_ret = SMC_OK;
			smc_resp = 0;
		}
		break;

	case OPEN:
		ret = open(parms.open.fname, arg2);
		if (ret >= 0) {
			smc_ret = SMC_OK;
			smc_resp = ret;
		}
		break;

	case CLOSE:
		ret = close(arg2);
		if (ret == 0) {
			smc_ret = SMC_OK;
			smc_resp = 0;
		}
		break;

	case READ:
		ret = read(arg2, DEBUGFS_SHARED_BUF_VIRT, arg3);
		if (ret >= 0) {
			smc_ret = SMC_OK;
			smc_resp = ret;
		}
		break;

	case SEEK:
		ret = seek(arg2, arg3, arg4);
		if (ret == 0) {
			smc_ret = SMC_OK;
			smc_resp = 0;
		}
		break;

	case BIND:
		ret = bind(parms.bind.oldpath, parms.bind.newpath);
		if (ret == 0) {
			smc_ret = SMC_OK;
			smc_resp = 0;
		}
		break;

	case STAT:
		ret = stat(parms.stat.path, &parms.stat.dir);
		if (ret == 0) {
			memcpy((void *)DEBUGFS_SHARED_BUF_VIRT, &parms,
			       sizeof(union debugfs_parms));
			smc_ret = SMC_OK;
			smc_resp = 0;
		}
		break;

	/* Not implemented */
	case CREATE:
		/* Intentional fall-through */

	/* Not implemented */
	case WRITE:
		/* Intentional fall-through */

	default:
		smc_ret = SMC_UNK;
		smc_resp = 0;
	}

	spin_unlock(&debugfs_access_lock);

	SMC_RET2(handle, smc_ret, smc_resp);

	/* Not reached */
	return smc_ret;
}

int debugfs_smc_setup(void)
{
	debugfs_initialized = false;
	debugfs_access_lock.lock = 0;

	return 0;
}
