/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Service Call tests
 *
 * Copyright (c) 2020 IBM Corp
 *
 * Authors:
 *  Claudio Imbrenda <imbrenda@linux.ibm.com>
 */

#include <libcflat.h>
#include <asm/page.h>
#include <asm/asm-offsets.h>
#include <asm/interrupt.h>
#include <sclp.h>

#define PGM_NONE	1
#define PGM_BIT_SPEC	(1ULL << PGM_INT_CODE_SPECIFICATION)
#define PGM_BIT_ADDR	(1ULL << PGM_INT_CODE_ADDRESSING)
#define PGM_BIT_PRIV	(1ULL << PGM_INT_CODE_PRIVILEGED_OPERATION)
#define MKPTR(x) ((void *)(uint64_t)(x))

#define LC_SIZE (2 * PAGE_SIZE)

static uint8_t pagebuf[LC_SIZE] __attribute__((aligned(LC_SIZE)));	/* scratch pages used for some tests */
static uint8_t prefix_buf[LC_SIZE] __attribute__((aligned(LC_SIZE)));	/* temporary lowcore for test_sccb_prefix */
/* SCCB template to be used */
static union {
	uint8_t raw[PAGE_SIZE];
	SCCBHeader header;
	WriteEventData data;
} sccb_template;
static uint32_t valid_code;						/* valid command code for READ SCP INFO */

/*
 * Perform one service call, handling exceptions and interrupts.
 */
static int sclp_service_call_test(unsigned int command, void *sccb)
{
	int cc;

	sclp_mark_busy();
	sclp_setup_int();
	cc = servc(command, __pa(sccb));
	if (lowcore.pgm_int_code) {
		sclp_handle_ext();
		return 0;
	}
	if (!cc)
		sclp_wait_busy();
	return cc;
}

/*
 * Perform one test at the given address, optionally using the SCCB template,
 * checking for the expected program interrupts and return codes.
 *
 * The parameter buf_len indicates the number of bytes of the template that
 * should be copied to the test address, and should be 0 when the test
 * address is invalid, in which case nothing is copied.
 *
 * The template is used to simplify tests where the same buffer content is
 * used many times in a row, at different addresses.
 *
 * Returns true in case of success or false in case of failure
 */
static bool test_one_sccb(uint32_t cmd, uint8_t *addr, uint16_t buf_len, uint64_t exp_pgm, uint16_t exp_rc)
{
	SCCBHeader *h = (SCCBHeader *)addr;
	int res, pgm;

	/* Copy the template to the test address if needed */
	if (buf_len)
		memcpy(addr, sccb_template.raw, buf_len);
	if (exp_pgm != PGM_NONE)
		expect_pgm_int();
	/* perform the actual call */
	res = sclp_service_call_test(cmd, h);
	if (res) {
		report_info("SCLP not ready (command %#x, address %p, cc %d)", cmd, addr, res);
		return false;
	}
	pgm = clear_pgm_int();
	/* Check if the program exception was one of the expected ones */
	if (!((1ULL << pgm) & exp_pgm)) {
		report_info("First failure at addr %p, buf_len %d, cmd %#x, pgm code %d",
				addr, buf_len, cmd, pgm);
		return false;
	}
	/* Check if the response code is the one expected */
	if (exp_rc && exp_rc != h->response_code) {
		report_info("First failure at addr %p, buf_len %d, cmd %#x, resp code %#x",
				addr, buf_len, cmd, h->response_code);
		return false;
	}
	return true;
}

/*
 * Wrapper for test_one_sccb to be used when the template should not be
 * copied and the memory address should not be touched.
 */
static bool test_one_ro(uint32_t cmd, uint8_t *addr, uint64_t exp_pgm, uint16_t exp_rc)
{
	return test_one_sccb(cmd, addr, 0, exp_pgm, exp_rc);
}

/*
 * Wrapper for test_one_sccb to set up a simple SCCB template.
 *
 * The parameter sccb_len indicates the value that will be saved in the SCCB
 * length field of the SCCB, buf_len indicates the number of bytes of
 * template that need to be copied to the actual test address. In many cases
 * it's enough to clear/copy the first 8 bytes of the buffer, while the SCCB
 * itself can be larger.
 *
 * Returns true in case of success or false in case of failure
 */
