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

Re: [microblaze-uclinux] [patch test] syscall interface cleanup



I wrote:

> I'll send the fixed version shortly, with the r14 and exception/trap 
> vector changes included.

Updated patch files attached, all comments welcome.

Kernel patch:

  - system call entry now achieved with BRKI r14, 0x8 instruction
  - debug trap entry now achieved with BRKI r14, 0x30.
  - debug vector changed to 0x30 (from 0x18) to avoid clashing with NMI 
and hardware breaks.

uClibc patch:
  - changes libc/sysdeps/linux/microblaze/ {syscall|clone|vfork} files 
to reflect new syscall entry mechanism (BRKI r14, 0x8)

Regards,

John

diff -Naur -x '.*' -x '*CVS*' -x '*.o' -x '*.a' /opt/src/uClinux-2.4.x/arch/microblaze/kernel/entry.S linux-2.4.x/arch/microblaze/kernel/entry.S
--- /opt/src/uClinux-2.4.x/arch/microblaze/kernel/entry.S	2004-10-14 04:27:47.000000000 +1000
+++ linux-2.4.x/arch/microblaze/kernel/entry.S	2004-10-16 14:27:36.000000000 +1000
@@ -38,7 +38,9 @@
 
 #define ENTRY_EI(scratch_reg)                                                 \
 	msrset scratch_reg, 0x2;
+
 #else
+
 #define ENTRY_CLI(scratch_reg)                                                \
         mfs     scratch_reg, rmsr;                                            \
         andi    scratch_reg, scratch_reg, ~2;                                 \
@@ -50,6 +52,40 @@
 	mts     rmsr, scratch_reg;
 #endif
 
+/* Various ways of setting and clearing BIP in flags reg.  This is mucky, but
+   necessary */
+#ifdef CONFIG_MICROBLAZE_BIPDIRECT
+  /* using microblaze version that allows msr ops to write to BIP */
+  #ifdef CONFIG_MICROBLAZE_MSRSETCLR
+	#define BIPCLR(scratch_reg)				      \
+		msrclr 	scratch_reg, 0x8;
+
+	#define BIPSET(scratch_reg)				      \
+		msrset	scratch_reg, 0x8;
+  #else
+	#define BIPCLR(scratch_reg)				      \
+		mfs	scratch_reg, rmsr;				      \
+		andi	scratch_reg, scratch_reg, ~0x8;			      \
+		mts	rmsr, scratch_reg;
+
+	#define BIPSET(scratch_reg)				      \
+		mfs	scratch_reg, rmsr;				      \
+		ori	scratch_reg, scratch_reg, 0x8;			      \
+		mts	rmsr, scratch_reg;
+  #endif
+#else
+  /* Older microblaze version that prevents direct access to BIP bit 
+     We hack around it using the rtbd and brki instructions */
+	#define BIPCLR(scratch_reg)					      \
+		rtbd	r0, 1f;						      \
+		nop;							      \
+	   1:
+
+	#define BIPSET(scratch_reg)					      \
+		brki	r0, 1f;						      \
+	   1:
+#endif
+	
 /* Standard macros to save and restore regs in the pt_regs struct pointed
    to by the stack pointer (r1) */
 #define SAVE_REG(reg_num) \
@@ -184,9 +220,9 @@
 /* Save system registers to the struct pt_regs pointed to by REG.  
    r11 is clobbered.  */
 #define SAVE_SYS_REGS_FOR_TRAP						      \
-	swi	r17, r1, PTO+PT_PC;	/* user's PC, before trap*/	      \
+	swi	r14, r1, PTO+PT_PC;	/* user's PC, before trap*/	      \
 	mfs	r11, rmsr;	/* & PSW (XXX save this?) */		      \
-	andi	r11, r11, ~8;	/* Don't save BIP bit in user state */	      \
+	ori	r11, r11, 0x2;		/* Ensure ints enabled on exit */     \
 	swi	r11, r1, PTO+PT_PSW;	
 
 /* Restore system registers from the struct pt_regs pointed to by EP.         
@@ -194,14 +230,14 @@
 #define RESTORE_SYS_REGS_FOR_TRAP					      \
 	lwi	r11, r1, PTO+PT_PSW;	/* Processor status word */	      \
 	mts	rmsr, r11;						      \
