Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 64fc74f5 authored by Wu Zhangjin's avatar Wu Zhangjin Committed by Ralf Baechle
Browse files

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: default avatarLiu Shiwei <liushiwei@gmail.com>
Signed-off-by: default avatarWu Zhangjin <wuzhangjin@gmail.com>
Cc: linux-mips <linux-mips@linux-mips.org>
Patchwork: http://patchwork.linux-mips.org/patch/1109/


Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
parent b197b628
Loading
Loading
Loading
Loading
+19 −1
Original line number Original line Diff line number Diff line
@@ -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)