1120373Smarcus/* SPDX-License-Identifier: GPL-2.0-or-later */ 2120373Smarcus/* 3120373Smarcus * Copyright 2015, Cyril Bur, IBM Corp. 4120373Smarcus */ 5120373Smarcus 6120373Smarcus#include "basic_asm.h" 7120373Smarcus#include "gpr_asm.h" 8120373Smarcus#include "fpu_asm.h" 9120373Smarcus#include "vmx_asm.h" 10120373Smarcus#include "vsx_asm.h" 11120373Smarcus 12120373Smarcus/* 13120373Smarcus * Large caveat here being that the caller cannot expect the 14120373Smarcus * signal to always be sent! The hardware can (AND WILL!) abort 15120373Smarcus * the transaction between the tbegin and the tsuspend (however 16120373Smarcus * unlikely it seems or infrequently it actually happens). 17120373Smarcus * You have been warned. 18120373Smarcus */ 19120373Smarcus/* long tm_signal_self(pid_t pid, long *gprs, double *fps, vector *vms, vector *vss); */ 20120373SmarcusFUNC_START(tm_signal_self_context_load) 21120373Smarcus PUSH_BASIC_STACK(512) 22120373Smarcus /* 23120373Smarcus * Don't strictly need to save and restore as it depends on if 24120373Smarcus * we're going to use them, however this reduces messy logic 25120373Smarcus */ 26120373Smarcus PUSH_VMX(STACK_FRAME_LOCAL(5,0),r8) 27120373Smarcus PUSH_FPU(512) 28120373Smarcus PUSH_NVREGS_BELOW_FPU(512) 29120373Smarcus std r3, STACK_FRAME_PARAM(0)(sp) /* pid */ 30120373Smarcus std r4, STACK_FRAME_PARAM(1)(sp) /* gps */ 31120373Smarcus std r5, STACK_FRAME_PARAM(2)(sp) /* fps */ 32120373Smarcus std r6, STACK_FRAME_PARAM(3)(sp) /* vms */ 33145921Sglebius std r7, STACK_FRAME_PARAM(4)(sp) /* vss */ 34145921Sglebius 35162674Spiso ld r3, STACK_FRAME_PARAM(1)(sp) 36162674Spiso cmpdi r3, 0 37145921Sglebius beq skip_gpr_lc 38162674Spiso bl load_gpr 39120373Smarcusskip_gpr_lc: 40145921Sglebius ld r3, STACK_FRAME_PARAM(2)(sp) 41145921Sglebius cmpdi r3, 0 42145921Sglebius beq skip_fpu_lc 43120373Smarcus bl load_fpu 44120373Smarcusskip_fpu_lc: 45120373Smarcus ld r3, STACK_FRAME_PARAM(3)(sp) 46120373Smarcus cmpdi r3, 0 47120373Smarcus beq skip_vmx_lc 48145921Sglebius bl load_vmx 49145921Sglebiusskip_vmx_lc: 50162674Spiso ld r3, STACK_FRAME_PARAM(4)(sp) 51145921Sglebius cmpdi r3, 0 52120373Smarcus beq skip_vsx_lc 53162674Spiso bl load_vsx 54145921Sglebiusskip_vsx_lc: 55120373Smarcus /* 56162674Spiso * Set r3 (return value) before tbegin. Use the pid as a known 57162674Spiso * 'all good' return value, zero is used to indicate a non-doomed 58162674Spiso * transaction. 59162674Spiso */ 60162674Spiso ld r3, STACK_FRAME_PARAM(0)(sp) 61162674Spiso tbegin. 62162674Spiso beq 1f 63162674Spiso tsuspend. /* Can't enter a syscall transactionally */ 64162674Spiso ld r3, STACK_FRAME_PARAM(1)(sp) 65162674Spiso cmpdi r3, 0 66162674Spiso beq skip_gpr_lt 67162674Spiso /* Get the second half of the array */ 68162674Spiso addi r3, r3, 8 * 18 69162674Spiso bl load_gpr 70162674Spisoskip_gpr_lt: 71162674Spiso ld r3, STACK_FRAME_PARAM(2)(sp) 72162674Spiso cmpdi r3, 0 73162674Spiso beq skip_fpu_lt 74162674Spiso /* Get the second half of the array */ 75162674Spiso addi r3, r3, 8 * 18 76162674Spiso bl load_fpu 77162674Spisoskip_fpu_lt: 78162674Spiso ld r3, STACK_FRAME_PARAM(3)(sp) 79162674Spiso cmpdi r3, 0 80162674Spiso beq skip_vmx_lt 81162674Spiso /* Get the second half of the array */ 82162674Spiso addi r3, r3, 16 * 12 83162674Spiso bl load_vmx 84162674Spisoskip_vmx_lt: 85162674Spiso ld r3, STACK_FRAME_PARAM(4)(sp) 86162674Spiso cmpdi r3, 0 87162674Spiso beq skip_vsx_lt 88162674Spiso /* Get the second half of the array */ 89162674Spiso addi r3, r3, 16 * 12 90162674Spiso bl load_vsx 91162674Spisoskip_vsx_lt: 92162674Spiso li r0, 37 /* sys_kill */ 93162674Spiso ld r3, STACK_FRAME_PARAM(0)(sp) /* pid */ 94162674Spiso li r4, 10 /* SIGUSR1 */ 95162674Spiso sc /* Taking the signal will doom the transaction */ 96162674Spiso tabort. 0 97162674Spiso tresume. /* Be super sure we abort */ 98162674Spiso /* 99162674Spiso * This will cause us to resume doomed transaction and cause 100162674Spiso * hardware to cleanup, we'll end up at 1: anything between 101162674Spiso * tresume. and 1: shouldn't ever run. 102162674Spiso */ 103162674Spiso li r3, 0 104162674Spiso 1: 105162674Spiso POP_VMX(STACK_FRAME_LOCAL(5,0),r4) 106162674Spiso POP_FPU(512) 107162674Spiso POP_NVREGS_BELOW_FPU(512) 108162674Spiso POP_BASIC_STACK(512) 109162674Spiso blr 110162674SpisoFUNC_END(tm_signal_self_context_load) 111162674Spiso