149 lines · plain
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,v210FUNC_START(check_vmx)11 PUSH_BASIC_STACK(32)12 mr r4,r313 li r3,1 # assume a bad result14 li r5,015 lvx v0,r5,r416 vcmpequd. v1,v0,v2017 vmr v2,v118 19 addi r5,r5,1620 lvx v0,r5,r421 vcmpequd. v1,v0,v2122 vand v2,v2,v123 24 addi r5,r5,1625 lvx v0,r5,r426 vcmpequd. v1,v0,v2227 vand v2,v2,v128 29 addi r5,r5,1630 lvx v0,r5,r431 vcmpequd. v1,v0,v2332 vand v2,v2,v133 34 addi r5,r5,1635 lvx v0,r5,r436 vcmpequd. v1,v0,v2437 vand v2,v2,v138 39 addi r5,r5,1640 lvx v0,r5,r441 vcmpequd. v1,v0,v2542 vand v2,v2,v143 44 addi r5,r5,1645 lvx v0,r5,r446 vcmpequd. v1,v0,v2647 vand v2,v2,v148 49 addi r5,r5,1650 lvx v0,r5,r451 vcmpequd. v1,v0,v2752 vand v2,v2,v153 54 addi r5,r5,1655 lvx v0,r5,r456 vcmpequd. v1,v0,v2857 vand v2,v2,v158 59 addi r5,r5,1660 lvx v0,r5,r461 vcmpequd. v1,v0,v2962 vand v2,v2,v163 64 addi r5,r5,1665 lvx v0,r5,r466 vcmpequd. v1,v0,v3067 vand v2,v2,v168 69 addi r5,r5,1670 lvx v0,r5,r471 vcmpequd. v1,v0,v3172 vand v2,v2,v173 74 li r5,STACK_FRAME_LOCAL(0,0)75 stvx v2,r5,sp76 ldx r0,r5,sp77 cmpdi r0,0xffffffffffffffff78 bne 1f79 li r3,0801: POP_BASIC_STACK(32)81 blr82FUNC_END(check_vmx)83 84# Safe from C85FUNC_START(test_vmx)86 # r3 holds pointer to where to put the result of fork87 # r4 holds pointer to the pid88 # v20-v31 are non-volatile89 PUSH_BASIC_STACK(512)90 std r3,STACK_FRAME_PARAM(0)(sp) # Address of varray91 std r4,STACK_FRAME_PARAM(1)(sp) # address of pid92 PUSH_VMX(STACK_FRAME_LOCAL(2,0),r4)93 94 bl load_vmx95 nop96 97 li r0,__NR_fork98 sc99 # Pass the result of fork back to the caller100 ld r9,STACK_FRAME_PARAM(1)(sp)101 std r3,0(r9)102 103 ld r3,STACK_FRAME_PARAM(0)(sp)104 bl check_vmx105 nop106 107 POP_VMX(STACK_FRAME_LOCAL(2,0),r4)108 POP_BASIC_STACK(512)109 blr110FUNC_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 that114# the VMX have been loaded with varray. Will proceed to check the validity of115# 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 *varray119 std r4,STACK_FRAME_PARAM(1)(sp) # int *threads_starting120 std r5,STACK_FRAME_PARAM(2)(sp) # int *running121 # 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_vmx125 nop126 127 sync128 # Atomic DEC129 ld r3,STACK_FRAME_PARAM(1)(sp)1301: lwarx r4,0,r3131 addi r4,r4,-1132 stwcx. r4,0,r3133 bne- 1b134 1352: ld r3,STACK_FRAME_PARAM(0)(sp)136 bl check_vmx137 nop138 cmpdi r3,0139 bne 3f140 ld r4,STACK_FRAME_PARAM(2)(sp)141 ld r5,0(r4)142 cmpwi r5,0143 bne 2b144 1453: POP_VMX(STACK_FRAME_LOCAL(4,0),r4)146 POP_BASIC_STACK(512)147 blr148FUNC_END(preempt_vmx)149