162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright 2015, Cyril Bur, IBM Corp. 462306a36Sopenharmony_ci */ 562306a36Sopenharmony_ci 662306a36Sopenharmony_ci#include "basic_asm.h" 762306a36Sopenharmony_ci#include "vmx_asm.h" 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci# Should be safe from C, only touches r4, r5 and v0,v1,v2 1062306a36Sopenharmony_ciFUNC_START(check_vmx) 1162306a36Sopenharmony_ci PUSH_BASIC_STACK(32) 1262306a36Sopenharmony_ci mr r4,r3 1362306a36Sopenharmony_ci li r3,1 # assume a bad result 1462306a36Sopenharmony_ci li r5,0 1562306a36Sopenharmony_ci lvx v0,r5,r4 1662306a36Sopenharmony_ci vcmpequd. v1,v0,v20 1762306a36Sopenharmony_ci vmr v2,v1 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci addi r5,r5,16 2062306a36Sopenharmony_ci lvx v0,r5,r4 2162306a36Sopenharmony_ci vcmpequd. v1,v0,v21 2262306a36Sopenharmony_ci vand v2,v2,v1 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_ci addi r5,r5,16 2562306a36Sopenharmony_ci lvx v0,r5,r4 2662306a36Sopenharmony_ci vcmpequd. v1,v0,v22 2762306a36Sopenharmony_ci vand v2,v2,v1 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ci addi r5,r5,16 3062306a36Sopenharmony_ci lvx v0,r5,r4 3162306a36Sopenharmony_ci vcmpequd. v1,v0,v23 3262306a36Sopenharmony_ci vand v2,v2,v1 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_ci addi r5,r5,16 3562306a36Sopenharmony_ci lvx v0,r5,r4 3662306a36Sopenharmony_ci vcmpequd. v1,v0,v24 3762306a36Sopenharmony_ci vand v2,v2,v1 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_ci addi r5,r5,16 4062306a36Sopenharmony_ci lvx v0,r5,r4 4162306a36Sopenharmony_ci vcmpequd. v1,v0,v25 4262306a36Sopenharmony_ci vand v2,v2,v1 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci addi r5,r5,16 4562306a36Sopenharmony_ci lvx v0,r5,r4 4662306a36Sopenharmony_ci vcmpequd. v1,v0,v26 4762306a36Sopenharmony_ci vand v2,v2,v1 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_ci addi r5,r5,16 5062306a36Sopenharmony_ci lvx v0,r5,r4 5162306a36Sopenharmony_ci vcmpequd. v1,v0,v27 5262306a36Sopenharmony_ci vand v2,v2,v1 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_ci addi r5,r5,16 5562306a36Sopenharmony_ci lvx v0,r5,r4 5662306a36Sopenharmony_ci vcmpequd. v1,v0,v28 5762306a36Sopenharmony_ci vand v2,v2,v1 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ci addi r5,r5,16 6062306a36Sopenharmony_ci lvx v0,r5,r4 6162306a36Sopenharmony_ci vcmpequd. v1,v0,v29 6262306a36Sopenharmony_ci vand v2,v2,v1 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_ci addi r5,r5,16 6562306a36Sopenharmony_ci lvx v0,r5,r4 6662306a36Sopenharmony_ci vcmpequd. v1,v0,v30 6762306a36Sopenharmony_ci vand v2,v2,v1 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ci addi r5,r5,16 7062306a36Sopenharmony_ci lvx v0,r5,r4 7162306a36Sopenharmony_ci vcmpequd. v1,v0,v31 7262306a36Sopenharmony_ci vand v2,v2,v1 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_ci li r5,STACK_FRAME_LOCAL(0,0) 7562306a36Sopenharmony_ci stvx v2,r5,sp 7662306a36Sopenharmony_ci ldx r0,r5,sp 7762306a36Sopenharmony_ci cmpdi r0,0xffffffffffffffff 7862306a36Sopenharmony_ci bne 1f 7962306a36Sopenharmony_ci li r3,0 8062306a36Sopenharmony_ci1: POP_BASIC_STACK(32) 8162306a36Sopenharmony_ci blr 8262306a36Sopenharmony_ciFUNC_END(check_vmx) 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_ci# Safe from C 8562306a36Sopenharmony_ciFUNC_START(test_vmx) 8662306a36Sopenharmony_ci # r3 holds pointer to where to put the result of fork 8762306a36Sopenharmony_ci # r4 holds pointer to the pid 8862306a36Sopenharmony_ci # v20-v31 are non-volatile 8962306a36Sopenharmony_ci PUSH_BASIC_STACK(512) 9062306a36Sopenharmony_ci std r3,STACK_FRAME_PARAM(0)(sp) # Address of varray 9162306a36Sopenharmony_ci std r4,STACK_FRAME_PARAM(1)(sp) # address of pid 9262306a36Sopenharmony_ci PUSH_VMX(STACK_FRAME_LOCAL(2,0),r4) 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_ci bl load_vmx 9562306a36Sopenharmony_ci nop 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_ci li r0,__NR_fork 9862306a36Sopenharmony_ci sc 9962306a36Sopenharmony_ci # Pass the result of fork back to the caller 10062306a36Sopenharmony_ci ld r9,STACK_FRAME_PARAM(1)(sp) 10162306a36Sopenharmony_ci std r3,0(r9) 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_ci ld r3,STACK_FRAME_PARAM(0)(sp) 10462306a36Sopenharmony_ci bl check_vmx 10562306a36Sopenharmony_ci nop 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_ci POP_VMX(STACK_FRAME_LOCAL(2,0),r4) 10862306a36Sopenharmony_ci POP_BASIC_STACK(512) 10962306a36Sopenharmony_ci blr 11062306a36Sopenharmony_ciFUNC_END(test_vmx) 11162306a36Sopenharmony_ci 11262306a36Sopenharmony_ci# int preempt_vmx(vector int *varray, int *threads_starting, int *running) 11362306a36Sopenharmony_ci# On starting will (atomically) decrement threads_starting as a signal that 11462306a36Sopenharmony_ci# the VMX have been loaded with varray. Will proceed to check the validity of 11562306a36Sopenharmony_ci# the VMX registers while running is not zero. 11662306a36Sopenharmony_ciFUNC_START(preempt_vmx) 11762306a36Sopenharmony_ci PUSH_BASIC_STACK(512) 11862306a36Sopenharmony_ci std r3,STACK_FRAME_PARAM(0)(sp) # vector int *varray 11962306a36Sopenharmony_ci std r4,STACK_FRAME_PARAM(1)(sp) # int *threads_starting 12062306a36Sopenharmony_ci std r5,STACK_FRAME_PARAM(2)(sp) # int *running 12162306a36Sopenharmony_ci # VMX need to write to 16 byte aligned addresses, skip STACK_FRAME_LOCAL(3,0) 12262306a36Sopenharmony_ci PUSH_VMX(STACK_FRAME_LOCAL(4,0),r4) 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_ci bl load_vmx 12562306a36Sopenharmony_ci nop 12662306a36Sopenharmony_ci 12762306a36Sopenharmony_ci sync 12862306a36Sopenharmony_ci # Atomic DEC 12962306a36Sopenharmony_ci ld r3,STACK_FRAME_PARAM(1)(sp) 13062306a36Sopenharmony_ci1: lwarx r4,0,r3 13162306a36Sopenharmony_ci addi r4,r4,-1 13262306a36Sopenharmony_ci stwcx. r4,0,r3 13362306a36Sopenharmony_ci bne- 1b 13462306a36Sopenharmony_ci 13562306a36Sopenharmony_ci2: ld r3,STACK_FRAME_PARAM(0)(sp) 13662306a36Sopenharmony_ci bl check_vmx 13762306a36Sopenharmony_ci nop 13862306a36Sopenharmony_ci cmpdi r3,0 13962306a36Sopenharmony_ci bne 3f 14062306a36Sopenharmony_ci ld r4,STACK_FRAME_PARAM(2)(sp) 14162306a36Sopenharmony_ci ld r5,0(r4) 14262306a36Sopenharmony_ci cmpwi r5,0 14362306a36Sopenharmony_ci bne 2b 14462306a36Sopenharmony_ci 14562306a36Sopenharmony_ci3: POP_VMX(STACK_FRAME_LOCAL(4,0),r4) 14662306a36Sopenharmony_ci POP_BASIC_STACK(512) 14762306a36Sopenharmony_ci blr 14862306a36Sopenharmony_ciFUNC_END(preempt_vmx) 149