/*
 * Copyright (c) 2017, Intel Corporation
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 * 3. Neither the name of the Intel Corporation nor the names of its
 *    contributors may be used to endorse or promote products derived from this
 *    software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE INTEL CORPORATION OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

/*
 * SoC Watch - QMSI power profiler
 */

#if (SOC_WATCH_ENABLE)

/*
 * Header files common to LMT and ARC Sensor.
 */
#include "soc_watch.h"
#include "qm_common.h"
#include "qm_soc_regs.h"

/*
 * Header files and macro defines specific to LMT and ARC Sensor.
 */
#if (!QM_SENSOR)
#include <x86intrin.h>
/* 64bit Timestamp counter. */
#define get_ticks() _rdtsc()
#else
#include "qm_sensor_regs.h"
/* Timestamp counter for sensor subsystem is 32bit. */
#define get_ticks() __builtin_arc_lr(QM_SS_TSC_BASE + QM_SS_TIMER_COUNT)
#endif
/*
 * Define a macro for exposing some functions and other definitions
 * only when unit testing.  If we're not unit testing, then declare
 * them as static, so that their declarations are hidden to normal
 * code.
 */
#if (UNIT_TEST)
#define NONUTSTATIC
#else
#define NONUTSTATIC static
#endif

/**
 * "Event strings" table, describing message structures.
 * The first character is the event code to write to the data file.
 * The 2nd and subsequent characters describe how to format the record's
 * data.  Note that the ordering here needs to agree with the
 * enumeration list in qmsw_stub.h.
 *
 * Table characters:
 * + First char = event code to write into the result file.
 * + T = TSC Timestamp  (Hi-res timestamp)
 * + t = RTC Timestamp  (lo-res timestamp)
 * + 1 = interpret ev_data as a 1-byte value
 * + 4 = interpret ev_data as a 4-byte value
 * + R = Using ev_data as a register enumeration, read that register,
 * +	   and put that 4-byte value into the data file.
 * + L = Trigger an RTC timestamp Later
 */
NONUTSTATIC const char *ev_strs[] = {
    "HT",   /* Halt event */
    "IT1",  /* Interrupt event */
    "STtL", /* Sleep event */
    "RT1R", /* Register read event: Timestamp, reg enum, reg value*/
    "UTs4", /* User event: timestamp, subtype, data value. */
    "FTf",  /* Frequency change event */
};

/*
 * This list of registers corresponds to the SoC Watch register ID
 * enumeration in soc_watch.h, and MUST STAY IN AGREEMENT with that
 * list, since that enumeration is used to index this list.
 *
 * To record a register value, the SoC Watch code indexes into this
 * array, and reads the corresponding address found in that slot.
 */
#if (QUARK_D2000)
static const uint32_t *platform_regs[] = {
    (uint32_t *)(&QM_SCSS_CCU->osc0_cfg1),
    (uint32_t *)(&QM_SCSS_CCU->ccu_lp_clk_ctl),
    (uint32_t *)(&QM_SCSS_CCU->ccu_sys_clk_ctl),
    /* Clock Gating Registers */
    (uint32_t *)(&QM_SCSS_CCU->ccu_periph_clk_gate_ctl),
    (uint32_t *)(&QM_SCSS_CCU->ccu_ext_clock_ctl),
    /* Power Consumption regs */
    (uint32_t *)(&QM_SCSS_CMP->cmp_pwr),
    (uint32_t *)(&QM_SCSS_PMUX->pmux_pullup),
    (uint32_t *)(&QM_SCSS_PMUX->pmux_slew),
    (uint32_t *)(&QM_SCSS_PMUX->pmux_in_en)};
