2 * Copyright 2004-2009 Analog Devices Inc.
4 * Licensed under the GPL-2 or later.
10 #include <asm/setup.h>
15 #define LFLUSH_I_AND_D 0x00000808
19 * NOTE! The single-stepping code assumes that all interrupt handlers
20 * start by saving SYSCFG on the stack with their first instruction.
23 /* This one is used for exceptions, emulation, and NMI. It doesn't push
24 RETI and doesn't do cli. */
25 #define SAVE_ALL_SYS save_context_no_interrupts
26 /* This is used for all normal interrupts. It saves a minimum of registers
27 to the stack, loads the IRQ number, and jumps to common code. */
29 # define LOAD_IPIPE_IPEND \
34 # define LOAD_IPIPE_IPEND
38 * Workaround for anomalies 05000283 and 05000315
40 #if ANOMALY_05000283 || ANOMALY_05000315
41 # define ANOMALY_283_315_WORKAROUND(preg, dreg) \
43 preg.h = HI(CHIPID); \
44 preg.l = LO(CHIPID); \
49 # define ANOMALY_283_315_WORKAROUND(preg, dreg)
50 #endif /* ANOMALY_05000283 || ANOMALY_05000315 */
52 #ifndef CONFIG_EXACT_HWERR
53 /* As a debugging aid - we save IPEND when DEBUG_KERNEL is on,
54 * otherwise it is a waste of cycles.
56 # ifndef CONFIG_DEBUG_KERNEL
57 #define INTERRUPT_ENTRY(N) \
59 [--sp] = P0; /*orig_p0*/ \
60 [--sp] = R0; /*orig_r0*/ \
61 [--sp] = (R7:0,P5:0); \
64 jump __common_int_entry;
65 # else /* CONFIG_DEBUG_KERNEL */
66 #define INTERRUPT_ENTRY(N) \
68 [--sp] = P0; /*orig_p0*/ \
69 [--sp] = R0; /*orig_r0*/ \
70 [--sp] = (R7:0,P5:0); \
76 jump __common_int_entry;
77 # endif /* CONFIG_DEBUG_KERNEL */
79 /* For timer interrupts, we need to save IPEND, since the user_mode
80 *macro accesses it to determine where to account time.
82 #define TIMER_INTERRUPT_ENTRY(N) \
84 [--sp] = P0; /*orig_p0*/ \
85 [--sp] = R0; /*orig_r0*/ \
86 [--sp] = (R7:0,P5:0); \
91 jump __common_int_entry;
92 #else /* CONFIG_EXACT_HWERR is defined */
94 /* if we want hardware error to be exact, we need to do a SSYNC (which forces
95 * read/writes to complete to the memory controllers), and check to see that
96 * caused a pending HW error condition. If so, we assume it was caused by user
97 * space, by setting the same interrupt that we are in (so it goes off again)
98 * and context restore, and a RTI (without servicing anything). This should
99 * cause the pending HWERR to fire, and when that is done, this interrupt will
100 * be re-serviced properly.
101 * As you can see by the code - we actually need to do two SSYNCS - one to
102 * make sure the read/writes complete, and another to make sure the hardware
103 * error is recognized by the core.
105 * The extra nop before the SSYNC is to make sure we work around 05000244,
106 * since the 283/315 workaround includes a branch to the end
108 #define INTERRUPT_ENTRY(N) \
110 [--sp] = P0; /*orig_p0*/ \
111 [--sp] = R0; /*orig_r0*/ \
112 [--sp] = (R7:0,P5:0); \
114 ANOMALY_283_315_WORKAROUND(p0, r0) \
121 CC = BITTST(R0, EVT_IVHW_P); \
129 jump __common_int_entry; \
132 (R7:0, P5:0) = [SP++]; \
138 #define TIMER_INTERRUPT_ENTRY(N) \
140 [--sp] = P0; /*orig_p0*/ \
141 [--sp] = R0; /*orig_r0*/ \
142 [--sp] = (R7:0,P5:0); \
144 ANOMALY_283_315_WORKAROUND(p0, r0) \
151 CC = BITTST(R0, EVT_IVHW_P); \
158 jump __common_int_entry; \
161 (R7:0, P5:0) = [SP++]; \
166 #endif /* CONFIG_EXACT_HWERR */
168 /* This one pushes RETI without using CLI. Interrupts are enabled. */
169 #define SAVE_CONTEXT_SYSCALL save_context_syscall
170 #define SAVE_CONTEXT save_context_with_interrupts
171 #define SAVE_CONTEXT_CPLB save_context_cplb
173 #define RESTORE_ALL_SYS restore_context_no_interrupts
174 #define RESTORE_CONTEXT restore_context_with_interrupts
175 #define RESTORE_CONTEXT_CPLB restore_context_cplb
177 #endif /* __ASSEMBLY__ */
178 #endif /* __BFIN_ENTRY_H */