Commit 1ebc723c authored by Bernd Schmidt's avatar Bernd Schmidt Committed by Bryan Wu
Browse files

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

parent d56daae9
Loading
Loading
Loading
Loading
+41 −23
Original line number Diff line number Diff line
@@ -146,14 +146,16 @@ static noinline int dcplb_miss(void)

	d_data = CPLB_SUPV_WR | CPLB_VALID | CPLB_DIRTY | PAGE_SIZE_4KB;
#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;
#ifdef CONFIG_BFIN_WT
		d_data |= CPLB_L1_AOW | CPLB_WT;
#endif
	}
#endif
	if (addr >= _ramend) {
	if (addr >= physical_mem_end) {
		if (addr >= ASYNC_BANK0_BASE && addr < ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE
		    && (status & FAULT_USERSUPV)) {
			addr &= ~0x3fffff;
@@ -161,6 +163,8 @@ static noinline int dcplb_miss(void)
			d_data |= PAGE_SIZE_4MB;
		} else
			return CPLB_PROT_VIOL;
	} else if (addr >= _ramend) {
	    d_data |= CPLB_USER_RD | CPLB_USER_WR;
	} else {
		mask = current_rwx_mask;
		if (mask) {
@@ -198,12 +202,14 @@ static noinline int icplb_miss(void)
	unsigned long i_data;

	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;

	if (status & FAULT_USERSUPV)
		nr_icplb_supv_miss++;

	/*
	 * 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
@@ -220,15 +226,27 @@ static noinline int icplb_miss(void)
	}

	i_data = CPLB_VALID | CPLB_PORTPRIO | PAGE_SIZE_4KB;

#ifdef CONFIG_BFIN_ICACHE
	/*
	 * Normal RAM, and possibly the reserved memory area, are
	 * cacheable.
	 */
	if (addr < _ramend ||
	    (addr < physical_mem_end && reserved_mem_icache_on))
		i_data |= CPLB_L1_CHBL | ANOMALY_05000158_WORKAROUND;
#endif

	if (addr >= physical_mem_end) {
	    return CPLB_PROT_VIOL;
	} 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.
		 * 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;
@@ -243,7 +261,7 @@ static noinline int icplb_miss(void)
					i_data |= CPLB_USER_RD;
			}
		}

	}
	idx = evict_one_icplb();
	addr &= PAGE_MASK;
	icplb_tbl[idx].addr = addr;