/*
 * Tests guarded storage support.
 *
 * Copyright 2018 IBM Corp.
 *
 * Authors:
 *    Martin Schwidefsky <schwidefsky@de.ibm.com>
 *    Janosch Frank <frankja@de.ibm.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/page.h>
#include <asm/facility.h>
#include <asm/interrupt.h>
#include <asm-generic/barrier.h>

struct gs_cb {
	uint64_t reserved;
	uint64_t gsd;
	uint64_t gssm;
	uint64_t gs_epl_a;
};

struct gs_epl {
	uint8_t pad1;
	union {
		uint8_t gs_eam;
		struct {
			uint8_t		: 6;
			uint8_t e	: 1;
			uint8_t b	: 1;
		};
	};
	union {
		uint8_t gs_eci;
		struct {
			uint8_t tx	: 1;
			uint8_t cx	: 1;
			uint8_t		: 5;
			uint8_t in	: 1;
		};
	};
	union {
		uint8_t gs_eai;
		struct {
			uint8_t		: 1;
			uint8_t t	: 1;
			uint8_t as	: 2;
			uint8_t ar	: 4;
		};
	};
	uint32_t pad2;
	uint64_t gs_eha;
	uint64_t gs_eia;
	uint64_t gs_eoa;
	uint64_t gs_eir;
	uint64_t gs_era;
};

static volatile int guarded = 0;
static struct gs_cb gs_cb;
static struct gs_epl gs_epl;
static unsigned long gs_area = 0x2000000;

void gs_handler(struct gs_cb *this_cb);

static inline void load_gs_cb(struct gs_cb *gs_cb)
{
	asm volatile(".insn rxy,0xe3000000004d,0,%0" : : "Q" (*gs_cb));
}

static inline void store_gs_cb(struct gs_cb *gs_cb)
{
	asm volatile(".insn rxy,0xe30000000049,0,%0" : : "Q" (*gs_cb));
}

static inline unsigned long load_guarded(unsigned long *p)
{
	unsigned long v;

	asm(".insn rxy,0xe3000000004c, %0,%1"
	    : "=d" (v)
	    : "m" (*p)
	    : "r14", "memory");
	return v;
}

/* guarded-storage event handler and finally it calls gs_handler */
extern void gs_handler_asm(void);
	asm(".globl gs_handler_asm\n"
	    "gs_handler_asm:\n"
	    "	    lgr	    %r14,%r15\n" 		/* Save current stack address in r14 */
	    "	    aghi    %r15,-320\n" 		/* Allocate stack frame */
	    "	    stmg    %r0,%r13,192(%r15)\n" 	/* Store regs to save area */
	    "	    stg	    %r14,312(%r15)\n"
	    "	    la	    %r2,160(%r15)\n" 		/* Store gscb address in this_cb */
	    "	    .insn   rxy,0xe30000000049,0,160(%r15)\n" /* stgsc */
	    "	    lg	    %r14,24(%r2)\n" 		/* Get GSEPLA from GSCB*/
	    "	    lg	    %r14,40(%r14)\n" 		/* Get GSERA from GSEPL*/
	    "	    stg	    %r14,304(%r15)\n" 		/* Store GSERA in r14 of reg save area */
	    "	    brasl   %r14,gs_handler\n" 		/* Jump to gs_handler */
	    "	    lmg	    %r0,%r15,192(%r15)\n" 	/* Restore regs */
	    "	    aghi    %r14, 6\n" 			/* Add lgg instr len to GSERA */
	    "	    br	    %r14\n" 			/* Jump to next instruction after lgg */
	    "	    .size gs_handler_asm,.-gs_handler_asm\n");

void gs_handler(struct gs_cb *this_cb)
{
	guarded = 1;
	struct gs_epl *gs_epl = (struct gs_epl *) this_cb->gs_epl_a;
	printf("gs_handler called for %016lx at %016lx\n",
	       gs_epl->gs_eir, gs_epl->gs_eia);
}

/* Test if load guarded gets intercepted. */
static void test_load(void)
{
	unsigned long v;

	guarded = 0;
	v = load_guarded(&gs_area);
	report(guarded, "load guarded %ld", v);
	guarded = 0;
}

/* Test gs instructions without enablement resulting in an exception */
static void test_special(void)
{
	report_prefix_push("disabled gs");
	report_prefix_push("load gs");
	expect_pgm_int();
	load_gs_cb(&gs_cb);
	check_pgm_int_code(PGM_INT_CODE_SPECIAL_OPERATION);
	report_prefix_pop();

	report_prefix_push("store gs");
	expect_pgm_int();
	store_gs_cb(&gs_cb);
	check_pgm_int_code(PGM_INT_CODE_SPECIAL_OPERATION);
	report_prefix_pop();

	report_prefix_pop();
}

static void init(void)
{
	/* Enable control bit for gs */
	ctl_set_bit(2, 4);

	/* Setup gs registers to guard the gs_area */
	gs_cb.gsd = gs_area | 25;

	/* Check all 512kb slots for events */
	gs_cb.gssm = 0xffffffffffffffffULL;
	gs_cb.gs_epl_a =  (unsigned long) &gs_epl;

	/* Register handler */
	gs_epl.gs_eha = (unsigned long) gs_handler_asm;
	load_gs_cb(&gs_cb);
}

int main(void)
{
	bool has_gs = test_facility(133);

	report_prefix_push("gs");
	if (!has_gs) {
		report_skip("Guarded storage is not available");
		goto done;
	}

	test_special();
	init();
	test_load();

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