/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Emulator tests - for s390x CPU instructions that are usually interpreted
 *                  by the hardware
 *
 * Copyright (c) 2017 Red Hat Inc
 *
 * Authors:
 *  David Hildenbrand <david@redhat.com>
 */
#include <libcflat.h>
#include <asm/cpacf.h>
#include <asm/interrupt.h>
#include <asm/float.h>
#include <asm/mem.h>
#include <linux/compiler.h>

static inline void __test_spm_ipm(uint8_t cc, uint8_t key)
{
	uint64_t in = (cc << 28) | (key << 24);
	uint64_t out = ~0ULL;

	report_prefix_pushf("cc=%d,key=%x", cc, key);

	asm volatile ("spm %1\n"
		      "ipm %0\n"
		      : "+r"(out) : "r"(in) : "cc");

	report(!(out & 0xc0000000UL), "bit 32 and 33 set to zero");
	report((out & ~0xff000000ULL) == ~0xff000000ULL,
	       "bit 0-31, 40-63 unchanged");
	report(!((in ^ out) & 0x3f000000UL), "cc and key applied");

	report_prefix_pop();
}

/* Test the SET PROGRAM PARAMETER and INSERT PROGRAM PARAMETER instruction */
static void test_spm_ipm(void)
{
	__test_spm_ipm(0, 0xf);
	__test_spm_ipm(1, 0x9);
	__test_spm_ipm(2, 0x5);
	__test_spm_ipm(3, 0x3);
	__test_spm_ipm(0, 0);
}

static __always_inline void __test_cpacf(unsigned int opcode, unsigned long func,
				unsigned int r1, unsigned int r2,
				unsigned int r3)
{
	register unsigned long gr0 asm("0") = func;
	cpacf_mask_t mask;
	register unsigned long gr1 asm("1") = (unsigned long)&mask;

	asm volatile(".insn rrf,%[opc] << 16,%[r1],%[r2],%[r3],0\n"
		     : : "d" (gr0), "d" (gr1), [opc] "i" (opcode),
		         [r1] "i" (r1), [r2] "i" (r2), [r3] "i" (r3));
}

static __always_inline void __test_cpacf_r1_odd(unsigned int opcode)
{
	report_prefix_push("r1 odd");
	expect_pgm_int();
	__test_cpacf(opcode, 0, 1, 4, 6);
	check_pgm_int_code(PGM_INT_CODE_SPECIFICATION);
	report_prefix_pop();
}

static __always_inline void __test_cpacf_r1_null(unsigned int opcode)
{
	report_prefix_push("r1 null");
	expect_pgm_int();
	__test_cpacf(opcode, 0, 0, 4, 6);
	check_pgm_int_code(PGM_INT_CODE_SPECIFICATION);
	report_prefix_pop();
}

static __always_inline void __test_cpacf_r2_odd(unsigned int opcode)
{
	report_prefix_push("r2 odd");
	expect_pgm_int();
	__test_cpacf(opcode, 0, 2, 3, 6);
	check_pgm_int_code(PGM_INT_CODE_SPECIFICATION);
	report_prefix_pop();
}

static __always_inline void __test_cpacf_r2_null(unsigned int opcode)
{
	report_prefix_push("r2 null");
	expect_pgm_int();
	__test_cpacf(opcode, 0, 2, 0, 6);
	check_pgm_int_code(PGM_INT_CODE_SPECIFICATION);
	report_prefix_pop();
}

static __always_inline void __test_cpacf_r3_odd(unsigned int opcode)
{
	report_prefix_push("r3 odd");
	expect_pgm_int();
	__test_cpacf(opcode, 0, 2, 4, 5);
	check_pgm_int_code(PGM_INT_CODE_SPECIFICATION);
	report_prefix_pop();
}

static __always_inline void __test_cpacf_r3_null(unsigned int opcode)
{
	report_prefix_push("r3 null");
	expect_pgm_int();
	__test_cpacf(opcode, 0, 2, 4, 0);
	check_pgm_int_code(PGM_INT_CODE_SPECIFICATION);
	report_prefix_pop();
}

static __always_inline void __test_cpacf_mod_bit(unsigned int opcode)
{
	report_prefix_push("mod bit");
	expect_pgm_int();
	__test_cpacf(opcode, CPACF_DECRYPT, 2, 4, 6);
	check_pgm_int_code(PGM_INT_CODE_SPECIFICATION);
	report_prefix_pop();
}

static __always_inline void __test_cpacf_invalid_func(unsigned int opcode)
{
	report_prefix_push("invalid subfunction");
	expect_pgm_int();
	/* 127 is unassigned for now. We don't simply use any, as HW
	 * might simply mask valid codes in query but they might still work */
	if (cpacf_query_func(opcode, 127)) {
		report_skip("127 not invalid");
	} else {
		__test_cpacf(opcode, 127, 2, 4, 6);
		check_pgm_int_code(PGM_INT_CODE_SPECIFICATION);
	}
	report_prefix_pop();
}

static __always_inline void __test_cpacf_invalid_parm(unsigned int opcode)
{
	report_prefix_push("invalid parm address");
	expect_pgm_int();
	__cpacf_query(opcode, OPAQUE_PTR(-1));
	check_pgm_int_code(PGM_INT_CODE_ADDRESSING);
	report_prefix_pop();
}

static __always_inline void __test_cpacf_protected_parm(unsigned int opcode)
{
	report_prefix_push("protected parm address");
	expect_pgm_int();
	low_prot_enable();
	__cpacf_query(opcode, OPAQUE_PTR(8));
	low_prot_disable();
	check_pgm_int_code(PGM_INT_CODE_PROTECTION);
	report_prefix_pop();
}

