Path: blob/master/arch/riscv/include/asm/alternative-macros.h
26471 views
/* SPDX-License-Identifier: GPL-2.0 */1#ifndef __ASM_ALTERNATIVE_MACROS_H2#define __ASM_ALTERNATIVE_MACROS_H34#ifdef CONFIG_RISCV_ALTERNATIVE56#ifdef __ASSEMBLY__78.macro ALT_ENTRY oldptr newptr vendor_id patch_id new_len9.4byte \oldptr - .10.4byte \newptr - .11.2byte \vendor_id12.2byte \new_len13.4byte \patch_id14.endm1516.macro ALT_NEW_CONTENT vendor_id, patch_id, enable = 1, new_c17.if \enable18.pushsection .alternative, "a"19ALT_ENTRY 886b, 888f, \vendor_id, \patch_id, 889f - 888f20.popsection21.subsection 122888 :23.option push24.option norvc25.option norelax26\new_c27.option pop28889 :29.org . - (889b - 888b) + (887b - 886b)30.org . - (887b - 886b) + (889b - 888b)31.previous32.endif33.endm3435.macro ALTERNATIVE_CFG old_c, new_c, vendor_id, patch_id, enable36886 :37.option push38.option norvc39.option norelax40\old_c41.option pop42887 :43ALT_NEW_CONTENT \vendor_id, \patch_id, \enable, "\new_c"44.endm4546.macro ALTERNATIVE_CFG_2 old_c, new_c_1, vendor_id_1, patch_id_1, enable_1, \47new_c_2, vendor_id_2, patch_id_2, enable_248ALTERNATIVE_CFG "\old_c", "\new_c_1", \vendor_id_1, \patch_id_1, \enable_149ALT_NEW_CONTENT \vendor_id_2, \patch_id_2, \enable_2, "\new_c_2"50.endm5152#define __ALTERNATIVE_CFG(...) ALTERNATIVE_CFG __VA_ARGS__53#define __ALTERNATIVE_CFG_2(...) ALTERNATIVE_CFG_2 __VA_ARGS__5455#else /* !__ASSEMBLY__ */5657#include <asm/asm.h>58#include <linux/stringify.h>5960#define ALT_ENTRY(oldptr, newptr, vendor_id, patch_id, newlen) \61".4byte ((" oldptr ") - .) \n" \62".4byte ((" newptr ") - .) \n" \63".2byte " vendor_id "\n" \64".2byte " newlen "\n" \65".4byte " patch_id "\n"6667#define ALT_NEW_CONTENT(vendor_id, patch_id, enable, new_c) \68".if " __stringify(enable) " == 1\n" \69".pushsection .alternative, \"a\"\n" \70ALT_ENTRY("886b", "888f", __stringify(vendor_id), __stringify(patch_id), "889f - 888f") \71".popsection\n" \72".subsection 1\n" \73"888 :\n" \74".option push\n" \75".option norvc\n" \76".option norelax\n" \77new_c "\n" \78".option pop\n" \79"889 :\n" \80".org . - (887b - 886b) + (889b - 888b)\n" \81".org . - (889b - 888b) + (887b - 886b)\n" \82".previous\n" \83".endif\n"8485#define __ALTERNATIVE_CFG(old_c, new_c, vendor_id, patch_id, enable) \86"886 :\n" \87".option push\n" \88".option norvc\n" \89".option norelax\n" \90old_c "\n" \91".option pop\n" \92"887 :\n" \93ALT_NEW_CONTENT(vendor_id, patch_id, enable, new_c)9495#define __ALTERNATIVE_CFG_2(old_c, new_c_1, vendor_id_1, patch_id_1, enable_1, \96new_c_2, vendor_id_2, patch_id_2, enable_2) \97__ALTERNATIVE_CFG(old_c, new_c_1, vendor_id_1, patch_id_1, enable_1) \98ALT_NEW_CONTENT(vendor_id_2, patch_id_2, enable_2, new_c_2)99100#endif /* __ASSEMBLY__ */101102#define _ALTERNATIVE_CFG(old_c, new_c, vendor_id, patch_id, CONFIG_k) \103__ALTERNATIVE_CFG(old_c, new_c, vendor_id, patch_id, IS_ENABLED(CONFIG_k))104105#define _ALTERNATIVE_CFG_2(old_c, new_c_1, vendor_id_1, patch_id_1, CONFIG_k_1, \106new_c_2, vendor_id_2, patch_id_2, CONFIG_k_2) \107__ALTERNATIVE_CFG_2(old_c, new_c_1, vendor_id_1, patch_id_1, IS_ENABLED(CONFIG_k_1), \108new_c_2, vendor_id_2, patch_id_2, IS_ENABLED(CONFIG_k_2))109110#else /* CONFIG_RISCV_ALTERNATIVE */111#ifdef __ASSEMBLY__112113.macro ALTERNATIVE_CFG old_c114\old_c115.endm116117#define __ALTERNATIVE_CFG(old_c, ...) ALTERNATIVE_CFG old_c118#define __ALTERNATIVE_CFG_2(old_c, ...) ALTERNATIVE_CFG old_c119120#else /* !__ASSEMBLY__ */121122#define __ALTERNATIVE_CFG(old_c, ...) old_c "\n"123#define __ALTERNATIVE_CFG_2(old_c, ...) old_c "\n"124125#endif /* __ASSEMBLY__ */126127#define _ALTERNATIVE_CFG(old_c, ...) __ALTERNATIVE_CFG(old_c)128#define _ALTERNATIVE_CFG_2(old_c, ...) __ALTERNATIVE_CFG_2(old_c)129130#endif /* CONFIG_RISCV_ALTERNATIVE */131132/*133* Usage:134* ALTERNATIVE(old_content, new_content, vendor_id, patch_id, CONFIG_k)135* in the assembly code. Otherwise,136* asm(ALTERNATIVE(old_content, new_content, vendor_id, patch_id, CONFIG_k));137*138* old_content: The old content which is probably replaced with new content.139* new_content: The new content.140* vendor_id: The CPU vendor ID.141* patch_id: The patch ID (erratum ID or cpufeature ID).142* CONFIG_k: The Kconfig of this patch ID. When Kconfig is disabled, the old143* content will always be executed.144*/145#define ALTERNATIVE(old_content, new_content, vendor_id, patch_id, CONFIG_k) \146_ALTERNATIVE_CFG(old_content, new_content, vendor_id, patch_id, CONFIG_k)147148/*149* A vendor wants to replace an old_content, but another vendor has used150* ALTERNATIVE() to patch its customized content at the same location. In151* this case, this vendor can create a new macro ALTERNATIVE_2() based152* on the following sample code and then replace ALTERNATIVE() with153* ALTERNATIVE_2() to append its customized content.154*/155#define ALTERNATIVE_2(old_content, new_content_1, vendor_id_1, patch_id_1, CONFIG_k_1, \156new_content_2, vendor_id_2, patch_id_2, CONFIG_k_2) \157_ALTERNATIVE_CFG_2(old_content, new_content_1, vendor_id_1, patch_id_1, CONFIG_k_1, \158new_content_2, vendor_id_2, patch_id_2, CONFIG_k_2)159160#endif161162163