提交 1ebc723c 编写于 作者: B Bernd Schmidt 提交者: Bryan Wu

[Blackfin] arch: support the reserved memory region in the MPU code

Pointed-out-by: NMike Frysinger <vapier.adi@gmail.com>
Signed-off-by: NBernd Schmidt <bernds_cb1@t-online.de>
Signed-off-by: NBryan Wu <cooloney@kernel.org>
上级 d56daae9
...@@ -146,14 +146,16 @@ static noinline int dcplb_miss(void) ...@@ -146,14 +146,16 @@ static noinline int dcplb_miss(void)
d_data = CPLB_SUPV_WR | CPLB_VALID | CPLB_DIRTY | PAGE_SIZE_4KB; d_data = CPLB_SUPV_WR | CPLB_VALID | CPLB_DIRTY | PAGE_SIZE_4KB;
#ifdef CONFIG_BFIN_DCACHE #ifdef CONFIG_BFIN_DCACHE
if (addr < _ramend - DMA_UNCACHED_REGION) { if (addr < _ramend - DMA_UNCACHED_REGION ||
(reserved_mem_dcache_on && addr >= _ramend &&
addr < physical_mem_end)) {
d_data |= CPLB_L1_CHBL | ANOMALY_05000158_WORKAROUND; d_data |= CPLB_L1_CHBL | ANOMALY_05000158_WORKAROUND;
#ifdef CONFIG_BFIN_WT #ifdef CONFIG_BFIN_WT
d_data |= CPLB_L1_AOW | CPLB_WT; d_data |= CPLB_L1_AOW | CPLB_WT;
#endif #endif
} }
#endif #endif
if (addr >= _ramend) { if (addr >= physical_mem_end) {
if (addr >= ASYNC_BANK0_BASE && addr < ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE if (addr >= ASYNC_BANK0_BASE && addr < ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE
&& (status & FAULT_USERSUPV)) { && (status & FAULT_USERSUPV)) {
addr &= ~0x3fffff; addr &= ~0x3fffff;
...@@ -161,6 +163,8 @@ static noinline int dcplb_miss(void) ...@@ -161,6 +163,8 @@ static noinline int dcplb_miss(void)
d_data |= PAGE_SIZE_4MB; d_data |= PAGE_SIZE_4MB;
} else } else
return CPLB_PROT_VIOL; return CPLB_PROT_VIOL;
} else if (addr >= _ramend) {
d_data |= CPLB_USER_RD | CPLB_USER_WR;
} else { } else {
mask = current_rwx_mask; mask = current_rwx_mask;
if (mask) { if (mask) {
...@@ -198,12 +202,14 @@ static noinline int icplb_miss(void) ...@@ -198,12 +202,14 @@ static noinline int icplb_miss(void)
unsigned long i_data; unsigned long i_data;
nr_icplb_miss++; nr_icplb_miss++;
if (status & FAULT_USERSUPV)
nr_icplb_supv_miss++;
if (addr >= _ramend) /* If inside the uncached DMA region, fault. */
if (addr >= _ramend - DMA_UNCACHED_REGION && addr < _ramend)
return CPLB_PROT_VIOL; return CPLB_PROT_VIOL;
if (status & FAULT_USERSUPV)
nr_icplb_supv_miss++;
/* /*
* First, try to find a CPLB that matches this address. If we * First, try to find a CPLB that matches this address. If we
* find one, then the fact that we're in the miss handler means * find one, then the fact that we're in the miss handler means
...@@ -220,30 +226,42 @@ static noinline int icplb_miss(void) ...@@ -220,30 +226,42 @@ static noinline int icplb_miss(void)
} }
i_data = CPLB_VALID | CPLB_PORTPRIO | PAGE_SIZE_4KB; i_data = CPLB_VALID | CPLB_PORTPRIO | PAGE_SIZE_4KB;
#ifdef CONFIG_BFIN_ICACHE
i_data |= CPLB_L1_CHBL | ANOMALY_05000158_WORKAROUND;
#endif
#ifdef CONFIG_BFIN_ICACHE
/* /*
* Two cases to distinguish - a supervisor access must necessarily * Normal RAM, and possibly the reserved memory area, are
* be for a module page; we grant it unconditionally (could do better * cacheable.
* here in the future). Otherwise, check the x bitmap of the current
* process.
*/ */
if (!(status & FAULT_USERSUPV)) { if (addr < _ramend ||
unsigned long *mask = current_rwx_mask; (addr < physical_mem_end && reserved_mem_icache_on))
i_data |= CPLB_L1_CHBL | ANOMALY_05000158_WORKAROUND;
if (mask) { #endif
int page = addr >> PAGE_SHIFT;
int offs = page >> 5;
int bit = 1 << (page & 31);
mask += 2 * page_mask_nelts; if (addr >= physical_mem_end) {
if (mask[offs] & bit) return CPLB_PROT_VIOL;
i_data |= CPLB_USER_RD; } else if (addr >= _ramend) {
i_data |= CPLB_USER_RD;
} else {
/*
* Two cases to distinguish - a supervisor access must
* necessarily be for a module page; we grant it
* unconditionally (could do better here in the future).
* Otherwise, check the x bitmap of the current process.
*/
if (!(status & FAULT_USERSUPV)) {
unsigned long *mask = current_rwx_mask;
if (mask) {
int page = addr >> PAGE_SHIFT;
int offs = page >> 5;
int bit = 1 << (page & 31);
mask += 2 * page_mask_nelts;
if (mask[offs] & bit)
i_data |= CPLB_USER_RD;
}
} }
} }
idx = evict_one_icplb(); idx = evict_one_icplb();
addr &= PAGE_MASK; addr &= PAGE_MASK;
icplb_tbl[idx].addr = addr; icplb_tbl[idx].addr = addr;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册