1/* 2 * Linux/PA-RISC Project (http://www.parisc-linux.org/) 3 * 4 * kernel entry points (interruptions, system call wrappers) 5 * Copyright (C) 1999,2000 Philipp Rumpf 6 * Copyright (C) 1999 SuSE GmbH Nuernberg 7 * Copyright (C) 2000 Hewlett-Packard (John Marvin) 8 * Copyright (C) 1999 Hewlett-Packard (Frank Rowand) 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License as published by 12 * the Free Software Foundation; either version 2, or (at your option) 13 * any later version. 14 * 15 * This program is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with this program; if not, write to the Free Software 22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 23 */ 24 25#include <linux/config.h> 26#include <asm/asm-offsets.h> 27 28/* we have the following possibilities to act on an interruption: 29 * - handle in assembly and use shadowed registers only 30 * - save registers to kernel stack and handle in assembly or C */ 31 32 33#include <asm/psw.h> 34#include <asm/assembly.h> /* for LDREG/STREG defines */ 35#include <asm/pgtable.h> 36#include <asm/signal.h> 37#include <asm/unistd.h> 38#include <asm/thread_info.h> 39 40#ifdef CONFIG_64BIT 41#define CMPIB cmpib,* 42#define CMPB cmpb,* 43#define COND(x) *x 44 45 .level 2.0w 46#else 47#define CMPIB cmpib, 48#define CMPB cmpb, 49#define COND(x) x 50 51 .level 2.0 52#endif 53 54 .import pa_dbit_lock,data 55 56 /* space_to_prot macro creates a prot id from a space id */ 57 58#if (SPACEID_SHIFT) == 0 59 .macro space_to_prot spc prot 60 depd,z \spc,62,31,\prot 61 .endm 62#else 63 .macro space_to_prot spc prot 64 extrd,u \spc,(64 - (SPACEID_SHIFT)),32,\prot 65 .endm 66#endif 67 68 /* Switch to virtual mapping, trashing only %r1 */ 69 .macro virt_map 70 /* pcxt_ssm_bug */ 71 rsm PSW_SM_I, %r0 /* barrier for "Relied upon Translation */ 72 mtsp %r0, %sr4 73 mtsp %r0, %sr5 74 mfsp %sr7, %r1 75 or,= %r0,%r1,%r0 /* Only save sr7 in sr3 if sr7 != 0 */ 76 mtsp %r1, %sr3 77 tovirt_r1 %r29 78 load32 KERNEL_PSW, %r1 79 80 rsm PSW_SM_QUIET,%r0 /* second "heavy weight" ctl op */ 81 mtsp %r0, %sr6 82 mtsp %r0, %sr7 83 mtctl %r0, %cr17 /* Clear IIASQ tail */ 84 mtctl %r0, %cr17 /* Clear IIASQ head */ 85 mtctl %r1, %ipsw 86 load32 4f, %r1 87 mtctl %r1, %cr18 /* Set IIAOQ tail */ 88 ldo 4(%r1), %r1 89 mtctl %r1, %cr18 /* Set IIAOQ head */ 90 rfir 91 nop 924: 93 .endm 94 95 /* 96 * The "get_stack" macros are responsible for determining the 97 * kernel stack value. 98 * 99 * For Faults: 100 * If sr7 == 0 101 * Already using a kernel stack, so call the 102 * get_stack_use_r30 macro to push a pt_regs structure 103 * on the stack, and store registers there. 104 * else 105 * Need to set up a kernel stack, so call the 106 * get_stack_use_cr30 macro to set up a pointer 107 * to the pt_regs structure contained within the 108 * task pointer pointed to by cr30. Set the stack 109 * pointer to point to the end of the task structure. 110 * 111 * For Interrupts: 112 * If sr7 == 0 113 * Already using a kernel stack, check to see if r30 114 * is already pointing to the per processor interrupt 115 * stack. If it is, call the get_stack_use_r30 macro 116 * to push a pt_regs structure on the stack, and store 117 * registers there. Otherwise, call get_stack_use_cr31 118 * to get a pointer to the base of the interrupt stack 119 * and push a pt_regs structure on that stack. 120 * else 121 * Need to set up a kernel stack, so call the 122 * get_stack_use_cr30 macro to set up a pointer 123 * to the pt_regs structure contained within the 124 * task pointer pointed to by cr30. Set the stack 125 * pointer to point to the end of the task structure. 126 * N.B: We don't use the interrupt stack for the 127 * first interrupt from userland, because signals/ 128 * resched's are processed when returning to userland, 129 * and we can sleep in those cases. 130 * 131 * Note that we use shadowed registers for temps until 132 * we can save %r26 and %r29. %r26 is used to preserve 133 * %r8 (a shadowed register) which temporarily contained 134 * either the fault type ("code") or the eirr. We need 135 * to use a non-shadowed register to carry the value over 136 * the rfir in virt_map. We use %r26 since this value winds 137 * up being passed as the argument to either do_cpu_irq_mask 138 * or handle_interruption. %r29 is used to hold a pointer 139 * the register save area, and once again, it needs to 140 * be a non-shadowed register so that it survives the rfir. 141 * 142 * N.B. TASK_SZ_ALGN and PT_SZ_ALGN include space for a stack frame. 143 */ 144 145 .macro get_stack_use_cr30 146 147 /* we save the registers in the task struct */ 148 149 mfctl %cr30, %r1 150 tophys %r1,%r9 151 LDREG TI_TASK(%r9), %r1 /* thread_info -> task_struct */ 152 tophys %r1,%r9 153 ldo TASK_REGS(%r9),%r9 154 STREG %r30, PT_GR30(%r9) 155 STREG %r29,PT_GR29(%r9) 156 STREG %r26,PT_GR26(%r9) 157 copy %r9,%r29 158 mfctl %cr30, %r1 159 ldo THREAD_SZ_ALGN(%r1), %r30 160 .endm 161 162 .macro get_stack_use_r30 163 164 /* we put a struct pt_regs on the stack and save the registers there */ 165 166 tophys %r30,%r9 167 STREG %r30,PT_GR30(%r9) 168 ldo PT_SZ_ALGN(%r30),%r30 169 STREG %r29,PT_GR29(%r9) 170 STREG %r26,PT_GR26(%r9) 171 copy %r9,%r29 172 .endm 173 174 .macro rest_stack 175 LDREG PT_GR1(%r29), %r1 176 LDREG PT_GR30(%r29),%r30 177 LDREG PT_GR29(%r29),%r29 178 .endm 179 180 /* default interruption handler 181 * (calls traps.c:handle_interruption) */ 182 .macro def code 183 b intr_save 184 ldi \code, %r8 185 .align 32 186 .endm 187 188 /* Interrupt interruption handler 189 * (calls irq.c:do_cpu_irq_mask) */ 190 .macro extint code 191 b intr_extint 192 mfsp %sr7,%r16 193 .align 32 194 .endm 195 196 .import os_hpmc, code 197 198 /* HPMC handler */ 199 .macro hpmc code 200 nop /* must be a NOP, will be patched later */ 201 load32 PA(os_hpmc), %r3 202 bv,n 0(%r3) 203 nop 204 .word 0 /* checksum (will be patched) */ 205 .word PA(os_hpmc) /* address of handler */ 206 .word 0 /* length of handler */ 207 .endm 208 209 /* 210 * Performance Note: Instructions will be moved up into 211 * this part of the code later on, once we are sure 212 * that the tlb miss handlers are close to final form. 213 */ 214 215 /* Register definitions for tlb miss handler macros */ 216 217 va = r8 /* virtual address for which the trap occured */ 218 spc = r24 /* space for which the trap occured */ 219 220#ifndef CONFIG_64BIT 221 222 /* 223 * itlb miss interruption handler (parisc 1.1 - 32 bit) 224 */ 225 226 .macro itlb_11 code 227 228 mfctl %pcsq, spc 229 b itlb_miss_11 230 mfctl %pcoq, va 231 232 .align 32 233 .endm 234#endif 235 236 /* 237 * itlb miss interruption handler (parisc 2.0) 238 */ 239 240 .macro itlb_20 code 241 mfctl %pcsq, spc 242#ifdef CONFIG_64BIT 243 b itlb_miss_20w 244#else 245 b itlb_miss_20 246#endif 247 mfctl %pcoq, va 248 249 .align 32 250 .endm 251 252#ifndef CONFIG_64BIT 253 /* 254 * naitlb miss interruption handler (parisc 1.1 - 32 bit) 255 * 256 * Note: naitlb misses will be treated 257 * as an ordinary itlb miss for now. 258 * However, note that naitlb misses 259 * have the faulting address in the 260 * IOR/ISR. 261 */ 262 263 .macro naitlb_11 code 264 265 mfctl %isr,spc 266 b itlb_miss_11 267 mfctl %ior,va 268 /* FIXME: If user causes a naitlb miss, the priv level may not be in 269 * lower bits of va, where the itlb miss handler is expecting them 270 */ 271 272 .align 32 273 .endm 274#endif 275 276 /* 277 * naitlb miss interruption handler (parisc 2.0) 278 * 279 * Note: naitlb misses will be treated 280 * as an ordinary itlb miss for now. 281 * However, note that naitlb misses 282 * have the faulting address in the 283 * IOR/ISR. 284 */ 285 286 .macro naitlb_20 code 287 288 mfctl %isr,spc 289#ifdef CONFIG_64BIT 290 b itlb_miss_20w 291#else 292 b itlb_miss_20 293#endif 294 mfctl %ior,va 295 /* FIXME: If user causes a naitlb miss, the priv level may not be in 296 * lower bits of va, where the itlb miss handler is expecting them 297 */ 298 299 .align 32 300 .endm 301 302#ifndef CONFIG_64BIT 303 /* 304 * dtlb miss interruption handler (parisc 1.1 - 32 bit) 305 */ 306 307 .macro dtlb_11 code 308 309 mfctl %isr, spc 310 b dtlb_miss_11 311 mfctl %ior, va 312 313 .align 32 314 .endm 315#endif 316 317 /* 318 * dtlb miss interruption handler (parisc 2.0) 319 */ 320 321 .macro dtlb_20 code 322 323 mfctl %isr, spc 324#ifdef CONFIG_64BIT 325 b dtlb_miss_20w 326#else 327 b dtlb_miss_20 328#endif 329 mfctl %ior, va 330 331 .align 32 332 .endm 333 334#ifndef CONFIG_64BIT 335 /* nadtlb miss interruption handler (parisc 1.1 - 32 bit) */ 336 337 .macro nadtlb_11 code 338 339 mfctl %isr,spc 340 b nadtlb_miss_11 341 mfctl %ior,va 342 343 .align 32 344 .endm 345#endif 346 347 /* nadtlb miss interruption handler (parisc 2.0) */ 348 349 .macro nadtlb_20 code 350 351 mfctl %isr,spc 352#ifdef CONFIG_64BIT 353 b nadtlb_miss_20w 354#else 355 b nadtlb_miss_20 356#endif 357 mfctl %ior,va 358 359 .align 32 360 .endm 361 362#ifndef CONFIG_64BIT 363 /* 364 * dirty bit trap interruption handler (parisc 1.1 - 32 bit) 365 */ 366 367 .macro dbit_11 code 368 369 mfctl %isr,spc 370 b dbit_trap_11 371 mfctl %ior,va 372 373 .align 32 374 .endm 375#endif 376 377 /* 378 * dirty bit trap interruption handler (parisc 2.0) 379 */ 380 381 .macro dbit_20 code 382 383 mfctl %isr,spc 384#ifdef CONFIG_64BIT 385 b dbit_trap_20w 386#else 387 b dbit_trap_20 388#endif 389 mfctl %ior,va 390 391 .align 32 392 .endm 393 394 /* The following are simple 32 vs 64 bit instruction 395 * abstractions for the macros */ 396 .macro EXTR reg1,start,length,reg2 397#ifdef CONFIG_64BIT 398 extrd,u \reg1,32+\start,\length,\reg2 399#else 400 extrw,u \reg1,\start,\length,\reg2 401#endif 402 .endm 403 404 .macro DEP reg1,start,length,reg2 405#ifdef CONFIG_64BIT 406 depd \reg1,32+\start,\length,\reg2 407#else 408 depw \reg1,\start,\length,\reg2 409#endif 410 .endm 411 412 .macro DEPI val,start,length,reg 413#ifdef CONFIG_64BIT 414 depdi \val,32+\start,\length,\reg 415#else 416 depwi \val,\start,\length,\reg 417#endif 418 .endm 419 420 /* In LP64, the space contains part of the upper 32 bits of the 421 * fault. We have to extract this and place it in the va, 422 * zeroing the corresponding bits in the space register */ 423 .macro space_adjust spc,va,tmp 424#ifdef CONFIG_64BIT 425 extrd,u \spc,63,SPACEID_SHIFT,\tmp 426 depd %r0,63,SPACEID_SHIFT,\spc 427 depd \tmp,31,SPACEID_SHIFT,\va 428#endif 429 .endm 430 431 .import swapper_pg_dir,code 432 433 /* Get the pgd. For faults on space zero (kernel space), this 434 * is simply swapper_pg_dir. For user space faults, the 435 * pgd is stored in %cr25 */ 436 .macro get_pgd spc,reg 437 ldil L%PA(swapper_pg_dir),\reg 438 ldo R%PA(swapper_pg_dir)(\reg),\reg 439 or,COND(=) %r0,\spc,%r0 440 mfctl %cr25,\reg 441 .endm 442 443 /* 444 space_check(spc,tmp,fault) 445 446 spc - The space we saw the fault with. 447 tmp - The place to store the current space. 448 fault - Function to call on failure. 449 450 Only allow faults on different spaces from the 451 currently active one if we're the kernel 452 453 */ 454 .macro space_check spc,tmp,fault 455 mfsp %sr7,\tmp 456 or,COND(<>) %r0,\spc,%r0 /* user may execute gateway page 457 * as kernel, so defeat the space 458 * check if it is */ 459 copy \spc,\tmp 460 or,COND(=) %r0,\tmp,%r0 /* nullify if executing as kernel */ 461 cmpb,COND(<>),n \tmp,\spc,\fault 462 .endm 463 464 /* Look up a PTE in a 2-Level scheme (faulting at each 465 * level if the entry isn't present 466 * 467 * NOTE: we use ldw even for LP64, since the short pointers 468 * can address up to 1TB 469 */ 470 .macro L2_ptep pmd,pte,index,va,fault 471#if PT_NLEVELS == 3 472 EXTR \va,31-ASM_PMD_SHIFT,ASM_BITS_PER_PMD,\index 473#else 474 EXTR \va,31-ASM_PGDIR_SHIFT,ASM_BITS_PER_PGD,\index 475#endif 476 DEP %r0,31,PAGE_SHIFT,\pmd /* clear offset */ 477 copy %r0,\pte 478 ldw,s \index(\pmd),\pmd 479 bb,>=,n \pmd,_PxD_PRESENT_BIT,\fault 480 DEP %r0,31,PxD_FLAG_SHIFT,\pmd /* clear flags */ 481 copy \pmd,%r9 482#ifdef CONFIG_64BIT 483 shld %r9,PxD_VALUE_SHIFT,\pmd 484#else 485 shlw %r9,PxD_VALUE_SHIFT,\pmd 486#endif 487 EXTR \va,31-PAGE_SHIFT,ASM_BITS_PER_PTE,\index 488 DEP %r0,31,PAGE_SHIFT,\pmd /* clear offset */ 489 shladd \index,BITS_PER_PTE_ENTRY,\pmd,\pmd 490 LDREG %r0(\pmd),\pte /* pmd is now pte */ 491 bb,>=,n \pte,_PAGE_PRESENT_BIT,\fault 492 .endm 493 494 /* Look up PTE in a 3-Level scheme. 495 * 496 * Here we implement a Hybrid L2/L3 scheme: we allocate the 497 * first pmd adjacent to the pgd. This means that we can 498 * subtract a constant offset to get to it. The pmd and pgd 499 * sizes are arranged so that a single pmd covers 4GB (giving 500 * a full LP64 process access to 8TB) so our lookups are 501 * effectively L2 for the first 4GB of the kernel (i.e. for 502 * all ILP32 processes and all the kernel for machines with 503 * under 4GB of memory) */ 504 .macro L3_ptep pgd,pte,index,va,fault 505 extrd,u \va,63-ASM_PGDIR_SHIFT,ASM_BITS_PER_PGD,\index 506 copy %r0,\pte 507 extrd,u,*= \va,31,32,%r0 508 ldw,s \index(\pgd),\pgd 509 extrd,u,*= \va,31,32,%r0 510 bb,>=,n \pgd,_PxD_PRESENT_BIT,\fault 511 extrd,u,*= \va,31,32,%r0 512 shld \pgd,PxD_VALUE_SHIFT,\index 513 extrd,u,*= \va,31,32,%r0 514 copy \index,\pgd 515 extrd,u,*<> \va,31,32,%r0 516 ldo ASM_PGD_PMD_OFFSET(\pgd),\pgd 517 L2_ptep \pgd,\pte,\index,\va,\fault 518 .endm 519 520 /* Set the _PAGE_ACCESSED bit of the PTE. Be clever and 521 * don't needlessly dirty the cache line if it was already set */ 522 .macro update_ptep ptep,pte,tmp,tmp1 523 ldi _PAGE_ACCESSED,\tmp1 524 or \tmp1,\pte,\tmp 525 and,COND(<>) \tmp1,\pte,%r0 526 STREG \tmp,0(\ptep) 527 .endm 528 529 /* Set the dirty bit (and accessed bit). No need to be 530 * clever, this is only used from the dirty fault */ 531 .macro update_dirty ptep,pte,tmp 532 ldi _PAGE_ACCESSED|_PAGE_DIRTY,\tmp 533 or \tmp,\pte,\pte 534 STREG \pte,0(\ptep) 535 .endm 536 537 /* Convert the pte and prot to tlb insertion values. How 538 * this happens is quite subtle, read below */ 539 .macro make_insert_tlb spc,pte,prot 540 space_to_prot \spc \prot /* create prot id from space */ 541 /* The following is the real subtlety. This is depositing 542 * T <-> _PAGE_REFTRAP 543 * D <-> _PAGE_DIRTY 544 * B <-> _PAGE_DMB (memory break) 545 * 546 * Then incredible subtlety: The access rights are 547 * _PAGE_GATEWAY _PAGE_EXEC _PAGE_READ 548 * See 3-14 of the parisc 2.0 manual 549 * 550 * Finally, _PAGE_READ goes in the top bit of PL1 (so we 551 * trigger an access rights trap in user space if the user 552 * tries to read an unreadable page */ 553 depd \pte,8,7,\prot 554 555 /* PAGE_USER indicates the page can be read with user privileges, 556 * so deposit X1|11 to PL1|PL2 (remember the upper bit of PL1 557 * contains _PAGE_READ */ 558 extrd,u,*= \pte,_PAGE_USER_BIT+32,1,%r0 559 depdi 7,11,3,\prot 560 /* If we're a gateway page, drop PL2 back to zero for promotion 561 * to kernel privilege (so we can execute the page as kernel). 562 * Any privilege promotion page always denys read and write */ 563 extrd,u,*= \pte,_PAGE_GATEWAY_BIT+32,1,%r0 564 depd %r0,11,2,\prot /* If Gateway, Set PL2 to 0 */ 565 566 /* Get rid of prot bits and convert to page addr for iitlbt and idtlbt */ 567 568 depd %r0,63,PAGE_SHIFT,\pte 569 extrd,s \pte,(63-PAGE_SHIFT)+(63-58),64-PAGE_SHIFT,\pte 570 .endm 571 572 /* Identical macro to make_insert_tlb above, except it 573 * makes the tlb entry for the differently formatted pa11 574 * insertion instructions */ 575 .macro make_insert_tlb_11 spc,pte,prot 576 zdep \spc,30,15,\prot 577 dep \pte,8,7,\prot 578 extru,= \pte,_PAGE_NO_CACHE_BIT,1,%r0 579 depi 1,12,1,\prot 580 extru,= \pte,_PAGE_USER_BIT,1,%r0 581 depi 7,11,3,\prot /* Set for user space (1 rsvd for read) */ 582 extru,= \pte,_PAGE_GATEWAY_BIT,1,%r0 583 depi 0,11,2,\prot /* If Gateway, Set PL2 to 0 */ 584 585 /* Get rid of prot bits and convert to page addr for iitlba */ 586 587 depi 0,31,PAGE_SHIFT,\pte 588 extru \pte,24,25,\pte 589 590 .endm 591 592 /* This is for ILP32 PA2.0 only. The TLB insertion needs 593 * to extend into I/O space if the address is 0xfXXXXXXX 594 * so we extend the f's into the top word of the pte in 595 * this case */ 596 .macro f_extend pte,tmp 597 extrd,s \pte,42,4,\tmp 598 addi,<> 1,\tmp,%r0 599 extrd,s \pte,63,25,\pte 600 .endm 601 602 /* The alias region is an 8MB aligned 16MB to do clear and 603 * copy user pages at addresses congruent with the user 604 * virtual address. 605 * 606 * To use the alias page, you set %r26 up with the to TLB 607 * entry (identifying the physical page) and %r23 up with 608 * the from tlb entry (or nothing if only a to entry---for 609 * clear_user_page_asm) */ 610 .macro do_alias spc,tmp,tmp1,va,pte,prot,fault 611 cmpib,COND(<>),n 0,\spc,\fault 612 ldil L%(TMPALIAS_MAP_START),\tmp 613#if defined(CONFIG_64BIT) && (TMPALIAS_MAP_START >= 0x80000000) 614 /* on LP64, ldi will sign extend into the upper 32 bits, 615 * which is behaviour we don't want */ 616 depdi 0,31,32,\tmp 617#endif 618 copy \va,\tmp1 619 DEPI 0,31,23,\tmp1 620 cmpb,COND(<>),n \tmp,\tmp1,\fault 621 ldi (_PAGE_DIRTY|_PAGE_WRITE|_PAGE_READ),\prot 622 depd,z \prot,8,7,\prot 623 /* 624 * OK, it is in the temp alias region, check whether "from" or "to". 625 * Check "subtle" note in pacache.S re: r23/r26. 626 */ 627#ifdef CONFIG_64BIT 628 extrd,u,*= \va,41,1,%r0 629#else 630 extrw,u,= \va,9,1,%r0 631#endif 632 or,COND(tr) %r23,%r0,\pte 633 or %r26,%r0,\pte 634 .endm 635 636 637 /* 638 * Align fault_vector_20 on 4K boundary so that both 639 * fault_vector_11 and fault_vector_20 are on the 640 * same page. This is only necessary as long as we 641 * write protect the kernel text, which we may stop 642 * doing once we use large page translations to cover 643 * the static part of the kernel address space. 644 */ 645 646 .export fault_vector_20 647 648 .text 649 650 .align 4096 651 652fault_vector_20: 653 /* First vector is invalid (0) */ 654 .ascii "cows can fly" 655 .byte 0 656 .align 32 657 658 hpmc 1 659 def 2 660 def 3 661 extint 4 662 def 5 663 itlb_20 6 664 def 7 665 def 8 666 def 9 667 def 10 668 def 11 669 def 12 670 def 13 671 def 14 672 dtlb_20 15 673#if 0 674 naitlb_20 16 675#else 676 def 16 677#endif 678 nadtlb_20 17 679 def 18 680 def 19 681 dbit_20 20 682 def 21 683 def 22 684 def 23 685 def 24 686 def 25 687 def 26 688 def 27 689 def 28 690 def 29 691 def 30 692 def 31 693 694#ifndef CONFIG_64BIT 695 696 .export fault_vector_11 697 698 .align 2048 699 700fault_vector_11: 701 /* First vector is invalid (0) */ 702 .ascii "cows can fly" 703 .byte 0 704 .align 32 705 706 hpmc 1 707 def 2 708 def 3 709 extint 4 710 def 5 711 itlb_11 6 712 def 7 713 def 8 714 def 9 715 def 10 716 def 11 717 def 12 718 def 13 719 def 14 720 dtlb_11 15 721#if 0 722 naitlb_11 16 723#else 724 def 16 725#endif 726 nadtlb_11 17 727 def 18 728 def 19 729 dbit_11 20 730 def 21 731 def 22 732 def 23 733 def 24 734 def 25 735 def 26 736 def 27 737 def 28 738 def 29 739 def 30 740 def 31 741 742#endif 743 744 .import handle_interruption,code 745 .import do_cpu_irq_mask,code 746 747 /* 748 * r26 = function to be called 749 * r25 = argument to pass in 750 * r24 = flags for do_fork() 751 * 752 * Kernel threads don't ever return, so they don't need 753 * a true register context. We just save away the arguments 754 * for copy_thread/ret_ to properly set up the child. 755 */ 756 757#define CLONE_VM 0x100 /* Must agree with <linux/sched.h> */ 758#define CLONE_UNTRACED 0x00800000 759 760 .export __kernel_thread, code 761 .import do_fork 762__kernel_thread: 763 STREG %r2, -RP_OFFSET(%r30) 764 765 copy %r30, %r1 766 ldo PT_SZ_ALGN(%r30),%r30 767#ifdef CONFIG_64BIT 768 /* Yo, function pointers in wide mode are little structs... -PB */ 769 ldd 24(%r26), %r2 770 STREG %r2, PT_GR27(%r1) /* Store childs %dp */ 771 ldd 16(%r26), %r26 772 773 STREG %r22, PT_GR22(%r1) /* save r22 (arg5) */ 774 copy %r0, %r22 /* user_tid */ 775#endif 776 STREG %r26, PT_GR26(%r1) /* Store function & argument for child */ 777 STREG %r25, PT_GR25(%r1) 778 ldil L%CLONE_UNTRACED, %r26 779 ldo CLONE_VM(%r26), %r26 /* Force CLONE_VM since only init_mm */ 780 or %r26, %r24, %r26 /* will have kernel mappings. */ 781 ldi 1, %r25 /* stack_start, signals kernel thread */ 782 stw %r0, -52(%r30) /* user_tid */ 783#ifdef CONFIG_64BIT 784 ldo -16(%r30),%r29 /* Reference param save area */ 785#endif 786 BL do_fork, %r2 787 copy %r1, %r24 /* pt_regs */ 788 789 /* Parent Returns here */ 790 791 LDREG -PT_SZ_ALGN-RP_OFFSET(%r30), %r2 792 ldo -PT_SZ_ALGN(%r30), %r30 793 bv %r0(%r2) 794 nop 795 796 /* 797 * Child Returns here 798 * 799 * copy_thread moved args from temp save area set up above 800 * into task save area. 801 */ 802 803 .export ret_from_kernel_thread 804ret_from_kernel_thread: 805 806 /* Call schedule_tail first though */ 807 BL schedule_tail, %r2 808 nop 809 810 LDREG TI_TASK-THREAD_SZ_ALGN(%r30), %r1 811 LDREG TASK_PT_GR25(%r1), %r26 812#ifdef CONFIG_64BIT 813 LDREG TASK_PT_GR27(%r1), %r27 814 LDREG TASK_PT_GR22(%r1), %r22 815#endif 816 LDREG TASK_PT_GR26(%r1), %r1 817 ble 0(%sr7, %r1) 818 copy %r31, %r2 819 820#ifdef CONFIG_64BIT 821 ldo -16(%r30),%r29 /* Reference param save area */ 822 loadgp /* Thread could have been in a module */ 823#endif 824#ifndef CONFIG_64BIT 825 b sys_exit 826#else 827 load32 sys_exit, %r1 828 bv %r0(%r1) 829#endif 830 ldi 0, %r26 831 832 .import sys_execve, code 833 .export __execve, code 834__execve: 835 copy %r2, %r15 836 copy %r30, %r16 837 ldo PT_SZ_ALGN(%r30), %r30 838 STREG %r26, PT_GR26(%r16) 839 STREG %r25, PT_GR25(%r16) 840 STREG %r24, PT_GR24(%r16) 841#ifdef CONFIG_64BIT 842 ldo -16(%r30),%r29 /* Reference param save area */ 843#endif 844 BL sys_execve, %r2 845 copy %r16, %r26 846 847 cmpib,=,n 0,%r28,intr_return /* forward */ 848 849 /* yes, this will trap and die. */ 850 copy %r15, %r2 851 copy %r16, %r30 852 bv %r0(%r2) 853 nop 854 855 .align 4 856 857 /* 858 * struct task_struct *_switch_to(struct task_struct *prev, 859 * struct task_struct *next) 860 * 861 * switch kernel stacks and return prev */ 862 .export _switch_to, code 863_switch_to: 864 STREG %r2, -RP_OFFSET(%r30) 865 866 callee_save_float 867 callee_save 868 869 load32 _switch_to_ret, %r2 870 871 STREG %r2, TASK_PT_KPC(%r26) 872 LDREG TASK_PT_KPC(%r25), %r2 873 874 STREG %r30, TASK_PT_KSP(%r26) 875 LDREG TASK_PT_KSP(%r25), %r30 876 LDREG TASK_THREAD_INFO(%r25), %r25 877 bv %r0(%r2) 878 mtctl %r25,%cr30 879 880_switch_to_ret: 881 mtctl %r0, %cr0 /* Needed for single stepping */ 882 callee_rest 883 callee_rest_float 884 885 LDREG -RP_OFFSET(%r30), %r2 886 bv %r0(%r2) 887 copy %r26, %r28 888 889 /* 890 * Common rfi return path for interruptions, kernel execve, and 891 * sys_rt_sigreturn (sometimes). The sys_rt_sigreturn syscall will 892 * return via this path if the signal was received when the process 893 * was running; if the process was blocked on a syscall then the 894 * normal syscall_exit path is used. All syscalls for traced 895 * proceses exit via intr_restore. 896 * 897 * XXX If any syscalls that change a processes space id ever exit 898 * this way, then we will need to copy %sr3 in to PT_SR[3..7], and 899 * adjust IASQ[0..1]. 900 * 901 */ 902 903 .align 4096 904 905 .export syscall_exit_rfi 906syscall_exit_rfi: 907 mfctl %cr30,%r16 908 LDREG TI_TASK(%r16), %r16 /* thread_info -> task_struct */ 909 ldo TASK_REGS(%r16),%r16 910 /* Force iaoq to userspace, as the user has had access to our current 911 * context via sigcontext. Also Filter the PSW for the same reason. 912 */ 913 LDREG PT_IAOQ0(%r16),%r19 914 depi 3,31,2,%r19 915 STREG %r19,PT_IAOQ0(%r16) 916 LDREG PT_IAOQ1(%r16),%r19 917 depi 3,31,2,%r19 918 STREG %r19,PT_IAOQ1(%r16) 919 LDREG PT_PSW(%r16),%r19 920 load32 USER_PSW_MASK,%r1 921#ifdef CONFIG_64BIT 922 load32 USER_PSW_HI_MASK,%r20 923 depd %r20,31,32,%r1 924#endif 925 and %r19,%r1,%r19 /* Mask out bits that user shouldn't play with */ 926 load32 USER_PSW,%r1 927 or %r19,%r1,%r19 /* Make sure default USER_PSW bits are set */ 928 STREG %r19,PT_PSW(%r16) 929 930 /* 931 * If we aren't being traced, we never saved space registers 932 * (we don't store them in the sigcontext), so set them 933 * to "proper" values now (otherwise we'll wind up restoring 934 * whatever was last stored in the task structure, which might 935 * be inconsistent if an interrupt occured while on the gateway 936 * page) Note that we may be "trashing" values the user put in 937 * them, but we don't support the the user changing them. 938 */ 939 940 STREG %r0,PT_SR2(%r16) 941 mfsp %sr3,%r19 942 STREG %r19,PT_SR0(%r16) 943 STREG %r19,PT_SR1(%r16) 944 STREG %r19,PT_SR3(%r16) 945 STREG %r19,PT_SR4(%r16) 946 STREG %r19,PT_SR5(%r16) 947 STREG %r19,PT_SR6(%r16) 948 STREG %r19,PT_SR7(%r16) 949 950intr_return: 951 /* NOTE: Need to enable interrupts incase we schedule. */ 952 ssm PSW_SM_I, %r0 953 954 /* Check for software interrupts */ 955 956 .import irq_stat,data 957 958 load32 irq_stat,%r19 959#ifdef CONFIG_SMP 960 mfctl %cr30,%r1 961 ldw TI_CPU(%r1),%r1 /* get cpu # - int */ 962 /* shift left ____cacheline_aligned (aka L1_CACHE_BYTES) amount 963 ** irq_stat[] is defined using ____cacheline_aligned. 964 */ 965#ifdef CONFIG_64BIT 966 shld %r1, 6, %r20 967#else 968 shlw %r1, 5, %r20 969#endif 970 add %r19,%r20,%r19 /* now have &irq_stat[smp_processor_id()] */ 971#endif /* CONFIG_SMP */ 972 973intr_check_resched: 974 975 /* check for reschedule */ 976 mfctl %cr30,%r1 977 LDREG TI_FLAGS(%r1),%r19 /* sched.h: TIF_NEED_RESCHED */ 978 bb,<,n %r19,31-TIF_NEED_RESCHED,intr_do_resched /* forward */ 979 980intr_check_sig: 981 /* As above */ 982 mfctl %cr30,%r1 983 LDREG TI_FLAGS(%r1),%r19 /* sched.h: TIF_SIGPENDING */ 984 bb,<,n %r19, 31-TIF_SIGPENDING, intr_do_signal /* forward */ 985 986intr_restore: 987 copy %r16,%r29 988 ldo PT_FR31(%r29),%r1 989 rest_fp %r1 990 rest_general %r29 991 992 /* inverse of virt_map */ 993 pcxt_ssm_bug 994 rsm PSW_SM_QUIET,%r0 /* prepare for rfi */ 995 tophys_r1 %r29 996 997 /* Restore space id's and special cr's from PT_REGS 998 * structure pointed to by r29 999 */ 1000 rest_specials %r29 1001 1002 /* IMPORTANT: rest_stack restores r29 last (we are using it)! 1003 * It also restores r1 and r30. 1004 */ 1005 rest_stack 1006 1007 rfi 1008 nop 1009 nop 1010 nop 1011 nop 1012 nop 1013 nop 1014 nop 1015 nop 1016 1017#ifndef CONFIG_PREEMPT 1018# define intr_do_preempt intr_restore 1019#endif /* !CONFIG_PREEMPT */ 1020 1021 .import schedule,code 1022intr_do_resched: 1023 /* Only call schedule on return to userspace. If we're returning 1024 * to kernel space, we may schedule if CONFIG_PREEMPT, otherwise 1025 * we jump back to intr_restore. 1026 */ 1027 LDREG PT_IASQ0(%r16), %r20 1028 CMPIB= 0, %r20, intr_do_preempt 1029 nop 1030 LDREG PT_IASQ1(%r16), %r20 1031 CMPIB= 0, %r20, intr_do_preempt 1032 nop 1033 1034#ifdef CONFIG_64BIT 1035 ldo -16(%r30),%r29 /* Reference param save area */ 1036#endif 1037 1038 ldil L%intr_check_sig, %r2 1039#ifndef CONFIG_64BIT 1040 b schedule 1041#else 1042 load32 schedule, %r20 1043 bv %r0(%r20) 1044#endif 1045 ldo R%intr_check_sig(%r2), %r2 1046 1047 /* preempt the current task on returning to kernel 1048 * mode from an interrupt, iff need_resched is set, 1049 * and preempt_count is 0. otherwise, we continue on 1050 * our merry way back to the current running task. 1051 */ 1052#ifdef CONFIG_PREEMPT 1053 .import preempt_schedule_irq,code 1054intr_do_preempt: 1055 rsm PSW_SM_I, %r0 /* disable interrupts */ 1056 1057 /* current_thread_info()->preempt_count */ 1058 mfctl %cr30, %r1 1059 LDREG TI_PRE_COUNT(%r1), %r19 1060 CMPIB<> 0, %r19, intr_restore /* if preempt_count > 0 */ 1061 nop /* prev insn branched backwards */ 1062 1063 /* check if we interrupted a critical path */ 1064 LDREG PT_PSW(%r16), %r20 1065 bb,<,n %r20, 31 - PSW_SM_I, intr_restore 1066 nop 1067 1068 BL preempt_schedule_irq, %r2 1069 nop 1070 1071 b intr_restore /* ssm PSW_SM_I done by intr_restore */ 1072#endif /* CONFIG_PREEMPT */ 1073 1074 .import do_signal,code 1075intr_do_signal: 1076 /* 1077 This check is critical to having LWS 1078 working. The IASQ is zero on the gateway 1079 page and we cannot deliver any signals until 1080 we get off the gateway page. 1081 1082 Only do signals if we are returning to user space 1083 */ 1084 LDREG PT_IASQ0(%r16), %r20 1085 CMPIB= 0,%r20,intr_restore /* backward */ 1086 nop 1087 LDREG PT_IASQ1(%r16), %r20 1088 CMPIB= 0,%r20,intr_restore /* backward */ 1089 nop 1090 1091 copy %r0, %r24 /* unsigned long in_syscall */ 1092 copy %r16, %r25 /* struct pt_regs *regs */ 1093#ifdef CONFIG_64BIT 1094 ldo -16(%r30),%r29 /* Reference param save area */ 1095#endif 1096 1097 BL do_signal,%r2 1098 copy %r0, %r26 /* sigset_t *oldset = NULL */ 1099 1100 b intr_check_sig 1101 nop 1102 1103 /* 1104 * External interrupts. 1105 */ 1106 1107intr_extint: 1108 CMPIB=,n 0,%r16,1f 1109 get_stack_use_cr30 1110 b,n 3f 1111 11121: 1113#if 0 /* Interrupt Stack support not working yet! */ 1114 mfctl %cr31,%r1 1115 copy %r30,%r17 1116 /* FIXME! depi below has hardcoded idea of interrupt stack size (32k)*/ 1117#ifdef CONFIG_64BIT 1118 depdi 0,63,15,%r17 1119#else 1120 depi 0,31,15,%r17 1121#endif 1122 CMPB=,n %r1,%r17,2f 1123 get_stack_use_cr31 1124 b,n 3f 1125#endif 11262: 1127 get_stack_use_r30 1128 11293: 1130 save_specials %r29 1131 virt_map 1132 save_general %r29 1133 1134 ldo PT_FR0(%r29), %r24 1135 save_fp %r24 1136 1137 loadgp 1138 1139 copy %r29, %r26 /* arg0 is pt_regs */ 1140 copy %r29, %r16 /* save pt_regs */ 1141 1142 ldil L%intr_return, %r2 1143 1144#ifdef CONFIG_64BIT 1145 ldo -16(%r30),%r29 /* Reference param save area */ 1146#endif 1147 1148 b do_cpu_irq_mask 1149 ldo R%intr_return(%r2), %r2 /* return to intr_return, not here */ 1150 1151 1152 /* Generic interruptions (illegal insn, unaligned, page fault, etc) */ 1153 1154 .export intr_save, code /* for os_hpmc */ 1155 1156intr_save: 1157 mfsp %sr7,%r16 1158 CMPIB=,n 0,%r16,1f 1159 get_stack_use_cr30 1160 b 2f 1161 copy %r8,%r26 1162 11631: 1164 get_stack_use_r30 1165 copy %r8,%r26 1166 11672: 1168 save_specials %r29 1169 1170 /* If this trap is a itlb miss, skip saving/adjusting isr/ior */ 1171 1172 /* 1173 * FIXME: 1) Use a #define for the hardwired "6" below (and in 1174 * traps.c. 1175 * 2) Once we start executing code above 4 Gb, we need 1176 * to adjust iasq/iaoq here in the same way we 1177 * adjust isr/ior below. 1178 */ 1179 1180 CMPIB=,n 6,%r26,skip_save_ior 1181 1182 1183 mfctl %cr20, %r16 /* isr */ 1184 nop /* serialize mfctl on PA 2.0 to avoid 4 cycle penalty */ 1185 mfctl %cr21, %r17 /* ior */ 1186 1187 1188#ifdef CONFIG_64BIT 1189 /* 1190 * If the interrupted code was running with W bit off (32 bit), 1191 * clear the b bits (bits 0 & 1) in the ior. 1192 * save_specials left ipsw value in r8 for us to test. 1193 */ 1194 extrd,u,*<> %r8,PSW_W_BIT,1,%r0 1195 depdi 0,1,2,%r17 1196 1197 /* 1198 * FIXME: This code has hardwired assumptions about the split 1199 * between space bits and offset bits. This will change 1200 * when we allow alternate page sizes. 1201 */ 1202 1203 /* adjust isr/ior. */ 1204 1205 extrd,u %r16,63,7,%r1 /* get high bits from isr for ior */ 1206 depd %r1,31,7,%r17 /* deposit them into ior */ 1207 depdi 0,63,7,%r16 /* clear them from isr */ 1208#endif 1209 STREG %r16, PT_ISR(%r29) 1210 STREG %r17, PT_IOR(%r29) 1211 1212 1213skip_save_ior: 1214 virt_map 1215 save_general %r29 1216 1217 ldo PT_FR0(%r29), %r25 1218 save_fp %r25 1219 1220 loadgp 1221 1222 copy %r29, %r25 /* arg1 is pt_regs */ 1223#ifdef CONFIG_64BIT 1224 ldo -16(%r30),%r29 /* Reference param save area */ 1225#endif 1226 1227 ldil L%intr_check_sig, %r2 1228 copy %r25, %r16 /* save pt_regs */ 1229 1230 b handle_interruption 1231 ldo R%intr_check_sig(%r2), %r2 1232 1233 1234 /* 1235 * Note for all tlb miss handlers: 1236 * 1237 * cr24 contains a pointer to the kernel address space 1238 * page directory. 1239 * 1240 * cr25 contains a pointer to the current user address 1241 * space page directory. 1242 * 1243 * sr3 will contain the space id of the user address space 1244 * of the current running thread while that thread is 1245 * running in the kernel. 1246 */ 1247 1248 /* 1249 * register number allocations. Note that these are all 1250 * in the shadowed registers 1251 */ 1252 1253 t0 = r1 /* temporary register 0 */ 1254 va = r8 /* virtual address for which the trap occured */ 1255 t1 = r9 /* temporary register 1 */ 1256 pte = r16 /* pte/phys page # */ 1257 prot = r17 /* prot bits */ 1258 spc = r24 /* space for which the trap occured */ 1259 ptp = r25 /* page directory/page table pointer */ 1260 1261#ifdef CONFIG_64BIT 1262 1263dtlb_miss_20w: 1264 space_adjust spc,va,t0 1265 get_pgd spc,ptp 1266 space_check spc,t0,dtlb_fault 1267 1268 L3_ptep ptp,pte,t0,va,dtlb_check_alias_20w 1269 1270 update_ptep ptp,pte,t0,t1 1271 1272 make_insert_tlb spc,pte,prot 1273 1274 idtlbt pte,prot 1275 1276 rfir 1277 nop 1278 1279dtlb_check_alias_20w: 1280 do_alias spc,t0,t1,va,pte,prot,dtlb_fault 1281 1282 idtlbt pte,prot 1283 1284 rfir 1285 nop 1286 1287nadtlb_miss_20w: 1288 space_adjust spc,va,t0 1289 get_pgd spc,ptp 1290 space_check spc,t0,nadtlb_fault 1291 1292 L3_ptep ptp,pte,t0,va,nadtlb_check_flush_20w 1293 1294 update_ptep ptp,pte,t0,t1 1295 1296 make_insert_tlb spc,pte,prot 1297 1298 idtlbt pte,prot 1299 1300 rfir 1301 nop 1302 1303nadtlb_check_flush_20w: 1304 bb,>=,n pte,_PAGE_FLUSH_BIT,nadtlb_emulate 1305 1306 /* Insert a "flush only" translation */ 1307 1308 depdi,z 7,7,3,prot 1309 depdi 1,10,1,prot 1310 1311 /* Get rid of prot bits and convert to page addr for idtlbt */ 1312 1313 depdi 0,63,12,pte 1314 extrd,u pte,56,52,pte 1315 idtlbt pte,prot 1316 1317 rfir 1318 nop 1319 1320#else 1321 1322dtlb_miss_11: 1323 get_pgd spc,ptp 1324 1325 space_check spc,t0,dtlb_fault 1326 1327 L2_ptep ptp,pte,t0,va,dtlb_check_alias_11 1328 1329 update_ptep ptp,pte,t0,t1 1330 1331 make_insert_tlb_11 spc,pte,prot 1332 1333 mfsp %sr1,t0 /* Save sr1 so we can use it in tlb inserts */ 1334 mtsp spc,%sr1 1335 1336 idtlba pte,(%sr1,va) 1337 idtlbp prot,(%sr1,va) 1338 1339 mtsp t0, %sr1 /* Restore sr1 */ 1340 1341 rfir 1342 nop 1343 1344dtlb_check_alias_11: 1345 1346 /* Check to see if fault is in the temporary alias region */ 1347 1348 cmpib,<>,n 0,spc,dtlb_fault /* forward */ 1349 ldil L%(TMPALIAS_MAP_START),t0 1350 copy va,t1 1351 depwi 0,31,23,t1 1352 cmpb,<>,n t0,t1,dtlb_fault /* forward */ 1353 ldi (_PAGE_DIRTY|_PAGE_WRITE|_PAGE_READ),prot 1354 depw,z prot,8,7,prot 1355 1356 /* 1357 * OK, it is in the temp alias region, check whether "from" or "to". 1358 * Check "subtle" note in pacache.S re: r23/r26. 1359 */ 1360 1361 extrw,u,= va,9,1,r0 1362 or,tr %r23,%r0,pte /* If "from" use "from" page */ 1363 or %r26,%r0,pte /* else "to", use "to" page */ 1364 1365 idtlba pte,(va) 1366 idtlbp prot,(va) 1367 1368 rfir 1369 nop 1370 1371nadtlb_miss_11: 1372 get_pgd spc,ptp 1373 1374 space_check spc,t0,nadtlb_fault 1375 1376 L2_ptep ptp,pte,t0,va,nadtlb_check_flush_11 1377 1378 update_ptep ptp,pte,t0,t1 1379 1380 make_insert_tlb_11 spc,pte,prot 1381 1382 1383 mfsp %sr1,t0 /* Save sr1 so we can use it in tlb inserts */ 1384 mtsp spc,%sr1 1385 1386 idtlba pte,(%sr1,va) 1387 idtlbp prot,(%sr1,va) 1388 1389 mtsp t0, %sr1 /* Restore sr1 */ 1390 1391 rfir 1392 nop 1393 1394nadtlb_check_flush_11: 1395 bb,>=,n pte,_PAGE_FLUSH_BIT,nadtlb_emulate 1396 1397 /* Insert a "flush only" translation */ 1398 1399 zdepi 7,7,3,prot 1400 depi 1,10,1,prot 1401 1402 /* Get rid of prot bits and convert to page addr for idtlba */ 1403 1404 depi 0,31,12,pte 1405 extru pte,24,25,pte 1406 1407 mfsp %sr1,t0 /* Save sr1 so we can use it in tlb inserts */ 1408 mtsp spc,%sr1 1409 1410 idtlba pte,(%sr1,va) 1411 idtlbp prot,(%sr1,va) 1412 1413 mtsp t0, %sr1 /* Restore sr1 */ 1414 1415 rfir 1416 nop 1417 1418dtlb_miss_20: 1419 space_adjust spc,va,t0 1420 get_pgd spc,ptp 1421 space_check spc,t0,dtlb_fault 1422 1423 L2_ptep ptp,pte,t0,va,dtlb_check_alias_20 1424 1425 update_ptep ptp,pte,t0,t1 1426 1427 make_insert_tlb spc,pte,prot 1428 1429 f_extend pte,t0 1430 1431 idtlbt pte,prot 1432 1433 rfir 1434 nop 1435 1436dtlb_check_alias_20: 1437 do_alias spc,t0,t1,va,pte,prot,dtlb_fault 1438 1439 idtlbt pte,prot 1440 1441 rfir 1442 nop 1443 1444nadtlb_miss_20: 1445 get_pgd spc,ptp 1446 1447 space_check spc,t0,nadtlb_fault 1448 1449 L2_ptep ptp,pte,t0,va,nadtlb_check_flush_20 1450 1451 update_ptep ptp,pte,t0,t1 1452 1453 make_insert_tlb spc,pte,prot 1454 1455 f_extend pte,t0 1456 1457 idtlbt pte,prot 1458 1459 rfir 1460 nop 1461 1462nadtlb_check_flush_20: 1463 bb,>=,n pte,_PAGE_FLUSH_BIT,nadtlb_emulate 1464 1465 /* Insert a "flush only" translation */ 1466 1467 depdi,z 7,7,3,prot 1468 depdi 1,10,1,prot 1469 1470 /* Get rid of prot bits and convert to page addr for idtlbt */ 1471 1472 depdi 0,63,12,pte 1473 extrd,u pte,56,32,pte 1474 idtlbt pte,prot 1475 1476 rfir 1477 nop 1478#endif 1479 1480nadtlb_emulate: 1481 1482 /* 1483 * Non access misses can be caused by fdc,fic,pdc,lpa,probe and 1484 * probei instructions. We don't want to fault for these 1485 * instructions (not only does it not make sense, it can cause 1486 * deadlocks, since some flushes are done with the mmap 1487 * semaphore held). If the translation doesn't exist, we can't 1488 * insert a translation, so have to emulate the side effects 1489 * of the instruction. Since we don't insert a translation 1490 * we can get a lot of faults during a flush loop, so it makes 1491 * sense to try to do it here with minimum overhead. We only 1492 * emulate fdc,fic,pdc,probew,prober instructions whose base 1493 * and index registers are not shadowed. We defer everything 1494 * else to the "slow" path. 1495 */ 1496 1497 mfctl %cr19,%r9 /* Get iir */ 1498 1499 /* PA 2.0 Arch Ref. Book pg 382 has a good description of the insn bits. 1500 Checks for fdc,fdce,pdc,"fic,4f",prober,probeir,probew, probeiw */ 1501 1502 /* Checks for fdc,fdce,pdc,"fic,4f" only */ 1503 ldi 0x280,%r16 1504 and %r9,%r16,%r17 1505 cmpb,<>,n %r16,%r17,nadtlb_probe_check 1506 bb,>=,n %r9,26,nadtlb_nullify /* m bit not set, just nullify */ 1507 BL get_register,%r25 1508 extrw,u %r9,15,5,%r8 /* Get index register # */ 1509 CMPIB=,n -1,%r1,nadtlb_fault /* have to use slow path */ 1510 copy %r1,%r24 1511 BL get_register,%r25 1512 extrw,u %r9,10,5,%r8 /* Get base register # */ 1513 CMPIB=,n -1,%r1,nadtlb_fault /* have to use slow path */ 1514 BL set_register,%r25 1515 add,l %r1,%r24,%r1 /* doesn't affect c/b bits */ 1516 1517nadtlb_nullify: 1518 mfctl %ipsw,%r8 1519 ldil L%PSW_N,%r9 1520 or %r8,%r9,%r8 /* Set PSW_N */ 1521 mtctl %r8,%ipsw 1522 1523 rfir 1524 nop 1525 1526 /* 1527 When there is no translation for the probe address then we 1528 must nullify the insn and return zero in the target regsiter. 1529 This will indicate to the calling code that it does not have 1530 write/read privileges to this address. 1531 1532 This should technically work for prober and probew in PA 1.1, 1533 and also probe,r and probe,w in PA 2.0 1534 1535 WARNING: USE ONLY NON-SHADOW REGISTERS WITH PROBE INSN! 1536 THE SLOW-PATH EMULATION HAS NOT BEEN WRITTEN YET. 1537 1538 */ 1539nadtlb_probe_check: 1540 ldi 0x80,%r16 1541 and %r9,%r16,%r17 1542 cmpb,<>,n %r16,%r17,nadtlb_fault /* Must be probe,[rw]*/ 1543 BL get_register,%r25 /* Find the target register */ 1544 extrw,u %r9,31,5,%r8 /* Get target register */ 1545 CMPIB=,n -1,%r1,nadtlb_fault /* have to use slow path */ 1546 BL set_register,%r25 1547 copy %r0,%r1 /* Write zero to target register */ 1548 b nadtlb_nullify /* Nullify return insn */ 1549 nop 1550 1551 1552#ifdef CONFIG_64BIT 1553itlb_miss_20w: 1554 1555 /* 1556 * I miss is a little different, since we allow users to fault 1557 * on the gateway page which is in the kernel address space. 1558 */ 1559 1560 space_adjust spc,va,t0 1561 get_pgd spc,ptp 1562 space_check spc,t0,itlb_fault 1563 1564 L3_ptep ptp,pte,t0,va,itlb_fault 1565 1566 update_ptep ptp,pte,t0,t1 1567 1568 make_insert_tlb spc,pte,prot 1569 1570 iitlbt pte,prot 1571 1572 rfir 1573 nop 1574 1575#else 1576 1577itlb_miss_11: 1578 get_pgd spc,ptp 1579 1580 space_check spc,t0,itlb_fault 1581 1582 L2_ptep ptp,pte,t0,va,itlb_fault 1583 1584 update_ptep ptp,pte,t0,t1 1585 1586 make_insert_tlb_11 spc,pte,prot 1587 1588 mfsp %sr1,t0 /* Save sr1 so we can use it in tlb inserts */ 1589 mtsp spc,%sr1 1590 1591 iitlba pte,(%sr1,va) 1592 iitlbp prot,(%sr1,va) 1593 1594 mtsp t0, %sr1 /* Restore sr1 */ 1595 1596 rfir 1597 nop 1598 1599itlb_miss_20: 1600 get_pgd spc,ptp 1601 1602 space_check spc,t0,itlb_fault 1603 1604 L2_ptep ptp,pte,t0,va,itlb_fault 1605 1606 update_ptep ptp,pte,t0,t1 1607 1608 make_insert_tlb spc,pte,prot 1609 1610 f_extend pte,t0 1611 1612 iitlbt pte,prot 1613 1614 rfir 1615 nop 1616 1617#endif 1618 1619#ifdef CONFIG_64BIT 1620 1621dbit_trap_20w: 1622 space_adjust spc,va,t0 1623 get_pgd spc,ptp 1624 space_check spc,t0,dbit_fault 1625 1626 L3_ptep ptp,pte,t0,va,dbit_fault 1627 1628#ifdef CONFIG_SMP 1629 CMPIB=,n 0,spc,dbit_nolock_20w 1630 load32 PA(pa_dbit_lock),t0 1631 1632dbit_spin_20w: 1633 ldcw 0(t0),t1 1634 cmpib,= 0,t1,dbit_spin_20w 1635 nop 1636 1637dbit_nolock_20w: 1638#endif 1639 update_dirty ptp,pte,t1 1640 1641 make_insert_tlb spc,pte,prot 1642 1643 idtlbt pte,prot 1644#ifdef CONFIG_SMP 1645 CMPIB=,n 0,spc,dbit_nounlock_20w 1646 ldi 1,t1 1647 stw t1,0(t0) 1648 1649dbit_nounlock_20w: 1650#endif 1651 1652 rfir 1653 nop 1654#else 1655 1656dbit_trap_11: 1657 1658 get_pgd spc,ptp 1659 1660 space_check spc,t0,dbit_fault 1661 1662 L2_ptep ptp,pte,t0,va,dbit_fault 1663 1664#ifdef CONFIG_SMP 1665 CMPIB=,n 0,spc,dbit_nolock_11 1666 load32 PA(pa_dbit_lock),t0 1667 1668dbit_spin_11: 1669 ldcw 0(t0),t1 1670 cmpib,= 0,t1,dbit_spin_11 1671 nop 1672 1673dbit_nolock_11: 1674#endif 1675 update_dirty ptp,pte,t1 1676 1677 make_insert_tlb_11 spc,pte,prot 1678 1679 mfsp %sr1,t1 /* Save sr1 so we can use it in tlb inserts */ 1680 mtsp spc,%sr1 1681 1682 idtlba pte,(%sr1,va) 1683 idtlbp prot,(%sr1,va) 1684 1685 mtsp t1, %sr1 /* Restore sr1 */ 1686#ifdef CONFIG_SMP 1687 CMPIB=,n 0,spc,dbit_nounlock_11 1688 ldi 1,t1 1689 stw t1,0(t0) 1690 1691dbit_nounlock_11: 1692#endif 1693 1694 rfir 1695 nop 1696 1697dbit_trap_20: 1698 get_pgd spc,ptp 1699 1700 space_check spc,t0,dbit_fault 1701 1702 L2_ptep ptp,pte,t0,va,dbit_fault 1703 1704#ifdef CONFIG_SMP 1705 CMPIB=,n 0,spc,dbit_nolock_20 1706 load32 PA(pa_dbit_lock),t0 1707 1708dbit_spin_20: 1709 ldcw 0(t0),t1 1710 cmpib,= 0,t1,dbit_spin_20 1711 nop 1712 1713dbit_nolock_20: 1714#endif 1715 update_dirty ptp,pte,t1 1716 1717 make_insert_tlb spc,pte,prot 1718 1719 f_extend pte,t1 1720 1721 idtlbt pte,prot 1722 1723#ifdef CONFIG_SMP 1724 CMPIB=,n 0,spc,dbit_nounlock_20 1725 ldi 1,t1 1726 stw t1,0(t0) 1727 1728dbit_nounlock_20: 1729#endif 1730 1731 rfir 1732 nop 1733#endif 1734 1735 .import handle_interruption,code 1736 1737kernel_bad_space: 1738 b intr_save 1739 ldi 31,%r8 /* Use an unused code */ 1740 1741dbit_fault: 1742 b intr_save 1743 ldi 20,%r8 1744 1745itlb_fault: 1746 b intr_save 1747 ldi 6,%r8 1748 1749nadtlb_fault: 1750 b intr_save 1751 ldi 17,%r8 1752 1753dtlb_fault: 1754 b intr_save 1755 ldi 15,%r8 1756 1757 /* Register saving semantics for system calls: 1758 1759 %r1 clobbered by system call macro in userspace 1760 %r2 saved in PT_REGS by gateway page 1761 %r3 - %r18 preserved by C code (saved by signal code) 1762 %r19 - %r20 saved in PT_REGS by gateway page 1763 %r21 - %r22 non-standard syscall args 1764 stored in kernel stack by gateway page 1765 %r23 - %r26 arg3-arg0, saved in PT_REGS by gateway page 1766 %r27 - %r30 saved in PT_REGS by gateway page 1767 %r31 syscall return pointer 1768 */ 1769 1770 /* Floating point registers (FIXME: what do we do with these?) 1771 1772 %fr0 - %fr3 status/exception, not preserved 1773 %fr4 - %fr7 arguments 1774 %fr8 - %fr11 not preserved by C code 1775 %fr12 - %fr21 preserved by C code 1776 %fr22 - %fr31 not preserved by C code 1777 */ 1778 1779 .macro reg_save regs 1780 STREG %r3, PT_GR3(\regs) 1781 STREG %r4, PT_GR4(\regs) 1782 STREG %r5, PT_GR5(\regs) 1783 STREG %r6, PT_GR6(\regs) 1784 STREG %r7, PT_GR7(\regs) 1785 STREG %r8, PT_GR8(\regs) 1786 STREG %r9, PT_GR9(\regs) 1787 STREG %r10,PT_GR10(\regs) 1788 STREG %r11,PT_GR11(\regs) 1789 STREG %r12,PT_GR12(\regs) 1790 STREG %r13,PT_GR13(\regs) 1791 STREG %r14,PT_GR14(\regs) 1792 STREG %r15,PT_GR15(\regs) 1793 STREG %r16,PT_GR16(\regs) 1794 STREG %r17,PT_GR17(\regs) 1795 STREG %r18,PT_GR18(\regs) 1796 .endm 1797 1798 .macro reg_restore regs 1799 LDREG PT_GR3(\regs), %r3 1800 LDREG PT_GR4(\regs), %r4 1801 LDREG PT_GR5(\regs), %r5 1802 LDREG PT_GR6(\regs), %r6 1803 LDREG PT_GR7(\regs), %r7 1804 LDREG PT_GR8(\regs), %r8 1805 LDREG PT_GR9(\regs), %r9 1806 LDREG PT_GR10(\regs),%r10 1807 LDREG PT_GR11(\regs),%r11 1808 LDREG PT_GR12(\regs),%r12 1809 LDREG PT_GR13(\regs),%r13 1810 LDREG PT_GR14(\regs),%r14 1811 LDREG PT_GR15(\regs),%r15 1812 LDREG PT_GR16(\regs),%r16 1813 LDREG PT_GR17(\regs),%r17 1814 LDREG PT_GR18(\regs),%r18 1815 .endm 1816 1817 .export sys_fork_wrapper 1818 .export child_return 1819sys_fork_wrapper: 1820 LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30), %r1 1821 ldo TASK_REGS(%r1),%r1 1822 reg_save %r1 1823 mfctl %cr27, %r3 1824 STREG %r3, PT_CR27(%r1) 1825 1826 STREG %r2,-RP_OFFSET(%r30) 1827 ldo FRAME_SIZE(%r30),%r30 1828#ifdef CONFIG_64BIT 1829 ldo -16(%r30),%r29 /* Reference param save area */ 1830#endif 1831 1832 /* These are call-clobbered registers and therefore 1833 also syscall-clobbered (we hope). */ 1834 STREG %r2,PT_GR19(%r1) /* save for child */ 1835 STREG %r30,PT_GR21(%r1) 1836 1837 LDREG PT_GR30(%r1),%r25 1838 copy %r1,%r24 1839 BL sys_clone,%r2 1840 ldi SIGCHLD,%r26 1841 1842 LDREG -RP_OFFSET-FRAME_SIZE(%r30),%r2 1843wrapper_exit: 1844 ldo -FRAME_SIZE(%r30),%r30 /* get the stackframe */ 1845 LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1 1846 ldo TASK_REGS(%r1),%r1 /* get pt regs */ 1847 1848 LDREG PT_CR27(%r1), %r3 1849 mtctl %r3, %cr27 1850 reg_restore %r1 1851 1852 /* strace expects syscall # to be preserved in r20 */ 1853 ldi __NR_fork,%r20 1854 bv %r0(%r2) 1855 STREG %r20,PT_GR20(%r1) 1856 1857 /* Set the return value for the child */ 1858child_return: 1859 BL schedule_tail, %r2 1860 nop 1861 1862 LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE-FRAME_SIZE(%r30), %r1 1863 LDREG TASK_PT_GR19(%r1),%r2 1864 b wrapper_exit 1865 copy %r0,%r28 1866 1867 1868 .export sys_clone_wrapper 1869sys_clone_wrapper: 1870 LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1 1871 ldo TASK_REGS(%r1),%r1 /* get pt regs */ 1872 reg_save %r1 1873 mfctl %cr27, %r3 1874 STREG %r3, PT_CR27(%r1) 1875 1876 STREG %r2,-RP_OFFSET(%r30) 1877 ldo FRAME_SIZE(%r30),%r30 1878#ifdef CONFIG_64BIT 1879 ldo -16(%r30),%r29 /* Reference param save area */ 1880#endif 1881 1882 /* WARNING - Clobbers r19 and r21, userspace must save these! */ 1883 STREG %r2,PT_GR19(%r1) /* save for child */ 1884 STREG %r30,PT_GR21(%r1) 1885 BL sys_clone,%r2 1886 copy %r1,%r24 1887 1888 b wrapper_exit 1889 LDREG -RP_OFFSET-FRAME_SIZE(%r30),%r2 1890 1891 .export sys_vfork_wrapper 1892sys_vfork_wrapper: 1893 LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1 1894 ldo TASK_REGS(%r1),%r1 /* get pt regs */ 1895 reg_save %r1 1896 mfctl %cr27, %r3 1897 STREG %r3, PT_CR27(%r1) 1898 1899 STREG %r2,-RP_OFFSET(%r30) 1900 ldo FRAME_SIZE(%r30),%r30 1901#ifdef CONFIG_64BIT 1902 ldo -16(%r30),%r29 /* Reference param save area */ 1903#endif 1904 1905 STREG %r2,PT_GR19(%r1) /* save for child */ 1906 STREG %r30,PT_GR21(%r1) 1907 1908 BL sys_vfork,%r2 1909 copy %r1,%r26 1910 1911 b wrapper_exit 1912 LDREG -RP_OFFSET-FRAME_SIZE(%r30),%r2 1913 1914 1915 .macro execve_wrapper execve 1916 LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1 1917 ldo TASK_REGS(%r1),%r1 /* get pt regs */ 1918 1919 /* 1920 * Do we need to save/restore r3-r18 here? 1921 * I don't think so. why would new thread need old 1922 * threads registers? 1923 */ 1924 1925 /* %arg0 - %arg3 are already saved for us. */ 1926 1927 STREG %r2,-RP_OFFSET(%r30) 1928 ldo FRAME_SIZE(%r30),%r30 1929#ifdef CONFIG_64BIT 1930 ldo -16(%r30),%r29 /* Reference param save area */ 1931#endif 1932 BL \execve,%r2 1933 copy %r1,%arg0 1934 1935 ldo -FRAME_SIZE(%r30),%r30 1936 LDREG -RP_OFFSET(%r30),%r2 1937 1938 /* If exec succeeded we need to load the args */ 1939 1940 ldo -1024(%r0),%r1 1941 cmpb,>>= %r28,%r1,error_\execve 1942 copy %r2,%r19 1943 1944error_\execve: 1945 bv %r0(%r19) 1946 nop 1947 .endm 1948 1949 .export sys_execve_wrapper 1950 .import sys_execve 1951 1952sys_execve_wrapper: 1953 execve_wrapper sys_execve 1954 1955#ifdef CONFIG_64BIT 1956 .export sys32_execve_wrapper 1957 .import sys32_execve 1958 1959sys32_execve_wrapper: 1960 execve_wrapper sys32_execve 1961#endif 1962 1963 .export sys_rt_sigreturn_wrapper 1964sys_rt_sigreturn_wrapper: 1965 LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r26 1966 ldo TASK_REGS(%r26),%r26 /* get pt regs */ 1967 /* Don't save regs, we are going to restore them from sigcontext. */ 1968 STREG %r2, -RP_OFFSET(%r30) 1969#ifdef CONFIG_64BIT 1970 ldo FRAME_SIZE(%r30), %r30 1971 BL sys_rt_sigreturn,%r2 1972 ldo -16(%r30),%r29 /* Reference param save area */ 1973#else 1974 BL sys_rt_sigreturn,%r2 1975 ldo FRAME_SIZE(%r30), %r30 1976#endif 1977 1978 ldo -FRAME_SIZE(%r30), %r30 1979 LDREG -RP_OFFSET(%r30), %r2 1980 1981 /* FIXME: I think we need to restore a few more things here. */ 1982 LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1 1983 ldo TASK_REGS(%r1),%r1 /* get pt regs */ 1984 reg_restore %r1 1985 1986 /* If the signal was received while the process was blocked on a 1987 * syscall, then r2 will take us to syscall_exit; otherwise r2 will 1988 * take us to syscall_exit_rfi and on to intr_return. 1989 */ 1990 bv %r0(%r2) 1991 LDREG PT_GR28(%r1),%r28 /* reload original r28 for syscall_exit */ 1992 1993 .export sys_sigaltstack_wrapper 1994sys_sigaltstack_wrapper: 1995 /* Get the user stack pointer */ 1996 LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1 1997 ldo TASK_REGS(%r1),%r24 /* get pt regs */ 1998 LDREG TASK_PT_GR30(%r24),%r24 1999 STREG %r2, -RP_OFFSET(%r30) 2000#ifdef CONFIG_64BIT 2001 ldo FRAME_SIZE(%r30), %r30 2002 b,l do_sigaltstack,%r2 2003 ldo -16(%r30),%r29 /* Reference param save area */ 2004#else 2005 bl do_sigaltstack,%r2 2006 ldo FRAME_SIZE(%r30), %r30 2007#endif 2008 2009 ldo -FRAME_SIZE(%r30), %r30 2010 LDREG -RP_OFFSET(%r30), %r2 2011 bv %r0(%r2) 2012 nop 2013 2014#ifdef CONFIG_64BIT 2015 .export sys32_sigaltstack_wrapper 2016sys32_sigaltstack_wrapper: 2017 /* Get the user stack pointer */ 2018 LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r24 2019 LDREG TASK_PT_GR30(%r24),%r24 2020 STREG %r2, -RP_OFFSET(%r30) 2021 ldo FRAME_SIZE(%r30), %r30 2022 b,l do_sigaltstack32,%r2 2023 ldo -16(%r30),%r29 /* Reference param save area */ 2024 2025 ldo -FRAME_SIZE(%r30), %r30 2026 LDREG -RP_OFFSET(%r30), %r2 2027 bv %r0(%r2) 2028 nop 2029#endif 2030 2031 .export sys_rt_sigsuspend_wrapper 2032sys_rt_sigsuspend_wrapper: 2033 LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30), %r1 2034 ldo TASK_REGS(%r1),%r24 2035 reg_save %r24 2036 2037 STREG %r2, -RP_OFFSET(%r30) 2038#ifdef CONFIG_64BIT 2039 ldo FRAME_SIZE(%r30), %r30 2040 b,l sys_rt_sigsuspend,%r2 2041 ldo -16(%r30),%r29 /* Reference param save area */ 2042#else 2043 bl sys_rt_sigsuspend,%r2 2044 ldo FRAME_SIZE(%r30), %r30 2045#endif 2046 2047 ldo -FRAME_SIZE(%r30), %r30 2048 LDREG -RP_OFFSET(%r30), %r2 2049 2050 LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30), %r1 2051 ldo TASK_REGS(%r1),%r1 2052 reg_restore %r1 2053 2054 bv %r0(%r2) 2055 nop 2056 2057 .export syscall_exit 2058syscall_exit: 2059 2060 /* NOTE: HP-UX syscalls also come through here 2061 * after hpux_syscall_exit fixes up return 2062 * values. */ 2063 2064 /* NOTE: Not all syscalls exit this way. rt_sigreturn will exit 2065 * via syscall_exit_rfi if the signal was received while the process 2066 * was running. 2067 */ 2068 2069 /* save return value now */ 2070 2071 mfctl %cr30, %r1 2072 LDREG TI_TASK(%r1),%r1 2073 STREG %r28,TASK_PT_GR28(%r1) 2074 2075#ifdef CONFIG_HPUX 2076 2077/* <linux/personality.h> cannot be easily included */ 2078#define PER_HPUX 0x10 2079 LDREG TASK_PERSONALITY(%r1),%r19 2080 2081 /* We can't use "CMPIB<> PER_HPUX" since "im5" field is sign extended */ 2082 ldo -PER_HPUX(%r19), %r19 2083 CMPIB<>,n 0,%r19,1f 2084 2085 /* Save other hpux returns if personality is PER_HPUX */ 2086 STREG %r22,TASK_PT_GR22(%r1) 2087 STREG %r29,TASK_PT_GR29(%r1) 20881: 2089 2090#endif /* CONFIG_HPUX */ 2091 2092 /* Seems to me that dp could be wrong here, if the syscall involved 2093 * calling a module, and nothing got round to restoring dp on return. 2094 */ 2095 loadgp 2096 2097syscall_check_bh: 2098 2099 /* Check for software interrupts */ 2100 2101 .import irq_stat,data 2102 2103 load32 irq_stat,%r19 2104 2105#ifdef CONFIG_SMP 2106 /* sched.h: int processor */ 2107 /* %r26 is used as scratch register to index into irq_stat[] */ 2108 ldw TI_CPU-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r26 /* cpu # */ 2109 2110 /* shift left ____cacheline_aligned (aka L1_CACHE_BYTES) bits */ 2111#ifdef CONFIG_64BIT 2112 shld %r26, 6, %r20 2113#else 2114 shlw %r26, 5, %r20 2115#endif 2116 add %r19,%r20,%r19 /* now have &irq_stat[smp_processor_id()] */ 2117#endif /* CONFIG_SMP */ 2118 2119syscall_check_resched: 2120 2121 /* check for reschedule */ 2122 2123 LDREG TI_FLAGS-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r19 /* long */ 2124 bb,<,n %r19, 31-TIF_NEED_RESCHED, syscall_do_resched /* forward */ 2125 2126syscall_check_sig: 2127 LDREG TI_FLAGS-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r19 /* get ti flags */ 2128 bb,<,n %r19, 31-TIF_SIGPENDING, syscall_do_signal /* forward */ 2129 2130syscall_restore: 2131 /* Are we being ptraced? */ 2132 LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1 2133 2134 LDREG TASK_PTRACE(%r1), %r19 2135 bb,< %r19,31,syscall_restore_rfi 2136 nop 2137 2138 ldo TASK_PT_FR31(%r1),%r19 /* reload fpregs */ 2139 rest_fp %r19 2140 2141 LDREG TASK_PT_SAR(%r1),%r19 /* restore SAR */ 2142 mtsar %r19 2143 2144 LDREG TASK_PT_GR2(%r1),%r2 /* restore user rp */ 2145 LDREG TASK_PT_GR19(%r1),%r19 2146 LDREG TASK_PT_GR20(%r1),%r20 2147 LDREG TASK_PT_GR21(%r1),%r21 2148 LDREG TASK_PT_GR22(%r1),%r22 2149 LDREG TASK_PT_GR23(%r1),%r23 2150 LDREG TASK_PT_GR24(%r1),%r24 2151 LDREG TASK_PT_GR25(%r1),%r25 2152 LDREG TASK_PT_GR26(%r1),%r26 2153 LDREG TASK_PT_GR27(%r1),%r27 /* restore user dp */ 2154 LDREG TASK_PT_GR28(%r1),%r28 /* syscall return value */ 2155 LDREG TASK_PT_GR29(%r1),%r29 2156 LDREG TASK_PT_GR31(%r1),%r31 /* restore syscall rp */ 2157 2158 /* NOTE: We use rsm/ssm pair to make this operation atomic */ 2159 rsm PSW_SM_I, %r0 2160 LDREG TASK_PT_GR30(%r1),%r30 /* restore user sp */ 2161 mfsp %sr3,%r1 /* Get users space id */ 2162 mtsp %r1,%sr7 /* Restore sr7 */ 2163 ssm PSW_SM_I, %r0 2164 2165 /* Set sr2 to zero for userspace syscalls to work. */ 2166 mtsp %r0,%sr2 2167 mtsp %r1,%sr4 /* Restore sr4 */ 2168 mtsp %r1,%sr5 /* Restore sr5 */ 2169 mtsp %r1,%sr6 /* Restore sr6 */ 2170 2171 depi 3,31,2,%r31 /* ensure return to user mode. */ 2172 2173#ifdef CONFIG_64BIT 2174 /* decide whether to reset the wide mode bit 2175 * 2176 * For a syscall, the W bit is stored in the lowest bit 2177 * of sp. Extract it and reset W if it is zero */ 2178 extrd,u,*<> %r30,63,1,%r1 2179 rsm PSW_SM_W, %r0 2180 /* now reset the lowest bit of sp if it was set */ 2181 xor %r30,%r1,%r30 2182#endif 2183 be,n 0(%sr3,%r31) /* return to user space */ 2184 2185 /* We have to return via an RFI, so that PSW T and R bits can be set 2186 * appropriately. 2187 * This sets up pt_regs so we can return via intr_restore, which is not 2188 * the most efficient way of doing things, but it works. 2189 */ 2190syscall_restore_rfi: 2191 ldo -1(%r0),%r2 /* Set recovery cntr to -1 */ 2192 mtctl %r2,%cr0 /* for immediate trap */ 2193 LDREG TASK_PT_PSW(%r1),%r2 /* Get old PSW */ 2194 ldi 0x0b,%r20 /* Create new PSW */ 2195 depi -1,13,1,%r20 /* C, Q, D, and I bits */ 2196 2197 /* The values of PA_SINGLESTEP_BIT and PA_BLOCKSTEP_BIT are 2198 * set in include/linux/ptrace.h and converted to PA bitmap 2199 * numbers in asm-offsets.c */ 2200 2201 /* if ((%r19.PA_SINGLESTEP_BIT)) { %r20.27=1} */ 2202 extru,= %r19,PA_SINGLESTEP_BIT,1,%r0 2203 depi -1,27,1,%r20 /* R bit */ 2204 2205 /* if ((%r19.PA_BLOCKSTEP_BIT)) { %r20.7=1} */ 2206 extru,= %r19,PA_BLOCKSTEP_BIT,1,%r0 2207 depi -1,7,1,%r20 /* T bit */ 2208 2209 STREG %r20,TASK_PT_PSW(%r1) 2210 2211 /* Always store space registers, since sr3 can be changed (e.g. fork) */ 2212 2213 mfsp %sr3,%r25 2214 STREG %r25,TASK_PT_SR3(%r1) 2215 STREG %r25,TASK_PT_SR4(%r1) 2216 STREG %r25,TASK_PT_SR5(%r1) 2217 STREG %r25,TASK_PT_SR6(%r1) 2218 STREG %r25,TASK_PT_SR7(%r1) 2219 STREG %r25,TASK_PT_IASQ0(%r1) 2220 STREG %r25,TASK_PT_IASQ1(%r1) 2221 2222 /* XXX W bit??? */ 2223 /* Now if old D bit is clear, it means we didn't save all registers 2224 * on syscall entry, so do that now. This only happens on TRACEME 2225 * calls, or if someone attached to us while we were on a syscall. 2226 * We could make this more efficient by not saving r3-r18, but 2227 * then we wouldn't be able to use the common intr_restore path. 2228 * It is only for traced processes anyway, so performance is not 2229 * an issue. 2230 */ 2231 bb,< %r2,30,pt_regs_ok /* Branch if D set */ 2232 ldo TASK_REGS(%r1),%r25 2233 reg_save %r25 /* Save r3 to r18 */ 2234 2235 /* Save the current sr */ 2236 mfsp %sr0,%r2 2237 STREG %r2,TASK_PT_SR0(%r1) 2238 2239 /* Save the scratch sr */ 2240 mfsp %sr1,%r2 2241 STREG %r2,TASK_PT_SR1(%r1) 2242 2243 /* sr2 should be set to zero for userspace syscalls */ 2244 STREG %r0,TASK_PT_SR2(%r1) 2245 2246pt_regs_ok: 2247 LDREG TASK_PT_GR31(%r1),%r2 2248 depi 3,31,2,%r2 /* ensure return to user mode. */ 2249 STREG %r2,TASK_PT_IAOQ0(%r1) 2250 ldo 4(%r2),%r2 2251 STREG %r2,TASK_PT_IAOQ1(%r1) 2252 copy %r25,%r16 2253 b intr_restore 2254 nop 2255 2256 .import schedule,code 2257syscall_do_resched: 2258 BL schedule,%r2 2259#ifdef CONFIG_64BIT 2260 ldo -16(%r30),%r29 /* Reference param save area */ 2261#else 2262 nop 2263#endif 2264 b syscall_check_bh /* if resched, we start over again */ 2265 nop 2266 2267 .import do_signal,code 2268syscall_do_signal: 2269 /* Save callee-save registers (for sigcontext). 2270 FIXME: After this point the process structure should be 2271 consistent with all the relevant state of the process 2272 before the syscall. We need to verify this. */ 2273 LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1 2274 ldo TASK_REGS(%r1), %r25 /* struct pt_regs *regs */ 2275 reg_save %r25 2276 2277 ldi 1, %r24 /* unsigned long in_syscall */ 2278 2279#ifdef CONFIG_64BIT 2280 ldo -16(%r30),%r29 /* Reference param save area */ 2281#endif 2282 BL do_signal,%r2 2283 copy %r0, %r26 /* sigset_t *oldset = NULL */ 2284 2285 LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1 2286 ldo TASK_REGS(%r1), %r20 /* reload pt_regs */ 2287 reg_restore %r20 2288 2289 b,n syscall_check_sig 2290 2291 /* 2292 * get_register is used by the non access tlb miss handlers to 2293 * copy the value of the general register specified in r8 into 2294 * r1. This routine can't be used for shadowed registers, since 2295 * the rfir will restore the original value. So, for the shadowed 2296 * registers we put a -1 into r1 to indicate that the register 2297 * should not be used (the register being copied could also have 2298 * a -1 in it, but that is OK, it just means that we will have 2299 * to use the slow path instead). 2300 */ 2301 2302get_register: 2303 blr %r8,%r0 2304 nop 2305 bv %r0(%r25) /* r0 */ 2306 copy %r0,%r1 2307 bv %r0(%r25) /* r1 - shadowed */ 2308 ldi -1,%r1 2309 bv %r0(%r25) /* r2 */ 2310 copy %r2,%r1 2311 bv %r0(%r25) /* r3 */ 2312 copy %r3,%r1 2313 bv %r0(%r25) /* r4 */ 2314 copy %r4,%r1 2315 bv %r0(%r25) /* r5 */ 2316 copy %r5,%r1 2317 bv %r0(%r25) /* r6 */ 2318 copy %r6,%r1 2319 bv %r0(%r25) /* r7 */ 2320 copy %r7,%r1 2321 bv %r0(%r25) /* r8 - shadowed */ 2322 ldi -1,%r1 2323 bv %r0(%r25) /* r9 - shadowed */ 2324 ldi -1,%r1 2325 bv %r0(%r25) /* r10 */ 2326 copy %r10,%r1 2327 bv %r0(%r25) /* r11 */ 2328 copy %r11,%r1 2329 bv %r0(%r25) /* r12 */ 2330 copy %r12,%r1 2331 bv %r0(%r25) /* r13 */ 2332 copy %r13,%r1 2333 bv %r0(%r25) /* r14 */ 2334 copy %r14,%r1 2335 bv %r0(%r25) /* r15 */ 2336 copy %r15,%r1 2337 bv %r0(%r25) /* r16 - shadowed */ 2338 ldi -1,%r1 2339 bv %r0(%r25) /* r17 - shadowed */ 2340 ldi -1,%r1 2341 bv %r0(%r25) /* r18 */ 2342 copy %r18,%r1 2343 bv %r0(%r25) /* r19 */ 2344 copy %r19,%r1 2345 bv %r0(%r25) /* r20 */ 2346 copy %r20,%r1 2347 bv %r0(%r25) /* r21 */ 2348 copy %r21,%r1 2349 bv %r0(%r25) /* r22 */ 2350 copy %r22,%r1 2351 bv %r0(%r25) /* r23 */ 2352 copy %r23,%r1 2353 bv %r0(%r25) /* r24 - shadowed */ 2354 ldi -1,%r1 2355 bv %r0(%r25) /* r25 - shadowed */ 2356 ldi -1,%r1 2357 bv %r0(%r25) /* r26 */ 2358 copy %r26,%r1 2359 bv %r0(%r25) /* r27 */ 2360 copy %r27,%r1 2361 bv %r0(%r25) /* r28 */ 2362 copy %r28,%r1 2363 bv %r0(%r25) /* r29 */ 2364 copy %r29,%r1 2365 bv %r0(%r25) /* r30 */ 2366 copy %r30,%r1 2367 bv %r0(%r25) /* r31 */ 2368 copy %r31,%r1 2369 2370 /* 2371 * set_register is used by the non access tlb miss handlers to 2372 * copy the value of r1 into the general register specified in 2373 * r8. 2374 */ 2375 2376set_register: 2377 blr %r8,%r0 2378 nop 2379 bv %r0(%r25) /* r0 (silly, but it is a place holder) */ 2380 copy %r1,%r0 2381 bv %r0(%r25) /* r1 */ 2382 copy %r1,%r1 2383 bv %r0(%r25) /* r2 */ 2384 copy %r1,%r2 2385 bv %r0(%r25) /* r3 */ 2386 copy %r1,%r3 2387 bv %r0(%r25) /* r4 */ 2388 copy %r1,%r4 2389 bv %r0(%r25) /* r5 */ 2390 copy %r1,%r5 2391 bv %r0(%r25) /* r6 */ 2392 copy %r1,%r6 2393 bv %r0(%r25) /* r7 */ 2394 copy %r1,%r7 2395 bv %r0(%r25) /* r8 */ 2396 copy %r1,%r8 2397 bv %r0(%r25) /* r9 */ 2398 copy %r1,%r9 2399 bv %r0(%r25) /* r10 */ 2400 copy %r1,%r10 2401 bv %r0(%r25) /* r11 */ 2402 copy %r1,%r11 2403 bv %r0(%r25) /* r12 */ 2404 copy %r1,%r12 2405 bv %r0(%r25) /* r13 */ 2406 copy %r1,%r13 2407 bv %r0(%r25) /* r14 */ 2408 copy %r1,%r14 2409 bv %r0(%r25) /* r15 */ 2410 copy %r1,%r15 2411 bv %r0(%r25) /* r16 */ 2412 copy %r1,%r16 2413 bv %r0(%r25) /* r17 */ 2414 copy %r1,%r17 2415 bv %r0(%r25) /* r18 */ 2416 copy %r1,%r18 2417 bv %r0(%r25) /* r19 */ 2418 copy %r1,%r19 2419 bv %r0(%r25) /* r20 */ 2420 copy %r1,%r20 2421 bv %r0(%r25) /* r21 */ 2422 copy %r1,%r21 2423 bv %r0(%r25) /* r22 */ 2424 copy %r1,%r22 2425 bv %r0(%r25) /* r23 */ 2426 copy %r1,%r23 2427 bv %r0(%r25) /* r24 */ 2428 copy %r1,%r24 2429 bv %r0(%r25) /* r25 */ 2430 copy %r1,%r25 2431 bv %r0(%r25) /* r26 */ 2432 copy %r1,%r26 2433 bv %r0(%r25) /* r27 */ 2434 copy %r1,%r27 2435 bv %r0(%r25) /* r28 */ 2436 copy %r1,%r28 2437 bv %r0(%r25) /* r29 */ 2438 copy %r1,%r29 2439 bv %r0(%r25) /* r30 */ 2440 copy %r1,%r30 2441 bv %r0(%r25) /* r31 */ 2442 copy %r1,%r31 2443