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