diff options
author | Wu Zhangjin <wuzhangjin@gmail.com> | 2009-09-11 12:52:28 +0800 |
---|---|---|
committer | Wu Zhangjin <wuzhangjin@gmail.com> | 2010-03-10 04:39:10 +0800 |
commit | 1699e9f1ed3c9a63920bfe26fef22e8dd69a3fdf (patch) | |
tree | 344009d883af29ef20011b109eabe629fb786386 /arch | |
parent | 555eed89f0c42c9f3f9f2a38cfbfc0a1a21c81ba (diff) | |
download | lwn-1699e9f1ed3c9a63920bfe26fef22e8dd69a3fdf.tar.gz lwn-1699e9f1ed3c9a63920bfe26fef22e8dd69a3fdf.zip |
Loongson-2F: Fixup of problems introduced by -mfix-loongson2f-jump of binutils 2.20.1
The -mfix-loongson2f-jump option provided by the binutils 2.20.1 have fixed the
Out-of-order Issue of Loongson-2F described in Chapter 15 of "Loongson2F User
Manual"[1,2], but introduced some problems.
The option changes all of the jumping target to "addr & 0xcfffffff" through the
at($1) register, but for the REBOOT address of loongson-2F: 0xbfc00000, this is
totally wrong, so, this patch try to avoid the problem via telling the
assembler not to use at($1) 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>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/mips/loongson/common/reset.c | 12 |
1 files changed, 11 insertions, 1 deletions
diff --git a/arch/mips/loongson/common/reset.c b/arch/mips/loongson/common/reset.c index d57f1719da95..dd66f2ede42a 100644 --- a/arch/mips/loongson/common/reset.c +++ b/arch/mips/loongson/common/reset.c @@ -21,8 +21,18 @@ static void loongson_restart(char *command) /* do preparation for reboot */ mach_prepare_reboot(); - /* reboot via jumping to boot base address */ + /* reboot via jumping to boot base address + * + * ".set noat" and ".set at" are used to ensure the address not broken + * by the -mfix-loongson2f-jump option provided by binutils 2.20.1 and + * higher which try to change the jumping address to "addr & + * 0xcfffffff" via the at($1) register, this is totally wrong for + * 0xbfc00000(LOONGSON_BOOT_BASE). + */ + + __asm__ __volatile__(".set noat\n"); ((void (*)(void))ioremap_nocache(LOONGSON_BOOT_BASE, 4)) (); + __asm__ __volatile__(".set at\n"); } static void loongson_halt(void) |