support.S (302408) | support.S (319202) |
---|---|
1/*- 2 * Copyright (c) 2014 Andrew Turner 3 * Copyright (c) 2014-2015 The FreeBSD Foundation 4 * All rights reserved. 5 * 6 * Portions of this software were developed by Andrew Turner 7 * under sponsorship from the FreeBSD Foundation 8 * --- 16 unchanged lines hidden (view full) --- 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 * 30 */ 31 32#include <machine/asm.h> | 1/*- 2 * Copyright (c) 2014 Andrew Turner 3 * Copyright (c) 2014-2015 The FreeBSD Foundation 4 * All rights reserved. 5 * 6 * Portions of this software were developed by Andrew Turner 7 * under sponsorship from the FreeBSD Foundation 8 * --- 16 unchanged lines hidden (view full) --- 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 * 30 */ 31 32#include <machine/asm.h> |
33__FBSDID("$FreeBSD: stable/11/sys/arm64/arm64/support.S 297615 2016-04-06 14:08:10Z andrew $"); | 33__FBSDID("$FreeBSD: stable/11/sys/arm64/arm64/support.S 319202 2017-05-30 12:26:36Z andrew $"); |
34 35#include <machine/setjmp.h> 36#include <machine/param.h> 37#include <machine/vmparam.h> 38 39#include "assym.s" 40 41/* 42 * One of the fu* or su* functions failed, return -1. 43 */ 44ENTRY(fsu_fault) 45 SET_FAULT_HANDLER(xzr, x1) /* Reset the handler function */ | 34 35#include <machine/setjmp.h> 36#include <machine/param.h> 37#include <machine/vmparam.h> 38 39#include "assym.s" 40 41/* 42 * One of the fu* or su* functions failed, return -1. 43 */ 44ENTRY(fsu_fault) 45 SET_FAULT_HANDLER(xzr, x1) /* Reset the handler function */ |
46 EXIT_USER_ACCESS_CHECK(w0, x1) |
|
46fsu_fault_nopcb: 47 mov x0, #-1 48 ret 49END(fsu_fault) 50 51/* 52 * int casueword32(volatile uint32_t *, uint32_t, uint32_t *, uint32_t) 53 */ 54ENTRY(casueword32) 55 ldr x4, =(VM_MAXUSER_ADDRESS-3) 56 cmp x0, x4 57 b.cs fsu_fault_nopcb 58 adr x6, fsu_fault /* Load the fault handler */ 59 SET_FAULT_HANDLER(x6, x4) /* And set it */ | 47fsu_fault_nopcb: 48 mov x0, #-1 49 ret 50END(fsu_fault) 51 52/* 53 * int casueword32(volatile uint32_t *, uint32_t, uint32_t *, uint32_t) 54 */ 55ENTRY(casueword32) 56 ldr x4, =(VM_MAXUSER_ADDRESS-3) 57 cmp x0, x4 58 b.cs fsu_fault_nopcb 59 adr x6, fsu_fault /* Load the fault handler */ 60 SET_FAULT_HANDLER(x6, x4) /* And set it */ |
61 ENTER_USER_ACCESS(w6, x4) |
|
601: ldxr w4, [x0] /* Load-exclusive the data */ 61 cmp w4, w1 /* Compare */ 62 b.ne 2f /* Not equal, exit */ 63 stxr w5, w3, [x0] /* Store the new data */ 64 cbnz w5, 1b /* Retry on failure */ | 621: ldxr w4, [x0] /* Load-exclusive the data */ 63 cmp w4, w1 /* Compare */ 64 b.ne 2f /* Not equal, exit */ 65 stxr w5, w3, [x0] /* Store the new data */ 66 cbnz w5, 1b /* Retry on failure */ |
67 EXIT_USER_ACCESS(w6) |
|
652: SET_FAULT_HANDLER(xzr, x5) /* Reset the fault handler */ 66 str w4, [x2] /* Store the read data */ 67 mov x0, #0 /* Success */ 68 ret /* Return */ 69END(casueword32) 70 71/* 72 * int casueword(volatile u_long *, u_long, u_long *, u_long) 73 */ 74ENTRY(casueword) 75 ldr x4, =(VM_MAXUSER_ADDRESS-7) 76 cmp x0, x4 77 b.cs fsu_fault_nopcb 78 adr x6, fsu_fault /* Load the fault handler */ 79 SET_FAULT_HANDLER(x6, x4) /* And set it */ | 682: SET_FAULT_HANDLER(xzr, x5) /* Reset the fault handler */ 69 str w4, [x2] /* Store the read data */ 70 mov x0, #0 /* Success */ 71 ret /* Return */ 72END(casueword32) 73 74/* 75 * int casueword(volatile u_long *, u_long, u_long *, u_long) 76 */ 77ENTRY(casueword) 78 ldr x4, =(VM_MAXUSER_ADDRESS-7) 79 cmp x0, x4 80 b.cs fsu_fault_nopcb 81 adr x6, fsu_fault /* Load the fault handler */ 82 SET_FAULT_HANDLER(x6, x4) /* And set it */ |
83 ENTER_USER_ACCESS(w6, x4) |
|
801: ldxr x4, [x0] /* Load-exclusive the data */ 81 cmp x4, x1 /* Compare */ 82 b.ne 2f /* Not equal, exit */ 83 stxr w5, x3, [x0] /* Store the new data */ 84 cbnz w5, 1b /* Retry on failure */ | 841: ldxr x4, [x0] /* Load-exclusive the data */ 85 cmp x4, x1 /* Compare */ 86 b.ne 2f /* Not equal, exit */ 87 stxr w5, x3, [x0] /* Store the new data */ 88 cbnz w5, 1b /* Retry on failure */ |
89 EXIT_USER_ACCESS(w6) |
|
852: SET_FAULT_HANDLER(xzr, x5) /* Reset the fault handler */ 86 str x4, [x2] /* Store the read data */ 87 mov x0, #0 /* Success */ 88 ret /* Return */ 89END(casueword) 90 91/* 92 * int fubyte(volatile const void *) 93 */ 94ENTRY(fubyte) 95 ldr x1, =VM_MAXUSER_ADDRESS 96 cmp x0, x1 97 b.cs fsu_fault_nopcb 98 adr x6, fsu_fault /* Load the fault handler */ 99 SET_FAULT_HANDLER(x6, x1) /* And set it */ | 902: SET_FAULT_HANDLER(xzr, x5) /* Reset the fault handler */ 91 str x4, [x2] /* Store the read data */ 92 mov x0, #0 /* Success */ 93 ret /* Return */ 94END(casueword) 95 96/* 97 * int fubyte(volatile const void *) 98 */ 99ENTRY(fubyte) 100 ldr x1, =VM_MAXUSER_ADDRESS 101 cmp x0, x1 102 b.cs fsu_fault_nopcb 103 adr x6, fsu_fault /* Load the fault handler */ 104 SET_FAULT_HANDLER(x6, x1) /* And set it */ |
100 ldrb w0, [x0] /* Try loading the data */ | 105 ldtrb w0, [x0] /* Try loading the data */ |
101 SET_FAULT_HANDLER(xzr, x1) /* Reset the fault handler */ 102 ret /* Return */ 103END(fubyte) 104 105/* 106 * int fuword(volatile const void *) 107 */ 108ENTRY(fuword16) 109 ldr x1, =(VM_MAXUSER_ADDRESS-1) 110 cmp x0, x1 111 b.cs fsu_fault_nopcb 112 adr x6, fsu_fault /* Load the fault handler */ 113 SET_FAULT_HANDLER(x6, x1) /* And set it */ | 106 SET_FAULT_HANDLER(xzr, x1) /* Reset the fault handler */ 107 ret /* Return */ 108END(fubyte) 109 110/* 111 * int fuword(volatile const void *) 112 */ 113ENTRY(fuword16) 114 ldr x1, =(VM_MAXUSER_ADDRESS-1) 115 cmp x0, x1 116 b.cs fsu_fault_nopcb 117 adr x6, fsu_fault /* Load the fault handler */ 118 SET_FAULT_HANDLER(x6, x1) /* And set it */ |
114 ldrh w0, [x0] /* Try loading the data */ | 119 ldtrh w0, [x0] /* Try loading the data */ |
115 SET_FAULT_HANDLER(xzr, x1) /* Reset the fault handler */ 116 ret /* Return */ 117END(fuword16) 118 119/* 120 * int32_t fueword32(volatile const void *, int32_t *) 121 */ 122ENTRY(fueword32) 123 ldr x2, =(VM_MAXUSER_ADDRESS-3) 124 cmp x0, x2 125 b.cs fsu_fault_nopcb 126 adr x6, fsu_fault /* Load the fault handler */ 127 SET_FAULT_HANDLER(x6, x2) /* And set it */ | 120 SET_FAULT_HANDLER(xzr, x1) /* Reset the fault handler */ 121 ret /* Return */ 122END(fuword16) 123 124/* 125 * int32_t fueword32(volatile const void *, int32_t *) 126 */ 127ENTRY(fueword32) 128 ldr x2, =(VM_MAXUSER_ADDRESS-3) 129 cmp x0, x2 130 b.cs fsu_fault_nopcb 131 adr x6, fsu_fault /* Load the fault handler */ 132 SET_FAULT_HANDLER(x6, x2) /* And set it */ |
128 ldr w0, [x0] /* Try loading the data */ | 133 ldtr w0, [x0] /* Try loading the data */ |
129 SET_FAULT_HANDLER(xzr, x2) /* Reset the fault handler */ 130 str w0, [x1] /* Save the data in kernel space */ 131 mov w0, #0 /* Success */ 132 ret /* Return */ 133END(fueword32) 134 135/* 136 * long fueword(volatile const void *, int64_t *) 137 * int64_t fueword64(volatile const void *, int64_t *) 138 */ 139ENTRY(fueword) 140EENTRY(fueword64) 141 ldr x2, =(VM_MAXUSER_ADDRESS-7) 142 cmp x0, x2 143 b.cs fsu_fault_nopcb 144 adr x6, fsu_fault /* Load the fault handler */ 145 SET_FAULT_HANDLER(x6, x2) /* And set it */ | 134 SET_FAULT_HANDLER(xzr, x2) /* Reset the fault handler */ 135 str w0, [x1] /* Save the data in kernel space */ 136 mov w0, #0 /* Success */ 137 ret /* Return */ 138END(fueword32) 139 140/* 141 * long fueword(volatile const void *, int64_t *) 142 * int64_t fueword64(volatile const void *, int64_t *) 143 */ 144ENTRY(fueword) 145EENTRY(fueword64) 146 ldr x2, =(VM_MAXUSER_ADDRESS-7) 147 cmp x0, x2 148 b.cs fsu_fault_nopcb 149 adr x6, fsu_fault /* Load the fault handler */ 150 SET_FAULT_HANDLER(x6, x2) /* And set it */ |
146 ldr x0, [x0] /* Try loading the data */ | 151 ldtr x0, [x0] /* Try loading the data */ |
147 SET_FAULT_HANDLER(xzr, x2) /* Reset the fault handler */ 148 str x0, [x1] /* Save the data in kernel space */ 149 mov x0, #0 /* Success */ 150 ret /* Return */ 151EEND(fueword64) 152END(fueword) 153 154/* 155 * int subyte(volatile void *, int) 156 */ 157ENTRY(subyte) 158 ldr x2, =VM_MAXUSER_ADDRESS 159 cmp x0, x2 160 b.cs fsu_fault_nopcb 161 adr x6, fsu_fault /* Load the fault handler */ 162 SET_FAULT_HANDLER(x6, x2) /* And set it */ | 152 SET_FAULT_HANDLER(xzr, x2) /* Reset the fault handler */ 153 str x0, [x1] /* Save the data in kernel space */ 154 mov x0, #0 /* Success */ 155 ret /* Return */ 156EEND(fueword64) 157END(fueword) 158 159/* 160 * int subyte(volatile void *, int) 161 */ 162ENTRY(subyte) 163 ldr x2, =VM_MAXUSER_ADDRESS 164 cmp x0, x2 165 b.cs fsu_fault_nopcb 166 adr x6, fsu_fault /* Load the fault handler */ 167 SET_FAULT_HANDLER(x6, x2) /* And set it */ |
163 strb w1, [x0] /* Try storing the data */ | 168 sttrb w1, [x0] /* Try storing the data */ |
164 SET_FAULT_HANDLER(xzr, x2) /* Reset the fault handler */ 165 mov x0, #0 /* Success */ 166 ret /* Return */ 167END(subyte) 168 169/* 170 * int suword16(volatile void *, int) 171 */ 172ENTRY(suword16) 173 ldr x2, =(VM_MAXUSER_ADDRESS-1) 174 cmp x0, x2 175 b.cs fsu_fault_nopcb 176 adr x6, fsu_fault /* Load the fault handler */ 177 SET_FAULT_HANDLER(x6, x2) /* And set it */ | 169 SET_FAULT_HANDLER(xzr, x2) /* Reset the fault handler */ 170 mov x0, #0 /* Success */ 171 ret /* Return */ 172END(subyte) 173 174/* 175 * int suword16(volatile void *, int) 176 */ 177ENTRY(suword16) 178 ldr x2, =(VM_MAXUSER_ADDRESS-1) 179 cmp x0, x2 180 b.cs fsu_fault_nopcb 181 adr x6, fsu_fault /* Load the fault handler */ 182 SET_FAULT_HANDLER(x6, x2) /* And set it */ |
178 strh w1, [x0] /* Try storing the data */ | 183 sttrh w1, [x0] /* Try storing the data */ |
179 SET_FAULT_HANDLER(xzr, x2) /* Reset the fault handler */ 180 mov x0, #0 /* Success */ 181 ret /* Return */ 182END(suword16) 183 184/* 185 * int suword32(volatile void *, int) 186 */ 187ENTRY(suword32) 188 ldr x2, =(VM_MAXUSER_ADDRESS-3) 189 cmp x0, x2 190 b.cs fsu_fault_nopcb 191 adr x6, fsu_fault /* Load the fault handler */ 192 SET_FAULT_HANDLER(x6, x2) /* And set it */ | 184 SET_FAULT_HANDLER(xzr, x2) /* Reset the fault handler */ 185 mov x0, #0 /* Success */ 186 ret /* Return */ 187END(suword16) 188 189/* 190 * int suword32(volatile void *, int) 191 */ 192ENTRY(suword32) 193 ldr x2, =(VM_MAXUSER_ADDRESS-3) 194 cmp x0, x2 195 b.cs fsu_fault_nopcb 196 adr x6, fsu_fault /* Load the fault handler */ 197 SET_FAULT_HANDLER(x6, x2) /* And set it */ |
193 str w1, [x0] /* Try storing the data */ | 198 sttr w1, [x0] /* Try storing the data */ |
194 SET_FAULT_HANDLER(xzr, x2) /* Reset the fault handler */ 195 mov x0, #0 /* Success */ 196 ret /* Return */ 197END(suword32) 198 199/* 200 * int suword(volatile void *, long) 201 */ 202ENTRY(suword) 203EENTRY(suword64) 204 ldr x2, =(VM_MAXUSER_ADDRESS-7) 205 cmp x0, x2 206 b.cs fsu_fault_nopcb 207 adr x6, fsu_fault /* Load the fault handler */ 208 SET_FAULT_HANDLER(x6, x2) /* And set it */ | 199 SET_FAULT_HANDLER(xzr, x2) /* Reset the fault handler */ 200 mov x0, #0 /* Success */ 201 ret /* Return */ 202END(suword32) 203 204/* 205 * int suword(volatile void *, long) 206 */ 207ENTRY(suword) 208EENTRY(suword64) 209 ldr x2, =(VM_MAXUSER_ADDRESS-7) 210 cmp x0, x2 211 b.cs fsu_fault_nopcb 212 adr x6, fsu_fault /* Load the fault handler */ 213 SET_FAULT_HANDLER(x6, x2) /* And set it */ |
209 str x1, [x0] /* Try storing the data */ | 214 sttr x1, [x0] /* Try storing the data */ |
210 SET_FAULT_HANDLER(xzr, x2) /* Reset the fault handler */ 211 mov x0, #0 /* Success */ 212 ret /* Return */ 213EEND(suword64) 214END(suword) 215 216/* 217 * fuswintr and suswintr are just like fusword and susword except that if 218 * the page is not in memory or would cause a trap, then we return an error. 219 * The important thing is to prevent sleep() and switch(). 220 */ 221 222/* 223 * Special handler so the trap code knows not to sleep. 224 */ 225ENTRY(fsu_intr_fault) 226 SET_FAULT_HANDLER(xzr, x1) /* Reset the handler function */ | 215 SET_FAULT_HANDLER(xzr, x2) /* Reset the fault handler */ 216 mov x0, #0 /* Success */ 217 ret /* Return */ 218EEND(suword64) 219END(suword) 220 221/* 222 * fuswintr and suswintr are just like fusword and susword except that if 223 * the page is not in memory or would cause a trap, then we return an error. 224 * The important thing is to prevent sleep() and switch(). 225 */ 226 227/* 228 * Special handler so the trap code knows not to sleep. 229 */ 230ENTRY(fsu_intr_fault) 231 SET_FAULT_HANDLER(xzr, x1) /* Reset the handler function */ |
232 EXIT_USER_ACCESS_CHECK(w0, x1) |
|
227 mov x0, #-1 228 ret 229END(fsu_fault) 230 231/* 232 * int fuswintr(void *) 233 */ 234ENTRY(fuswintr) 235 ldr x1, =(VM_MAXUSER_ADDRESS-3) 236 cmp x0, x1 237 b.cs fsu_fault_nopcb 238 adr x6, fsu_intr_fault /* Load the fault handler */ 239 SET_FAULT_HANDLER(x6, x1) /* And set it */ | 233 mov x0, #-1 234 ret 235END(fsu_fault) 236 237/* 238 * int fuswintr(void *) 239 */ 240ENTRY(fuswintr) 241 ldr x1, =(VM_MAXUSER_ADDRESS-3) 242 cmp x0, x1 243 b.cs fsu_fault_nopcb 244 adr x6, fsu_intr_fault /* Load the fault handler */ 245 SET_FAULT_HANDLER(x6, x1) /* And set it */ |
240 ldr w0, [x0] /* Try loading the data */ | 246 ldtr w0, [x0] /* Try loading the data */ |
241 SET_FAULT_HANDLER(xzr, x1) /* Reset the fault handler */ 242 ret /* Return */ 243END(fuswintr) 244 245/* 246 * int suswintr(void *base, int word) 247 */ 248ENTRY(suswintr) 249 ldr x2, =(VM_MAXUSER_ADDRESS-3) 250 cmp x0, x2 251 b.cs fsu_fault_nopcb 252 adr x6, fsu_intr_fault /* Load the fault handler */ 253 SET_FAULT_HANDLER(x6, x2) /* And set it */ | 247 SET_FAULT_HANDLER(xzr, x1) /* Reset the fault handler */ 248 ret /* Return */ 249END(fuswintr) 250 251/* 252 * int suswintr(void *base, int word) 253 */ 254ENTRY(suswintr) 255 ldr x2, =(VM_MAXUSER_ADDRESS-3) 256 cmp x0, x2 257 b.cs fsu_fault_nopcb 258 adr x6, fsu_intr_fault /* Load the fault handler */ 259 SET_FAULT_HANDLER(x6, x2) /* And set it */ |
254 str w1, [x0] /* Try storing the data */ | 260 sttr w1, [x0] /* Try storing the data */ |
255 SET_FAULT_HANDLER(xzr, x2) /* Reset the fault handler */ 256 mov x0, #0 /* Success */ 257 ret /* Return */ 258END(suswintr) 259 260ENTRY(setjmp) 261 /* Store the stack pointer */ 262 mov x8, sp --- 67 unchanged lines hidden --- | 261 SET_FAULT_HANDLER(xzr, x2) /* Reset the fault handler */ 262 mov x0, #0 /* Success */ 263 ret /* Return */ 264END(suswintr) 265 266ENTRY(setjmp) 267 /* Store the stack pointer */ 268 mov x8, sp --- 67 unchanged lines hidden --- |