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