1 // SPDX-License-Identifier: GPL-2.0-only 1 // SPDX-License-Identifier: GPL-2.0-only 2 // Copyright (C) 2015-2019 ARM Limited. 2 // Copyright (C) 2015-2019 ARM Limited. 3 // Original author: Dave Martin <Dave.Martin@ar 3 // Original author: Dave Martin <Dave.Martin@arm.com> 4 // 4 // 5 // Simple Scalable Vector Extension context sw 5 // Simple Scalable Vector Extension context switch test 6 // Repeatedly writes unique test patterns into 6 // Repeatedly writes unique test patterns into each SVE register 7 // and reads them back to verify integrity. 7 // and reads them back to verify integrity. 8 // 8 // 9 // for x in `seq 1 NR_CPUS`; do sve-test & pid 9 // for x in `seq 1 NR_CPUS`; do sve-test & pids=$pids\ $! ; done 10 // (leave it running for as long as you want.. 10 // (leave it running for as long as you want...) 11 // kill $pids 11 // kill $pids 12 12 13 #include <asm/unistd.h> 13 #include <asm/unistd.h> 14 #include "assembler.h" 14 #include "assembler.h" 15 #include "asm-offsets.h" 15 #include "asm-offsets.h" 16 #include "sme-inst.h" 16 #include "sme-inst.h" 17 17 18 #define NZR 32 18 #define NZR 32 19 #define NPR 16 19 #define NPR 16 20 #define MAXVL_B (2048 / 8) 20 #define MAXVL_B (2048 / 8) 21 21 22 .arch_extension sve 22 .arch_extension sve 23 23 24 .macro _sve_ldr_v zt, xn 24 .macro _sve_ldr_v zt, xn 25 ldr z\zt, [x\xn] 25 ldr z\zt, [x\xn] 26 .endm 26 .endm 27 27 28 .macro _sve_str_v zt, xn 28 .macro _sve_str_v zt, xn 29 str z\zt, [x\xn] 29 str z\zt, [x\xn] 30 .endm 30 .endm 31 31 32 .macro _sve_ldr_p pt, xn 32 .macro _sve_ldr_p pt, xn 33 ldr p\pt, [x\xn] 33 ldr p\pt, [x\xn] 34 .endm 34 .endm 35 35 36 .macro _sve_str_p pt, xn 36 .macro _sve_str_p pt, xn 37 str p\pt, [x\xn] 37 str p\pt, [x\xn] 38 .endm 38 .endm 39 39 40 // Generate accessor functions to read/write p 40 // Generate accessor functions to read/write programmatically selected 41 // SVE registers. 41 // SVE registers. 42 // x0 is the register index to access 42 // x0 is the register index to access 43 // x1 is the memory address to read from (getz 43 // x1 is the memory address to read from (getz,setp) or store to (setz,setp) 44 // All clobber x0-x2 44 // All clobber x0-x2 45 define_accessor setz, NZR, _sve_ldr_v 45 define_accessor setz, NZR, _sve_ldr_v 46 define_accessor getz, NZR, _sve_str_v 46 define_accessor getz, NZR, _sve_str_v 47 define_accessor setp, NPR, _sve_ldr_p 47 define_accessor setp, NPR, _sve_ldr_p 48 define_accessor getp, NPR, _sve_str_p 48 define_accessor getp, NPR, _sve_str_p 49 49 50 // Declare some storate space to shadow the SV 50 // Declare some storate space to shadow the SVE register contents: 51 .pushsection .text 51 .pushsection .text 52 .data 52 .data 53 .align 4 53 .align 4 54 zref: 54 zref: 55 .space MAXVL_B * NZR 55 .space MAXVL_B * NZR 56 pref: 56 pref: 57 .space MAXVL_B / 8 * NPR 57 .space MAXVL_B / 8 * NPR 58 ffrref: 58 ffrref: 59 .space MAXVL_B / 8 59 .space MAXVL_B / 8 60 scratch: 60 scratch: 61 .space MAXVL_B 61 .space MAXVL_B 62 .popsection 62 .popsection 63 63 64 // Generate a test pattern for storage in SVE 64 // Generate a test pattern for storage in SVE registers 65 // x0: pid (16 bits) 65 // x0: pid (16 bits) 66 // x1: register number (6 bits) 66 // x1: register number (6 bits) 67 // x2: generation (4 bits) 67 // x2: generation (4 bits) 68 68 69 // These values are used to constuct a 32-bit 69 // These values are used to constuct a 32-bit pattern that is repeated in the 70 // scratch buffer as many times as will fit: 70 // scratch buffer as many times as will fit: 71 // bits 31:28 generation number (increments 71 // bits 31:28 generation number (increments once per test_loop) 72 // bits 27:22 32-bit lane index 72 // bits 27:22 32-bit lane index 73 // bits 21:16 register number 73 // bits 21:16 register number 74 // bits 15: 0 pid 74 // bits 15: 0 pid 75 75 76 function pattern 76 function pattern 77 orr w1, w0, w1, lsl #16 77 orr w1, w0, w1, lsl #16 78 orr w2, w1, w2, lsl #28 78 orr w2, w1, w2, lsl #28 79 79 80 ldr x0, =scratch 80 ldr x0, =scratch 81 mov w1, #MAXVL_B / 4 81 mov w1, #MAXVL_B / 4 82 82 83 0: str w2, [x0], #4 83 0: str w2, [x0], #4 84 add w2, w2, #(1 << 22) 84 add w2, w2, #(1 << 22) 85 subs w1, w1, #1 85 subs w1, w1, #1 86 bne 0b 86 bne 0b 87 87 88 ret 88 ret 89 endfunction 89 endfunction 90 90 91 // Get the address of shadow data for SVE Z-re 91 // Get the address of shadow data for SVE Z-register Z<xn> 92 .macro _adrz xd, xn, nrtmp 92 .macro _adrz xd, xn, nrtmp 93 ldr \xd, =zref 93 ldr \xd, =zref 94 rdvl x\nrtmp, #1 94 rdvl x\nrtmp, #1 95 madd \xd, x\nrtmp, \xn, \xd 95 madd \xd, x\nrtmp, \xn, \xd 96 .endm 96 .endm 97 97 98 // Get the address of shadow data for SVE P-re 98 // Get the address of shadow data for SVE P-register P<xn - NZR> 99 .macro _adrp xd, xn, nrtmp 99 .macro _adrp xd, xn, nrtmp 100 ldr \xd, =pref 100 ldr \xd, =pref 101 rdvl x\nrtmp, #1 101 rdvl x\nrtmp, #1 102 lsr x\nrtmp, x\nrtmp, #3 102 lsr x\nrtmp, x\nrtmp, #3 103 sub \xn, \xn, #NZR 103 sub \xn, \xn, #NZR 104 madd \xd, x\nrtmp, \xn, \xd 104 madd \xd, x\nrtmp, \xn, \xd 105 .endm 105 .endm 106 106 107 // Set up test pattern in a SVE Z-register 107 // Set up test pattern in a SVE Z-register 108 // x0: pid 108 // x0: pid 109 // x1: register number 109 // x1: register number 110 // x2: generation 110 // x2: generation 111 function setup_zreg 111 function setup_zreg 112 mov x4, x30 112 mov x4, x30 113 113 114 mov x6, x1 114 mov x6, x1 115 bl pattern 115 bl pattern 116 _adrz x0, x6, 2 116 _adrz x0, x6, 2 117 mov x5, x0 117 mov x5, x0 118 ldr x1, =scratch 118 ldr x1, =scratch 119 bl memcpy 119 bl memcpy 120 120 121 mov x0, x6 121 mov x0, x6 122 mov x1, x5 122 mov x1, x5 123 bl setz 123 bl setz 124 124 125 ret x4 125 ret x4 126 endfunction 126 endfunction 127 127 128 // Set up test pattern in a SVE P-register 128 // Set up test pattern in a SVE P-register 129 // x0: pid 129 // x0: pid 130 // x1: register number 130 // x1: register number 131 // x2: generation 131 // x2: generation 132 function setup_preg 132 function setup_preg 133 mov x4, x30 133 mov x4, x30 134 134 135 mov x6, x1 135 mov x6, x1 136 bl pattern 136 bl pattern 137 _adrp x0, x6, 2 137 _adrp x0, x6, 2 138 mov x5, x0 138 mov x5, x0 139 ldr x1, =scratch 139 ldr x1, =scratch 140 bl memcpy 140 bl memcpy 141 141 142 mov x0, x6 142 mov x0, x6 143 mov x1, x5 143 mov x1, x5 144 bl setp 144 bl setp 145 145 146 ret x4 146 ret x4 147 endfunction 147 endfunction 148 148 149 // Set up test pattern in the FFR 149 // Set up test pattern in the FFR 150 // x0: pid 150 // x0: pid 151 // x2: generation 151 // x2: generation 152 // 152 // 153 // We need to generate a canonical FFR value, 153 // We need to generate a canonical FFR value, which consists of a number of 154 // low "1" bits, followed by a number of zeros 154 // low "1" bits, followed by a number of zeros. This gives us 17 unique values 155 // per 16 bits of FFR, so we create a 4 bit si 155 // per 16 bits of FFR, so we create a 4 bit signature out of the PID and 156 // generation, and use that as the initial num 156 // generation, and use that as the initial number of ones in the pattern. 157 // We fill the upper lanes of FFR with zeros. 157 // We fill the upper lanes of FFR with zeros. 158 // Beware: corrupts P0. 158 // Beware: corrupts P0. 159 function setup_ffr 159 function setup_ffr 160 #ifndef SSVE 160 #ifndef SSVE 161 mov x4, x30 161 mov x4, x30 162 162 163 and w0, w0, #0x3 163 and w0, w0, #0x3 164 bfi w0, w2, #2, #2 164 bfi w0, w2, #2, #2 165 mov w1, #1 165 mov w1, #1 166 lsl w1, w1, w0 166 lsl w1, w1, w0 167 sub w1, w1, #1 167 sub w1, w1, #1 168 168 169 ldr x0, =ffrref 169 ldr x0, =ffrref 170 strh w1, [x0], 2 170 strh w1, [x0], 2 171 rdvl x1, #1 171 rdvl x1, #1 172 lsr x1, x1, #3 172 lsr x1, x1, #3 173 sub x1, x1, #2 173 sub x1, x1, #2 174 bl memclr 174 bl memclr 175 175 176 mov x0, #0 176 mov x0, #0 177 ldr x1, =ffrref 177 ldr x1, =ffrref 178 bl setp 178 bl setp 179 179 180 wrffr p0.b 180 wrffr p0.b 181 181 182 ret x4 182 ret x4 183 #else 183 #else 184 ret 184 ret 185 #endif 185 #endif 186 endfunction 186 endfunction 187 187 188 // Trivial memory compare: compare x2 bytes st 188 // Trivial memory compare: compare x2 bytes starting at address x0 with 189 // bytes starting at address x1. 189 // bytes starting at address x1. 190 // Returns only if all bytes match; otherwise, 190 // Returns only if all bytes match; otherwise, the program is aborted. 191 // Clobbers x0-x5. 191 // Clobbers x0-x5. 192 function memcmp 192 function memcmp 193 cbz x2, 2f 193 cbz x2, 2f 194 194 195 stp x0, x1, [sp, #-0x20]! 195 stp x0, x1, [sp, #-0x20]! 196 str x2, [sp, #0x10] 196 str x2, [sp, #0x10] 197 197 198 mov x5, #0 198 mov x5, #0 199 0: ldrb w3, [x0, x5] 199 0: ldrb w3, [x0, x5] 200 ldrb w4, [x1, x5] 200 ldrb w4, [x1, x5] 201 add x5, x5, #1 201 add x5, x5, #1 202 cmp w3, w4 202 cmp w3, w4 203 b.ne 1f 203 b.ne 1f 204 subs x2, x2, #1 204 subs x2, x2, #1 205 b.ne 0b 205 b.ne 0b 206 206 207 1: ldr x2, [sp, #0x10] 207 1: ldr x2, [sp, #0x10] 208 ldp x0, x1, [sp], #0x20 208 ldp x0, x1, [sp], #0x20 209 b.ne barf 209 b.ne barf 210 210 211 2: ret 211 2: ret 212 endfunction 212 endfunction 213 213 214 // Verify that a SVE Z-register matches its sh 214 // Verify that a SVE Z-register matches its shadow in memory, else abort 215 // x0: reg number 215 // x0: reg number 216 // Clobbers x0-x7. 216 // Clobbers x0-x7. 217 function check_zreg 217 function check_zreg 218 mov x3, x30 218 mov x3, x30 219 219 220 _adrz x5, x0, 6 220 _adrz x5, x0, 6 221 mov x4, x0 221 mov x4, x0 222 ldr x7, =scratch 222 ldr x7, =scratch 223 223 224 mov x0, x7 224 mov x0, x7 225 mov x1, x6 225 mov x1, x6 226 bl memfill_ae 226 bl memfill_ae 227 227 228 mov x0, x4 228 mov x0, x4 229 mov x1, x7 229 mov x1, x7 230 bl getz 230 bl getz 231 231 232 mov x0, x5 232 mov x0, x5 233 mov x1, x7 233 mov x1, x7 234 mov x2, x6 234 mov x2, x6 235 mov x30, x3 235 mov x30, x3 236 b memcmp 236 b memcmp 237 endfunction 237 endfunction 238 238 239 // Verify that a SVE P-register matches its sh 239 // Verify that a SVE P-register matches its shadow in memory, else abort 240 // x0: reg number 240 // x0: reg number 241 // Clobbers x0-x7. 241 // Clobbers x0-x7. 242 function check_preg 242 function check_preg 243 mov x3, x30 243 mov x3, x30 244 244 245 _adrp x5, x0, 6 245 _adrp x5, x0, 6 246 mov x4, x0 246 mov x4, x0 247 ldr x7, =scratch 247 ldr x7, =scratch 248 248 249 mov x0, x7 249 mov x0, x7 250 mov x1, x6 250 mov x1, x6 251 bl memfill_ae 251 bl memfill_ae 252 252 253 mov x0, x4 253 mov x0, x4 254 mov x1, x7 254 mov x1, x7 255 bl getp 255 bl getp 256 256 257 mov x0, x5 257 mov x0, x5 258 mov x1, x7 258 mov x1, x7 259 mov x2, x6 259 mov x2, x6 260 mov x30, x3 260 mov x30, x3 261 b memcmp 261 b memcmp 262 endfunction 262 endfunction 263 263 264 // Verify that the FFR matches its shadow in m 264 // Verify that the FFR matches its shadow in memory, else abort 265 // Beware -- corrupts P0. 265 // Beware -- corrupts P0. 266 // Clobbers x0-x5. 266 // Clobbers x0-x5. 267 function check_ffr 267 function check_ffr 268 #ifndef SSVE 268 #ifndef SSVE 269 mov x3, x30 269 mov x3, x30 270 270 271 ldr x4, =scratch 271 ldr x4, =scratch 272 rdvl x5, #1 272 rdvl x5, #1 273 lsr x5, x5, #3 273 lsr x5, x5, #3 274 274 275 mov x0, x4 275 mov x0, x4 276 mov x1, x5 276 mov x1, x5 277 bl memfill_ae 277 bl memfill_ae 278 278 279 rdffr p0.b 279 rdffr p0.b 280 mov x0, #0 280 mov x0, #0 281 mov x1, x4 281 mov x1, x4 282 bl getp 282 bl getp 283 283 284 ldr x0, =ffrref 284 ldr x0, =ffrref 285 mov x1, x4 285 mov x1, x4 286 mov x2, x5 286 mov x2, x5 287 mov x30, x3 287 mov x30, x3 288 b memcmp 288 b memcmp 289 #else 289 #else 290 ret 290 ret 291 #endif 291 #endif 292 endfunction 292 endfunction 293 293 294 // Any SVE register modified here can cause co 294 // Any SVE register modified here can cause corruption in the main 295 // thread -- but *only* the registers modified 295 // thread -- but *only* the registers modified here. 296 function irritator_handler 296 function irritator_handler 297 // Increment the irritation signal cou 297 // Increment the irritation signal count (x23): 298 ldr x0, [x2, #ucontext_regs + 8 * 298 ldr x0, [x2, #ucontext_regs + 8 * 23] 299 add x0, x0, #1 299 add x0, x0, #1 300 str x0, [x2, #ucontext_regs + 8 * 300 str x0, [x2, #ucontext_regs + 8 * 23] 301 301 302 // Corrupt some random Z-regs 302 // Corrupt some random Z-regs 303 adr x0, .text + (irritator_handler 303 adr x0, .text + (irritator_handler - .text) / 16 * 16 304 movi v0.8b, #1 304 movi v0.8b, #1 305 movi v9.16b, #2 305 movi v9.16b, #2 306 movi v31.8b, #3 306 movi v31.8b, #3 307 #ifndef SSVE 307 #ifndef SSVE 308 // And P0 308 // And P0 309 rdffr p0.b 309 rdffr p0.b 310 // And FFR 310 // And FFR 311 wrffr p15.b 311 wrffr p15.b 312 #endif 312 #endif 313 313 314 ret 314 ret 315 endfunction 315 endfunction 316 316 317 function tickle_handler << 318 // Increment the signal count (x23): << 319 ldr x0, [x2, #ucontext_regs + 8 * << 320 add x0, x0, #1 << 321 str x0, [x2, #ucontext_regs + 8 * << 322 << 323 ret << 324 endfunction << 325 << 326 function terminate_handler 317 function terminate_handler 327 mov w21, w0 318 mov w21, w0 328 mov x20, x2 319 mov x20, x2 329 320 330 puts "Terminated by signal " 321 puts "Terminated by signal " 331 mov w0, w21 322 mov w0, w21 332 bl putdec 323 bl putdec 333 puts ", no error, iterations=" 324 puts ", no error, iterations=" 334 ldr x0, [x20, #ucontext_regs + 8 * 325 ldr x0, [x20, #ucontext_regs + 8 * 22] 335 bl putdec 326 bl putdec 336 puts ", signals=" 327 puts ", signals=" 337 ldr x0, [x20, #ucontext_regs + 8 * 328 ldr x0, [x20, #ucontext_regs + 8 * 23] 338 bl putdecn 329 bl putdecn 339 330 340 mov x0, #0 331 mov x0, #0 341 mov x8, #__NR_exit 332 mov x8, #__NR_exit 342 svc #0 333 svc #0 343 endfunction 334 endfunction 344 335 345 // w0: signal number 336 // w0: signal number 346 // x1: sa_action 337 // x1: sa_action 347 // w2: sa_flags 338 // w2: sa_flags 348 // Clobbers x0-x6,x8 339 // Clobbers x0-x6,x8 349 function setsignal 340 function setsignal 350 str x30, [sp, #-((sa_sz + 15) / 16 341 str x30, [sp, #-((sa_sz + 15) / 16 * 16 + 16)]! 351 342 352 mov w4, w0 343 mov w4, w0 353 mov x5, x1 344 mov x5, x1 354 mov w6, w2 345 mov w6, w2 355 346 356 add x0, sp, #16 347 add x0, sp, #16 357 mov x1, #sa_sz 348 mov x1, #sa_sz 358 bl memclr 349 bl memclr 359 350 360 mov w0, w4 351 mov w0, w4 361 add x1, sp, #16 352 add x1, sp, #16 362 str w6, [x1, #sa_flags] 353 str w6, [x1, #sa_flags] 363 str x5, [x1, #sa_handler] 354 str x5, [x1, #sa_handler] 364 mov x2, #0 355 mov x2, #0 365 mov x3, #sa_mask_sz 356 mov x3, #sa_mask_sz 366 mov x8, #__NR_rt_sigaction 357 mov x8, #__NR_rt_sigaction 367 svc #0 358 svc #0 368 359 369 cbz w0, 1f 360 cbz w0, 1f 370 361 371 puts "sigaction failure\n" 362 puts "sigaction failure\n" 372 b .Labort 363 b .Labort 373 364 374 1: ldr x30, [sp], #((sa_sz + 15) / 16 365 1: ldr x30, [sp], #((sa_sz + 15) / 16 * 16 + 16) 375 ret 366 ret 376 endfunction 367 endfunction 377 368 378 // Main program entry point 369 // Main program entry point 379 .globl _start 370 .globl _start 380 function _start 371 function _start 381 mov x23, #0 // Irritation !! 372 _start: 382 << 383 mov w0, #SIGINT << 384 adr x1, terminate_handler << 385 mov w2, #SA_SIGINFO << 386 bl setsignal << 387 << 388 mov w0, #SIGTERM << 389 adr x1, terminate_handler << 390 mov w2, #SA_SIGINFO << 391 bl setsignal << 392 << 393 mov w0, #SIGUSR1 << 394 adr x1, irritator_handler << 395 mov w2, #SA_SIGINFO << 396 orr w2, w2, #SA_NODEFER << 397 bl setsignal << 398 << 399 mov w0, #SIGUSR2 << 400 adr x1, tickle_handler << 401 mov w2, #SA_SIGINFO << 402 orr w2, w2, #SA_NODEFER << 403 bl setsignal << 404 << 405 #ifdef SSVE 373 #ifdef SSVE 406 puts "Streaming mode " 374 puts "Streaming mode " 407 smstart_sm 375 smstart_sm 408 #endif 376 #endif 409 377 410 // Sanity-check and report the vector 378 // Sanity-check and report the vector length 411 379 412 rdvl x19, #8 380 rdvl x19, #8 413 cmp x19, #128 381 cmp x19, #128 414 b.lo 1f 382 b.lo 1f 415 cmp x19, #2048 383 cmp x19, #2048 416 b.hi 1f 384 b.hi 1f 417 tst x19, #(8 - 1) 385 tst x19, #(8 - 1) 418 b.eq 2f 386 b.eq 2f 419 387 420 1: puts "Bad vector length: " 388 1: puts "Bad vector length: " 421 mov x0, x19 389 mov x0, x19 422 bl putdecn 390 bl putdecn 423 b .Labort 391 b .Labort 424 392 425 2: puts "Vector length:\t" 393 2: puts "Vector length:\t" 426 mov x0, x19 394 mov x0, x19 427 bl putdec 395 bl putdec 428 puts " bits\n" 396 puts " bits\n" 429 397 430 // Obtain our PID, to ensure test patt 398 // Obtain our PID, to ensure test pattern uniqueness between processes 431 399 432 mov x8, #__NR_getpid 400 mov x8, #__NR_getpid 433 svc #0 401 svc #0 434 mov x20, x0 402 mov x20, x0 435 403 436 puts "PID:\t" 404 puts "PID:\t" 437 mov x0, x20 405 mov x0, x20 438 bl putdecn 406 bl putdecn 439 407 >> 408 mov x23, #0 // Irritation signal count >> 409 >> 410 mov w0, #SIGINT >> 411 adr x1, terminate_handler >> 412 mov w2, #SA_SIGINFO >> 413 bl setsignal >> 414 >> 415 mov w0, #SIGTERM >> 416 adr x1, terminate_handler >> 417 mov w2, #SA_SIGINFO >> 418 bl setsignal >> 419 >> 420 mov w0, #SIGUSR1 >> 421 adr x1, irritator_handler >> 422 mov w2, #SA_SIGINFO >> 423 orr w2, w2, #SA_NODEFER >> 424 bl setsignal >> 425 440 #ifdef SSVE 426 #ifdef SSVE 441 smstart_sm // syscalls wi 427 smstart_sm // syscalls will have exited streaming mode 442 #endif 428 #endif 443 429 444 mov x22, #0 // generation 430 mov x22, #0 // generation number, increments per iteration 445 .Ltest_loop: 431 .Ltest_loop: 446 rdvl x0, #8 432 rdvl x0, #8 447 cmp x0, x19 433 cmp x0, x19 448 b.ne vl_barf 434 b.ne vl_barf 449 435 450 mov x21, #0 // Set up Z-re 436 mov x21, #0 // Set up Z-regs & shadow with test pattern 451 0: mov x0, x20 437 0: mov x0, x20 452 mov x1, x21 438 mov x1, x21 453 and x2, x22, #0xf 439 and x2, x22, #0xf 454 bl setup_zreg 440 bl setup_zreg 455 add x21, x21, #1 441 add x21, x21, #1 456 cmp x21, #NZR 442 cmp x21, #NZR 457 b.lo 0b 443 b.lo 0b 458 444 459 mov x0, x20 // Set up FFR 445 mov x0, x20 // Set up FFR & shadow with test pattern 460 mov x1, #NZR + NPR 446 mov x1, #NZR + NPR 461 and x2, x22, #0xf 447 and x2, x22, #0xf 462 bl setup_ffr 448 bl setup_ffr 463 449 464 0: mov x0, x20 // Set up P-re 450 0: mov x0, x20 // Set up P-regs & shadow with test pattern 465 mov x1, x21 451 mov x1, x21 466 and x2, x22, #0xf 452 and x2, x22, #0xf 467 bl setup_preg 453 bl setup_preg 468 add x21, x21, #1 454 add x21, x21, #1 469 cmp x21, #NZR + NPR 455 cmp x21, #NZR + NPR 470 b.lo 0b 456 b.lo 0b 471 457 472 // Can't do this when SVE state is volatile ac 458 // Can't do this when SVE state is volatile across SVC: 473 // mov x8, #__NR_sched_yield // Enc 459 // mov x8, #__NR_sched_yield // Encourage preemption 474 // svc #0 460 // svc #0 475 461 476 #ifdef SSVE << 477 mrs x0, S3_3_C4_C2_2 // SVC << 478 and x1, x0, #3 << 479 cmp x1, #1 << 480 b.ne svcr_barf << 481 #endif << 482 << 483 mov x21, #0 462 mov x21, #0 484 0: mov x0, x21 463 0: mov x0, x21 485 bl check_zreg 464 bl check_zreg 486 add x21, x21, #1 465 add x21, x21, #1 487 cmp x21, #NZR 466 cmp x21, #NZR 488 b.lo 0b 467 b.lo 0b 489 468 490 0: mov x0, x21 469 0: mov x0, x21 491 bl check_preg 470 bl check_preg 492 add x21, x21, #1 471 add x21, x21, #1 493 cmp x21, #NZR + NPR 472 cmp x21, #NZR + NPR 494 b.lo 0b 473 b.lo 0b 495 474 496 bl check_ffr 475 bl check_ffr 497 476 498 add x22, x22, #1 477 add x22, x22, #1 499 b .Ltest_loop 478 b .Ltest_loop 500 479 501 .Labort: 480 .Labort: 502 mov x0, #0 481 mov x0, #0 503 mov x1, #SIGABRT 482 mov x1, #SIGABRT 504 mov x8, #__NR_kill 483 mov x8, #__NR_kill 505 svc #0 484 svc #0 506 endfunction 485 endfunction 507 486 508 function barf 487 function barf 509 // fpsimd.c acitivty log dump hack 488 // fpsimd.c acitivty log dump hack 510 // ldr w0, =0xdeadc0de 489 // ldr w0, =0xdeadc0de 511 // mov w8, #__NR_exit 490 // mov w8, #__NR_exit 512 // svc #0 491 // svc #0 513 // end hack 492 // end hack 514 mov x10, x0 // expected data 493 mov x10, x0 // expected data 515 mov x11, x1 // actual data 494 mov x11, x1 // actual data 516 mov x12, x2 // data size 495 mov x12, x2 // data size 517 496 518 #ifdef SSVE << 519 mrs x13, S3_3_C4_C2_2 << 520 #endif << 521 << 522 puts "Mismatch: PID=" 497 puts "Mismatch: PID=" 523 mov x0, x20 498 mov x0, x20 524 bl putdec 499 bl putdec 525 puts ", iteration=" 500 puts ", iteration=" 526 mov x0, x22 501 mov x0, x22 527 bl putdec 502 bl putdec 528 puts ", reg=" 503 puts ", reg=" 529 mov x0, x21 504 mov x0, x21 530 bl putdecn 505 bl putdecn 531 puts "\tExpected [" 506 puts "\tExpected [" 532 mov x0, x10 507 mov x0, x10 533 mov x1, x12 508 mov x1, x12 534 bl dumphex 509 bl dumphex 535 puts "]\n\tGot [" 510 puts "]\n\tGot [" 536 mov x0, x11 511 mov x0, x11 537 mov x1, x12 512 mov x1, x12 538 bl dumphex 513 bl dumphex 539 puts "]\n" 514 puts "]\n" 540 515 541 #ifdef SSVE << 542 puts "\tSVCR: " << 543 mov x0, x13 << 544 bl putdecn << 545 #endif << 546 << 547 mov x8, #__NR_getpid 516 mov x8, #__NR_getpid 548 svc #0 517 svc #0 549 // fpsimd.c acitivty log dump hack 518 // fpsimd.c acitivty log dump hack 550 // ldr w0, =0xdeadc0de 519 // ldr w0, =0xdeadc0de 551 // mov w8, #__NR_exit 520 // mov w8, #__NR_exit 552 // svc #0 521 // svc #0 553 // ^ end of hack 522 // ^ end of hack 554 mov x1, #SIGABRT 523 mov x1, #SIGABRT 555 mov x8, #__NR_kill 524 mov x8, #__NR_kill 556 svc #0 525 svc #0 557 // mov x8, #__NR_exit 526 // mov x8, #__NR_exit 558 // mov x1, #1 527 // mov x1, #1 559 // svc #0 528 // svc #0 560 endfunction 529 endfunction 561 530 562 function vl_barf 531 function vl_barf 563 mov x10, x0 532 mov x10, x0 564 533 565 puts "Bad active VL: " 534 puts "Bad active VL: " 566 mov x0, x10 << 567 bl putdecn << 568 << 569 mov x8, #__NR_exit << 570 mov x1, #1 << 571 svc #0 << 572 endfunction << 573 << 574 function svcr_barf << 575 mov x10, x0 << 576 << 577 puts "Bad SVCR: " << 578 mov x0, x10 535 mov x0, x10 579 bl putdecn 536 bl putdecn 580 537 581 mov x8, #__NR_exit 538 mov x8, #__NR_exit 582 mov x1, #1 539 mov x1, #1 583 svc #0 540 svc #0 584 endfunction 541 endfunction
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.