/*
 * Service Call tests
 *
 * Copyright (c) 2020 IBM Corp
 *
 * Authors:
 *  Claudio Imbrenda <imbrenda@linux.ibm.com>
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2.
 */

#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 */
static struct lowcore *lc;

/**
 * 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 (lc->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;
	int cc;

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

	asm volatile(
		"       .insn   rre,0xb2204200,%1,%2\n"  /* servc %1,%2 */
		"       ipm     %0\n"
		"       srl     %0,28"
		: "=&d" (cc) : "d" (valid_code), "a" (__pa(pagebuf))
		: "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();
}
