entry-header.S 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  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. .macro zero_fp
  10. #ifdef CONFIG_FRAME_POINTER
  11. mov fp, #0
  12. #endif
  13. .endm
  14. .text
  15. @ Bad Abort numbers
  16. @ -----------------
  17. @
  18. #define BAD_PREFETCH 0
  19. #define BAD_DATA 1
  20. #define BAD_ADDREXCPTN 2
  21. #define BAD_IRQ 3
  22. #define BAD_UNDEFINSTR 4
  23. #define PT_TRACESYS 0x00000002
  24. @
  25. @ Most of the stack format comes from struct pt_regs, but with
  26. @ the addition of 8 bytes for storing syscall args 5 and 6.
  27. @
  28. #define S_OFF 8
  29. /*
  30. * The SWI code relies on the fact that R0 is at the bottom of the stack
  31. * (due to slow/fast restore user regs).
  32. */
  33. #if S_R0 != 0
  34. #error "Please fix"
  35. #endif
  36. #if __LINUX_ARM_ARCH__ >= 6
  37. .macro disable_irq
  38. cpsid i
  39. .endm
  40. .macro enable_irq
  41. cpsie i
  42. .endm
  43. #else
  44. .macro disable_irq
  45. msr cpsr_c, #PSR_I_BIT | SVC_MODE
  46. .endm
  47. .macro enable_irq
  48. msr cpsr_c, #SVC_MODE
  49. .endm
  50. #endif
  51. .macro save_user_regs
  52. sub sp, sp, #S_FRAME_SIZE
  53. stmia sp, {r0 - r12} @ Calling r0 - r12
  54. add r8, sp, #S_PC
  55. stmdb r8, {sp, lr}^ @ Calling sp, lr
  56. mrs r8, spsr @ called from non-FIQ mode, so ok.
  57. str lr, [sp, #S_PC] @ Save calling PC
  58. str r8, [sp, #S_PSR] @ Save CPSR
  59. str r0, [sp, #S_OLD_R0] @ Save OLD_R0
  60. .endm
  61. .macro restore_user_regs
  62. ldr r1, [sp, #S_PSR] @ Get calling cpsr
  63. disable_irq ip @ disable IRQs
  64. ldr lr, [sp, #S_PC]! @ Get PC
  65. msr spsr_cxsf, r1 @ save in spsr_svc
  66. ldmdb sp, {r0 - lr}^ @ Get calling r0 - lr
  67. mov r0, r0
  68. add sp, sp, #S_FRAME_SIZE - S_PC
  69. movs pc, lr @ return & move spsr_svc into cpsr
  70. .endm
  71. /*
  72. * Must be called with IRQs already disabled.
  73. */
  74. .macro fast_restore_user_regs
  75. ldr r1, [sp, #S_OFF + S_PSR] @ get calling cpsr
  76. ldr lr, [sp, #S_OFF + S_PC]! @ get pc
  77. msr spsr_cxsf, r1 @ save in spsr_svc
  78. ldmdb sp, {r1 - lr}^ @ get calling r1 - lr
  79. mov r0, r0
  80. add sp, sp, #S_FRAME_SIZE - S_PC
  81. movs pc, lr @ return & move spsr_svc into cpsr
  82. .endm
  83. /*
  84. * Must be called with IRQs already disabled.
  85. */
  86. .macro slow_restore_user_regs
  87. ldr r1, [sp, #S_PSR] @ get calling cpsr
  88. ldr lr, [sp, #S_PC]! @ get pc
  89. msr spsr_cxsf, r1 @ save in spsr_svc
  90. ldmdb sp, {r0 - lr}^ @ get calling r1 - lr
  91. mov r0, r0
  92. add sp, sp, #S_FRAME_SIZE - S_PC
  93. movs pc, lr @ return & move spsr_svc into cpsr
  94. .endm
  95. .macro mask_pc, rd, rm
  96. .endm
  97. .macro get_thread_info, rd
  98. mov \rd, sp, lsr #13
  99. mov \rd, \rd, lsl #13
  100. .endm
  101. .macro alignment_trap, rbase, rtemp, sym
  102. #ifdef CONFIG_ALIGNMENT_TRAP
  103. #define OFF_CR_ALIGNMENT(x) cr_alignment - x
  104. ldr \rtemp, [\rbase, #OFF_CR_ALIGNMENT(\sym)]
  105. mcr p15, 0, \rtemp, c1, c0
  106. #endif
  107. .endm
  108. /*
  109. * These are the registers used in the syscall handler, and allow us to
  110. * have in theory up to 7 arguments to a function - r0 to r6.
  111. *
  112. * r7 is reserved for the system call number for thumb mode.
  113. *
  114. * Note that tbl == why is intentional.
  115. *
  116. * We must set at least "tsk" and "why" when calling ret_with_reschedule.
  117. */
  118. scno .req r7 @ syscall number
  119. tbl .req r8 @ syscall table pointer
  120. why .req r8 @ Linux syscall (!= 0)
  121. tsk .req r9 @ current thread_info