1dff9d3c215251022dd8bb3823c9f75edb4b63fe9David S. Miller#include <linux/kernel.h>
2dff9d3c215251022dd8bb3823c9f75edb4b63fe9David S. Miller#include <linux/types.h>
3dff9d3c215251022dd8bb3823c9f75edb4b63fe9David S. Miller#include <linux/mutex.h>
4dff9d3c215251022dd8bb3823c9f75edb4b63fe9David S. Miller#include <linux/cpu.h>
5dff9d3c215251022dd8bb3823c9f75edb4b63fe9David S. Miller
6dff9d3c215251022dd8bb3823c9f75edb4b63fe9David S. Miller#include <linux/jump_label.h>
7dff9d3c215251022dd8bb3823c9f75edb4b63fe9David S. Miller#include <linux/memory.h>
8dff9d3c215251022dd8bb3823c9f75edb4b63fe9David S. Miller
98befc9f23c695395de011ced289c611fada22f35David S. Miller#include <asm/cacheflush.h>
108befc9f23c695395de011ced289c611fada22f35David S. Miller
11dff9d3c215251022dd8bb3823c9f75edb4b63fe9David S. Miller#ifdef HAVE_JUMP_LABEL
12dff9d3c215251022dd8bb3823c9f75edb4b63fe9David S. Miller
13dff9d3c215251022dd8bb3823c9f75edb4b63fe9David S. Millervoid arch_jump_label_transform(struct jump_entry *entry,
14dff9d3c215251022dd8bb3823c9f75edb4b63fe9David S. Miller			       enum jump_label_type type)
15dff9d3c215251022dd8bb3823c9f75edb4b63fe9David S. Miller{
16dff9d3c215251022dd8bb3823c9f75edb4b63fe9David S. Miller	u32 val;
17dff9d3c215251022dd8bb3823c9f75edb4b63fe9David S. Miller	u32 *insn = (u32 *) (unsigned long) entry->code;
18dff9d3c215251022dd8bb3823c9f75edb4b63fe9David S. Miller
19dff9d3c215251022dd8bb3823c9f75edb4b63fe9David S. Miller	if (type == JUMP_LABEL_ENABLE) {
20dff9d3c215251022dd8bb3823c9f75edb4b63fe9David S. Miller		s32 off = (s32)entry->target - (s32)entry->code;
21dff9d3c215251022dd8bb3823c9f75edb4b63fe9David S. Miller
22dff9d3c215251022dd8bb3823c9f75edb4b63fe9David S. Miller#ifdef CONFIG_SPARC64
23dff9d3c215251022dd8bb3823c9f75edb4b63fe9David S. Miller		/* ba,pt %xcc, . + (off << 2) */
24dff9d3c215251022dd8bb3823c9f75edb4b63fe9David S. Miller		val = 0x10680000 | ((u32) off >> 2);
25dff9d3c215251022dd8bb3823c9f75edb4b63fe9David S. Miller#else
26dff9d3c215251022dd8bb3823c9f75edb4b63fe9David S. Miller		/* ba . + (off << 2) */
27dff9d3c215251022dd8bb3823c9f75edb4b63fe9David S. Miller		val = 0x10800000 | ((u32) off >> 2);
28dff9d3c215251022dd8bb3823c9f75edb4b63fe9David S. Miller#endif
29dff9d3c215251022dd8bb3823c9f75edb4b63fe9David S. Miller	} else {
30dff9d3c215251022dd8bb3823c9f75edb4b63fe9David S. Miller		val = 0x01000000;
31dff9d3c215251022dd8bb3823c9f75edb4b63fe9David S. Miller	}
32dff9d3c215251022dd8bb3823c9f75edb4b63fe9David S. Miller
33dff9d3c215251022dd8bb3823c9f75edb4b63fe9David S. Miller	get_online_cpus();
34dff9d3c215251022dd8bb3823c9f75edb4b63fe9David S. Miller	mutex_lock(&text_mutex);
35dff9d3c215251022dd8bb3823c9f75edb4b63fe9David S. Miller	*insn = val;
36dff9d3c215251022dd8bb3823c9f75edb4b63fe9David S. Miller	flushi(insn);
37dff9d3c215251022dd8bb3823c9f75edb4b63fe9David S. Miller	mutex_unlock(&text_mutex);
38dff9d3c215251022dd8bb3823c9f75edb4b63fe9David S. Miller	put_online_cpus();
39dff9d3c215251022dd8bb3823c9f75edb4b63fe9David S. Miller}
40dff9d3c215251022dd8bb3823c9f75edb4b63fe9David S. Miller
41dff9d3c215251022dd8bb3823c9f75edb4b63fe9David S. Miller#endif
42