-	lwi	r17, r1, PTO+PT_PC;	/* User's PC before trap */      
+	lwi	r14, r1, PTO+PT_PC;	/* User's PC before trap */      
 
 /* Save system registers to the struct pt_regs pointed to by REG.  
    r11 is clobbered.  */
 #define SAVE_SYS_REGS_FOR_DBTRAP					      \
-	swi	r17, r1, PTO+PT_PC;	/* user's PC, before trap*/	      \
+	swi	r14, r1, PTO+PT_PC;	/* user's PC, before trap*/	      \
 	mfs	r11, rmsr;	/* & PSW (XXX save this?) */		      \
-	andi	r11, r11, ~8;	/* Don't save BIP bit */		      \
+	ori	r11, r11, 0x2;		/* Ensure ints enabled on exit */     \
 	swi	r11, r1, PTO+PT_PSW;	
 
 /* Restore system registers from the struct pt_regs pointed to by EP.         
@@ -209,13 +245,13 @@
 #define RESTORE_SYS_REGS_FOR_DBTRAP					      \
 	lwi	r11, r1, PTO+PT_PSW;	/* Processor status word */	      \
 	mts	rmsr, r11;						      \
-	lwi	r17, r1, PTO+PT_PC;	/* User's PC before trap */      
+	lwi	r14, r1, PTO+PT_PC;	/* User's PC before trap */      
 
 /* Save system registers to the struct pt_regs pointed to by REG.  This is a
    NMI-specific version, because NMIs save the PC/PSW in a different place
    than other interrupt requests.  r11 is clobbered.  */
 #define SAVE_SYS_REGS_FOR_NMI						      \
-	swi	r14, r1, PTO+PT_PC;	/* user's PC, before NMI */	      \
+	swi	r16, r1, PTO+PT_PC;	/* user's PC, before NMI */	      \
 	mfs	r11, rmsr;						      \
 	swi	r11, r1, PTO+PT_PSW;
 
@@ -466,16 +502,17 @@
 	nop;			/* Delay slot */		      
 
 /* Instructions to return from a trap */
-/* Note we use rtid to force interrupts back on */
+/* Note we use rtbd to clear BIP bit on way out */
+/* Return offset is 4, to execute instruction after syscall brki insn*/
 #define TRAP_RETURN_INST						      \
-	rtid	r17, 8;		/* r17 used as trap link register */	      \
+	rtbd	r14, 4;		/* r14 used as trap link register */	      \
 	nop;
 
 /* Instructions to return from a debug trap */
 /* Note we use rtbd to clear BIP bit on exit */
 /* Return offset is zero, to ensure trapped instruction is re-executed */
 #define DBTRAP_RETURN_INST						      \
-	rtbd	r17, 0;		/* r17 used as trap link register */	      \
+	rtbd	r14, 0;		/* r14 used as trap link register */	      \
 	nop;
 
 /* Code fragment to return from NMI */
@@ -520,10 +557,12 @@
 	swi	r1, r0, KSP;		/* Save the kernel stack pointer. */  \
 	lwi	r1, r1, PT_GPR(GPR_SP)-PT_SIZE;				      \
 					/* Restore user stack pointer. */     \
-	type ## _RETURN_INST  		/* Perform appropriate return */      \
+	bri	6f;							      \
 									      \
 /* Return to kernel state.  */						      \
 2:	POP_STATE(type);						      \
+6:									      \
+type ## _return:		/* Make global symbol for debugging */	      \
 	type ## _RETURN_INST						      \
 									      \
 /* Call the scheduler before returning from a syscall/trap. */		      \
@@ -567,7 +606,7 @@
 	/* Note Microblaze barrel shift is optional, so don't rely on it */   \
 	add	r12, r12, r12;			/* convert num -> ptr */      \
 	add	r12, r12, r12;						      \
-	lwi	r12, r12, CSYM(sys_call_table);	/* Get function pointer */		      \
+	lwi	r12, r12, CSYM(sys_call_table);	/* Get function pointer */    \
 	/* Make the system call.  */					      \
 	bra	r12;							      \
 	/* The syscall number is invalid, return an error.  */		      \
@@ -588,28 +627,23 @@
  *
  * System calls are handled here.
  *
