[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[microblaze-uclinux] kernel patch



Hi folks,

It's been a busy day!  Attached is a kernel patch with some significant 
fixes.  It should be in CVS soon - just do a CVS update from within the 
linux-2.4.x directory to get the changes.  Or, apply it manually if you 
prefer.

Changes:

1. Work-around for a very subtle compiler bug that caused erroneous 
behaviour in le16_to_cpu and other endian-swapping code.  This was the 
root cause of the ext2 filesystem code not working properly, so at last 
we have a stable read-write filesystem on microblaze uClinux!  This is 
the last of the really nasty (known) bugs.

2. Bug fixes in entry.S from Xilinx (thanks Raj and Vasanth!), fixing 
some logical errors regarding interrupt enabling, system call handling 
and also the PTRACE system call.  Stay tuned for full gdbserver and 
remote application debugging support...

3. General tidy-up, including defaulting the mbvanilla platform to use 
the full 32MB of memory.

Cheers,

John
Index: arch/microblaze/kernel/entry.S
===================================================================
RCS file: /var/cvs/uClinux-2.4.x/arch/microblaze/kernel/entry.S,v
retrieving revision 1.6
diff -u -b -B -w -p -r1.6 entry.S
--- arch/microblaze/kernel/entry.S	2003/11/12 03:17:43	1.6
+++ arch/microblaze/kernel/entry.S	2004/03/03 05:40:50
@@ -445,13 +445,16 @@
 	nop;			/* Delay slot */		      
 
 /* Instructions to return from a trap */
+/* Note we use rtid to force interrupts back on */
 #define TRAP_RETURN_INST						      \
-	rtsd	r17, 8;		/* r17 used as trap link register */	      \
+	rtid	r17, 8;		/* r17 used as trap link register */	      \
 	nop;
 
 /* Instructions to return from a debug trap */
+/* Note we use rtid to force interrupts back on */
+/* Return offset is zero, to ensure trapped instruction is re-executed */
 #define DBTRAP_RETURN_INST						      \
-	rtsd	r17, 8;		/* r17 used as trap link register */	      \
+	rtid	r17, 0;		/* r17 used as trap link register */	      \
 	nop;
 
 /* Code fragment to return from NMI */
@@ -484,10 +487,14 @@
 	/* XXX m68knommu also checks TASK_STATE & TASK_COUNTER here.  */      \
 									      \
 	/* Maybe handle a signal */					      \
-	RETRIEVE_CURRENT_TASK(r11);					      \
+5:	RETRIEVE_CURRENT_TASK(r11);					      \
 	lwi	r11, r11, TASK_SIGPENDING;				      \
 	bnei	r11, 4f;		/* Signals to handle, handle them */  \
 									      \
+	RETRIEVE_CURRENT_TASK(r11);					      \
+	lwi	r11, r11, TASK_PTRACE;					      \
+	bnei	r11, 4f;		/* Signals to handle, handle them */  \
+									      \
 /* Finally, return to user state.  */					      \
 1:	swi	r0, r0, KM;		/* Now officially in user state. */   \
 	POP_STATE(type);						      \
@@ -508,7 +515,7 @@
 	andi	r11, r11, ~2;						      \
 	mts	rmsr, r11;						      \
 	RESTORE_EXTRA_STATE_FOR_FUNCALL(type);				      \
-	brid	1b;							      \
+	brid	5b;		/* Back to continue return processing */      \
 	nop;								      \
 									      \
 /* Handle a signal return; Pending signals should be in r18.  */	      \
@@ -821,8 +828,14 @@ END(illegal_instruction)
 
 /*
  * `Debug' trap
+ *  We enter dbtrap in "BIP" (breakpoint) mode. That is bad for us.
+ *  So we exit the breakpoint mode with an 'rtbd' and proceed with the
+ *  original dbtrap.
  */
 G_ENTRY(dbtrap):
+	rtbd	r16, dbtrap_o;
+	nop;
+dbtrap_o:
 	mfs	r11, rmsr;		// disable interrupts 
 	andi	r11, r11, ~2;
 	mts	rmsr, r11;		
Index: arch/microblaze/kernel/signal.c
===================================================================
RCS file: /var/cvs/uClinux-2.4.x/arch/microblaze/kernel/signal.c,v
retrieving revision 1.4
diff -u -b -B -w -p -r1.4 signal.c
--- arch/microblaze/kernel/signal.c	2003/11/27 05:50:28	1.4
+++ arch/microblaze/kernel/signal.c	2004/03/03 05:40:51
@@ -559,12 +559,15 @@ int do_signal(struct pt_regs *regs, sigs
 
 			/* We're back.  Did the debugger cancel the sig?  */
 			if (!(signr = current->exit_code))
-				continue;
+				// continue;
+				return 1;
+
 			current->exit_code = 0;
 
 			/* The debugger continued.  Ignore SIGSTOP.  */
 			if (signr == SIGSTOP)
-				continue;
+				// continue;
+				return 1;
 
 			/* Update the siginfo structure.  Is this good?  */
 			if (signr != info.si_signo) {
Index: include/asm-microblaze/byteorder.h
===================================================================
RCS file: /var/cvs/uClinux-2.4.x/include/asm-microblaze/byteorder.h,v
retrieving revision 1.2
diff -u -b -B -w -p -r1.2 byteorder.h
--- include/asm-microblaze/byteorder.h	2003/04/15 03:00:19	1.2
+++ include/asm-microblaze/byteorder.h	2004/03/03 05:41:18
@@ -20,6 +20,26 @@
 
 #ifdef __GNUC__
 
+/* This is effectively a dupe of the arch-independent byteswap
+   code in include/linux/byteorder/swab.h, however we force a cast 
+   of the result up to 32 bits.  This in turn forces the compiler
+   to explicitly clear the high 16 bits, which it wasn't doing otherwise.
+
+   I think this is a symptom of a bug in mb-gcc.  JW 20040303
+*/
+static __inline__ __const__ __u16 ___arch__swab16 (__u16 half_word)
+{
+	/* 32 bit temp to cast result, forcing clearing of high word */
+	__u32 temp;
+
+	temp = ((half_word & 0x00FFU) << 8) |
+		((half_word & 0xFF00U) >> 8);
+
+	return (__u16) temp;
+}
+
+#define __arch__swab16(x) ___arch__swab16(x)
+
 /* Microblaze has no arch-specific endian conversion insns */
 
 #if !defined(__STRICT_ANSI__) || defined(__KERNEL__)
Index: include/asm-microblaze/mbvanilla.h
===================================================================
RCS file: /var/cvs/uClinux-2.4.x/include/asm-microblaze/mbvanilla.h,v
retrieving revision 1.4
diff -u -b -B -w -p -r1.4 mbvanilla.h
--- include/asm-microblaze/mbvanilla.h	2003/08/12 01:55:07	1.4
+++ include/asm-microblaze/mbvanilla.h	2004/03/03 05:41:18
@@ -54,7 +54,7 @@
 /* #define ERAM_ADDR 0xFFE00000
 #define ERAM_SIZE 0x00100000 */
 #define ERAM_ADDR 0x80000000
-#define ERAM_SIZE 0x01000000
+#define ERAM_SIZE 0x02000000
 
 /* for <asm/page.h> */
 #define PAGE_OFFSET ERAM_ADDR