static bool test_one_simple(uint32_t cmd, uint8_t *addr, uint16_t sccb_len,
			uint16_t buf_len, uint64_t exp_pgm, uint16_t exp_rc)
{
	memset(sccb_template.raw, 0, sizeof(sccb_template.raw));
	sccb_template.header.length = sccb_len;
	return test_one_sccb(cmd, addr, buf_len, exp_pgm, exp_rc);
}

/*
 * Test SCCB lengths < 8.
 */
static void test_sccb_too_short(void)
{
	int len;

	for (len = 0; len < 8; len++)
		if (!test_one_simple(valid_code, pagebuf, len, 8, PGM_BIT_SPEC, 0))
			break;

	report(len == 8, "SCCB too short");
}

/*
 * Test SCCBs that are not 64-bit aligned.
 */
static void test_sccb_unaligned(void)
{
	int offset;

	for (offset = 1; offset < 8; offset++)
		if (!test_one_simple(valid_code, offset + pagebuf, 8, 8, PGM_BIT_SPEC, 0))
			break;
	report(offset == 8, "SCCB unaligned");
}

/*
 * Test SCCBs whose address is in the lowcore or prefix area.
 */
static void test_sccb_prefix(void)
{
	uint8_t scratch[LC_SIZE];
	uint32_t prefix, new_prefix;
	int offset;

	/*
	 * copy the current lowcore to the future new location, otherwise we
	 * will not have a valid lowcore after setting the new prefix.
	 */
	memcpy(prefix_buf, 0, LC_SIZE);
	/* save the current prefix (it's probably going to be 0) */
	prefix = get_prefix();
	/*
	 * save the current content of absolute pages 0 and 1, so we can
	 * restore them after we trash them later on
	 */
	memcpy(scratch, (void *)(intptr_t)prefix, LC_SIZE);
	/* set the new prefix to prefix_buf */
	new_prefix = (uint32_t)(intptr_t)prefix_buf;
	set_prefix(new_prefix);

	/*
	 * testing with SCCB addresses in the lowcore; since we can't
	 * actually trash the lowcore (unsurprisingly, things break if we
	 * do), this will be a read-only test.
	 */
	for (offset = 0; offset < LC_SIZE; offset += 8)
		if (!test_one_ro(valid_code, MKPTR(offset), PGM_BIT_SPEC, 0))
			break;
	report(offset == LC_SIZE, "SCCB low pages");

	/*
	 * the SCLP should not even touch the memory, but we will write the
	 * SCCBs all over the two pages starting at absolute address 0, thus
	 * trashing them; we will need to restore them later.
	 */
	for (offset = 0; offset < LC_SIZE; offset += 8)
		if (!test_one_simple(valid_code, MKPTR(new_prefix + offset), 8, 8, PGM_BIT_SPEC, 0))
			break;
	report(offset == LC_SIZE, "SCCB prefix pages");

	/* restore the previous contents of absolute pages 0 and 1 */
	memcpy(prefix_buf, 0, LC_SIZE);
	/* restore the prefix to the original value */
	set_prefix(prefix);
}

/*
 * Test SCCBs that are above 2GB. If outside of memory, an addressing
 * exception is also allowed.
 */
static void test_sccb_high(void)
{
	SCCBHeader *h = (SCCBHeader *)pagebuf;
	uintptr_t a[33 * 4 * 2 + 2];	/* for the list of addresses to test */

	uint64_t maxram;
	int i, pgm, len = 0;

	h->length = 8;
	/* addresses with 1 bit set in the first 33 bits */
	for (i = 0; i < 33; i++)
		a[len++] = 1UL << (i + 31);
	/* addresses with 2 consecutive bits set in the first 33 bits */
	for (i = 0; i < 33; i++)
		a[len++] = 3UL << (i + 31);
	/* addresses with all bits set in bits 0..N */
	for (i = 0; i < 33; i++)
		a[len++] = 0xffffffff80000000UL << i;
	/* addresses with all bits set in bits N..33 */
	a[len++] = 0x80000000;
	for (i = 1; i < 33; i++, len++)
		a[len] = a[len - 1] | (1UL << (i + 31));
	/* all the addresses above, but adding the offset of a valid buffer */
	for (i = 0; i < len; i++)
		a[len + i] = a[i] + (intptr_t)h;
	len += i;
	/* two more hand-crafted addresses */
	a[len++] = 0xdeadbeef00000000;
	a[len++] = 0xdeaddeadbeef0000;

	maxram = get_ram_size();
	for (i = 0; i < len; i++) {
		pgm = PGM_BIT_SPEC | (a[i] >= maxram ? PGM_BIT_ADDR : 0);
		if (!test_one_ro(valid_code, (void *)a[i], pgm, 0))
			break;
	}
	report(i == len, "SCCB high addresses");
}

