aboutsummaryrefslogtreecommitdiffstats
path: root/arch/blackfin
diff options
context:
space:
mode:
authorRobin Getz <robin.getz@analog.com>2009-06-08 21:18:41 -0400
committerMike Frysinger <vapier@gentoo.org>2009-06-13 07:20:06 -0400
commit16aadcb680e188bd0a6d7b0ecd5d0ceabd4fba4d (patch)
tree2de288531c36c733bdc3b452a764b2588356e00c /arch/blackfin
parentf3ad116588151b3371ae4e092290e4f48e62b8bb (diff)
Blackfin: only handle CPLB protection violations when MPU is enabled
We don't need to handle CPLB protection violations unless we are running with the MPU on. Fix the entry code to call common trap_c, and remove the code which is never run. This allows the traps test suite to run on older boards with the MPU disabled. URL: http://blackfin.uclinux.org/gf/tracker/5129 Signed-off-by: Robin Getz <robin.getz@analog.com> Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Diffstat (limited to 'arch/blackfin')
-rw-r--r--arch/blackfin/kernel/cplb-nompu/cplbmgr.c54
-rw-r--r--arch/blackfin/mach-common/entry.S11
2 files changed, 10 insertions, 55 deletions
diff --git a/arch/blackfin/kernel/cplb-nompu/cplbmgr.c b/arch/blackfin/kernel/cplb-nompu/cplbmgr.c
index 8cbb47c7b663..12b030842fdb 100644
--- a/arch/blackfin/kernel/cplb-nompu/cplbmgr.c
+++ b/arch/blackfin/kernel/cplb-nompu/cplbmgr.c
@@ -28,6 +28,7 @@
28#include <asm/cplbinit.h> 28#include <asm/cplbinit.h>
29#include <asm/cplb.h> 29#include <asm/cplb.h>
30#include <asm/mmu_context.h> 30#include <asm/mmu_context.h>
31#include <asm/traps.h>
31 32
32/* 33/*
33 * WARNING 34 * WARNING
@@ -100,28 +101,6 @@ static inline void write_icplb_data(int cpu, int idx, unsigned long data,
100#endif 101#endif
101} 102}
102 103
103/*
104 * Given the contents of the status register, return the index of the
105 * CPLB that caused the fault.
106 */
107static inline int faulting_cplb_index(int status)
108{
109 int signbits = __builtin_bfin_norm_fr1x32(status & 0xFFFF);
110 return 30 - signbits;
111}
112
113/*
114 * Given the contents of the status register and the DCPLB_DATA contents,
115 * return true if a write access should be permitted.
116 */
117static inline int write_permitted(int status, unsigned long data)
118{
119 if (status & FAULT_USERSUPV)
120 return !!(data & CPLB_SUPV_WR);
121 else
122 return !!(data & CPLB_USER_WR);
123}
124
125/* Counters to implement round-robin replacement. */ 104/* Counters to implement round-robin replacement. */
126static int icplb_rr_index[NR_CPUS] PDT_ATTR; 105static int icplb_rr_index[NR_CPUS] PDT_ATTR;
127static int dcplb_rr_index[NR_CPUS] PDT_ATTR; 106static int dcplb_rr_index[NR_CPUS] PDT_ATTR;
@@ -245,43 +224,16 @@ MGR_ATTR static int dcplb_miss(int cpu)
245 return CPLB_RELOADED; 224 return CPLB_RELOADED;
246} 225}
247 226
248MGR_ATTR static noinline int dcplb_protection_fault(int cpu)
249{
250 int status = bfin_read_DCPLB_STATUS();
251
252 nr_dcplb_prot[cpu]++;
253
254 if (likely(status & FAULT_RW)) {
255 int idx = faulting_cplb_index(status);
256 unsigned long regaddr = DCPLB_DATA0 + idx * 4;
257 unsigned long data = bfin_read32(regaddr);
258
259 /* Check if fault is to dirty a clean page */
260 if (!(data & CPLB_WT) && !(data & CPLB_DIRTY) &&
261 write_permitted(status, data)) {
262
263 dcplb_tbl[cpu][idx].data = data;
264 bfin_write32(regaddr, data);
265 return CPLB_RELOADED;
266 }
267 }
268
269 return CPLB_PROT_VIOL;
270}
271
272MGR_ATTR int cplb_hdr(int seqstat, struct pt_regs *regs) 227MGR_ATTR int cplb_hdr(int seqstat, struct pt_regs *regs)
273{ 228{
274 int cause = seqstat & 0x3f; 229 int cause = seqstat & 0x3f;
275 unsigned int cpu = smp_processor_id(); 230 unsigned int cpu = smp_processor_id();
276 switch (cause) { 231 switch (cause) {
277 case 0x2C: 232 case VEC_CPLB_I_M:
278 return icplb_miss(cpu); 233 return icplb_miss(cpu);
279 case 0x26: 234 case VEC_CPLB_M:
280 return dcplb_miss(cpu); 235 return dcplb_miss(cpu);
281 default: 236 default:
282 if (unlikely(cause == 0x23))
283 return dcplb_protection_fault(cpu);
284
285 return CPLB_UNKNOWN_ERR; 237 return CPLB_UNKNOWN_ERR;
286 } 238 }
287} 239}
diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S
index da0558ad1b1a..25c6aa42d45e 100644
--- a/arch/blackfin/mach-common/entry.S
+++ b/arch/blackfin/mach-common/entry.S
@@ -42,6 +42,7 @@
42#include <asm/thread_info.h> /* TIF_NEED_RESCHED */ 42#include <asm/thread_info.h> /* TIF_NEED_RESCHED */
43#include <asm/asm-offsets.h> 43#include <asm/asm-offsets.h>
44#include <asm/trace.h> 44#include <asm/trace.h>
45#include <asm/traps.h>
45 46
46#include <asm/context.S> 47#include <asm/context.S>
47 48
@@ -84,13 +85,15 @@ ENTRY(_ex_workaround_261)
84 if !cc jump _bfin_return_from_exception; 85 if !cc jump _bfin_return_from_exception;
85 /* fall through */ 86 /* fall through */
86 R7 = P4; 87 R7 = P4;
87 R6 = 0x26; /* Data CPLB Miss */ 88 R6 = VEC_CPLB_M; /* Data CPLB Miss */
88 cc = R6 == R7; 89 cc = R6 == R7;
89 if cc jump _ex_dcplb_miss (BP); 90 if cc jump _ex_dcplb_miss (BP);
90 R6 = 0x23; /* Data CPLB Miss */ 91#ifdef CONFIG_MPU
92 R6 = VEC_CPLB_VL; /* Data CPLB Violation */
91 cc = R6 == R7; 93 cc = R6 == R7;
92 if cc jump _ex_dcplb_viol (BP); 94 if cc jump _ex_dcplb_viol (BP);
93 /* Handle 0x23 Data CPLB Protection Violation 95#endif
96 /* Handle Data CPLB Protection Violation
94 * and Data CPLB Multiple Hits - Linux Trap Zero 97 * and Data CPLB Multiple Hits - Linux Trap Zero
95 */ 98 */
96 jump _ex_trap_c; 99 jump _ex_trap_c;
@@ -270,7 +273,7 @@ ENTRY(_bfin_return_from_exception)
270 r6.l = lo(SEQSTAT_EXCAUSE); 273 r6.l = lo(SEQSTAT_EXCAUSE);
271 r6.h = hi(SEQSTAT_EXCAUSE); 274 r6.h = hi(SEQSTAT_EXCAUSE);
272 r7 = r7 & r6; 275 r7 = r7 & r6;
273 r6 = 0x25; 276 r6 = VEC_UNCOV;
274 CC = R7 == R6; 277 CC = R7 == R6;
275 if CC JUMP _double_fault; 278 if CC JUMP _double_fault;
276#endif 279#endif