powerpc: Use a datatype for instructions
Currently unsigned ints are used to represent instructions on powerpc. This has worked well as instructions have always been 4 byte words. However, ISA v3.1 introduces some changes to instructions that mean this scheme will no longer work as well. This change is Prefixed Instructions. A prefixed instruction is made up of a word prefix followed by a word suffix to make an 8 byte double word instruction. No matter the endianness of the system the prefix always comes first. Prefixed instructions are only planned for powerpc64. Introduce a ppc_inst type to represent both prefixed and word instructions on powerpc64 while keeping it possible to exclusively have word instructions on powerpc32. Signed-off-by: Jordan Niethe <jniethe5@gmail.com> [mpe: Fix compile error in emulate_spe()] Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://lore.kernel.org/r/20200506034050.24806-12-jniethe5@gmail.com
This commit is contained in:

committed by
Michael Ellerman

parent
217862d9b9
commit
94afd069d9
@@ -23,33 +23,33 @@
|
||||
#define BRANCH_ABSOLUTE 0x2
|
||||
|
||||
bool is_offset_in_branch_range(long offset);
|
||||
int create_branch(unsigned int *instr, const unsigned int *addr,
|
||||
int create_branch(struct ppc_inst *instr, const struct ppc_inst *addr,
|
||||
unsigned long target, int flags);
|
||||
int create_cond_branch(unsigned int *instr, const unsigned int *addr,
|
||||
int create_cond_branch(struct ppc_inst *instr, const struct ppc_inst *addr,
|
||||
unsigned long target, int flags);
|
||||
int patch_branch(unsigned int *addr, unsigned long target, int flags);
|
||||
int patch_instruction(unsigned int *addr, unsigned int instr);
|
||||
int raw_patch_instruction(unsigned int *addr, unsigned int instr);
|
||||
int patch_branch(struct ppc_inst *addr, unsigned long target, int flags);
|
||||
int patch_instruction(struct ppc_inst *addr, struct ppc_inst instr);
|
||||
int raw_patch_instruction(struct ppc_inst *addr, struct ppc_inst instr);
|
||||
|
||||
static inline unsigned long patch_site_addr(s32 *site)
|
||||
{
|
||||
return (unsigned long)site + *site;
|
||||
}
|
||||
|
||||
static inline int patch_instruction_site(s32 *site, unsigned int instr)
|
||||
static inline int patch_instruction_site(s32 *site, struct ppc_inst instr)
|
||||
{
|
||||
return patch_instruction((unsigned int *)patch_site_addr(site), instr);
|
||||
return patch_instruction((struct ppc_inst *)patch_site_addr(site), instr);
|
||||
}
|
||||
|
||||
static inline int patch_branch_site(s32 *site, unsigned long target, int flags)
|
||||
{
|
||||
return patch_branch((unsigned int *)patch_site_addr(site), target, flags);
|
||||
return patch_branch((struct ppc_inst *)patch_site_addr(site), target, flags);
|
||||
}
|
||||
|
||||
static inline int modify_instruction(unsigned int *addr, unsigned int clr,
|
||||
unsigned int set)
|
||||
{
|
||||
return patch_instruction(addr, ppc_inst((*addr & ~clr) | set));
|
||||
return patch_instruction((struct ppc_inst *)addr, ppc_inst((*addr & ~clr) | set));
|
||||
}
|
||||
|
||||
static inline int modify_instruction_site(s32 *site, unsigned int clr, unsigned int set)
|
||||
@@ -57,13 +57,13 @@ static inline int modify_instruction_site(s32 *site, unsigned int clr, unsigned
|
||||
return modify_instruction((unsigned int *)patch_site_addr(site), clr, set);
|
||||
}
|
||||
|
||||
int instr_is_relative_branch(unsigned int instr);
|
||||
int instr_is_relative_link_branch(unsigned int instr);
|
||||
int instr_is_branch_to_addr(const unsigned int *instr, unsigned long addr);
|
||||
unsigned long branch_target(const unsigned int *instr);
|
||||
int translate_branch(unsigned int *instr, const unsigned int *dest,
|
||||
const unsigned int *src);
|
||||
extern bool is_conditional_branch(unsigned int instr);
|
||||
int instr_is_relative_branch(struct ppc_inst instr);
|
||||
int instr_is_relative_link_branch(struct ppc_inst instr);
|
||||
int instr_is_branch_to_addr(const struct ppc_inst *instr, unsigned long addr);
|
||||
unsigned long branch_target(const struct ppc_inst *instr);
|
||||
int translate_branch(struct ppc_inst *instr, const struct ppc_inst *dest,
|
||||
const struct ppc_inst *src);
|
||||
extern bool is_conditional_branch(struct ppc_inst instr);
|
||||
#ifdef CONFIG_PPC_BOOK3E_64
|
||||
void __patch_exception(int exc, unsigned long addr);
|
||||
#define patch_exception(exc, name) do { \
|
||||
|
Reference in New Issue
Block a user