#elif(QUARK_SE)
static const uint32_t *platform_regs[] = {
    (uint32_t *)(&QM_SCSS_CCU->osc0_cfg1),
    (uint32_t *)(&QM_SCSS_CCU->ccu_lp_clk_ctl),
    (uint32_t *)(&QM_SCSS_CCU->ccu_sys_clk_ctl),
    /* Clock Gating Registers */
    (uint32_t *)(&QM_SCSS_CCU->ccu_periph_clk_gate_ctl),
    (uint32_t *)(&QM_SCSS_CCU->ccu_ss_periph_clk_gate_ctl),
    (uint32_t *)(&QM_SCSS_CCU->ccu_ext_clock_ctl),
    /* Power Consumption regs */
    (uint32_t *)(&QM_SCSS_CMP->cmp_pwr), (uint32_t *)(&QM_SCSS_PMU->slp_cfg),
    (uint32_t *)(&QM_SCSS_PMUX->pmux_pullup),
    (uint32_t *)(&QM_SCSS_PMUX->pmux_pullup[1]),
    (uint32_t *)(&QM_SCSS_PMUX->pmux_pullup[2]),
    (uint32_t *)(&QM_SCSS_PMUX->pmux_pullup[3]),
    (uint32_t *)(&QM_SCSS_PMUX->pmux_slew),
    (uint32_t *)(&QM_SCSS_PMUX->pmux_slew[1]),
    (uint32_t *)(&QM_SCSS_PMUX->pmux_slew[2]),
    (uint32_t *)(&QM_SCSS_PMUX->pmux_slew[3]),
    (uint32_t *)(&QM_SCSS_PMUX->pmux_in_en),
    (uint32_t *)(&QM_SCSS_PMUX->pmux_in_en[1]),
    (uint32_t *)(&QM_SCSS_PMUX->pmux_in_en[2]),
    (uint32_t *)(&QM_SCSS_PMUX->pmux_in_en[3])};
#endif /* QUARK_SE */

/* Define VERBOSE to turn on printf-based logging */
#ifdef VERBOSE
#define SOC_WATCH_TRACE QM_PRINTF
#else
#define SOC_WATCH_TRACE(...)
#endif

/*
 * mlog routines -- low-level memory debug logging.
 * Only enable if there's a need to debug this module.
 */
#ifdef MLOG_ENABLE
#define MLOG(e) mlog(e)
#define MLOG_BYTE(b) mlog_byte(b)
#define MLOG_SIZE 512 /* Must be a power of 2 */
static uint8_t mlog_events[MLOG_SIZE];
static uint16_t mlog_idx = 0;
void mlog(uint8_t event)
{
	mlog_events[++mlog_idx % (MLOG_SIZE)] = event;
}
void mlog_byte(uint8_t byte)
{
	const char c[] = {"0123456789ABCDEF"};
	MLOG(c[byte >> 4]);
	MLOG(c[byte & 4]);
}
#else /* !MLOG_ENABLE */
#define MLOG(event)
#define MLOG_BYTE(b)
#endif /* !MLOG_ENABLE */

/*
 * Defines for frequency related platform registers.
 */
#define SW_OSC0_CFG1 (0)
#define SW_SYS_CLK_CTL (2)

/*
 * CONFIGURABLE: Set this to control the number of bytes of RAM you
 *     want to dedicate to event buffering.  The larger the buffer,
 *     the fewer (expensive) flushes we will have to do.  The smaller,
 *     the lower the memory cost, but the more flushes you will do.
 */
#define SOC_WATCH_EVENT_BUFFER_SIZE (256) /* Measured in bytes */

/**
 * Power profiling event data buffer.  Symbol must be globally
 * visible, so that it can be seen by external tools.
 */
struct sw_profiling_event_buffer {
	uint8_t eb_idx;  /* Index of next byte to be written */
	uint8_t eb_size; /* Buffer size == SOC_WATCH_EVENT_BUFFER_SIZE */
	uint8_t event_data[SOC_WATCH_EVENT_BUFFER_SIZE - 2]; /* Event data -
							   sizeof(idx + size) */
} soc_watch_event_buffer = {0, SOC_WATCH_EVENT_BUFFER_SIZE - 1, {0}};

/* High water mark, i.e. "start trying to flush" point. */
#define SW_EB_HIGH_WATER (((SOC_WATCH_EVENT_BUFFER_SIZE - 2) * 7) >> 3)

NONUTSTATIC int soc_watch_buffer_full(void)
{
	return (soc_watch_event_buffer.eb_idx >= SW_EB_HIGH_WATER);
}

/**
 * Flag used by the JTAG data extraction routine. During setup, a HW
 * watchpoint is placed on this address.  During the flush routine,
 * software writes to it, causing the HW watchpoint to fire, and
 * OpenOCD to extract the data.  This symbol MUST be globally visible
 * in order for JTAG data transfer to work.
 */
volatile uint8_t soc_watch_flush_flag = 0;

/*
 * soc_watch_event_buffer_flush -- Trigger the data buffer flush.
 */
static void soc_watch_event_buffer_flush(void)
{
/* Figure out if we can successfully flush the data out.
 * If we're sleeping, the JTAG query will fail.
 */
#if (QUARK_D2000)
	/**
	 * If the "we're going to sleep" bit is set, parts of the
	 * SOC are already asleep, and transferring data over
	 * the JTAG port is not always reliable. So defer transferring
	 * the data until later.
	 * @TODO: Determine if there is also a sensitivity to the
	 * clock rate.
	 */
	MLOG('F');
	if (QM_SCSS_PMU->aon_vr & QM_AON_VR_VREG_SEL) {
		MLOG('-');
		return; /* We would only send junk, so don't flush.	 */
	}
#endif

	soc_watch_flush_flag = 1; /* Trigger the data extract brkpt */
	soc_watch_event_buffer.eb_idx = 0;
	MLOG('+');
}

/* Store a byte in the event buffer. */
static void eb_write_char(uint8_t data)
{
	SOC_WATCH_TRACE("c%d:0x%x [0]=%x\n", soc_watch_event_buffer.eb_idx,
			data, soc_watch_event_buffer.event_data[0]);
	soc_watch_event_buffer.event_data[soc_watch_event_buffer.eb_idx++] =
	    data;
}

/* Store a word in the event buffer. */
static void eb_write_uint32(uint32_t *data)
{
	uint32_t dst_data = *data;
	uint8_t byte_count = 0;
	SOC_WATCH_TRACE("I%d:0x%x\n", soc_watch_event_buffer.eb_idx, *data);
	while (byte_count < sizeof(uint32_t)) {
		soc_watch_event_buffer
		    .event_data[soc_watch_event_buffer.eb_idx++] =
		    ((dst_data & 0xFF));
		dst_data = dst_data >> 8;
		byte_count++;
	}
}

/*
 * soc_watch is duplicating the implementation of qm_irq_lock/unlock APIs
 * for both sensor and x86. This is required to remove the dependency on
 * qm_interrupt.h
 * Reason: soc_watch driver is common to both zephyr and QMSI based applications
 * and zephyr
 * has it's own interrupt handling implementation.
 * Both the functions are added as static inline and hence no side-effects.
 */

#if (QM_SENSOR)
static inline unsigned int soc_watch_irq_lock(void)
{
	unsigned int key = 0;

	/*
	 * Store the ARC STATUS32 register fields relating to interrupts into
	 * the variable `key' and disable interrupt delivery to the core.
	 */
	__asm__ __volatile__("clri %0" : "=r"(key));

	return key;
}

static inline void soc_watch_irq_unlock(unsigned int key)
{
	/*
	 * Restore the ARC STATUS32 register fields relating to interrupts based
	 * on the variable `key' populated by qm_irq_lock().
	 */
	__asm__ __volatile__("seti %0" : : "ir"(key));
}

#else /* x86 */
/* x86 CPU FLAGS.IF register field (Interrupt enable Flag, bit 9), indicating
 * whether or not CPU interrupts are enabled.
 */
#define X86_FLAGS_IF BIT(9)

/**
 * Save interrupt state and disable all interrupts on the CPU.
 * Defined locally for modularity when used in other contexts (i.e. RTOS)
 *
 * @return An architecture-dependent lock-out key representing the "interrupt
 * 	   disable state" prior to the call.
 */
static inline unsigned int soc_watch_irq_lock(void)
{
	unsigned int key = 0;

	/*
	 * Store the CPU FLAGS register into the variable `key' and disable
	 * interrupt delivery to the core.
	 */
	__asm__ __volatile__("pushfl;\n\t"
			     "cli;\n\t"
			     "popl %0;\n\t"
			     : "=g"(key)
			     :
			     : "memory");

	return key;
}

/**
 *
 * Restore previous interrupt state on the CPU saved via soc_watch_irq_lock().
 * Defined locally for modularity when used in other contexts (i.e. RTOS)
 *
 * @param[in] key architecture-dependent lock-out key returned by a previous
 * 		  invocation of soc_watch_irq_lock().
 */
static inline void soc_watch_irq_unlock(unsigned int key)
{
	/*
	 * `key' holds the CPU FLAGS register content at the time when
	 * soc_watch_irq_lock() was called.
	 */
	if (!(key & X86_FLAGS_IF)) {
		/*
		 * Interrupts were disabled when soc_watch_irq_lock() was
		 * invoked:
		 * do not re-enable interrupts.
		 */
		return;
	}

	/* Enable interrupts */
	__asm__ __volatile__("sti;\n\t" : :);
}
#endif

/* Log an event with one parameter. */
void soc_watch_log_event(soc_watch_event_t event_id, uintptr_t ev_data)
{
	soc_watch_log_app_event(event_id, 0, ev_data);
}

/*
 * Log an event with two parameters, where the subtype comes from
 * the user.  Note that what actually makes this an 'application event' is
 * the event_id, not the fact that it is coming in via this interface.
 */
