/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Tests sigp store additional status order
 *
 * Copyright IBM Corp. 2022
 *
 * Authors:
 *    Nico Boehr <nrb@linux.ibm.com>
 */
#include <libcflat.h>
#include <asm/asm-offsets.h>
#include <asm/interrupt.h>
#include <asm/facility.h>
#include <asm-generic/barrier.h>
#include <asm/sigp.h>
#include <asm/vector.h>

#include <smp.h>
#include <gs.h>

static int testflag = 0;

#define INVALID_CPU_ADDRESS -4711

struct mcesa_lc12 {
	uint8_t vregs[0x200];		      /* 0x000 */
	uint8_t reserved200[0x400 - 0x200];   /* 0x200 */
	struct gs_cb gs_cb;                   /* 0x400 */
	uint8_t reserved420[0x800 - 0x420];   /* 0x420 */
	uint8_t reserved800[0x1000 - 0x800];  /* 0x800 */
};

static struct mcesa_lc12 adtl_status __attribute__((aligned(4096)));

static uint8_t expected_vec_contents[VEC_REGISTER_NUM][VEC_REGISTER_SIZE];

static struct gs_cb gs_cb;
static struct gs_epl gs_epl;

static bool memisset(void *s, int c, size_t n)
{
	uint8_t *p = s;
	size_t i;

	for (i = 0; i < n; i++) {
		if (p[i] != c)
			return false;
	}

	return true;
}

static void wait_for_flag(void)
{
	while (!testflag)
		mb();
}

static void set_flag(int val)
{
	mb();
	testflag = val;
	mb();
}

static void test_func(void)
{
	set_flag(1);
}

static bool have_adtl_status(void)
{
	return test_facility(133) || test_facility(129);
}

static void test_store_adtl_status(void)
{
	uint32_t status = -1;
	int cc;

	report_prefix_push("store additional status");

	if (!have_adtl_status()) {
		report_skip("no guarded-storage or vector facility installed");
		goto out;
	}

	memset(&adtl_status, 0xff, sizeof(adtl_status));

	report_prefix_push("running");
	smp_cpu_restart(1);

	cc = smp_sigp(1, SIGP_STORE_ADDITIONAL_STATUS,
		  (unsigned long)&adtl_status, &status);

	report(cc == 1, "CC = 1");
	report(status == SIGP_STATUS_INCORRECT_STATE, "status = INCORRECT_STATE");
	report(memisset(&adtl_status, 0xff, sizeof(adtl_status)),
	       "additional status not touched");

	report_prefix_pop();

	report_prefix_push("invalid CPU address");

	cc = sigp(INVALID_CPU_ADDRESS, SIGP_STORE_ADDITIONAL_STATUS,
		  (unsigned long)&adtl_status, &status);
	report(cc == 3, "CC = 3");
	report(memisset(&adtl_status, 0xff, sizeof(adtl_status)),
	       "additional status not touched");

	report_prefix_pop();

	report_prefix_push("unaligned");
	smp_cpu_stop(1);

	cc = smp_sigp(1, SIGP_STORE_ADDITIONAL_STATUS,
		  (unsigned long)&adtl_status + 256, &status);
	report(cc == 1, "CC = 1");
	report(status == SIGP_STATUS_INVALID_PARAMETER, "status = INVALID_PARAMETER");
	report(memisset(&adtl_status, 0xff, sizeof(adtl_status)),
	       "additional status not touched");

	report_prefix_pop();

out:
	report_prefix_pop();
}

static void test_store_adtl_status_unavail(void)
{
	uint32_t status = 0;
	int cc;

	report_prefix_push("store additional status unavailable");

	if (have_adtl_status()) {
		report_skip("guarded-storage or vector facility installed");
		goto out;
	}

	report_prefix_push("not accepted");
	smp_cpu_stop(1);

	memset(&adtl_status, 0xff, sizeof(adtl_status));

	cc = smp_sigp(1, SIGP_STORE_ADDITIONAL_STATUS,
		  (unsigned long)&adtl_status, &status);

	report(cc == 1, "CC = 1");
	report(status == SIGP_STATUS_INVALID_ORDER,
	       "status = INVALID_ORDER");
	report(memisset(&adtl_status, 0xff, sizeof(adtl_status)),
	       "additional status not touched");

	report_prefix_pop();

out:
	report_prefix_pop();
}