- * The stack-pointer (r1) should have already been saved to the memory
- * location ENTRY_SP (the reason for this is that the interrupt vectors may be
- * beyond a 22-bit signed offset jump from the actual interrupt handler, and
- * this allows them to save the stack-pointer and use that register to do an
- * indirect jump).
- *	
  * Syscall protocol:
  *   Syscall number in r12, args in r5-r10
  *   Return value in r3
+ *
+ * Trap entered via brki instruction, so BIP bit is set, and interrupts
+ * are masked.  This is nice, means we don't have to CLI before state save
+ * however we do have to do a special trick (rtbd) to clear BIP bit
+ * we also re-enable BIP bit prior to exit state save
  */
 G_ENTRY(trap):
-	ENTRY_CLI(r11);
 	swi	r1, r0, ENTRY_SP;	// save stack (emulate v850)
 	SAVE_STATE (TRAP, r12, ENTRY_SP) // Save registers. 
-	// No need to enable intrs here because microblaze
-	// traps just implemented as a branch, not a hardware trap
-	ENTRY_EI(r11);
+	BIPCLR(r11);			// Clear BIP
+					// BIP now cleared, interrupts enabled
 	la	r15, r0, ret_from_trap-8// where the trap should return
 					// need -8 to adjust for rtsd r15, 8
-
 	MAKE_SYS_CALL			// Jump to the syscall function. 
-
 END(trap)
 
 /* This is just like ret_from_trap, but first restores extra registers
@@ -620,7 +654,9 @@
 END(restore_extra_regs_and_ret_from_trap)
 
 /* Entry point used to return from a syscall/trap.  */
+/* We re-enable BIP bit before state restore */
 L_ENTRY(ret_from_trap):
+	BIPSET(r11);
 	RETURN(TRAP)
 END(ret_from_trap)
 
@@ -836,7 +872,7 @@
 
 /*
  * `Debug' trap
- *  We enter dbtrap in "BIP" (breakpoint) mode. That is bad for us.
+ *  We enter dbtrap in "BIP" (breakpoint) mode. 
  *  So we exit the breakpoint mode with an 'rtbd' and proceed with the
  *  original dbtrap.
  *  however, wait to save state first
@@ -845,9 +881,7 @@
 	/* BIP bit is set on entry, no interrupts can occur */
 	swi	r1, r0, ENTRY_SP;	// Save stack (emulate v850)
 	SAVE_STATE (DBTRAP, r0, ENTRY_SP)   // Save registers. 
-	rtbd	r16, dbtrap_o;
-	nop;
-dbtrap_o:
+	BIPCLR(r11);
 	/* BIP bit now clear, interrupts can occur */
 	// Should insert code to detect illegal traps etc
 
@@ -862,13 +896,44 @@
 
 	/* Do a "null brk" to force BIP bit on, thus masking interrupts during
 	   state restore.  dbtrap ends with rtbd to clear this */
-	brki	r0, dbtrap_1;
-dbtrap_1:
+	BIPSET(r11);
 	RETURN(DBTRAP);
 
 END(dbtrap)
 
 /*
+ * `HW exception' trap
+ *  We enter dbtrap in "BIP" (breakpoint) mode. 
+ *  So we exit the breakpoint mode with an 'rtbd' and proceed with the
+ *  original dbtrap.
+ *  however, wait to save state first
+ */
+#if 0
+G_ENTRY(hw_ex):
+	/* BIP bit is set on entry, no interrupts can occur */
+	swi	r1, r0, ENTRY_SP;	// Save stack (emulate v850)
+	SAVE_STATE (DBTRAP, r0, ENTRY_SP)   // Save registers. 
+	BIPCLR(r11);			// Clear BIP, r11 is scfratch register
+	/* BIP bit now clear, interrupts can occur */
+	// Should insert code to detect illegal traps etc
+
+	// For now, call into kernel for debugging
+	brlid	r15, CSYM(debug_trap);
+	la	r5, r1, PTO
+
+	// addi	r5, r0, SIGTRAP;	// send the trap signal
+	// RETRIEVE_CURRENT_TASK(r6);	// to the current task
+	// brlid	r15, CSYM(send_sig);
+	// nop;
+
+	/* Do a "null brk" to force BIP bit on, thus masking interrupts during
+	   state restore.  dbtrap ends with rtbd to clear this */
+	BIPSET(r11);			// set BIP, r11 is scratch register 
+	RETURN(DBTRAP);
+
+END(hw_ex)
+#endif
+/*
  * Trap with no handler
  */
 L_ENTRY(bad_trap_wrapper):
