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" << 17 16 18 #define NZR 32 17 #define NZR 32 19 #define NPR 16 18 #define NPR 16 20 #define MAXVL_B (2048 / 8) 19 #define MAXVL_B (2048 / 8) 21 20 22 .arch_extension sve 21 .arch_extension sve 23 22 24 .macro _sve_ldr_v zt, xn 23 .macro _sve_ldr_v zt, xn 25 ldr z\zt, [x\xn] 24 ldr z\zt, [x\xn] 26 .endm 25 .endm 27 26 28 .macro _sve_str_v zt, xn 27 .macro _sve_str_v zt, xn 29 str z\zt, [x\xn] 28 str z\zt, [x\xn] 30 .endm 29 .endm 31 30 32 .macro _sve_ldr_p pt, xn 31 .macro _sve_ldr_p pt, xn 33 ldr p\pt, [x\xn] 32 ldr p\pt, [x\xn] 34 .endm 33 .endm 35 34 36 .macro _sve_str_p pt, xn 35 .macro _sve_str_p pt, xn 37 str p\pt, [x\xn] 36 str p\pt, [x\xn] 38 .endm 37 .endm 39 38 40 // Generate accessor functions to read/write p 39 // Generate accessor functions to read/write programmatically selected 41 // SVE registers. 40 // SVE registers. 42 // x0 is the register index to access 41 // x0 is the register index to access 43 // x1 is the memory address to read from (getz 42 // x1 is the memory address to read from (getz,setp) or store to (setz,setp) 44 // All clobber x0-x2 43 // All clobber x0-x2 45 define_accessor setz, NZR, _sve_ldr_v 44 define_accessor setz, NZR, _sve_ldr_v 46 define_accessor getz, NZR, _sve_str_v 45 define_accessor getz, NZR, _sve_str_v 47 define_accessor setp, NPR, _sve_ldr_p 46 define_accessor setp, NPR, _sve_ldr_p 48 define_accessor getp, NPR, _sve_str_p 47 define_accessor getp, NPR, _sve_str_p 49 48 >> 49 // Print a single character x0 to stdout >> 50 // Clobbers x0-x2,x8 >> 51 function putc >> 52 str x0, [sp, #-16]! >> 53 >> 54 mov x0, #1 // STDOUT_FILENO >> 55 mov x1, sp >> 56 mov x2, #1 >> 57 mov x8, #__NR_write >> 58 svc #0 >> 59 >> 60 add sp, sp, #16 >> 61 ret >> 62 endfunction >> 63 >> 64 // Print a NUL-terminated string starting at address x0 to stdout >> 65 // Clobbers x0-x3,x8 >> 66 function puts >> 67 mov x1, x0 >> 68 >> 69 mov x2, #0 >> 70 0: ldrb w3, [x0], #1 >> 71 cbz w3, 1f >> 72 add x2, x2, #1 >> 73 b 0b >> 74 >> 75 1: mov w0, #1 // STDOUT_FILENO >> 76 mov x8, #__NR_write >> 77 svc #0 >> 78 >> 79 ret >> 80 endfunction >> 81 >> 82 // Utility macro to print a literal string >> 83 // Clobbers x0-x4,x8 >> 84 .macro puts string >> 85 .pushsection .rodata.str1.1, "aMS", 1 >> 86 .L__puts_literal\@: .string "\string" >> 87 .popsection >> 88 >> 89 ldr x0, =.L__puts_literal\@ >> 90 bl puts >> 91 .endm >> 92 >> 93 // Print an unsigned decimal number x0 to stdout >> 94 // Clobbers x0-x4,x8 >> 95 function putdec >> 96 mov x1, sp >> 97 str x30, [sp, #-32]! // Result can't be > 20 digits >> 98 >> 99 mov x2, #0 >> 100 strb w2, [x1, #-1]! // Write the NUL terminator >> 101 >> 102 mov x2, #10 >> 103 0: udiv x3, x0, x2 // div-mod loop to generate the digits >> 104 msub x0, x3, x2, x0 >> 105 add w0, w0, #'0' >> 106 strb w0, [x1, #-1]! >> 107 mov x0, x3 >> 108 cbnz x3, 0b >> 109 >> 110 ldrb w0, [x1] >> 111 cbnz w0, 1f >> 112 mov w0, #'0' // Print "0" for 0, not "" >> 113 strb w0, [x1, #-1]! >> 114 >> 115 1: mov x0, x1 >> 116 bl puts >> 117 >> 118 ldr x30, [sp], #32 >> 119 ret >> 120 endfunction >> 121 >> 122 // Print an unsigned decimal number x0 to stdout, followed by a newline >> 123 // Clobbers x0-x5,x8 >> 124 function putdecn >> 125 mov x5, x30 >> 126 >> 127 bl putdec >> 128 mov x0, #'\n' >> 129 bl putc >> 130 >> 131 ret x5 >> 132 endfunction >> 133 >> 134 // Clobbers x0-x3,x8 >> 135 function puthexb >> 136 str x30, [sp, #-0x10]! >> 137 >> 138 mov w3, w0 >> 139 lsr w0, w0, #4 >> 140 bl puthexnibble >> 141 mov w0, w3 >> 142 >> 143 ldr x30, [sp], #0x10 >> 144 // fall through to puthexnibble >> 145 endfunction >> 146 // Clobbers x0-x2,x8 >> 147 function puthexnibble >> 148 and w0, w0, #0xf >> 149 cmp w0, #10 >> 150 blo 1f >> 151 add w0, w0, #'a' - ('9' + 1) >> 152 1: add w0, w0, #'0' >> 153 b putc >> 154 endfunction >> 155 >> 156 // x0=data in, x1=size in, clobbers x0-x5,x8 >> 157 function dumphex >> 158 str x30, [sp, #-0x10]! >> 159 >> 160 mov x4, x0 >> 161 mov x5, x1 >> 162 >> 163 0: subs x5, x5, #1 >> 164 b.lo 1f >> 165 ldrb w0, [x4], #1 >> 166 bl puthexb >> 167 b 0b >> 168 >> 169 1: ldr x30, [sp], #0x10 >> 170 ret >> 171 endfunction >> 172 50 // Declare some storate space to shadow the SV 173 // Declare some storate space to shadow the SVE register contents: 51 .pushsection .text 174 .pushsection .text 52 .data 175 .data 53 .align 4 176 .align 4 54 zref: 177 zref: 55 .space MAXVL_B * NZR 178 .space MAXVL_B * NZR 56 pref: 179 pref: 57 .space MAXVL_B / 8 * NPR 180 .space MAXVL_B / 8 * NPR 58 ffrref: 181 ffrref: 59 .space MAXVL_B / 8 182 .space MAXVL_B / 8 60 scratch: 183 scratch: 61 .space MAXVL_B 184 .space MAXVL_B 62 .popsection 185 .popsection 63 186 >> 187 // Trivial memory copy: copy x2 bytes, starting at address x1, to address x0. >> 188 // Clobbers x0-x3 >> 189 function memcpy >> 190 cmp x2, #0 >> 191 b.eq 1f >> 192 0: ldrb w3, [x1], #1 >> 193 strb w3, [x0], #1 >> 194 subs x2, x2, #1 >> 195 b.ne 0b >> 196 1: ret >> 197 endfunction >> 198 64 // Generate a test pattern for storage in SVE 199 // Generate a test pattern for storage in SVE registers 65 // x0: pid (16 bits) 200 // x0: pid (16 bits) 66 // x1: register number (6 bits) 201 // x1: register number (6 bits) 67 // x2: generation (4 bits) 202 // x2: generation (4 bits) 68 203 69 // These values are used to constuct a 32-bit 204 // These values are used to constuct a 32-bit pattern that is repeated in the 70 // scratch buffer as many times as will fit: 205 // scratch buffer as many times as will fit: 71 // bits 31:28 generation number (increments 206 // bits 31:28 generation number (increments once per test_loop) 72 // bits 27:22 32-bit lane index 207 // bits 27:22 32-bit lane index 73 // bits 21:16 register number 208 // bits 21:16 register number 74 // bits 15: 0 pid 209 // bits 15: 0 pid 75 210 76 function pattern 211 function pattern 77 orr w1, w0, w1, lsl #16 212 orr w1, w0, w1, lsl #16 78 orr w2, w1, w2, lsl #28 213 orr w2, w1, w2, lsl #28 79 214 80 ldr x0, =scratch 215 ldr x0, =scratch 81 mov w1, #MAXVL_B / 4 216 mov w1, #MAXVL_B / 4 82 217 83 0: str w2, [x0], #4 218 0: str w2, [x0], #4 84 add w2, w2, #(1 << 22) 219 add w2, w2, #(1 << 22) 85 subs w1, w1, #1 220 subs w1, w1, #1 86 bne 0b 221 bne 0b 87 222 88 ret 223 ret 89 endfunction 224 endfunction 90 225 91 // Get the address of shadow data for SVE Z-re 226 // Get the address of shadow data for SVE Z-register Z<xn> 92 .macro _adrz xd, xn, nrtmp 227 .macro _adrz xd, xn, nrtmp 93 ldr \xd, =zref 228 ldr \xd, =zref 94 rdvl x\nrtmp, #1 229 rdvl x\nrtmp, #1 95 madd \xd, x\nrtmp, \xn, \xd 230 madd \xd, x\nrtmp, \xn, \xd 96 .endm 231 .endm 97 232 98 // Get the address of shadow data for SVE P-re 233 // Get the address of shadow data for SVE P-register P<xn - NZR> 99 .macro _adrp xd, xn, nrtmp 234 .macro _adrp xd, xn, nrtmp 100 ldr \xd, =pref 235 ldr \xd, =pref 101 rdvl x\nrtmp, #1 236 rdvl x\nrtmp, #1 102 lsr x\nrtmp, x\nrtmp, #3 237 lsr x\nrtmp, x\nrtmp, #3 103 sub \xn, \xn, #NZR 238 sub \xn, \xn, #NZR 104 madd \xd, x\nrtmp, \xn, \xd 239 madd \xd, x\nrtmp, \xn, \xd 105 .endm 240 .endm 106 241 107 // Set up test pattern in a SVE Z-register 242 // Set up test pattern in a SVE Z-register 108 // x0: pid 243 // x0: pid 109 // x1: register number 244 // x1: register number 110 // x2: generation 245 // x2: generation 111 function setup_zreg 246 function setup_zreg 112 mov x4, x30 247 mov x4, x30 113 248 114 mov x6, x1 249 mov x6, x1 115 bl pattern 250 bl pattern 116 _adrz x0, x6, 2 251 _adrz x0, x6, 2 117 mov x5, x0 252 mov x5, x0 118 ldr x1, =scratch 253 ldr x1, =scratch 119 bl memcpy 254 bl memcpy 120 255 121 mov x0, x6 256 mov x0, x6 122 mov x1, x5 257 mov x1, x5 123 bl setz 258 bl setz 124 259 125 ret x4 260 ret x4 126 endfunction 261 endfunction 127 262 128 // Set up test pattern in a SVE P-register 263 // Set up test pattern in a SVE P-register 129 // x0: pid 264 // x0: pid 130 // x1: register number 265 // x1: register number 131 // x2: generation 266 // x2: generation 132 function setup_preg 267 function setup_preg 133 mov x4, x30 268 mov x4, x30 134 269 135 mov x6, x1 270 mov x6, x1 136 bl pattern 271 bl pattern 137 _adrp x0, x6, 2 272 _adrp x0, x6, 2 138 mov x5, x0 273 mov x5, x0 139 ldr x1, =scratch 274 ldr x1, =scratch 140 bl memcpy 275 bl memcpy 141 276 142 mov x0, x6 277 mov x0, x6 143 mov x1, x5 278 mov x1, x5 144 bl setp 279 bl setp 145 280 146 ret x4 281 ret x4 147 endfunction 282 endfunction 148 283 149 // Set up test pattern in the FFR 284 // Set up test pattern in the FFR 150 // x0: pid 285 // x0: pid 151 // x2: generation 286 // x2: generation 152 // 287 // 153 // We need to generate a canonical FFR value, 288 // We need to generate a canonical FFR value, which consists of a number of 154 // low "1" bits, followed by a number of zeros 289 // 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 290 // 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 291 // generation, and use that as the initial number of ones in the pattern. 157 // We fill the upper lanes of FFR with zeros. 292 // We fill the upper lanes of FFR with zeros. 158 // Beware: corrupts P0. 293 // Beware: corrupts P0. 159 function setup_ffr 294 function setup_ffr 160 #ifndef SSVE << 161 mov x4, x30 295 mov x4, x30 162 296 163 and w0, w0, #0x3 297 and w0, w0, #0x3 164 bfi w0, w2, #2, #2 298 bfi w0, w2, #2, #2 165 mov w1, #1 299 mov w1, #1 166 lsl w1, w1, w0 300 lsl w1, w1, w0 167 sub w1, w1, #1 301 sub w1, w1, #1 168 302 169 ldr x0, =ffrref 303 ldr x0, =ffrref 170 strh w1, [x0], 2 304 strh w1, [x0], 2 171 rdvl x1, #1 305 rdvl x1, #1 172 lsr x1, x1, #3 306 lsr x1, x1, #3 173 sub x1, x1, #2 307 sub x1, x1, #2 174 bl memclr 308 bl memclr 175 309 176 mov x0, #0 310 mov x0, #0 177 ldr x1, =ffrref 311 ldr x1, =ffrref 178 bl setp 312 bl setp 179 313 180 wrffr p0.b 314 wrffr p0.b 181 315 182 ret x4 316 ret x4 183 #else !! 317 endfunction 184 ret !! 318 185 #endif !! 319 // Fill x1 bytes starting at x0 with 0xae (for canary purposes) >> 320 // Clobbers x1, x2. >> 321 function memfill_ae >> 322 mov w2, #0xae >> 323 b memfill >> 324 endfunction >> 325 >> 326 // Fill x1 bytes starting at x0 with 0. >> 327 // Clobbers x1, x2. >> 328 function memclr >> 329 mov w2, #0 >> 330 endfunction >> 331 // fall through to memfill >> 332 >> 333 // Trivial memory fill: fill x1 bytes starting at address x0 with byte w2 >> 334 // Clobbers x1 >> 335 function memfill >> 336 cmp x1, #0 >> 337 b.eq 1f >> 338 >> 339 0: strb w2, [x0], #1 >> 340 subs x1, x1, #1 >> 341 b.ne 0b >> 342 >> 343 1: ret 186 endfunction 344 endfunction 187 345 188 // Trivial memory compare: compare x2 bytes st 346 // Trivial memory compare: compare x2 bytes starting at address x0 with 189 // bytes starting at address x1. 347 // bytes starting at address x1. 190 // Returns only if all bytes match; otherwise, 348 // Returns only if all bytes match; otherwise, the program is aborted. 191 // Clobbers x0-x5. 349 // Clobbers x0-x5. 192 function memcmp 350 function memcmp 193 cbz x2, 2f 351 cbz x2, 2f 194 352 195 stp x0, x1, [sp, #-0x20]! 353 stp x0, x1, [sp, #-0x20]! 196 str x2, [sp, #0x10] 354 str x2, [sp, #0x10] 197 355 198 mov x5, #0 356 mov x5, #0 199 0: ldrb w3, [x0, x5] 357 0: ldrb w3, [x0, x5] 200 ldrb w4, [x1, x5] 358 ldrb w4, [x1, x5] 201 add x5, x5, #1 359 add x5, x5, #1 202 cmp w3, w4 360 cmp w3, w4 203 b.ne 1f 361 b.ne 1f 204 subs x2, x2, #1 362 subs x2, x2, #1 205 b.ne 0b 363 b.ne 0b 206 364 207 1: ldr x2, [sp, #0x10] 365 1: ldr x2, [sp, #0x10] 208 ldp x0, x1, [sp], #0x20 366 ldp x0, x1, [sp], #0x20 209 b.ne barf 367 b.ne barf 210 368 211 2: ret 369 2: ret 212 endfunction 370 endfunction 213 371 214 // Verify that a SVE Z-register matches its sh 372 // Verify that a SVE Z-register matches its shadow in memory, else abort 215 // x0: reg number 373 // x0: reg number 216 // Clobbers x0-x7. 374 // Clobbers x0-x7. 217 function check_zreg 375 function check_zreg 218 mov x3, x30 376 mov x3, x30 219 377 220 _adrz x5, x0, 6 378 _adrz x5, x0, 6 221 mov x4, x0 379 mov x4, x0 222 ldr x7, =scratch 380 ldr x7, =scratch 223 381 224 mov x0, x7 382 mov x0, x7 225 mov x1, x6 383 mov x1, x6 226 bl memfill_ae 384 bl memfill_ae 227 385 228 mov x0, x4 386 mov x0, x4 229 mov x1, x7 387 mov x1, x7 230 bl getz 388 bl getz 231 389 232 mov x0, x5 390 mov x0, x5 233 mov x1, x7 391 mov x1, x7 234 mov x2, x6 392 mov x2, x6 235 mov x30, x3 393 mov x30, x3 236 b memcmp 394 b memcmp 237 endfunction 395 endfunction 238 396 239 // Verify that a SVE P-register matches its sh 397 // Verify that a SVE P-register matches its shadow in memory, else abort 240 // x0: reg number 398 // x0: reg number 241 // Clobbers x0-x7. 399 // Clobbers x0-x7. 242 function check_preg 400 function check_preg 243 mov x3, x30 401 mov x3, x30 244 402 245 _adrp x5, x0, 6 403 _adrp x5, x0, 6 246 mov x4, x0 404 mov x4, x0 247 ldr x7, =scratch 405 ldr x7, =scratch 248 406 249 mov x0, x7 407 mov x0, x7 250 mov x1, x6 408 mov x1, x6 251 bl memfill_ae 409 bl memfill_ae 252 410 253 mov x0, x4 411 mov x0, x4 254 mov x1, x7 412 mov x1, x7 255 bl getp 413 bl getp 256 414 257 mov x0, x5 415 mov x0, x5 258 mov x1, x7 416 mov x1, x7 259 mov x2, x6 417 mov x2, x6 260 mov x30, x3 418 mov x30, x3 261 b memcmp 419 b memcmp 262 endfunction 420 endfunction 263 421 264 // Verify that the FFR matches its shadow in m 422 // Verify that the FFR matches its shadow in memory, else abort 265 // Beware -- corrupts P0. 423 // Beware -- corrupts P0. 266 // Clobbers x0-x5. 424 // Clobbers x0-x5. 267 function check_ffr 425 function check_ffr 268 #ifndef SSVE << 269 mov x3, x30 426 mov x3, x30 270 427 271 ldr x4, =scratch 428 ldr x4, =scratch 272 rdvl x5, #1 429 rdvl x5, #1 273 lsr x5, x5, #3 430 lsr x5, x5, #3 274 431 275 mov x0, x4 432 mov x0, x4 276 mov x1, x5 433 mov x1, x5 277 bl memfill_ae 434 bl memfill_ae 278 435 279 rdffr p0.b 436 rdffr p0.b 280 mov x0, #0 437 mov x0, #0 281 mov x1, x4 438 mov x1, x4 282 bl getp 439 bl getp 283 440 284 ldr x0, =ffrref 441 ldr x0, =ffrref 285 mov x1, x4 442 mov x1, x4 286 mov x2, x5 443 mov x2, x5 287 mov x30, x3 444 mov x30, x3 288 b memcmp 445 b memcmp 289 #else << 290 ret << 291 #endif << 292 endfunction 446 endfunction 293 447 294 // Any SVE register modified here can cause co 448 // Any SVE register modified here can cause corruption in the main 295 // thread -- but *only* the registers modified 449 // thread -- but *only* the registers modified here. 296 function irritator_handler 450 function irritator_handler 297 // Increment the irritation signal cou 451 // Increment the irritation signal count (x23): 298 ldr x0, [x2, #ucontext_regs + 8 * 452 ldr x0, [x2, #ucontext_regs + 8 * 23] 299 add x0, x0, #1 453 add x0, x0, #1 300 str x0, [x2, #ucontext_regs + 8 * 454 str x0, [x2, #ucontext_regs + 8 * 23] 301 455 302 // Corrupt some random Z-regs 456 // Corrupt some random Z-regs 303 adr x0, .text + (irritator_handler 457 adr x0, .text + (irritator_handler - .text) / 16 * 16 304 movi v0.8b, #1 458 movi v0.8b, #1 305 movi v9.16b, #2 459 movi v9.16b, #2 306 movi v31.8b, #3 460 movi v31.8b, #3 307 #ifndef SSVE << 308 // And P0 461 // And P0 309 rdffr p0.b 462 rdffr p0.b 310 // And FFR 463 // And FFR 311 wrffr p15.b 464 wrffr p15.b 312 #endif << 313 << 314 ret << 315 endfunction << 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 465 323 ret 466 ret 324 endfunction 467 endfunction 325 468 326 function terminate_handler 469 function terminate_handler 327 mov w21, w0 470 mov w21, w0 328 mov x20, x2 471 mov x20, x2 329 472 330 puts "Terminated by signal " 473 puts "Terminated by signal " 331 mov w0, w21 474 mov w0, w21 332 bl putdec 475 bl putdec 333 puts ", no error, iterations=" 476 puts ", no error, iterations=" 334 ldr x0, [x20, #ucontext_regs + 8 * 477 ldr x0, [x20, #ucontext_regs + 8 * 22] 335 bl putdec 478 bl putdec 336 puts ", signals=" 479 puts ", signals=" 337 ldr x0, [x20, #ucontext_regs + 8 * 480 ldr x0, [x20, #ucontext_regs + 8 * 23] 338 bl putdecn 481 bl putdecn 339 482 340 mov x0, #0 483 mov x0, #0 341 mov x8, #__NR_exit 484 mov x8, #__NR_exit 342 svc #0 485 svc #0 343 endfunction 486 endfunction 344 487 345 // w0: signal number 488 // w0: signal number 346 // x1: sa_action 489 // x1: sa_action 347 // w2: sa_flags 490 // w2: sa_flags 348 // Clobbers x0-x6,x8 491 // Clobbers x0-x6,x8 349 function setsignal 492 function setsignal 350 str x30, [sp, #-((sa_sz + 15) / 16 493 str x30, [sp, #-((sa_sz + 15) / 16 * 16 + 16)]! 351 494 352 mov w4, w0 495 mov w4, w0 353 mov x5, x1 496 mov x5, x1 354 mov w6, w2 497 mov w6, w2 355 498 356 add x0, sp, #16 499 add x0, sp, #16 357 mov x1, #sa_sz 500 mov x1, #sa_sz 358 bl memclr 501 bl memclr 359 502 360 mov w0, w4 503 mov w0, w4 361 add x1, sp, #16 504 add x1, sp, #16 362 str w6, [x1, #sa_flags] 505 str w6, [x1, #sa_flags] 363 str x5, [x1, #sa_handler] 506 str x5, [x1, #sa_handler] 364 mov x2, #0 507 mov x2, #0 365 mov x3, #sa_mask_sz 508 mov x3, #sa_mask_sz 366 mov x8, #__NR_rt_sigaction 509 mov x8, #__NR_rt_sigaction 367 svc #0 510 svc #0 368 511 369 cbz w0, 1f 512 cbz w0, 1f 370 513 371 puts "sigaction failure\n" 514 puts "sigaction failure\n" 372 b .Labort 515 b .Labort 373 516 374 1: ldr x30, [sp], #((sa_sz + 15) / 16 517 1: ldr x30, [sp], #((sa_sz + 15) / 16 * 16 + 16) 375 ret 518 ret 376 endfunction 519 endfunction 377 520 378 // Main program entry point 521 // Main program entry point 379 .globl _start 522 .globl _start 380 function _start 523 function _start 381 mov x23, #0 // Irritation !! 524 _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 << 406 puts "Streaming mode " << 407 smstart_sm << 408 #endif << 409 << 410 // Sanity-check and report the vector 525 // Sanity-check and report the vector length 411 526 412 rdvl x19, #8 527 rdvl x19, #8 413 cmp x19, #128 528 cmp x19, #128 414 b.lo 1f 529 b.lo 1f 415 cmp x19, #2048 530 cmp x19, #2048 416 b.hi 1f 531 b.hi 1f 417 tst x19, #(8 - 1) 532 tst x19, #(8 - 1) 418 b.eq 2f 533 b.eq 2f 419 534 420 1: puts "Bad vector length: " 535 1: puts "Bad vector length: " 421 mov x0, x19 536 mov x0, x19 422 bl putdecn 537 bl putdecn 423 b .Labort 538 b .Labort 424 539 425 2: puts "Vector length:\t" 540 2: puts "Vector length:\t" 426 mov x0, x19 541 mov x0, x19 427 bl putdec 542 bl putdec 428 puts " bits\n" 543 puts " bits\n" 429 544 430 // Obtain our PID, to ensure test patt 545 // Obtain our PID, to ensure test pattern uniqueness between processes 431 546 432 mov x8, #__NR_getpid 547 mov x8, #__NR_getpid 433 svc #0 548 svc #0 434 mov x20, x0 549 mov x20, x0 435 550 436 puts "PID:\t" 551 puts "PID:\t" 437 mov x0, x20 552 mov x0, x20 438 bl putdecn 553 bl putdecn 439 554 440 #ifdef SSVE !! 555 mov x23, #0 // Irritation signal count 441 smstart_sm // syscalls wi !! 556 442 #endif !! 557 mov w0, #SIGINT >> 558 adr x1, terminate_handler >> 559 mov w2, #SA_SIGINFO >> 560 bl setsignal >> 561 >> 562 mov w0, #SIGTERM >> 563 adr x1, terminate_handler >> 564 mov w2, #SA_SIGINFO >> 565 bl setsignal >> 566 >> 567 mov w0, #SIGUSR1 >> 568 adr x1, irritator_handler >> 569 mov w2, #SA_SIGINFO >> 570 orr w2, w2, #SA_NODEFER >> 571 bl setsignal 443 572 444 mov x22, #0 // generation 573 mov x22, #0 // generation number, increments per iteration 445 .Ltest_loop: 574 .Ltest_loop: 446 rdvl x0, #8 575 rdvl x0, #8 447 cmp x0, x19 576 cmp x0, x19 448 b.ne vl_barf 577 b.ne vl_barf 449 578 450 mov x21, #0 // Set up Z-re 579 mov x21, #0 // Set up Z-regs & shadow with test pattern 451 0: mov x0, x20 580 0: mov x0, x20 452 mov x1, x21 581 mov x1, x21 453 and x2, x22, #0xf 582 and x2, x22, #0xf 454 bl setup_zreg 583 bl setup_zreg 455 add x21, x21, #1 584 add x21, x21, #1 456 cmp x21, #NZR 585 cmp x21, #NZR 457 b.lo 0b 586 b.lo 0b 458 587 459 mov x0, x20 // Set up FFR 588 mov x0, x20 // Set up FFR & shadow with test pattern 460 mov x1, #NZR + NPR 589 mov x1, #NZR + NPR 461 and x2, x22, #0xf 590 and x2, x22, #0xf 462 bl setup_ffr 591 bl setup_ffr 463 592 464 0: mov x0, x20 // Set up P-re 593 0: mov x0, x20 // Set up P-regs & shadow with test pattern 465 mov x1, x21 594 mov x1, x21 466 and x2, x22, #0xf 595 and x2, x22, #0xf 467 bl setup_preg 596 bl setup_preg 468 add x21, x21, #1 597 add x21, x21, #1 469 cmp x21, #NZR + NPR 598 cmp x21, #NZR + NPR 470 b.lo 0b 599 b.lo 0b 471 600 472 // Can't do this when SVE state is volatile ac 601 // Can't do this when SVE state is volatile across SVC: 473 // mov x8, #__NR_sched_yield // Enc 602 // mov x8, #__NR_sched_yield // Encourage preemption 474 // svc #0 603 // svc #0 475 604 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 605 mov x21, #0 484 0: mov x0, x21 606 0: mov x0, x21 485 bl check_zreg 607 bl check_zreg 486 add x21, x21, #1 608 add x21, x21, #1 487 cmp x21, #NZR 609 cmp x21, #NZR 488 b.lo 0b 610 b.lo 0b 489 611 490 0: mov x0, x21 612 0: mov x0, x21 491 bl check_preg 613 bl check_preg 492 add x21, x21, #1 614 add x21, x21, #1 493 cmp x21, #NZR + NPR 615 cmp x21, #NZR + NPR 494 b.lo 0b 616 b.lo 0b 495 617 496 bl check_ffr 618 bl check_ffr 497 619 498 add x22, x22, #1 620 add x22, x22, #1 499 b .Ltest_loop 621 b .Ltest_loop 500 622 501 .Labort: 623 .Labort: 502 mov x0, #0 624 mov x0, #0 503 mov x1, #SIGABRT 625 mov x1, #SIGABRT 504 mov x8, #__NR_kill 626 mov x8, #__NR_kill 505 svc #0 627 svc #0 506 endfunction 628 endfunction 507 629 508 function barf 630 function barf 509 // fpsimd.c acitivty log dump hack 631 // fpsimd.c acitivty log dump hack 510 // ldr w0, =0xdeadc0de 632 // ldr w0, =0xdeadc0de 511 // mov w8, #__NR_exit 633 // mov w8, #__NR_exit 512 // svc #0 634 // svc #0 513 // end hack 635 // end hack 514 mov x10, x0 // expected data 636 mov x10, x0 // expected data 515 mov x11, x1 // actual data 637 mov x11, x1 // actual data 516 mov x12, x2 // data size 638 mov x12, x2 // data size 517 639 518 #ifdef SSVE !! 640 puts "Mistatch: PID=" 519 mrs x13, S3_3_C4_C2_2 << 520 #endif << 521 << 522 puts "Mismatch: PID=" << 523 mov x0, x20 641 mov x0, x20 524 bl putdec 642 bl putdec 525 puts ", iteration=" 643 puts ", iteration=" 526 mov x0, x22 644 mov x0, x22 527 bl putdec 645 bl putdec 528 puts ", reg=" 646 puts ", reg=" 529 mov x0, x21 647 mov x0, x21 530 bl putdecn 648 bl putdecn 531 puts "\tExpected [" 649 puts "\tExpected [" 532 mov x0, x10 650 mov x0, x10 533 mov x1, x12 651 mov x1, x12 534 bl dumphex 652 bl dumphex 535 puts "]\n\tGot [" 653 puts "]\n\tGot [" 536 mov x0, x11 654 mov x0, x11 537 mov x1, x12 655 mov x1, x12 538 bl dumphex 656 bl dumphex 539 puts "]\n" 657 puts "]\n" 540 658 541 #ifdef SSVE << 542 puts "\tSVCR: " << 543 mov x0, x13 << 544 bl putdecn << 545 #endif << 546 << 547 mov x8, #__NR_getpid 659 mov x8, #__NR_getpid 548 svc #0 660 svc #0 549 // fpsimd.c acitivty log dump hack 661 // fpsimd.c acitivty log dump hack 550 // ldr w0, =0xdeadc0de 662 // ldr w0, =0xdeadc0de 551 // mov w8, #__NR_exit 663 // mov w8, #__NR_exit 552 // svc #0 664 // svc #0 553 // ^ end of hack 665 // ^ end of hack 554 mov x1, #SIGABRT 666 mov x1, #SIGABRT 555 mov x8, #__NR_kill 667 mov x8, #__NR_kill 556 svc #0 668 svc #0 557 // mov x8, #__NR_exit 669 // mov x8, #__NR_exit 558 // mov x1, #1 670 // mov x1, #1 559 // svc #0 671 // svc #0 560 endfunction 672 endfunction 561 673 562 function vl_barf 674 function vl_barf 563 mov x10, x0 675 mov x10, x0 564 676 565 puts "Bad active VL: " 677 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 678 mov x0, x10 579 bl putdecn 679 bl putdecn 580 680 581 mov x8, #__NR_exit 681 mov x8, #__NR_exit 582 mov x1, #1 682 mov x1, #1 583 svc #0 683 svc #0 584 endfunction 684 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.