entry-header.S 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  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. @ Most of the stack format comes from struct pt_regs, but with
  35. @ the addition of 8 bytes for storing syscall args 5 and 6.
  36. @
  37. #define S_OFF 8
  38. /*
  39. * The SWI code relies on the fact that R0 is at the bottom of the stack
  40. * (due to slow/fast restore user regs).
  41. */
  42. #if S_R0 != 0
  43. #error "Please fix"
  44. #endif
  45. #if __LINUX_ARM_ARCH__ >= 6
  46. .macro disable_irq
  47. cpsid i
  48. .endm
  49. .macro enable_irq
  50. cpsie i
  51. .endm
  52. #else
  53. .macro disable_irq
  54. msr cpsr_c, #PSR_I_BIT | SVC_MODE
  55. .endm
  56. .macro enable_irq
  57. msr cpsr_c, #SVC_MODE
  58. .endm
  59. #endif
  60. .macro save_user_regs
  61. sub sp, sp, #S_FRAME_SIZE
  62. stmia sp, {r0 - r12} @ Calling r0 - r12
  63. add r8, sp, #S_PC
  64. stmdb r8, {sp, lr}^ @ Calling sp, lr
  65. mrs r8, spsr @ called from non-FIQ mode, so ok.
  66. str lr, [sp, #S_PC] @ Save calling PC
  67. str r8, [sp, #S_PSR] @ Save CPSR
  68. str r0, [sp, #S_OLD_R0] @ Save OLD_R0
  69. .endm
  70. .macro restore_user_regs
  71. ldr r1, [sp, #S_PSR] @ Get calling cpsr
  72. disable_irq ip @ disable IRQs
  73. ldr lr, [sp, #S_PC]! @ Get PC
  74. msr spsr_cxsf, r1 @ save in spsr_svc
  75. ldmdb sp, {r0 - lr}^ @ Get calling r0 - lr
  76. mov r0, r0
  77. add sp, sp, #S_FRAME_SIZE - S_PC
  78. movs pc, lr @ return & move spsr_svc into cpsr
  79. .endm
  80. /*
  81. * Must be called with IRQs already disabled.
  82. */
  83. .macro fast_restore_user_regs
  84. ldr r1, [sp, #S_OFF + S_PSR] @ get calling cpsr
  85. ldr lr, [sp, #S_OFF + S_PC]! @ get pc
  86. msr spsr_cxsf, r1 @ save in spsr_svc
  87. ldmdb sp, {r1 - lr}^ @ get calling r1 - lr
  88. mov r0, r0
  89. add sp, sp, #S_FRAME_SIZE - S_PC
  90. movs pc, lr @ return & move spsr_svc into cpsr
  91. .endm
  92. /*
  93. * Must be called with IRQs already disabled.
  94. */
  95. .macro slow_restore_user_regs
  96. ldr r1, [sp, #S_PSR] @ get calling cpsr
  97. ldr lr, [sp, #S_PC]! @ get pc
  98. msr spsr_cxsf, r1 @ save in spsr_svc
  99. ldmdb sp, {r0 - lr}^ @ get calling r1 - lr
  100. mov r0, r0
  101. add sp, sp, #S_FRAME_SIZE - S_PC
  102. movs pc, lr @ return & move spsr_svc into cpsr
  103. .endm
  104. .macro mask_pc, rd, rm
  105. .endm
  106. .macro get_thread_info, rd
  107. mov \rd, sp, lsr #13
  108. mov \rd, \rd, lsl #13
  109. .endm
  110. .macro alignment_trap, rbase, rtemp, sym
  111. #ifdef CONFIG_ALIGNMENT_TRAP
  112. #define OFF_CR_ALIGNMENT(x) cr_alignment - x
  113. ldr \rtemp, [\rbase, #OFF_CR_ALIGNMENT(\sym)]
  114. mcr p15, 0, \rtemp, c1, c0
  115. #endif
  116. .endm
  117. /*
  118. * These are the registers used in the syscall handler, and allow us to
  119. * have in theory up to 7 arguments to a function - r0 to r6.
  120. *
  121. * r7 is reserved for the system call number for thumb mode.
  122. *
  123. * Note that tbl == why is intentional.
  124. *
  125. * We must set at least "tsk" and "why" when calling ret_with_reschedule.
  126. */
  127. scno .req r7 @ syscall number
  128. tbl .req r8 @ syscall table pointer
  129. why .req r8 @ Linux syscall (!= 0)
  130. tsk .req r9 @ current thread_info
  131. /*
  132. * Get the system call number.
  133. */
  134. .macro get_scno
  135. #ifdef CONFIG_ARM_THUMB
  136. tst r8, #PSR_T_BIT @ this is SPSR from save_user_regs
  137. addne scno, r7, #OS_NUMBER << 20 @ put OS number in
  138. ldreq scno, [lr, #-4]
  139. #else
  140. mask_pc lr, lr
  141. ldr scno, [lr, #-4] @ get SWI instruction
  142. #endif
  143. .endm