diff -Naur -x '.*' -x '*CVS*' -x '*.o' -x '*.a' /opt/src/uClinux-2.4.x/arch/microblaze/kernel/intv.S linux-2.4.x/arch/microblaze/kernel/intv.S
--- /opt/src/uClinux-2.4.x/arch/microblaze/kernel/intv.S	2004-07-08 16:07:01.000000000 +1000
+++ linux-2.4.x/arch/microblaze/kernel/intv.S	2004-10-15 20:34:53.000000000 +1000
@@ -21,13 +21,23 @@
 	   copied into place in mach_early_setup */
 	.section	.intv.common, "ax"
 	.org	0x0
-	brai	C_SYMBOL_NAME(start);	// Kernel entry point (0x00)
+	brai	C_SYMBOL_NAME(start);	// Kernel entry point
 
 	.org	0x08
-	brai	C_SYMBOL_NAME(trap);	// Exception handler  (0x08)
+	brai	C_SYMBOL_NAME(trap);	// syscall handler
 
 	.org	0x10
-	brai	C_SYMBOL_NAME(irq);	// Interrupt handler  (0x10)
+	brai	C_SYMBOL_NAME(irq);	// Interrupt handler
 
 	.org	0x18
-	brai	C_SYMBOL_NAME(dbtrap);	// debug trap handler (0x18)
+	brai	C_SYMBOL_NAME(nmi);	// nmi trap handler
+
+	.org	0x20
+	//brai	C_SYMBOL_NAME(hw_ex);	// HW exception handler
+
+	.org	0x28
+	//brai	C_SYMBOL_NAME(mmu_ex);	// MMU exception
+
+	.org	0x30
+	brai	C_SYMBOL_NAME(dbtrap);	// debug trap handler
+
diff -Naur -x '.*' -x '*CVS*' -x '*.o' -x '*.a' /opt/src/uClinux-2.4.x/arch/microblaze/kernel/process.c linux-2.4.x/arch/microblaze/kernel/process.c
--- /opt/src/uClinux-2.4.x/arch/microblaze/kernel/process.c	2004-07-08 16:07:01.000000000 +1000
+++ linux-2.4.x/arch/microblaze/kernel/process.c	2004-10-15 15:52:14.000000000 +1000
@@ -135,7 +135,7 @@
 	/* Clone this thread.  */
 	arg0 = flags | CLONE_VM;
 	syscall = __NR_clone;
