| 
									
										
										
										
											2014-11-14 15:54:08 +00:00
										 |  |  | #ifndef __ASM_ALTERNATIVE_H
 | 
					
						
							|  |  |  | #define __ASM_ALTERNATIVE_H
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <linux/types.h>
 | 
					
						
							|  |  |  | #include <linux/stddef.h>
 | 
					
						
							|  |  |  | #include <linux/stringify.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct alt_instr { | 
					
						
							|  |  |  | 	s32 orig_offset;	/* offset to original instruction */ | 
					
						
							|  |  |  | 	s32 alt_offset;		/* offset to replacement instruction */ | 
					
						
							|  |  |  | 	u16 cpufeature;		/* cpufeature bit set for replacement */ | 
					
						
							|  |  |  | 	u8  orig_len;		/* size of original instruction(s) */ | 
					
						
							|  |  |  | 	u8  alt_len;		/* size of new instruction(s), <= orig_len */ | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-28 13:40:45 +00:00
										 |  |  | void apply_alternatives_all(void); | 
					
						
							|  |  |  | void apply_alternatives(void *start, size_t length); | 
					
						
							| 
									
										
										
										
											2014-11-14 15:54:08 +00:00
										 |  |  | void free_alternatives_memory(void); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define ALTINSTR_ENTRY(feature)						      \
 | 
					
						
							|  |  |  | 	" .word 661b - .\n"				/* label           */ \ | 
					
						
							|  |  |  | 	" .word 663f - .\n"				/* new instruction */ \ | 
					
						
							|  |  |  | 	" .hword " __stringify(feature) "\n"		/* feature bit     */ \ | 
					
						
							|  |  |  | 	" .byte 662b-661b\n"				/* source len      */ \ | 
					
						
							|  |  |  | 	" .byte 664f-663f\n"				/* replacement len */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* alternative assembly primitive: */ | 
					
						
							|  |  |  | #define ALTERNATIVE(oldinstr, newinstr, feature)			\
 | 
					
						
							|  |  |  | 	"661:\n\t"							\ | 
					
						
							|  |  |  | 	oldinstr "\n"							\ | 
					
						
							|  |  |  | 	"662:\n"							\ | 
					
						
							|  |  |  | 	".pushsection .altinstructions,\"a\"\n"				\ | 
					
						
							|  |  |  | 	ALTINSTR_ENTRY(feature)						\ | 
					
						
							|  |  |  | 	".popsection\n"							\ | 
					
						
							|  |  |  | 	".pushsection .altinstr_replacement, \"a\"\n"			\ | 
					
						
							|  |  |  | 	"663:\n\t"							\ | 
					
						
							|  |  |  | 	newinstr "\n"							\ | 
					
						
							|  |  |  | 	"664:\n\t"							\ | 
					
						
							|  |  |  | 	".popsection\n\t"						\ | 
					
						
							|  |  |  | 	".if ((664b-663b) != (662b-661b))\n\t"				\ | 
					
						
							|  |  |  | 	"	.error \"Alternatives instruction length mismatch\"\n\t"\ | 
					
						
							|  |  |  | 	".endif\n" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif /* __ASM_ALTERNATIVE_H */
 |