1/*- 2 * Copyright (c) 2002, 2003 Marcel Moolenaar 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * 26 * $FreeBSD$ 27 */ 28 29#include <sys/syscall.h> 30#include <machine/asm.h> 31#include <assym.s> 32 33/* 34 * A process performs a syscall by performing an indirect call to the 35 * address stored in ar.k5. The contents of ar.pfs and rp should be 36 * saved prior to the syscall in r9 and r10 respectively. The kernel 37 * will restore these values on return. The value of gp is preserved 38 * across the call. This allows for small enough syscall stubs without 39 * getting too weird. 40 * The address in ar.k5 is the start of the EPC gateway page and also 41 * the syscall entry point. The syscall code in the gateway page is 42 * primarily responsible for increasing the privilege level, but will 43 * also make sure we have a reliable psr. 44 * 45 * A process defines: 46 * r8 - syscall number 47 * r9 - copy of ar.pfs 48 * r10 - copy of rp 49 * in0-in7 - syscall arguments 50 * 51 * A syscall returns: 52 * r8+r9 - syscall return value(s) 53 * r10 - syscall error flag 54 * ar.pfs - restored from r9 55 * rp - restored from r10 56 * gp - preserved 57 * 58 * The EPC syscall code defines: 59 * r11 - copy of psr.l 60 * r14 - Kernel memory stack 61 * r15 - Kernel register stack 62 * 63 * Also in the gateway page are the signal trampolines. As such, stacks 64 * don't have to be made executable per se. Since debuggers have a need 65 * to know about trampolines, we probably need to define a table of 66 * vectors or something along those lines so that debuggers can get the 67 * information they need and we have the freedom to move code around. 68 */ 69 70 .section .text.gateway, "ax" 71 .align PAGE_SIZE 72 .global ia64_gateway_page 73ia64_gateway_page: 74{ .mmb 75 mov r14=ar.k7 // Memory stack 76 mov r15=ar.k6 // Register stack 77 epc 78 ;; 79} 80{ .mlx 81 mov r11=psr 82 movl r31=epc_syscall 83 ;; 84} 85{ .mib 86 rum psr.be 87 mov b7=r31 88 br b7 89 ;; 90} 91gw_ret: 92{ .mmi 93 mov ar.rnat=r22 94 ;; 95 mov ar.rsc=r24 96 mov ar.pfs=r20 97} 98{ .mib 99 mov ar.fpsr=r25 100 mov b0=r18 101 br.sptk b6 102 ;; 103} 104gw_ret_ia32: 105{ .mmi 106 flushrs 107 nop 0 108 nop 0 109 ;; 110} 111{ .mib 112 nop 0 113 nop 0 114 br.ia.sptk b6 115 ;; 116} 117 118 119ENTRY_NOPROFILE(break_sigtramp, 0) 120{ .mib 121 mov ar.rsc=0 122 cmp.ne p15,p0=0,gp 123 cover 124 ;; 125} 126{ .mmi 127 flushrs 128(p15) invala 129 add r16=16+UC_MCONTEXT+MC_SPECIAL,sp 130 ;; 131} 132{ .mmi 133 mov r17=ar.bsp 134 mov r18=ar.rnat 135 add r14=40,r16 136 ;; 137} 138{ .mmi 139 st8 [r14]=r17,64 // bspstore 140(p15) mov ar.bspstore=gp 141 add r15=48,r16 142 ;; 143} 144{ .mmi 145 st8 [r15]=r18 // rnat 146 st8 [r14]=r0 // ndirty 147 nop 0 148 ;; 149} 150{ .mmi 151 alloc r14=ar.pfs, 0, 0, 3, 0 152 mov ar.rsc=15 153 mov out0=r8 154 ;; 155} 156{ .mmi 157 ld8 r16=[r10],8 // function address 158 ;; 159 ld8 gp=[r10] // function's gp value 160 mov b7=r16 161 ;; 162} 163{ .mib 164 mov out1=r9 165 add out2=16,sp 166 br.call.sptk rp=b7 167 ;; 168} 169{ .mmi 170 mov r15=SYS_sigreturn 171 add out0=16,sp 172 break 0x100000 173 ;; 174} 175{ .mmi 176 mov r15=SYS_exit 177 mov out0=ret0 178 break 0x100000 179 ;; 180} 181END(break_sigtramp) 182 183ENTRY_NOPROFILE(epc_sigtramp, 0) 184{ .mmi 185 ld8 r16=[r10],8 // function address 186 mov ar.rsc=0 187 cmp.ne p15,p0=0,gp 188 ;; 189} 190{ .mmi 191(p15) invala 192(p15) mov ar.bspstore=gp 193 mov b7=r16 194 ;; 195} 196{ .mmi 197 alloc r14=ar.pfs, 0, 0, 3, 0 198 mov ar.rsc=15 199 nop 0 200 ;; 201} 202{ .mii 203 ld8 gp=[r10] // function's gp value 204 mov out0=r8 205 mov out1=r9 206} 207{ .mib 208 add out2=16,sp 209 nop 0 210 br.call.sptk rp=b7 211 ;; 212} 213 add out0=16,sp 214 CALLSYS_NOERROR(sigreturn) 215 mov out0=ret0 216 CALLSYS_NOERROR(exit) 217END(epc_sigtramp) 218 219 .align PAGE_SIZE 220 221 .text 222 223ENTRY_NOPROFILE(epc_syscall, 8) 224 .prologue 225 .unwabi @svr4, 'E' 226 .save rp, r0 227 .body 228{ .mmi 229 mov r16=ar.rsc 230 mov ar.rsc=0 231 nop 0 232 ;; 233} 234{ .mmi 235 mov r18=ar.bspstore 236 ;; 237 mov r19=ar.rnat 238 dep r15=r18,r15,0,9 239 ;; 240} 241{ .mmi 242 mov r21=ar.unat 243 add r30=-SIZEOF_TRAPFRAME,r14 244 mov r20=sp 245 ;; 246} 247{ .mii 248 mov r17=r13 249 dep r30=0,r30,0,10 250 ;; 251 add sp=-16,r30 252 ;; 253} 254{ .mmi 255 mov ar.bspstore=r15 256 ;; 257 mov ar.rnat=r19 258 add r31=8,r30 259 ;; 260} 261{ .mmi 262 mov r13=ar.k4 263 mov r22=ar.fpsr 264 sub r29=r14,r30 265} 266{ .mmi 267 mov r23=ar.bsp 268 mov ar.rsc=3 269 add r28=FRAME_SYSCALL,r0 270 ;; 271} 272{ .mmi 273 st8 [r30]=r29,16 // tf_length 274 st8 [r31]=r28,16 // tf_flags 275 mov r24=rp 276 ;; 277} 278{ .mmi 279 st8 [r30]=r20,16 // sp 280 st8 [r31]=r21,16 // unat 281 mov r25=pr 282 ;; 283} 284{ .mmi 285 st8 [r30]=r10,16 // rp (syscall caller) 286 st8 [r31]=r25,16 // pr 287 mov r26=ar.pfs 288 ;; 289} 290{ .mmi 291 st8 [r30]=r9,16 // pfs (syscall caller) 292 st8 [r31]=r18,16 // bspstore 293 sub r27=r23,r15 294 ;; 295} 296{ .mmi 297 st8 [r30]=r19,16 // rnat 298 st8 [r31]=r0,16 // __spare 299 dep r11=-1,r11,44,1 // Set psr.bn=1 300 ;; 301} 302{ .mmi 303 st8 [r30]=r17,16 // tp 304 st8 [r31]=r16,16 // rsc 305 dep r11=-1,r11,32,2 // Set psr.cpl=3 306 ;; 307} 308{ .mmi 309 st8 [r30]=r22,16 // fpsr 310 st8 [r31]=r11,16 // psr 311 nop 0 312 ;; 313} 314{ .mmi 315 st8 [r30]=r1,16 // gp 316 st8 [r31]=r27,16 // ndirty 317 nop 0 318 ;; 319} 320{ .mmi 321 st8 [r30]=r26,16 // pfs (syscall stub) 322 st8 [r31]=r24,16 // rp (syscall stub) 323 nop 0 324 ;; 325} 326{ .mmi 327 st8 [r30]=r0,80 // ifa 328 st8 [r31]=r0,80 // isr 329 nop 0 330 ;; 331} 332{ .mmi 333 alloc r14=ar.pfs,0,0,8,0 334 st8 [r30]=r8,16 // syscall number (=r15) 335 nop 0 336 ;; 337} 338{ .mmi 339 .mem.offset 0,0 340 st8.spill [r31]=r32,16 // arg0 (=r16) 341 .mem.offset 8,0 342 st8.spill [r30]=r33,16 // arg1 (=r17) 343 nop 0 344 ;; 345} 346{ .mmi 347 .mem.offset 16,0 348 st8.spill [r31]=r34,16 // arg2 (=r18) 349 .mem.offset 24,0 350 st8.spill [r30]=r35,16 // arg3 (=r19) 351 nop 0 352 ;; 353} 354{ .mmi 355 .mem.offset 32,0 356 st8.spill [r31]=r36,16 // arg4 (=r20) 357 .mem.offset 40,0 358 st8.spill [r30]=r37,16 // arg5 (=r21) 359 nop 0 360 ;; 361} 362{ .mmi 363 .mem.offset 48,0 364 st8.spill [r31]=r38 // arg6 (=r22) 365 .mem.offset 56,0 366 st8.spill [r30]=r39 // arg7 (=r23) 367 nop 0 368 ;; 369} 370{ .mlx 371 ssm psr.dfh|psr.ac 372 movl gp=__gp 373 ;; 374} 3751: 376{ .mib 377 srlz.d 378 add out0=16,sp 379 br.call.sptk rp=syscall 380 ;; 381} 382 .global epc_syscall_return 383epc_syscall_return: 384{ .mib 385 add out0=16,sp 386 nop 0 387 br.call.sptk rp=do_ast 388 ;; 389} 390{ .mib 391 cmp4.eq p15,p0=ERESTART,r8 392 add r14=24,sp 393(p15) br.spnt 1b // restart syscall 394 ;; 395} 396{ .mmi 397 ld8 r14=[r14] // tf_flags 398 nop 0 399 nop 0 400 ;; 401} 402{ .mib 403 nop 0 404 tbit.z p15,p0=r14,0 405(p15) br.spnt exception_restore 406 ;; 407} 408{ .mmi 409 alloc r31=ar.pfs,0,0,0,0 410 add r14=32,sp 411 add r15=16,sp 412 ;; 413} 414{ .mmi 415 ld8 r31=[r15],24 // tf_length 416 ld8 r16=[r14],16 // sp 417 add sp=16,sp 418 ;; 419} 420{ .mmi 421 ld8 r17=[r15],16 // unat (before) 422 ld8 r18=[r14],16 // rp (syscall caller) 423 add r31=r31,sp 424 ;; 425} 426{ .mmi 427 ld8 r19=[r15],16 // pr 428 ld8 r20=[r14],16 // pfs (syscall caller) 429 nop 0 430 ;; 431} 432{ .mmi 433 ld8 r21=[r15],24 // bspstore 434 ld8 r22=[r14],24 // rnat 435 mov pr=r19,0x1fffe 436 ;; 437} 438{ .mmi 439 ld8 r23=[r15],16 // tp 440 ld8 r24=[r14],16 // rsc 441 nop 0 442 ;; 443} 444{ .mmi 445 ld8 r25=[r15],16 // fpsr 446 ld8 r26=[r14],16 // psr 447 nop 0 448 ;; 449} 450{ .mmi 451 ld8 gp=[r15],16 // gp 452 ld8 r27=[r14],16 // ndirty 453 tbit.z p14,p15=r26,34 // p14=ia64, p15=ia32 454 ;; 455} 456{ .mmi 457 ld8 r28=[r15],56 // pfs (syscall stub) 458 ld8 r29=[r14],56 // rp (syscall stub) 459 shl r27=r27,16 460 ;; 461} 462{ .mmi 463 ld8 r8=[r15],16 // r8 464 mov ar.rsc=r27 465 mov b6=r29 466 ;; 467} 468{ .mmb 469 ld8 r9=[r14],40 // r9 470 ld8 r10=[r15],40 // r10 471(p15) br.spnt epc_syscall_setup_ia32 472 ;; 473} 474{ .mmi 475 loadrs 476 mov ar.k7=r31 477 mov sp=r16 478 ;; 479} 480{ .mmi 481 mov r30=ar.bspstore 482 mov r14=ar.k5 483 mov ar.pfs=r28 484 ;; 485} 486{ .mmi 487 mov ar.bspstore=r21 488 add r14=gw_ret-ia64_gateway_page,r14 489 dep r30=0,r30,0,13 // 8KB aligned. 490 ;; 491} 492{ .mii 493 mov ar.k6=r30 494 mov r13=r23 495 nop 0 496} 497{ .mmi 498 mov psr.l=r26 499 mov ar.unat=r17 500 nop 0 501 ;; 502} 503{ .mib 504 srlz.d 505 mov b7=r14 506 br.ret.sptk b7 507 ;; 508} 509epc_syscall_setup_ia32: 510{ .mmi 511 loadrs 512 mov ar.k7=r31 513 mov sp=r16 514 ;; 515} 516{ .mmi 517 mov r30=ar.bspstore 518 ;; 519 mov ar.unat=r17 520 dep r30=0,r30,0,13 // 8KB aligned 521 ;; 522} 523{ .mmi 524 mov ar.k6=r30 525 mov ar.bspstore=r21 526 mov r11=r0 527 ;; 528} 529{ .mmi 530 ld8 r16=[r14],64 531 ld8 r17=[r15],80 532 mov r13=r0 533 ;; 534} 535 536 ld8 r24=[r14],32 537 ld8 r27=[r15],16 538 ;; 539 ld8 r28=[r14],16 540 ld8 r29=[r15],16 541 ;; 542 ld8 r30=[r14],40 543 ld8 r31=[r15],40 544 ;; 545 546{ .mmi 547 ld8 r2=[r14] 548 ld8 r3=[r15] 549 mov r14=r0 550 ;; 551} 552{ .mmi 553 mov ar.csd=r2 554 mov ar.ssd=r3 555 mov r15=r0 556 ;; 557} 558 559 mov r2=ar.k5 560 mov psr.l=r26 561 ;; 562 srlz.d 563 add r2=gw_ret_ia32-ia64_gateway_page,r2 564 ;; 565 mov ar.rsc=0 566 mov b7=r2 567 br.ret.sptk b7 568 ;; 569END(epc_syscall) 570