-	asm volatile ("	bralid r17, 0x8; nop;"
+	asm volatile ("	brki	r14, 0x8;"
 		        : "=r" (ret) 
 			: "r" (syscall), "r" (arg0)
 		        : SYSCALL_CLOBBERS);
@@ -145,7 +145,7 @@
 		/* In child thread, call FN and exit.  */
 		arg0 = (*fn) (arg);
 		syscall = __NR_exit;
-		asm volatile ("bralid r17, 0x8; nop;"
+		asm volatile ("brki	r14, 0x8"
 			        : "=r" (ret) 
 				: "r" (syscall), "r" (arg0)
 			        : SYSCALL_CLOBBERS);
diff -Naur -x '.*' -x '*CVS*' -x '*.o' -x '*.a' /opt/src/uClinux-2.4.x/arch/microblaze/kernel/signal.c linux-2.4.x/arch/microblaze/kernel/signal.c
--- /opt/src/uClinux-2.4.x/arch/microblaze/kernel/signal.c	2004-07-08 16:07:01.000000000 +1000
+++ linux-2.4.x/arch/microblaze/kernel/signal.c	2004-10-15 15:59:25.000000000 +1000
@@ -1,6 +1,7 @@
 /*
- * arch/v850/kernel/signal.c -- Signal handling
+ * arch/microblaze/kernel/signal.c -- Signal handling
  *
+ *  Copyright (C) 2003,2004  John Williams <jwilliams@itee.uq.edu.au>
  *  Copyright (C) 2001  NEC Corporation
  *  Copyright (C) 2001  Miles Bader <miles@gnu.org>
  *  Copyright (C) 1999,2000  Niibe Yutaka & Kaz Kojima
@@ -349,10 +350,8 @@
 		/* addi  r12, r0, __NR_sigreturn  */
 		err |= __put_user(0x31800000 | __NR_sigreturn ,
 				  frame->tramp + 0);
-		/* bralid r17, 0x8 */
-		err |= __put_user(0xba3c0008, frame->tramp + 1);
-		/* nop; */
-		err |= __put_user(0x80000000, frame->tramp + 2);
+		/* brki r14, 0x8 */
+		err |= __put_user(0xb9cc0008, frame->tramp + 1);
 
 		regs->gpr[GPR_LP] = (unsigned long)frame->tramp-8;
 
@@ -365,8 +364,8 @@
 	/* Set up registers for signal handler */
 	regs->gpr[GPR_SP] = (unsigned long) frame;
 	regs->gpr[GPR_ARG0] = signal; /* Arg for signal handler */
-	/* Offset of 8 to handle microblaze return wierdness */
-	regs->pc = (unsigned long) ka->sa.sa_handler-8;
+	/* Offset of 4 to handle microblaze rtbd r14, 4 */
+	regs->pc = (unsigned long) ka->sa.sa_handler-4;
 
 	set_fs(USER_DS);
 
@@ -423,15 +422,11 @@
 	if (ka->sa.sa_flags & SA_RESTORER) {
 		regs->gpr[GPR_LP] = (unsigned long) ka->sa.sa_restorer-8;
 	} else {
-		/* Note, these encodings are _big endian_!  */
-
 		/* addi  r12, r0, __NR_sigreturn  */
 		err |= __put_user(0x31800000 | __NR_sigreturn ,
 				  frame->tramp + 0);
-		/* bralid r17, 0x8 */
-		err |= __put_user(0xba3c0008, frame->tramp + 1);
-		/* nop; */
-		err |= __put_user(0x80000000, frame->tramp + 2);
+		/* brki r14, 0x8 */
+		err |= __put_user(0xb9cc0008, frame->tramp + 1);
 
 		regs->gpr[GPR_LP] = (unsigned long)frame->tramp-8;
 
@@ -444,8 +439,8 @@
 	/* Set up registers for signal handler */
 	regs->gpr[GPR_SP] = (unsigned long) frame;
 	regs->gpr[GPR_ARG0] = signal; /* Arg for signal handler */
-	/* Offset to handle microblaze return offset wierdness */
-	regs->pc = (unsigned long) ka->sa.sa_handler-8;
+	/* Offset to handle microblaze rtbd r14, 4 */
+	regs->pc = (unsigned long) ka->sa.sa_handler-4;
 
 	set_fs(USER_DS);
 
@@ -486,11 +481,11 @@
 			/* fallthrough */
 			case -ERESTARTNOINTR:
 				regs->gpr[12] = PT_REGS_SYSCALL (regs);
-				/* offset of 12 bytes required = 8 for rtsd
+				/* offset of 8 bytes required = 4 for rtbd
 				   offset, plus 4 for size of 
-					"bralid r17,8"
+					"brki r14,8"
 				   instruction. */
-				regs->pc -= 12; 
+				regs->pc -= 8; 
 		}
 
 		PT_REGS_SET_SYSCALL (regs, 0);
@@ -647,7 +642,7 @@
 		    regs->gpr[GPR_RVAL] == -ERESTARTSYS ||
 		    regs->gpr[GPR_RVAL] == -ERESTARTNOINTR) {
 			regs->gpr[12] = PT_REGS_SYSCALL (regs);
-			regs->pc -= 12; /* 4 + 8 for microblaze return offset wierdness */
+			regs->pc -= 8; /* 4 + 8 for microblaze return offset wierdness */
 		}
 	}
 	return 0;
diff -Naur -x '.*' -x '*CVS*' -x '*.o' -x '*.a' /opt/src/uClinux-2.4.x/include/asm-microblaze/unistd.h linux-2.4.x/include/asm-microblaze/unistd.h
--- /opt/src/uClinux-2.4.x/include/asm-microblaze/unistd.h	2004-07-08 16:08:28.000000000 +1000
+++ linux-2.4.x/include/asm-microblaze/unistd.h	2004-10-15 15:55:33.000000000 +1000
@@ -238,7 +238,7 @@
 
    System calls are achieved by branching to absolute address 0x8, 
    the exception handler.  Microblaze doesn't currently use exceptions
