Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 #include <linux/kernel.h>
0003 #include <linux/types.h>
0004 #include <linux/mutex.h>
0005 #include <linux/cpu.h>
0006 
0007 #include <linux/jump_label.h>
0008 #include <linux/memory.h>
0009 
0010 #include <asm/cacheflush.h>
0011 
0012 void arch_jump_label_transform(struct jump_entry *entry,
0013                    enum jump_label_type type)
0014 {
0015     u32 *insn = (u32 *) (unsigned long) entry->code;
0016     u32 val;
0017 
0018     if (type == JUMP_LABEL_JMP) {
0019         s32 off = (s32)entry->target - (s32)entry->code;
0020         bool use_v9_branch = false;
0021 
0022         BUG_ON(off & 3);
0023 
0024 #ifdef CONFIG_SPARC64
0025         if (off <= 0xfffff && off >= -0x100000)
0026             use_v9_branch = true;
0027 #endif
0028         if (use_v9_branch) {
0029             /* WDISP19 - target is . + immed << 2 */
0030             /* ba,pt %xcc, . + off */
0031             val = 0x10680000 | (((u32) off >> 2) & 0x7ffff);
0032         } else {
0033             /* WDISP22 - target is . + immed << 2 */
0034             BUG_ON(off > 0x7fffff);
0035             BUG_ON(off < -0x800000);
0036             /* ba . + off */
0037             val = 0x10800000 | (((u32) off >> 2) & 0x3fffff);
0038         }
0039     } else {
0040         val = 0x01000000;
0041     }
0042 
0043     mutex_lock(&text_mutex);
0044     *insn = val;
0045     flushi(insn);
0046     mutex_unlock(&text_mutex);
0047 }