diff options
author | Robin Getz <robin.getz@analog.com> | 2007-11-15 02:10:48 -0500 |
---|---|---|
committer | Bryan Wu <bryan.wu@analog.com> | 2007-11-15 02:10:48 -0500 |
commit | 6a3f0b460cea79f08683cef1862d686a887efd8c (patch) | |
tree | 4133b0e4e2af811cd96a4ee722f8453e07082266 /arch/blackfin | |
parent | 0954f70ab1ffd9ad945c88c11877a08baed311c7 (diff) |
Blackfin arch: fix bug cplbmgr.S does not exit properly on error condition
https://blackfin.uclinux.org/gf/project/uclinux-dist/tracker/?action=TrackerItemEdit&tracker_item_id=1685
Ensure that cache/protection is turned back on when we get a
fault, and ensure that the initial population of the CPLB tables are
correct - that kernel is locked in CPLB tables
Signed-off-by: Robin Getz <robin.getz@analog.com>
Signed-off-by: Bryan Wu <bryan.wu@analog.com>
Diffstat (limited to 'arch/blackfin')
-rw-r--r-- | arch/blackfin/kernel/cplbinit.c | 4 | ||||
-rw-r--r-- | arch/blackfin/kernel/traps.c | 4 | ||||
-rw-r--r-- | arch/blackfin/mach-common/cplbmgr.S | 25 |
3 files changed, 22 insertions, 11 deletions
diff --git a/arch/blackfin/kernel/cplbinit.c b/arch/blackfin/kernel/cplbinit.c index f2db6a5e2b5b..7392ac2d2c29 100644 --- a/arch/blackfin/kernel/cplbinit.c +++ b/arch/blackfin/kernel/cplbinit.c | |||
@@ -163,8 +163,8 @@ static struct cplb_desc cplb_data[] = { | |||
163 | 163 | ||
164 | static u16 __init lock_kernel_check(u32 start, u32 end) | 164 | static u16 __init lock_kernel_check(u32 start, u32 end) |
165 | { | 165 | { |
166 | if ((start <= (u32) _stext && end >= (u32) _end) | 166 | if ((end <= (u32) _end && end >= (u32)_stext) || |
167 | || (start >= (u32) _stext && end <= (u32) _end)) | 167 | (start <= (u32) _end && start >= (u32)_stext)) |
168 | return IN_KERNEL; | 168 | return IN_KERNEL; |
169 | return 0; | 169 | return 0; |
170 | } | 170 | } |
diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c index ce9981b5339b..fbdf999bd2b5 100644 --- a/arch/blackfin/kernel/traps.c +++ b/arch/blackfin/kernel/traps.c | |||
@@ -670,8 +670,8 @@ void dump_bfin_regs(struct pt_regs *fp, void *retaddr) | |||
670 | printk("\n"); | 670 | printk("\n"); |
671 | } else | 671 | } else |
672 | printk("\n" KERN_NOTICE | 672 | printk("\n" KERN_NOTICE |
673 | "Cannot look at the [PC] for it is" | 673 | "Cannot look at the [PC] <%p> for it is" |
674 | " in unreadable memory - sorry\n"); | 674 | " in unreadable memory - sorry\n", retaddr); |
675 | 675 | ||
676 | printk(KERN_NOTICE "\n" KERN_NOTICE "SEQUENCER STATUS:\n"); | 676 | printk(KERN_NOTICE "\n" KERN_NOTICE "SEQUENCER STATUS:\n"); |
677 | printk(KERN_NOTICE " SEQSTAT: %08lx IPEND: %04lx SYSCFG: %04lx\n", | 677 | printk(KERN_NOTICE " SEQSTAT: %08lx IPEND: %04lx SYSCFG: %04lx\n", |
diff --git a/arch/blackfin/mach-common/cplbmgr.S b/arch/blackfin/mach-common/cplbmgr.S index 946703ef48ff..6f909cbfac7b 100644 --- a/arch/blackfin/mach-common/cplbmgr.S +++ b/arch/blackfin/mach-common/cplbmgr.S | |||
@@ -73,7 +73,7 @@ ENTRY(_cplb_mgr) | |||
73 | /* ICPLB Miss Exception. We need to choose one of the | 73 | /* ICPLB Miss Exception. We need to choose one of the |
74 | * currently-installed CPLBs, and replace it with one | 74 | * currently-installed CPLBs, and replace it with one |
75 | * from the configuration table. | 75 | * from the configuration table. |
76 | */ | 76 | */ |
77 | 77 | ||
78 | P4.L = LO(ICPLB_FAULT_ADDR); | 78 | P4.L = LO(ICPLB_FAULT_ADDR); |
79 | P4.H = HI(ICPLB_FAULT_ADDR); | 79 | P4.H = HI(ICPLB_FAULT_ADDR); |
@@ -222,7 +222,7 @@ ENTRY(_cplb_mgr) | |||
222 | 222 | ||
223 | /* See if failed address > start address */ | 223 | /* See if failed address > start address */ |
224 | CC = R4 <= R0(IU); | 224 | CC = R4 <= R0(IU); |
225 | IF !CC JUMP .Linext; | 225 | IF !CC JUMP .Linext; |
226 | 226 | ||
227 | /* extract page size (17:16)*/ | 227 | /* extract page size (17:16)*/ |
228 | R3 = EXTRACT(R2, R1.L) (Z); | 228 | R3 = EXTRACT(R2, R1.L) (Z); |
@@ -271,16 +271,27 @@ ENTRY(_cplb_mgr) | |||
271 | 271 | ||
272 | /* FAILED CASES*/ | 272 | /* FAILED CASES*/ |
273 | .Lno_page_in_table: | 273 | .Lno_page_in_table: |
274 | ( R7:4,P5:3 ) = [SP++]; | ||
275 | R0 = CPLB_NO_ADDR_MATCH; | 274 | R0 = CPLB_NO_ADDR_MATCH; |
276 | RTS; | 275 | JUMP .Lfail_ret; |
276 | |||
277 | .Lall_locked: | 277 | .Lall_locked: |
278 | ( R7:4,P5:3 ) = [SP++]; | ||
279 | R0 = CPLB_NO_UNLOCKED; | 278 | R0 = CPLB_NO_UNLOCKED; |
280 | RTS; | 279 | JUMP .Lfail_ret; |
280 | |||
281 | .Lprot_violation: | 281 | .Lprot_violation: |
282 | ( R7:4,P5:3 ) = [SP++]; | ||
283 | R0 = CPLB_PROT_VIOL; | 282 | R0 = CPLB_PROT_VIOL; |
283 | |||
284 | .Lfail_ret: | ||
285 | /* Make sure we turn protection/cache back on, even in the failing case */ | ||
286 | BITSET(R5,ENICPLB_P); | ||
287 | CLI R2; | ||
288 | SSYNC; /* SSYNC required before writing to IMEM_CONTROL. */ | ||
289 | .align 8; | ||
290 | [P4] = R5; | ||
291 | SSYNC; | ||
292 | STI R2; | ||
293 | |||
294 | ( R7:4,P5:3 ) = [SP++]; | ||
284 | RTS; | 295 | RTS; |
285 | 296 | ||
286 | .Ldcplb_write: | 297 | .Ldcplb_write: |