Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux...
[deliverable/linux.git] / arch / blackfin / include / asm / entry.h
CommitLineData
1394f032
BW
1#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
0893f125
BS
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
1394f032
BW
25/* 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. */
6a01f230
YL
30#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
b9a3899d 38
dedfd5d7
RG
39/*
40 * Workaround for anomalies 05000283 and 05000315
41 */
42#if ANOMALY_05000283 || ANOMALY_05000315
43# define ANOMALY_283_315_WORKAROUND(preg, dreg) \
44 cc = dreg == dreg; \
45 preg.h = HI(CHIPID); \
46 preg.l = LO(CHIPID); \
47 if cc jump 1f; \
48 dreg.l = W[preg]; \
491:
50#else
51# define ANOMALY_283_315_WORKAROUND(preg, dreg)
52#endif /* ANOMALY_05000283 || ANOMALY_05000315 */
53
b9a3899d
RG
54#ifndef CONFIG_EXACT_HWERR
55/* As a debugging aid - we save IPEND when DEBUG_KERNEL is on,
56 * otherwise it is a waste of cycles.
57 */
58# ifndef CONFIG_DEBUG_KERNEL
59#define INTERRUPT_ENTRY(N) \
60 [--sp] = SYSCFG; \
61 [--sp] = P0; /*orig_p0*/ \
62 [--sp] = R0; /*orig_r0*/ \
63 [--sp] = (R7:0,P5:0); \
64 R0 = (N); \
65 LOAD_IPIPE_IPEND \
66 jump __common_int_entry;
67# else /* CONFIG_DEBUG_KERNEL */
1394f032
BW
68#define INTERRUPT_ENTRY(N) \
69 [--sp] = SYSCFG; \
1394f032
BW
70 [--sp] = P0; /*orig_p0*/ \
71 [--sp] = R0; /*orig_r0*/ \
72 [--sp] = (R7:0,P5:0); \
b9a3899d
RG
73 p0.l = lo(IPEND); \
74 p0.h = hi(IPEND); \
75 r1 = [p0]; \
1394f032 76 R0 = (N); \
6a01f230 77 LOAD_IPIPE_IPEND \
1394f032 78 jump __common_int_entry;
b9a3899d 79# endif /* CONFIG_DEBUG_KERNEL */
1394f032
BW
80
81/* For timer interrupts, we need to save IPEND, since the user_mode
b9a3899d
RG
82 *macro accesses it to determine where to account time.
83 */
1394f032
BW
84#define TIMER_INTERRUPT_ENTRY(N) \
85 [--sp] = SYSCFG; \
1394f032
BW
86 [--sp] = P0; /*orig_p0*/ \
87 [--sp] = R0; /*orig_r0*/ \
88 [--sp] = (R7:0,P5:0); \
89 p0.l = lo(IPEND); \
90 p0.h = hi(IPEND); \
91 r1 = [p0]; \
92 R0 = (N); \
93 jump __common_int_entry;
b9a3899d
RG
94#else /* CONFIG_EXACT_HWERR is defined */
95
96/* if we want hardware error to be exact, we need to do a SSYNC (which forces
97 * read/writes to complete to the memory controllers), and check to see that
98 * caused a pending HW error condition. If so, we assume it was caused by user
99 * space, by setting the same interrupt that we are in (so it goes off again)
100 * and context restore, and a RTI (without servicing anything). This should
101 * cause the pending HWERR to fire, and when that is done, this interrupt will
102 * be re-serviced properly.
103 * As you can see by the code - we actually need to do two SSYNCS - one to
104 * make sure the read/writes complete, and another to make sure the hardware
105 * error is recognized by the core.
dedfd5d7
RG
106 *
107 * The extra nop before the SSYNC is to make sure we work around 05000244,
108 * since the 283/315 workaround includes a branch to the end
b9a3899d
RG
109 */
110#define INTERRUPT_ENTRY(N) \
b9a3899d
RG
111 [--sp] = SYSCFG; \
112 [--sp] = P0; /*orig_p0*/ \
113 [--sp] = R0; /*orig_r0*/ \
114 [--sp] = (R7:0,P5:0); \
115 R1 = ASTAT; \
dedfd5d7 116 ANOMALY_283_315_WORKAROUND(p0, r0) \
b9a3899d
RG
117 P0.L = LO(ILAT); \
118 P0.H = HI(ILAT); \
dedfd5d7
RG
119 NOP; \
120 SSYNC; \
121 SSYNC; \
b9a3899d
RG
122 R0 = [P0]; \
123 CC = BITTST(R0, EVT_IVHW_P); \
124 IF CC JUMP 1f; \
125 ASTAT = R1; \
126 p0.l = lo(IPEND); \
127 p0.h = hi(IPEND); \
128 r1 = [p0]; \
129 R0 = (N); \
130 LOAD_IPIPE_IPEND \
131 jump __common_int_entry; \
1321: ASTAT = R1; \
133 RAISE N; \
134 (R7:0, P5:0) = [SP++]; \
135 SP += 0x8; \
136 SYSCFG = [SP++]; \
137 CSYNC; \
138 RTI;
139
140#define TIMER_INTERRUPT_ENTRY(N) \
b9a3899d
RG
141 [--sp] = SYSCFG; \
142 [--sp] = P0; /*orig_p0*/ \
143 [--sp] = R0; /*orig_r0*/ \
144 [--sp] = (R7:0,P5:0); \
145 R1 = ASTAT; \
dedfd5d7 146 ANOMALY_283_315_WORKAROUND(p0, r0) \
b9a3899d
RG
147 P0.L = LO(ILAT); \
148 P0.H = HI(ILAT); \
dedfd5d7
RG
149 NOP; \
150 SSYNC; \
151 SSYNC; \
b9a3899d
RG
152 R0 = [P0]; \
153 CC = BITTST(R0, EVT_IVHW_P); \
154 IF CC JUMP 1f; \
155 ASTAT = R1; \
156 p0.l = lo(IPEND); \
157 p0.h = hi(IPEND); \
158 r1 = [p0]; \
159 R0 = (N); \
160 jump __common_int_entry; \
1611: ASTAT = R1; \
162 RAISE N; \
163 (R7:0, P5:0) = [SP++]; \
164 SP += 0x8; \
165 SYSCFG = [SP++]; \
166 CSYNC; \
167 RTI;
168#endif /* CONFIG_EXACT_HWERR */
1394f032
BW
169
170/* This one pushes RETI without using CLI. Interrupts are enabled. */
171#define SAVE_CONTEXT_SYSCALL save_context_syscall
172#define SAVE_CONTEXT save_context_with_interrupts
dbdf20db 173#define SAVE_CONTEXT_CPLB save_context_cplb
1394f032
BW
174
175#define RESTORE_ALL_SYS restore_context_no_interrupts
176#define RESTORE_CONTEXT restore_context_with_interrupts
dbdf20db 177#define RESTORE_CONTEXT_CPLB restore_context_cplb
1394f032
BW
178
179#endif /* __ASSEMBLY__ */
180#endif /* __BFIN_ENTRY_H */
This page took 0.251611 seconds and 5 git commands to generate.