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>
This commit is contained in:
Родитель
b197b62866
Коммит
64fc74f5f6
|
@ -16,13 +16,31 @@
|
||||||
|
|
||||||
#include <loongson.h>
|
#include <loongson.h>
|
||||||
|
|
||||||
|
static inline void loongson_reboot(void)
|
||||||
|
{
|
||||||
|
#ifndef CONFIG_CPU_JUMP_WORKAROUNDS
|
||||||
|
((void (*)(void))ioremap_nocache(LOONGSON_BOOT_BASE, 4)) ();
|
||||||
|
#else
|
||||||
|
void (*func)(void);
|
||||||
|
|
||||||
|
func = (void *)ioremap_nocache(LOONGSON_BOOT_BASE, 4);
|
||||||
|
|
||||||
|
__asm__ __volatile__(
|
||||||
|
" .set noat \n"
|
||||||
|
" jr %[func] \n"
|
||||||
|
" .set at \n"
|
||||||
|
: /* No outputs */
|
||||||
|
: [func] "r" (func));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
static void loongson_restart(char *command)
|
static void loongson_restart(char *command)
|
||||||
{
|
{
|
||||||
/* do preparation for reboot */
|
/* do preparation for reboot */
|
||||||
mach_prepare_reboot();
|
mach_prepare_reboot();
|
||||||
|
|
||||||
/* reboot via jumping to boot base address */
|
/* reboot via jumping to boot base address */
|
||||||
((void (*)(void))ioremap_nocache(LOONGSON_BOOT_BASE, 4)) ();
|
loongson_reboot();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void loongson_poweroff(void)
|
static void loongson_poweroff(void)
|
||||||
|
|
Загрузка…
Ссылка в новой задаче