Explorar o código

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>
Robin Getz %!s(int64=17) %!d(string=hai) anos
pai
achega
6a3f0b460c

+ 2 - 2
arch/blackfin/kernel/cplbinit.c

@@ -163,8 +163,8 @@ static struct cplb_desc cplb_data[] = {
 
 static u16 __init lock_kernel_check(u32 start, u32 end)
 {
-	if ((start <= (u32) _stext && end >= (u32) _end)
-	    || (start >= (u32) _stext && end <= (u32) _end))
+	if ((end   <= (u32) _end && end   >= (u32)_stext) ||
+	    (start <= (u32) _end && start >= (u32)_stext))
 		return IN_KERNEL;
 	return 0;
 }

+ 2 - 2
arch/blackfin/kernel/traps.c

@@ -670,8 +670,8 @@ void dump_bfin_regs(struct pt_regs *fp, void *retaddr)
 		printk("\n");
 	} else
 		printk("\n" KERN_NOTICE
-			"Cannot look at the [PC] for it is"
-			" in unreadable memory - sorry\n");
+			"Cannot look at the [PC] <%p> for it is"
+			" in unreadable memory - sorry\n", retaddr);
 
 	printk(KERN_NOTICE "\n" KERN_NOTICE "SEQUENCER STATUS:\n");
 	printk(KERN_NOTICE " SEQSTAT: %08lx  IPEND: %04lx  SYSCFG: %04lx\n",

+ 18 - 7
arch/blackfin/mach-common/cplbmgr.S

@@ -73,7 +73,7 @@ ENTRY(_cplb_mgr)
 	/* ICPLB Miss Exception. We need to choose one of the
 	* currently-installed CPLBs, and replace it with one
 	* from the configuration table.
- 	*/
+	*/
 
 	P4.L = LO(ICPLB_FAULT_ADDR);
 	P4.H = HI(ICPLB_FAULT_ADDR);
@@ -222,7 +222,7 @@ ENTRY(_cplb_mgr)
 
 	/* See if failed address > start address */
 	CC = R4 <= R0(IU);
- 	IF !CC JUMP .Linext;
+	IF !CC JUMP .Linext;
 
 	/* extract page size (17:16)*/
 	R3 = EXTRACT(R2, R1.L) (Z);
@@ -271,16 +271,27 @@ ENTRY(_cplb_mgr)
 
 /* FAILED CASES*/
 .Lno_page_in_table:
-	( R7:4,P5:3 ) = [SP++];
 	R0 = CPLB_NO_ADDR_MATCH;
-	RTS;
+	JUMP .Lfail_ret;
+
 .Lall_locked:
-	( R7:4,P5:3 ) = [SP++];
 	R0 = CPLB_NO_UNLOCKED;
-	RTS;
+	JUMP .Lfail_ret;
+
 .Lprot_violation:
-	( R7:4,P5:3 ) = [SP++];
 	R0 = CPLB_PROT_VIOL;
+
+.Lfail_ret:
+	/* Make sure we turn protection/cache back on, even in the failing case */
+	BITSET(R5,ENICPLB_P);
+	CLI R2;
+	SSYNC;          /* SSYNC required before writing to IMEM_CONTROL. */
+	.align 8;
+	[P4] = R5;
+	SSYNC;
+	STI R2;
+
+	( R7:4,P5:3 ) = [SP++];
 	RTS;
 
 .Ldcplb_write: