xref: /openbmc/linux/tools/testing/selftests/powerpc/tm/tm-signal.S (revision 75bf465f0bc33e9b776a46d6a1b9b990f5fb7c37)
1*2874c5fdSThomas Gleixner/* SPDX-License-Identifier: GPL-2.0-or-later */
2f10d4424SCyril Bur/*
3f10d4424SCyril Bur * Copyright 2015, Cyril Bur, IBM Corp.
4f10d4424SCyril Bur */
5f10d4424SCyril Bur
615ec3997SSimon Guo#include "basic_asm.h"
715ec3997SSimon Guo#include "gpr_asm.h"
815ec3997SSimon Guo#include "fpu_asm.h"
915ec3997SSimon Guo#include "vmx_asm.h"
1015ec3997SSimon Guo#include "vsx_asm.h"
11f10d4424SCyril Bur
12f10d4424SCyril Bur/*
13f10d4424SCyril Bur * Large caveat here being that the caller cannot expect the
14f10d4424SCyril Bur * signal to always be sent! The hardware can (AND WILL!) abort
15f10d4424SCyril Bur * the transaction between the tbegin and the tsuspend (however
16f10d4424SCyril Bur * unlikely it seems or infrequently it actually happens).
17f10d4424SCyril Bur * You have been warned.
18f10d4424SCyril Bur */
19f10d4424SCyril Bur/* long tm_signal_self(pid_t pid, long *gprs, double *fps, vector *vms, vector *vss); */
20f10d4424SCyril BurFUNC_START(tm_signal_self_context_load)
21f10d4424SCyril Bur	PUSH_BASIC_STACK(512)
22f10d4424SCyril Bur	/*
23f10d4424SCyril Bur	 * Don't strictly need to save and restore as it depends on if
24f10d4424SCyril Bur	 * we're going to use them, however this reduces messy logic
25f10d4424SCyril Bur	 */
26f10d4424SCyril Bur	PUSH_VMX(STACK_FRAME_LOCAL(5,0),r8)
27f10d4424SCyril Bur	PUSH_FPU(512)
28f10d4424SCyril Bur	PUSH_NVREGS_BELOW_FPU(512)
29f10d4424SCyril Bur	std r3, STACK_FRAME_PARAM(0)(sp) /* pid */
30f10d4424SCyril Bur	std r4, STACK_FRAME_PARAM(1)(sp) /* gps */
31f10d4424SCyril Bur	std r5, STACK_FRAME_PARAM(2)(sp) /* fps */
32f10d4424SCyril Bur	std r6, STACK_FRAME_PARAM(3)(sp) /* vms */
33f10d4424SCyril Bur	std r7, STACK_FRAME_PARAM(4)(sp) /* vss */
34f10d4424SCyril Bur
35f10d4424SCyril Bur	ld r3, STACK_FRAME_PARAM(1)(sp)
36f10d4424SCyril Bur	cmpdi r3, 0
37f10d4424SCyril Bur	beq skip_gpr_lc
38f10d4424SCyril Bur	bl load_gpr
39f10d4424SCyril Burskip_gpr_lc:
40f10d4424SCyril Bur	ld r3, STACK_FRAME_PARAM(2)(sp)
41f10d4424SCyril Bur	cmpdi	r3, 0
42f10d4424SCyril Bur	beq	skip_fpu_lc
43f10d4424SCyril Bur	bl load_fpu
44f10d4424SCyril Burskip_fpu_lc:
45f10d4424SCyril Bur	ld r3, STACK_FRAME_PARAM(3)(sp)
46f10d4424SCyril Bur	cmpdi r3, 0
47f10d4424SCyril Bur	beq	skip_vmx_lc
48f10d4424SCyril Bur	bl load_vmx
49f10d4424SCyril Burskip_vmx_lc:
50f10d4424SCyril Bur	ld r3, STACK_FRAME_PARAM(4)(sp)
51f10d4424SCyril Bur	cmpdi	r3, 0
52f10d4424SCyril Bur	beq	skip_vsx_lc
53f10d4424SCyril Bur	bl load_vsx
54f10d4424SCyril Burskip_vsx_lc:
55f10d4424SCyril Bur	/*
56f10d4424SCyril Bur	 * Set r3 (return value) before tbegin. Use the pid as a known
57f10d4424SCyril Bur	 * 'all good' return value, zero is used to indicate a non-doomed
58f10d4424SCyril Bur	 * transaction.
59f10d4424SCyril Bur	 */
60f10d4424SCyril Bur	ld	r3, STACK_FRAME_PARAM(0)(sp)
61f10d4424SCyril Bur	tbegin.
62f10d4424SCyril Bur	beq	1f
63f10d4424SCyril Bur	tsuspend. /* Can't enter a syscall transactionally */
64f10d4424SCyril Bur	ld	r3, STACK_FRAME_PARAM(1)(sp)
65f10d4424SCyril Bur	cmpdi	r3, 0
66f10d4424SCyril Bur	beq skip_gpr_lt
67f10d4424SCyril Bur	/* Get the second half of the array */
68f10d4424SCyril Bur	addi	r3, r3, 8 * 18
69f10d4424SCyril Bur	bl load_gpr
70f10d4424SCyril Burskip_gpr_lt:
71f10d4424SCyril Bur	ld r3, STACK_FRAME_PARAM(2)(sp)
72f10d4424SCyril Bur	cmpdi	r3, 0
73f10d4424SCyril Bur	beq	skip_fpu_lt
74f10d4424SCyril Bur	/* Get the second half of the array */
75f10d4424SCyril Bur	addi	r3, r3, 8 * 18
76f10d4424SCyril Bur	bl load_fpu
77f10d4424SCyril Burskip_fpu_lt:
78f10d4424SCyril Bur	ld r3, STACK_FRAME_PARAM(3)(sp)
79f10d4424SCyril Bur	cmpdi r3, 0
80f10d4424SCyril Bur	beq	skip_vmx_lt
81f10d4424SCyril Bur	/* Get the second half of the array */
82f10d4424SCyril Bur	addi	r3, r3, 16 * 12
83f10d4424SCyril Bur	bl load_vmx
84f10d4424SCyril Burskip_vmx_lt:
85f10d4424SCyril Bur	ld r3, STACK_FRAME_PARAM(4)(sp)
86f10d4424SCyril Bur	cmpdi	r3, 0
87f10d4424SCyril Bur	beq	skip_vsx_lt
88f10d4424SCyril Bur	/* Get the second half of the array */
89f10d4424SCyril Bur	addi	r3, r3, 16 * 12
90f10d4424SCyril Bur	bl load_vsx
91f10d4424SCyril Burskip_vsx_lt:
92f10d4424SCyril Bur	li	r0, 37 /* sys_kill */
93f10d4424SCyril Bur	ld r3, STACK_FRAME_PARAM(0)(sp) /* pid */
94f10d4424SCyril Bur	li r4, 10 /* SIGUSR1 */
95f10d4424SCyril Bur	sc /* Taking the signal will doom the transaction */
96f10d4424SCyril Bur	tabort. 0
97f10d4424SCyril Bur	tresume. /* Be super sure we abort */
98f10d4424SCyril Bur	/*
99f10d4424SCyril Bur	 * This will cause us to resume doomed transaction and cause
100f10d4424SCyril Bur	 * hardware to cleanup, we'll end up at 1: anything between
101f10d4424SCyril Bur	 * tresume. and 1: shouldn't ever run.
102f10d4424SCyril Bur	 */
103f10d4424SCyril Bur	li r3, 0
104f10d4424SCyril Bur	1:
105f10d4424SCyril Bur	POP_VMX(STACK_FRAME_LOCAL(5,0),r4)
106f10d4424SCyril Bur	POP_FPU(512)
107f10d4424SCyril Bur	POP_NVREGS_BELOW_FPU(512)
108f10d4424SCyril Bur	POP_BASIC_STACK(512)
109f10d4424SCyril Bur	blr
110f10d4424SCyril BurFUNC_END(tm_signal_self_context_load)
111