entry.h 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. /*
  2. * Copyright 2004-2009 Analog Devices Inc.
  3. *
  4. * Licensed under the GPL-2 or later.
  5. */
  6. #ifndef __BFIN_ENTRY_H
  7. #define __BFIN_ENTRY_H
  8. #include <asm/setup.h>
  9. #include <asm/page.h>
  10. #ifdef __ASSEMBLY__
  11. #define LFLUSH_I_AND_D 0x00000808
  12. #define LSIGTRAP 5
  13. /* process bits for task_struct.flags */
  14. #define PF_TRACESYS_OFF 3
  15. #define PF_TRACESYS_BIT 5
  16. #define PF_PTRACED_OFF 3
  17. #define PF_PTRACED_BIT 4
  18. #define PF_DTRACE_OFF 1
  19. #define PF_DTRACE_BIT 5
  20. /*
  21. * NOTE! The single-stepping code assumes that all interrupt handlers
  22. * start by saving SYSCFG on the stack with their first instruction.
  23. */
  24. /* This one is used for exceptions, emulation, and NMI. It doesn't push
  25. RETI and doesn't do cli. */
  26. #define SAVE_ALL_SYS save_context_no_interrupts
  27. /* This is used for all normal interrupts. It saves a minimum of registers
  28. to the stack, loads the IRQ number, and jumps to common code. */
  29. #ifdef CONFIG_IPIPE
  30. # define LOAD_IPIPE_IPEND \
  31. P0.l = lo(IPEND); \
  32. P0.h = hi(IPEND); \
  33. R1 = [P0];
  34. #else
  35. # define LOAD_IPIPE_IPEND
  36. #endif
  37. /*
  38. * Workaround for anomalies 05000283 and 05000315
  39. */
  40. #if ANOMALY_05000283 || ANOMALY_05000315
  41. # define ANOMALY_283_315_WORKAROUND(preg, dreg) \
  42. cc = dreg == dreg; \
  43. preg.h = HI(CHIPID); \
  44. preg.l = LO(CHIPID); \
  45. if cc jump 1f; \
  46. dreg.l = W[preg]; \
  47. 1:
  48. #else
  49. # define ANOMALY_283_315_WORKAROUND(preg, dreg)
  50. #endif /* ANOMALY_05000283 || ANOMALY_05000315 */
  51. #ifndef CONFIG_EXACT_HWERR
  52. /* As a debugging aid - we save IPEND when DEBUG_KERNEL is on,
  53. * otherwise it is a waste of cycles.
  54. */
  55. # ifndef CONFIG_DEBUG_KERNEL
  56. #define INTERRUPT_ENTRY(N) \
  57. [--sp] = SYSCFG; \
  58. [--sp] = P0; /*orig_p0*/ \
  59. [--sp] = R0; /*orig_r0*/ \
  60. [--sp] = (R7:0,P5:0); \
  61. R0 = (N); \
  62. LOAD_IPIPE_IPEND \
  63. jump __common_int_entry;
  64. # else /* CONFIG_DEBUG_KERNEL */
  65. #define INTERRUPT_ENTRY(N) \
  66. [--sp] = SYSCFG; \
  67. [--sp] = P0; /*orig_p0*/ \
  68. [--sp] = R0; /*orig_r0*/ \
  69. [--sp] = (R7:0,P5:0); \
  70. p0.l = lo(IPEND); \
  71. p0.h = hi(IPEND); \
  72. r1 = [p0]; \
  73. R0 = (N); \
  74. LOAD_IPIPE_IPEND \
  75. jump __common_int_entry;
  76. # endif /* CONFIG_DEBUG_KERNEL */
  77. /* For timer interrupts, we need to save IPEND, since the user_mode
  78. *macro accesses it to determine where to account time.
  79. */
  80. #define TIMER_INTERRUPT_ENTRY(N) \
  81. [--sp] = SYSCFG; \
  82. [--sp] = P0; /*orig_p0*/ \
  83. [--sp] = R0; /*orig_r0*/ \
  84. [--sp] = (R7:0,P5:0); \
  85. p0.l = lo(IPEND); \
  86. p0.h = hi(IPEND); \
  87. r1 = [p0]; \
  88. R0 = (N); \
  89. jump __common_int_entry;
  90. #else /* CONFIG_EXACT_HWERR is defined */
  91. /* if we want hardware error to be exact, we need to do a SSYNC (which forces
  92. * read/writes to complete to the memory controllers), and check to see that
  93. * caused a pending HW error condition. If so, we assume it was caused by user
  94. * space, by setting the same interrupt that we are in (so it goes off again)
  95. * and context restore, and a RTI (without servicing anything). This should
  96. * cause the pending HWERR to fire, and when that is done, this interrupt will
  97. * be re-serviced properly.
  98. * As you can see by the code - we actually need to do two SSYNCS - one to
  99. * make sure the read/writes complete, and another to make sure the hardware
  100. * error is recognized by the core.
  101. *
  102. * The extra nop before the SSYNC is to make sure we work around 05000244,
  103. * since the 283/315 workaround includes a branch to the end
  104. */
  105. #define INTERRUPT_ENTRY(N) \
  106. [--sp] = SYSCFG; \
  107. [--sp] = P0; /*orig_p0*/ \
  108. [--sp] = R0; /*orig_r0*/ \
  109. [--sp] = (R7:0,P5:0); \
  110. R1 = ASTAT; \
  111. ANOMALY_283_315_WORKAROUND(p0, r0) \
  112. P0.L = LO(ILAT); \
  113. P0.H = HI(ILAT); \
  114. NOP; \
  115. SSYNC; \
  116. SSYNC; \
  117. R0 = [P0]; \
  118. CC = BITTST(R0, EVT_IVHW_P); \
  119. IF CC JUMP 1f; \
  120. ASTAT = R1; \
  121. p0.l = lo(IPEND); \
  122. p0.h = hi(IPEND); \
  123. r1 = [p0]; \
  124. R0 = (N); \
  125. LOAD_IPIPE_IPEND \
  126. jump __common_int_entry; \
  127. 1: ASTAT = R1; \
  128. RAISE N; \
  129. (R7:0, P5:0) = [SP++]; \
  130. SP += 0x8; \
  131. SYSCFG = [SP++]; \
  132. CSYNC; \
  133. RTI;
  134. #define TIMER_INTERRUPT_ENTRY(N) \
  135. [--sp] = SYSCFG; \
  136. [--sp] = P0; /*orig_p0*/ \
  137. [--sp] = R0; /*orig_r0*/ \
  138. [--sp] = (R7:0,P5:0); \
  139. R1 = ASTAT; \
  140. ANOMALY_283_315_WORKAROUND(p0, r0) \
  141. P0.L = LO(ILAT); \
  142. P0.H = HI(ILAT); \
  143. NOP; \
  144. SSYNC; \
  145. SSYNC; \
  146. R0 = [P0]; \
  147. CC = BITTST(R0, EVT_IVHW_P); \
  148. IF CC JUMP 1f; \
  149. ASTAT = R1; \
  150. p0.l = lo(IPEND); \
  151. p0.h = hi(IPEND); \
  152. r1 = [p0]; \
  153. R0 = (N); \
  154. jump __common_int_entry; \
  155. 1: ASTAT = R1; \
  156. RAISE N; \
  157. (R7:0, P5:0) = [SP++]; \
  158. SP += 0x8; \
  159. SYSCFG = [SP++]; \
  160. CSYNC; \
  161. RTI;
  162. #endif /* CONFIG_EXACT_HWERR */
  163. /* This one pushes RETI without using CLI. Interrupts are enabled. */
  164. #define SAVE_CONTEXT_SYSCALL save_context_syscall
  165. #define SAVE_CONTEXT save_context_with_interrupts
  166. #define SAVE_CONTEXT_CPLB save_context_cplb
  167. #define RESTORE_ALL_SYS restore_context_no_interrupts
  168. #define RESTORE_CONTEXT restore_context_with_interrupts
  169. #define RESTORE_CONTEXT_CPLB restore_context_cplb
  170. #endif /* __ASSEMBLY__ */
  171. #endif /* __BFIN_ENTRY_H */