aboutsummaryrefslogtreecommitdiffstats
path: root/arch/blackfin/kernel/cplb-mpu/cplbmgr.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-03-18 20:02:35 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-03-18 20:02:35 -0400
commit39710479303fd3affb3e204e9a7a75cc676977b5 (patch)
tree3fff5fb412df77170883f02fc54bdbee9aba4f22 /arch/blackfin/kernel/cplb-mpu/cplbmgr.c
parent9d20593a722c2dab7a5ab74f5d8c9b604aca52f9 (diff)
parenteb63e5d15758d2b1e607ddd5fb861b5596629380 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/vapier/blackfin
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/vapier/blackfin: (96 commits) Blackfin: stop cleaning include/asm/asm-offsets.h Blackfin: scale calibration when cpu freq changes Blackfin: eat spurious space in asm/dpmc.h Blackfin: fix anomaly 283 handling with exact hardware error Blackfin: bf537-stamp: add example ADXL346 orientation resources Blackfin: bf537-stamp: add example AD2S1210 IIO resources Blackfin: don't support keypad wakeup from hibernate Blackfin: bf537-stamp: add example AD7416 IIO resources Blackfin: bf537-stamp: add example ADP8860 backlight/led resources Blackfin: bf537-stamp: add example AD7414 temp sensor resources Blackfin: rename AD1836 to AD183X in board files Blackfin: bf537-stamp: add example AD2S120x resources Blackfin: add support for the on-chip MAC status interrupts Blackfin: asm/page.h: pull in asm-generic headers Blackfin: mark gpio lib functions static Blackfin: bf537-stamp: add example ADAU1361 resources Blackfin: GPIO: implement to_irq handler Blackfin: bf537-stamp: add example ADP122/ADP150 power regulator resources Blackfin: bf537-stamp: add example AD2S90 resources Blackfin: bf537-stamp: add example AD5398 power regulator resources ...
Diffstat (limited to 'arch/blackfin/kernel/cplb-mpu/cplbmgr.c')
-rw-r--r--arch/blackfin/kernel/cplb-mpu/cplbmgr.c54
1 files changed, 39 insertions, 15 deletions
diff --git a/arch/blackfin/kernel/cplb-mpu/cplbmgr.c b/arch/blackfin/kernel/cplb-mpu/cplbmgr.c
index 930c01c0681..87b25b1b30e 100644
--- a/arch/blackfin/kernel/cplb-mpu/cplbmgr.c
+++ b/arch/blackfin/kernel/cplb-mpu/cplbmgr.c
@@ -31,6 +31,12 @@ int nr_dcplb_miss[NR_CPUS], nr_icplb_miss[NR_CPUS];
31int nr_icplb_supv_miss[NR_CPUS], nr_dcplb_prot[NR_CPUS]; 31int nr_icplb_supv_miss[NR_CPUS], nr_dcplb_prot[NR_CPUS];
32int nr_cplb_flush[NR_CPUS]; 32int nr_cplb_flush[NR_CPUS];
33 33
34#ifdef CONFIG_EXCPT_IRQ_SYSC_L1
35#define MGR_ATTR __attribute__((l1_text))
36#else
37#define MGR_ATTR
38#endif
39
34/* 40/*
35 * Given the contents of the status register, return the index of the 41 * Given the contents of the status register, return the index of the
36 * CPLB that caused the fault. 42 * CPLB that caused the fault.
@@ -59,7 +65,7 @@ static int icplb_rr_index[NR_CPUS], dcplb_rr_index[NR_CPUS];
59/* 65/*
60 * Find an ICPLB entry to be evicted and return its index. 66 * Find an ICPLB entry to be evicted and return its index.
61 */ 67 */
62static int evict_one_icplb(unsigned int cpu) 68MGR_ATTR static int evict_one_icplb(unsigned int cpu)
63{ 69{
64 int i; 70 int i;
65 for (i = first_switched_icplb; i < MAX_CPLBS; i++) 71 for (i = first_switched_icplb; i < MAX_CPLBS; i++)
@@ -74,7 +80,7 @@ static int evict_one_icplb(unsigned int cpu)
74 return i; 80 return i;
75} 81}
76 82
77static int evict_one_dcplb(unsigned int cpu) 83MGR_ATTR static int evict_one_dcplb(unsigned int cpu)
78{ 84{
79 int i; 85 int i;
80 for (i = first_switched_dcplb; i < MAX_CPLBS; i++) 86 for (i = first_switched_dcplb; i < MAX_CPLBS; i++)
@@ -89,7 +95,7 @@ static int evict_one_dcplb(unsigned int cpu)
89 return i; 95 return i;
90} 96}
91 97
92static noinline int dcplb_miss(unsigned int cpu) 98MGR_ATTR static noinline int dcplb_miss(unsigned int cpu)
93{ 99{
94 unsigned long addr = bfin_read_DCPLB_FAULT_ADDR(); 100 unsigned long addr = bfin_read_DCPLB_FAULT_ADDR();
95 int status = bfin_read_DCPLB_STATUS(); 101 int status = bfin_read_DCPLB_STATUS();
@@ -114,10 +120,15 @@ static noinline int dcplb_miss(unsigned int cpu)
114 d_data = L2_DMEMORY; 120 d_data = L2_DMEMORY;
115 } else if (addr >= physical_mem_end) { 121 } else if (addr >= physical_mem_end) {
116 if (addr >= ASYNC_BANK0_BASE && addr < ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE) { 122 if (addr >= ASYNC_BANK0_BASE && addr < ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE) {
117 addr &= ~(4 * 1024 * 1024 - 1); 123 mask = current_rwx_mask[cpu];
118 d_data &= ~PAGE_SIZE_4KB; 124 if (mask) {
119 d_data |= PAGE_SIZE_4MB; 125 int page = (addr - (ASYNC_BANK0_BASE - _ramend)) >> PAGE_SHIFT;
120 d_data |= CPLB_USER_RD | CPLB_USER_WR; 126 int idx = page >> 5;
127 int bit = 1 << (page & 31);
128
129 if (mask[idx] & bit)
130 d_data |= CPLB_USER_RD;
131 }
121 } else if (addr >= BOOT_ROM_START && addr < BOOT_ROM_START + BOOT_ROM_LENGTH 132 } else if (addr >= BOOT_ROM_START && addr < BOOT_ROM_START + BOOT_ROM_LENGTH
122 && (status & (FAULT_RW | FAULT_USERSUPV)) == FAULT_USERSUPV) { 133 && (status & (FAULT_RW | FAULT_USERSUPV)) == FAULT_USERSUPV) {
123 addr &= ~(1 * 1024 * 1024 - 1); 134 addr &= ~(1 * 1024 * 1024 - 1);
@@ -126,7 +137,9 @@ static noinline int dcplb_miss(unsigned int cpu)
126 } else 137 } else
127 return CPLB_PROT_VIOL; 138 return CPLB_PROT_VIOL;
128 } else if (addr >= _ramend) { 139 } else if (addr >= _ramend) {
129 d_data |= CPLB_USER_RD | CPLB_USER_WR; 140 d_data |= CPLB_USER_RD | CPLB_USER_WR;
141 if (reserved_mem_dcache_on)
142 d_data |= CPLB_L1_CHBL;
130 } else { 143 } else {
131 mask = current_rwx_mask[cpu]; 144 mask = current_rwx_mask[cpu];
132 if (mask) { 145 if (mask) {
@@ -156,7 +169,7 @@ static noinline int dcplb_miss(unsigned int cpu)
156 return 0; 169 return 0;
157} 170}
158 171
159static noinline int icplb_miss(unsigned int cpu) 172MGR_ATTR static noinline int icplb_miss(unsigned int cpu)
160{ 173{
161 unsigned long addr = bfin_read_ICPLB_FAULT_ADDR(); 174 unsigned long addr = bfin_read_ICPLB_FAULT_ADDR();
162 int status = bfin_read_ICPLB_STATUS(); 175 int status = bfin_read_ICPLB_STATUS();
@@ -204,10 +217,19 @@ static noinline int icplb_miss(unsigned int cpu)
204 i_data = L2_IMEMORY; 217 i_data = L2_IMEMORY;
205 } else if (addr >= physical_mem_end) { 218 } else if (addr >= physical_mem_end) {
206 if (addr >= ASYNC_BANK0_BASE && addr < ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE) { 219 if (addr >= ASYNC_BANK0_BASE && addr < ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE) {
207 addr &= ~(4 * 1024 * 1024 - 1); 220 if (!(status & FAULT_USERSUPV)) {
208 i_data &= ~PAGE_SIZE_4KB; 221 unsigned long *mask = current_rwx_mask[cpu];
209 i_data |= PAGE_SIZE_4MB; 222
210 i_data |= CPLB_USER_RD; 223 if (mask) {
224 int page = (addr - (ASYNC_BANK0_BASE - _ramend)) >> PAGE_SHIFT;
225 int idx = page >> 5;
226 int bit = 1 << (page & 31);
227
228 mask += 2 * page_mask_nelts;
229 if (mask[idx] & bit)
230 i_data |= CPLB_USER_RD;
231 }
232 }
211 } else if (addr >= BOOT_ROM_START && addr < BOOT_ROM_START + BOOT_ROM_LENGTH 233 } else if (addr >= BOOT_ROM_START && addr < BOOT_ROM_START + BOOT_ROM_LENGTH
212 && (status & FAULT_USERSUPV)) { 234 && (status & FAULT_USERSUPV)) {
213 addr &= ~(1 * 1024 * 1024 - 1); 235 addr &= ~(1 * 1024 * 1024 - 1);
@@ -217,6 +239,8 @@ static noinline int icplb_miss(unsigned int cpu)
217 return CPLB_PROT_VIOL; 239 return CPLB_PROT_VIOL;
218 } else if (addr >= _ramend) { 240 } else if (addr >= _ramend) {
219 i_data |= CPLB_USER_RD; 241 i_data |= CPLB_USER_RD;
242 if (reserved_mem_icache_on)
243 i_data |= CPLB_L1_CHBL;
220 } else { 244 } else {
221 /* 245 /*
222 * Two cases to distinguish - a supervisor access must 246 * Two cases to distinguish - a supervisor access must
@@ -251,7 +275,7 @@ static noinline int icplb_miss(unsigned int cpu)
251 return 0; 275 return 0;
252} 276}
253 277
254static noinline int dcplb_protection_fault(unsigned int cpu) 278MGR_ATTR static noinline int dcplb_protection_fault(unsigned int cpu)
255{ 279{
256 int status = bfin_read_DCPLB_STATUS(); 280 int status = bfin_read_DCPLB_STATUS();
257 281
@@ -271,7 +295,7 @@ static noinline int dcplb_protection_fault(unsigned int cpu)
271 return CPLB_PROT_VIOL; 295 return CPLB_PROT_VIOL;
272} 296}
273 297
274int cplb_hdr(int seqstat, struct pt_regs *regs) 298MGR_ATTR int cplb_hdr(int seqstat, struct pt_regs *regs)
275{ 299{
276 int cause = seqstat & 0x3f; 300 int cause = seqstat & 0x3f;
277 unsigned int cpu = raw_smp_processor_id(); 301 unsigned int cpu = raw_smp_processor_id();