18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */ 28c2ecf20Sopenharmony_ci#ifndef _ASM_POWERPC_INST_H 38c2ecf20Sopenharmony_ci#define _ASM_POWERPC_INST_H 48c2ecf20Sopenharmony_ci 58c2ecf20Sopenharmony_ci#include <asm/ppc-opcode.h> 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ci/* 88c2ecf20Sopenharmony_ci * Instruction data type for POWER 98c2ecf20Sopenharmony_ci */ 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_cistruct ppc_inst { 128c2ecf20Sopenharmony_ci u32 val; 138c2ecf20Sopenharmony_ci#ifdef CONFIG_PPC64 148c2ecf20Sopenharmony_ci u32 suffix; 158c2ecf20Sopenharmony_ci#endif 168c2ecf20Sopenharmony_ci} __packed; 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_cistatic inline u32 ppc_inst_val(struct ppc_inst x) 198c2ecf20Sopenharmony_ci{ 208c2ecf20Sopenharmony_ci return x.val; 218c2ecf20Sopenharmony_ci} 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_cistatic inline int ppc_inst_primary_opcode(struct ppc_inst x) 248c2ecf20Sopenharmony_ci{ 258c2ecf20Sopenharmony_ci return ppc_inst_val(x) >> 26; 268c2ecf20Sopenharmony_ci} 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_ci#ifdef CONFIG_PPC64 298c2ecf20Sopenharmony_ci#define ppc_inst(x) ((struct ppc_inst){ .val = (x), .suffix = 0xff }) 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ci#define ppc_inst_prefix(x, y) ((struct ppc_inst){ .val = (x), .suffix = (y) }) 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_cistatic inline u32 ppc_inst_suffix(struct ppc_inst x) 348c2ecf20Sopenharmony_ci{ 358c2ecf20Sopenharmony_ci return x.suffix; 368c2ecf20Sopenharmony_ci} 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_cistatic inline bool ppc_inst_prefixed(struct ppc_inst x) 398c2ecf20Sopenharmony_ci{ 408c2ecf20Sopenharmony_ci return (ppc_inst_primary_opcode(x) == 1) && ppc_inst_suffix(x) != 0xff; 418c2ecf20Sopenharmony_ci} 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_cistatic inline struct ppc_inst ppc_inst_swab(struct ppc_inst x) 448c2ecf20Sopenharmony_ci{ 458c2ecf20Sopenharmony_ci return ppc_inst_prefix(swab32(ppc_inst_val(x)), 468c2ecf20Sopenharmony_ci swab32(ppc_inst_suffix(x))); 478c2ecf20Sopenharmony_ci} 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_cistatic inline struct ppc_inst ppc_inst_read(const struct ppc_inst *ptr) 508c2ecf20Sopenharmony_ci{ 518c2ecf20Sopenharmony_ci u32 val, suffix; 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ci val = *(u32 *)ptr; 548c2ecf20Sopenharmony_ci if ((val >> 26) == OP_PREFIX) { 558c2ecf20Sopenharmony_ci suffix = *((u32 *)ptr + 1); 568c2ecf20Sopenharmony_ci return ppc_inst_prefix(val, suffix); 578c2ecf20Sopenharmony_ci } else { 588c2ecf20Sopenharmony_ci return ppc_inst(val); 598c2ecf20Sopenharmony_ci } 608c2ecf20Sopenharmony_ci} 618c2ecf20Sopenharmony_ci 628c2ecf20Sopenharmony_cistatic inline bool ppc_inst_equal(struct ppc_inst x, struct ppc_inst y) 638c2ecf20Sopenharmony_ci{ 648c2ecf20Sopenharmony_ci return *(u64 *)&x == *(u64 *)&y; 658c2ecf20Sopenharmony_ci} 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_ci#else 688c2ecf20Sopenharmony_ci 698c2ecf20Sopenharmony_ci#define ppc_inst(x) ((struct ppc_inst){ .val = x }) 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_cistatic inline bool ppc_inst_prefixed(struct ppc_inst x) 728c2ecf20Sopenharmony_ci{ 738c2ecf20Sopenharmony_ci return false; 748c2ecf20Sopenharmony_ci} 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_cistatic inline u32 ppc_inst_suffix(struct ppc_inst x) 778c2ecf20Sopenharmony_ci{ 788c2ecf20Sopenharmony_ci return 0; 798c2ecf20Sopenharmony_ci} 808c2ecf20Sopenharmony_ci 818c2ecf20Sopenharmony_cistatic inline struct ppc_inst ppc_inst_swab(struct ppc_inst x) 828c2ecf20Sopenharmony_ci{ 838c2ecf20Sopenharmony_ci return ppc_inst(swab32(ppc_inst_val(x))); 848c2ecf20Sopenharmony_ci} 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_cistatic inline struct ppc_inst ppc_inst_read(const struct ppc_inst *ptr) 878c2ecf20Sopenharmony_ci{ 888c2ecf20Sopenharmony_ci return *ptr; 898c2ecf20Sopenharmony_ci} 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_cistatic inline bool ppc_inst_equal(struct ppc_inst x, struct ppc_inst y) 928c2ecf20Sopenharmony_ci{ 938c2ecf20Sopenharmony_ci return ppc_inst_val(x) == ppc_inst_val(y); 948c2ecf20Sopenharmony_ci} 958c2ecf20Sopenharmony_ci 968c2ecf20Sopenharmony_ci#endif /* CONFIG_PPC64 */ 978c2ecf20Sopenharmony_ci 988c2ecf20Sopenharmony_cistatic inline int ppc_inst_len(struct ppc_inst x) 998c2ecf20Sopenharmony_ci{ 1008c2ecf20Sopenharmony_ci return ppc_inst_prefixed(x) ? 8 : 4; 1018c2ecf20Sopenharmony_ci} 1028c2ecf20Sopenharmony_ci 1038c2ecf20Sopenharmony_ci/* 1048c2ecf20Sopenharmony_ci * Return the address of the next instruction, if the instruction @value was 1058c2ecf20Sopenharmony_ci * located at @location. 1068c2ecf20Sopenharmony_ci */ 1078c2ecf20Sopenharmony_cistatic inline struct ppc_inst *ppc_inst_next(void *location, struct ppc_inst *value) 1088c2ecf20Sopenharmony_ci{ 1098c2ecf20Sopenharmony_ci struct ppc_inst tmp; 1108c2ecf20Sopenharmony_ci 1118c2ecf20Sopenharmony_ci tmp = ppc_inst_read(value); 1128c2ecf20Sopenharmony_ci 1138c2ecf20Sopenharmony_ci return location + ppc_inst_len(tmp); 1148c2ecf20Sopenharmony_ci} 1158c2ecf20Sopenharmony_ci 1168c2ecf20Sopenharmony_cistatic inline u64 ppc_inst_as_u64(struct ppc_inst x) 1178c2ecf20Sopenharmony_ci{ 1188c2ecf20Sopenharmony_ci#ifdef CONFIG_CPU_LITTLE_ENDIAN 1198c2ecf20Sopenharmony_ci return (u64)ppc_inst_suffix(x) << 32 | ppc_inst_val(x); 1208c2ecf20Sopenharmony_ci#else 1218c2ecf20Sopenharmony_ci return (u64)ppc_inst_val(x) << 32 | ppc_inst_suffix(x); 1228c2ecf20Sopenharmony_ci#endif 1238c2ecf20Sopenharmony_ci} 1248c2ecf20Sopenharmony_ci 1258c2ecf20Sopenharmony_ci#define PPC_INST_STR_LEN sizeof("00000000 00000000") 1268c2ecf20Sopenharmony_ci 1278c2ecf20Sopenharmony_cistatic inline char *__ppc_inst_as_str(char str[PPC_INST_STR_LEN], struct ppc_inst x) 1288c2ecf20Sopenharmony_ci{ 1298c2ecf20Sopenharmony_ci if (ppc_inst_prefixed(x)) 1308c2ecf20Sopenharmony_ci sprintf(str, "%08x %08x", ppc_inst_val(x), ppc_inst_suffix(x)); 1318c2ecf20Sopenharmony_ci else 1328c2ecf20Sopenharmony_ci sprintf(str, "%08x", ppc_inst_val(x)); 1338c2ecf20Sopenharmony_ci 1348c2ecf20Sopenharmony_ci return str; 1358c2ecf20Sopenharmony_ci} 1368c2ecf20Sopenharmony_ci 1378c2ecf20Sopenharmony_ci#define ppc_inst_as_str(x) \ 1388c2ecf20Sopenharmony_ci({ \ 1398c2ecf20Sopenharmony_ci char __str[PPC_INST_STR_LEN]; \ 1408c2ecf20Sopenharmony_ci __ppc_inst_as_str(__str, x); \ 1418c2ecf20Sopenharmony_ci __str; \ 1428c2ecf20Sopenharmony_ci}) 1438c2ecf20Sopenharmony_ci 1448c2ecf20Sopenharmony_ciint probe_user_read_inst(struct ppc_inst *inst, 1458c2ecf20Sopenharmony_ci struct ppc_inst __user *nip); 1468c2ecf20Sopenharmony_ci 1478c2ecf20Sopenharmony_ciint probe_kernel_read_inst(struct ppc_inst *inst, 1488c2ecf20Sopenharmony_ci struct ppc_inst *src); 1498c2ecf20Sopenharmony_ci 1508c2ecf20Sopenharmony_ci#endif /* _ASM_POWERPC_INST_H */ 151