interrupt.S 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. /*
  2. * interrupt.S - trampoline default exceptions/interrupts to C handlers
  3. *
  4. * Copyright (c) 2005-2009 Analog Devices Inc.
  5. * Licensed under the GPL-2 or later.
  6. */
  7. #include <config.h>
  8. #include <asm/blackfin.h>
  9. #include <asm/entry.h>
  10. #include <asm/ptrace.h>
  11. #include <asm/deferred.h>
  12. #include <asm/mach-common/bits/core.h>
  13. .text
  14. /* default entry point for exceptions */
  15. ENTRY(_trap)
  16. CONFIG_BFIN_SCRATCH_REG = sp;
  17. sp.l = LO(L1_SRAM_SCRATCH_END - 20);
  18. sp.h = HI(L1_SRAM_SCRATCH_END - 20);
  19. SAVE_ALL_SYS
  20. r0 = sp; /* stack frame pt_regs pointer argument ==> r0 */
  21. r1 = 3; /* EVT3 space */
  22. sp += -12;
  23. call _trap_c;
  24. sp += 12;
  25. #ifdef CONFIG_EXCEPTION_DEFER
  26. CC = R0 == 0;
  27. IF CC JUMP .Lexit_trap;
  28. /* To avoid double faults, lower our priority to IRQ5 */
  29. p4.l = lo(COREMMR_BASE);
  30. p4.h = hi(COREMMR_BASE);
  31. r7.h = _exception_to_level5;
  32. r7.l = _exception_to_level5;
  33. [p4 + (EVT5 - COREMMR_BASE)] = r7;
  34. /*
  35. * Save these registers, as they are only valid in exception context
  36. * (where we are now - as soon as we defer to IRQ5, they can change)
  37. */
  38. p5.l = _deferred_regs;
  39. p5.h = _deferred_regs;
  40. r6 = [p4 + (DCPLB_FAULT_ADDR - COREMMR_BASE)];
  41. [p5 + (deferred_regs_DCPLB_FAULT_ADDR * 4)] = r6;
  42. r6 = [p4 + (ICPLB_FAULT_ADDR - COREMMR_BASE)];
  43. [p5 + (deferred_regs_ICPLB_FAULT_ADDR * 4)] = r6;
  44. /* Save the state of single stepping */
  45. r6 = SYSCFG;
  46. [p5 + (deferred_regs_SYSCFG * 4)] = r6;
  47. /* Clear it while we handle the exception in IRQ5 mode
  48. * RESTORE_ALL_SYS will load it, so all we need to do is store it
  49. * in the right place
  50. */
  51. BITCLR(r6, SYSCFG_SSSTEP_P);
  52. [SP + PT_SYSCFG] = r6;
  53. /* Since we are going to clobber RETX, we need to save it */
  54. r6 = retx;
  55. [p5 + (deferred_regs_retx * 4)] = r6;
  56. /* Save the current IMASK, since we change in order to jump to level 5 */
  57. cli r6;
  58. [p5 + (deferred_regs_IMASK * 4)] = r6;
  59. /* Disable all interrupts, but make sure level 5 is enabled so
  60. * we can switch to that level.
  61. */
  62. r6 = 0x3f;
  63. sti r6;
  64. /* Clobber RETX so we don't end up back at a faulting instruction */
  65. [sp + PT_RETX] = r7;
  66. /* In case interrupts are disabled IPEND[4] (global interrupt disable bit)
  67. * clear it (re-enabling interrupts again) by the special sequence of pushing
  68. * RETI onto the stack. This way we can lower ourselves to IVG5 even if the
  69. * exception was taken after the interrupt handler was called but before it
  70. * got a chance to enable global interrupts itself.
  71. */
  72. [--sp] = reti;
  73. sp += 4;
  74. RAISE 5;
  75. .Lexit_trap:
  76. #endif
  77. #if ANOMALY_05000257
  78. R7 = LC0;
  79. LC0 = R7;
  80. R7 = LC1;
  81. LC1 = R7;
  82. #endif
  83. RESTORE_ALL_SYS
  84. sp = CONFIG_BFIN_SCRATCH_REG;
  85. rtx;
  86. ENDPROC(_trap)
  87. #ifdef CONFIG_EXCEPTION_DEFER
  88. /* Deferred (IRQ5) exceptions */
  89. ENTRY(_exception_to_level5)
  90. SAVE_ALL_SYS
  91. /* Now we have to fix things up */
  92. p4.l = lo(EVT5);
  93. p4.h = hi(EVT5);
  94. r0.l = _evt_default;
  95. r0.h = _evt_default;
  96. [p4] = r0;
  97. csync;
  98. p4.l = _deferred_regs;
  99. p4.h = _deferred_regs;
  100. r0 = [p4 + (deferred_regs_retx * 4)];
  101. [sp + PT_PC] = r0;
  102. r0 = [p4 + (deferred_regs_SYSCFG * 4)];
  103. [sp + PT_SYSCFG] = r0;
  104. r0 = sp; /* stack frame pt_regs pointer argument ==> r0 */
  105. r1 = 5; /* EVT5 space */
  106. sp += -12;
  107. call _trap_c;
  108. sp += 12;
  109. /* Restore IMASK */
  110. r0 = [p4 + (deferred_regs_IMASK * 4)];
  111. sti r0;
  112. RESTORE_ALL_SYS
  113. rti;
  114. ENDPROC(_exception_to_level5)
  115. #endif
  116. /* default entry point for interrupts */
  117. ENTRY(_evt_default)
  118. SAVE_ALL_SYS
  119. r0 = sp; /* stack frame pt_regs pointer argument ==> r0 */
  120. sp += -12;
  121. call _bfin_panic;
  122. sp += 12;
  123. RESTORE_ALL_SYS
  124. rti;
  125. ENDPROC(_evt_default)
  126. /* NMI handler */
  127. ENTRY(_evt_nmi)
  128. rtn;
  129. ENDPROC(_evt_nmi)