Commit 2db4bc34 authored by Maciej W. Rozycki's avatar Maciej W. Rozycki Committed by Ralf Baechle

MIPS: __delay CPU_DADDI_WORKAROUNDS bug fix

With CPU_DADDI_WORKAROUNDS enabled __delay assembles with a macro in a
branch delay slot:

{standard input}: Assembler messages:
{standard input}:18: Warning: Macro instruction expanded into multiple
instructions in a branch delay slot

and broken code results:

0000000000000000 <__delay>:
   0:	1480ffff 	bnez	a0,0 <__delay>
   4:	24010001 	li	at,1
   8:	0081202f 	dsubu	a0,a0,at
   c:	03e00008 	jr	ra
  10:	00000000 	nop
  14:	00000000 	nop

Consequently the function loops indefinitely, showing up prominently as a
hang in the delay loop calibration at bootstrap.

This change corrects the problem by forcing the immediate 1 into a
register while keeping code produced identical where CPU_DADDI_WORKAROUNDS
is disabled.
Signed-off-by: default avatarMaciej W. Rozycki <macro@linux-mips.org>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/6669/Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
parent 824122a3
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Copyright (C) 1994 by Waldorf Electronics * Copyright (C) 1994 by Waldorf Electronics
* Copyright (C) 1995 - 2000, 01, 03 by Ralf Baechle * Copyright (C) 1995 - 2000, 01, 03 by Ralf Baechle
* Copyright (C) 1999, 2000 Silicon Graphics, Inc. * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
* Copyright (C) 2007 Maciej W. Rozycki * Copyright (C) 2007, 2014 Maciej W. Rozycki
*/ */
#include <linux/module.h> #include <linux/module.h>
#include <linux/param.h> #include <linux/param.h>
...@@ -15,6 +15,12 @@ ...@@ -15,6 +15,12 @@
#include <asm/compiler.h> #include <asm/compiler.h>
#include <asm/war.h> #include <asm/war.h>
#ifndef CONFIG_CPU_DADDI_WORKAROUNDS
#define GCC_DADDI_IMM_ASM() "I"
#else
#define GCC_DADDI_IMM_ASM() "r"
#endif
void __delay(unsigned long loops) void __delay(unsigned long loops)
{ {
__asm__ __volatile__ ( __asm__ __volatile__ (
...@@ -22,13 +28,13 @@ void __delay(unsigned long loops) ...@@ -22,13 +28,13 @@ void __delay(unsigned long loops)
" .align 3 \n" " .align 3 \n"
"1: bnez %0, 1b \n" "1: bnez %0, 1b \n"
#if BITS_PER_LONG == 32 #if BITS_PER_LONG == 32
" subu %0, 1 \n" " subu %0, %1 \n"
#else #else
" dsubu %0, 1 \n" " dsubu %0, %1 \n"
#endif #endif
" .set reorder \n" " .set reorder \n"
: "=r" (loops) : "=r" (loops)
: "0" (loops)); : GCC_DADDI_IMM_ASM() (1), "0" (loops));
} }
EXPORT_SYMBOL(__delay); EXPORT_SYMBOL(__delay);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment