diff options
author | Bernd Schmidt <bernds_cb1@t-online.de> | 2008-04-22 19:26:23 -0400 |
---|---|---|
committer | Bryan Wu <cooloney@kernel.org> | 2008-04-22 19:26:23 -0400 |
commit | b4bb68f7d049e923a812903133e7e3747dfe0fce (patch) | |
tree | 32c83ca7d4709cdde47274f225e17be5ac5747ce /arch/blackfin | |
parent | 2a0c4fdb6602ea066380aaf71ff7bb2f61ffeee8 (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')
-rw-r--r-- | arch/blackfin/kernel/cplb-mpu/cplbmgr.c | 46 |
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 | ||