-   so we take them over.  Contrary to the Microblaze ABI, we use r17
+   so we take them over.  Contrary to the Microblaze ABI, we use r14
    as the exception/trap return link address.  This is due to the
    structure of entry.S, which uses common return code for traps and
    interrupts.  This probably reflects some architectural stuff about 
@@ -254,15 +254,17 @@
 #define SYSCALL_ARG5	"r10"
 #define SYSCALL_RET	"r3"
 
+/* Backwards compatability for old dodgy way of doing syscalls with bralid.
+   As soon as possible, all targets must migrate to using brki instruction */
+
 #define SYSCALL_ENTRY_POINT C_SYMBOL_NAME(syscall_entry)
 
 /*
  * Registers clobbered by a syscall.
- * Since we are using brach to implement syscall,
  * all volatile registers, except r5-r10, must be in the clobbered list.
  * r5-r10 should be in input list.
  */
-#define SYSCALL_CLOBBERS	"cc", "r3", "r4", "r11", "r12", "r17"
+#define SYSCALL_CLOBBERS	"cc", "r3", "r4", "r11", "r12", "r14"
 
 #define __syscall_return(type, res)			 		\
 do {									\
@@ -279,8 +281,8 @@
 type name (void)							\
 {									\
 	long __ret;							\
-	__asm__ __volatile__ ("bralid	r17, 0x8	\n\t"		\
-			      "addik	r12, r0, %1	\n\t"		\
+	__asm__ __volatile__ ("addik	r12, r0, %1	\n\t"		\
+			      "brki	r14, 0x8	\n\t"		\
 			      "addk	%0, r3, r0	\n\t"		\
 			      : "=r" (__ret)				\
 			      : "i" (__NR_##name)			\
@@ -293,8 +295,8 @@
 {									\
 	long __ret;							\
 	__asm__ __volatile__ ("addk	r5, r0, %2	\n\t"		\
-			      "bralid	r17, 0x8	\n\t"		\
 			      "addik	r12, r0, %1	\n\t"		\
+			      "brki	r14, 0x8	\n\t"		\
 			      "addk	%0, r3, r0	\n\t"		\
 			      : "=r" (__ret)				\
 			      : "i" (__NR_##name),			\
@@ -309,8 +311,8 @@
 	long __ret;							\
 	__asm__ __volatile__ ("addk	r5, r0, %2	\n\t"		\
 			      "addk	r6, r0, %3	\n\t"	   	\
-			      "bralid	r17, 0x8	\n\t"	   	\
 			      "addik	r12, r0, %1	\n\t"	   	\
+			      "brki	r14, 0x8	\n\t"	   	\
 			      "addk	%0, r3, r0	\n\t"	   	\
 			      : "=r" (__ret)			    	\
 			      : "i" (__NR_##name),		      	\
@@ -327,8 +329,8 @@
 	__asm__ __volatile__ ("addk	r5, r0, %2	\n\t"	   	\
 			      "addk	r6, r0, %3	\n\t"	   	\
 			      "addk	r7, r0, %4	\n\t"	   	\
-			      "bralid	r17, 0x8	\n\t"	   	\
 			      "addik	r12, r0, %1	\n\t"	   	\
+			      "brki	r14, 0x8	\n\t"	   	\
 			      "addk	%0, r3, r0	\n\t"	   	\
 			      : "=r" (__ret)			    	\
 			      : "i" (__NR_##name),		      	\
@@ -347,8 +349,8 @@
 			      "addk	r6, r0, %3	\n\t"	   	\
 			      "addk	r7, r0, %4	\n\t"	   	\
 			      "addk	r8, r0, %5	\n\t"	   	\
-			      "bralid	r17, 0x8	\n\t"	   	\
 			      "addik	r12, r0, %1	\n\t"	   	\
+			      "brki	r14, 0x8	\n\t"	   	\
 			      "addk	%0, r3, r0	\n\t"	   	\
 			      : "=r" (__ret)			    	\
 			      : "i" (__NR_##name),		      	\
@@ -369,8 +371,8 @@
 			      "addk	r7, r0, %4	\n\t"	   	\
 			      "addk	r8, r0, %5	\n\t"	   	\
 			      "addk	r9, r0, %6	\n\t"	   	\
-			      "bralid	r17, 0x8	\n\t"	   	\
 			      "addik	r12, r0, %1	\n\t"	   	\
+			      "brki	r14, 0x8	\n\t"	   	\
 			      "addk	%0, r3, r0	\n\t"	   	\
 			      : "=r" (__ret)			    	\
 			      : "i" (__NR_##name),		      	\
@@ -393,8 +395,8 @@
 			      "addk	r8, r0, %5	\n\t"	   	\
 			      "addk	r9, r0, %6	\n\t"	   	\
 			      "addk	r10, r0, %7	\n\t"	   	\
-			      "bralid	r17, 0x8	\n\t"	   	\
 			      "addik	r12, r0, %1	\n\t"	   	\
+			      "brki	r14, 0x8	\n\t"	   	\
 			      "addk	%0, r3, r0	\n\t"	   	\
 			      : "=r" (__ret)			    	\
 			      : "i" (__NR_##name),		      	\
diff -Naur -x '.*' -x '*CVS*' -x '*.o' -x '*.a' /opt/src/uClinux-dist/uClibc/libc/sysdeps/linux/microblaze/clone.c uClibc/libc/sysdeps/linux/microblaze/clone.c
--- /opt/src/uClinux-dist/uClibc/libc/sysdeps/linux/microblaze/clone.c	2004-07-08 16:10:54.000000000 +1000
+++ uClibc/libc/sysdeps/linux/microblaze/clone.c	2004-10-15 15:59:59.000000000 +1000
@@ -31,7 +31,7 @@
       arg0 = flags;
       arg1 = (unsigned long)child_stack;
       syscall = __NR_clone;
-      asm volatile ("bralid r17, 0x08;nop;" 
+      asm volatile ("brki	r14, 0x08;" 
 		    : "=r" (rval), "=r" (syscall)
 		    : "1" (syscall), "r" (arg0), "r" (arg1)
 		    : SYSCALL_CLOBBERS);
@@ -41,7 +41,7 @@
 	{
 	  arg0 = (*fn) (arg);
 	  syscall = __NR_exit;
-	  asm volatile ("bralid r17, 0x08;nop;" 
+	  asm volatile ("brki	r14, 0x08;" 
 			: "=r" (rval), "=r" (syscall)
 			: "1" (syscall), "r" (arg0)
 			: SYSCALL_CLOBBERS);
diff -Naur -x '.*' -x '*CVS*' -x '*.o' -x '*.a' /opt/src/uClinux-dist/uClibc/libc/sysdeps/linux/microblaze/syscall.c uClibc/libc/sysdeps/linux/microblaze/syscall.c
--- /opt/src/uClinux-dist/uClibc/libc/sysdeps/linux/microblaze/syscall.c	2004-07-08 16:10:54.000000000 +1000
+++ uClibc/libc/sysdeps/linux/microblaze/syscall.c	2004-10-15 16:00:05.000000000 +1000
@@ -36,7 +36,7 @@
   register unsigned long ret asm (SYSCALL_RET);
 	unsigned long ret_sav;
 
-  asm ("bralid r17, 0x08; nop;" 
+  asm ("brki	r14, 0x08" 
        : "=r" (ret)
        : "r" (syscall), "r" (a), "r" (b), "r" (c), "r" (d), "r" (e), "r" (f)
        : SYSCALL_CLOBBERS);
diff -Naur -x '.*' -x '*CVS*' -x '*.o' -x '*.a' /opt/src/uClinux-dist/uClibc/libc/sysdeps/linux/microblaze/vfork.S uClibc/libc/sysdeps/linux/microblaze/vfork.S
--- /opt/src/uClinux-dist/uClibc/libc/sysdeps/linux/microblaze/vfork.S	2004-07-08 16:10:54.000000000 +1000
+++ uClibc/libc/sysdeps/linux/microblaze/vfork.S	2004-10-15 16:00:15.000000000 +1000
@@ -29,8 +29,7 @@
 
 C_ENTRY (__vfork):
 	addi	r12, r0, SYS_vfork
-	bralid	r17, 0x08;
-	nop
+	brki	r14, 0x08;
 	addi	r4, r3, 125		// minimum err value
 	blti	r4, 1f			// is r3 < -125?
 	rtsd	r15, 8			// normal return