Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-or-later */
0002 /*
0003  * Copyright 2015, Cyril Bur, IBM Corp.
0004  */
0005 
0006 #include "basic_asm.h"
0007 #include "vmx_asm.h"
0008 
0009 # Should be safe from C, only touches r4, r5 and v0,v1,v2
0010 FUNC_START(check_vmx)
0011     PUSH_BASIC_STACK(32)
0012     mr r4,r3
0013     li  r3,1 # assume a bad result
0014     li  r5,0
0015     lvx v0,r5,r4
0016     vcmpequd.   v1,v0,v20
0017     vmr v2,v1
0018 
0019     addi    r5,r5,16
0020     lvx v0,r5,r4
0021     vcmpequd.   v1,v0,v21
0022     vand    v2,v2,v1
0023 
0024     addi    r5,r5,16
0025     lvx v0,r5,r4
0026     vcmpequd.   v1,v0,v22
0027     vand    v2,v2,v1
0028 
0029     addi    r5,r5,16
0030     lvx v0,r5,r4
0031     vcmpequd.   v1,v0,v23
0032     vand    v2,v2,v1
0033 
0034     addi    r5,r5,16
0035     lvx v0,r5,r4
0036     vcmpequd.   v1,v0,v24
0037     vand    v2,v2,v1
0038 
0039     addi    r5,r5,16
0040     lvx v0,r5,r4
0041     vcmpequd.   v1,v0,v25
0042     vand    v2,v2,v1
0043 
0044     addi    r5,r5,16
0045     lvx v0,r5,r4
0046     vcmpequd.   v1,v0,v26
0047     vand    v2,v2,v1
0048 
0049     addi    r5,r5,16
0050     lvx v0,r5,r4
0051     vcmpequd.   v1,v0,v27
0052     vand    v2,v2,v1
0053 
0054     addi    r5,r5,16
0055     lvx v0,r5,r4
0056     vcmpequd.   v1,v0,v28
0057     vand    v2,v2,v1
0058 
0059     addi    r5,r5,16
0060     lvx v0,r5,r4
0061     vcmpequd.   v1,v0,v29
0062     vand    v2,v2,v1
0063 
0064     addi    r5,r5,16
0065     lvx v0,r5,r4
0066     vcmpequd.   v1,v0,v30
0067     vand    v2,v2,v1
0068 
0069     addi    r5,r5,16
0070     lvx v0,r5,r4
0071     vcmpequd.   v1,v0,v31
0072     vand    v2,v2,v1
0073 
0074     li  r5,STACK_FRAME_LOCAL(0,0)
0075     stvx    v2,r5,sp
0076     ldx r0,r5,sp
0077     cmpdi   r0,0xffffffffffffffff
0078     bne 1f
0079     li  r3,0
0080 1:  POP_BASIC_STACK(32)
0081     blr
0082 FUNC_END(check_vmx)
0083 
0084 # Safe from C
0085 FUNC_START(test_vmx)
0086     # r3 holds pointer to where to put the result of fork
0087     # r4 holds pointer to the pid
0088     # v20-v31 are non-volatile
0089     PUSH_BASIC_STACK(512)
0090     std r3,STACK_FRAME_PARAM(0)(sp) # Address of varray
0091     std r4,STACK_FRAME_PARAM(1)(sp) # address of pid
0092     PUSH_VMX(STACK_FRAME_LOCAL(2,0),r4)
0093 
0094     bl load_vmx
0095     nop
0096 
0097     li  r0,__NR_fork
0098     sc
0099     # Pass the result of fork back to the caller
0100     ld  r9,STACK_FRAME_PARAM(1)(sp)
0101     std r3,0(r9)
0102 
0103     ld r3,STACK_FRAME_PARAM(0)(sp)
0104     bl check_vmx
0105     nop
0106 
0107     POP_VMX(STACK_FRAME_LOCAL(2,0),r4)
0108     POP_BASIC_STACK(512)
0109     blr
0110 FUNC_END(test_vmx)
0111 
0112 # int preempt_vmx(vector int *varray, int *threads_starting, int *running)
0113 # On starting will (atomically) decrement threads_starting as a signal that
0114 # the VMX have been loaded with varray. Will proceed to check the validity of
0115 # the VMX registers while running is not zero.
0116 FUNC_START(preempt_vmx)
0117     PUSH_BASIC_STACK(512)
0118     std r3,STACK_FRAME_PARAM(0)(sp) # vector int *varray
0119     std r4,STACK_FRAME_PARAM(1)(sp) # int *threads_starting
0120     std r5,STACK_FRAME_PARAM(2)(sp) # int *running
0121     # VMX need to write to 16 byte aligned addresses, skip STACK_FRAME_LOCAL(3,0)
0122     PUSH_VMX(STACK_FRAME_LOCAL(4,0),r4)
0123 
0124     bl load_vmx
0125     nop
0126 
0127     sync
0128     # Atomic DEC
0129     ld r3,STACK_FRAME_PARAM(1)(sp)
0130 1:  lwarx r4,0,r3
0131     addi r4,r4,-1
0132     stwcx. r4,0,r3
0133     bne- 1b
0134 
0135 2:  ld r3,STACK_FRAME_PARAM(0)(sp)
0136     bl check_vmx
0137     nop
0138     cmpdi r3,0
0139     bne 3f
0140     ld r4,STACK_FRAME_PARAM(2)(sp)
0141     ld r5,0(r4)
0142     cmpwi r5,0
0143     bne 2b
0144 
0145 3:  POP_VMX(STACK_FRAME_LOCAL(4,0),r4)
0146     POP_BASIC_STACK(512)
0147     blr
0148 FUNC_END(preempt_vmx)