1/* SPDX-License-Identifier: GPL-2.0-or-later */ 2/* 3 * Copyright 2015, Cyril Bur, IBM Corp. 4 */ 5 6#include "basic_asm.h" 7#include "vmx_asm.h" 8 9# Should be safe from C, only touches r4, r5 and v0,v1,v2 10FUNC_START(check_vmx) 11 PUSH_BASIC_STACK(32) 12 mr r4,r3 13 li r3,1 # assume a bad result 14 li r5,0 15 lvx v0,r5,r4 16 vcmpequd. v1,v0,v20 17 vmr v2,v1 18 19 addi r5,r5,16 20 lvx v0,r5,r4 21 vcmpequd. v1,v0,v21 22 vand v2,v2,v1 23 24 addi r5,r5,16 25 lvx v0,r5,r4 26 vcmpequd. v1,v0,v22 27 vand v2,v2,v1 28 29 addi r5,r5,16 30 lvx v0,r5,r4 31 vcmpequd. v1,v0,v23 32 vand v2,v2,v1 33 34 addi r5,r5,16 35 lvx v0,r5,r4 36 vcmpequd. v1,v0,v24 37 vand v2,v2,v1 38 39 addi r5,r5,16 40 lvx v0,r5,r4 41 vcmpequd. v1,v0,v25 42 vand v2,v2,v1 43 44 addi r5,r5,16 45 lvx v0,r5,r4 46 vcmpequd. v1,v0,v26 47 vand v2,v2,v1 48 49 addi r5,r5,16 50 lvx v0,r5,r4 51 vcmpequd. v1,v0,v27 52 vand v2,v2,v1 53 54 addi r5,r5,16 55 lvx v0,r5,r4 56 vcmpequd. v1,v0,v28 57 vand v2,v2,v1 58 59 addi r5,r5,16 60 lvx v0,r5,r4 61 vcmpequd. v1,v0,v29 62 vand v2,v2,v1 63 64 addi r5,r5,16 65 lvx v0,r5,r4 66 vcmpequd. v1,v0,v30 67 vand v2,v2,v1 68 69 addi r5,r5,16 70 lvx v0,r5,r4 71 vcmpequd. v1,v0,v31 72 vand v2,v2,v1 73 74 li r5,STACK_FRAME_LOCAL(0,0) 75 stvx v2,r5,sp 76 ldx r0,r5,sp 77 cmpdi r0,0xffffffffffffffff 78 bne 1f 79 li r3,0 801: POP_BASIC_STACK(32) 81 blr 82FUNC_END(check_vmx) 83 84# Safe from C 85FUNC_START(test_vmx) 86 # r3 holds pointer to where to put the result of fork 87 # r4 holds pointer to the pid 88 # v20-v31 are non-volatile 89 PUSH_BASIC_STACK(512) 90 std r3,STACK_FRAME_PARAM(0)(sp) # Address of varray 91 std r4,STACK_FRAME_PARAM(1)(sp) # address of pid 92 PUSH_VMX(STACK_FRAME_LOCAL(2,0),r4) 93 94 bl load_vmx 95 nop 96 97 li r0,__NR_fork 98 sc 99 # Pass the result of fork back to the caller 100 ld r9,STACK_FRAME_PARAM(1)(sp) 101 std r3,0(r9) 102 103 ld r3,STACK_FRAME_PARAM(0)(sp) 104 bl check_vmx 105 nop 106 107 POP_VMX(STACK_FRAME_LOCAL(2,0),r4) 108 POP_BASIC_STACK(512) 109 blr 110FUNC_END(test_vmx) 111 112# int preempt_vmx(vector int *varray, int *threads_starting, int *running) 113# On starting will (atomically) decrement threads_starting as a signal that 114# the VMX have been loaded with varray. Will proceed to check the validity of 115# the VMX registers while running is not zero. 116FUNC_START(preempt_vmx) 117 PUSH_BASIC_STACK(512) 118 std r3,STACK_FRAME_PARAM(0)(sp) # vector int *varray 119 std r4,STACK_FRAME_PARAM(1)(sp) # int *threads_starting 120 std r5,STACK_FRAME_PARAM(2)(sp) # int *running 121 # VMX need to write to 16 byte aligned addresses, skip STACK_FRAME_LOCAL(3,0) 122 PUSH_VMX(STACK_FRAME_LOCAL(4,0),r4) 123 124 bl load_vmx 125 nop 126 127 sync 128 # Atomic DEC 129 ld r3,STACK_FRAME_PARAM(1)(sp) 1301: lwarx r4,0,r3 131 addi r4,r4,-1 132 stwcx. r4,0,r3 133 bne- 1b 134 1352: ld r3,STACK_FRAME_PARAM(0)(sp) 136 bl check_vmx 137 nop 138 cmpdi r3,0 139 bne 3f 140 ld r4,STACK_FRAME_PARAM(2)(sp) 141 ld r5,0(r4) 142 cmpwi r5,0 143 bne 2b 144 1453: POP_VMX(STACK_FRAME_LOCAL(4,0),r4) 146 POP_BASIC_STACK(512) 147 blr 148FUNC_END(preempt_vmx) 149