1/* 2 * Copyright 2004-2009 Analog Devices Inc. 3 * 4 * Licensed under the GPL-2 or later. 5 */ 6 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 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 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. */ 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 44 45#if ANOMALY_05000283 || ANOMALY_05000315 46# define ANOMALY_283_315_WORKAROUND(preg, dreg) \ 47 cc = dreg == dreg; \ 48 preg.h = HI(CHIPID); \ 49 preg.l = LO(CHIPID); \ 50 if cc jump 1f; \ 51 dreg.l = W[preg]; \ 521: 53#else 54# define ANOMALY_283_315_WORKAROUND(preg, dreg) 55#endif /* ANOMALY_05000283 || ANOMALY_05000315 */ 56 57#ifndef CONFIG_EXACT_HWERR 58/* As a debugging aid - we save IPEND when DEBUG_KERNEL is on, 59 * otherwise it is a waste of cycles. 60 */ 61# ifndef CONFIG_DEBUG_KERNEL 62#define INTERRUPT_ENTRY(N) \ 63 [--sp] = SYSCFG; \ 64 [--sp] = P0; /*orig_p0*/ \ 65 [--sp] = R0; /*orig_r0*/ \ 66 [--sp] = (R7:0,P5:0); \ 67 R0 = (N); \ 68 LOAD_IPIPE_IPEND \ 69 jump __common_int_entry; 70# else /* CONFIG_DEBUG_KERNEL */ 71#define INTERRUPT_ENTRY(N) \ 72 [--sp] = SYSCFG; \ 73 [--sp] = P0; /*orig_p0*/ \ 74 [--sp] = R0; /*orig_r0*/ \ 75 [--sp] = (R7:0,P5:0); \ 76 p0.l = lo(IPEND); \ 77 p0.h = hi(IPEND); \ 78 r1 = [p0]; \ 79 R0 = (N); \ 80 LOAD_IPIPE_IPEND \ 81 jump __common_int_entry; 82# endif /* CONFIG_DEBUG_KERNEL */ 83 84/* For timer interrupts, we need to save IPEND, since the user_mode 85 *macro accesses it to determine where to account time. 86 */ 87#define TIMER_INTERRUPT_ENTRY(N) \ 88 [--sp] = SYSCFG; \ 89 [--sp] = P0; /*orig_p0*/ \ 90 [--sp] = R0; /*orig_r0*/ \ 91 [--sp] = (R7:0,P5:0); \ 92 p0.l = lo(IPEND); \ 93 p0.h = hi(IPEND); \ 94 r1 = [p0]; \ 95 R0 = (N); \ 96 jump __common_int_entry; 97#else /* CONFIG_EXACT_HWERR is defined */ 98 99#define INTERRUPT_ENTRY(N) \ 100 [--sp] = SYSCFG; \ 101 [--sp] = P0; /*orig_p0*/ \ 102 [--sp] = R0; /*orig_r0*/ \ 103 [--sp] = (R7:0,P5:0); \ 104 R1 = ASTAT; \ 105 ANOMALY_283_315_WORKAROUND(p0, r0) \ 106 P0.L = LO(ILAT); \ 107 P0.H = HI(ILAT); \ 108 NOP; \ 109 SSYNC; \ 110 SSYNC; \ 111 R0 = [P0]; \ 112 CC = BITTST(R0, EVT_IVHW_P); \ 113 IF CC JUMP 1f; \ 114 ASTAT = R1; \ 115 p0.l = lo(IPEND); \ 116 p0.h = hi(IPEND); \ 117 r1 = [p0]; \ 118 R0 = (N); \ 119 LOAD_IPIPE_IPEND \ 120 jump __common_int_entry; \ 1211: ASTAT = R1; \ 122 RAISE N; \ 123 (R7:0, P5:0) = [SP++]; \ 124 SP += 0x8; \ 125 SYSCFG = [SP++]; \ 126 CSYNC; \ 127 RTI; 128 129#define TIMER_INTERRUPT_ENTRY(N) \ 130 [--sp] = SYSCFG; \ 131 [--sp] = P0; /*orig_p0*/ \ 132 [--sp] = R0; /*orig_r0*/ \ 133 [--sp] = (R7:0,P5:0); \ 134 R1 = ASTAT; \ 135 ANOMALY_283_315_WORKAROUND(p0, r0) \ 136 P0.L = LO(ILAT); \ 137 P0.H = HI(ILAT); \ 138 NOP; \ 139 SSYNC; \ 140 SSYNC; \ 141 R0 = [P0]; \ 142 CC = BITTST(R0, EVT_IVHW_P); \ 143 IF CC JUMP 1f; \ 144 ASTAT = R1; \ 145 p0.l = lo(IPEND); \ 146 p0.h = hi(IPEND); \ 147 r1 = [p0]; \ 148 R0 = (N); \ 149 jump __common_int_entry; \ 1501: ASTAT = R1; \ 151 RAISE N; \ 152 (R7:0, P5:0) = [SP++]; \ 153 SP += 0x8; \ 154 SYSCFG = [SP++]; \ 155 CSYNC; \ 156 RTI; 157#endif /* CONFIG_EXACT_HWERR */ 158 159/* This one pushes RETI without using CLI. Interrupts are enabled. */ 160#define SAVE_CONTEXT_SYSCALL save_context_syscall 161#define SAVE_CONTEXT save_context_with_interrupts 162#define SAVE_CONTEXT_CPLB save_context_cplb 163 164#define RESTORE_ALL_SYS restore_context_no_interrupts 165#define RESTORE_CONTEXT restore_context_with_interrupts 166#define RESTORE_CONTEXT_CPLB restore_context_cplb 167 168#endif /* __ASSEMBLY__ */ 169#endif /* __BFIN_ENTRY_H */ 170