arm64: alternative: Merge alternative-asm.h into alternative.h
[firefly-linux-kernel-4.4.55.git] / arch / arm64 / include / asm / alternative.h
1 #ifndef __ASM_ALTERNATIVE_H
2 #define __ASM_ALTERNATIVE_H
3
4 #ifndef __ASSEMBLY__
5
6 #include <linux/types.h>
7 #include <linux/stddef.h>
8 #include <linux/stringify.h>
9
10 struct alt_instr {
11         s32 orig_offset;        /* offset to original instruction */
12         s32 alt_offset;         /* offset to replacement instruction */
13         u16 cpufeature;         /* cpufeature bit set for replacement */
14         u8  orig_len;           /* size of original instruction(s) */
15         u8  alt_len;            /* size of new instruction(s), <= orig_len */
16 };
17
18 void apply_alternatives_all(void);
19 void apply_alternatives(void *start, size_t length);
20 void free_alternatives_memory(void);
21
22 #define ALTINSTR_ENTRY(feature)                                               \
23         " .word 661b - .\n"                             /* label           */ \
24         " .word 663f - .\n"                             /* new instruction */ \
25         " .hword " __stringify(feature) "\n"            /* feature bit     */ \
26         " .byte 662b-661b\n"                            /* source len      */ \
27         " .byte 664f-663f\n"                            /* replacement len */
28
29 /* alternative assembly primitive: */
30 #define ALTERNATIVE(oldinstr, newinstr, feature)                        \
31         "661:\n\t"                                                      \
32         oldinstr "\n"                                                   \
33         "662:\n"                                                        \
34         ".pushsection .altinstructions,\"a\"\n"                         \
35         ALTINSTR_ENTRY(feature)                                         \
36         ".popsection\n"                                                 \
37         ".pushsection .altinstr_replacement, \"a\"\n"                   \
38         "663:\n\t"                                                      \
39         newinstr "\n"                                                   \
40         "664:\n\t"                                                      \
41         ".popsection\n\t"                                               \
42         ".if ((664b-663b) != (662b-661b))\n\t"                          \
43         "       .error \"Alternatives instruction length mismatch\"\n\t"\
44         ".endif\n"
45
46 #else
47
48 .macro altinstruction_entry orig_offset alt_offset feature orig_len alt_len
49         .word \orig_offset - .
50         .word \alt_offset - .
51         .hword \feature
52         .byte \orig_len
53         .byte \alt_len
54 .endm
55
56 .macro alternative_insn insn1 insn2 cap
57 661:    \insn1
58 662:    .pushsection .altinstructions, "a"
59         altinstruction_entry 661b, 663f, \cap, 662b-661b, 664f-663f
60         .popsection
61         .pushsection .altinstr_replacement, "ax"
62 663:    \insn2
63 664:    .popsection
64         .if ((664b-663b) != (662b-661b))
65                 .error "Alternatives instruction length mismatch"
66         .endif
67 .endm
68
69 #endif  /*  __ASSEMBLY__  */
70
71 #endif /* __ASM_ALTERNATIVE_H */