diff options
author | Robin Getz <robin.getz@analog.com> | 2009-06-08 21:18:41 -0400 |
---|---|---|
committer | Mike Frysinger <vapier@gentoo.org> | 2009-06-13 07:20:06 -0400 |
commit | 16aadcb680e188bd0a6d7b0ecd5d0ceabd4fba4d (patch) | |
tree | 2de288531c36c733bdc3b452a764b2588356e00c /arch/blackfin | |
parent | f3ad116588151b3371ae4e092290e4f48e62b8bb (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.c | 54 | ||||
-rw-r--r-- | arch/blackfin/mach-common/entry.S | 11 |
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 | */ | ||
107 | static 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 | */ | ||
117 | static 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. */ |
126 | static int icplb_rr_index[NR_CPUS] PDT_ATTR; | 105 | static int icplb_rr_index[NR_CPUS] PDT_ATTR; |
127 | static int dcplb_rr_index[NR_CPUS] PDT_ATTR; | 106 | static 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 | ||
248 | MGR_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 | |||
272 | MGR_ATTR int cplb_hdr(int seqstat, struct pt_regs *regs) | 227 | MGR_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 |