// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Copyright (c) 2017, Amlogic, Inc.
 *
 * This software is licensed under the terms of the GNU General Public
 * License version 2, as published by the Free Software Foundation, and
 * may be copied, distributed, and modified under those terms.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 */
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/types.h>
#include <linux/workqueue.h>
#include <linux/io.h>

#include "optee_smc.h"
#include "log.h"
#include "optee_private.h"

#define LOGGER_LOOPBUFFER_MAGIC       0xAA00AA00
#define LOGGER_LOOPBUFFER_OFFSET      0x00000080
#define OPTEE_LOG_READ_MAX            PAGE_SIZE
#define OPTEE_LOG_LINE_MAX            1024
#define OPTEE_LOG_TIMER_INTERVAL      1

#undef pr_fmt
#define pr_fmt(fmt) "[TEE] " fmt

struct loopbuffer_ctl_s {
	unsigned int magic;
	unsigned int inited;
	unsigned int total_size;
	unsigned int fill_size;
	unsigned int mode;
	unsigned int reader;
	unsigned int writer;

	char *buffer;
};

static void *log_buf_va;
static u8 line_buff[OPTEE_LOG_LINE_MAX];

struct delayed_work log_work;
static struct workqueue_struct *log_workqueue;

static ssize_t log_buff_get_read_buff(char **buf, int len)
{
	int writer;
	int reader;
	int read_size = 0;
	struct loopbuffer_ctl_s *ctl = (struct loopbuffer_ctl_s *)log_buf_va;

	if (!ctl || len <= 0)
		return 0;

	writer = ctl->writer;
	reader = ctl->reader;

	if (reader == writer)
		read_size = 0;
	else if (reader < writer)
		read_size = writer - reader;
	else
		read_size = ctl->total_size - reader;

	if (read_size > len)
		read_size = len;

	*buf = (char *)log_buf_va + LOGGER_LOOPBUFFER_OFFSET + reader;
	ctl->reader += read_size;
	if (ctl->reader == ctl->total_size)
		ctl->reader = 0;

	return read_size;
}

static size_t log_print_text(char *buf, size_t size)
{
	char *line = line_buff;
	const char *text = buf;
	const char *next = NULL;
	s32 remaining = size;
	size_t line_size = 0;
	size_t scan_size = 0;

	if (!buf || !size)
		return 0;

	while (text && remaining > 0) {
		/* Reserve 2 bytes for EOL and EOS */
		scan_size = remaining > (OPTEE_LOG_LINE_MAX - 2) ?
			(OPTEE_LOG_LINE_MAX - 2) : remaining;
		next = memchr(text, '\n', scan_size);
		if (next) {
			/* EOL is found */
			next++;
			line_size = next - text;
			/* Add a extra EOS */
			line[line_size] = '\0';
		} else {
			/* No EOL found.*/
			line_size = scan_size;
			/* Truncate string to scan_size and add EOL and EOS. */
			line[line_size] = '\n';
			line[line_size + 1] = '\0';
		}
		memcpy(line, text, line_size);
		remaining -= line_size;
		text += line_size;
		pr_notice("%s", line);
	}

	/* All remaining should be consumed */
	if (!text || remaining) {
		pr_err("WARNING: text(%p) is NULL or remaining(%d) is not 0.\n",
				text, remaining);
	}

	return size;
}

static void do_log_timer(struct work_struct *work)
{
	size_t len;
	char *read_buff = NULL;

	len = log_buff_get_read_buff(&read_buff, OPTEE_LOG_READ_MAX);
	if (len > 0)
		log_print_text(read_buff, len);

	if (queue_delayed_work(log_workqueue, &log_work, OPTEE_LOG_TIMER_INTERVAL * HZ) == 0)
		pr_err("%s:%d Failed to join the workqueue\n", __func__, __LINE__);
}

int optee_log_init(void *va)
{
	int rc = 0;
	size_t size = 0;
	phys_addr_t begin = 0;
	phys_addr_t end = 0;
	struct arm_smccc_res smccc = { 0 };
	struct loopbuffer_ctl_s *log_ctl = NULL;

	arm_smccc_smc(OPTEE_SMC_ENABLE_LOGGER, 1, 0, 0, 0, 0, 0, 0,
			&smccc);

	if (smccc.a0 != TEEC_SUCCESS) {
		pr_err("smc enable logger failed, res = 0x%lx\n", smccc.a0);
		rc = -EACCES;
		goto err;
	}

	if (smccc.a1 == LOGGER_SHM_ADDR_MAGIC) {
		/*
		 * for new logger solution
		 * a1: logger get flags
		 * a2: logger start address
		 * a3: logger size
		 */
		begin = roundup(smccc.a2, PAGE_SIZE);
		end = rounddown(smccc.a2 + smccc.a3, PAGE_SIZE);
		size = end - begin;
		log_buf_va = memremap(begin, size, MEMREMAP_WB);
	} else {
		/* for previous logger solution */
		log_buf_va = va;
	}

	if (!log_buf_va) {
		pr_err("shared memory logger ioremap failed\n");
		return -ENOMEM;
	}

	log_ctl = (struct loopbuffer_ctl_s *)log_buf_va;
	if (log_ctl->magic != LOGGER_LOOPBUFFER_MAGIC || log_ctl->inited != 1) {
		pr_err("tee log buffer init failed\n");
		rc = -EINVAL;
		goto err;
	}

	/* init workqueue */
	log_workqueue = create_singlethread_workqueue("tee-log-wq");
	INIT_DELAYED_WORK(&log_work, do_log_timer);
	if (queue_delayed_work(log_workqueue, &log_work, OPTEE_LOG_TIMER_INTERVAL * HZ) == 0) {
		pr_err("%s:%d failed to join the workqueue.\n", __func__, __LINE__);
		rc = -EBUSY;
		goto err;
	}

	return rc;

err:
	arm_smccc_smc(OPTEE_SMC_ENABLE_LOGGER, 0, 0, 0, 0, 0, 0, 0, &smccc);

	return rc;
}

void optee_log_uninit(void)
{
	struct arm_smccc_res smccc;

	if (log_workqueue) {
		cancel_delayed_work_sync(&log_work);
		destroy_workqueue(log_workqueue);
	}

	arm_smccc_smc(OPTEE_SMC_ENABLE_LOGGER, 0, 0, 0, 0, 0, 0, 0, &smccc);
}
