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