static void restart_write_vector(void)
{
	uint8_t *vec_reg;
	/* vlm handles at most 16 registers at a time */
	uint8_t *vec_reg_16_31 = &expected_vec_contents[16][0];
	uint64_t cr0, cr0_mask = ~BIT_ULL(CTL0_VECTOR);
	int i;

	for (i = 0; i < VEC_REGISTER_NUM; i++) {
		vec_reg = &expected_vec_contents[i][0];
		/* i+1 to avoid zero content */
		memset(vec_reg, i + 1, VEC_REGISTER_SIZE);
	}

	ctl_set_bit(0, CTL0_VECTOR);

	asm volatile (
		"	.machine z13\n"
		/* load vector registers */
		"	vlm 0,15, %[vec_reg_0_15]\n"
		"	vlm 16,31, %[vec_reg_16_31]\n"
		/* turn off vector instructions */
		"	stctg 0,0, %[cr0]\n"
		"	ng %[cr0_mask], %[cr0]\n"
		"	stg %[cr0_mask], %[cr0]\n"
		"	lctlg 0,0, %[cr0]\n"
		/* inform CPU 0 we are done by setting testflag to 1 */
		"	mvhi %[testflag], 1\n"
		/*
		 * infinite loop. function epilogue will restore floating point
		 * registers and hence destroy vector register contents
		 */
		"0:	j 0\n"
		: [cr0_mask] "+&d"(cr0_mask)
		: [vec_reg_0_15] "Q"(expected_vec_contents),
		  [vec_reg_16_31] "Q"(*vec_reg_16_31),
		  [cr0] "Q"(cr0),
		  [testflag] "T"(testflag)
		: "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9",
		  "v10", "v11", "v12", "v13", "v14", "v15", "v16", "v17", "v18",
		  "v19", "v20", "v21", "v22", "v23", "v24", "v25", "v26", "v27",
		  "v28", "v29", "v30", "v31", "cc", "memory"
	);
}

static void cpu_write_magic_to_vector_regs(uint16_t cpu_idx)
{
	struct psw new_psw;

	smp_cpu_stop(cpu_idx);

	new_psw.mask = extract_psw_mask();
	new_psw.addr = (unsigned long)restart_write_vector;

	set_flag(0);

	smp_cpu_start(cpu_idx, new_psw);

	wait_for_flag();
}

static int adtl_status_check_unmodified_fields_for_lc(unsigned long lc)
{
	assert (!lc || (lc >= 10 && lc <= 12));

	if (lc <= 10 && !memisset(&adtl_status.gs_cb, 0xff, sizeof(adtl_status.gs_cb)))
		return false;

	if (!memisset(adtl_status.reserved200, 0xff, sizeof(adtl_status.reserved200)))
		return false;

	if (!memisset(adtl_status.reserved420, 0xff, sizeof(adtl_status.reserved420)))
		return false;

	if (!memisset(adtl_status.reserved800, 0xff, sizeof(adtl_status.reserved800)))
		return false;

	return true;
}

