Skip to content

Commit

Permalink
Blackfin: only handle CPLB protection violations when MPU is enabled
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Robin Getz authored and Mike Frysinger committed Jun 13, 2009
1 parent f3ad116 commit 16aadcb
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 55 deletions.
54 changes: 3 additions & 51 deletions arch/blackfin/kernel/cplb-nompu/cplbmgr.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include <asm/cplbinit.h>
#include <asm/cplb.h>
#include <asm/mmu_context.h>
#include <asm/traps.h>

/*
* WARNING
Expand Down Expand Up @@ -100,28 +101,6 @@ static inline void write_icplb_data(int cpu, int idx, unsigned long data,
#endif
}

/*
* Given the contents of the status register, return the index of the
* CPLB that caused the fault.
*/
static inline int faulting_cplb_index(int status)
{
int signbits = __builtin_bfin_norm_fr1x32(status & 0xFFFF);
return 30 - signbits;
}

/*
* Given the contents of the status register and the DCPLB_DATA contents,
* return true if a write access should be permitted.
*/
static inline int write_permitted(int status, unsigned long data)
{
if (status & FAULT_USERSUPV)
return !!(data & CPLB_SUPV_WR);
else
return !!(data & CPLB_USER_WR);
}

/* Counters to implement round-robin replacement. */
static int icplb_rr_index[NR_CPUS] PDT_ATTR;
static int dcplb_rr_index[NR_CPUS] PDT_ATTR;
Expand Down Expand Up @@ -245,43 +224,16 @@ MGR_ATTR static int dcplb_miss(int cpu)
return CPLB_RELOADED;
}

MGR_ATTR static noinline int dcplb_protection_fault(int cpu)
{
int status = bfin_read_DCPLB_STATUS();

nr_dcplb_prot[cpu]++;

if (likely(status & FAULT_RW)) {
int idx = faulting_cplb_index(status);
unsigned long regaddr = DCPLB_DATA0 + idx * 4;
unsigned long data = bfin_read32(regaddr);

/* Check if fault is to dirty a clean page */
if (!(data & CPLB_WT) && !(data & CPLB_DIRTY) &&
write_permitted(status, data)) {

dcplb_tbl[cpu][idx].data = data;
bfin_write32(regaddr, data);
return CPLB_RELOADED;
}
}

return CPLB_PROT_VIOL;
}

MGR_ATTR int cplb_hdr(int seqstat, struct pt_regs *regs)
{
int cause = seqstat & 0x3f;
unsigned int cpu = smp_processor_id();
switch (cause) {
case 0x2C:
case VEC_CPLB_I_M:
return icplb_miss(cpu);
case 0x26:
case VEC_CPLB_M:
return dcplb_miss(cpu);
default:
if (unlikely(cause == 0x23))
return dcplb_protection_fault(cpu);

return CPLB_UNKNOWN_ERR;
}
}
11 changes: 7 additions & 4 deletions arch/blackfin/mach-common/entry.S
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
#include <asm/thread_info.h> /* TIF_NEED_RESCHED */
#include <asm/asm-offsets.h>
#include <asm/trace.h>
#include <asm/traps.h>

#include <asm/context.S>

Expand Down Expand Up @@ -84,13 +85,15 @@ ENTRY(_ex_workaround_261)
if !cc jump _bfin_return_from_exception;
/* fall through */
R7 = P4;
R6 = 0x26; /* Data CPLB Miss */
R6 = VEC_CPLB_M; /* Data CPLB Miss */
cc = R6 == R7;
if cc jump _ex_dcplb_miss (BP);
R6 = 0x23; /* Data CPLB Miss */
#ifdef CONFIG_MPU
R6 = VEC_CPLB_VL; /* Data CPLB Violation */
cc = R6 == R7;
if cc jump _ex_dcplb_viol (BP);
/* Handle 0x23 Data CPLB Protection Violation
#endif
/* Handle Data CPLB Protection Violation
* and Data CPLB Multiple Hits - Linux Trap Zero
*/
jump _ex_trap_c;
Expand Down Expand Up @@ -270,7 +273,7 @@ ENTRY(_bfin_return_from_exception)
r6.l = lo(SEQSTAT_EXCAUSE);
r6.h = hi(SEQSTAT_EXCAUSE);
r7 = r7 & r6;
r6 = 0x25;
r6 = VEC_UNCOV;
CC = R7 == R6;
if CC JUMP _double_fault;
#endif
Expand Down

0 comments on commit 16aadcb

Please sign in to comment.