0001
0002
0003
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)