/* SPDX-License-Identifier: GPL-2.0-or-later */
/* 
 * HPMC (High Priority Machine Check) handler.
 *
 * Copyright (C) 1999 Philipp Rumpf <prumpf@tux.org>
 * Copyright (C) 1999 Hewlett-Packard (Frank Rowand)
 * Copyright (C) 2000 Hewlett-Packard (John Marvin)
 */


/*
 * This HPMC handler retrieves the HPMC pim data, resets IO and
 * returns to the default trap handler with code set to 1 (HPMC).
 * The default trap handler calls handle interruption, which
 * does a stack and register dump. This at least allows kernel
 * developers to get back to C code in virtual mode, where they
 * have the option to examine and print values from memory that
 * would help in debugging an HPMC caused by a software bug.
 *
 * There is more to do here:
 *
 *      1) On MP systems we need to synchronize processors
 *         before calling pdc/iodc.
 *      2) We should be checking the system state and not
 *         returning to the fault handler if things are really
 *         bad.
 *
 */

	.level		1.1

#include <asm/assembly.h>
#include <asm/pdc.h>
#include <asm/psw.h>

#include <linux/linkage.h>
#include <linux/init.h>

	/*
	 * stack for os_hpmc, the HPMC handler.
	 * buffer for IODC procedures (for the HPMC handler).
	 *
	 * IODC requires 7K byte stack.  That leaves 1K byte for os_hpmc.
	 */

	__PAGE_ALIGNED_BSS
	.align 4096
hpmc_stack:
	.block 16384

#define HPMC_IODC_BUF_SIZE 0x8000

	__PAGE_ALIGNED_BSS
	.align 4096
hpmc_iodc_buf:
	.block HPMC_IODC_BUF_SIZE

	.section .bss
	.align 8
hpmc_raddr:
	.block 128

#define HPMC_PIM_DATA_SIZE 896 /* Enough to hold all architected 2.0 state */

	.section .bss
	.align 8
ENTRY(hpmc_pim_data)
	.block HPMC_PIM_DATA_SIZE
END(hpmc_pim_data)

	.text

	.import intr_save, code
	.align 16
ENTRY(os_hpmc)
.os_hpmc:

	/*
	 * registers modified:
	 *
	 *   Using callee saves registers without saving them.  The
	 *   original values are in the pim dump if we need them.
	 *
	 *   r2   (rp)  return pointer
	 *   r3   address of PDCE_PROC
	 *   r4   scratch
	 *   r5   scratch
	 *   r23  (arg3) procedure arg
	 *   r24  (arg2) procedure arg
	 *   r25  (arg1) procedure arg
	 *   r26  (arg0) procedure arg
	 *   r30  (sp)   stack pointer
	 *
	 * registers read:
	 *
	 *   r26  contains address of PDCE_PROC on entry
	 *   r28  (ret0) return value from procedure
	 */

	copy    arg0, %r3       /* save address of PDCE_PROC */

	/*
	 *  disable nested HPMCs
	 *
	 * Increment os_hpmc checksum to invalidate it.
	 * Do this before turning the PSW M bit off.
	 */

	mfctl   %cr14, %r4
	ldw     52(%r4),%r5
	addi    1,%r5,%r5
	stw     %r5,52(%r4)

	/* MP_FIXME: synchronize all processors. */

	/* Setup stack pointer. */

	load32	PA(hpmc_stack),sp
	
	ldo     128(sp),sp /* leave room for arguments */

	/*
	 * Most PDC routines require that the M bit be off.
	 * So turn on the Q bit and turn off the M bit.
	 */

	ldi     PSW_SM_Q,%r4                   /* PSW Q on, PSW M off */
	mtctl   %r4,ipsw
	mtctl   %r0,pcsq
	mtctl   %r0,pcsq
	load32	PA(os_hpmc_1),%r4
	mtctl   %r4,pcoq
	ldo     4(%r4),%r4
	mtctl   %r4,pcoq
	rfi
	nop

os_hpmc_1:

	/* Call PDC_PIM to get HPMC pim info */

	/*
	 * Note that on some newer boxes, PDC_PIM must be called
	 * before PDC_IO if you want IO to be reset. PDC_PIM sets
	 * a flag that PDC_IO examines.
	 */

	ldo     PDC_PIM(%r0), arg0
	ldo     PDC_PIM_HPMC(%r0),arg1          /* Transfer HPMC data */
	load32	PA(hpmc_raddr),arg2
	load32	PA(hpmc_pim_data),arg3
	load32	HPMC_PIM_DATA_SIZE,%r4
	stw     %r4,-52(sp)

	ldil    L%PA(os_hpmc_2), rp
	bv      (r3)                            /* call pdce_proc */
	ldo     R%PA(os_hpmc_2)(rp), rp

