aboutsummaryrefslogtreecommitdiffstats
path: root/arch/blackfin/kernel
diff options
context:
space:
mode:
authorBernd Schmidt <bernds_cb1@t-online.de>2008-04-22 19:26:23 -0400
committerBryan Wu <cooloney@kernel.org>2008-04-22 19:26:23 -0400
commitb4bb68f7d049e923a812903133e7e3747dfe0fce (patch)
tree32c83ca7d4709cdde47274f225e17be5ac5747ce /arch/blackfin/kernel
parent2a0c4fdb6602ea066380aaf71ff7bb2f61ffeee8 (diff)
[Blackfin] arch: fix bug - Make the MPU code aware of the async banks and the uncached DMA area.
Bug: CONFIG_MPU doesn't seem to handle access to ASYNC/IO Memory well http://blackfin.uclinux.org/gf/project/uclinux-dist/tracker/?action=TrackerItemEdit&tracker_item_id=3912 Signed-off-by: Bernd Schmidt <bernds_cb1@t-online.de> Signed-off-by: Bryan Wu <cooloney@kernel.org>
Diffstat (limited to 'arch/blackfin/kernel')
-rw-r--r--arch/blackfin/kernel/cplb-mpu/cplbmgr.c46
1 files changed, 27 insertions, 19 deletions
diff --git a/arch/blackfin/kernel/cplb-mpu/cplbmgr.c b/arch/blackfin/kernel/cplb-mpu/cplbmgr.c
index 0a30d6256073..6f1c053903c4 100644
--- a/arch/blackfin/kernel/cplb-mpu/cplbmgr.c
+++ b/arch/blackfin/kernel/cplb-mpu/cplbmgr.c
@@ -143,30 +143,39 @@ static noinline int dcplb_miss(void)
143 unsigned long d_data; 143 unsigned long d_data;
144 144
145 nr_dcplb_miss++; 145 nr_dcplb_miss++;
146 if (addr >= _ramend)
147 return CPLB_PROT_VIOL;
148 146
149 d_data = CPLB_SUPV_WR | CPLB_VALID | CPLB_DIRTY | PAGE_SIZE_4KB; 147 d_data = CPLB_SUPV_WR | CPLB_VALID | CPLB_DIRTY | PAGE_SIZE_4KB;
150#ifdef CONFIG_BFIN_DCACHE 148#ifdef CONFIG_BFIN_DCACHE
151 d_data |= CPLB_L1_CHBL | ANOMALY_05000158_WORKAROUND; 149 if (addr < _ramend - DMA_UNCACHED_REGION) {
150 d_data |= CPLB_L1_CHBL | ANOMALY_05000158_WORKAROUND;
152#ifdef CONFIG_BFIN_WT 151#ifdef CONFIG_BFIN_WT
153 d_data |= CPLB_L1_AOW | CPLB_WT; 152 d_data |= CPLB_L1_AOW | CPLB_WT;
154#endif
155#endif 153#endif
156 mask = current_rwx_mask;
157 if (mask) {
158 int page = addr >> PAGE_SHIFT;
159 int offs = page >> 5;
160 int bit = 1 << (page & 31);
161
162 if (mask[offs] & bit)
163 d_data |= CPLB_USER_RD;
164
165 mask += page_mask_nelts;
166 if (mask[offs] & bit)
167 d_data |= CPLB_USER_WR;
168 } 154 }
155#endif
156 if (addr >= _ramend) {
157 if (addr >= ASYNC_BANK0_BASE && addr < ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE
158 && (status & FAULT_USERSUPV)) {
159 addr &= ~0x3fffff;
160 d_data &= ~PAGE_SIZE_4KB;
161 d_data |= PAGE_SIZE_4MB;
162 } else
163 return CPLB_PROT_VIOL;
164 } else {
165 mask = current_rwx_mask;
166 if (mask) {
167 int page = addr >> PAGE_SHIFT;
168 int offs = page >> 5;
169 int bit = 1 << (page & 31);
170
171 if (mask[offs] & bit)
172 d_data |= CPLB_USER_RD;
169 173
174 mask += page_mask_nelts;
175 if (mask[offs] & bit)
176 d_data |= CPLB_USER_WR;
177 }
178 }
170 idx = evict_one_dcplb(); 179 idx = evict_one_dcplb();
171 180
172 addr &= PAGE_MASK; 181 addr &= PAGE_MASK;
@@ -280,8 +289,7 @@ int cplb_hdr(int seqstat, struct pt_regs *regs)
280 case 0x26: 289 case 0x26:
281 return dcplb_miss(); 290 return dcplb_miss();
282 default: 291 default:
283 return 1; 292 return 1;
284 panic_cplb_error(seqstat, regs);
285 } 293 }
286} 294}
287 295