/*
 * Test invalid commands, both invalid command detail codes and valid
 * ones with invalid command class code.
 */
static void test_inval(void)
{
	const uint16_t res = SCLP_RC_INVALID_SCLP_COMMAND;
	uint32_t cmd;
	int i;

	report_prefix_push("Invalid command");
	for (i = 0; i < 65536; i++) {
		cmd = 0xdead0000 | i;
		if (!test_one_simple(cmd, pagebuf, PAGE_SIZE, PAGE_SIZE, PGM_NONE, res))
			break;
	}
	report(i == 65536, "Command detail code");

	for (i = 0; i < 256; i++) {
		cmd = (valid_code & ~0xff) | i;
		if (cmd == valid_code)
			continue;
		if (!test_one_simple(cmd, pagebuf, PAGE_SIZE, PAGE_SIZE, PGM_NONE, res))
			break;
	}
	report(i == 256, "Command class code");
	report_prefix_pop();
}


/*
 * Test short SCCBs (but larger than 8).
 */
static void test_short(void)
{
	const uint16_t res = SCLP_RC_INSUFFICIENT_SCCB_LENGTH;
	int len;

	for (len = 8; len < 144; len++)
		if (!test_one_simple(valid_code, pagebuf, len, len, PGM_NONE, res))
			break;
	report(len == 144, "Insufficient SCCB length (Read SCP info)");

	for (len = 8; len < 40; len++)
		if (!test_one_simple(SCLP_READ_CPU_INFO, pagebuf, len, len, PGM_NONE, res))
			break;
	report(len == 40, "Insufficient SCCB length (Read CPU info)");
}

/*
 * Test SCCB page boundary violations.
 */
static void test_boundary(void)
{
	const uint32_t cmd = SCLP_CMD_WRITE_EVENT_DATA;
	const uint16_t res = SCLP_RC_SCCB_BOUNDARY_VIOLATION;
	WriteEventData *sccb = &sccb_template.data;
	int len, offset;

	memset(sccb_template.raw, 0, sizeof(sccb_template.raw));
	sccb->h.function_code = SCLP_FC_NORMAL_WRITE;
	for (len = 32; len <= 4096; len++) {
		offset = len & 7 ? len & ~7 : len - 8;
		for (offset = 4096 - offset; offset < 4096; offset += 8) {
			sccb->h.length = len;
			if (!test_one_sccb(cmd, offset + pagebuf, len, PGM_NONE, res))
				goto out;
		}
	}
out:
	report(len > 4096 && offset == 4096, "SCCB page boundary violation");
}

/*
 * Test excessively long SCCBs.
 */
static void test_toolong(void)
{
	const uint32_t cmd = SCLP_CMD_WRITE_EVENT_DATA;
	const uint16_t res = SCLP_RC_SCCB_BOUNDARY_VIOLATION;
	WriteEventData *sccb = &sccb_template.data;
	int len;

	memset(sccb_template.raw, 0, sizeof(sccb_template.raw));
	sccb->h.function_code = SCLP_FC_NORMAL_WRITE;
	for (len = 4097; len < 8192; len++) {
		sccb->h.length = len;
		if (!test_one_sccb(cmd, pagebuf, PAGE_SIZE, PGM_NONE, res))
			break;
	}
	report(len == 8192, "SCCB bigger than 4k");
}

/*
 * Test privileged operation.
 */
static void test_priv(void)
{
	SCCBHeader *h = (SCCBHeader *)pagebuf;

	report_prefix_push("Privileged operation");
	h->length = 8;
	expect_pgm_int();
	enter_pstate();
	servc(valid_code, __pa(h));
	check_pgm_int_code(PGM_INT_CODE_PRIVILEGED_OPERATION);
	report_prefix_pop();
}