os_hpmc_2:
	comib,<>  0,ret0, os_hpmc_fail

	/* Reset IO by calling the hversion dependent PDC_IO routine */

	ldo     PDC_IO(%r0),arg0
	ldo     0(%r0),arg1                     /* log IO errors */
	ldo     0(%r0),arg2                     /* reserved */
	ldo     0(%r0),arg3                     /* reserved */
	stw     %r0,-52(sp)                     /* reserved */

	ldil    L%PA(os_hpmc_3),rp
	bv      (%r3)                           /* call pdce_proc */
	ldo     R%PA(os_hpmc_3)(rp),rp

os_hpmc_3:

	/* FIXME? Check for errors from PDC_IO (-1 might be OK) */

	/*
	 * Initialize the IODC console device (HPA,SPA, path etc.
	 * are stored on page 0.
	 */

	/*
	 * Load IODC into hpmc_iodc_buf by calling PDC_IODC.
	 * Note that PDC_IODC handles flushing the appropriate
	 * data and instruction cache lines.
	 */

	ldo     PDC_IODC(%r0),arg0
	ldo     PDC_IODC_READ(%r0),arg1
	load32	PA(hpmc_raddr),arg2
	ldw     BOOT_CONSOLE_HPA_OFFSET(%r0),arg3 /* console hpa */
	ldo     PDC_IODC_RI_INIT(%r0),%r4
	stw     %r4,-52(sp)
	load32	PA(hpmc_iodc_buf),%r4
	stw     %r4,-56(sp)
	load32	HPMC_IODC_BUF_SIZE,%r4
	stw     %r4,-60(sp)

	ldil    L%PA(os_hpmc_4),rp
	bv      (%r3)                            /* call pdce_proc */
	ldo     R%PA(os_hpmc_4)(rp),rp

os_hpmc_4:
	comib,<>  0,ret0,os_hpmc_fail

	/* Call the entry init (just loaded by PDC_IODC) */

	ldw     BOOT_CONSOLE_HPA_OFFSET(%r0),arg0  /* console hpa */
	ldo     ENTRY_INIT_MOD_DEV(%r0), arg1
	ldw     BOOT_CONSOLE_SPA_OFFSET(%r0),arg2  /* console spa */
	depi    0,31,11,arg2                       /* clear bits 21-31    */
	ldo     BOOT_CONSOLE_PATH_OFFSET(%r0),arg3 /* console path */
	load32	PA(hpmc_raddr),%r4
	stw     %r4, -52(sp)
	stw     %r0, -56(sp)                    /* HV                  */
	stw     %r0, -60(sp)                    /* HV                  */
	stw     %r0, -64(sp)                    /* HV                  */
	stw     %r0, -68(sp)                    /* lang, must be zero  */

	load32	PA(hpmc_iodc_buf),%r5
	ldil    L%PA(os_hpmc_5),rp
	bv      (%r5)
	ldo     R%PA(os_hpmc_5)(rp),rp

os_hpmc_5:
	comib,<>  0,ret0,os_hpmc_fail

	/* Prepare to call intr_save */

	/*
	 * Load kernel page directory (load into user also, since
	 * we don't intend to ever return to user land anyway)
	 */

	load32		PA(swapper_pg_dir),%r4
	mtctl		%r4,%cr24	/* Initialize kernel root pointer */
	mtctl		%r4,%cr25	/* Initialize user root pointer */

	/* Clear sr4-sr7 */

	mtsp	%r0, %sr4
	mtsp	%r0, %sr5
	mtsp	%r0, %sr6
	mtsp	%r0, %sr7

	tovirt_r1 %r30      /* make sp virtual */

	rsm     PSW_SM_Q,%r0           /* Clear Q bit */
	ldi     1,%r8       /* Set trap code to "1" for HPMC */
	load32	PA(intr_save),%r1
	be      0(%sr7,%r1)
	nop

os_hpmc_fail:

	/*
	 * Reset the system
	 *
	 * Some systems may lockup from a broadcast reset, so try the
	 * hversion PDC_BROADCAST_RESET() first.
	 * MP_FIXME: reset all processors if more than one central bus.
	 */

	/* PDC_BROADCAST_RESET() */

	ldo     PDC_BROADCAST_RESET(%r0),arg0
	ldo     0(%r0),arg1                     /* do reset */

	ldil    L%PA(os_hpmc_6),rp
	bv      (%r3)                           /* call pdce_proc */
	ldo     R%PA(os_hpmc_6)(rp),rp

os_hpmc_6:

	/*
	 * possible return values:
	 *  -1  non-existent procedure
	 *  -2  non-existent option
	 *  -16 unaligned stack
	 *
	 * If call returned, do a broadcast reset.
	 */

	ldil    L%0xfffc0000,%r4        /* IO_BROADCAST */
	ldo     5(%r0),%r5
	stw     %r5,48(%r4)             /*  CMD_RESET to IO_COMMAND offset */

	b .
	nop
	.align 16	/* make function length multiple of 16 bytes */
.os_hpmc_end:


	__INITRODATA
.globl os_hpmc_size
	.align 4
	.type   os_hpmc_size, @object
	.size   os_hpmc_size, 4
os_hpmc_size:
	.word .os_hpmc_end-.os_hpmc
