/*
 * Copyright (c) 2019,2022 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/logging/log_backend_adsp_mtrace.h>
#include <zephyr/logging/log_backend.h>
#include <zephyr/logging/log_core.h>
#include <zephyr/logging/log_output.h>
#include <zephyr/logging/log_backend_std.h>
#include <zephyr/kernel.h>
#include <soc.h>

#include <adsp_memory.h>
#include <adsp_debug_window.h>

/*
 * A lock is needed as log_process() and log_panic() have no internal locks
 * to prevent concurrency. Meaning if log_process is called after
 * log_panic was called previously, log_process may happen from another
 * CPU and calling context than the log processing thread running in
 * the background. On an SMP system this is a race.
 *
 * This caused a race on the output trace such that the logging output
 * was garbled and useless.
 */
static struct k_spinlock mtrace_lock;

static uint32_t log_format_current = CONFIG_LOG_BACKEND_ADSP_MTRACE_OUTPUT_DEFAULT;

static adsp_mtrace_log_hook_t mtrace_hook;

static bool mtrace_active;

static bool mtrace_panic_mode;

/*
 * SRAM window for debug info is organized to equal size slots.
 * The descriptors on first page describe the layout of slots.
 * One type of debug info slot is ADSP_DBG_WIN_SLOT_DEBUG_LOG.
 * These slots (if defined) can be used for mtrace output.
 *
 * The log buffer slots have the following layout:
 *
 * u32 host_read_ptr;
 * u32 dsp_write_ptr;
 * u8 buffer[];
 *
 * The two pointers are offsets within the buffer. Buffer is empty
 * when the two pointers are equal, and full when host read pointer
 * is one ahead of the DSP writer pointer.
 */

#define MTRACE_LOG_BUF_SIZE		(ADSP_DW_SLOT_SIZE - 2 * sizeof(uint32_t))

#define MTRACE_LOGGING_SLOT_TYPE(n)	(ADSP_DW_SLOT_DEBUG_LOG | ((n) & ADSP_DW_SLOT_CORE_MASK))

#define MTRACE_CORE		0

struct adsp_debug_slot {
	uint32_t host_ptr;
	uint32_t dsp_ptr;
	uint8_t data[ADSP_DW_SLOT_SIZE - sizeof(uint32_t) * 2];
} __packed;

static void mtrace_init(void)
{
	if (ADSP_DW->descs[0].type == MTRACE_LOGGING_SLOT_TYPE(MTRACE_CORE)) {
		return;
	}

	ADSP_DW->descs[0].type = MTRACE_LOGGING_SLOT_TYPE(MTRACE_CORE);
}

static size_t mtrace_out(int8_t *str, size_t len, size_t *space_left)
{
	struct adsp_debug_slot *slot = (struct adsp_debug_slot *)(ADSP_DW->slots[0]);
	uint8_t *data = slot->data;
	uint32_t r = slot->host_ptr;
	uint32_t w = slot->dsp_ptr;
	size_t avail, out;

	if (w > r) {
		avail = MTRACE_LOG_BUF_SIZE - w + r - 1;
	} else if (w == r) {
		avail = MTRACE_LOG_BUF_SIZE - 1;
	} else {
		avail = r - w - 1;
	}

	if (len == 0) {
		out = 0;
		goto out;
	}

	/* data that does not fit is dropped */
	out = MIN(avail, len);

	if (w + out >= MTRACE_LOG_BUF_SIZE) {
		size_t tail = MTRACE_LOG_BUF_SIZE - w;
		size_t head = out - tail;

		memcpy(data + w, str, tail);
		memcpy(data, str + tail, head);
		w = head;
	} else {
		memcpy(data + w, str, out);
		w += out;
	}

	slot->dsp_ptr = w;

out:
	if (space_left) {
		*space_left = avail > len ? avail - len : 0;
	}

	return out;
}

static int char_out(uint8_t *data, size_t length, void *ctx)
{
	size_t space_left = 0;
	size_t out;

	/*
	 * we handle the data even if mtrace notifier is not
	 * active. this ensures we can capture early boot messages.
	 */
	out = mtrace_out(data, length, &space_left);

	if (mtrace_active && mtrace_hook) {

		/* if we are in panic mode, need to flush out asap */
		if (unlikely(mtrace_panic_mode))
			space_left = 0;

		mtrace_hook(out, space_left);
	}

	return length;
}

/**
 * 80 bytes seems to catch most sensibly sized log message lines
 * in one go letting the trace out call output whole complete
 * lines. This avoids the overhead of a spin lock in the trace_out
 * more often as well as avoiding entwined characters from printk if
 * LOG_PRINTK=n.
 */
#define LOG_BUF_SIZE 80
static uint8_t log_buf[LOG_BUF_SIZE];

LOG_OUTPUT_DEFINE(log_output_adsp_mtrace, char_out, log_buf, sizeof(log_buf));

static uint32_t format_flags(void)
{
	uint32_t flags = LOG_OUTPUT_FLAG_LEVEL | LOG_OUTPUT_FLAG_TIMESTAMP;

	if (IS_ENABLED(CONFIG_LOG_BACKEND_FORMAT_TIMESTAMP)) {
		flags |= LOG_OUTPUT_FLAG_FORMAT_TIMESTAMP;
	}

	return flags;
}

static void panic(struct log_backend const *const backend)
{
	mtrace_panic_mode = true;
}

static void dropped(const struct log_backend *const backend,
		    uint32_t cnt)
{
	log_output_dropped_process(&log_output_adsp_mtrace, cnt);
}

static void process(const struct log_backend *const backend,
		    union log_msg_generic *msg)
{
	log_format_func_t log_output_func = log_format_func_t_get(log_format_current);

	k_spinlock_key_t key = k_spin_lock(&mtrace_lock);

	log_output_func(&log_output_adsp_mtrace, &msg->log, format_flags());

	k_spin_unlock(&mtrace_lock, key);
}

static int format_set(const struct log_backend *const backend, uint32_t log_type)
{
	log_format_current = log_type;
	return 0;
}

/**
 * Lazily initialized, while the DMA may not be setup we continue
 * to buffer log messages untilt he buffer is full.
 */
static void init(const struct log_backend *const backend)
{
	ARG_UNUSED(backend);

	mtrace_init();
}

const struct log_backend_api log_backend_adsp_mtrace_api = {
	.process = process,
	.dropped = IS_ENABLED(CONFIG_LOG_MODE_IMMEDIATE) ? NULL : dropped,
	.panic = panic,
	.format_set = format_set,
	.init = init,
};

LOG_BACKEND_DEFINE(log_backend_adsp_mtrace, log_backend_adsp_mtrace_api, true);

void adsp_mtrace_log_init(adsp_mtrace_log_hook_t hook)
{
	mtrace_init();

	mtrace_hook = hook;
	mtrace_active = true;
}

const struct log_backend *log_backend_adsp_mtrace_get(void)
{
	return &log_backend_adsp_mtrace;
}
