// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright 2014, Michael Ellerman, IBM Corp.
 */

#define _GNU_SOURCE	/* For CPU_ZERO etc. */

#include <sched.h>
#include <sys/wait.h>
#include <setjmp.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>

#include "trace.h"
#include "ebb.h"


void (*ebb_user_func)(void);

void ebb_hook(void)
{
	if (ebb_user_func)
		ebb_user_func();
}

struct ebb_state ebb_state;

u64 sample_period = 0x40000000ull;

void reset_ebb_with_clear_mask(unsigned long mmcr0_clear_mask)
{
	u64 val;

	/* 2) clear MMCR0[PMAO] - docs say BESCR[PMEO] should do this */
	/* 3) set MMCR0[PMAE]	- docs say BESCR[PME] should do this */
	val = mfspr(SPRN_MMCR0);
	mtspr(SPRN_MMCR0, (val & ~mmcr0_clear_mask) | MMCR0_PMAE);

	/* 4) clear BESCR[PMEO] */
	mtspr(SPRN_BESCRR, BESCR_PMEO);

	/* 5) set BESCR[PME] */
	mtspr(SPRN_BESCRS, BESCR_PME);

	/* 6) rfebb 1 - done in our caller */
}

void reset_ebb(void)
{
	reset_ebb_with_clear_mask(MMCR0_PMAO | MMCR0_FC);
}

/* Called outside of the EBB handler to check MMCR0 is sane */
int ebb_check_mmcr0(void)
{
	u64 val;

	val = mfspr(SPRN_MMCR0);
	if ((val & (MMCR0_FC | MMCR0_PMAO)) == MMCR0_FC) {
		/* It's OK if we see FC & PMAO, but not FC by itself */
		printf("Outside of loop, only FC set 0x%llx\n", val);
		return 1;
	}

	return 0;
}

bool ebb_check_count(int pmc, u64 sample_period, int fudge)
{
	u64 count, upper, lower;

	count = ebb_state.stats.pmc_count[PMC_INDEX(pmc)];

	lower = ebb_state.stats.ebb_count * (sample_period - fudge);

	if (count < lower) {
		printf("PMC%d count (0x%llx) below lower limit 0x%llx (-0x%llx)\n",
			pmc, count, lower, lower - count);
		return false;
	}

	upper = ebb_state.stats.ebb_count * (sample_period + fudge);

	if (count > upper) {
		printf("PMC%d count (0x%llx) above upper limit 0x%llx (+0x%llx)\n",
			pmc, count, upper, count - upper);
		return false;
	}

	printf("PMC%d count (0x%llx) is between 0x%llx and 0x%llx delta +0x%llx/-0x%llx\n",
		pmc, count, lower, upper, count - lower, upper - count);

	return true;
}

void standard_ebb_callee(void)
{
	int found, i;
	u64 val;

	val = mfspr(SPRN_BESCR);
	if (!(val & BESCR_PMEO)) {
		ebb_state.stats.spurious++;
		goto out;
	}

	ebb_state.stats.ebb_count++;
	trace_log_counter(ebb_state.trace, ebb_state.stats.ebb_count);

	val = mfspr(SPRN_MMCR0);
	trace_log_reg(ebb_state.trace, SPRN_MMCR0, val);

	found = 0;
	for (i = 1; i <= 6; i++) {
		if (ebb_state.pmc_enable[PMC_INDEX(i)])
			found += count_pmc(i, sample_period);
	}

	if (!found)
		ebb_state.stats.no_overflow++;

out:
	reset_ebb();
}

extern void ebb_handler(void);

void setup_ebb_handler(void (*callee)(void))
{
	u64 entry;

#if defined(_CALL_ELF) && _CALL_ELF == 2
	entry = (u64)ebb_handler;
#else
	struct opd
	{
	    u64 entry;
	    u64 toc;
	} *opd;

	opd = (struct opd *)ebb_handler;
	entry = opd->entry;
#endif
	printf("EBB Handler is at %#llx\n", entry);

	ebb_user_func = callee;

	/* Ensure ebb_user_func is set before we set the handler */
	mb();
	mtspr(SPRN_EBBHR, entry);

	/* Make sure the handler is set before we return */
	mb();
}

void clear_ebb_stats(void)
{
	memset(&ebb_state.stats, 0, sizeof(ebb_state.stats));
}

