summaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel/jump_label.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-01-18 14:28:48 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2011-01-18 14:28:48 -0800
commit5d7e8af3c5727626b9e7f909c778b9ac9b4a1809 (patch)
tree13d51e31ee070113538a6d26d9a52503ba4a3cd0 /arch/mips/kernel/jump_label.c
parentaa891f6b3f440402c6879ad1ecf332d318137422 (diff)
parent79aa18d557bef02171da42ee928c23509e6ef4f7 (diff)
downloadlinux-5d7e8af3c5727626b9e7f909c778b9ac9b4a1809.tar.bz2
Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/upstream-linus
* 'upstream' of git://git.linux-mips.org/pub/scm/upstream-linus: (26 commits) MIPS: Malta: enable Cirrus FB console MIPS: add CONFIG_VIRTUALIZATION for virtio support MIPS: Implement __read_mostly MIPS: ath79: add common WMAC device for AR913X based boards MIPS: ath79: Add initial support for the Atheros AP81 reference board MIPS: ath79: add common SPI controller device SPI: Add SPI controller driver for the Atheros AR71XX/AR724X/AR913X SoCs MIPS: ath79: add common GPIO buttons device MIPS: ath79: add common watchdog device MIPS: ath79: add common GPIO LEDs device MIPS: ath79: add initial support for the Atheros PB44 reference board MIPS: ath79: utilize the MIPS multi-machine support MIPS: ath79: add GPIOLIB support MIPS: Add initial support for the Atheros AR71XX/AR724X/AR931X SoCs MIPS: jump label: Add MIPS support. MIPS: Use WARN() in uasm for better diagnostics. MIPS: Optimize TLB handlers for Octeon CPUs MIPS: Add LDX and LWX instructions to uasm. MIPS: Use BBIT instructions in TLB handlers MIPS: Declare uasm bbit0 and bbit1 functions. ...
Diffstat (limited to 'arch/mips/kernel/jump_label.c')
-rw-r--r--arch/mips/kernel/jump_label.c54
1 files changed, 54 insertions, 0 deletions
diff --git a/arch/mips/kernel/jump_label.c b/arch/mips/kernel/jump_label.c
new file mode 100644
index 000000000000..6001610cfe55
--- /dev/null
+++ b/arch/mips/kernel/jump_label.c
@@ -0,0 +1,54 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 2010 Cavium Networks, Inc.
+ */
+
+#include <linux/jump_label.h>
+#include <linux/kernel.h>
+#include <linux/memory.h>
+#include <linux/mutex.h>
+#include <linux/types.h>
+#include <linux/cpu.h>
+
+#include <asm/cacheflush.h>
+#include <asm/inst.h>
+
+#ifdef HAVE_JUMP_LABEL
+
+#define J_RANGE_MASK ((1ul << 28) - 1)
+
+void arch_jump_label_transform(struct jump_entry *e,
+ enum jump_label_type type)
+{
+ union mips_instruction insn;
+ union mips_instruction *insn_p =
+ (union mips_instruction *)(unsigned long)e->code;
+
+ /* Jump only works within a 256MB aligned region. */
+ BUG_ON((e->target & ~J_RANGE_MASK) != (e->code & ~J_RANGE_MASK));
+
+ /* Target must have 4 byte alignment. */
+ BUG_ON((e->target & 3) != 0);
+
+ if (type == JUMP_LABEL_ENABLE) {
+ insn.j_format.opcode = j_op;
+ insn.j_format.target = (e->target & J_RANGE_MASK) >> 2;
+ } else {
+ insn.word = 0; /* nop */
+ }
+
+ get_online_cpus();
+ mutex_lock(&text_mutex);
+ *insn_p = insn;
+
+ flush_icache_range((unsigned long)insn_p,
+ (unsigned long)insn_p + sizeof(*insn_p));
+
+ mutex_unlock(&text_mutex);
+ put_online_cpus();
+}
+
+#endif /* HAVE_JUMP_LABEL */