/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright (c) 2017 Red Hat Inc
 *
 * Authors:
 *  Thomas Huth <thuth@redhat.com>
 *  David Hildenbrand <david@redhat.com>
 */
#include <libcflat.h>
#include <util.h>
#include <alloc.h>
#include <vmalloc.h>
#include <asm/interrupt.h>
#include <asm/barrier.h>
#include <asm/pgtable.h>

static void test_fp(void)
{
	double a = 3.0;
	double b = 2.0;
	double c;

	asm volatile(
		"	ddb %1, %2\n"
		"	std %1, %0\n"
		: "=m" (c) : "f" (a), "m" (b));

	report(c == 1.5, "3.0/2.0 == 1.5");
}

static void test_pgm_int(void)
{
	expect_pgm_int();
	asm volatile("	.insn e,0x0000"); /* used for SW breakpoints in QEMU */
	check_pgm_int_code(PGM_INT_CODE_OPERATION);

	expect_pgm_int();
	asm volatile("	stg %0,0(%0)\n" : : "a"(-1L));
	check_pgm_int_code(PGM_INT_CODE_ADDRESSING);
}

static void test_malloc(void)
{
	int *tmp, *tmp2;

	report_prefix_push("malloc");

	report_prefix_push("ptr_0");
	tmp = malloc(sizeof(int));
	report((uintptr_t)tmp & 0xf000000000000000ul, "allocated memory");
	*tmp = 123456789;
	mb();
	report(*tmp == 123456789, "wrote allocated memory");
	report_prefix_pop();

	report_prefix_push("ptr_1");
	tmp2 = malloc(sizeof(int));
	report((uintptr_t)tmp2 & 0xf000000000000000ul,
	       "allocated memory");
	*tmp2 = 123456789;
	mb();
	report((*tmp2 == 123456789), "wrote allocated memory");
	report_prefix_pop();

	report(tmp != tmp2, "allocated memory addresses differ");

	expect_pgm_int();
	disable_dat();
	*tmp = 987654321;
	enable_dat();
	check_pgm_int_code(PGM_INT_CODE_ADDRESSING);

	free(tmp);
	free(tmp2);
	report_prefix_pop();
}

static void test_psw_mask(void)
{
	uint64_t expected_key = 0xf;
	struct psw test_psw = PSW(0, 0);

	report_prefix_push("PSW mask");
	test_psw.mask = PSW_MASK_DAT;
	report(test_psw.dat, "DAT matches expected=0x%016lx actual=0x%016lx", PSW_MASK_DAT, test_psw.mask);

	test_psw.mask = PSW_MASK_IO;
	report(test_psw.io, "IO matches expected=0x%016lx actual=0x%016lx", PSW_MASK_IO, test_psw.mask);

	test_psw.mask = PSW_MASK_EXT;
	report(test_psw.ext, "EXT matches expected=0x%016lx actual=0x%016lx", PSW_MASK_EXT, test_psw.mask);

	test_psw.mask = expected_key << (63 - 11);
	report(test_psw.key == expected_key, "PSW Key matches expected=0x%lx actual=0x%x", expected_key, test_psw.key);

	test_psw.mask = 1UL << (63 - 13);
	report(test_psw.mchk, "MCHK matches");

	test_psw.mask = PSW_MASK_WAIT;
	report(test_psw.wait, "Wait matches expected=0x%016lx actual=0x%016lx", PSW_MASK_WAIT, test_psw.mask);

	test_psw.mask = PSW_MASK_PSTATE;
	report(test_psw.pstate, "Pstate matches expected=0x%016lx actual=0x%016lx", PSW_MASK_PSTATE, test_psw.mask);

	test_psw.mask = PSW_MASK_64;
	report(test_psw.ea && test_psw.ba, "BA/EA matches expected=0x%016lx actual=0x%016lx", PSW_MASK_64, test_psw.mask);

	report_prefix_pop();
}

int main(int argc, char**argv)
{
	report_prefix_push("selftest");

	report_pass("true");
	report(argc == 3, "argc == 3");
	report(!strcmp(argv[0], "s390x/selftest.elf"), "argv[0] == PROGNAME");
	report(!strcmp(argv[1], "test"), "argv[1] == test");
	report(!strcmp(argv[2], "123"), "argv[2] == 123");

	setup_vm();

	test_fp();
	test_pgm_int();
	test_malloc();
	test_psw_mask();

	return report_summary();
}
