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