/*
 * Perform Frame Management Function (pfmf) tests
 *
 * Copyright (c) 2018 IBM
 *
 * Authors:
 *  Janosch Frank <frankja@linux.vnet.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/asm-offsets.h>
#include <asm/interrupt.h>
#include <asm/page.h>
#include <asm/facility.h>
#include <asm/mem.h>

static uint8_t pagebuf[PAGE_SIZE * 256] __attribute__((aligned(PAGE_SIZE * 256)));

static void test_priv(void)
{
	report_prefix_push("privileged");
	expect_pgm_int();
	enter_pstate();
	pfmf(0, pagebuf);
	check_pgm_int_code(PGM_INT_CODE_PRIVILEGED_OPERATION);
	report_prefix_pop();
}

static void test_4k_key(void)
{
	union pfmf_r1 r1;
	union skey skey;

	report_prefix_push("4K");
	if (test_facility(169)) {
		report_skip("storage key removal facility is active");
		goto out;
	}
	r1.val = 0;
	r1.reg.sk = 1;
	r1.reg.fsc = PFMF_FSC_4K;
	r1.reg.key = 0x30;
	pfmf(r1.val, pagebuf);
	skey.val = get_storage_key(pagebuf);
	skey.val &= SKEY_ACC | SKEY_FP;
	report(skey.val == 0x30, "set storage keys");
out:
	report_prefix_pop();
}

static void test_1m_key(void)
{
	int i;
	bool rp = true;
	union pfmf_r1 r1;
	union skey skey;

	report_prefix_push("1M");
	if (test_facility(169)) {
		report_skip("storage key removal facility is active");
		goto out;
	}
	r1.val = 0;
	r1.reg.sk = 1;
	r1.reg.fsc = PFMF_FSC_1M;
	r1.reg.key = 0x30;
	pfmf(r1.val, pagebuf);
	for (i = 0; i < 256; i++) {
		skey.val = get_storage_key(pagebuf + i * PAGE_SIZE);
		skey.val &= SKEY_ACC | SKEY_FP;
		if (skey.val != 0x30) {
			rp = false;
			break;
		}
	}
	report(rp, "set storage keys");
out:
	report_prefix_pop();
}

static void test_4k_clear(void)
{
	union pfmf_r1 r1;

	r1.val = 0;
	r1.reg.cf = 1;
	r1.reg.fsc = PFMF_FSC_4K;

	report_prefix_push("4K");
	memset(pagebuf, 42, PAGE_SIZE);
	pfmf(r1.val, pagebuf);
	report(!memcmp(pagebuf, pagebuf + PAGE_SIZE, PAGE_SIZE),
	       "clear memory");
	report_prefix_pop();
}

static void test_1m_clear(void)
{
	int i;
	union pfmf_r1 r1;
	unsigned long sum = 0;

	r1.val = 0;
	r1.reg.cf = 1;
	r1.reg.fsc = PFMF_FSC_1M;

	report_prefix_push("1M");
	memset(pagebuf, 42, PAGE_SIZE * 256);
	pfmf(r1.val, pagebuf);
	for (i = 0; i < PAGE_SIZE * 256; i++)
		sum |= pagebuf[i];
	report(!sum, "clear memory");
	report_prefix_pop();
}

int main(void)
{
	bool has_edat = test_facility(8);

	report_prefix_push("pfmf");
	if (!has_edat) {
		report_skip("PFMF is not available");
		goto done;
	}

	test_priv();
	/* Force the buffer pages in */
	memset(pagebuf, 0, PAGE_SIZE * 256);

	test_4k_key();
	test_4k_clear();
	test_1m_key();
	test_1m_clear();

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