static void __store_adtl_status_vector_lc(unsigned long lc)
{
	uint32_t status = -1;
	struct psw psw;
	int cc;

	report_prefix_pushf("LC %lu", lc);

	if (!test_facility(133) && lc) {
		report_skip("not supported, no guarded-storage facility");
		goto out;
	}

	cpu_write_magic_to_vector_regs(1);
	smp_cpu_stop(1);

	memset(&adtl_status, 0xff, sizeof(adtl_status));

	cc = smp_sigp(1, SIGP_STORE_ADDITIONAL_STATUS,
		  (unsigned long)&adtl_status | lc, &status);
	report(!cc, "CC = 0");

	report(!memcmp(adtl_status.vregs,
		       expected_vec_contents, sizeof(expected_vec_contents)),
	       "additional status contents match");

	report(adtl_status_check_unmodified_fields_for_lc(lc),
	       "no write outside expected fields");

	/*
	 * To avoid the floating point/vector registers being cleaned up, we
	 * stopped CPU1 right in the middle of a function. Hence the cleanup of
	 * the function didn't run yet and the stackpointer is messed up.
	 * Destroy and re-initalize the CPU to fix that.
	 */
	smp_cpu_destroy(1);
	psw.mask = extract_psw_mask();
	psw.addr = (unsigned long)test_func;
	smp_cpu_setup(1, psw);

out:
	report_prefix_pop();
}

static void test_store_adtl_status_vector(void)
{
	report_prefix_push("store additional status vector");

	if (!test_facility(129)) {
		report_skip("vector facility not installed");
		goto out;
	}

	__store_adtl_status_vector_lc(0);
	__store_adtl_status_vector_lc(10);
	__store_adtl_status_vector_lc(11);
	__store_adtl_status_vector_lc(12);

out:
	report_prefix_pop();
}

static void restart_write_gs_regs(void)
{
	const unsigned long gs_area = 0x2000000;
	const unsigned long gsc = 25; /* align = 32 M, section size = 512K */

	ctl_set_bit(2, CTL2_GUARDED_STORAGE);

	gs_cb.gsd = gs_area | gsc;
	gs_cb.gssm = 0xfeedc0ffe;
	gs_cb.gs_epl_a = (uint64_t) &gs_epl;

	load_gs_cb(&gs_cb);

	set_flag(1);

	ctl_clear_bit(2, CTL2_GUARDED_STORAGE);

	/*
	 * Safe to return here. r14 will point to the endless loop in
	 * smp_cpu_setup_state.
	 */
}

static void cpu_write_to_gs_regs(uint16_t cpu_idx)
{
	struct psw new_psw;

	smp_cpu_stop(cpu_idx);

	new_psw.mask = extract_psw_mask();
	new_psw.addr = (unsigned long)restart_write_gs_regs;

	set_flag(0);

	smp_cpu_start(cpu_idx, new_psw);

	wait_for_flag();
}

static void __store_adtl_status_gs(unsigned long lc)
{
	uint32_t status = 0;
	int cc;

	report_prefix_pushf("LC %lu", lc);

	cpu_write_to_gs_regs(1);
	smp_cpu_stop(1);

	memset(&adtl_status, 0xff, sizeof(adtl_status));

	cc = smp_sigp(1, SIGP_STORE_ADDITIONAL_STATUS,
		  (unsigned long)&adtl_status | lc, &status);
	report(!cc, "CC = 0");

	report(!memcmp(&adtl_status.gs_cb, &gs_cb, sizeof(gs_cb)),
	       "additional status contents match");

	report(adtl_status_check_unmodified_fields_for_lc(lc),
	       "no write outside expected fields");

	report_prefix_pop();
}

static void test_store_adtl_status_gs(void)
{
	report_prefix_push("store additional status guarded-storage");

	if (!test_facility(133)) {
		report_skip("guarded-storage facility not installed");
		goto out;
	}

	__store_adtl_status_gs(11);
	__store_adtl_status_gs(12);

out:
	report_prefix_pop();
}

int main(void)
{
	struct psw psw;
	report_prefix_push("adtl_status");

	if (smp_query_num_cpus() == 1) {
		report_skip("need at least 2 cpus for this test");
		goto done;
	}

	/* Setting up the cpu to give it a stack and lowcore */
	psw.mask = extract_psw_mask();
	psw.addr = (unsigned long)test_func;
	smp_cpu_setup(1, psw);
	smp_cpu_stop(1);

	test_store_adtl_status_unavail();
	test_store_adtl_status_vector();
	test_store_adtl_status_gs();
	test_store_adtl_status();
	smp_cpu_destroy(1);

done:
	report_prefix_pop();
	return report_summary();
}