void dump_summary_ebb_state(void)
{
	printf("ebb_state:\n"			\
	       "  ebb_count    = %d\n"		\
	       "  spurious     = %d\n"		\
	       "  negative     = %d\n"		\
	       "  no_overflow  = %d\n"		\
	       "  pmc[1] count = 0x%llx\n"	\
	       "  pmc[2] count = 0x%llx\n"	\
	       "  pmc[3] count = 0x%llx\n"	\
	       "  pmc[4] count = 0x%llx\n"	\
	       "  pmc[5] count = 0x%llx\n"	\
	       "  pmc[6] count = 0x%llx\n",
		ebb_state.stats.ebb_count, ebb_state.stats.spurious,
		ebb_state.stats.negative, ebb_state.stats.no_overflow,
		ebb_state.stats.pmc_count[0], ebb_state.stats.pmc_count[1],
		ebb_state.stats.pmc_count[2], ebb_state.stats.pmc_count[3],
		ebb_state.stats.pmc_count[4], ebb_state.stats.pmc_count[5]);
}

static char *decode_mmcr0(u32 value)
{
	static char buf[16];

	buf[0] = '\0';

	if (value & (1 << 31))
		strcat(buf, "FC ");
	if (value & (1 << 26))
		strcat(buf, "PMAE ");
	if (value & (1 << 7))
		strcat(buf, "PMAO ");

	return buf;
}

static char *decode_bescr(u64 value)
{
	static char buf[16];

	buf[0] = '\0';

	if (value & (1ull << 63))
		strcat(buf, "GE ");
	if (value & (1ull << 32))
		strcat(buf, "PMAE ");
	if (value & 1)
		strcat(buf, "PMAO ");

	return buf;
}

void dump_ebb_hw_state(void)
{
	u64 bescr;
	u32 mmcr0;

	mmcr0 = mfspr(SPRN_MMCR0);
	bescr = mfspr(SPRN_BESCR);

	printf("HW state:\n"		\
	       "MMCR0 0x%016x %s\n"	\
	       "MMCR2 0x%016lx\n"	\
	       "EBBHR 0x%016lx\n"	\
	       "BESCR 0x%016llx %s\n"	\
	       "PMC1  0x%016lx\n"	\
	       "PMC2  0x%016lx\n"	\
	       "PMC3  0x%016lx\n"	\
	       "PMC4  0x%016lx\n"	\
	       "PMC5  0x%016lx\n"	\
	       "PMC6  0x%016lx\n"	\
	       "SIAR  0x%016lx\n",
	       mmcr0, decode_mmcr0(mmcr0), mfspr(SPRN_MMCR2),
	       mfspr(SPRN_EBBHR), bescr, decode_bescr(bescr),
	       mfspr(SPRN_PMC1), mfspr(SPRN_PMC2), mfspr(SPRN_PMC3),
	       mfspr(SPRN_PMC4), mfspr(SPRN_PMC5), mfspr(SPRN_PMC6),
	       mfspr(SPRN_SIAR));
}

void dump_ebb_state(void)
{
	dump_summary_ebb_state();

	dump_ebb_hw_state();

	trace_buffer_print(ebb_state.trace);
}

int count_pmc(int pmc, uint32_t sample_period)
{
	uint32_t start_value;
	u64 val;

	/* 0) Read PMC */
	start_value = pmc_sample_period(sample_period);

	val = read_pmc(pmc);
	if (val < start_value)
		ebb_state.stats.negative++;
	else
		ebb_state.stats.pmc_count[PMC_INDEX(pmc)] += val - start_value;

	trace_log_reg(ebb_state.trace, SPRN_PMC1 + pmc - 1, val);

	/* 1) Reset PMC */
	write_pmc(pmc, start_value);

	/* Report if we overflowed */
	return val >= COUNTER_OVERFLOW;
}

int ebb_event_enable(struct event *e)
{
	int rc;

	/* Ensure any SPR writes are ordered vs us */
	mb();

	rc = ioctl(e->fd, PERF_EVENT_IOC_ENABLE);
	if (rc)
		return rc;

	rc = event_read(e);

	/* Ditto */
	mb();

	return rc;
}

void ebb_freeze_pmcs(void)
{
	mtspr(SPRN_MMCR0, mfspr(SPRN_MMCR0) | MMCR0_FC);
	mb();
}

void ebb_unfreeze_pmcs(void)
{
	/* Unfreeze counters */
	mtspr(SPRN_MMCR0, mfspr(SPRN_MMCR0) & ~MMCR0_FC);
	mb();
}

void ebb_global_enable(void)
{
	/* Enable EBBs globally and PMU EBBs */
	mtspr(SPRN_BESCR, 0x8000000100000000ull);
	mb();
}

