linux/arch/sparc/kernel/jump_label.c
<<
>>
Prefs
   1#include <linux/kernel.h>
   2#include <linux/types.h>
   3#include <linux/mutex.h>
   4#include <linux/cpu.h>
   5
   6#include <linux/jump_label.h>
   7#include <linux/memory.h>
   8
   9#include <asm/cacheflush.h>
  10
  11#ifdef HAVE_JUMP_LABEL
  12
  13void arch_jump_label_transform(struct jump_entry *entry,
  14                               enum jump_label_type type)
  15{
  16        u32 *insn = (u32 *) (unsigned long) entry->code;
  17        u32 val;
  18
  19        if (type == JUMP_LABEL_JMP) {
  20                s32 off = (s32)entry->target - (s32)entry->code;
  21                bool use_v9_branch = false;
  22
  23                BUG_ON(off & 3);
  24
  25#ifdef CONFIG_SPARC64
  26                if (off <= 0xfffff && off >= -0x100000)
  27                        use_v9_branch = true;
  28#endif
  29                if (use_v9_branch) {
  30                        /* WDISP19 - target is . + immed << 2 */
  31                        /* ba,pt %xcc, . + off */
  32                        val = 0x10680000 | (((u32) off >> 2) & 0x7ffff);
  33                } else {
  34                        /* WDISP22 - target is . + immed << 2 */
  35                        BUG_ON(off > 0x7fffff);
  36                        BUG_ON(off < -0x800000);
  37                        /* ba . + off */
  38                        val = 0x10800000 | (((u32) off >> 2) & 0x3fffff);
  39                }
  40        } else {
  41                val = 0x01000000;
  42        }
  43
  44        get_online_cpus();
  45        mutex_lock(&text_mutex);
  46        *insn = val;
  47        flushi(insn);
  48        mutex_unlock(&text_mutex);
  49        put_online_cpus();
  50}
  51
  52#endif
  53