]>
Commit | Line | Data |
---|---|---|
6f4eea90 VC |
1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | #ifndef __ASM_ALTERNATIVE_MACROS_H | |
3 | #define __ASM_ALTERNATIVE_MACROS_H | |
4 | ||
5 | #ifdef CONFIG_RISCV_ERRATA_ALTERNATIVE | |
6 | ||
7 | #ifdef __ASSEMBLY__ | |
8 | ||
9 | .macro ALT_ENTRY oldptr newptr vendor_id errata_id new_len | |
10 | RISCV_PTR \oldptr | |
11 | RISCV_PTR \newptr | |
12 | REG_ASM \vendor_id | |
13 | REG_ASM \new_len | |
14 | .word \errata_id | |
15 | .endm | |
16 | ||
17 | .macro ALT_NEW_CONTENT vendor_id, errata_id, enable = 1, new_c : vararg | |
18 | .if \enable | |
19 | .pushsection .alternative, "a" | |
20 | ALT_ENTRY 886b, 888f, \vendor_id, \errata_id, 889f - 888f | |
21 | .popsection | |
22 | .subsection 1 | |
23 | 888 : | |
24 | \new_c | |
25 | 889 : | |
26 | .previous | |
27 | .org . - (889b - 888b) + (887b - 886b) | |
28 | .org . - (887b - 886b) + (889b - 888b) | |
29 | .endif | |
30 | .endm | |
31 | ||
32 | .macro __ALTERNATIVE_CFG old_c, new_c, vendor_id, errata_id, enable | |
33 | 886 : | |
34 | \old_c | |
35 | 887 : | |
36 | ALT_NEW_CONTENT \vendor_id, \errata_id, \enable, \new_c | |
37 | .endm | |
38 | ||
39 | #define _ALTERNATIVE_CFG(old_c, new_c, vendor_id, errata_id, CONFIG_k) \ | |
40 | __ALTERNATIVE_CFG old_c, new_c, vendor_id, errata_id, IS_ENABLED(CONFIG_k) | |
41 | ||
42 | #else /* !__ASSEMBLY__ */ | |
43 | ||
44 | #include <asm/asm.h> | |
45 | #include <linux/stringify.h> | |
46 | ||
47 | #define ALT_ENTRY(oldptr, newptr, vendor_id, errata_id, newlen) \ | |
48 | RISCV_PTR " " oldptr "\n" \ | |
49 | RISCV_PTR " " newptr "\n" \ | |
50 | REG_ASM " " vendor_id "\n" \ | |
51 | REG_ASM " " newlen "\n" \ | |
52 | ".word " errata_id "\n" | |
53 | ||
858cf860 | 54 | #define ALT_NEW_CONTENT(vendor_id, errata_id, enable, new_c) \ |
6f4eea90 VC |
55 | ".if " __stringify(enable) " == 1\n" \ |
56 | ".pushsection .alternative, \"a\"\n" \ | |
57 | ALT_ENTRY("886b", "888f", __stringify(vendor_id), __stringify(errata_id), "889f - 888f") \ | |
58 | ".popsection\n" \ | |
59 | ".subsection 1\n" \ | |
60 | "888 :\n" \ | |
61 | new_c "\n" \ | |
62 | "889 :\n" \ | |
63 | ".previous\n" \ | |
64 | ".org . - (887b - 886b) + (889b - 888b)\n" \ | |
65 | ".org . - (889b - 888b) + (887b - 886b)\n" \ | |
66 | ".endif\n" | |
67 | ||
68 | #define __ALTERNATIVE_CFG(old_c, new_c, vendor_id, errata_id, enable) \ | |
69 | "886 :\n" \ | |
70 | old_c "\n" \ | |
71 | "887 :\n" \ | |
858cf860 | 72 | ALT_NEW_CONTENT(vendor_id, errata_id, enable, new_c) |
6f4eea90 VC |
73 | |
74 | #define _ALTERNATIVE_CFG(old_c, new_c, vendor_id, errata_id, CONFIG_k) \ | |
75 | __ALTERNATIVE_CFG(old_c, new_c, vendor_id, errata_id, IS_ENABLED(CONFIG_k)) | |
76 | ||
77 | #endif /* __ASSEMBLY__ */ | |
78 | ||
79 | #else /* !CONFIG_RISCV_ERRATA_ALTERNATIVE*/ | |
80 | #ifdef __ASSEMBLY__ | |
81 | ||
82 | .macro __ALTERNATIVE_CFG old_c | |
83 | \old_c | |
84 | .endm | |
85 | ||
86 | #define _ALTERNATIVE_CFG(old_c, new_c, vendor_id, errata_id, CONFIG_k) \ | |
87 | __ALTERNATIVE_CFG old_c | |
88 | ||
89 | #else /* !__ASSEMBLY__ */ | |
90 | ||
91 | #define __ALTERNATIVE_CFG(old_c) \ | |
92 | old_c "\n" | |
93 | ||
94 | #define _ALTERNATIVE_CFG(old_c, new_c, vendor_id, errata_id, CONFIG_k) \ | |
95 | __ALTERNATIVE_CFG(old_c) | |
96 | ||
97 | #endif /* __ASSEMBLY__ */ | |
98 | #endif /* CONFIG_RISCV_ERRATA_ALTERNATIVE */ | |
99 | /* | |
100 | * Usage: | |
101 | * ALTERNATIVE(old_content, new_content, vendor_id, errata_id, CONFIG_k) | |
102 | * in the assembly code. Otherwise, | |
103 | * asm(ALTERNATIVE(old_content, new_content, vendor_id, errata_id, CONFIG_k)); | |
104 | * | |
105 | * old_content: The old content which is probably replaced with new content. | |
106 | * new_content: The new content. | |
107 | * vendor_id: The CPU vendor ID. | |
108 | * errata_id: The errata ID. | |
109 | * CONFIG_k: The Kconfig of this errata. When Kconfig is disabled, the old | |
110 | * content will alwyas be executed. | |
111 | */ | |
112 | #define ALTERNATIVE(old_content, new_content, vendor_id, errata_id, CONFIG_k) \ | |
113 | _ALTERNATIVE_CFG(old_content, new_content, vendor_id, errata_id, CONFIG_k) | |
114 | ||
115 | /* | |
116 | * A vendor wants to replace an old_content, but another vendor has used | |
117 | * ALTERNATIVE() to patch its customized content at the same location. In | |
118 | * this case, this vendor can create a new macro ALTERNATIVE_2() based | |
119 | * on the following sample code and then replace ALTERNATIVE() with | |
120 | * ALTERNATIVE_2() to append its customized content. | |
121 | * | |
122 | * .macro __ALTERNATIVE_CFG_2 old_c, new_c_1, vendor_id_1, errata_id_1, enable_1, \ | |
123 | * new_c_2, vendor_id_2, errata_id_2, enable_2 | |
124 | * 886 : | |
125 | * \old_c | |
126 | * 887 : | |
127 | * ALT_NEW_CONTENT \vendor_id_1, \errata_id_1, \enable_1, \new_c_1 | |
128 | * ALT_NEW_CONTENT \vendor_id_2, \errata_id_2, \enable_2, \new_c_2 | |
129 | * .endm | |
130 | * | |
131 | * #define _ALTERNATIVE_CFG_2(old_c, new_c_1, vendor_id_1, errata_id_1, CONFIG_k_1, \ | |
132 | * new_c_2, vendor_id_2, errata_id_2, CONFIG_k_2) \ | |
133 | * __ALTERNATIVE_CFG_2 old_c, new_c_1, vendor_id_1, errata_id_1, IS_ENABLED(CONFIG_k_1), \ | |
134 | * new_c_2, vendor_id_2, errata_id_2, IS_ENABLED(CONFIG_k_2) \ | |
135 | * | |
136 | * #define ALTERNATIVE_2(old_content, new_content_1, vendor_id_1, errata_id_1, CONFIG_k_1, \ | |
137 | * new_content_2, vendor_id_2, errata_id_2, CONFIG_k_2) \ | |
138 | * _ALTERNATIVE_CFG_2(old_content, new_content_1, vendor_id_1, errata_id_1, CONFIG_k_1, \ | |
139 | * new_content_2, vendor_id_2, errata_id_2, CONFIG_k_2) | |
140 | * | |
141 | */ | |
142 | #endif |