Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) /* SPDX-License-Identifier: GPL-2.0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) #ifndef _ASM_S390_ALTERNATIVE_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3) #define _ASM_S390_ALTERNATIVE_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) #ifndef __ASSEMBLY__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <linux/stddef.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/stringify.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) struct alt_instr {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) 	s32 instr_offset;	/* original instruction */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) 	s32 repl_offset;	/* offset to replacement instruction */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) 	u16 facility;		/* facility bit set for replacement */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) 	u8  instrlen;		/* length of original instruction */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) 	u8  replacementlen;	/* length of new instruction */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) void apply_alternative_instructions(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) void apply_alternatives(struct alt_instr *start, struct alt_instr *end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23)  * |661:       |662:	  |6620      |663:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24)  * +-----------+---------------------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25)  * | oldinstr  | oldinstr_padding    |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26)  * |	       +----------+----------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27)  * |	       |	  |	     |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28)  * |	       | >6 bytes |6/4/2 nops|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29)  * |	       |6 bytes jg----------->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30)  * +-----------+---------------------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31)  *		 ^^ static padding ^^
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33)  * .altinstr_replacement section
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34)  * +---------------------+-----------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35)  * |6641:			     |6651:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36)  * | alternative instr 1	     |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37)  * +-----------+---------+- - - - - -+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38)  * |6642:		 |6652:      |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39)  * | alternative instr 2 | padding
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40)  * +---------------------+- - - - - -+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41)  *			  ^ runtime ^
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43)  * .altinstructions section
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44)  * +---------------------------------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45)  * | alt_instr entries for each      |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46)  * | alternative instr		     |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47)  * +---------------------------------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) #define b_altinstr(num)	"664"#num
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) #define e_altinstr(num)	"665"#num
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) #define e_oldinstr_pad_end	"663"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) #define oldinstr_len		"662b-661b"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) #define oldinstr_total_len	e_oldinstr_pad_end"b-661b"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) #define altinstr_len(num)	e_altinstr(num)"b-"b_altinstr(num)"b"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) #define oldinstr_pad_len(num) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	"-(((" altinstr_len(num) ")-(" oldinstr_len ")) > 0) * " \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	"((" altinstr_len(num) ")-(" oldinstr_len "))"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) #define INSTR_LEN_SANITY_CHECK(len)					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	".if " len " > 254\n"						\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	"\t.error \"cpu alternatives does not support instructions "	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 		"blocks > 254 bytes\"\n"				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	".endif\n"							\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	".if (" len ") %% 2\n"						\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	"\t.error \"cpu alternatives instructions length is odd\"\n"	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	".endif\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) #define OLDINSTR_PADDING(oldinstr, num)					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	".if " oldinstr_pad_len(num) " > 6\n"				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	"\tjg " e_oldinstr_pad_end "f\n"				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	"6620:\n"							\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	"\t.fill (" oldinstr_pad_len(num) " - (6620b-662b)) / 2, 2, 0x0700\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	".else\n"							\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	"\t.fill " oldinstr_pad_len(num) " / 6, 6, 0xc0040000\n"	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	"\t.fill " oldinstr_pad_len(num) " %% 6 / 4, 4, 0x47000000\n"	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	"\t.fill " oldinstr_pad_len(num) " %% 6 %% 4 / 2, 2, 0x0700\n"	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	".endif\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) #define OLDINSTR(oldinstr, num)						\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	"661:\n\t" oldinstr "\n662:\n"					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	OLDINSTR_PADDING(oldinstr, num)					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	e_oldinstr_pad_end ":\n"					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	INSTR_LEN_SANITY_CHECK(oldinstr_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) #define OLDINSTR_2(oldinstr, num1, num2)				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	"661:\n\t" oldinstr "\n662:\n"					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	".if " altinstr_len(num1) " < " altinstr_len(num2) "\n"		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	OLDINSTR_PADDING(oldinstr, num2)				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	".else\n"							\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	OLDINSTR_PADDING(oldinstr, num1)				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	".endif\n"							\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	e_oldinstr_pad_end ":\n"					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	INSTR_LEN_SANITY_CHECK(oldinstr_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) #define ALTINSTR_ENTRY(facility, num)					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	"\t.long 661b - .\n"			/* old instruction */	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	"\t.long " b_altinstr(num)"b - .\n"	/* alt instruction */	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	"\t.word " __stringify(facility) "\n"	/* facility bit    */	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	"\t.byte " oldinstr_total_len "\n"	/* source len	   */	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	"\t.byte " altinstr_len(num) "\n"	/* alt instruction len */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) #define ALTINSTR_REPLACEMENT(altinstr, num)	/* replacement */	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	b_altinstr(num)":\n\t" altinstr "\n" e_altinstr(num) ":\n"	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	INSTR_LEN_SANITY_CHECK(altinstr_len(num))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) /* alternative assembly primitive: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #define ALTERNATIVE(oldinstr, altinstr, facility) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	".pushsection .altinstr_replacement, \"ax\"\n"			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	ALTINSTR_REPLACEMENT(altinstr, 1)				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	".popsection\n"							\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	OLDINSTR(oldinstr, 1)						\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	".pushsection .altinstructions,\"a\"\n"				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	ALTINSTR_ENTRY(facility, 1)					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	".popsection\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) #define ALTERNATIVE_2(oldinstr, altinstr1, facility1, altinstr2, facility2)\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	".pushsection .altinstr_replacement, \"ax\"\n"			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	ALTINSTR_REPLACEMENT(altinstr1, 1)				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	ALTINSTR_REPLACEMENT(altinstr2, 2)				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	".popsection\n"							\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	OLDINSTR_2(oldinstr, 1, 2)					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	".pushsection .altinstructions,\"a\"\n"				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	ALTINSTR_ENTRY(facility1, 1)					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	ALTINSTR_ENTRY(facility2, 2)					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	".popsection\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)  * Alternative instructions for different CPU types or capabilities.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)  * This allows to use optimized instructions even on generic binary
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)  * kernels.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)  * oldinstr is padded with jump and nops at compile time if altinstr is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)  * longer. altinstr is padded with jump and nops at run-time during patching.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)  * For non barrier like inlines please define new variants
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)  * without volatile and memory clobber.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) #define alternative(oldinstr, altinstr, facility)			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	asm_inline volatile(ALTERNATIVE(oldinstr, altinstr, facility) : : : "memory")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) #define alternative_2(oldinstr, altinstr1, facility1, altinstr2, facility2) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	asm_inline volatile(ALTERNATIVE_2(oldinstr, altinstr1, facility1,   \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 				   altinstr2, facility2) ::: "memory")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) #endif /* __ASSEMBLY__ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) #endif /* _ASM_S390_ALTERNATIVE_H */