entry.h 4.7 KB

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