88
89
#define xnarch_fault_trap(fi) ((fi)->exception)
89
90
#define xnarch_fault_code(fi) (0)
90
91
#define xnarch_fault_pc(fi) ((fi)->regs->ARM_pc - (thumb_mode((fi)->regs) ? 2 : 4)) /* XXX ? */
91
#define xnarch_fault_fpu_p(fi) (0)
92
#ifndef CONFIG_XENO_HW_FPU
93
/* It is normal on ARM for user-space support running with a kernel compiled
94
with FPU support to make FPU faults, even on the context of real-time threads
95
which do not otherwise use FPU, so we simply ignore these faults. */
96
#define xnarch_fault_fpu_p(fi) (0)
97
#else /* CONFIG_XENO_HW_FPU */
98
static inline int xnarch_fault_fpu_p(struct xnarch_fltinfo *fi)
100
/* This function does the same thing to decode the faulting instruct as
101
"call_fpe" in arch/arm/entry-armv.S */
102
static unsigned copro_to_exc[16] = {
103
IPIPE_TRAP_UNDEFINSTR,
105
IPIPE_TRAP_FPU, IPIPE_TRAP_FPU,
106
IPIPE_TRAP_UNDEFINSTR,
108
IPIPE_TRAP_FPU, IPIPE_TRAP_FPU, IPIPE_TRAP_FPU,
109
#else /* !CONFIG_CRUNCH */
110
IPIPE_TRAP_UNDEFINSTR, IPIPE_TRAP_UNDEFINSTR, IPIPE_TRAP_UNDEFINSTR,
111
#endif /* !CONFIG_CRUNCH */
112
IPIPE_TRAP_UNDEFINSTR, IPIPE_TRAP_UNDEFINSTR, IPIPE_TRAP_UNDEFINSTR,
114
IPIPE_TRAP_VFP, IPIPE_TRAP_VFP,
115
#else /* !CONFIG_VFP */
116
IPIPE_TRAP_UNDEFINSTR, IPIPE_TRAP_UNDEFINSTR,
117
#endif /* !CONFIG_VFP */
118
IPIPE_TRAP_UNDEFINSTR, IPIPE_TRAP_UNDEFINSTR,
119
IPIPE_TRAP_UNDEFINSTR, IPIPE_TRAP_UNDEFINSTR,
121
unsigned instr, exc, cp;
124
if (fi->exception == IPIPE_TRAP_FPU || fi->exception == IPIPE_TRAP_VFP)
127
/* When an FPU fault occurs in user-mode, it will be properly resolved
128
before __ipipe_dispatch_event is called. */
129
if (fi->exception != IPIPE_TRAP_UNDEFINSTR || xnarch_fault_um(fi))
132
pc = (char *) xnarch_fault_pc(fi);
133
if (unlikely(thumb_mode(fi->regs))) {
134
unsigned short thumbh, thumbl;
136
thumbh = *(unsigned short *) pc;
137
thumbl = *((unsigned short *) pc + 1);
139
if ((thumbh & 0x0000f800) < 0x0000e800)
141
instr = (thumbh << 16) | thumbl;
144
if ((instr & 0xef000000) == 0xef000000
145
|| (instr & 0xff100000) == 0xf9000000) {
146
fi->exception = IPIPE_TRAP_VFP;
151
instr = *(unsigned *) pc;
154
if ((instr & 0xfe000000) == 0xf2000000
155
|| (instr & 0xff100000) == 0xf4000000) {
156
fi->exception = IPIPE_TRAP_VFP;
162
if ((instr & 0x0c000000) != 0x0c000000)
165
cp = (instr & 0x00000f00) >> 8;
167
/* We need something equivalent to _TIF_USING_IWMMXT for Xenomai kernel
170
fi->exception = IPIPE_TRAP_FPU;
175
fi->exception = exc = copro_to_exc[cp];
176
return exc != IPIPE_TRAP_UNDEFINSTR;
178
#endif /* CONFIG_XENO_HW_FPU */
92
179
/* The following predicates are only usable over a regular Linux stack
94
181
#define xnarch_fault_pf_p(fi) ((fi)->exception == IPIPE_TRAP_ACCESS)