/* SPDX-License-Identifier: GPL-2.0 */
/*
* Code that needs to run below 2 GB .
*
* Copyright IBM Corp . 2019
*/
#include <linux/linkage.h>
#include <asm/asm-extable.h>
#include <asm/errno.h>
#include <asm/sigp.h>
.section .amode31.text,"ax"
/*
* Simplified version of expoline thunk . The normal thunks can not be used here ,
* because they might be more than 2 GB away , and not reachable by the relative
* branch . No comdat , exrl , etc . optimizations used here , because it only
* affects a few functions that are not performance - relevant .
*/
.macro BR_EX_AMODE31_r14
exrl 0 ,0 f
j .
0 : br %r14
.endm
/*
* int _ diag14_amode31 ( unsigned long rx , unsigned long ry1 , unsigned long subcode )
*/
SYM_FUNC_START(_diag14_amode31)
lgr %r1,%r2
lgr %r2,%r3
lgr %r3,%r4
lhi %r5,-EIO
sam31
diag %r1,%r2,0 x14
.Ldiag14_ex:
ipm %r5
srl %r5,28
.Ldiag14_fault:
sam64
lgfr %r2,%r5
BR_EX_AMODE31_r14
EX_TABLE_AMODE31(.Ldiag14_ex, .Ldiag14_fault)
SYM_FUNC_END(_diag14_amode31)
/*
* int _ diag210_amode31 ( struct diag210 * addr )
*/
SYM_FUNC_START(_diag210_amode31)
lgr %r1,%r2
lhi %r2,-1
sam31
diag %r1,%r0,0 x210
.Ldiag210_ex:
ipm %r2
srl %r2,28
.Ldiag210_fault:
sam64
lgfr %r2,%r2
BR_EX_AMODE31_r14
EX_TABLE_AMODE31(.Ldiag210_ex, .Ldiag210_fault)
SYM_FUNC_END(_diag210_amode31)
/*
* int diag8c ( struct diag8c * addr , struct ccw_dev_id * devno , size_t len )
*/
SYM_FUNC_START(_diag8c_amode31)
llgf %r3,0 (%r3)
sam31
diag %r2,%r4,0 x8c
.Ldiag8c_ex:
sam64
lgfr %r2,%r3
BR_EX_AMODE31_r14
EX_TABLE_AMODE31(.Ldiag8c_ex, .Ldiag8c_ex)
SYM_FUNC_END(_diag8c_amode31)
/*
* int _ diag26c_amode31 ( void * req , void * resp , enum diag26c_sc subcode )
*/
SYM_FUNC_START(_diag26c_amode31)
lghi %r5,-EOPNOTSUPP
sam31
diag %r2,%r4,0 x26c
.Ldiag26c_ex:
sam64
lgfr %r2,%r5
BR_EX_AMODE31_r14
EX_TABLE_AMODE31(.Ldiag26c_ex, .Ldiag26c_ex)
SYM_FUNC_END(_diag26c_amode31)
/*
* void _ diag0c_amode31 ( unsigned long rx )
*/
SYM_FUNC_START(_diag0c_amode31)
sam31
diag %r2,%r2,0 x0c
sam64
BR_EX_AMODE31_r14
SYM_FUNC_END(_diag0c_amode31)
/*
* void _ diag308_reset_amode31 ( void )
*
* Calls diag 308 subcode 1 and continues execution
*/
SYM_FUNC_START(_diag308_reset_amode31)
larl %r4,ctlregs # Save control registers
stctg %c0,%c15,0 (%r4)
lg %r2,0 (%r4) # Disable lowcore protection
nilh %r2,0 xefff
larl %r4,ctlreg0
stg %r2,0 (%r4)
lctlg %c0,%c0,0 (%r4)
larl %r4,fpctl # Floating point control register
stfpc 0 (%r4)
larl %r4,prefix # Save prefix register
stpx 0 (%r4)
larl %r4,prefix_zero # Set prefix register to 0
spx 0 (%r4)
larl %r4,continue_psw # Save PSW flags
epsw %r2,%r3
stm %r2,%r3,0 (%r4)
larl %r4,.Lrestart_part2 # Setup restart PSW at absolute 0
larl %r3,restart_diag308_psw
og %r4,0 (%r3) # Save PSW
lghi %r3,0
sturg %r4,%r3 # Use sturg, because of large pages
lghi %r1,1
lghi %r0,0
diag %r0,%r1,0 x308
.Lrestart_part2:
lhi %r0,0 # Load r0 with zero
lhi %r1,2 # Use mode 2 = ESAME (dump)
sigp %r1,%r0,SIGP_SET_ARCHITECTURE # Switch to ESAME mode
sam64 # Switch to 64 bit addressing mode
larl %r4,ctlregs # Restore control registers
lctlg %c0,%c15,0 (%r4)
larl %r4,fpctl # Restore floating point ctl register
lfpc 0 (%r4)
larl %r4,prefix # Restore prefix register
spx 0 (%r4)
larl %r4,continue_psw # Restore PSW flags
larl %r2,.Lcontinue
stg %r2,8 (%r4)
lpswe 0 (%r4)
.Lcontinue:
BR_EX_AMODE31_r14
SYM_FUNC_END(_diag308_reset_amode31)
.section .amode31.data ,"aw" ,@progbits
.balign 8
SYM_DATA_LOCAL(restart_diag308_psw, .long 0 x00080000,0 x80000000)
SYM_DATA_LOCAL(continue_psw, .quad 0 ,0 )
SYM_DATA_LOCAL(ctlreg0, .quad 0 )
SYM_DATA_LOCAL(ctlregs, .fill 16 ,8 ,0 )
SYM_DATA_LOCAL(fpctl, .long 0 )
SYM_DATA_LOCAL(prefix, .long 0 )
SYM_DATA_LOCAL(prefix_zero, .long 0 )
Messung V0.5 in Prozent C=94 H=78 G=86
¤ Dauer der Verarbeitung: 0.12 Sekunden
(vorverarbeitet am 2026-09-28)
¤
*© Formatika GbR, Deutschland