Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

MIPS: Loongson 2F: Fix of problems introduced by -mfix-loongson2f-jump

The -mfix-loongson2f-jump option provided by latest CVS binutils have fixed
the out-of-order issue of Loongson-2F described in chapter 15 of the
Loongson2F User Manual [1, 2], but introduced some problems.

The option changes all of the jump target to "addr & 0xcfffffff" through the
at($1) register, but for the reboot address of Loongson 2F 0xbfc00000 this is
wrong. Avoids the problem via telling the assembler to not use the $at
register.

[1] Loongson2F User Manual (Chinese Version)
http://www.loongson.cn/uploadfile/file/200808211
[2] English Version of Chapter 15:
http://groups.google.com.hk/group/loongson-dev/msg/e0d2e220958f10a6?dmode=source

Reported-and-tested-by: Liu Shiwei <liushiwei@gmail.com>
Signed-off-by: Wu Zhangjin <wuzhangjin@gmail.com>
Cc: linux-mips <linux-mips@linux-mips.org>
Patchwork: http://patchwork.linux-mips.org/patch/1109/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>

authored by

Wu Zhangjin and committed by
Ralf Baechle
64fc74f5 b197b628

+19 -1
+19 -1
arch/mips/loongson/common/reset.c
··· 16 16 17 17 #include <loongson.h> 18 18 19 + static inline void loongson_reboot(void) 20 + { 21 + #ifndef CONFIG_CPU_JUMP_WORKAROUNDS 22 + ((void (*)(void))ioremap_nocache(LOONGSON_BOOT_BASE, 4)) (); 23 + #else 24 + void (*func)(void); 25 + 26 + func = (void *)ioremap_nocache(LOONGSON_BOOT_BASE, 4); 27 + 28 + __asm__ __volatile__( 29 + " .set noat \n" 30 + " jr %[func] \n" 31 + " .set at \n" 32 + : /* No outputs */ 33 + : [func] "r" (func)); 34 + #endif 35 + } 36 + 19 37 static void loongson_restart(char *command) 20 38 { 21 39 /* do preparation for reboot */ 22 40 mach_prepare_reboot(); 23 41 24 42 /* reboot via jumping to boot base address */ 25 - ((void (*)(void))ioremap_nocache(LOONGSON_BOOT_BASE, 4)) (); 43 + loongson_reboot(); 26 44 } 27 45 28 46 static void loongson_poweroff(void)