void soc_watch_log_app_event(soc_watch_event_t event_id, uint8_t ev_subtype,
			     uintptr_t ev_data)
{
	static uint8_t record_rtc = 0;
	const uint32_t *rtc_ctr = (uint32_t *)&QM_RTC[QM_RTC_0]->rtc_ccvr;
	const char *cp;
	unsigned int irq_flag = 0;
#if (!QM_SENSOR)
	uint64_t tsc = 0; /* hi-res timestamp */
#else
	uint32_t tsc = 0;
#endif
	uint32_t rtc_val = *rtc_ctr;

#define AVG_EVENT_SIZE 8 /* Size of a typical message in bytes. */

	MLOG('[');
	irq_flag = soc_watch_irq_lock();
	/* TODO: We know exactly how many bytes of storage we need,
	 * since we know the event code.  So don't do an "AVG" size thing
	 * here--use the exact size!
	 */
	if ((soc_watch_event_buffer.eb_idx + AVG_EVENT_SIZE) <=
	    soc_watch_event_buffer.eb_size) {

/* Map a halt event to a sleep event where appropriate. */
#if (QUARK_D2000)
		if (event_id == SOCW_EVENT_HALT) {
			if (QM_SCSS_PMU->aon_vr & QM_AON_VR_VREG_SEL) {
				event_id = SOCW_EVENT_SLEEP;
			}
		}
#endif

		/* Record the RTC of the waking event, if it's rousing us from
		 * sleep. */
		if (record_rtc) {
			eb_write_char('t');
			eb_write_uint32((uint32_t *)(&rtc_val)); /* Timestamp */
			record_rtc = 0;
		}

		if (event_id >= SOCW_EVENT_MAX) {
			SOC_WATCH_TRACE("Unknown event id: 0x%x\n", event_id);
			MLOG('?');
			soc_watch_irq_unlock(irq_flag);
			return;
		}
		cp = ev_strs[event_id]; /* Look up event string */
		SOC_WATCH_TRACE("%c", *cp);
		MLOG(*cp);
		eb_write_char(*cp); /* Write event code */
		while (*++cp) {
			switch (*cp) {
			case 'T':
				tsc = get_ticks();
				eb_write_uint32((uint32_t *)(&tsc)); /* Hi-res
						Timestamp */
				break;
			case 't':
				eb_write_uint32(
				    (uint32_t *)(&rtc_val)); /* Lo-res
					    Timestamp */
				break;
			case 'L':
				record_rtc = 1;
				break;
			case 'R': /* Register data value */
				eb_write_uint32(
				    (uint32_t *)platform_regs[ev_data]);
				break;
			case '4': /* 32-bit data value */
				eb_write_uint32((uint32_t *)&ev_data);
				break;
			case '1':
				/* Register ID */
				eb_write_char(((uint32_t)ev_data) & 0xff);
				break;
			case 's':
				/* Event subtype */
				eb_write_char(((uint32_t)ev_subtype) & 0xff);
				break;
			case 'f':
				eb_write_uint32(
				    (uint32_t *)platform_regs[SW_OSC0_CFG1]);
				eb_write_uint32(
				    (uint32_t *)platform_regs[SW_SYS_CLK_CTL]);
				break;
			default:
				SOC_WATCH_TRACE(
				    "Unknown string char: 0x%x on string "
				    "0x%x\n",
				    *cp, event_id);
				break;
			}
		}
	}

	/*
	 * If this is an interrupt which roused the CPU out of a sleep state,
	 * don't flush the buffer.  (Due to a bug in OpenOCD, doing so will
	 * clear the HW watchpoint, ensuring no further flushes are seen by
	 * OpenOCD.)
	 */
	if ((soc_watch_buffer_full()) && (event_id != SOCW_EVENT_INTERRUPT)) {
		SOC_WATCH_TRACE("\n --- FLUSH: idx= %d ---\n",
				soc_watch_event_buffer.eb_idx);
		soc_watch_event_buffer_flush();
	}
	MLOG(':');
	MLOG_BYTE(soc_watch_event_buffer.eb_idx);
	soc_watch_irq_unlock(irq_flag);
	MLOG(']');
}

/*
 * Trigger the Watchpoint to flush the data.
 * Application can use this API to trigger the transfer of
 * profiler information to the host whenever it requires.
 * The static function soc_watch_event_buffer_flush() is also used internally
 * when the soc_watch_buffer_full flag is set and is  not exposed to the
 * application.
 */
void soc_watch_trigger_flush()
{
	soc_watch_event_buffer_flush();
}
#endif /* !(defined(SOC_WATCH) && (!QM_SENSOR)) */
