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