entry-header.S 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. #include <linux/config.h> /* for CONFIG_ARCH_xxxx */
  2. #include <linux/linkage.h>
  3. #include <asm/assembler.h>
  4. #include <asm/constants.h>
  5. #include <asm/errno.h>
  6. #include <asm/hardware.h>
  7. #include <asm/arch/irqs.h>
  8. #include <asm/arch/entry-macro.S>
  9. #ifndef MODE_SVC
  10. #define MODE_SVC 0x13
  11. #endif
  12. .macro zero_fp
  13. #ifdef CONFIG_FRAME_POINTER
  14. mov fp, #0
  15. #endif
  16. .endm
  17. .text
  18. @ Bad Abort numbers
  19. @ -----------------
  20. @
  21. #define BAD_PREFETCH 0
  22. #define BAD_DATA 1
  23. #define BAD_ADDREXCPTN 2
  24. #define BAD_IRQ 3
  25. #define BAD_UNDEFINSTR 4
  26. #define PT_TRACESYS 0x00000002
  27. @ OS version number used in SWIs
  28. @ RISC OS is 0
  29. @ RISC iX is 8
  30. @
  31. #define OS_NUMBER 9
  32. #define ARMSWI_OFFSET 0x000f0000
  33. @
  34. @ Stack format (ensured by USER_* and SVC_*)
  35. @
  36. #define S_FRAME_SIZE 72
  37. #define S_OLD_R0 68
  38. #define S_PSR 64
  39. #define S_PC 60
  40. #define S_LR 56
  41. #define S_SP 52
  42. #define S_IP 48
  43. #define S_FP 44
  44. #define S_R10 40
  45. #define S_R9 36
  46. #define S_R8 32
  47. #define S_R7 28
  48. #define S_R6 24
  49. #define S_R5 20
  50. #define S_R4 16
  51. #define S_R3 12
  52. #define S_R2 8
  53. #define S_R1 4
  54. #define S_R0 0
  55. #define S_OFF 8
  56. .macro set_cpsr_c, reg, mode
  57. msr cpsr_c, \mode
  58. .endm
  59. #if __LINUX_ARM_ARCH__ >= 6
  60. .macro disable_irq, temp
  61. cpsid i
  62. .endm
  63. .macro enable_irq, temp
  64. cpsie i
  65. .endm
  66. #else
  67. .macro disable_irq, temp
  68. set_cpsr_c \temp, #PSR_I_BIT | MODE_SVC
  69. .endm
  70. .macro enable_irq, temp
  71. set_cpsr_c \temp, #MODE_SVC
  72. .endm
  73. #endif
  74. .macro save_user_regs
  75. sub sp, sp, #S_FRAME_SIZE
  76. stmia sp, {r0 - r12} @ Calling r0 - r12
  77. add r8, sp, #S_PC
  78. stmdb r8, {sp, lr}^ @ Calling sp, lr
  79. mrs r8, spsr @ called from non-FIQ mode, so ok.
  80. str lr, [sp, #S_PC] @ Save calling PC
  81. str r8, [sp, #S_PSR] @ Save CPSR
  82. str r0, [sp, #S_OLD_R0] @ Save OLD_R0
  83. .endm
  84. .macro restore_user_regs
  85. ldr r1, [sp, #S_PSR] @ Get calling cpsr
  86. disable_irq ip @ disable IRQs
  87. ldr lr, [sp, #S_PC]! @ Get PC
  88. msr spsr_cxsf, r1 @ save in spsr_svc
  89. ldmdb sp, {r0 - lr}^ @ Get calling r0 - lr
  90. mov r0, r0
  91. add sp, sp, #S_FRAME_SIZE - S_PC
  92. movs pc, lr @ return & move spsr_svc into cpsr
  93. .endm
  94. /*
  95. * Must be called with IRQs already disabled.
  96. */
  97. .macro fast_restore_user_regs
  98. ldr r1, [sp, #S_OFF + S_PSR] @ get calling cpsr
  99. ldr lr, [sp, #S_OFF + S_PC]! @ get pc
  100. msr spsr_cxsf, r1 @ save in spsr_svc
  101. ldmdb sp, {r1 - lr}^ @ get calling r1 - lr
  102. mov r0, r0
  103. add sp, sp, #S_FRAME_SIZE - S_PC
  104. movs pc, lr @ return & move spsr_svc into cpsr
  105. .endm
  106. /*
  107. * Must be called with IRQs already disabled.
  108. */
  109. .macro slow_restore_user_regs
  110. ldr r1, [sp, #S_PSR] @ get calling cpsr
  111. ldr lr, [sp, #S_PC]! @ get pc
  112. msr spsr_cxsf, r1 @ save in spsr_svc
  113. ldmdb sp, {r0 - lr}^ @ get calling r1 - lr
  114. mov r0, r0
  115. add sp, sp, #S_FRAME_SIZE - S_PC
  116. movs pc, lr @ return & move spsr_svc into cpsr
  117. .endm
  118. .macro mask_pc, rd, rm
  119. .endm
  120. .macro get_thread_info, rd
  121. mov \rd, sp, lsr #13
  122. mov \rd, \rd, lsl #13
  123. .endm
  124. .macro alignment_trap, rbase, rtemp, sym
  125. #ifdef CONFIG_ALIGNMENT_TRAP
  126. #define OFF_CR_ALIGNMENT(x) cr_alignment - x
  127. ldr \rtemp, [\rbase, #OFF_CR_ALIGNMENT(\sym)]
  128. mcr p15, 0, \rtemp, c1, c0
  129. #endif
  130. .endm
  131. /*
  132. * These are the registers used in the syscall handler, and allow us to
  133. * have in theory up to 7 arguments to a function - r0 to r6.
  134. *
  135. * r7 is reserved for the system call number for thumb mode.
  136. *
  137. * Note that tbl == why is intentional.
  138. *
  139. * We must set at least "tsk" and "why" when calling ret_with_reschedule.
  140. */
  141. scno .req r7 @ syscall number
  142. tbl .req r8 @ syscall table pointer
  143. why .req r8 @ Linux syscall (!= 0)
  144. tsk .req r9 @ current thread_info
  145. /*
  146. * Get the system call number.
  147. */
  148. .macro get_scno
  149. #ifdef CONFIG_ARM_THUMB
  150. tst r8, #PSR_T_BIT @ this is SPSR from save_user_regs
  151. addne scno, r7, #OS_NUMBER << 20 @ put OS number in
  152. ldreq scno, [lr, #-4]
  153. #else
  154. mask_pc lr, lr
  155. ldr scno, [lr, #-4] @ get SWI instruction
  156. #endif
  157. .endm