]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blame - arch/blackfin/include/asm/entry.h
Merge remote branch 'nouveau/for-airlied' into drm-linus
[mirror_ubuntu-zesty-kernel.git] / arch / blackfin / include / asm / entry.h
CommitLineData
96f1050d
RG
1/*
2 * Copyright 2004-2009 Analog Devices Inc.
3 *
4 * Licensed under the GPL-2 or later.
5 */
6
1394f032
BW
7#ifndef __BFIN_ENTRY_H
8#define __BFIN_ENTRY_H
9
10#include <asm/setup.h>
11#include <asm/page.h>
12
13#ifdef __ASSEMBLY__
14
15#define LFLUSH_I_AND_D 0x00000808
16#define LSIGTRAP 5
17
18/* process bits for task_struct.flags */
19#define PF_TRACESYS_OFF 3
20#define PF_TRACESYS_BIT 5
21#define PF_PTRACED_OFF 3
22#define PF_PTRACED_BIT 4
23#define PF_DTRACE_OFF 1
24#define PF_DTRACE_BIT 5
25
0893f125
BS
26/*
27 * NOTE! The single-stepping code assumes that all interrupt handlers
28 * start by saving SYSCFG on the stack with their first instruction.
29 */
30
1394f032
BW
31/* This one is used for exceptions, emulation, and NMI. It doesn't push
32 RETI and doesn't do cli. */
33#define SAVE_ALL_SYS save_context_no_interrupts
34/* This is used for all normal interrupts. It saves a minimum of registers
35 to the stack, loads the IRQ number, and jumps to common code. */
6a01f230
YL
36#ifdef CONFIG_IPIPE
37# define LOAD_IPIPE_IPEND \
38 P0.l = lo(IPEND); \
39 P0.h = hi(IPEND); \
40 R1 = [P0];
41#else
42# define LOAD_IPIPE_IPEND
43#endif
b9a3899d 44
dedfd5d7
RG
45/*
46 * Workaround for anomalies 05000283 and 05000315
47 */
48#if ANOMALY_05000283 || ANOMALY_05000315
49# define ANOMALY_283_315_WORKAROUND(preg, dreg) \
50 cc = dreg == dreg; \
51 preg.h = HI(CHIPID); \
52 preg.l = LO(CHIPID); \
53 if cc jump 1f; \
54 dreg.l = W[preg]; \
551:
56#else
57# define ANOMALY_283_315_WORKAROUND(preg, dreg)
58#endif /* ANOMALY_05000283 || ANOMALY_05000315 */
59
b9a3899d
RG
60#ifndef CONFIG_EXACT_HWERR
61/* As a debugging aid - we save IPEND when DEBUG_KERNEL is on,
62 * otherwise it is a waste of cycles.
63 */
64# ifndef CONFIG_DEBUG_KERNEL
65#define INTERRUPT_ENTRY(N) \
66 [--sp] = SYSCFG; \
67 [--sp] = P0; /*orig_p0*/ \
68 [--sp] = R0; /*orig_r0*/ \
69 [--sp] = (R7:0,P5:0); \
70 R0 = (N); \
71 LOAD_IPIPE_IPEND \
72 jump __common_int_entry;
73# else /* CONFIG_DEBUG_KERNEL */
1394f032
BW
74#define INTERRUPT_ENTRY(N) \
75 [--sp] = SYSCFG; \
1394f032
BW
76 [--sp] = P0; /*orig_p0*/ \
77 [--sp] = R0; /*orig_r0*/ \
78 [--sp] = (R7:0,P5:0); \
b9a3899d
RG
79 p0.l = lo(IPEND); \
80 p0.h = hi(IPEND); \
81 r1 = [p0]; \
1394f032 82 R0 = (N); \
6a01f230 83 LOAD_IPIPE_IPEND \
1394f032 84 jump __common_int_entry;
b9a3899d 85# endif /* CONFIG_DEBUG_KERNEL */
1394f032
BW
86
87/* For timer interrupts, we need to save IPEND, since the user_mode
b9a3899d
RG
88 *macro accesses it to determine where to account time.
89 */
1394f032
BW
90#define TIMER_INTERRUPT_ENTRY(N) \
91 [--sp] = SYSCFG; \
1394f032
BW
92 [--sp] = P0; /*orig_p0*/ \
93 [--sp] = R0; /*orig_r0*/ \
94 [--sp] = (R7:0,P5:0); \
95 p0.l = lo(IPEND); \
96 p0.h = hi(IPEND); \
97 r1 = [p0]; \
98 R0 = (N); \
99 jump __common_int_entry;
b9a3899d
RG
100#else /* CONFIG_EXACT_HWERR is defined */
101
102/* if we want hardware error to be exact, we need to do a SSYNC (which forces
103 * read/writes to complete to the memory controllers), and check to see that
104 * caused a pending HW error condition. If so, we assume it was caused by user
105 * space, by setting the same interrupt that we are in (so it goes off again)
106 * and context restore, and a RTI (without servicing anything). This should
107 * cause the pending HWERR to fire, and when that is done, this interrupt will
108 * be re-serviced properly.
109 * As you can see by the code - we actually need to do two SSYNCS - one to
110 * make sure the read/writes complete, and another to make sure the hardware
111 * error is recognized by the core.
dedfd5d7
RG
112 *
113 * The extra nop before the SSYNC is to make sure we work around 05000244,
114 * since the 283/315 workaround includes a branch to the end
b9a3899d
RG
115 */
116#define INTERRUPT_ENTRY(N) \
b9a3899d
RG
117 [--sp] = SYSCFG; \
118 [--sp] = P0; /*orig_p0*/ \
119 [--sp] = R0; /*orig_r0*/ \
120 [--sp] = (R7:0,P5:0); \
121 R1 = ASTAT; \
dedfd5d7 122 ANOMALY_283_315_WORKAROUND(p0, r0) \
b9a3899d
RG
123 P0.L = LO(ILAT); \
124 P0.H = HI(ILAT); \
dedfd5d7
RG
125 NOP; \
126 SSYNC; \
127 SSYNC; \
b9a3899d
RG
128 R0 = [P0]; \
129 CC = BITTST(R0, EVT_IVHW_P); \
130 IF CC JUMP 1f; \
131 ASTAT = R1; \
132 p0.l = lo(IPEND); \
133 p0.h = hi(IPEND); \
134 r1 = [p0]; \
135 R0 = (N); \
136 LOAD_IPIPE_IPEND \
137 jump __common_int_entry; \
1381: ASTAT = R1; \
139 RAISE N; \
140 (R7:0, P5:0) = [SP++]; \
141 SP += 0x8; \
142 SYSCFG = [SP++]; \
143 CSYNC; \
144 RTI;
145
146#define TIMER_INTERRUPT_ENTRY(N) \
b9a3899d
RG
147 [--sp] = SYSCFG; \
148 [--sp] = P0; /*orig_p0*/ \
149 [--sp] = R0; /*orig_r0*/ \
150 [--sp] = (R7:0,P5:0); \
151 R1 = ASTAT; \
dedfd5d7 152 ANOMALY_283_315_WORKAROUND(p0, r0) \
b9a3899d
RG
153 P0.L = LO(ILAT); \
154 P0.H = HI(ILAT); \
dedfd5d7
RG
155 NOP; \
156 SSYNC; \
157 SSYNC; \
b9a3899d
RG
158 R0 = [P0]; \
159 CC = BITTST(R0, EVT_IVHW_P); \
160 IF CC JUMP 1f; \
161 ASTAT = R1; \
162 p0.l = lo(IPEND); \
163 p0.h = hi(IPEND); \
164 r1 = [p0]; \
165 R0 = (N); \
166 jump __common_int_entry; \
1671: ASTAT = R1; \
168 RAISE N; \
169 (R7:0, P5:0) = [SP++]; \
170 SP += 0x8; \
171 SYSCFG = [SP++]; \
172 CSYNC; \
173 RTI;
174#endif /* CONFIG_EXACT_HWERR */
1394f032
BW
175
176/* This one pushes RETI without using CLI. Interrupts are enabled. */
177#define SAVE_CONTEXT_SYSCALL save_context_syscall
178#define SAVE_CONTEXT save_context_with_interrupts
dbdf20db 179#define SAVE_CONTEXT_CPLB save_context_cplb
1394f032
BW
180
181#define RESTORE_ALL_SYS restore_context_no_interrupts
182#define RESTORE_CONTEXT restore_context_with_interrupts
dbdf20db 183#define RESTORE_CONTEXT_CPLB restore_context_cplb
1394f032
BW
184
185#endif /* __ASSEMBLY__ */
186#endif /* __BFIN_ENTRY_H */