static __always_inline void __test_basic_cpacf_opcode(unsigned int opcode)
{
	bool mod_bit_allowed = false;

	if (!__cpacf_check_opcode(opcode)) {
		report_skip("not available");
		return;
	}
	report(cpacf_query_func(opcode, 0), "query indicated in query");

	switch (opcode) {
	case CPACF_KMCTR:
		__test_cpacf_r3_odd(opcode);
		__test_cpacf_r3_null(opcode);
		/* FALL THROUGH */
	case CPACF_PRNO:
	case CPACF_KMF:
	case CPACF_KMC:
	case CPACF_KMO:
	case CPACF_KM:
		__test_cpacf_r1_odd(opcode);
		__test_cpacf_r1_null(opcode);
		mod_bit_allowed = true;
		/* FALL THROUGH */
	case CPACF_KMAC:
	case CPACF_KIMD:
	case CPACF_KLMD:
		__test_cpacf_r2_odd(opcode);
		__test_cpacf_r2_null(opcode);
	        break;
	}
	if (!mod_bit_allowed)
		__test_cpacf_mod_bit(opcode);
	__test_cpacf_invalid_func(opcode);
	__test_cpacf_invalid_parm(opcode);
	__test_cpacf_protected_parm(opcode);
}

/* COMPUTE MESSAGE AUTHENTICATION CODE */
static void test_kmac(void)
{
	__test_basic_cpacf_opcode(CPACF_KMAC);
}

/* CIPHER MESSAGE */
static void test_km(void)
{
	__test_basic_cpacf_opcode(CPACF_KM);
}
/* CIPHER MESSAGE WITH CHAINING */
static void test_kmc(void)
{
	__test_basic_cpacf_opcode(CPACF_KMC);
}

/* COMPUTE INTERMEDIATE MESSAGE DIGEST */
static void test_kimd(void)
{
	__test_basic_cpacf_opcode(CPACF_KIMD);
}

/* COMPUTE LAST MESSAGE DIGEST */
static void test_klmd(void)
{
	__test_basic_cpacf_opcode(CPACF_KLMD);
}

/* PERFORM CRYPTOGRAPHIC KEY MANAGEMENT OPERATION */
static void test_pckmo(void)
{
	__test_basic_cpacf_opcode(CPACF_PCKMO);
}

/* CIPHER MESSAGE WITH CIPHER FEEDBACK */
static void test_kmf(void)
{
	__test_basic_cpacf_opcode(CPACF_KMF);
}

/* PERFORM CRYPTOGRAPHIC KEY MANAGEMENT OPERATION */
static void test_kmo(void)
{
	__test_basic_cpacf_opcode(CPACF_KMO);
}

/* PERFORM CRYPTOGRAPHIC COMPUTATION */
static void test_pcc(void)
{
	__test_basic_cpacf_opcode(CPACF_PCC);
}

/* CIPHER MESSAGE WITH COUNTER */
static void test_kmctr(void)
{
	__test_basic_cpacf_opcode(CPACF_KMCTR);
}

/* PERFORM RANDOM NUMBER OPERATION (formerly PPNO) */
static void test_prno(void)
{
	__test_basic_cpacf_opcode(CPACF_PRNO);
}

static void test_dxc(void)
{
	/* DXC (0xff) is to be stored in LC and FPC on a trap (CRT) with AFP */
	lowcore.dxc_vxc = 0x12345678;
	set_fpc_dxc(0);

	report_prefix_push("afp");
	expect_pgm_int();
	asm volatile("	.insn	rrf,0xb9600000,%0,%0,8,0\n"
		     : : "r"(0) : "memory");
	check_pgm_int_code(PGM_INT_CODE_DATA);

	report(lowcore.dxc_vxc == 0xff, "dxc in LC");
	report(get_fpc_dxc() == 0xff, "dxc in FPC");
	report_prefix_pop();

	/* DXC (0xff) is to be stored in LC only on a trap (CRT) without AFP */
	lowcore.dxc_vxc = 0x12345678;
	set_fpc_dxc(0);

	report_prefix_push("no-afp");
	expect_pgm_int();
	/* temporarily disable AFP */
	afp_disable();
	asm volatile("	.insn	rrf,0xb9600000,%0,%0,8,0\n"
		     : : "r"(0) : "memory");
	afp_enable();
	check_pgm_int_code(PGM_INT_CODE_DATA);

	report(lowcore.dxc_vxc == 0xff, "dxc in LC");
	report(get_fpc_dxc() == 0, "dxc not in FPC");
	report_prefix_pop();
}

static struct {
	const char *name;
	void (*func)(void);
} tests[] = {
	{ "spm/ipm", test_spm_ipm },
	{ "kmac", test_kmac },
	{ "km", test_km },
	{ "kmc", test_kmc },
	{ "kimd", test_kimd },
	{ "klmd", test_klmd },
	{ "pckmo", test_pckmo },
	{ "kmf", test_kmf },
	{ "kmo", test_kmo },
	{ "pcc", test_pcc },
	{ "kmctr", test_kmctr },
	{ "prno", test_prno },
	{ "dxc", test_dxc },
	{ NULL, NULL }
};

int main(int argc, char**argv)
{
	int i;

	report_prefix_push("emulator");
	for (i = 0; tests[i].name; i++) {
		report_prefix_push(tests[i].name);
		tests[i].func();
		report_prefix_pop();
	}
	report_prefix_pop();

	return report_summary();
}
