diff options
author | Wu Zhangjin <wuzhangjin@gmail.com> | 2010-04-10 08:07:13 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2010-04-30 15:52:58 -0400 |
commit | 64fc74f5f6055e8470208a7d9cfc8d3994fff34d (patch) | |
tree | c8f744047cfd6403fa12cc5719868d7cce55c799 /arch/mips/loongson | |
parent | b197b6286650feb9c991826519065aac6f4399b1 (diff) |
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>
Diffstat (limited to 'arch/mips/loongson')
-rw-r--r-- | arch/mips/loongson/common/reset.c | 20 |
1 files changed, 19 insertions, 1 deletions
diff --git a/arch/mips/loongson/common/reset.c b/arch/mips/loongson/common/reset.c index 4bd9c18b07a5..9e10d6225d9b 100644 --- a/arch/mips/loongson/common/reset.c +++ b/arch/mips/loongson/common/reset.c | |||
@@ -16,13 +16,31 @@ | |||
16 | 16 | ||
17 | #include <loongson.h> | 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 | static void loongson_restart(char *command) | 37 | static void loongson_restart(char *command) |
20 | { | 38 | { |
21 | /* do preparation for reboot */ | 39 | /* do preparation for reboot */ |
22 | mach_prepare_reboot(); | 40 | mach_prepare_reboot(); |
23 | 41 | ||
24 | /* reboot via jumping to boot base address */ | 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 | static void loongson_poweroff(void) | 46 | static void loongson_poweroff(void) |