/*
 * s390x interrupt handling
 *
 * 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/interrupt.h>
#include <asm/barrier.h>
#include <sclp.h>

static bool pgm_int_expected;
static bool ext_int_expected;
static struct lowcore *lc;

void expect_pgm_int(void)
{
	pgm_int_expected = true;
	lc->pgm_int_code = 0;
	mb();
}

void expect_ext_int(void)
{
	ext_int_expected = true;
	lc->ext_int_code = 0;
	mb();
}

uint16_t clear_pgm_int(void)
{
	uint16_t code;

	mb();
	code = lc->pgm_int_code;
	lc->pgm_int_code = 0;
	pgm_int_expected = false;
	return code;
}

void check_pgm_int_code(uint16_t code)
{
	mb();
	report(code == lc->pgm_int_code,
	       "Program interrupt: expected(%d) == received(%d)", code,
	       lc->pgm_int_code);
}

static void fixup_pgm_int(void)
{
	switch (lc->pgm_int_code) {
	case PGM_INT_CODE_PRIVILEGED_OPERATION:
		/* Normal operation is in supervisor state, so this exception
		 * was produced intentionally and we should return to the
		 * supervisor state.
		 */
		lc->pgm_old_psw.mask &= ~PSW_MASK_PSTATE;
		break;
	case PGM_INT_CODE_PROTECTION:
		/* Handling for iep.c test case. */
		if (lc->trans_exc_id & 0x80UL && lc->trans_exc_id & 0x04UL &&
		    !(lc->trans_exc_id & 0x08UL))
			lc->pgm_old_psw.addr = lc->sw_int_grs[14];
		break;
	case PGM_INT_CODE_SEGMENT_TRANSLATION:
	case PGM_INT_CODE_PAGE_TRANSLATION:
	case PGM_INT_CODE_TRACE_TABLE:
	case PGM_INT_CODE_AFX_TRANSLATION:
	case PGM_INT_CODE_ASX_TRANSLATION:
	case PGM_INT_CODE_LX_TRANSLATION:
	case PGM_INT_CODE_EX_TRANSLATION:
	case PGM_INT_CODE_PRIMARY_AUTHORITY:
	case PGM_INT_CODE_SECONDARY_AUTHORITY:
	case PGM_INT_CODE_LFX_TRANSLATION:
	case PGM_INT_CODE_LSX_TRANSLATION:
	case PGM_INT_CODE_ALEN_TRANSLATION:
	case PGM_INT_CODE_ALE_SEQUENCE:
	case PGM_INT_CODE_ASTE_VALIDITY:
	case PGM_INT_CODE_ASTE_SEQUENCE:
	case PGM_INT_CODE_EXTENDED_AUTHORITY:
	case PGM_INT_CODE_LSTE_SEQUENCE:
	case PGM_INT_CODE_ASTE_INSTANCE:
	case PGM_INT_CODE_STACK_FULL:
	case PGM_INT_CODE_STACK_EMPTY:
	case PGM_INT_CODE_STACK_SPECIFICATION:
	case PGM_INT_CODE_STACK_TYPE:
	case PGM_INT_CODE_STACK_OPERATION:
	case PGM_INT_CODE_ASCE_TYPE:
	case PGM_INT_CODE_REGION_FIRST_TRANS:
	case PGM_INT_CODE_REGION_SECOND_TRANS:
	case PGM_INT_CODE_REGION_THIRD_TRANS:
	case PGM_INT_CODE_PER:
	case PGM_INT_CODE_CRYPTO_OPERATION:
		/* The interrupt was nullified, the old PSW points at the
		 * responsible instruction. Forward the PSW so we don't loop.
		 */
		lc->pgm_old_psw.addr += lc->pgm_int_id;
	}
	/* suppressed/terminated/completed point already at the next address */
}

void handle_pgm_int(void)
{
	if (!pgm_int_expected) {
		/* Force sclp_busy to false, otherwise we will loop forever */
		sclp_handle_ext();
		report_abort("Unexpected program interrupt: %d on cpu %d at %#lx, ilen %d\n",
			     lc->pgm_int_code, stap(), lc->pgm_old_psw.addr,
			     lc->pgm_int_id);
	}

	pgm_int_expected = false;
	fixup_pgm_int();
}

void handle_ext_int(void)
{
	if (!ext_int_expected &&
	    lc->ext_int_code != EXT_IRQ_SERVICE_SIG) {
		report_abort("Unexpected external call interrupt (code %#x): on cpu %d at %#lx",
			     lc->ext_int_code, stap(), lc->ext_old_psw.addr);
		return;
	}

	if (lc->ext_int_code == EXT_IRQ_SERVICE_SIG) {
		lc->sw_int_crs[0] &= ~(1UL << 9);
		sclp_handle_ext();
	} else {
		ext_int_expected = false;
	}

	if (!(lc->sw_int_crs[0] & CR0_EXTM_MASK))
		lc->ext_old_psw.mask &= ~PSW_MASK_EXT;
}

void handle_mcck_int(void)
{
	report_abort("Unexpected machine check interrupt: on cpu %d at %#lx",
		     stap(), lc->mcck_old_psw.addr);
}

void handle_io_int(void)
{
	report_abort("Unexpected io interrupt: on cpu %d at %#lx",
		     stap(), lc->io_old_psw.addr);
}

void handle_svc_int(void)
{
	report_abort("Unexpected supervisor call interrupt: on cpu %d at %#lx",
		     stap(), lc->svc_old_psw.addr);
}
