blob: 9155b0443597f09ddb3cb746182cc6a78551c5e6 [file] [log] [blame]
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* s390x assembly library
*
* Copyright (c) 2019 IBM Corp.
*
* Authors:
* Janosch Frank <frankja@linux.ibm.com>
*/
#include <asm/asm-offsets.h>
#include <asm/sigp.h>
#include "macros.S"
/*
* load_reset calling convention:
* %r2 subcode (0 or 1)
*/
.globl diag308_load_reset
diag308_load_reset:
SAVE_REGS_STACK
/* Backup current PSW mask, as we have to restore it on success */
epsw %r0, %r1
st %r0, GEN_LC_SW_INT_PSW
st %r1, GEN_LC_SW_INT_PSW + 4
/* Load reset psw mask (short psw, 64 bit) */
lg %r0, reset_psw
/* Load the success label address */
larl %r1, 0f
/* Or it to the mask */
ogr %r0, %r1
/* Store it at the reset PSW location (real 0x0) */
stg %r0, 0
stg %r15, GEN_LC_SW_INT_GRS + 15 * 8
/* Do the reset */
diag %r0,%r2,0x308
/* Failure path */
xgr %r2, %r2
br %r14
/* Success path */
/* load a cr0 that has the AFP control bit which enables all FPRs */
0: larl %r1, initial_cr0
lctlg %c0, %c0, 0(%r1)
lg %r15, GEN_LC_SW_INT_GRS + 15 * 8
RESTORE_REGS_STACK
lhi %r2, 1
larl %r0, 1f
stg %r0, GEN_LC_SW_INT_PSW + 8
lpswe GEN_LC_SW_INT_PSW
1: br %r14
/* Sets up general registers and cr0 when a new cpu is brought online. */
.globl smp_cpu_setup_state
smp_cpu_setup_state:
xgr %r1, %r1
lmg %r0, %r15, GEN_LC_SW_INT_GRS
lctlg %c0, %c0, GEN_LC_SW_INT_CRS
/* We should only go once through cpu setup and not for every restart */
stg %r14, GEN_LC_RESTART_NEW_PSW + 8
larl %r14, 0f
lpswe GEN_LC_SW_INT_PSW
/* If the function returns, just loop here */
0: j 0
/*
* sie64a calling convention:
* %r2 pointer to sie control block
* %r3 guest register save area
*/
.globl sie64a
sie64a:
# Save host grs, fprs, fpc
stmg %r0,%r14,SIE_SAVEAREA_HOST_GRS(%r3) # save kernel registers
.irp i, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
std \i, \i * 8 + SIE_SAVEAREA_HOST_FPRS(%r3)
.endr
stfpc SIE_SAVEAREA_HOST_FPC(%r3)
stctg %c1, %c1, SIE_SAVEAREA_HOST_ASCE(%r3)
lctlg %c1, %c1, SIE_SAVEAREA_GUEST_ASCE(%r3)
# Store scb and save_area pointer into stack frame
stg %r2,__SF_SIE_CONTROL(%r15) # save control block pointer
stg %r3,__SF_SIE_SAVEAREA(%r15) # save guest register save area
.globl sie_entry_gregs
sie_entry_gregs:
# Load guest's gprs, fprs and fpc
.irp i, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
ld \i, \i * 8 + SIE_SAVEAREA_GUEST_FPRS(%r3)
.endr
lfpc SIE_SAVEAREA_GUEST_FPC(%r3)
lmg %r0,%r13,SIE_SAVEAREA_GUEST_GRS(%r3)
# Move scb ptr into r14 for the sie instruction
lg %r14,__SF_SIE_CONTROL(%r15)
.globl sie_entry
sie_entry:
sie 0(%r14)
nopr 7
nopr 7
nopr 7
.globl sie_exit
sie_exit:
# Load guest register save area
lg %r14,__SF_SIE_SAVEAREA(%r15)
# Restore the host asce
lctlg %c1, %c1, SIE_SAVEAREA_HOST_ASCE(%r14)
# Store guest's gprs, fprs and fpc
stmg %r0,%r13,SIE_SAVEAREA_GUEST_GRS(%r14) # save guest gprs 0-13
.irp i, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
std \i, \i * 8 + SIE_SAVEAREA_GUEST_FPRS(%r14)
.endr
stfpc SIE_SAVEAREA_GUEST_FPC(%r14)
# Restore host's gprs, fprs and fpc
.irp i, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
ld \i, \i * 8 + SIE_SAVEAREA_HOST_FPRS(%r14)
.endr
lfpc SIE_SAVEAREA_HOST_FPC(%r14)
lmg %r0,%r14,SIE_SAVEAREA_HOST_GRS(%r14) # restore kernel registers
.globl sie_exit_gregs
sie_exit_gregs:
br %r14
.align 8
reset_psw:
.quad 0x0008000180000000