gate.S 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. /*
  2. *
  3. * Linux/PARISC Project (http://www.parisc-linux.org/)
  4. *
  5. * System call entry code Copyright (c) Matthew Wilcox 1999 <willy@bofh.ai>
  6. * Licensed under the GNU GPL.
  7. * thanks to Philipp Rumpf, Mike Shaver and various others
  8. * sorry about the wall, puffin..
  9. */
  10. #include <asm/assembly.h>
  11. #include <asm/asm-offsets.h>
  12. #include <asm/unistd.h>
  13. #include <asm/errno.h>
  14. #include <linux/linkage.h>
  15. .level LEVEL
  16. .text
  17. .import hpux_call_table
  18. .import hpux_syscall_exit,code
  19. .align PAGE_SIZE
  20. ENTRY(hpux_gateway_page)
  21. nop
  22. #ifdef CONFIG_64BIT
  23. #warning NEEDS WORK for 64-bit
  24. #endif
  25. ldw -64(%r30), %r29 ;! 8th argument
  26. ldw -60(%r30), %r19 ;! 7th argument
  27. ldw -56(%r30), %r20 ;! 6th argument
  28. ldw -52(%r30), %r21 ;! 5th argument
  29. gate .+8, %r0 /* become privileged */
  30. mtsp %r0,%sr4 /* get kernel space into sr4 */
  31. mtsp %r0,%sr5 /* get kernel space into sr5 */
  32. mtsp %r0,%sr6 /* get kernel space into sr6 */
  33. mfsp %sr7,%r1 /* save user sr7 */
  34. mtsp %r1,%sr3 /* and store it in sr3 */
  35. mtctl %r30,%cr28
  36. mfctl %cr30,%r1
  37. xor %r1,%r30,%r30 /* ye olde xor trick */
  38. xor %r1,%r30,%r1
  39. xor %r1,%r30,%r30
  40. ldo TASK_SZ_ALGN+FRAME_SIZE(%r30),%r30 /* set up kernel stack */
  41. /* N.B.: It is critical that we don't set sr7 to 0 until r30
  42. * contains a valid kernel stack pointer. It is also
  43. * critical that we don't start using the kernel stack
  44. * until after sr7 has been set to 0.
  45. */
  46. mtsp %r0,%sr7 /* get kernel space into sr7 */
  47. STREG %r1,TASK_PT_GR30-TASK_SZ_ALGN-FRAME_SIZE(%r30) /* save usp */
  48. ldo -TASK_SZ_ALGN-FRAME_SIZE(%r30),%r1 /* get task ptr in %r1 */
  49. /* Save some registers for sigcontext and potential task
  50. switch (see entry.S for the details of which ones are
  51. saved/restored). TASK_PT_PSW is zeroed so we can see whether
  52. a process is on a syscall or not. For an interrupt the real
  53. PSW value is stored. This is needed for gdb and sys_ptrace. */
  54. STREG %r0, TASK_PT_PSW(%r1)
  55. STREG %r2, TASK_PT_GR2(%r1) /* preserve rp */
  56. STREG %r19, TASK_PT_GR19(%r1) /* 7th argument */
  57. STREG %r20, TASK_PT_GR20(%r1) /* 6th argument */
  58. STREG %r21, TASK_PT_GR21(%r1) /* 5th argument */
  59. STREG %r22, TASK_PT_GR22(%r1) /* syscall # */
  60. STREG %r23, TASK_PT_GR23(%r1) /* 4th argument */
  61. STREG %r24, TASK_PT_GR24(%r1) /* 3rd argument */
  62. STREG %r25, TASK_PT_GR25(%r1) /* 2nd argument */
  63. STREG %r26, TASK_PT_GR26(%r1) /* 1st argument */
  64. STREG %r27, TASK_PT_GR27(%r1) /* user dp */
  65. STREG %r28, TASK_PT_GR28(%r1) /* return value 0 */
  66. STREG %r28, TASK_PT_ORIG_R28(%r1) /* return value 0 (saved for signals) */
  67. STREG %r29, TASK_PT_GR29(%r1) /* 8th argument */
  68. STREG %r31, TASK_PT_GR31(%r1) /* preserve syscall return ptr */
  69. ldo TASK_PT_FR0(%r1), %r27 /* save fpregs from the kernel */
  70. save_fp %r27 /* or potential task switch */
  71. mfctl %cr11, %r27 /* i.e. SAR */
  72. STREG %r27, TASK_PT_SAR(%r1)
  73. loadgp
  74. stw %r21, -52(%r30) ;! 5th argument
  75. stw %r20, -56(%r30) ;! 6th argument
  76. stw %r19, -60(%r30) ;! 7th argument
  77. stw %r29, -64(%r30) ;! 8th argument
  78. ldil L%hpux_call_table, %r21
  79. ldo R%hpux_call_table(%r21), %r21
  80. comiclr,>>= __NR_HPUX_syscalls, %r22, %r0
  81. b,n syscall_nosys
  82. LDREGX %r22(%r21), %r21
  83. ldil L%hpux_syscall_exit,%r2
  84. be 0(%sr7,%r21)
  85. ldo R%hpux_syscall_exit(%r2),%r2
  86. syscall_nosys:
  87. ldil L%hpux_syscall_exit,%r1
  88. be R%hpux_syscall_exit(%sr7,%r1)
  89. ldo -ENOSYS(%r0),%r28
  90. ENDPROC(hpux_gateway_page)
  91. .align PAGE_SIZE
  92. ENTRY(end_hpux_gateway_page)