void ebb_global_disable(void)
{
	/* Disable EBBs & freeze counters, events are still scheduled */
	mtspr(SPRN_BESCRR, BESCR_PME);
	mb();
}

bool ebb_is_supported(void)
{
#ifdef PPC_FEATURE2_EBB
	/* EBB requires at least POWER8 */
	return have_hwcap2(PPC_FEATURE2_EBB);
#else
	return false;
#endif
}

void event_ebb_init(struct event *e)
{
	e->attr.config |= (1ull << 63);
}

void event_bhrb_init(struct event *e, unsigned ifm)
{
	e->attr.config |= (1ull << 62) | ((u64)ifm << 60);
}

void event_leader_ebb_init(struct event *e)
{
	event_ebb_init(e);

	e->attr.exclusive = 1;
	e->attr.pinned = 1;
}

int ebb_child(union pipe read_pipe, union pipe write_pipe)
{
	struct event event;
	uint64_t val;

	FAIL_IF(wait_for_parent(read_pipe));

	event_init_named(&event, 0x1001e, "cycles");
	event_leader_ebb_init(&event);

	event.attr.exclude_kernel = 1;
	event.attr.exclude_hv = 1;
	event.attr.exclude_idle = 1;

	FAIL_IF(event_open(&event));

	ebb_enable_pmc_counting(1);
	setup_ebb_handler(standard_ebb_callee);
	ebb_global_enable();

	FAIL_IF(event_enable(&event));

	if (event_read(&event)) {
		/*
		 * Some tests expect to fail here, so don't report an error on
		 * this line, and return a distinguisable error code. Tell the
		 * parent an error happened.
		 */
		notify_parent_of_error(write_pipe);
		return 2;
	}

	mtspr(SPRN_PMC1, pmc_sample_period(sample_period));

	FAIL_IF(notify_parent(write_pipe));
	FAIL_IF(wait_for_parent(read_pipe));
	FAIL_IF(notify_parent(write_pipe));

	while (ebb_state.stats.ebb_count < 20) {
		FAIL_IF(core_busy_loop());

		/* To try and hit SIGILL case */
		val  = mfspr(SPRN_MMCRA);
		val |= mfspr(SPRN_MMCR2);
		val |= mfspr(SPRN_MMCR0);
	}

	ebb_global_disable();
	ebb_freeze_pmcs();

	dump_ebb_state();

	event_close(&event);

	FAIL_IF(ebb_state.stats.ebb_count == 0);

	return 0;
}

static jmp_buf setjmp_env;

static void sigill_handler(int signal)
{
	printf("Took sigill\n");
	longjmp(setjmp_env, 1);
}

static struct sigaction sigill_action = {
	.sa_handler = sigill_handler,
};

int catch_sigill(void (*func)(void))
{
	if (sigaction(SIGILL, &sigill_action, NULL)) {
		perror("sigaction");
		return 1;
	}

	if (setjmp(setjmp_env) == 0) {
		func();
		return 1;
	}

	return 0;
}

void write_pmc1(void)
{
	mtspr(SPRN_PMC1, 0);
}

void write_pmc(int pmc, u64 value)
{
	switch (pmc) {
		case 1: mtspr(SPRN_PMC1, value); break;
		case 2: mtspr(SPRN_PMC2, value); break;
		case 3: mtspr(SPRN_PMC3, value); break;
		case 4: mtspr(SPRN_PMC4, value); break;
		case 5: mtspr(SPRN_PMC5, value); break;
		case 6: mtspr(SPRN_PMC6, value); break;
	}
}

u64 read_pmc(int pmc)
{
	switch (pmc) {
		case 1: return mfspr(SPRN_PMC1);
		case 2: return mfspr(SPRN_PMC2);
		case 3: return mfspr(SPRN_PMC3);
		case 4: return mfspr(SPRN_PMC4);
		case 5: return mfspr(SPRN_PMC5);
		case 6: return mfspr(SPRN_PMC6);
	}

	return 0;
}

static void term_handler(int signal)
{
	dump_summary_ebb_state();
	dump_ebb_hw_state();
	abort();
}

struct sigaction term_action = {
	.sa_handler = term_handler,
};

static void __attribute__((constructor)) ebb_init(void)
{
	clear_ebb_stats();

	if (sigaction(SIGTERM, &term_action, NULL))
		perror("sigaction");

	ebb_state.trace = trace_buffer_allocate(1 * 1024 * 1024);
}
