/*
 * 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>
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Library General Public License version 2.
 */
#include <libcflat.h>
#include <asm/cpacf.h>
#include <asm/interrupt.h>
#include <asm/float.h>

struct lowcore *lc = NULL;

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 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 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 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 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 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 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 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 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 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 inline void __test_cpacf_invalid_parm(unsigned int opcode)
{
	report_prefix_push("invalid parm address");
	expect_pgm_int();
	__cpacf_query(opcode, (void *) -1);
	check_pgm_int_code(PGM_INT_CODE_ADDRESSING);
	report_prefix_pop();
}

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

static 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 */
	lc->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(lc->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 */
	lc->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(lc->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();
}
