162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */ 262306a36Sopenharmony_ci 362306a36Sopenharmony_ci/* From asm-compat.h */ 462306a36Sopenharmony_ci#define __stringify_in_c(...) #__VA_ARGS__ 562306a36Sopenharmony_ci#define stringify_in_c(...) __stringify_in_c(__VA_ARGS__) " " 662306a36Sopenharmony_ci 762306a36Sopenharmony_ci/* 862306a36Sopenharmony_ci * Macros taken from arch/powerpc/include/asm/ppc-opcode.h and other 962306a36Sopenharmony_ci * header files. 1062306a36Sopenharmony_ci */ 1162306a36Sopenharmony_ci#define ___PPC_RA(a) (((a) & 0x1f) << 16) 1262306a36Sopenharmony_ci#define ___PPC_RB(b) (((b) & 0x1f) << 11) 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ci#define PPC_INST_COPY 0x7c20060c 1562306a36Sopenharmony_ci#define PPC_INST_PASTE 0x7c20070d 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci#define PPC_COPY(a, b) stringify_in_c(.long PPC_INST_COPY | \ 1862306a36Sopenharmony_ci ___PPC_RA(a) | ___PPC_RB(b)) 1962306a36Sopenharmony_ci#define PPC_PASTE(a, b) stringify_in_c(.long PPC_INST_PASTE | \ 2062306a36Sopenharmony_ci ___PPC_RA(a) | ___PPC_RB(b)) 2162306a36Sopenharmony_ci#define CR0_SHIFT 28 2262306a36Sopenharmony_ci#define CR0_MASK 0xF 2362306a36Sopenharmony_ci/* 2462306a36Sopenharmony_ci * Copy/paste instructions: 2562306a36Sopenharmony_ci * 2662306a36Sopenharmony_ci * copy RA,RB 2762306a36Sopenharmony_ci * Copy contents of address (RA) + effective_address(RB) 2862306a36Sopenharmony_ci * to internal copy-buffer. 2962306a36Sopenharmony_ci * 3062306a36Sopenharmony_ci * paste RA,RB 3162306a36Sopenharmony_ci * Paste contents of internal copy-buffer to the address 3262306a36Sopenharmony_ci * (RA) + effective_address(RB) 3362306a36Sopenharmony_ci */ 3462306a36Sopenharmony_cistatic inline int vas_copy(void *crb, int offset) 3562306a36Sopenharmony_ci{ 3662306a36Sopenharmony_ci asm volatile(PPC_COPY(%0, %1)";" 3762306a36Sopenharmony_ci : 3862306a36Sopenharmony_ci : "b" (offset), "b" (crb) 3962306a36Sopenharmony_ci : "memory"); 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_ci return 0; 4262306a36Sopenharmony_ci} 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_cistatic inline int vas_paste(void *paste_address, int offset) 4562306a36Sopenharmony_ci{ 4662306a36Sopenharmony_ci __u32 cr; 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ci cr = 0; 4962306a36Sopenharmony_ci asm volatile(PPC_PASTE(%1, %2)";" 5062306a36Sopenharmony_ci "mfocrf %0, 0x80;" 5162306a36Sopenharmony_ci : "=r" (cr) 5262306a36Sopenharmony_ci : "b" (offset), "b" (paste_address) 5362306a36Sopenharmony_ci : "memory", "cr0"); 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_ci return (cr >> CR0_SHIFT) & CR0_MASK; 5662306a36Sopenharmony_ci} 57