/* SPDX-License-Identifier: GPL-2.0-only */ /* * s390x assembly library * * Copyright (c) 2019 IBM Corp. * * Authors: * Janosch Frank */ #include #include #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