/*
 * Test addressing exceptions. We need to test SCCB addresses between the
 * end of available memory and 2GB, because after 2GB a specification
 * exception is also allowed.
 * Only applicable if the VM has less than 2GB of memory
 */
static void test_addressing(void)
{
	unsigned long i, maxram = get_ram_size();

	/* the VM has more than 2GB of memory */
	if (maxram >= 0x80000000) {
		report_skip("Invalid SCCB address");
		return;
	}
	/* test all possible valid addresses immediately after the end of memory
	 * up to 64KB after the end of memory
	 */
	for (i = 0; i < 0x10000 && i + maxram < 0x80000000; i += 8)
		if (!test_one_ro(valid_code, MKPTR(i + maxram), PGM_BIT_ADDR, 0))
			goto out;
	/* test more addresses until we reach 1MB after end of memory;
	 * increment by a prime number (times 8) in order to test all
	 * possible valid offsets inside pages
	 */
	for (; i < 0x100000 && i + maxram < 0x80000000 ; i += 808)
		if (!test_one_ro(valid_code, MKPTR(i + maxram), PGM_BIT_ADDR, 0))
			goto out;
	/* test the remaining addresses until we reach address 2GB;
	 * increment by a prime number (times 8) in order to test all
	 * possible valid offsets inside pages
	 */
	for (; i + maxram < 0x80000000; i += 800024)
		if (!test_one_ro(valid_code, MKPTR(i + maxram), PGM_BIT_ADDR, 0))
			goto out;
out:
	report(i + maxram >= 0x80000000, "Invalid SCCB address");
}

/*
 * Test some bits in the instruction format that are specified to be ignored.
 */
static void test_instbits(void)
{
	SCCBHeader *h = (SCCBHeader *)pagebuf;
	uint64_t bogus_cc = 1;
	int cc;

	sclp_mark_busy();
	h->length = 8;
	sclp_setup_int();

	asm volatile(
		"	tmll	%[bogus_cc],3\n"
		"       .insn   rre,0xb2204200,%1,%2\n"  /* servc %1,%2 */
		"       ipm     %0\n"
		"       srl     %0,28"
		: "=&d" (cc)
		: "d" (valid_code), "a" (__pa(pagebuf)), [bogus_cc] "d" (bogus_cc)
		: "cc", "memory");
	/* No exception, but also no command accepted, so no interrupt is
	 * expected. We need to clear the flag manually otherwise we will
	 * loop forever when we try to report failure.
	 */
	if (cc)
		sclp_handle_ext();
	else
		sclp_wait_busy();
	report(cc == 0, "Instruction format ignored bits");
}

/*
 * Find a valid READ INFO command code; not all codes are always allowed, and
 * probing should be performed in the right order.
 */
static void find_valid_sclp_code(void)
{
	const unsigned int commands[] = { SCLP_CMDW_READ_SCP_INFO_FORCED,
					  SCLP_CMDW_READ_SCP_INFO };
	SCCBHeader *h = (SCCBHeader *)pagebuf;
	int i, cc;

	for (i = 0; i < ARRAY_SIZE(commands); i++) {
		sclp_mark_busy();
		memset(h, 0, sizeof(*h));
		h->length = 4096;

		valid_code = commands[i];
		cc = sclp_service_call(commands[i], h);
		if (cc)
			break;
		if (h->response_code == SCLP_RC_NORMAL_READ_COMPLETION)
			return;
		if (h->response_code != SCLP_RC_INVALID_SCLP_COMMAND)
			break;
	}
	report_abort("READ_SCP_INFO failed");
}

int main(void)
{
	report_prefix_push("sclp");
	find_valid_sclp_code();

	/* Test some basic things */
	test_instbits();
	test_priv();
	test_addressing();

	/* Test the specification exceptions */
	test_sccb_too_short();
	test_sccb_unaligned();
	test_sccb_prefix();
	test_sccb_high();

	/* Test the expected response codes */
	test_inval();
	test_short();
	test_boundary();
	test_toolong();

	return report_summary();
}
