/*
 * Copyright (c) 2020 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */
#include <zephyr.h>
#include <adsp/cache.h>
#include <soc/shim.h>

/* Simple output driver for the trace window of an ADSP device used
 * for communication with the host processor as a shared memory
 * region.  The protocol uses an array of 64-byte "slots", each of
 * which is prefixed by a 16 bit magic number followed by a sequential
 * ID number.  The remaining bytes are a (potentially nul-terminated)
 * string containing output data.
 *
 * IMPORTANT NOTE on cache coherence: the shared memory window is in
 * HP-SRAM.  Each DSP core has an L1 cache that is incoherent (!) from
 * the perspective of the other cores.  To handle this, we take care
 * to access all memory through the uncached window into HP-SRAM at
 * 0x9xxxxxxx and not the L1-cached mapping of the same memory at
 * 0xBxxxxxxx.
 */

#define SLOT_SIZE 64
#define SLOT_MAGIC 0x55aa

#define NSLOTS (SRAM_TRACE_SIZE / SLOT_SIZE)
#define MSGSZ (SLOT_SIZE - sizeof(struct slot_hdr))

struct slot_hdr {
	uint16_t magic;
	uint16_t id;
};

struct slot {
	struct slot_hdr hdr;
	char msg[MSGSZ];
};

struct metadata {
	struct k_spinlock lock;
	bool initialized;
	uint32_t curr_slot;   /* To which slot are we writing? */
	uint32_t n_bytes;     /* How many bytes buffered in curr_slot */
};

/* Give it a cache line all its own! */
static __aligned(64) union {
	struct metadata meta;
	uint32_t cache_pad[16];
} data_rec;

#define data ((volatile struct metadata *)z_soc_uncached_ptr(&data_rec.meta))

static inline struct slot *slot(int i)
{
	struct slot *slots = z_soc_uncached_ptr((void *)SRAM_TRACE_BASE);

	return &slots[i];
}

static int slot_incr(int s)
{
	return (s + 1) % NSLOTS;
}

void intel_adsp_trace_out(int8_t *str, size_t len)
{
	if (len == 0) {
		return;
	}

	k_spinlock_key_t key = k_spin_lock((void *)&data->lock);

	if (!data->initialized) {
		slot(0)->hdr.magic = 0;
		slot(0)->hdr.id = 0;
		data->curr_slot = data->n_bytes = 0;
		data->initialized = 1;
	}

	/* We work with a local copy of the global data for
	 * performance reasons (The memory behind the "data" pointer
	 * is uncached and volatile!) and put it back at the end.
	 */
	uint32_t curr_slot = data->curr_slot;
	uint32_t n_bytes = data->n_bytes;

	for (size_t i = 0; i < len; i++) {
		int8_t c = str[i];
		struct slot *s = slot(curr_slot);

		s->msg[n_bytes++] = c;

		/* Are we done with this slot?  Terminate it and flag
		 * it for consumption on the other side
		 */
		if (c == '\n' || n_bytes >= MSGSZ) {
			if (n_bytes < MSGSZ) {
				s->msg[n_bytes] = 0;
			}

			/* Make sure the next slot has a magic number
			 * (so the reader can distinguish between
			 * no-new-data and system-reset), but does NOT
			 * have the correct successor ID (so can never
			 * be picked up as valid data).  We'll
			 * increment it later when we terminate that
			 * slot.
			 */
			int next_slot = slot_incr(curr_slot);
			uint16_t new_id = s->hdr.id + 1;

			slot(next_slot)->hdr.id = new_id;
			slot(next_slot)->hdr.magic = SLOT_MAGIC;
			slot(next_slot)->msg[0] = 0;

			s->hdr.id = new_id;
			s->hdr.magic = SLOT_MAGIC;

			curr_slot = next_slot;
			n_bytes = 0;
		}
	}

	data->curr_slot = curr_slot;
	data->n_bytes = n_bytes;
	k_spin_unlock((void *)&data->lock, key);
}

int arch_printk_char_out(int c)
{
	int8_t s = c;

	intel_adsp_trace_out(&s, 1);
	return 0;
}
