entry.S
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:64k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  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. #include <linux/config.h>
  25. #include <asm/offset.h>
  26. /* we have the following possibilities to act on an interruption:
  27.  *  - handle in assembly and use shadowed registers only
  28.  *  - save registers to kernel stack and handle in assembly or C */
  29. #include <asm/assembly.h> /* for LDREG/STREG defines */
  30. #include <asm/pgtable.h>
  31. #include <asm/psw.h>
  32. #include <asm/signal.h>
  33. #include <asm/unistd.h>
  34. #ifdef __LP64__
  35. #define FRAME_SIZE 128
  36. #define CMPIB           cmpib,*
  37. #define CMPB            cmpb,*
  38. .level 2.0w
  39. #else
  40. #define FRAME_SIZE 64
  41. #define CMPIB           cmpib,
  42. #define CMPB            cmpb,
  43. .level 2.0
  44. #endif
  45. .import         pa_dbit_lock,data
  46. /* space_to_prot macro creates a prot id from a space id */
  47. #if (SPACEID_SHIFT) == 0
  48. .macro  space_to_prot spc prot
  49. depd,z  spc,62,31,prot
  50. .endm
  51. #else
  52. .macro  space_to_prot spc prot
  53. extrd,u spc,(64 - (SPACEID_SHIFT)),32,prot
  54. .endm
  55. #endif
  56. /* Switch to virtual mapping, trashing only %r1 */
  57. .macro  virt_map
  58. rsm     PSW_SM_Q,%r0
  59. tovirt_r1 %r29
  60. mfsp %sr7, %r1
  61. or,=    %r0,%r1,%r0 /* Only save sr7 in sr3 if sr7 != 0 */
  62. mtsp %r1, %sr3
  63. mtsp %r0, %sr4
  64. mtsp %r0, %sr5
  65. mtsp %r0, %sr6
  66. mtsp %r0, %sr7
  67. ldil L%KERNEL_PSW, %r1
  68. ldo R%KERNEL_PSW(%r1), %r1
  69. mtctl %r1, %cr22
  70. mtctl %r0, %cr17
  71. mtctl %r0, %cr17
  72. ldil L%4f, %r1
  73. ldo R%4f(%r1), %r1
  74. mtctl %r1, %cr18
  75. ldo 4(%r1), %r1
  76. mtctl %r1, %cr18
  77. rfir
  78. nop
  79. 4:
  80. .endm
  81. /*
  82.  * The "get_stack" macros are responsible for determining the
  83.  * kernel stack value.
  84.  *
  85.  * For Faults:
  86.  *      If sr7 == 0
  87.  *          Already using a kernel stack, so call the
  88.  *          get_stack_use_r30 macro to push a pt_regs structure
  89.  *          on the stack, and store registers there.
  90.  *      else
  91.  *          Need to set up a kernel stack, so call the
  92.  *          get_stack_use_cr30 macro to set up a pointer
  93.  *          to the pt_regs structure contained within the
  94.  *          task pointer pointed to by cr30. Set the stack
  95.  *          pointer to point to the end of the task structure.
  96.  *
  97.  * For Interrupts:
  98.  *      If sr7 == 0
  99.  *          Already using a kernel stack, check to see if r30
  100.  *          is already pointing to the per processor interrupt
  101.  *          stack. If it is, call the get_stack_use_r30 macro
  102.  *          to push a pt_regs structure on the stack, and store
  103.  *          registers there. Otherwise, call get_stack_use_cr31
  104.  *          to get a pointer to the base of the interrupt stack
  105.  *          and push a pt_regs structure on that stack.
  106.  *      else
  107.  *          Need to set up a kernel stack, so call the
  108.  *          get_stack_use_cr30 macro to set up a pointer
  109.  *          to the pt_regs structure contained within the
  110.  *          task pointer pointed to by cr30. Set the stack
  111.  *          pointer to point to the end of the task structure.
  112.  *          N.B: We don't use the interrupt stack for the
  113.  *          first interrupt from userland, because signals/
  114.  *          resched's are processed when returning to userland,
  115.  *          and we can sleep in those cases.
  116.  *
  117.  * Note that we use shadowed registers for temps until
  118.  * we can save %r26 and %r29. %r26 is used to preserve
  119.  * %r8 (a shadowed register) which temporarily contained
  120.  * either the fault type ("code") or the eirr. We need
  121.  * to use a non-shadowed register to carry the value over
  122.  * the rfir in virt_map. We use %r26 since this value winds
  123.  * up being passed as the argument to either do_cpu_irq_mask
  124.  * or handle_interruption. %r29 is used to hold a pointer
  125.  * the register save area, and once again, it needs to
  126.  * be a non-shadowed register so that it survives the rfir.
  127.  *
  128.  * N.B. TASK_SZ_ALGN and PT_SZ_ALGN include space for a stack frame.
  129.  */
  130. .macro  get_stack_use_cr30
  131. /* we save the registers in the task struct */
  132. mfctl   %cr30, %r1
  133. tophys  %r1,%r9
  134. ldo     TASK_REGS(%r9),%r9
  135. STREG   %r30, PT_GR30(%r9)
  136. ldo TASK_SZ_ALGN(%r1), %r30
  137. STREG   %r29,PT_GR29(%r9)
  138. STREG   %r26,PT_GR26(%r9)
  139. copy    %r9,%r29
  140. .endm
  141. .macro  get_stack_use_r30
  142. /* we put a struct pt_regs on the stack and save the registers there */
  143. tophys  %r30,%r9
  144. STREG   %r30,PT_GR30(%r9)
  145. ldo PT_SZ_ALGN(%r30),%r30
  146. STREG   %r29,PT_GR29(%r9)
  147. STREG   %r26,PT_GR26(%r9)
  148. copy    %r9,%r29
  149. .endm
  150. .macro  rest_stack
  151. LDREG   PT_GR1(%r29), %r1
  152. LDREG   PT_GR30(%r29),%r30
  153. LDREG   PT_GR29(%r29),%r29
  154. .endm
  155. /* default interruption handler
  156.  * (calls traps.c:handle_interruption) */
  157. .macro def code
  158. b intr_save
  159. ldi     code, %r8
  160. .align 32
  161. .endm
  162. /* Interrupt interruption handler
  163.  * (calls irq.c:do_cpu_irq_mask) */
  164. .macro extint code
  165. b intr_extint
  166. mfsp    %sr7,%r16
  167. .align 32
  168. .endm
  169. .import os_hpmc, code
  170. /* HPMC handler */
  171. .macro hpmc code
  172. nop /* must be a NOP, will be patched later */
  173. ldil L%PA(os_hpmc), %r3
  174. ldo R%PA(os_hpmc)(%r3), %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.  * Performance Note: Instructions will be moved up into
  183.  * this part of the code later on, once we are sure
  184.  * that the tlb miss handlers are close to final form.
  185.  */
  186. /* Register definitions for tlb miss handler macros */
  187. va  = r8 /* virtual address for which the trap occured */
  188. spc = r24 /* space for which the trap occured */
  189. #ifndef __LP64__
  190. /*
  191.  * itlb miss interruption handler (parisc 1.1 - 32 bit)
  192.  */
  193. .macro itlb_11 code
  194. mfctl %pcsq, spc
  195. b itlb_miss_11
  196. mfctl %pcoq, va
  197. .align 32
  198. .endm
  199. #endif
  200. /*
  201.  * itlb miss interruption handler (parisc 2.0)
  202.  */
  203. .macro itlb_20 code
  204. mfctl %pcsq, spc
  205. #ifdef __LP64__
  206. b       itlb_miss_20w
  207. #else
  208. b itlb_miss_20
  209. #endif
  210. mfctl %pcoq, va
  211. .align 32
  212. .endm
  213. #ifndef __LP64__
  214. /*
  215.  * naitlb miss interruption handler (parisc 1.1 - 32 bit)
  216.  *
  217.  * Note: naitlb misses will be treated
  218.  * as an ordinary itlb miss for now.
  219.  * However, note that naitlb misses
  220.  * have the faulting address in the
  221.  * IOR/ISR.
  222.  */
  223. .macro naitlb_11 code
  224. mfctl %isr,spc
  225. b itlb_miss_11
  226. mfctl  %ior,va
  227. /* FIXME: If user causes a naitlb miss, the priv level may not be in
  228.  * lower bits of va, where the itlb miss handler is expecting them
  229.  */
  230. .align 32
  231. .endm
  232. #endif
  233. /*
  234.  * naitlb miss interruption handler (parisc 2.0)
  235.  *
  236.  * Note: naitlb misses will be treated
  237.  * as an ordinary itlb miss for now.
  238.  * However, note that naitlb misses
  239.  * have the faulting address in the
  240.  * IOR/ISR.
  241.  */
  242. .macro naitlb_20 code
  243. mfctl %isr,spc
  244. #ifdef __LP64__
  245. b       itlb_miss_20w
  246. #else
  247. b itlb_miss_20
  248. #endif
  249. mfctl  %ior,va
  250. /* FIXME: If user causes a naitlb miss, the priv level may not be in
  251.  * lower bits of va, where the itlb miss handler is expecting them
  252.  */
  253. .align 32
  254. .endm
  255. #ifndef __LP64__
  256. /*
  257.  * dtlb miss interruption handler (parisc 1.1 - 32 bit)
  258.  */
  259. .macro dtlb_11 code
  260. mfctl %isr, spc
  261. b dtlb_miss_11
  262. mfctl %ior, va
  263. .align 32
  264. .endm
  265. #endif
  266. /*
  267.  * dtlb miss interruption handler (parisc 2.0)
  268.  */
  269. .macro dtlb_20 code
  270. mfctl %isr, spc
  271. #ifdef __LP64__
  272. b       dtlb_miss_20w
  273. #else
  274. b dtlb_miss_20
  275. #endif
  276. mfctl %ior, va
  277. .align 32
  278. .endm
  279. #ifndef __LP64__
  280. /* nadtlb miss interruption handler (parisc 1.1 - 32 bit) */
  281. .macro nadtlb_11 code
  282. mfctl %isr,spc
  283. b       nadtlb_miss_11
  284. mfctl %ior,va
  285. .align 32
  286. .endm
  287. #endif
  288. /* nadtlb miss interruption handler (parisc 2.0) */
  289. .macro nadtlb_20 code
  290. mfctl %isr,spc
  291. #ifdef __LP64__
  292. b       nadtlb_miss_20w
  293. #else
  294. b       nadtlb_miss_20
  295. #endif
  296. mfctl %ior,va
  297. .align 32
  298. .endm
  299. #ifndef __LP64__
  300. /*
  301.  * dirty bit trap interruption handler (parisc 1.1 - 32 bit)
  302.  */
  303. .macro dbit_11 code
  304. mfctl %isr,spc
  305. b dbit_trap_11
  306. mfctl %ior,va
  307. .align 32
  308. .endm
  309. #endif
  310. /*
  311.  * dirty bit trap interruption handler (parisc 2.0)
  312.  */
  313. .macro dbit_20 code
  314. mfctl %isr,spc
  315. #ifdef __LP64__
  316. b       dbit_trap_20w
  317. #else
  318. b dbit_trap_20
  319. #endif
  320. mfctl %ior,va
  321. .align 32
  322. .endm
  323. /*
  324.  * Align fault_vector_20 on 4K boundary so that both
  325.  * fault_vector_11 and fault_vector_20 are on the
  326.  * same page. This is only necessary as long as we
  327.  * write protect the kernel text, which we may stop
  328.  * doing once we use large page translations to cover
  329.  * the static part of the kernel address space.
  330.  */
  331. .export fault_vector_20
  332. .text
  333. .align 4096
  334. fault_vector_20:
  335. /* First vector is invalid (0) */
  336. .ascii "cows can fly"
  337. .byte 0
  338. .align 32
  339. hpmc  1
  340. def  2
  341. def  3
  342. extint  4
  343. def  5
  344. itlb_20  6
  345. def  7
  346. def  8
  347. def              9
  348. def 10
  349. def 11
  350. def 12
  351. def 13
  352. def 14
  353. dtlb_20 15
  354. #if 0
  355. naitlb_20 16
  356. #else
  357. def             16
  358. #endif
  359. nadtlb_20 17
  360. def 18
  361. def 19
  362. dbit_20 20
  363. def 21
  364. def 22
  365. def 23
  366. def 24
  367. def 25
  368. def 26
  369. def 27
  370. def 28
  371. def 29
  372. def 30
  373. def 31
  374. #ifndef __LP64__
  375. .export fault_vector_11
  376. .align 2048
  377. fault_vector_11:
  378. /* First vector is invalid (0) */
  379. .ascii "cows can fly"
  380. .byte 0
  381. .align 32
  382. hpmc  1
  383. def  2
  384. def  3
  385. extint  4
  386. def  5
  387. itlb_11  6
  388. def  7
  389. def  8
  390. def              9
  391. def 10
  392. def 11
  393. def 12
  394. def 13
  395. def 14
  396. dtlb_11 15
  397. #if 0
  398. naitlb_11 16
  399. #else
  400. def             16
  401. #endif
  402. nadtlb_11 17
  403. def 18
  404. def 19
  405. dbit_11 20
  406. def 21
  407. def 22
  408. def 23
  409. def 24
  410. def 25
  411. def 26
  412. def 27
  413. def 28
  414. def 29
  415. def 30
  416. def 31
  417. #endif
  418. .import handle_interruption,code
  419. .import handle_real_interruption,code
  420. .import do_cpu_irq_mask,code
  421. .import parisc_stopkernel,code
  422. /*
  423.  * r26 = function to be called
  424.  * r25 = argument to pass in
  425.  * r24 = flags for do_fork()
  426.  *
  427.  * Kernel threads don't ever return, so they don't need
  428.  * a true register context. We just save away the arguments
  429.  * for copy_thread/ret_ to properly set up the child.
  430.  */
  431. #define CLONE_VM 0x100 /* Must agree with <linux/sched.h> */
  432. .export __kernel_thread, code
  433. .import do_fork
  434. __kernel_thread:
  435. STREG %r2, -RP_OFFSET(%r30)
  436. copy %r30, %r1
  437. ldo PT_SZ_ALGN(%r30),%r30
  438. #ifdef __LP64__
  439. /* Yo, function pointers in wide mode are little structs... -PB */
  440. ldd 24(%r26), %r2
  441. STREG %r2, PT_GR27(%r1) /* Store childs %dp */
  442. ldd 16(%r26), %r26
  443. #endif
  444. STREG %r26, PT_GR26(%r1)  /* Store function & argument for child */
  445. STREG %r25, PT_GR25(%r1)
  446. ldo CLONE_VM(%r0), %r26   /* Force CLONE_VM since only init_mm */
  447. or %r26, %r24, %r26      /* will have kernel mappings.  */
  448. copy %r0, %r25
  449. #ifdef __LP64__
  450. ldo -16(%r30),%r29 /* Reference param save area */
  451. #endif
  452. bl do_fork, %r2
  453. copy %r1, %r24
  454. /* Parent Returns here */
  455. LDREG -PT_SZ_ALGN-RP_OFFSET(%r30), %r2
  456. bv %r0(%r2)
  457. ldo -PT_SZ_ALGN(%r30), %r30
  458. /*
  459.  * Child Returns here
  460.  *
  461.  * copy_thread moved args from temp save area set up above
  462.  * into task save area.
  463.  */
  464. .export ret_from_kernel_thread
  465. ret_from_kernel_thread:
  466. /* Call schedule_tail first though */
  467. bl schedule_tail, %r2
  468. nop
  469. LDREG TASK_PT_GR26-TASK_SZ_ALGN(%r30), %r1
  470. LDREG TASK_PT_GR25-TASK_SZ_ALGN(%r30), %r26
  471. #ifdef __LP64__
  472. LDREG TASK_PT_GR27-TASK_SZ_ALGN(%r30), %r27
  473. #endif
  474. ble 0(%sr7, %r1)
  475. copy %r31, %r2
  476. #ifdef __LP64__
  477. ldo -16(%r30),%r29 /* Reference param save area */
  478. loadgp /* Thread could have been in a module */
  479. #endif
  480. b sys_exit
  481. ldi 0, %r26
  482. .import sys_execve, code
  483. .export __execve, code
  484. __execve:
  485. copy %r2, %r15
  486. copy %r30, %r16
  487. ldo PT_SZ_ALGN(%r30), %r30
  488. STREG %r26, PT_GR26(%r16)
  489. STREG %r25, PT_GR25(%r16)
  490. STREG %r24, PT_GR24(%r16)
  491. #ifdef __LP64__
  492. ldo -16(%r30),%r29 /* Reference param save area */
  493. #endif
  494. bl sys_execve, %r2
  495. copy %r16, %r26
  496. cmpib,=,n 0,%r28,intr_return    /* forward */
  497. /* yes, this will trap and die. */
  498. copy %r15, %r2
  499. copy %r16, %r30
  500. bv %r0(%r2)
  501. nop
  502. .align 4
  503. /*
  504.  * struct task_struct *_switch_to(struct task_struct *prev,
  505.  * struct task_struct *next)
  506.  *
  507.  * switch kernel stacks and return prev */
  508. .export _switch_to, code
  509. _switch_to:
  510. STREG  %r2, -RP_OFFSET(%r30)
  511. callee_save
  512. ldil L%_switch_to_ret, %r2
  513. ldo R%_switch_to_ret(%r2), %r2
  514. STREG %r2, TASK_PT_KPC(%r26)
  515. LDREG TASK_PT_KPC(%r25), %r2
  516. STREG %r30, TASK_PT_KSP(%r26)
  517. LDREG TASK_PT_KSP(%r25), %r30
  518. bv %r0(%r2)
  519. mtctl   %r25,%cr30
  520. _switch_to_ret:
  521. mtctl %r0, %cr0 /* Needed for single stepping */
  522. callee_rest
  523. LDREG -RP_OFFSET(%r30), %r2
  524. bv %r0(%r2)
  525. copy %r26, %r28
  526. /*
  527.  * Common rfi return path for interruptions, kernel execve, and
  528.  * sys_rt_sigreturn (sometimes).  The sys_rt_sigreturn syscall will
  529.  * return via this path if the signal was received when the process
  530.  * was running; if the process was blocked on a syscall then the
  531.  * normal syscall_exit path is used.  All syscalls for traced
  532.  * proceses exit via intr_restore.
  533.  *
  534.  * XXX If any syscalls that change a processes space id ever exit
  535.  * this way, then we will need to copy %sr3 in to PT_SR[3..7], and
  536.  * adjust IASQ[0..1].
  537.  *
  538.  * Note that the following code uses a "relied upon translation".
  539.  * See the parisc ACD for details. The ssm is necessary due to a
  540.  * PCXT bug.
  541.  */
  542. .align 4096
  543. .export syscall_exit_rfi
  544. syscall_exit_rfi:
  545. mfctl   %cr30,%r16
  546. ldo TASK_REGS(%r16),%r16
  547. /* Force iaoq to userspace, as the user has had access to our current
  548.  * context via sigcontext. Also Filter the PSW for the same reason.
  549.  */
  550. LDREG PT_IAOQ0(%r16),%r19
  551. depi 3,31,2,%r19
  552. STREG %r19,PT_IAOQ0(%r16)
  553. LDREG PT_IAOQ1(%r16),%r19
  554. depi 3,31,2,%r19
  555. STREG %r19,PT_IAOQ1(%r16)
  556. LDREG   PT_PSW(%r16),%r19
  557. ldil    L%USER_PSW_MASK,%r1
  558. ldo     R%USER_PSW_MASK(%r1),%r1
  559. #ifdef __LP64__
  560. ldil    L%USER_PSW_HI_MASK,%r20
  561. ldo     R%USER_PSW_HI_MASK(%r20),%r20
  562. depd    %r20,31,32,%r1
  563. #endif
  564. and     %r19,%r1,%r19 /* Mask out bits that user shouldn't play with */
  565. ldil    L%USER_PSW,%r1
  566. ldo     R%USER_PSW(%r1),%r1
  567. or      %r19,%r1,%r19 /* Make sure default USER_PSW bits are set */
  568. STREG   %r19,PT_PSW(%r16)
  569. /*
  570.  * If we aren't being traced, we never saved space registers
  571.  * (we don't store them in the sigcontext), so set them
  572.  * to "proper" values now (otherwise we'll wind up restoring
  573.  * whatever was last stored in the task structure, which might
  574.  * be inconsistant if an interrupt occured while on the gateway
  575.  * page) Note that we may be "trashing" values the user put in
  576.  * them, but we don't support the the user changing them.
  577.  */
  578. STREG   %r0,PT_SR2(%r16)
  579. mfsp    %sr3,%r19
  580. STREG   %r19,PT_SR0(%r16)
  581. STREG   %r19,PT_SR1(%r16)
  582. STREG   %r19,PT_SR3(%r16)
  583. STREG   %r19,PT_SR4(%r16)
  584. STREG   %r19,PT_SR5(%r16)
  585. STREG   %r19,PT_SR6(%r16)
  586. STREG   %r19,PT_SR7(%r16)
  587. intr_return:
  588. ssm     PSW_SM_I, %r0
  589. /* Check for software interrupts */
  590. .import irq_stat,data
  591. ldil L%irq_stat,%r19
  592. ldo R%irq_stat(%r19),%r19
  593. #ifdef CONFIG_SMP
  594. mfctl   %cr30,%r1
  595. ldw TASK_PROCESSOR(%r1),%r1 /* get cpu # - int */
  596. /* shift left ____cacheline_aligned (aka L1_CACHE_BYTES) amount
  597. ** irq_stat[] is defined using ____cacheline_aligned.
  598. */
  599. #ifdef __LP64__
  600. shld %r1, 6, %r20
  601. #else
  602. shlw %r1, 5, %r20
  603. #endif
  604. add     %r19,%r20,%r19 /* now have &irq_stat[smp_processor_id()] */
  605. #endif /* CONFIG_SMP */
  606. LDREG   IRQSTAT_SIRQ_PEND(%r19),%r20    /* hardirq.h: unsigned long */
  607. cmpib,<>,n 0,%r20,intr_do_softirq /* forward */
  608. intr_check_resched:
  609. /* check for reschedule */
  610. mfctl   %cr30,%r1
  611. LDREG     TASK_NEED_RESCHED(%r1),%r19 /* sched.h: long need_resched */
  612. CMPIB<>,n 0,%r19,intr_do_resched /* forward */
  613. intr_check_sig:
  614. /* As above */
  615. mfctl   %cr30,%r1
  616. ldw TASK_SIGPENDING(%r1),%r19 /* sched.h: int sigpending */
  617. cmpib,<>,n 0,%r19,intr_do_signal /* forward */
  618. intr_restore:
  619. copy            %r16,%r29
  620. ldo             PT_FR31(%r29),%r1
  621. rest_fp         %r1
  622. rest_general    %r29
  623. ssm 0,%r0
  624. nop
  625. nop
  626. nop
  627. nop
  628. nop
  629. nop
  630. nop
  631. tophys_r1       %r29
  632. rsm             (PSW_SM_Q|PSW_SM_P|PSW_SM_D|PSW_SM_I),%r0
  633. rest_specials %r29
  634. rest_stack
  635. rfi
  636. nop
  637. nop
  638. nop
  639. nop
  640. nop
  641. nop
  642. nop
  643. nop
  644. .import do_softirq,code
  645. intr_do_softirq:
  646. bl      do_softirq,%r2
  647. #ifdef __LP64__
  648. ldo -16(%r30),%r29 /* Reference param save area */
  649. #else
  650. nop
  651. #endif
  652. b       intr_check_resched
  653. nop
  654. .import schedule,code
  655. intr_do_resched:
  656. /* Only do reschedule if we are returning to user space */
  657. LDREG   PT_IASQ0(%r16), %r20
  658. CMPIB= 0,%r20,intr_restore /* backward */
  659. nop
  660. LDREG   PT_IASQ1(%r16), %r20
  661. CMPIB= 0,%r20,intr_restore /* backward */
  662. nop
  663. #ifdef __LP64__
  664. ldo -16(%r30),%r29 /* Reference param save area */
  665. #endif
  666. ldil L%intr_return, %r2
  667. b schedule
  668. ldo R%intr_return(%r2), %r2 /* return to intr_return, not here */
  669. .import do_signal,code
  670. intr_do_signal:
  671. /* Only do signals if we are returning to user space */
  672. LDREG   PT_IASQ0(%r16), %r20
  673. CMPIB= 0,%r20,intr_restore /* backward */
  674. nop
  675. LDREG   PT_IASQ1(%r16), %r20
  676. CMPIB= 0,%r20,intr_restore /* backward */
  677. nop
  678. copy %r0, %r24 /* unsigned long in_syscall */
  679. copy %r16, %r25 /* struct pt_regs *regs */
  680. ssm     PSW_SM_I, %r0
  681. #ifdef __LP64__
  682. ldo -16(%r30),%r29 /* Reference param save area */
  683. #endif
  684. bl do_signal,%r2
  685. copy %r0, %r26 /* sigset_t *oldset = NULL */
  686. b intr_restore
  687. nop
  688. /*
  689.  * External interrupts.
  690.  */
  691. intr_extint:
  692. CMPIB=,n 0,%r16,1f /* on User or kernel stack? */
  693. get_stack_use_cr30
  694. b,n 3f
  695. 1:
  696. #if 0  /* Interrupt Stack support not working yet! */
  697. mfctl %cr31,%r1
  698. copy %r30,%r17
  699. /* FIXME! depi below has hardcoded idea of interrupt stack size (32k)*/
  700. #ifdef __LP64__
  701. depdi 0,63,15,%r17
  702. #else
  703. depi 0,31,15,%r17
  704. #endif
  705. CMPB=,n %r1,%r17,2f
  706. get_stack_use_cr31
  707. b,n 3f
  708. #endif
  709. 2:
  710. get_stack_use_r30
  711. 3:
  712. save_specials %r29
  713. virt_map
  714. save_general %r29
  715. ldo PT_FR0(%r29), %r24
  716. save_fp %r24
  717. loadgp
  718. copy %r29, %r26 /* arg0 is pt_regs */
  719. copy %r29, %r16 /* save pt_regs */
  720. ldil L%intr_return, %r2
  721. #ifdef __LP64__
  722. ldo -16(%r30),%r29 /* Reference param save area */
  723. #endif
  724. b do_cpu_irq_mask
  725. ldo R%intr_return(%r2), %r2 /* return to intr_return, not here */
  726. /* Generic interruptions (illegal insn, unaligned, page fault, etc) */
  727. .export         intr_save, code /* for os_hpmc */
  728. intr_save:
  729. mfsp    %sr7,%r16
  730. CMPIB=,n 0,%r16,1f
  731. get_stack_use_cr30
  732. b 2f
  733. copy    %r8,%r26
  734. 1:
  735. get_stack_use_r30
  736. copy    %r8,%r26
  737. 2:
  738. save_specials %r29
  739. /* If this trap is a itlb miss, skip saving/adjusting isr/ior */
  740. /*
  741.  * FIXME: 1) Use a #define for the hardwired "6" below (and in
  742.  *           traps.c.
  743.  *        2) Once we start executing code above 4 Gb, we need
  744.  *           to adjust iasq/iaoq here in the same way we
  745.  *           adjust isr/ior below.
  746.  */
  747. CMPIB=,n        6,%r26,skip_save_ior
  748. /* save_specials left ipsw value in r8 for us to test */
  749. mfctl           %cr20, %r16 /* isr */
  750. mfctl           %cr21, %r17 /* ior */
  751. #ifdef __LP64__
  752. /*
  753.  * If the interrupted code was running with W bit off (32 bit),
  754.  * clear the b bits (bits 0 & 1) in the ior.
  755.  */
  756. extrd,u,*<>     %r8,PSW_W_BIT,1,%r0
  757. depdi           0,1,2,%r17
  758. /*
  759.  * FIXME: This code has hardwired assumptions about the split
  760.  *        between space bits and offset bits. This will change
  761.  *        when we allow alternate page sizes.
  762.  */
  763. /* adjust isr/ior. */
  764. extrd,u         %r16,63,7,%r1    /* get high bits from isr for ior */
  765. depd            %r1,31,7,%r17    /* deposit them into ior */
  766. depdi           0,63,7,%r16      /* clear them from isr */
  767. #endif
  768. STREG           %r16, PT_ISR(%r29)
  769. STREG           %r17, PT_IOR(%r29)
  770. skip_save_ior:
  771. virt_map
  772. save_general %r29
  773. ldo PT_FR0(%r29), %r25
  774. save_fp %r25
  775. loadgp
  776. copy %r29, %r25 /* arg1 is pt_regs */
  777. #ifdef CONFIG_KWDB
  778. copy %r29, %r3 /* KWDB - update frame pointer (gr3) */
  779. #endif
  780. #ifdef __LP64__
  781. ldo -16(%r30),%r29 /* Reference param save area */
  782. #endif
  783. ldil L%intr_return, %r2
  784. copy %r25, %r16 /* save pt_regs */
  785. b handle_interruption
  786. ldo R%intr_return(%r2), %r2 /* return to intr_return */
  787. /*
  788.  * Note for all tlb miss handlers:
  789.  *
  790.  * cr24 contains a pointer to the kernel address space
  791.  * page directory.
  792.  *
  793.  * cr25 contains a pointer to the current user address
  794.  * space page directory.
  795.  *
  796.  * sr3 will contain the space id of the user address space
  797.  * of the current running thread while that thread is
  798.  * running in the kernel.
  799.  */
  800. /*
  801.  * register number allocations.  Note that these are all
  802.  * in the shadowed registers
  803.  */
  804. t0 = r1 /* temporary register 0 */
  805. va = r8 /* virtual address for which the trap occured */
  806. t1 = r9 /* temporary register 1 */
  807. pte  = r16 /* pte/phys page # */
  808. prot = r17 /* prot bits */
  809. spc  = r24 /* space for which the trap occured */
  810. ptp = r25 /* page directory/page table pointer */
  811. #ifdef __LP64__
  812. dtlb_miss_20w:
  813. extrd,u         spc,63,7,t1     /* adjust va */
  814. depd            t1,31,7,va      /* adjust va */
  815. depdi           0,63,7,spc      /* adjust space */
  816. mfctl           %cr25,ptp /* Assume user space miss */
  817. or,*<>          %r0,spc,%r0     /* If it is user space, nullify */
  818. mfctl           %cr24,ptp /* Load kernel pgd instead */
  819. extrd,u         va,33,9,t1      /* Get pgd index */
  820. mfsp            %sr7,t0 /* Get current space */
  821. or,*=           %r0,t0,%r0      /* If kernel, nullify following test */
  822. cmpb,*<>,n       t0,spc,dtlb_fault /* forward */
  823. /* First level page table lookup */
  824. ldd,s           t1(ptp),ptp
  825. extrd,u         va,42,9,t0     /* get second-level index */
  826. bb,>=,n         ptp,_PAGE_PRESENT_BIT,dtlb_check_alias_20w
  827. depdi           0,63,12,ptp     /* clear prot bits */
  828. /* Second level page table lookup */
  829. ldd,s           t0(ptp),ptp
  830. extrd,u         va,51,9,t0     /* get third-level index */
  831. bb,>=,n         ptp,_PAGE_PRESENT_BIT,dtlb_check_alias_20w
  832. depdi           0,63,12,ptp     /* clear prot bits */
  833. /* Third level page table lookup */
  834. shladd           t0,3,ptp,ptp
  835. ldi _PAGE_ACCESSED,t1
  836. ldd              0(ptp),pte
  837. bb,>=,n          pte,_PAGE_PRESENT_BIT,dtlb_check_alias_20w
  838. /* Check whether the "accessed" bit was set, otherwise do so */
  839. or t1,pte,t0 /* t0 has R bit set */
  840. and,*<>         t1,pte,%r0      /* test and nullify if already set */
  841. std             t0,0(ptp)       /* write back pte */
  842. space_to_prot   spc prot        /* create prot id from space */
  843. depd            pte,8,7,prot    /* add in prot bits from pte */
  844. extrd,u,*=      pte,_PAGE_USER_BIT+32,1,r0
  845. depdi 7,11,3,prot   /* Set for user space (1 rsvd for read) */
  846. extrd,u,*=  pte,_PAGE_GATEWAY_BIT+32,1,r0
  847. depdi 0,11,2,prot /* If Gateway, Set PL2 to 0 */
  848. /* Get rid of prot bits and convert to page addr for idtlbt */
  849. depdi 0,63,12,pte
  850. extrd,u         pte,56,52,pte
  851. idtlbt          pte,prot
  852. rfir
  853. nop
  854. dtlb_check_alias_20w:
  855. /* Check to see if fault is in the temporary alias region */
  856. cmpib,*<>,n     0,spc,dtlb_fault /* forward */
  857. ldil            L%(TMPALIAS_MAP_START),t0
  858. copy            va,t1
  859. depdi           0,63,23,t1
  860. cmpb,*<>,n      t0,t1,dtlb_fault /* forward */
  861. ldi             (_PAGE_DIRTY|_PAGE_WRITE|_PAGE_READ),prot
  862. depd,z          prot,8,7,prot
  863. /*
  864.  * OK, it is in the temp alias region, check whether "from" or "to".
  865.  * Check "subtle" note in pacache.S re: r23/r26.
  866.  */
  867. extrd,u,*=      va,41,1,r0
  868. or,*tr          %r23,%r0,pte    /* If "from" use "from" page */
  869. or,*            %r26,%r0,pte    /* else "to", use "to" page  */
  870. idtlbt          pte,prot
  871. rfir
  872. nop
  873. nadtlb_miss_20w:
  874. extrd,u         spc,63,7,t1     /* adjust va */
  875. depd            t1,31,7,va      /* adjust va */
  876. depdi           0,63,7,spc      /* adjust space */
  877. mfctl           %cr25,ptp /* Assume user space miss */
  878. or,*<>          %r0,spc,%r0     /* If it is user space, nullify */
  879. mfctl           %cr24,ptp /* Load kernel pgd instead */
  880. extrd,u         va,33,9,t1      /* Get pgd index */
  881. mfsp            %sr7,t0 /* Get current space */
  882. or,*=           %r0,t0,%r0      /* If kernel, nullify following test */
  883. cmpb,*<>,n       t0,spc,nadtlb_fault /* forward */
  884. /* First level page table lookup */
  885. ldd,s           t1(ptp),ptp
  886. extrd,u         va,42,9,t0     /* get second-level index */
  887. bb,>=,n         ptp,_PAGE_PRESENT_BIT,nadtlb_emulate
  888. depdi           0,63,12,ptp     /* clear prot bits */
  889. /* Second level page table lookup */
  890. ldd,s           t0(ptp),ptp
  891. extrd,u         va,51,9,t0     /* get third-level index */
  892. bb,>=,n         ptp,_PAGE_PRESENT_BIT,nadtlb_emulate
  893. depdi           0,63,12,ptp     /* clear prot bits */
  894. /* Third level page table lookup */
  895. shladd           t0,3,ptp,ptp
  896. ldi _PAGE_ACCESSED,t1
  897. ldd              0(ptp),pte
  898. bb,>=,n          pte,_PAGE_PRESENT_BIT,nadtlb_check_flush_20w
  899. space_to_prot   spc prot        /* create prot id from space */
  900. depd            pte,8,7,prot    /* add in prot bits from pte */
  901. extrd,u,*=      pte,_PAGE_USER_BIT+32,1,r0
  902. depdi 7,11,3,prot   /* Set for user space (1 rsvd for read) */
  903. extrd,u,*=  pte,_PAGE_GATEWAY_BIT+32,1,r0
  904. depdi 0,11,2,prot /* If Gateway, Set PL2 to 0 */
  905. /* Get rid of prot bits and convert to page addr for idtlbt */
  906. depdi 0,63,12,pte
  907. extrd,u         pte,56,52,pte
  908. idtlbt          pte,prot
  909. rfir
  910. nop
  911. nadtlb_check_flush_20w:
  912. bb,>=,n          pte,_PAGE_FLUSH_BIT,nadtlb_emulate
  913. /* Insert a "flush only" translation */
  914. depdi,z         7,7,3,prot
  915. depdi           1,10,1,prot
  916. /* Get rid of prot bits and convert to page addr for idtlbt */
  917. depdi 0,63,12,pte
  918. extrd,u         pte,56,52,pte
  919. idtlbt          pte,prot
  920. rfir
  921. nop
  922. #else
  923. dtlb_miss_11:
  924. mfctl           %cr25,ptp /* Assume user space miss */
  925. or,<>           %r0,spc,%r0 /* If it is user space, nullify */
  926. mfctl           %cr24,ptp /* Load kernel pgd instead */
  927. extru va,9,10,t1 /* Get pgd index */
  928. mfsp            %sr7,t0 /* Get current space */
  929. or,=            %r0,t0,%r0 /* If kernel, nullify following test */
  930. cmpb,<>,n       t0,spc,dtlb_fault /* forward */
  931. /* First level page table lookup */
  932. ldwx,s t1(ptp),ptp
  933. extru va,19,10,t0 /* get second-level index */
  934. bb,>=,n         ptp,_PAGE_PRESENT_BIT,dtlb_check_alias_11
  935. depi 0,31,12,ptp /* clear prot bits */
  936. /* Second level page table lookup */
  937. sh2addl   t0,ptp,ptp
  938. ldi _PAGE_ACCESSED,t1
  939. ldw  0(ptp),pte
  940. bb,>=,n          pte,_PAGE_PRESENT_BIT,dtlb_check_alias_11
  941. /* Check whether the "accessed" bit was set, otherwise do so */
  942. or t1,pte,t0 /* t0 has R bit set */
  943. and,<> t1,pte,%r0 /* test and nullify if already set */
  944. stw t0,0(ptp) /* write back pte */
  945. zdep            spc,30,15,prot  /* create prot id from space */
  946. dep             pte,8,7,prot    /* add in prot bits from pte */
  947. extru,= pte,_PAGE_NO_CACHE_BIT,1,r0
  948. depi 1,12,1,prot
  949. extru,=         pte,_PAGE_USER_BIT,1,r0
  950. depi 7,11,3,prot   /* Set for user space (1 rsvd for read) */
  951. extru,=  pte,_PAGE_GATEWAY_BIT,1,r0
  952. depi 0,11,2,prot /* If Gateway, Set PL2 to 0 */
  953. /* Get rid of prot bits and convert to page addr for idtlba */
  954. depi 0,31,12,pte
  955. extru pte,24,25,pte
  956. mfsp %sr1,t0  /* Save sr1 so we can use it in tlb inserts */
  957. mtsp spc,%sr1
  958. idtlba pte,(%sr1,va)
  959. idtlbp prot,(%sr1,va)
  960. mtsp t0, %sr1 /* Restore sr1 */
  961. rfir
  962. nop
  963. dtlb_check_alias_11:
  964. /* Check to see if fault is in the temporary alias region */
  965. cmpib,<>,n      0,spc,dtlb_fault /* forward */
  966. ldil            L%(TMPALIAS_MAP_START),t0
  967. copy            va,t1
  968. depwi           0,31,23,t1
  969. cmpb,<>,n       t0,t1,dtlb_fault /* forward */
  970. ldi             (_PAGE_DIRTY|_PAGE_WRITE|_PAGE_READ),prot
  971. depw,z          prot,8,7,prot
  972. /*
  973.  * OK, it is in the temp alias region, check whether "from" or "to".
  974.  * Check "subtle" note in pacache.S re: r23/r26.
  975.  */
  976. extrw,u,=       va,9,1,r0
  977. or,tr           %r23,%r0,pte    /* If "from" use "from" page */
  978. or              %r26,%r0,pte    /* else "to", use "to" page  */
  979. idtlba          pte,(va)
  980. idtlbp          prot,(va)
  981. rfir
  982. nop
  983. nadtlb_miss_11:
  984. mfctl           %cr25,ptp /* Assume user space miss */
  985. or,<>           %r0,spc,%r0 /* If it is user space, nullify */
  986. mfctl           %cr24,ptp /* Load kernel pgd instead */
  987. extru va,9,10,t1 /* Get pgd index */
  988. mfsp            %sr7,t0 /* Get current space */
  989. or,=            %r0,t0,%r0 /* If kernel, nullify following test */
  990. cmpb,<>,n       t0,spc,nadtlb_fault /* forward */
  991. /* First level page table lookup */
  992. ldwx,s t1(ptp),ptp
  993. extru va,19,10,t0 /* get second-level index */
  994. bb,>=,n         ptp,_PAGE_PRESENT_BIT,nadtlb_emulate
  995. depi 0,31,12,ptp /* clear prot bits */
  996. /* Second level page table lookup */
  997. sh2addl   t0,ptp,ptp
  998. ldi _PAGE_ACCESSED,t1
  999. ldw  0(ptp),pte
  1000. bb,>=,n          pte,_PAGE_PRESENT_BIT,nadtlb_check_flush_11
  1001. zdep            spc,30,15,prot  /* create prot id from space */
  1002. dep             pte,8,7,prot    /* add in prot bits from pte */
  1003. extru,= pte,_PAGE_NO_CACHE_BIT,1,r0
  1004. depi 1,12,1,prot
  1005. extru,=         pte,_PAGE_USER_BIT,1,r0
  1006. depi 7,11,3,prot   /* Set for user space (1 rsvd for read) */
  1007. extru,=  pte,_PAGE_GATEWAY_BIT,1,r0
  1008. depi 0,11,2,prot /* If Gateway, Set PL2 to 0 */
  1009. /* Get rid of prot bits and convert to page addr for idtlba */
  1010. depi 0,31,12,pte
  1011. extru pte,24,25,pte
  1012. mfsp %sr1,t0  /* Save sr1 so we can use it in tlb inserts */
  1013. mtsp spc,%sr1
  1014. idtlba pte,(%sr1,va)
  1015. idtlbp prot,(%sr1,va)
  1016. mtsp t0, %sr1 /* Restore sr1 */
  1017. rfir
  1018. nop
  1019. nadtlb_check_flush_11:
  1020. bb,>=,n          pte,_PAGE_FLUSH_BIT,nadtlb_emulate
  1021. /* Insert a "flush only" translation */
  1022. zdepi           7,7,3,prot
  1023. depi            1,10,1,prot
  1024. /* Get rid of prot bits and convert to page addr for idtlba */
  1025. depi 0,31,12,pte
  1026. extru pte,24,25,pte
  1027. mfsp %sr1,t0  /* Save sr1 so we can use it in tlb inserts */
  1028. mtsp spc,%sr1
  1029. idtlba pte,(%sr1,va)
  1030. idtlbp prot,(%sr1,va)
  1031. mtsp t0, %sr1 /* Restore sr1 */
  1032. rfir
  1033. nop
  1034. dtlb_miss_20:
  1035. mfctl           %cr25,ptp /* Assume user space miss */
  1036. or,<>           %r0,spc,%r0 /* If it is user space, nullify */
  1037. mfctl           %cr24,ptp /* Load kernel pgd instead */
  1038. extru va,9,10,t1 /* Get pgd index */
  1039. mfsp            %sr7,t0 /* Get current space */
  1040. or,=            %r0,t0,%r0 /* If kernel, nullify following test */
  1041. cmpb,<>,n       t0,spc,dtlb_fault /* forward */
  1042. /* First level page table lookup */
  1043. ldwx,s t1(ptp),ptp
  1044. extru va,19,10,t0 /* get second-level index */
  1045. bb,>=,n         ptp,_PAGE_PRESENT_BIT,dtlb_check_alias_20
  1046. depi 0,31,12,ptp /* clear prot bits */
  1047. /* Second level page table lookup */
  1048. sh2addl   t0,ptp,ptp
  1049. ldi _PAGE_ACCESSED,t1
  1050. ldw  0(ptp),pte
  1051. bb,>=,n          pte,_PAGE_PRESENT_BIT,dtlb_check_alias_20
  1052. /* Check whether the "accessed" bit was set, otherwise do so */
  1053. or t1,pte,t0 /* t0 has R bit set */
  1054. and,<> t1,pte,%r0 /* test and nullify if already set */
  1055. stw t0,0(ptp) /* write back pte */
  1056. space_to_prot   spc prot        /* create prot id from space */
  1057. depd            pte,8,7,prot    /* add in prot bits from pte */
  1058. extrd,u,*=      pte,_PAGE_USER_BIT+32,1,r0
  1059. depdi 7,11,3,prot   /* Set for user space (1 rsvd for read) */
  1060. extrd,u,*=  pte,_PAGE_GATEWAY_BIT+32,1,r0
  1061. depdi 0,11,2,prot /* If Gateway, Set PL2 to 0 */
  1062. /* Get rid of prot bits and convert to page addr for idtlbt */
  1063. extrd,s         pte,35,4,t0
  1064. depdi 0,63,12,pte /* clear lower 12 bits */
  1065.         addi,=          1,t0,0 
  1066.         extrd,u,*tr     pte,56,25,pte 
  1067. extrd,s pte,56,25,pte /* bit 31:8 >> 8  */ 
  1068. idtlbt          pte,prot
  1069. rfir
  1070. nop
  1071. dtlb_check_alias_20:
  1072. /* Check to see if fault is in the temporary alias region */
  1073. cmpib,<>,n      0,spc,dtlb_fault /* forward */
  1074. ldil            L%(TMPALIAS_MAP_START),t0
  1075. copy            va,t1
  1076. depwi           0,31,23,t1
  1077. cmpb,<>,n       t0,t1,dtlb_fault /* forward */
  1078. ldi             (_PAGE_DIRTY|_PAGE_WRITE|_PAGE_READ),prot
  1079. depd,z          prot,8,7,prot
  1080. /*
  1081.  * OK, it is in the temp alias region, check whether "from" or "to".
  1082.  * Check "subtle" note in pacache.S re: r23/r26.
  1083.  */
  1084. extrw,u,=       va,9,1,r0
  1085. or,tr           %r23,%r0,pte    /* If "from" use "from" page */
  1086. or              %r26,%r0,pte    /* else "to", use "to" page  */
  1087. idtlbt          pte,prot
  1088. rfir
  1089. nop
  1090. nadtlb_miss_20:
  1091. mfctl           %cr25,ptp /* Assume user space miss */
  1092. or,<>           %r0,spc,%r0 /* If it is user space, nullify */
  1093. mfctl           %cr24,ptp /* Load kernel pgd instead */
  1094. extru va,9,10,t1 /* Get pgd index */
  1095. mfsp            %sr7,t0 /* Get current space */
  1096. or,=            %r0,t0,%r0 /* If kernel, nullify following test */
  1097. cmpb,<>,n       t0,spc,nadtlb_fault /* forward */
  1098. /* First level page table lookup */
  1099. ldwx,s t1(ptp),ptp
  1100. extru va,19,10,t0 /* get second-level index */
  1101. bb,>=,n         ptp,_PAGE_PRESENT_BIT,nadtlb_emulate
  1102. depi 0,31,12,ptp /* clear prot bits */
  1103. /* Second level page table lookup */
  1104. sh2addl   t0,ptp,ptp
  1105. ldi _PAGE_ACCESSED,t1
  1106. ldw  0(ptp),pte
  1107. bb,>=,n          pte,_PAGE_PRESENT_BIT,nadtlb_check_flush_20
  1108. space_to_prot   spc prot        /* create prot id from space */
  1109. depd            pte,8,7,prot    /* add in prot bits from pte */
  1110. extrd,u,*=      pte,_PAGE_USER_BIT+32,1,r0
  1111. depdi 7,11,3,prot   /* Set for user space (1 rsvd for read) */
  1112. extrd,u,*=  pte,_PAGE_GATEWAY_BIT+32,1,r0
  1113. depdi 0,11,2,prot /* If Gateway, Set PL2 to 0 */
  1114. /* Get rid of prot bits and convert to page addr for idtlbt */
  1115.         extrd,s         pte,35,4,t0
  1116.         depdi           0,63,12,pte     /* clear lower 12 bits */
  1117.         addi,=          1,t0,0
  1118.         extrd,u,*tr     pte,56,25,pte
  1119.         extrd,s         pte,56,25,pte   /* bit 31:8 >> 8  */
  1120.         idtlbt          pte,prot
  1121. rfir
  1122. nop
  1123. nadtlb_check_flush_20:
  1124. bb,>=,n          pte,_PAGE_FLUSH_BIT,nadtlb_emulate
  1125. /* Insert a "flush only" translation */
  1126. depdi,z         7,7,3,prot
  1127. depdi           1,10,1,prot
  1128. /* Get rid of prot bits and convert to page addr for idtlbt */
  1129. depdi 0,63,12,pte
  1130. extrd,u         pte,56,32,pte
  1131. idtlbt          pte,prot
  1132. rfir
  1133. nop
  1134. #endif
  1135. nadtlb_emulate:
  1136. /*
  1137.  * Non access misses can be caused by fdc,fic,pdc,lpa,probe and
  1138.  * probei instructions. We don't want to fault for these
  1139.  * instructions (not only does it not make sense, it can cause
  1140.  * deadlocks, since some flushes are done with the mmap
  1141.  * semaphore held). If the translation doesn't exist, we can't
  1142.  * insert a translation, so have to emulate the side effects
  1143.  * of the instruction. Since we don't insert a translation
  1144.  * we can get a lot of faults during a flush loop, so it makes
  1145.  * sense to try to do it here with minimum overhead. We only
  1146.  * emulate fdc,fic & pdc instructions whose base and index
  1147.  * registers are not shadowed. We defer everything else to the
  1148.  * "slow" path.
  1149.  */
  1150. mfctl           %cr19,%r9 /* Get iir */
  1151. ldi             0x280,%r16
  1152. and             %r9,%r16,%r17
  1153. cmpb,<>,n       %r16,%r17,nadtlb_fault /* Not fdc,fic,pdc */
  1154. bb,>=,n         %r9,26,nadtlb_nullify  /* m bit not set, just nullify */
  1155. b,l             get_register,%r25
  1156. extrw,u         %r9,15,5,%r8           /* Get index register # */
  1157. CMPIB=,n        -1,%r1,nadtlb_fault    /* have to use slow path */
  1158. copy            %r1,%r24
  1159. b,l             get_register,%r25
  1160. extrw,u         %r9,10,5,%r8           /* Get base register # */
  1161. CMPIB=,n        -1,%r1,nadtlb_fault    /* have to use slow path */
  1162. b,l             set_register,%r25
  1163. add,l           %r1,%r24,%r1           /* doesn't affect c/b bits */
  1164. nadtlb_nullify:
  1165. mfctl           %cr22,%r8              /* Get ipsw */
  1166. ldil            L%PSW_N,%r9
  1167. or              %r8,%r9,%r8            /* Set PSW_N */
  1168. mtctl           %r8,%cr22
  1169. rfir
  1170. nop
  1171. #ifdef __LP64__
  1172. itlb_miss_20w:
  1173. /*
  1174.  * I miss is a little different, since we allow users to fault
  1175.  * on the gateway page which is in the kernel address space.
  1176.  */
  1177. extrd,u         spc,63,7,t1     /* adjust va */
  1178. depd            t1,31,7,va      /* adjust va */
  1179. depdi           0,63,7,spc      /* adjust space */
  1180. cmpib,*=        0,spc,itlb_miss_kernel_20w
  1181. extrd,u         va,33,9,t1      /* Get pgd index */
  1182. mfctl           %cr25,ptp /* load user pgd */
  1183. mfsp            %sr7,t0 /* Get current space */
  1184. or,*=           %r0,t0,%r0      /* If kernel, nullify following test */
  1185. cmpb,*<>,n      t0,spc,itlb_fault /* forward */
  1186. /* First level page table lookup */
  1187. itlb_miss_common_20w:
  1188. ldd,s           t1(ptp),ptp
  1189. extrd,u         va,42,9,t0     /* get second-level index */
  1190. bb,>=,n  ptp,_PAGE_PRESENT_BIT,itlb_fault
  1191. depdi           0,63,12,ptp     /* clear prot bits */
  1192. /* Second level page table lookup */
  1193. ldd,s           t0(ptp),ptp
  1194. extrd,u         va,51,9,t0     /* get third-level index */
  1195. bb,>=,n         ptp,_PAGE_PRESENT_BIT,itlb_fault
  1196. depdi           0,63,12,ptp     /* clear prot bits */
  1197. /* Third level page table lookup */
  1198. shladd           t0,3,ptp,ptp
  1199. ldi _PAGE_ACCESSED,t1
  1200. ldd              0(ptp),pte
  1201. bb,>=,n          pte,_PAGE_PRESENT_BIT,itlb_fault
  1202. /* Check whether the "accessed" bit was set, otherwise do so */
  1203. or t1,pte,t0 /* t0 has R bit set */
  1204. and,*<>         t1,pte,%r0      /* test and nullify if already set */
  1205. std             t0,0(ptp)       /* write back pte */
  1206. space_to_prot   spc prot        /* create prot id from space */
  1207. depd            pte,8,7,prot    /* add in prot bits from pte */
  1208. extrd,u,*=      pte,_PAGE_USER_BIT+32,1,r0
  1209. depdi 7,11,3,prot   /* Set for user space (1 rsvd for read) */
  1210. extrd,u,*=  pte,_PAGE_GATEWAY_BIT+32,1,r0
  1211. depdi 0,11,2,prot /* If Gateway, Set PL2 to 0 */
  1212. /* Get rid of prot bits and convert to page addr for iitlbt */
  1213. depdi 0,63,12,pte
  1214. extrd,u         pte,56,32,pte
  1215. iitlbt          pte,prot
  1216. rfir
  1217. nop
  1218. itlb_miss_kernel_20w:
  1219. b               itlb_miss_common_20w
  1220. mfctl           %cr24,ptp /* Load kernel pgd */
  1221. #else
  1222. itlb_miss_11:
  1223. /*
  1224.  * I miss is a little different, since we allow users to fault
  1225.  * on the gateway page which is in the kernel address space.
  1226.  */
  1227. cmpib,=         0,spc,itlb_miss_kernel_11
  1228. extru va,9,10,t1 /* Get pgd index */
  1229. mfctl           %cr25,ptp /* load user pgd */
  1230. mfsp            %sr7,t0 /* Get current space */
  1231. or,=            %r0,t0,%r0 /* If kernel, nullify following test */
  1232. cmpb,<>,n       t0,spc,itlb_fault /* forward */
  1233. /* First level page table lookup */
  1234. itlb_miss_common_11:
  1235. ldwx,s t1(ptp),ptp
  1236. extru va,19,10,t0 /* get second-level index */
  1237. bb,>=,n  ptp,_PAGE_PRESENT_BIT,itlb_fault
  1238. depi 0,31,12,ptp /* clear prot bits */
  1239. /* Second level page table lookup */
  1240. sh2addl   t0,ptp,ptp
  1241. ldi _PAGE_ACCESSED,t1
  1242. ldw  0(ptp),pte
  1243. bb,>=,n   pte,_PAGE_PRESENT_BIT,itlb_fault
  1244. /* Check whether the "accessed" bit was set, otherwise do so */
  1245. or t1,pte,t0 /* t0 has R bit set */
  1246. and,<> t1,pte,%r0 /* test and nullify if already set */
  1247. stw t0,0(ptp) /* write back pte */
  1248. zdep            spc,30,15,prot  /* create prot id from space */
  1249. dep             pte,8,7,prot    /* add in prot bits from pte */
  1250. extru,= pte,_PAGE_NO_CACHE_BIT,1,r0
  1251. depi 1,12,1,prot
  1252. extru,=         pte,_PAGE_USER_BIT,1,r0
  1253. depi 7,11,3,prot   /* Set for user space (1 rsvd for read) */
  1254. extru,=  pte,_PAGE_GATEWAY_BIT,1,r0
  1255. depi 0,11,2,prot /* If Gateway, Set PL2 to 0 */
  1256. /* Get rid of prot bits and convert to page addr for iitlba */
  1257. depi 0,31,12,pte
  1258. extru pte,24,25,pte
  1259. mfsp %sr1,t0  /* Save sr1 so we can use it in tlb inserts */
  1260. mtsp spc,%sr1
  1261. iitlba pte,(%sr1,va)
  1262. iitlbp prot,(%sr1,va)
  1263. mtsp t0, %sr1 /* Restore sr1 */
  1264. rfir
  1265. nop
  1266. itlb_miss_kernel_11:
  1267. b               itlb_miss_common_11
  1268. mfctl           %cr24,ptp /* Load kernel pgd */
  1269. itlb_miss_20:
  1270. /*
  1271.  * I miss is a little different, since we allow users to fault
  1272.  * on the gateway page which is in the kernel address space.
  1273.  */
  1274. cmpib,=         0,spc,itlb_miss_kernel_20
  1275. extru va,9,10,t1 /* Get pgd index */
  1276. mfctl           %cr25,ptp /* load user pgd */
  1277. mfsp            %sr7,t0 /* Get current space */
  1278. or,=            %r0,t0,%r0 /* If kernel, nullify following test */
  1279. cmpb,<>,n       t0,spc,itlb_fault /* forward */
  1280. /* First level page table lookup */
  1281. itlb_miss_common_20:
  1282. ldwx,s t1(ptp),ptp
  1283. extru va,19,10,t0 /* get second-level index */
  1284. bb,>=,n  ptp,_PAGE_PRESENT_BIT,itlb_fault
  1285. depi 0,31,12,ptp /* clear prot bits */
  1286. /* Second level page table lookup */
  1287. sh2addl   t0,ptp,ptp
  1288. ldi _PAGE_ACCESSED,t1
  1289. ldw  0(ptp),pte
  1290. bb,>=,n   pte,_PAGE_PRESENT_BIT,itlb_fault
  1291. /* Check whether the "accessed" bit was set, otherwise do so */
  1292. or t1,pte,t0 /* t0 has R bit set */
  1293. and,<> t1,pte,%r0 /* test and nullify if already set */
  1294. stw t0,0(ptp) /* write back pte */
  1295. space_to_prot   spc prot        /* create prot id from space */
  1296. depd            pte,8,7,prot    /* add in prot bits from pte */
  1297. extrd,u,*=      pte,_PAGE_USER_BIT+32,1,r0
  1298. depdi 7,11,3,prot   /* Set for user space (1 rsvd for read) */
  1299. extrd,u,*=  pte,_PAGE_GATEWAY_BIT+32,1,r0
  1300. depdi 0,11,2,prot /* If Gateway, Set PL2 to 0 */
  1301. /* Get rid of prot bits and convert to page addr for iitlbt */
  1302.         extrd,s         pte,35,4,t0 
  1303.         depdi           0,63,12,pte     /* clear lower 12 bits */
  1304.         addi,=          1,t0,0
  1305.         extrd,u,*tr     pte,56,25,pte 
  1306.         extrd,s         pte,56,25,pte   /* bit 31:8 >> 8  */
  1307. iitlbt          pte,prot
  1308. rfir
  1309. nop
  1310. itlb_miss_kernel_20:
  1311. b               itlb_miss_common_20
  1312. mfctl           %cr24,ptp /* Load kernel pgd */
  1313. #endif
  1314. #ifdef __LP64__
  1315. dbit_trap_20w:
  1316. extrd,u         spc,63,7,t1     /* adjust va */
  1317. depd            t1,31,7,va      /* adjust va */
  1318. depdi           0,1,2,va        /* adjust va */
  1319. depdi           0,63,7,spc      /* adjust space */
  1320. mfctl           %cr25,ptp /* Assume user space miss */
  1321. or,*<>          %r0,spc,%r0     /* If it is user space, nullify */
  1322. mfctl           %cr24,ptp /* Load kernel pgd instead */
  1323. extrd,u         va,33,9,t1      /* Get pgd index */
  1324. mfsp            %sr7,t0 /* Get current space */
  1325. or,*=           %r0,t0,%r0      /* If kernel, nullify following test */
  1326. cmpb,*<>,n       t0,spc,dbit_fault /* forward */
  1327. /* First level page table lookup */
  1328. ldd,s           t1(ptp),ptp
  1329. extrd,u         va,42,9,t0     /* get second-level index */
  1330. bb,>=,n         ptp,_PAGE_PRESENT_BIT,dbit_fault
  1331. depdi           0,63,12,ptp     /* clear prot bits */
  1332. /* Second level page table lookup */
  1333. ldd,s           t0(ptp),ptp
  1334. extrd,u         va,51,9,t0     /* get third-level index */
  1335. bb,>=,n         ptp,_PAGE_PRESENT_BIT,dbit_fault
  1336. depdi           0,63,12,ptp     /* clear prot bits */
  1337. /* Third level page table lookup */
  1338. shladd           t0,3,ptp,ptp
  1339. #ifdef CONFIG_SMP
  1340. CMPIB=,n        0,spc,dbit_nolock_20w
  1341. ldil            L%PA(pa_dbit_lock),t0
  1342. ldo             R%PA(pa_dbit_lock)(t0),t0
  1343. dbit_spin_20w:
  1344. ldcw            0(t0),t1
  1345. cmpib,=         0,t1,dbit_spin_20w
  1346. nop
  1347. dbit_nolock_20w:
  1348. #endif
  1349. ldi (_PAGE_ACCESSED|_PAGE_DIRTY),t1
  1350. ldd              0(ptp),pte
  1351. bb,>=,n          pte,_PAGE_PRESENT_BIT,dbit_fault
  1352. /* Set Accessed and Dirty bits in the pte */
  1353. or t1,pte,pte
  1354. std             pte,0(ptp)      /* write back pte */
  1355. space_to_prot   spc prot        /* create prot id from space */
  1356. depd            pte,8,7,prot    /* add in prot bits from pte */
  1357. extrd,u,*=      pte,_PAGE_USER_BIT+32,1,r0
  1358. depdi 7,11,3,prot   /* Set for user space (1 rsvd for read) */
  1359. extrd,u,*=  pte,_PAGE_GATEWAY_BIT+32,1,r0
  1360. depdi 0,11,2,prot /* If Gateway, Set PL2 to 0 */
  1361. /* Get rid of prot bits and convert to page addr for idtlbt */
  1362. depdi 0,63,12,pte
  1363. extrd,u         pte,56,52,pte
  1364. idtlbt          pte,prot
  1365. #ifdef CONFIG_SMP
  1366. CMPIB=,n        0,spc,dbit_nounlock_20w
  1367. ldi             1,t1
  1368. stw             t1,0(t0)
  1369. dbit_nounlock_20w:
  1370. #endif
  1371. rfir
  1372. nop
  1373. #else
  1374. dbit_trap_11:
  1375. mfctl           %cr25,ptp /* Assume user space trap */
  1376. or,<>           %r0,spc,%r0 /* If it is user space, nullify */
  1377. mfctl           %cr24,ptp /* Load kernel pgd instead */
  1378. extru va,9,10,t1 /* Get pgd index */
  1379. mfsp            %sr7,t0 /* Get current space */
  1380. or,=            %r0,t0,%r0 /* If kernel, nullify following test */
  1381. cmpb,<>,n       t0,spc,dbit_fault /* forward */
  1382. /* First level page table lookup */
  1383. ldwx,s t1(ptp),ptp
  1384. extru va,19,10,t0 /* get second-level index */
  1385. bb,>=,n  ptp,_PAGE_PRESENT_BIT,dbit_fault
  1386. depi 0,31,12,ptp /* clear prot bits */
  1387. /* Second level page table lookup */
  1388. sh2addl   t0,ptp,ptp
  1389. #ifdef CONFIG_SMP
  1390. CMPIB=,n        0,spc,dbit_nolock_11
  1391. ldil            L%PA(pa_dbit_lock),t0
  1392. ldo             R%PA(pa_dbit_lock)(t0),t0
  1393. dbit_spin_11:
  1394. ldcw            0(t0),t1
  1395. cmpib,=         0,t1,dbit_spin_11
  1396. nop
  1397. dbit_nolock_11:
  1398. #endif
  1399. ldi (_PAGE_ACCESSED|_PAGE_DIRTY),t1
  1400. ldw  0(ptp),pte
  1401. bb,>=,n   pte,_PAGE_PRESENT_BIT,dbit_fault
  1402. /* Set Accessed and Dirty bits in the pte */
  1403. or t1,pte,pte
  1404. stw pte,0(ptp) /* write back pte */
  1405. zdep            spc,30,15,prot  /* create prot id from space */
  1406. dep             pte,8,7,prot    /* add in prot bits from pte */
  1407. extru,= pte,_PAGE_NO_CACHE_BIT,1,r0
  1408. depi 1,12,1,prot
  1409. extru,=         pte,_PAGE_USER_BIT,1,r0
  1410. depi 7,11,3,prot /* Set for user space (1 rsvd for read) */
  1411. extru,=  pte,_PAGE_GATEWAY_BIT,1,r0
  1412. depi 0,11,2,prot /* If Gateway, Set PL2 to 0 */
  1413. /* Get rid of prot bits and convert to page addr for idtlba */
  1414. depi 0,31,12,pte
  1415. extru pte,24,25,pte
  1416. mfsp            %sr1,t1  /* Save sr1 so we can use it in tlb inserts */
  1417. mtsp spc,%sr1
  1418. idtlba pte,(%sr1,va)
  1419. idtlbp prot,(%sr1,va)
  1420. mtsp            t1, %sr1     /* Restore sr1 */
  1421. #ifdef CONFIG_SMP
  1422. CMPIB=,n        0,spc,dbit_nounlock_11
  1423. ldi             1,t1
  1424. stw             t1,0(t0)
  1425. dbit_nounlock_11:
  1426. #endif
  1427. rfir
  1428. nop
  1429. dbit_trap_20:
  1430. mfctl           %cr25,ptp /* Assume user space trap */
  1431. or,<>           %r0,spc,%r0 /* If it is user space, nullify */
  1432. mfctl           %cr24,ptp /* Load kernel pgd instead */
  1433. extru va,9,10,t1 /* Get pgd index */
  1434. mfsp            %sr7,t0 /* Get current space */
  1435. or,=            %r0,t0,%r0 /* If kernel, nullify following test */
  1436. cmpb,<>,n       t0,spc,dbit_fault /* forward */
  1437. /* First level page table lookup */
  1438. ldwx,s t1(ptp),ptp
  1439. extru va,19,10,t0 /* get second-level index */
  1440. bb,>=,n  ptp,_PAGE_PRESENT_BIT,dbit_fault
  1441. depi 0,31,12,ptp /* clear prot bits */
  1442. /* Second level page table lookup */
  1443. sh2addl   t0,ptp,ptp
  1444. #ifdef CONFIG_SMP
  1445. CMPIB=,n        0,spc,dbit_nolock_20
  1446. ldil            L%PA(pa_dbit_lock),t0
  1447. ldo             R%PA(pa_dbit_lock)(t0),t0
  1448. dbit_spin_20:
  1449. ldcw            0(t0),t1
  1450. cmpib,=         0,t1,dbit_spin_20
  1451. nop
  1452. dbit_nolock_20:
  1453. #endif
  1454. ldi (_PAGE_ACCESSED|_PAGE_DIRTY),t1
  1455. ldw  0(ptp),pte
  1456. bb,>=,n   pte,_PAGE_PRESENT_BIT,dbit_fault
  1457. /* Set Accessed and Dirty bits in the pte */
  1458. or t1,pte,pte
  1459. stw pte,0(ptp) /* write back pte */
  1460. space_to_prot   spc prot        /* create prot id from space */
  1461. depd            pte,8,7,prot    /* add in prot bits from pte */
  1462. extrd,u,*=      pte,_PAGE_USER_BIT+32,1,r0
  1463. depdi 7,11,3,prot   /* Set for user space (1 rsvd for read) */
  1464. extrd,u,*=  pte,_PAGE_GATEWAY_BIT+32,1,r0
  1465. depdi 0,11,2,prot /* If Gateway, Set PL2 to 0 */
  1466.         extrd,s         pte,35,4,t0 
  1467.         depdi           0,63,12,pte     /* clear lower 12 bits */
  1468.         addi,=          1,t0,0
  1469.         extrd,u,*tr     pte,56,25,pte 
  1470.         extrd,s         pte,56,25,pte   /* bit 31:8 >> 8  */
  1471.         idtlbt          pte,prot
  1472. #ifdef CONFIG_SMP
  1473. CMPIB=,n        0,spc,dbit_nounlock_20
  1474. ldi             1,t1
  1475. stw             t1,0(t0)
  1476. dbit_nounlock_20:
  1477. #endif
  1478. rfir
  1479. nop
  1480. #endif
  1481. .import handle_interruption,code
  1482. kernel_bad_space:
  1483. b               intr_save
  1484. ldi             31,%r8  /* Use an unused code */
  1485. dbit_fault:
  1486. b               intr_save
  1487. ldi             20,%r8
  1488. itlb_fault:
  1489. b               intr_save
  1490. ldi             6,%r8
  1491. nadtlb_fault:
  1492. b               intr_save
  1493. ldi             17,%r8
  1494. dtlb_fault:
  1495. b               intr_save
  1496. ldi             15,%r8
  1497. /* Register saving semantics for system calls:
  1498.    %r1    clobbered by system call macro in userspace
  1499.    %r2    saved in PT_REGS by gateway page
  1500.    %r3  - %r18    preserved by C code (saved by signal code)
  1501.    %r19 - %r20    saved in PT_REGS by gateway page
  1502.    %r21 - %r22    non-standard syscall args
  1503.    stored in kernel stack by gateway page
  1504.    %r23 - %r26    arg3-arg0, saved in PT_REGS by gateway page
  1505.    %r27 - %r30    saved in PT_REGS by gateway page
  1506.    %r31    syscall return pointer
  1507.  */
  1508. /* Floating point registers (FIXME: what do we do with these?)
  1509.    %fr0  - %fr3    status/exception, not preserved
  1510.    %fr4  - %fr7    arguments
  1511.    %fr8  - %fr11   not preserved by C code
  1512.    %fr12 - %fr21   preserved by C code
  1513.    %fr22 - %fr31   not preserved by C code
  1514.  */
  1515. .macro reg_save regs
  1516. STREG %r3, PT_GR3(regs)
  1517. STREG %r4, PT_GR4(regs)
  1518. STREG %r5, PT_GR5(regs)
  1519. STREG %r6, PT_GR6(regs)
  1520. STREG %r7, PT_GR7(regs)
  1521. STREG %r8, PT_GR8(regs)
  1522. STREG %r9, PT_GR9(regs)
  1523. STREG   %r10,PT_GR10(regs)
  1524. STREG   %r11,PT_GR11(regs)
  1525. STREG   %r12,PT_GR12(regs)
  1526. STREG   %r13,PT_GR13(regs)
  1527. STREG   %r14,PT_GR14(regs)
  1528. STREG   %r15,PT_GR15(regs)
  1529. STREG   %r16,PT_GR16(regs)
  1530. STREG   %r17,PT_GR17(regs)
  1531. STREG   %r18,PT_GR18(regs)
  1532. .endm
  1533. .macro reg_restore regs
  1534. LDREG PT_GR3(regs), %r3
  1535. LDREG PT_GR4(regs), %r4
  1536. LDREG PT_GR5(regs), %r5
  1537. LDREG PT_GR6(regs), %r6
  1538. LDREG PT_GR7(regs), %r7
  1539. LDREG PT_GR8(regs), %r8
  1540. LDREG PT_GR9(regs), %r9
  1541. LDREG   PT_GR10(regs),%r10
  1542. LDREG   PT_GR11(regs),%r11
  1543. LDREG   PT_GR12(regs),%r12
  1544. LDREG   PT_GR13(regs),%r13
  1545. LDREG   PT_GR14(regs),%r14
  1546. LDREG   PT_GR15(regs),%r15
  1547. LDREG   PT_GR16(regs),%r16
  1548. LDREG   PT_GR17(regs),%r17
  1549. LDREG   PT_GR18(regs),%r18
  1550. .endm
  1551. .export sys_fork_wrapper
  1552. .export child_return
  1553. sys_fork_wrapper:
  1554. ldo TASK_REGS-TASK_SZ_ALGN-FRAME_SIZE(%r30),%r1 /* get pt regs */
  1555. reg_save %r1
  1556. mfctl %cr27, %r3
  1557. STREG %r3, PT_CR27(%r1)
  1558. STREG %r2,-RP_OFFSET(%r30)
  1559. ldo FRAME_SIZE(%r30),%r30
  1560. #ifdef __LP64__
  1561. ldo -16(%r30),%r29 /* Reference param save area */
  1562. #endif
  1563. /* These are call-clobbered registers and therefore
  1564.    also syscall-clobbered (we hope). */
  1565. STREG %r2,PT_GR19(%r1) /* save for child */
  1566. STREG %r30,PT_GR21(%r1)
  1567. LDREG PT_GR30(%r1),%r25
  1568. copy %r1,%r24
  1569. bl sys_clone,%r2
  1570. ldi SIGCHLD,%r26
  1571. LDREG -RP_OFFSET-FRAME_SIZE(%r30),%r2
  1572. wrapper_exit:
  1573. ldo -FRAME_SIZE(%r30),%r30 /* get the stackframe */
  1574. ldo TASK_REGS-TASK_SZ_ALGN-FRAME_SIZE(%r30),%r1    /* get pt regs */
  1575. LDREG PT_CR27(%r1), %r3
  1576. mtctl %r3, %cr27
  1577. reg_restore %r1
  1578. /* strace expects syscall # to be preserved in r20 */
  1579. ldi __NR_fork,%r20
  1580. bv %r0(%r2)
  1581. STREG %r20,PT_GR20(%r1)
  1582. /* Set the return value for the child */
  1583. child_return:
  1584. bl schedule_tail, %r2
  1585. nop
  1586. LDREG TASK_PT_GR19-TASK_SZ_ALGN-FRAME_SIZE-FRAME_SIZE(%r30),%r2
  1587. b wrapper_exit
  1588. copy %r0,%r28
  1589. .export sys_clone_wrapper
  1590. sys_clone_wrapper:
  1591. ldo TASK_REGS-TASK_SZ_ALGN-FRAME_SIZE(%r30),%r1 /* get pt regs */
  1592. reg_save %r1
  1593. mfctl %cr27, %r3
  1594. STREG %r3, PT_CR27(%r1)
  1595. STREG %r2,-RP_OFFSET(%r30)
  1596. ldo FRAME_SIZE(%r30),%r30
  1597. #ifdef __LP64__
  1598. ldo -16(%r30),%r29 /* Reference param save area */
  1599. #endif
  1600. STREG %r2,PT_GR19(%r1) /* save for child */
  1601. STREG %r30,PT_GR21(%r1)
  1602. bl sys_clone,%r2
  1603. copy %r1,%r24
  1604. b wrapper_exit
  1605. LDREG -RP_OFFSET-FRAME_SIZE(%r30),%r2
  1606. .export sys_vfork_wrapper
  1607. sys_vfork_wrapper:
  1608. ldo TASK_REGS-TASK_SZ_ALGN-FRAME_SIZE(%r30),%r1 /* get pt regs */
  1609. reg_save %r1
  1610. mfctl %cr27, %r3
  1611. STREG %r3, PT_CR27(%r1)
  1612. STREG %r2,-RP_OFFSET(%r30)
  1613. ldo FRAME_SIZE(%r30),%r30
  1614. #ifdef __LP64__
  1615. ldo -16(%r30),%r29 /* Reference param save area */
  1616. #endif
  1617. STREG %r2,PT_GR19(%r1) /* save for child */
  1618. STREG %r30,PT_GR21(%r1)
  1619. bl sys_vfork,%r2
  1620. copy %r1,%r26
  1621. b wrapper_exit
  1622. LDREG -RP_OFFSET-FRAME_SIZE(%r30),%r2
  1623. .macro  execve_wrapper execve
  1624. ldo TASK_REGS-TASK_SZ_ALGN-FRAME_SIZE(%r30),%r1     /* get pt regs */
  1625. /*
  1626.  * Do we need to save/restore r3-r18 here?
  1627.  * I don't think so. why would new thread need old
  1628.  * threads registers?
  1629.  */
  1630. /* %arg0 - %arg3 are already saved for us. */
  1631. STREG %r2,-RP_OFFSET(%r30)
  1632. ldo FRAME_SIZE(%r30),%r30
  1633. #ifdef __LP64__
  1634. ldo -16(%r30),%r29 /* Reference param save area */
  1635. #endif
  1636. bl execve,%r2
  1637. copy %r1,%arg0
  1638. ldo -FRAME_SIZE(%r30),%r30
  1639. LDREG -RP_OFFSET(%r30),%r2
  1640. /* If exec succeeded we need to load the args */
  1641. ldo -1024(%r0),%r1
  1642. cmpb,>>= %r28,%r1,error_execve
  1643. copy %r2,%r19
  1644. error_execve:
  1645. bv %r0(%r19)
  1646. nop
  1647. .endm
  1648. .export sys_execve_wrapper
  1649. .import sys_execve
  1650. sys_execve_wrapper:
  1651. execve_wrapper sys_execve
  1652. #ifdef __LP64__
  1653. .export sys32_execve_wrapper
  1654. .import sys32_execve
  1655. sys32_execve_wrapper:
  1656. execve_wrapper sys32_execve
  1657. #endif
  1658. .export sys_rt_sigreturn_wrapper
  1659. sys_rt_sigreturn_wrapper:
  1660. ldo TASK_REGS-TASK_SZ_ALGN-FRAME_SIZE(%r30), %r26
  1661. /* Don't save regs, we are going to restore them from sigcontext. */
  1662. STREG %r2, -RP_OFFSET(%r30)
  1663. #ifdef __LP64__
  1664. ldo FRAME_SIZE(%r30), %r30
  1665. bl sys_rt_sigreturn,%r2
  1666. ldo -16(%r30),%r29 /* Reference param save area */
  1667. #else
  1668. bl sys_rt_sigreturn,%r2
  1669. ldo FRAME_SIZE(%r30), %r30
  1670. #endif
  1671. ldo -FRAME_SIZE(%r30), %r30
  1672. LDREG -RP_OFFSET(%r30), %r2
  1673. /* FIXME: I think we need to restore a few more things here. */
  1674. ldo TASK_REGS-TASK_SZ_ALGN-FRAME_SIZE(%r30),%r1     /* get pt regs */
  1675. reg_restore %r1
  1676. /* If the signal was received while the process was blocked on a
  1677.  * syscall, then r2 will take us to syscall_exit; otherwise r2 will
  1678.  * take us to syscall_exit_rfi and on to intr_return.
  1679.  */
  1680. bv %r0(%r2)
  1681. LDREG PT_GR28(%r1),%r28  /* reload original r28 for syscall_exit */
  1682. .export sys_sigaltstack_wrapper
  1683. sys_sigaltstack_wrapper:
  1684. /* Get the user stack pointer */
  1685. LDREG -TASK_SZ_ALGN-FRAME_SIZE+TASK_PT_GR30(%r30), %r24
  1686. STREG %r2, -RP_OFFSET(%r30)
  1687. #ifdef __LP64__
  1688. ldo FRAME_SIZE(%r30), %r30
  1689. bl do_sigaltstack,%r2
  1690. ldo -16(%r30),%r29 /* Reference param save area */
  1691. #else
  1692. bl do_sigaltstack,%r2
  1693. ldo FRAME_SIZE(%r30), %r30
  1694. #endif
  1695. ldo -FRAME_SIZE(%r30), %r30
  1696. LDREG -RP_OFFSET(%r30), %r2
  1697. bv %r0(%r2)
  1698. nop
  1699. #ifdef __LP64__
  1700. .export sys32_sigaltstack_wrapper
  1701. sys32_sigaltstack_wrapper:
  1702. /* Get the user stack pointer */
  1703. LDREG -TASK_SZ_ALGN-FRAME_SIZE+TASK_PT_GR30(%r30), %r24
  1704. STREG %r2, -RP_OFFSET(%r30)
  1705. ldo FRAME_SIZE(%r30), %r30
  1706. bl do_sigaltstack32,%r2
  1707. ldo -16(%r30),%r29 /* Reference param save area */
  1708. ldo -FRAME_SIZE(%r30), %r30
  1709. LDREG -RP_OFFSET(%r30), %r2
  1710. bv %r0(%r2)
  1711. nop
  1712. #endif
  1713. .export sys_rt_sigsuspend_wrapper
  1714. sys_rt_sigsuspend_wrapper:
  1715. ldo TASK_REGS-TASK_SZ_ALGN-FRAME_SIZE(%r30), %r24
  1716. reg_save %r24
  1717. STREG %r2, -RP_OFFSET(%r30)
  1718. #ifdef __LP64__
  1719. ldo FRAME_SIZE(%r30), %r30
  1720. bl sys_rt_sigsuspend,%r2
  1721. ldo -16(%r30),%r29 /* Reference param save area */
  1722. #else
  1723. bl sys_rt_sigsuspend,%r2
  1724. ldo FRAME_SIZE(%r30), %r30
  1725. #endif
  1726. ldo -FRAME_SIZE(%r30), %r30
  1727. LDREG -RP_OFFSET(%r30), %r2
  1728. ldo TASK_REGS-TASK_SZ_ALGN-FRAME_SIZE(%r30),%r1
  1729. reg_restore %r1
  1730. bv %r0(%r2)
  1731. nop
  1732. .export syscall_exit
  1733. syscall_exit:
  1734. /* NOTE: HP-UX syscalls also come through here
  1735.    after hpux_syscall_exit fixes up return
  1736.    values. */
  1737. /* NOTE: Not all syscalls exit this way.  rt_sigreturn will exit
  1738.  * via syscall_exit_rfi if the signal was received while the process
  1739.  * was running.
  1740.  */
  1741. /* save return value now */
  1742. STREG     %r28,TASK_PT_GR28-TASK_SZ_ALGN-FRAME_SIZE(%r30)
  1743. /* Save other hpux returns if personality is PER_HPUX */
  1744. #define PER_HPUX 0xe /* <linux/personality.h> cannot be easily included */
  1745. LDREG     TASK_PERSONALITY-TASK_SZ_ALGN-FRAME_SIZE(%r30),%r19
  1746. CMPIB<>,n PER_HPUX,%r19,1f
  1747. STREG     %r22,TASK_PT_GR22-TASK_SZ_ALGN-FRAME_SIZE(%r30)
  1748. STREG     %r29,TASK_PT_GR29-TASK_SZ_ALGN-FRAME_SIZE(%r30)
  1749. 1:
  1750. /* Seems to me that dp could be wrong here, if the syscall involved
  1751.  * calling a module, and nothing got round to restoring dp on return.
  1752.  */
  1753. loadgp
  1754. syscall_check_bh:
  1755. /* Check for software interrupts */
  1756. .import irq_stat,data
  1757. ldil    L%irq_stat,%r19
  1758. ldo     R%irq_stat(%r19),%r19
  1759. #ifdef CONFIG_SMP
  1760. /* sched.h: int processor */
  1761. /* %r26 is used as scratch register to index into irq_stat[] */
  1762. ldw     TASK_PROCESSOR-TASK_SZ_ALGN-FRAME_SIZE(%r30),%r26 /* cpu # */
  1763. /* shift left ____cacheline_aligned (aka L1_CACHE_BYTES) bits */
  1764. #ifdef __LP64__
  1765. shld %r26, 6, %r20
  1766. #else
  1767. shlw %r26, 5, %r20
  1768. #endif
  1769. add     %r19,%r20,%r19 /* now have &irq_stat[smp_processor_id()] */
  1770. #endif /* CONFIG_SMP */
  1771. LDREG   IRQSTAT_SIRQ_PEND(%r19),%r20    /* hardirq.h: unsigned long */
  1772. cmpib,<>,n 0,%r20,syscall_do_softirq /* forward */
  1773. syscall_check_resched:
  1774. /* check for reschedule */
  1775. LDREG  TASK_NEED_RESCHED-TASK_SZ_ALGN-FRAME_SIZE(%r30),%r19 /* long */
  1776. CMPIB<>,n 0,%r19,syscall_do_resched /* forward */
  1777. syscall_check_sig:
  1778. ldo     -TASK_SZ_ALGN-FRAME_SIZE(%r30),%r1         /* get task ptr */
  1779. /* check for pending signals */
  1780. ldw     TASK_SIGPENDING(%r1),%r19
  1781. cmpib,<>,n 0,%r19,syscall_do_signal  /* forward */
  1782. syscall_restore:
  1783. LDREG TASK_PTRACE(%r1), %r19 /* Are we being ptraced? */
  1784. bb,<,n %r19,31,syscall_restore_rfi
  1785. ldo TASK_PT_FR31(%r1),%r19    /* reload fpregs */
  1786. rest_fp %r19
  1787. LDREG TASK_PT_SAR(%r1),%r19    /* restore SAR */
  1788. mtsar %r19
  1789. LDREG TASK_PT_GR2(%r1),%r2    /* restore user rp */
  1790. LDREG TASK_PT_GR19(%r1),%r19
  1791. LDREG   TASK_PT_GR20(%r1),%r20
  1792. LDREG TASK_PT_GR21(%r1),%r21
  1793. LDREG TASK_PT_GR22(%r1),%r22
  1794. LDREG TASK_PT_GR23(%r1),%r23
  1795. LDREG TASK_PT_GR24(%r1),%r24
  1796. LDREG TASK_PT_GR25(%r1),%r25
  1797. LDREG TASK_PT_GR26(%r1),%r26
  1798. LDREG TASK_PT_GR27(%r1),%r27    /* restore user dp */
  1799. LDREG TASK_PT_GR28(%r1),%r28    /* syscall return value */
  1800. LDREG TASK_PT_GR29(%r1),%r29
  1801. LDREG TASK_PT_GR31(%r1),%r31    /* restore syscall rp */
  1802. rsm     PSW_SM_I, %r0
  1803. LDREG   TASK_PT_GR30(%r1),%r30             /* restore user sp */
  1804. mfsp %sr3,%r1    /* Get users space id */
  1805. mtsp    %r1,%sr7                           /* Restore sr7 */
  1806. ssm     PSW_SM_I, %r0
  1807. mtsp %r1,%sr4    /* Restore sr4 */
  1808. mtsp %r1,%sr5    /* Restore sr5 */
  1809. mtsp %r1,%sr6    /* Restore sr6 */
  1810. depi 3,31,2,%r31    /* ensure return to user mode. */
  1811. #ifdef __LP64__
  1812. /* Since we are returning to a 32 bit user process, we always
  1813.  * clear the W bit. This means that the be (and mtsp) gets
  1814.  * executed in narrow mode, but that is OK, since we are
  1815.  * returning to a 32 bit process. When we support 64 bit processes
  1816.  * we won't clear the W bit, so the be will run in wide mode.
  1817.  */
  1818. be 0(%sr3,%r31)    /* return to user space */
  1819. rsm PSW_SM_W, %r0
  1820. #else
  1821. be,n    0(%sr3,%r31)                       /* return to user space */
  1822. #endif
  1823. /* We have to return via an RFI, so that PSW T and R bits can be set
  1824.  * appropriately.
  1825.  * This sets up pt_regs so we can return via intr_restore, which is not
  1826.  * the most efficient way of doing things, but it works.
  1827.  */
  1828. syscall_restore_rfi:
  1829. ldo -1(%r0),%r2    /* Set recovery cntr to -1 */
  1830. mtctl %r2,%cr0    /*   for immediate trap */
  1831. LDREG TASK_PT_PSW(%r1),%r2    /* Get old PSW */
  1832. ldi 0x0b,%r20    /* Create new PSW */
  1833. depi -1,13,1,%r20    /* C, Q, D, and I bits */
  1834. bb,>=,n %r19,15,try_tbit    /* PT_SINGLESTEP */
  1835. depi -1,27,1,%r20    /* R bit */
  1836. try_tbit:
  1837. bb,>=,n %r19,14,psw_setup    /* PT_BLOCKSTEP, see ptrace.c */
  1838. depi -1,7,1,%r20    /* T bit */
  1839. psw_setup:
  1840. STREG %r20,TASK_PT_PSW(%r1)
  1841. /* Always store space registers, since sr3 can be changed (e.g. fork) */
  1842. mfsp    %sr3,%r25
  1843. STREG   %r25,TASK_PT_SR3(%r1)
  1844. STREG   %r25,TASK_PT_SR4(%r1)
  1845. STREG   %r25,TASK_PT_SR5(%r1)
  1846. STREG   %r25,TASK_PT_SR6(%r1)
  1847. STREG   %r25,TASK_PT_SR7(%r1)
  1848. STREG   %r25,TASK_PT_IASQ0(%r1)
  1849. STREG   %r25,TASK_PT_IASQ1(%r1)
  1850. /* XXX W bit??? */
  1851. /* Now if old D bit is clear, it means we didn't save all registers
  1852.  * on syscall entry, so do that now.  This only happens on TRACEME
  1853.  * calls, or if someone attached to us while we were on a syscall.
  1854.  * We could make this more efficient by not saving r3-r18, but
  1855.  * then we wouldn't be able to use the common intr_restore path.
  1856.  * It is only for traced processes anyway, so performance is not
  1857.  * an issue.
  1858.  */
  1859. bb,< %r2,30,pt_regs_ok    /* Branch if D set */
  1860. ldo TASK_REGS(%r1),%r25
  1861. reg_save %r25    /* Save r3 to r18 */
  1862. mfsp %sr0,%r2
  1863. STREG %r2,TASK_PT_SR0(%r1)
  1864. mfsp %sr1,%r2
  1865. STREG %r2,TASK_PT_SR1(%r1)
  1866. mfsp %sr2,%r2
  1867. STREG %r2,TASK_PT_SR2(%r1)
  1868. pt_regs_ok:
  1869. LDREG TASK_PT_GR31(%r1),%r2
  1870. depi 3,31,2,%r2    /* ensure return to user mode. */
  1871. STREG %r2,TASK_PT_IAOQ0(%r1)
  1872. ldo 4(%r2),%r2
  1873. STREG %r2,TASK_PT_IAOQ1(%r1)
  1874. copy %r25,%r16
  1875. b intr_restore
  1876. nop
  1877. .import do_softirq,code
  1878. syscall_do_softirq:
  1879. bl      do_softirq,%r2
  1880. nop
  1881. b       syscall_check_resched
  1882. ssm     PSW_SM_I, %r0  /* do_softirq returns with I bit off */
  1883. .import schedule,code
  1884. syscall_do_resched:
  1885. bl schedule,%r2
  1886. #ifdef __LP64__
  1887. ldo -16(%r30),%r29 /* Reference param save area */
  1888. #else
  1889. nop
  1890. #endif
  1891. b       syscall_check_bh  /* if resched, we start over again */
  1892. nop
  1893. .import do_signal,code
  1894. syscall_do_signal:
  1895. /* Save callee-save registers (for sigcontext).
  1896.    FIXME: After this point the process structure should be
  1897.    consistent with all the relevant state of the process
  1898.    before the syscall.  We need to verify this. */
  1899. ldo TASK_REGS(%r1), %r25 /* struct pt_regs *regs */
  1900. reg_save %r25
  1901. ldi 1, %r24 /* unsigned long in_syscall */
  1902. #ifdef __LP64__
  1903. ldo -16(%r30),%r29 /* Reference param save area */
  1904. #endif
  1905. bl do_signal,%r2
  1906. copy %r0, %r26 /* sigset_t *oldset = NULL */
  1907. ldo     -TASK_SZ_ALGN-FRAME_SIZE(%r30), %r1     /* reload task ptr */
  1908. ldo TASK_REGS(%r1), %r20 /* reload pt_regs */
  1909. reg_restore %r20
  1910. b,n     syscall_restore
  1911. /*
  1912.  * get_register is used by the non access tlb miss handlers to
  1913.  * copy the value of the general register specified in r8 into
  1914.  * r1. This routine can't be used for shadowed registers, since
  1915.  * the rfir will restore the original value. So, for the shadowed
  1916.  * registers we put a -1 into r1 to indicate that the register
  1917.  * should not be used (the register being copied could also have
  1918.  * a -1 in it, but that is OK, it just means that we will have
  1919.  * to use the slow path instead).
  1920.  */
  1921. get_register:
  1922. blr     %r8,%r0
  1923. nop
  1924. bv      %r0(%r25)    /* r0 */
  1925. copy    %r0,%r1
  1926. bv      %r0(%r25)    /* r1 - shadowed */
  1927. ldi     -1,%r1
  1928. bv      %r0(%r25)    /* r2 */
  1929. copy    %r2,%r1
  1930. bv      %r0(%r25)    /* r3 */
  1931. copy    %r3,%r1
  1932. bv      %r0(%r25)    /* r4 */
  1933. copy    %r4,%r1
  1934. bv      %r0(%r25)    /* r5 */
  1935. copy    %r5,%r1
  1936. bv      %r0(%r25)    /* r6 */
  1937. copy    %r6,%r1
  1938. bv      %r0(%r25)    /* r7 */
  1939. copy    %r7,%r1
  1940. bv      %r0(%r25)    /* r8 - shadowed */
  1941. ldi     -1,%r1
  1942. bv      %r0(%r25)    /* r9 - shadowed */
  1943. ldi     -1,%r1
  1944. bv      %r0(%r25)    /* r10 */
  1945. copy    %r10,%r1
  1946. bv      %r0(%r25)    /* r11 */
  1947. copy    %r11,%r1
  1948. bv      %r0(%r25)    /* r12 */
  1949. copy    %r12,%r1
  1950. bv      %r0(%r25)    /* r13 */
  1951. copy    %r13,%r1
  1952. bv      %r0(%r25)    /* r14 */
  1953. copy    %r14,%r1
  1954. bv      %r0(%r25)    /* r15 */
  1955. copy    %r15,%r1
  1956. bv      %r0(%r25)    /* r16 - shadowed */
  1957. ldi     -1,%r1
  1958. bv      %r0(%r25)    /* r17 - shadowed */
  1959. ldi     -1,%r1
  1960. bv      %r0(%r25)    /* r18 */
  1961. copy    %r18,%r1
  1962. bv      %r0(%r25)    /* r19 */
  1963. copy    %r19,%r1
  1964. bv      %r0(%r25)    /* r20 */
  1965. copy    %r20,%r1
  1966. bv      %r0(%r25)    /* r21 */
  1967. copy    %r21,%r1
  1968. bv      %r0(%r25)    /* r22 */
  1969. copy    %r22,%r1
  1970. bv      %r0(%r25)    /* r23 */
  1971. copy    %r23,%r1
  1972. bv      %r0(%r25)    /* r24 - shadowed */
  1973. ldi     -1,%r1
  1974. bv      %r0(%r25)    /* r25 - shadowed */
  1975. ldi     -1,%r1
  1976. bv      %r0(%r25)    /* r26 */
  1977. copy    %r26,%r1
  1978. bv      %r0(%r25)    /* r27 */
  1979. copy    %r27,%r1
  1980. bv      %r0(%r25)    /* r28 */
  1981. copy    %r28,%r1
  1982. bv      %r0(%r25)    /* r29 */
  1983. copy    %r29,%r1
  1984. bv      %r0(%r25)    /* r30 */
  1985. copy    %r30,%r1
  1986. bv      %r0(%r25)    /* r31 */
  1987. copy    %r31,%r1
  1988. /*
  1989.  * set_register is used by the non access tlb miss handlers to
  1990.  * copy the value of r1 into the general register specified in
  1991.  * r8.
  1992.  */
  1993. set_register:
  1994. blr     %r8,%r0
  1995. nop
  1996. bv      %r0(%r25)    /* r0 (silly, but it is a place holder) */
  1997. copy    %r1,%r0
  1998. bv      %r0(%r25)    /* r1 */
  1999. copy    %r1,%r1
  2000. bv      %r0(%r25)    /* r2 */
  2001. copy    %r1,%r2
  2002. bv      %r0(%r25)    /* r3 */
  2003. copy    %r1,%r3
  2004. bv      %r0(%r25)    /* r4 */
  2005. copy    %r1,%r4
  2006. bv      %r0(%r25)    /* r5 */
  2007. copy    %r1,%r5
  2008. bv      %r0(%r25)    /* r6 */
  2009. copy    %r1,%r6
  2010. bv      %r0(%r25)    /* r7 */
  2011. copy    %r1,%r7
  2012. bv      %r0(%r25)    /* r8 */
  2013. copy    %r1,%r8
  2014. bv      %r0(%r25)    /* r9 */
  2015. copy    %r1,%r9
  2016. bv      %r0(%r25)    /* r10 */
  2017. copy    %r1,%r10
  2018. bv      %r0(%r25)    /* r11 */
  2019. copy    %r1,%r11
  2020. bv      %r0(%r25)    /* r12 */
  2021. copy    %r1,%r12
  2022. bv      %r0(%r25)    /* r13 */
  2023. copy    %r1,%r13
  2024. bv      %r0(%r25)    /* r14 */
  2025. copy    %r1,%r14
  2026. bv      %r0(%r25)    /* r15 */
  2027. copy    %r1,%r15
  2028. bv      %r0(%r25)    /* r16 */
  2029. copy    %r1,%r16
  2030. bv      %r0(%r25)    /* r17 */
  2031. copy    %r1,%r17
  2032. bv      %r0(%r25)    /* r18 */
  2033. copy    %r1,%r18
  2034. bv      %r0(%r25)    /* r19 */
  2035. copy    %r1,%r19
  2036. bv      %r0(%r25)    /* r20 */
  2037. copy    %r1,%r20
  2038. bv      %r0(%r25)    /* r21 */
  2039. copy    %r1,%r21
  2040. bv      %r0(%r25)    /* r22 */
  2041. copy    %r1,%r22
  2042. bv      %r0(%r25)    /* r23 */
  2043. copy    %r1,%r23
  2044. bv      %r0(%r25)    /* r24 */
  2045. copy    %r1,%r24
  2046. bv      %r0(%r25)    /* r25 */
  2047. copy    %r1,%r25
  2048. bv      %r0(%r25)    /* r26 */
  2049. copy    %r1,%r26
  2050. bv      %r0(%r25)    /* r27 */
  2051. copy    %r1,%r27
  2052. bv      %r0(%r25)    /* r28 */
  2053. copy    %r1,%r28
  2054. bv      %r0(%r25)    /* r29 */
  2055. copy    %r1,%r29
  2056. bv      %r0(%r25)    /* r30 */
  2057. copy    %r1,%r30
  2058. bv      %r0(%r25)    /* r31 */
  2059. copy    %r1,%r31