18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci * Copyright (C) 1995-1999 Gary Thomas, Paul Mackerras, Cort Dougan. 38c2ecf20Sopenharmony_ci */ 48c2ecf20Sopenharmony_ci#ifndef _ASM_POWERPC_PPC_ASM_H 58c2ecf20Sopenharmony_ci#define _ASM_POWERPC_PPC_ASM_H 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ci#include <linux/stringify.h> 88c2ecf20Sopenharmony_ci#include <asm/asm-compat.h> 98c2ecf20Sopenharmony_ci#include <asm/processor.h> 108c2ecf20Sopenharmony_ci#include <asm/ppc-opcode.h> 118c2ecf20Sopenharmony_ci#include <asm/firmware.h> 128c2ecf20Sopenharmony_ci#include <asm/feature-fixups.h> 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_ci#ifdef __ASSEMBLY__ 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_ci#define SZL (BITS_PER_LONG/8) 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_ci/* 198c2ecf20Sopenharmony_ci * Stuff for accurate CPU time accounting. 208c2ecf20Sopenharmony_ci * These macros handle transitions between user and system state 218c2ecf20Sopenharmony_ci * in exception entry and exit and accumulate time to the 228c2ecf20Sopenharmony_ci * user_time and system_time fields in the paca. 238c2ecf20Sopenharmony_ci */ 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_ci#ifndef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE 268c2ecf20Sopenharmony_ci#define ACCOUNT_CPU_USER_ENTRY(ptr, ra, rb) 278c2ecf20Sopenharmony_ci#define ACCOUNT_CPU_USER_EXIT(ptr, ra, rb) 288c2ecf20Sopenharmony_ci#define ACCOUNT_STOLEN_TIME 298c2ecf20Sopenharmony_ci#else 308c2ecf20Sopenharmony_ci#define ACCOUNT_CPU_USER_ENTRY(ptr, ra, rb) \ 318c2ecf20Sopenharmony_ci MFTB(ra); /* get timebase */ \ 328c2ecf20Sopenharmony_ci PPC_LL rb, ACCOUNT_STARTTIME_USER(ptr); \ 338c2ecf20Sopenharmony_ci PPC_STL ra, ACCOUNT_STARTTIME(ptr); \ 348c2ecf20Sopenharmony_ci subf rb,rb,ra; /* subtract start value */ \ 358c2ecf20Sopenharmony_ci PPC_LL ra, ACCOUNT_USER_TIME(ptr); \ 368c2ecf20Sopenharmony_ci add ra,ra,rb; /* add on to user time */ \ 378c2ecf20Sopenharmony_ci PPC_STL ra, ACCOUNT_USER_TIME(ptr); \ 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_ci#define ACCOUNT_CPU_USER_EXIT(ptr, ra, rb) \ 408c2ecf20Sopenharmony_ci MFTB(ra); /* get timebase */ \ 418c2ecf20Sopenharmony_ci PPC_LL rb, ACCOUNT_STARTTIME(ptr); \ 428c2ecf20Sopenharmony_ci PPC_STL ra, ACCOUNT_STARTTIME_USER(ptr); \ 438c2ecf20Sopenharmony_ci subf rb,rb,ra; /* subtract start value */ \ 448c2ecf20Sopenharmony_ci PPC_LL ra, ACCOUNT_SYSTEM_TIME(ptr); \ 458c2ecf20Sopenharmony_ci add ra,ra,rb; /* add on to system time */ \ 468c2ecf20Sopenharmony_ci PPC_STL ra, ACCOUNT_SYSTEM_TIME(ptr) 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_ci#ifdef CONFIG_PPC_SPLPAR 498c2ecf20Sopenharmony_ci#define ACCOUNT_STOLEN_TIME \ 508c2ecf20Sopenharmony_ciBEGIN_FW_FTR_SECTION; \ 518c2ecf20Sopenharmony_ci beq 33f; \ 528c2ecf20Sopenharmony_ci /* from user - see if there are any DTL entries to process */ \ 538c2ecf20Sopenharmony_ci ld r10,PACALPPACAPTR(r13); /* get ptr to VPA */ \ 548c2ecf20Sopenharmony_ci ld r11,PACA_DTL_RIDX(r13); /* get log read index */ \ 558c2ecf20Sopenharmony_ci addi r10,r10,LPPACA_DTLIDX; \ 568c2ecf20Sopenharmony_ci LDX_BE r10,0,r10; /* get log write index */ \ 578c2ecf20Sopenharmony_ci cmpd cr1,r11,r10; \ 588c2ecf20Sopenharmony_ci beq+ cr1,33f; \ 598c2ecf20Sopenharmony_ci bl accumulate_stolen_time; \ 608c2ecf20Sopenharmony_ci ld r12,_MSR(r1); \ 618c2ecf20Sopenharmony_ci andi. r10,r12,MSR_PR; /* Restore cr0 (coming from user) */ \ 628c2ecf20Sopenharmony_ci33: \ 638c2ecf20Sopenharmony_ciEND_FW_FTR_SECTION_IFSET(FW_FEATURE_SPLPAR) 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_ci#else /* CONFIG_PPC_SPLPAR */ 668c2ecf20Sopenharmony_ci#define ACCOUNT_STOLEN_TIME 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ci#endif /* CONFIG_PPC_SPLPAR */ 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_ci#endif /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */ 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_ci/* 738c2ecf20Sopenharmony_ci * Macros for storing registers into and loading registers from 748c2ecf20Sopenharmony_ci * exception frames. 758c2ecf20Sopenharmony_ci */ 768c2ecf20Sopenharmony_ci#ifdef __powerpc64__ 778c2ecf20Sopenharmony_ci#define SAVE_GPR(n, base) std n,GPR0+8*(n)(base) 788c2ecf20Sopenharmony_ci#define REST_GPR(n, base) ld n,GPR0+8*(n)(base) 798c2ecf20Sopenharmony_ci#define SAVE_NVGPRS(base) SAVE_8GPRS(14, base); SAVE_10GPRS(22, base) 808c2ecf20Sopenharmony_ci#define REST_NVGPRS(base) REST_8GPRS(14, base); REST_10GPRS(22, base) 818c2ecf20Sopenharmony_ci#else 828c2ecf20Sopenharmony_ci#define SAVE_GPR(n, base) stw n,GPR0+4*(n)(base) 838c2ecf20Sopenharmony_ci#define REST_GPR(n, base) lwz n,GPR0+4*(n)(base) 848c2ecf20Sopenharmony_ci#define SAVE_NVGPRS(base) stmw 13, GPR0+4*13(base) 858c2ecf20Sopenharmony_ci#define REST_NVGPRS(base) lmw 13, GPR0+4*13(base) 868c2ecf20Sopenharmony_ci#endif 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_ci#define SAVE_2GPRS(n, base) SAVE_GPR(n, base); SAVE_GPR(n+1, base) 898c2ecf20Sopenharmony_ci#define SAVE_4GPRS(n, base) SAVE_2GPRS(n, base); SAVE_2GPRS(n+2, base) 908c2ecf20Sopenharmony_ci#define SAVE_8GPRS(n, base) SAVE_4GPRS(n, base); SAVE_4GPRS(n+4, base) 918c2ecf20Sopenharmony_ci#define SAVE_10GPRS(n, base) SAVE_8GPRS(n, base); SAVE_2GPRS(n+8, base) 928c2ecf20Sopenharmony_ci#define REST_2GPRS(n, base) REST_GPR(n, base); REST_GPR(n+1, base) 938c2ecf20Sopenharmony_ci#define REST_4GPRS(n, base) REST_2GPRS(n, base); REST_2GPRS(n+2, base) 948c2ecf20Sopenharmony_ci#define REST_8GPRS(n, base) REST_4GPRS(n, base); REST_4GPRS(n+4, base) 958c2ecf20Sopenharmony_ci#define REST_10GPRS(n, base) REST_8GPRS(n, base); REST_2GPRS(n+8, base) 968c2ecf20Sopenharmony_ci 978c2ecf20Sopenharmony_ci#define SAVE_FPR(n, base) stfd n,8*TS_FPRWIDTH*(n)(base) 988c2ecf20Sopenharmony_ci#define SAVE_2FPRS(n, base) SAVE_FPR(n, base); SAVE_FPR(n+1, base) 998c2ecf20Sopenharmony_ci#define SAVE_4FPRS(n, base) SAVE_2FPRS(n, base); SAVE_2FPRS(n+2, base) 1008c2ecf20Sopenharmony_ci#define SAVE_8FPRS(n, base) SAVE_4FPRS(n, base); SAVE_4FPRS(n+4, base) 1018c2ecf20Sopenharmony_ci#define SAVE_16FPRS(n, base) SAVE_8FPRS(n, base); SAVE_8FPRS(n+8, base) 1028c2ecf20Sopenharmony_ci#define SAVE_32FPRS(n, base) SAVE_16FPRS(n, base); SAVE_16FPRS(n+16, base) 1038c2ecf20Sopenharmony_ci#define REST_FPR(n, base) lfd n,8*TS_FPRWIDTH*(n)(base) 1048c2ecf20Sopenharmony_ci#define REST_2FPRS(n, base) REST_FPR(n, base); REST_FPR(n+1, base) 1058c2ecf20Sopenharmony_ci#define REST_4FPRS(n, base) REST_2FPRS(n, base); REST_2FPRS(n+2, base) 1068c2ecf20Sopenharmony_ci#define REST_8FPRS(n, base) REST_4FPRS(n, base); REST_4FPRS(n+4, base) 1078c2ecf20Sopenharmony_ci#define REST_16FPRS(n, base) REST_8FPRS(n, base); REST_8FPRS(n+8, base) 1088c2ecf20Sopenharmony_ci#define REST_32FPRS(n, base) REST_16FPRS(n, base); REST_16FPRS(n+16, base) 1098c2ecf20Sopenharmony_ci 1108c2ecf20Sopenharmony_ci#define SAVE_VR(n,b,base) li b,16*(n); stvx n,base,b 1118c2ecf20Sopenharmony_ci#define SAVE_2VRS(n,b,base) SAVE_VR(n,b,base); SAVE_VR(n+1,b,base) 1128c2ecf20Sopenharmony_ci#define SAVE_4VRS(n,b,base) SAVE_2VRS(n,b,base); SAVE_2VRS(n+2,b,base) 1138c2ecf20Sopenharmony_ci#define SAVE_8VRS(n,b,base) SAVE_4VRS(n,b,base); SAVE_4VRS(n+4,b,base) 1148c2ecf20Sopenharmony_ci#define SAVE_16VRS(n,b,base) SAVE_8VRS(n,b,base); SAVE_8VRS(n+8,b,base) 1158c2ecf20Sopenharmony_ci#define SAVE_32VRS(n,b,base) SAVE_16VRS(n,b,base); SAVE_16VRS(n+16,b,base) 1168c2ecf20Sopenharmony_ci#define REST_VR(n,b,base) li b,16*(n); lvx n,base,b 1178c2ecf20Sopenharmony_ci#define REST_2VRS(n,b,base) REST_VR(n,b,base); REST_VR(n+1,b,base) 1188c2ecf20Sopenharmony_ci#define REST_4VRS(n,b,base) REST_2VRS(n,b,base); REST_2VRS(n+2,b,base) 1198c2ecf20Sopenharmony_ci#define REST_8VRS(n,b,base) REST_4VRS(n,b,base); REST_4VRS(n+4,b,base) 1208c2ecf20Sopenharmony_ci#define REST_16VRS(n,b,base) REST_8VRS(n,b,base); REST_8VRS(n+8,b,base) 1218c2ecf20Sopenharmony_ci#define REST_32VRS(n,b,base) REST_16VRS(n,b,base); REST_16VRS(n+16,b,base) 1228c2ecf20Sopenharmony_ci 1238c2ecf20Sopenharmony_ci#ifdef __BIG_ENDIAN__ 1248c2ecf20Sopenharmony_ci#define STXVD2X_ROT(n,b,base) STXVD2X(n,b,base) 1258c2ecf20Sopenharmony_ci#define LXVD2X_ROT(n,b,base) LXVD2X(n,b,base) 1268c2ecf20Sopenharmony_ci#else 1278c2ecf20Sopenharmony_ci#define STXVD2X_ROT(n,b,base) XXSWAPD(n,n); \ 1288c2ecf20Sopenharmony_ci STXVD2X(n,b,base); \ 1298c2ecf20Sopenharmony_ci XXSWAPD(n,n) 1308c2ecf20Sopenharmony_ci 1318c2ecf20Sopenharmony_ci#define LXVD2X_ROT(n,b,base) LXVD2X(n,b,base); \ 1328c2ecf20Sopenharmony_ci XXSWAPD(n,n) 1338c2ecf20Sopenharmony_ci#endif 1348c2ecf20Sopenharmony_ci/* Save the lower 32 VSRs in the thread VSR region */ 1358c2ecf20Sopenharmony_ci#define SAVE_VSR(n,b,base) li b,16*(n); STXVD2X_ROT(n,R##base,R##b) 1368c2ecf20Sopenharmony_ci#define SAVE_2VSRS(n,b,base) SAVE_VSR(n,b,base); SAVE_VSR(n+1,b,base) 1378c2ecf20Sopenharmony_ci#define SAVE_4VSRS(n,b,base) SAVE_2VSRS(n,b,base); SAVE_2VSRS(n+2,b,base) 1388c2ecf20Sopenharmony_ci#define SAVE_8VSRS(n,b,base) SAVE_4VSRS(n,b,base); SAVE_4VSRS(n+4,b,base) 1398c2ecf20Sopenharmony_ci#define SAVE_16VSRS(n,b,base) SAVE_8VSRS(n,b,base); SAVE_8VSRS(n+8,b,base) 1408c2ecf20Sopenharmony_ci#define SAVE_32VSRS(n,b,base) SAVE_16VSRS(n,b,base); SAVE_16VSRS(n+16,b,base) 1418c2ecf20Sopenharmony_ci#define REST_VSR(n,b,base) li b,16*(n); LXVD2X_ROT(n,R##base,R##b) 1428c2ecf20Sopenharmony_ci#define REST_2VSRS(n,b,base) REST_VSR(n,b,base); REST_VSR(n+1,b,base) 1438c2ecf20Sopenharmony_ci#define REST_4VSRS(n,b,base) REST_2VSRS(n,b,base); REST_2VSRS(n+2,b,base) 1448c2ecf20Sopenharmony_ci#define REST_8VSRS(n,b,base) REST_4VSRS(n,b,base); REST_4VSRS(n+4,b,base) 1458c2ecf20Sopenharmony_ci#define REST_16VSRS(n,b,base) REST_8VSRS(n,b,base); REST_8VSRS(n+8,b,base) 1468c2ecf20Sopenharmony_ci#define REST_32VSRS(n,b,base) REST_16VSRS(n,b,base); REST_16VSRS(n+16,b,base) 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_ci/* 1498c2ecf20Sopenharmony_ci * b = base register for addressing, o = base offset from register of 1st EVR 1508c2ecf20Sopenharmony_ci * n = first EVR, s = scratch 1518c2ecf20Sopenharmony_ci */ 1528c2ecf20Sopenharmony_ci#define SAVE_EVR(n,s,b,o) evmergehi s,s,n; stw s,o+4*(n)(b) 1538c2ecf20Sopenharmony_ci#define SAVE_2EVRS(n,s,b,o) SAVE_EVR(n,s,b,o); SAVE_EVR(n+1,s,b,o) 1548c2ecf20Sopenharmony_ci#define SAVE_4EVRS(n,s,b,o) SAVE_2EVRS(n,s,b,o); SAVE_2EVRS(n+2,s,b,o) 1558c2ecf20Sopenharmony_ci#define SAVE_8EVRS(n,s,b,o) SAVE_4EVRS(n,s,b,o); SAVE_4EVRS(n+4,s,b,o) 1568c2ecf20Sopenharmony_ci#define SAVE_16EVRS(n,s,b,o) SAVE_8EVRS(n,s,b,o); SAVE_8EVRS(n+8,s,b,o) 1578c2ecf20Sopenharmony_ci#define SAVE_32EVRS(n,s,b,o) SAVE_16EVRS(n,s,b,o); SAVE_16EVRS(n+16,s,b,o) 1588c2ecf20Sopenharmony_ci#define REST_EVR(n,s,b,o) lwz s,o+4*(n)(b); evmergelo n,s,n 1598c2ecf20Sopenharmony_ci#define REST_2EVRS(n,s,b,o) REST_EVR(n,s,b,o); REST_EVR(n+1,s,b,o) 1608c2ecf20Sopenharmony_ci#define REST_4EVRS(n,s,b,o) REST_2EVRS(n,s,b,o); REST_2EVRS(n+2,s,b,o) 1618c2ecf20Sopenharmony_ci#define REST_8EVRS(n,s,b,o) REST_4EVRS(n,s,b,o); REST_4EVRS(n+4,s,b,o) 1628c2ecf20Sopenharmony_ci#define REST_16EVRS(n,s,b,o) REST_8EVRS(n,s,b,o); REST_8EVRS(n+8,s,b,o) 1638c2ecf20Sopenharmony_ci#define REST_32EVRS(n,s,b,o) REST_16EVRS(n,s,b,o); REST_16EVRS(n+16,s,b,o) 1648c2ecf20Sopenharmony_ci 1658c2ecf20Sopenharmony_ci/* Macros to adjust thread priority for hardware multithreading */ 1668c2ecf20Sopenharmony_ci#define HMT_VERY_LOW or 31,31,31 # very low priority 1678c2ecf20Sopenharmony_ci#define HMT_LOW or 1,1,1 1688c2ecf20Sopenharmony_ci#define HMT_MEDIUM_LOW or 6,6,6 # medium low priority 1698c2ecf20Sopenharmony_ci#define HMT_MEDIUM or 2,2,2 1708c2ecf20Sopenharmony_ci#define HMT_MEDIUM_HIGH or 5,5,5 # medium high priority 1718c2ecf20Sopenharmony_ci#define HMT_HIGH or 3,3,3 1728c2ecf20Sopenharmony_ci#define HMT_EXTRA_HIGH or 7,7,7 # power7 only 1738c2ecf20Sopenharmony_ci 1748c2ecf20Sopenharmony_ci#ifdef CONFIG_PPC64 1758c2ecf20Sopenharmony_ci#define ULONG_SIZE 8 1768c2ecf20Sopenharmony_ci#else 1778c2ecf20Sopenharmony_ci#define ULONG_SIZE 4 1788c2ecf20Sopenharmony_ci#endif 1798c2ecf20Sopenharmony_ci#define __VCPU_GPR(n) (VCPU_GPRS + (n * ULONG_SIZE)) 1808c2ecf20Sopenharmony_ci#define VCPU_GPR(n) __VCPU_GPR(__REG_##n) 1818c2ecf20Sopenharmony_ci 1828c2ecf20Sopenharmony_ci#ifdef __KERNEL__ 1838c2ecf20Sopenharmony_ci#ifdef CONFIG_PPC64 1848c2ecf20Sopenharmony_ci 1858c2ecf20Sopenharmony_ci#define STACKFRAMESIZE 256 1868c2ecf20Sopenharmony_ci#define __STK_REG(i) (112 + ((i)-14)*8) 1878c2ecf20Sopenharmony_ci#define STK_REG(i) __STK_REG(__REG_##i) 1888c2ecf20Sopenharmony_ci 1898c2ecf20Sopenharmony_ci#ifdef PPC64_ELF_ABI_v2 1908c2ecf20Sopenharmony_ci#define STK_GOT 24 1918c2ecf20Sopenharmony_ci#define __STK_PARAM(i) (32 + ((i)-3)*8) 1928c2ecf20Sopenharmony_ci#else 1938c2ecf20Sopenharmony_ci#define STK_GOT 40 1948c2ecf20Sopenharmony_ci#define __STK_PARAM(i) (48 + ((i)-3)*8) 1958c2ecf20Sopenharmony_ci#endif 1968c2ecf20Sopenharmony_ci#define STK_PARAM(i) __STK_PARAM(__REG_##i) 1978c2ecf20Sopenharmony_ci 1988c2ecf20Sopenharmony_ci#ifdef PPC64_ELF_ABI_v2 1998c2ecf20Sopenharmony_ci 2008c2ecf20Sopenharmony_ci#define _GLOBAL(name) \ 2018c2ecf20Sopenharmony_ci .align 2 ; \ 2028c2ecf20Sopenharmony_ci .type name,@function; \ 2038c2ecf20Sopenharmony_ci .globl name; \ 2048c2ecf20Sopenharmony_ciname: 2058c2ecf20Sopenharmony_ci 2068c2ecf20Sopenharmony_ci#define _GLOBAL_TOC(name) \ 2078c2ecf20Sopenharmony_ci .align 2 ; \ 2088c2ecf20Sopenharmony_ci .type name,@function; \ 2098c2ecf20Sopenharmony_ci .globl name; \ 2108c2ecf20Sopenharmony_ciname: \ 2118c2ecf20Sopenharmony_ci0: addis r2,r12,(.TOC.-0b)@ha; \ 2128c2ecf20Sopenharmony_ci addi r2,r2,(.TOC.-0b)@l; \ 2138c2ecf20Sopenharmony_ci .localentry name,.-name 2148c2ecf20Sopenharmony_ci 2158c2ecf20Sopenharmony_ci#define DOTSYM(a) a 2168c2ecf20Sopenharmony_ci 2178c2ecf20Sopenharmony_ci#else 2188c2ecf20Sopenharmony_ci 2198c2ecf20Sopenharmony_ci#define XGLUE(a,b) a##b 2208c2ecf20Sopenharmony_ci#define GLUE(a,b) XGLUE(a,b) 2218c2ecf20Sopenharmony_ci 2228c2ecf20Sopenharmony_ci#define _GLOBAL(name) \ 2238c2ecf20Sopenharmony_ci .align 2 ; \ 2248c2ecf20Sopenharmony_ci .globl name; \ 2258c2ecf20Sopenharmony_ci .globl GLUE(.,name); \ 2268c2ecf20Sopenharmony_ci .pushsection ".opd","aw"; \ 2278c2ecf20Sopenharmony_ciname: \ 2288c2ecf20Sopenharmony_ci .quad GLUE(.,name); \ 2298c2ecf20Sopenharmony_ci .quad .TOC.@tocbase; \ 2308c2ecf20Sopenharmony_ci .quad 0; \ 2318c2ecf20Sopenharmony_ci .popsection; \ 2328c2ecf20Sopenharmony_ci .type GLUE(.,name),@function; \ 2338c2ecf20Sopenharmony_ciGLUE(.,name): 2348c2ecf20Sopenharmony_ci 2358c2ecf20Sopenharmony_ci#define _GLOBAL_TOC(name) _GLOBAL(name) 2368c2ecf20Sopenharmony_ci 2378c2ecf20Sopenharmony_ci#define DOTSYM(a) GLUE(.,a) 2388c2ecf20Sopenharmony_ci 2398c2ecf20Sopenharmony_ci#endif 2408c2ecf20Sopenharmony_ci 2418c2ecf20Sopenharmony_ci#else /* 32-bit */ 2428c2ecf20Sopenharmony_ci 2438c2ecf20Sopenharmony_ci#define _ENTRY(n) \ 2448c2ecf20Sopenharmony_ci .globl n; \ 2458c2ecf20Sopenharmony_cin: 2468c2ecf20Sopenharmony_ci 2478c2ecf20Sopenharmony_ci#define _GLOBAL(n) \ 2488c2ecf20Sopenharmony_ci .stabs __stringify(n:F-1),N_FUN,0,0,n;\ 2498c2ecf20Sopenharmony_ci .globl n; \ 2508c2ecf20Sopenharmony_cin: 2518c2ecf20Sopenharmony_ci 2528c2ecf20Sopenharmony_ci#define _GLOBAL_TOC(name) _GLOBAL(name) 2538c2ecf20Sopenharmony_ci 2548c2ecf20Sopenharmony_ci#endif 2558c2ecf20Sopenharmony_ci 2568c2ecf20Sopenharmony_ci/* 2578c2ecf20Sopenharmony_ci * __kprobes (the C annotation) puts the symbol into the .kprobes.text 2588c2ecf20Sopenharmony_ci * section, which gets emitted at the end of regular text. 2598c2ecf20Sopenharmony_ci * 2608c2ecf20Sopenharmony_ci * _ASM_NOKPROBE_SYMBOL and NOKPROBE_SYMBOL just adds the symbol to 2618c2ecf20Sopenharmony_ci * a blacklist. The former is for core kprobe functions/data, the 2628c2ecf20Sopenharmony_ci * latter is for those that incdentially must be excluded from probing 2638c2ecf20Sopenharmony_ci * and allows them to be linked at more optimal location within text. 2648c2ecf20Sopenharmony_ci */ 2658c2ecf20Sopenharmony_ci#ifdef CONFIG_KPROBES 2668c2ecf20Sopenharmony_ci#define _ASM_NOKPROBE_SYMBOL(entry) \ 2678c2ecf20Sopenharmony_ci .pushsection "_kprobe_blacklist","aw"; \ 2688c2ecf20Sopenharmony_ci PPC_LONG (entry) ; \ 2698c2ecf20Sopenharmony_ci .popsection 2708c2ecf20Sopenharmony_ci#else 2718c2ecf20Sopenharmony_ci#define _ASM_NOKPROBE_SYMBOL(entry) 2728c2ecf20Sopenharmony_ci#endif 2738c2ecf20Sopenharmony_ci 2748c2ecf20Sopenharmony_ci#define FUNC_START(name) _GLOBAL(name) 2758c2ecf20Sopenharmony_ci#define FUNC_END(name) 2768c2ecf20Sopenharmony_ci 2778c2ecf20Sopenharmony_ci/* 2788c2ecf20Sopenharmony_ci * LOAD_REG_IMMEDIATE(rn, expr) 2798c2ecf20Sopenharmony_ci * Loads the value of the constant expression 'expr' into register 'rn' 2808c2ecf20Sopenharmony_ci * using immediate instructions only. Use this when it's important not 2818c2ecf20Sopenharmony_ci * to reference other data (i.e. on ppc64 when the TOC pointer is not 2828c2ecf20Sopenharmony_ci * valid) and when 'expr' is a constant or absolute address. 2838c2ecf20Sopenharmony_ci * 2848c2ecf20Sopenharmony_ci * LOAD_REG_ADDR(rn, name) 2858c2ecf20Sopenharmony_ci * Loads the address of label 'name' into register 'rn'. Use this when 2868c2ecf20Sopenharmony_ci * you don't particularly need immediate instructions only, but you need 2878c2ecf20Sopenharmony_ci * the whole address in one register (e.g. it's a structure address and 2888c2ecf20Sopenharmony_ci * you want to access various offsets within it). On ppc32 this is 2898c2ecf20Sopenharmony_ci * identical to LOAD_REG_IMMEDIATE. 2908c2ecf20Sopenharmony_ci * 2918c2ecf20Sopenharmony_ci * LOAD_REG_ADDR_PIC(rn, name) 2928c2ecf20Sopenharmony_ci * Loads the address of label 'name' into register 'run'. Use this when 2938c2ecf20Sopenharmony_ci * the kernel doesn't run at the linked or relocated address. Please 2948c2ecf20Sopenharmony_ci * note that this macro will clobber the lr register. 2958c2ecf20Sopenharmony_ci * 2968c2ecf20Sopenharmony_ci * LOAD_REG_ADDRBASE(rn, name) 2978c2ecf20Sopenharmony_ci * ADDROFF(name) 2988c2ecf20Sopenharmony_ci * LOAD_REG_ADDRBASE loads part of the address of label 'name' into 2998c2ecf20Sopenharmony_ci * register 'rn'. ADDROFF(name) returns the remainder of the address as 3008c2ecf20Sopenharmony_ci * a constant expression. ADDROFF(name) is a signed expression < 16 bits 3018c2ecf20Sopenharmony_ci * in size, so is suitable for use directly as an offset in load and store 3028c2ecf20Sopenharmony_ci * instructions. Use this when loading/storing a single word or less as: 3038c2ecf20Sopenharmony_ci * LOAD_REG_ADDRBASE(rX, name) 3048c2ecf20Sopenharmony_ci * ld rY,ADDROFF(name)(rX) 3058c2ecf20Sopenharmony_ci */ 3068c2ecf20Sopenharmony_ci 3078c2ecf20Sopenharmony_ci/* Be careful, this will clobber the lr register. */ 3088c2ecf20Sopenharmony_ci#define LOAD_REG_ADDR_PIC(reg, name) \ 3098c2ecf20Sopenharmony_ci bl 0f; \ 3108c2ecf20Sopenharmony_ci0: mflr reg; \ 3118c2ecf20Sopenharmony_ci addis reg,reg,(name - 0b)@ha; \ 3128c2ecf20Sopenharmony_ci addi reg,reg,(name - 0b)@l; 3138c2ecf20Sopenharmony_ci 3148c2ecf20Sopenharmony_ci#if defined(__powerpc64__) && defined(HAVE_AS_ATHIGH) 3158c2ecf20Sopenharmony_ci#define __AS_ATHIGH high 3168c2ecf20Sopenharmony_ci#else 3178c2ecf20Sopenharmony_ci#define __AS_ATHIGH h 3188c2ecf20Sopenharmony_ci#endif 3198c2ecf20Sopenharmony_ci 3208c2ecf20Sopenharmony_ci.macro __LOAD_REG_IMMEDIATE_32 r, x 3218c2ecf20Sopenharmony_ci .if (\x) >= 0x8000 || (\x) < -0x8000 3228c2ecf20Sopenharmony_ci lis \r, (\x)@__AS_ATHIGH 3238c2ecf20Sopenharmony_ci .if (\x) & 0xffff != 0 3248c2ecf20Sopenharmony_ci ori \r, \r, (\x)@l 3258c2ecf20Sopenharmony_ci .endif 3268c2ecf20Sopenharmony_ci .else 3278c2ecf20Sopenharmony_ci li \r, (\x)@l 3288c2ecf20Sopenharmony_ci .endif 3298c2ecf20Sopenharmony_ci.endm 3308c2ecf20Sopenharmony_ci 3318c2ecf20Sopenharmony_ci.macro __LOAD_REG_IMMEDIATE r, x 3328c2ecf20Sopenharmony_ci .if (\x) >= 0x80000000 || (\x) < -0x80000000 3338c2ecf20Sopenharmony_ci __LOAD_REG_IMMEDIATE_32 \r, (\x) >> 32 3348c2ecf20Sopenharmony_ci sldi \r, \r, 32 3358c2ecf20Sopenharmony_ci .if (\x) & 0xffff0000 != 0 3368c2ecf20Sopenharmony_ci oris \r, \r, (\x)@__AS_ATHIGH 3378c2ecf20Sopenharmony_ci .endif 3388c2ecf20Sopenharmony_ci .if (\x) & 0xffff != 0 3398c2ecf20Sopenharmony_ci ori \r, \r, (\x)@l 3408c2ecf20Sopenharmony_ci .endif 3418c2ecf20Sopenharmony_ci .else 3428c2ecf20Sopenharmony_ci __LOAD_REG_IMMEDIATE_32 \r, \x 3438c2ecf20Sopenharmony_ci .endif 3448c2ecf20Sopenharmony_ci.endm 3458c2ecf20Sopenharmony_ci 3468c2ecf20Sopenharmony_ci#ifdef __powerpc64__ 3478c2ecf20Sopenharmony_ci 3488c2ecf20Sopenharmony_ci#define LOAD_REG_IMMEDIATE(reg, expr) __LOAD_REG_IMMEDIATE reg, expr 3498c2ecf20Sopenharmony_ci 3508c2ecf20Sopenharmony_ci#define LOAD_REG_IMMEDIATE_SYM(reg, tmp, expr) \ 3518c2ecf20Sopenharmony_ci lis tmp, (expr)@highest; \ 3528c2ecf20Sopenharmony_ci lis reg, (expr)@__AS_ATHIGH; \ 3538c2ecf20Sopenharmony_ci ori tmp, tmp, (expr)@higher; \ 3548c2ecf20Sopenharmony_ci ori reg, reg, (expr)@l; \ 3558c2ecf20Sopenharmony_ci rldimi reg, tmp, 32, 0 3568c2ecf20Sopenharmony_ci 3578c2ecf20Sopenharmony_ci#define LOAD_REG_ADDR(reg,name) \ 3588c2ecf20Sopenharmony_ci ld reg,name@got(r2) 3598c2ecf20Sopenharmony_ci 3608c2ecf20Sopenharmony_ci#define LOAD_REG_ADDRBASE(reg,name) LOAD_REG_ADDR(reg,name) 3618c2ecf20Sopenharmony_ci#define ADDROFF(name) 0 3628c2ecf20Sopenharmony_ci 3638c2ecf20Sopenharmony_ci/* offsets for stack frame layout */ 3648c2ecf20Sopenharmony_ci#define LRSAVE 16 3658c2ecf20Sopenharmony_ci 3668c2ecf20Sopenharmony_ci#else /* 32-bit */ 3678c2ecf20Sopenharmony_ci 3688c2ecf20Sopenharmony_ci#define LOAD_REG_IMMEDIATE(reg, expr) __LOAD_REG_IMMEDIATE_32 reg, expr 3698c2ecf20Sopenharmony_ci 3708c2ecf20Sopenharmony_ci#define LOAD_REG_IMMEDIATE_SYM(reg,expr) \ 3718c2ecf20Sopenharmony_ci lis reg,(expr)@ha; \ 3728c2ecf20Sopenharmony_ci addi reg,reg,(expr)@l; 3738c2ecf20Sopenharmony_ci 3748c2ecf20Sopenharmony_ci#define LOAD_REG_ADDR(reg,name) LOAD_REG_IMMEDIATE_SYM(reg, name) 3758c2ecf20Sopenharmony_ci 3768c2ecf20Sopenharmony_ci#define LOAD_REG_ADDRBASE(reg, name) lis reg,name@ha 3778c2ecf20Sopenharmony_ci#define ADDROFF(name) name@l 3788c2ecf20Sopenharmony_ci 3798c2ecf20Sopenharmony_ci/* offsets for stack frame layout */ 3808c2ecf20Sopenharmony_ci#define LRSAVE 4 3818c2ecf20Sopenharmony_ci 3828c2ecf20Sopenharmony_ci#endif 3838c2ecf20Sopenharmony_ci 3848c2ecf20Sopenharmony_ci/* various errata or part fixups */ 3858c2ecf20Sopenharmony_ci#if defined(CONFIG_PPC_CELL) || defined(CONFIG_PPC_FSL_BOOK3E) 3868c2ecf20Sopenharmony_ci#define MFTB(dest) \ 3878c2ecf20Sopenharmony_ci90: mfspr dest, SPRN_TBRL; \ 3888c2ecf20Sopenharmony_ciBEGIN_FTR_SECTION_NESTED(96); \ 3898c2ecf20Sopenharmony_ci cmpwi dest,0; \ 3908c2ecf20Sopenharmony_ci beq- 90b; \ 3918c2ecf20Sopenharmony_ciEND_FTR_SECTION_NESTED(CPU_FTR_CELL_TB_BUG, CPU_FTR_CELL_TB_BUG, 96) 3928c2ecf20Sopenharmony_ci#else 3938c2ecf20Sopenharmony_ci#define MFTB(dest) MFTBL(dest) 3948c2ecf20Sopenharmony_ci#endif 3958c2ecf20Sopenharmony_ci 3968c2ecf20Sopenharmony_ci#ifdef CONFIG_PPC_8xx 3978c2ecf20Sopenharmony_ci#define MFTBL(dest) mftb dest 3988c2ecf20Sopenharmony_ci#define MFTBU(dest) mftbu dest 3998c2ecf20Sopenharmony_ci#else 4008c2ecf20Sopenharmony_ci#define MFTBL(dest) mfspr dest, SPRN_TBRL 4018c2ecf20Sopenharmony_ci#define MFTBU(dest) mfspr dest, SPRN_TBRU 4028c2ecf20Sopenharmony_ci#endif 4038c2ecf20Sopenharmony_ci 4048c2ecf20Sopenharmony_ci#ifndef CONFIG_SMP 4058c2ecf20Sopenharmony_ci#define TLBSYNC 4068c2ecf20Sopenharmony_ci#else 4078c2ecf20Sopenharmony_ci#define TLBSYNC tlbsync; sync 4088c2ecf20Sopenharmony_ci#endif 4098c2ecf20Sopenharmony_ci 4108c2ecf20Sopenharmony_ci#ifdef CONFIG_PPC64 4118c2ecf20Sopenharmony_ci#define MTOCRF(FXM, RS) \ 4128c2ecf20Sopenharmony_ci BEGIN_FTR_SECTION_NESTED(848); \ 4138c2ecf20Sopenharmony_ci mtcrf (FXM), RS; \ 4148c2ecf20Sopenharmony_ci FTR_SECTION_ELSE_NESTED(848); \ 4158c2ecf20Sopenharmony_ci mtocrf (FXM), RS; \ 4168c2ecf20Sopenharmony_ci ALT_FTR_SECTION_END_NESTED_IFCLR(CPU_FTR_NOEXECUTE, 848) 4178c2ecf20Sopenharmony_ci#endif 4188c2ecf20Sopenharmony_ci 4198c2ecf20Sopenharmony_ci/* 4208c2ecf20Sopenharmony_ci * This instruction is not implemented on the PPC 603 or 601; however, on 4218c2ecf20Sopenharmony_ci * the 403GCX and 405GP tlbia IS defined and tlbie is not. 4228c2ecf20Sopenharmony_ci * All of these instructions exist in the 8xx, they have magical powers, 4238c2ecf20Sopenharmony_ci * and they must be used. 4248c2ecf20Sopenharmony_ci */ 4258c2ecf20Sopenharmony_ci 4268c2ecf20Sopenharmony_ci#if !defined(CONFIG_4xx) && !defined(CONFIG_PPC_8xx) 4278c2ecf20Sopenharmony_ci#define tlbia \ 4288c2ecf20Sopenharmony_ci li r4,1024; \ 4298c2ecf20Sopenharmony_ci mtctr r4; \ 4308c2ecf20Sopenharmony_ci lis r4,KERNELBASE@h; \ 4318c2ecf20Sopenharmony_ci .machine push; \ 4328c2ecf20Sopenharmony_ci .machine "power4"; \ 4338c2ecf20Sopenharmony_ci0: tlbie r4; \ 4348c2ecf20Sopenharmony_ci .machine pop; \ 4358c2ecf20Sopenharmony_ci addi r4,r4,0x1000; \ 4368c2ecf20Sopenharmony_ci bdnz 0b 4378c2ecf20Sopenharmony_ci#endif 4388c2ecf20Sopenharmony_ci 4398c2ecf20Sopenharmony_ci 4408c2ecf20Sopenharmony_ci#ifdef CONFIG_IBM440EP_ERR42 4418c2ecf20Sopenharmony_ci#define PPC440EP_ERR42 isync 4428c2ecf20Sopenharmony_ci#else 4438c2ecf20Sopenharmony_ci#define PPC440EP_ERR42 4448c2ecf20Sopenharmony_ci#endif 4458c2ecf20Sopenharmony_ci 4468c2ecf20Sopenharmony_ci/* The following stops all load and store data streams associated with stream 4478c2ecf20Sopenharmony_ci * ID (ie. streams created explicitly). The embedded and server mnemonics for 4488c2ecf20Sopenharmony_ci * dcbt are different so this must only be used for server. 4498c2ecf20Sopenharmony_ci */ 4508c2ecf20Sopenharmony_ci#define DCBT_BOOK3S_STOP_ALL_STREAM_IDS(scratch) \ 4518c2ecf20Sopenharmony_ci lis scratch,0x60000000@h; \ 4528c2ecf20Sopenharmony_ci dcbt 0,scratch,0b01010 4538c2ecf20Sopenharmony_ci 4548c2ecf20Sopenharmony_ci/* 4558c2ecf20Sopenharmony_ci * toreal/fromreal/tophys/tovirt macros. 32-bit BookE makes them 4568c2ecf20Sopenharmony_ci * keep the address intact to be compatible with code shared with 4578c2ecf20Sopenharmony_ci * 32-bit classic. 4588c2ecf20Sopenharmony_ci * 4598c2ecf20Sopenharmony_ci * On the other hand, I find it useful to have them behave as expected 4608c2ecf20Sopenharmony_ci * by their name (ie always do the addition) on 64-bit BookE 4618c2ecf20Sopenharmony_ci */ 4628c2ecf20Sopenharmony_ci#if defined(CONFIG_BOOKE) && !defined(CONFIG_PPC64) 4638c2ecf20Sopenharmony_ci#define toreal(rd) 4648c2ecf20Sopenharmony_ci#define fromreal(rd) 4658c2ecf20Sopenharmony_ci 4668c2ecf20Sopenharmony_ci/* 4678c2ecf20Sopenharmony_ci * We use addis to ensure compatibility with the "classic" ppc versions of 4688c2ecf20Sopenharmony_ci * these macros, which use rs = 0 to get the tophys offset in rd, rather than 4698c2ecf20Sopenharmony_ci * converting the address in r0, and so this version has to do that too 4708c2ecf20Sopenharmony_ci * (i.e. set register rd to 0 when rs == 0). 4718c2ecf20Sopenharmony_ci */ 4728c2ecf20Sopenharmony_ci#define tophys(rd,rs) \ 4738c2ecf20Sopenharmony_ci addis rd,rs,0 4748c2ecf20Sopenharmony_ci 4758c2ecf20Sopenharmony_ci#define tovirt(rd,rs) \ 4768c2ecf20Sopenharmony_ci addis rd,rs,0 4778c2ecf20Sopenharmony_ci 4788c2ecf20Sopenharmony_ci#elif defined(CONFIG_PPC64) 4798c2ecf20Sopenharmony_ci#define toreal(rd) /* we can access c000... in real mode */ 4808c2ecf20Sopenharmony_ci#define fromreal(rd) 4818c2ecf20Sopenharmony_ci 4828c2ecf20Sopenharmony_ci#define tophys(rd,rs) \ 4838c2ecf20Sopenharmony_ci clrldi rd,rs,2 4848c2ecf20Sopenharmony_ci 4858c2ecf20Sopenharmony_ci#define tovirt(rd,rs) \ 4868c2ecf20Sopenharmony_ci rotldi rd,rs,16; \ 4878c2ecf20Sopenharmony_ci ori rd,rd,((KERNELBASE>>48)&0xFFFF);\ 4888c2ecf20Sopenharmony_ci rotldi rd,rd,48 4898c2ecf20Sopenharmony_ci#else 4908c2ecf20Sopenharmony_ci#define toreal(rd) tophys(rd,rd) 4918c2ecf20Sopenharmony_ci#define fromreal(rd) tovirt(rd,rd) 4928c2ecf20Sopenharmony_ci 4938c2ecf20Sopenharmony_ci#define tophys(rd, rs) addis rd, rs, -PAGE_OFFSET@h 4948c2ecf20Sopenharmony_ci#define tovirt(rd, rs) addis rd, rs, PAGE_OFFSET@h 4958c2ecf20Sopenharmony_ci#endif 4968c2ecf20Sopenharmony_ci 4978c2ecf20Sopenharmony_ci#ifdef CONFIG_PPC_BOOK3S_64 4988c2ecf20Sopenharmony_ci#define RFI rfid 4998c2ecf20Sopenharmony_ci#define MTMSRD(r) mtmsrd r 5008c2ecf20Sopenharmony_ci#define MTMSR_EERI(reg) mtmsrd reg,1 5018c2ecf20Sopenharmony_ci#else 5028c2ecf20Sopenharmony_ci#ifndef CONFIG_40x 5038c2ecf20Sopenharmony_ci#define RFI rfi 5048c2ecf20Sopenharmony_ci#else 5058c2ecf20Sopenharmony_ci#define RFI rfi; b . /* Prevent prefetch past rfi */ 5068c2ecf20Sopenharmony_ci#endif 5078c2ecf20Sopenharmony_ci#define MTMSRD(r) mtmsr r 5088c2ecf20Sopenharmony_ci#define MTMSR_EERI(reg) mtmsr reg 5098c2ecf20Sopenharmony_ci#endif 5108c2ecf20Sopenharmony_ci 5118c2ecf20Sopenharmony_ci#endif /* __KERNEL__ */ 5128c2ecf20Sopenharmony_ci 5138c2ecf20Sopenharmony_ci/* The boring bits... */ 5148c2ecf20Sopenharmony_ci 5158c2ecf20Sopenharmony_ci/* Condition Register Bit Fields */ 5168c2ecf20Sopenharmony_ci 5178c2ecf20Sopenharmony_ci#define cr0 0 5188c2ecf20Sopenharmony_ci#define cr1 1 5198c2ecf20Sopenharmony_ci#define cr2 2 5208c2ecf20Sopenharmony_ci#define cr3 3 5218c2ecf20Sopenharmony_ci#define cr4 4 5228c2ecf20Sopenharmony_ci#define cr5 5 5238c2ecf20Sopenharmony_ci#define cr6 6 5248c2ecf20Sopenharmony_ci#define cr7 7 5258c2ecf20Sopenharmony_ci 5268c2ecf20Sopenharmony_ci 5278c2ecf20Sopenharmony_ci/* 5288c2ecf20Sopenharmony_ci * General Purpose Registers (GPRs) 5298c2ecf20Sopenharmony_ci * 5308c2ecf20Sopenharmony_ci * The lower case r0-r31 should be used in preference to the upper 5318c2ecf20Sopenharmony_ci * case R0-R31 as they provide more error checking in the assembler. 5328c2ecf20Sopenharmony_ci * Use R0-31 only when really nessesary. 5338c2ecf20Sopenharmony_ci */ 5348c2ecf20Sopenharmony_ci 5358c2ecf20Sopenharmony_ci#define r0 %r0 5368c2ecf20Sopenharmony_ci#define r1 %r1 5378c2ecf20Sopenharmony_ci#define r2 %r2 5388c2ecf20Sopenharmony_ci#define r3 %r3 5398c2ecf20Sopenharmony_ci#define r4 %r4 5408c2ecf20Sopenharmony_ci#define r5 %r5 5418c2ecf20Sopenharmony_ci#define r6 %r6 5428c2ecf20Sopenharmony_ci#define r7 %r7 5438c2ecf20Sopenharmony_ci#define r8 %r8 5448c2ecf20Sopenharmony_ci#define r9 %r9 5458c2ecf20Sopenharmony_ci#define r10 %r10 5468c2ecf20Sopenharmony_ci#define r11 %r11 5478c2ecf20Sopenharmony_ci#define r12 %r12 5488c2ecf20Sopenharmony_ci#define r13 %r13 5498c2ecf20Sopenharmony_ci#define r14 %r14 5508c2ecf20Sopenharmony_ci#define r15 %r15 5518c2ecf20Sopenharmony_ci#define r16 %r16 5528c2ecf20Sopenharmony_ci#define r17 %r17 5538c2ecf20Sopenharmony_ci#define r18 %r18 5548c2ecf20Sopenharmony_ci#define r19 %r19 5558c2ecf20Sopenharmony_ci#define r20 %r20 5568c2ecf20Sopenharmony_ci#define r21 %r21 5578c2ecf20Sopenharmony_ci#define r22 %r22 5588c2ecf20Sopenharmony_ci#define r23 %r23 5598c2ecf20Sopenharmony_ci#define r24 %r24 5608c2ecf20Sopenharmony_ci#define r25 %r25 5618c2ecf20Sopenharmony_ci#define r26 %r26 5628c2ecf20Sopenharmony_ci#define r27 %r27 5638c2ecf20Sopenharmony_ci#define r28 %r28 5648c2ecf20Sopenharmony_ci#define r29 %r29 5658c2ecf20Sopenharmony_ci#define r30 %r30 5668c2ecf20Sopenharmony_ci#define r31 %r31 5678c2ecf20Sopenharmony_ci 5688c2ecf20Sopenharmony_ci 5698c2ecf20Sopenharmony_ci/* Floating Point Registers (FPRs) */ 5708c2ecf20Sopenharmony_ci 5718c2ecf20Sopenharmony_ci#define fr0 0 5728c2ecf20Sopenharmony_ci#define fr1 1 5738c2ecf20Sopenharmony_ci#define fr2 2 5748c2ecf20Sopenharmony_ci#define fr3 3 5758c2ecf20Sopenharmony_ci#define fr4 4 5768c2ecf20Sopenharmony_ci#define fr5 5 5778c2ecf20Sopenharmony_ci#define fr6 6 5788c2ecf20Sopenharmony_ci#define fr7 7 5798c2ecf20Sopenharmony_ci#define fr8 8 5808c2ecf20Sopenharmony_ci#define fr9 9 5818c2ecf20Sopenharmony_ci#define fr10 10 5828c2ecf20Sopenharmony_ci#define fr11 11 5838c2ecf20Sopenharmony_ci#define fr12 12 5848c2ecf20Sopenharmony_ci#define fr13 13 5858c2ecf20Sopenharmony_ci#define fr14 14 5868c2ecf20Sopenharmony_ci#define fr15 15 5878c2ecf20Sopenharmony_ci#define fr16 16 5888c2ecf20Sopenharmony_ci#define fr17 17 5898c2ecf20Sopenharmony_ci#define fr18 18 5908c2ecf20Sopenharmony_ci#define fr19 19 5918c2ecf20Sopenharmony_ci#define fr20 20 5928c2ecf20Sopenharmony_ci#define fr21 21 5938c2ecf20Sopenharmony_ci#define fr22 22 5948c2ecf20Sopenharmony_ci#define fr23 23 5958c2ecf20Sopenharmony_ci#define fr24 24 5968c2ecf20Sopenharmony_ci#define fr25 25 5978c2ecf20Sopenharmony_ci#define fr26 26 5988c2ecf20Sopenharmony_ci#define fr27 27 5998c2ecf20Sopenharmony_ci#define fr28 28 6008c2ecf20Sopenharmony_ci#define fr29 29 6018c2ecf20Sopenharmony_ci#define fr30 30 6028c2ecf20Sopenharmony_ci#define fr31 31 6038c2ecf20Sopenharmony_ci 6048c2ecf20Sopenharmony_ci/* AltiVec Registers (VPRs) */ 6058c2ecf20Sopenharmony_ci 6068c2ecf20Sopenharmony_ci#define v0 0 6078c2ecf20Sopenharmony_ci#define v1 1 6088c2ecf20Sopenharmony_ci#define v2 2 6098c2ecf20Sopenharmony_ci#define v3 3 6108c2ecf20Sopenharmony_ci#define v4 4 6118c2ecf20Sopenharmony_ci#define v5 5 6128c2ecf20Sopenharmony_ci#define v6 6 6138c2ecf20Sopenharmony_ci#define v7 7 6148c2ecf20Sopenharmony_ci#define v8 8 6158c2ecf20Sopenharmony_ci#define v9 9 6168c2ecf20Sopenharmony_ci#define v10 10 6178c2ecf20Sopenharmony_ci#define v11 11 6188c2ecf20Sopenharmony_ci#define v12 12 6198c2ecf20Sopenharmony_ci#define v13 13 6208c2ecf20Sopenharmony_ci#define v14 14 6218c2ecf20Sopenharmony_ci#define v15 15 6228c2ecf20Sopenharmony_ci#define v16 16 6238c2ecf20Sopenharmony_ci#define v17 17 6248c2ecf20Sopenharmony_ci#define v18 18 6258c2ecf20Sopenharmony_ci#define v19 19 6268c2ecf20Sopenharmony_ci#define v20 20 6278c2ecf20Sopenharmony_ci#define v21 21 6288c2ecf20Sopenharmony_ci#define v22 22 6298c2ecf20Sopenharmony_ci#define v23 23 6308c2ecf20Sopenharmony_ci#define v24 24 6318c2ecf20Sopenharmony_ci#define v25 25 6328c2ecf20Sopenharmony_ci#define v26 26 6338c2ecf20Sopenharmony_ci#define v27 27 6348c2ecf20Sopenharmony_ci#define v28 28 6358c2ecf20Sopenharmony_ci#define v29 29 6368c2ecf20Sopenharmony_ci#define v30 30 6378c2ecf20Sopenharmony_ci#define v31 31 6388c2ecf20Sopenharmony_ci 6398c2ecf20Sopenharmony_ci/* VSX Registers (VSRs) */ 6408c2ecf20Sopenharmony_ci 6418c2ecf20Sopenharmony_ci#define vs0 0 6428c2ecf20Sopenharmony_ci#define vs1 1 6438c2ecf20Sopenharmony_ci#define vs2 2 6448c2ecf20Sopenharmony_ci#define vs3 3 6458c2ecf20Sopenharmony_ci#define vs4 4 6468c2ecf20Sopenharmony_ci#define vs5 5 6478c2ecf20Sopenharmony_ci#define vs6 6 6488c2ecf20Sopenharmony_ci#define vs7 7 6498c2ecf20Sopenharmony_ci#define vs8 8 6508c2ecf20Sopenharmony_ci#define vs9 9 6518c2ecf20Sopenharmony_ci#define vs10 10 6528c2ecf20Sopenharmony_ci#define vs11 11 6538c2ecf20Sopenharmony_ci#define vs12 12 6548c2ecf20Sopenharmony_ci#define vs13 13 6558c2ecf20Sopenharmony_ci#define vs14 14 6568c2ecf20Sopenharmony_ci#define vs15 15 6578c2ecf20Sopenharmony_ci#define vs16 16 6588c2ecf20Sopenharmony_ci#define vs17 17 6598c2ecf20Sopenharmony_ci#define vs18 18 6608c2ecf20Sopenharmony_ci#define vs19 19 6618c2ecf20Sopenharmony_ci#define vs20 20 6628c2ecf20Sopenharmony_ci#define vs21 21 6638c2ecf20Sopenharmony_ci#define vs22 22 6648c2ecf20Sopenharmony_ci#define vs23 23 6658c2ecf20Sopenharmony_ci#define vs24 24 6668c2ecf20Sopenharmony_ci#define vs25 25 6678c2ecf20Sopenharmony_ci#define vs26 26 6688c2ecf20Sopenharmony_ci#define vs27 27 6698c2ecf20Sopenharmony_ci#define vs28 28 6708c2ecf20Sopenharmony_ci#define vs29 29 6718c2ecf20Sopenharmony_ci#define vs30 30 6728c2ecf20Sopenharmony_ci#define vs31 31 6738c2ecf20Sopenharmony_ci#define vs32 32 6748c2ecf20Sopenharmony_ci#define vs33 33 6758c2ecf20Sopenharmony_ci#define vs34 34 6768c2ecf20Sopenharmony_ci#define vs35 35 6778c2ecf20Sopenharmony_ci#define vs36 36 6788c2ecf20Sopenharmony_ci#define vs37 37 6798c2ecf20Sopenharmony_ci#define vs38 38 6808c2ecf20Sopenharmony_ci#define vs39 39 6818c2ecf20Sopenharmony_ci#define vs40 40 6828c2ecf20Sopenharmony_ci#define vs41 41 6838c2ecf20Sopenharmony_ci#define vs42 42 6848c2ecf20Sopenharmony_ci#define vs43 43 6858c2ecf20Sopenharmony_ci#define vs44 44 6868c2ecf20Sopenharmony_ci#define vs45 45 6878c2ecf20Sopenharmony_ci#define vs46 46 6888c2ecf20Sopenharmony_ci#define vs47 47 6898c2ecf20Sopenharmony_ci#define vs48 48 6908c2ecf20Sopenharmony_ci#define vs49 49 6918c2ecf20Sopenharmony_ci#define vs50 50 6928c2ecf20Sopenharmony_ci#define vs51 51 6938c2ecf20Sopenharmony_ci#define vs52 52 6948c2ecf20Sopenharmony_ci#define vs53 53 6958c2ecf20Sopenharmony_ci#define vs54 54 6968c2ecf20Sopenharmony_ci#define vs55 55 6978c2ecf20Sopenharmony_ci#define vs56 56 6988c2ecf20Sopenharmony_ci#define vs57 57 6998c2ecf20Sopenharmony_ci#define vs58 58 7008c2ecf20Sopenharmony_ci#define vs59 59 7018c2ecf20Sopenharmony_ci#define vs60 60 7028c2ecf20Sopenharmony_ci#define vs61 61 7038c2ecf20Sopenharmony_ci#define vs62 62 7048c2ecf20Sopenharmony_ci#define vs63 63 7058c2ecf20Sopenharmony_ci 7068c2ecf20Sopenharmony_ci/* SPE Registers (EVPRs) */ 7078c2ecf20Sopenharmony_ci 7088c2ecf20Sopenharmony_ci#define evr0 0 7098c2ecf20Sopenharmony_ci#define evr1 1 7108c2ecf20Sopenharmony_ci#define evr2 2 7118c2ecf20Sopenharmony_ci#define evr3 3 7128c2ecf20Sopenharmony_ci#define evr4 4 7138c2ecf20Sopenharmony_ci#define evr5 5 7148c2ecf20Sopenharmony_ci#define evr6 6 7158c2ecf20Sopenharmony_ci#define evr7 7 7168c2ecf20Sopenharmony_ci#define evr8 8 7178c2ecf20Sopenharmony_ci#define evr9 9 7188c2ecf20Sopenharmony_ci#define evr10 10 7198c2ecf20Sopenharmony_ci#define evr11 11 7208c2ecf20Sopenharmony_ci#define evr12 12 7218c2ecf20Sopenharmony_ci#define evr13 13 7228c2ecf20Sopenharmony_ci#define evr14 14 7238c2ecf20Sopenharmony_ci#define evr15 15 7248c2ecf20Sopenharmony_ci#define evr16 16 7258c2ecf20Sopenharmony_ci#define evr17 17 7268c2ecf20Sopenharmony_ci#define evr18 18 7278c2ecf20Sopenharmony_ci#define evr19 19 7288c2ecf20Sopenharmony_ci#define evr20 20 7298c2ecf20Sopenharmony_ci#define evr21 21 7308c2ecf20Sopenharmony_ci#define evr22 22 7318c2ecf20Sopenharmony_ci#define evr23 23 7328c2ecf20Sopenharmony_ci#define evr24 24 7338c2ecf20Sopenharmony_ci#define evr25 25 7348c2ecf20Sopenharmony_ci#define evr26 26 7358c2ecf20Sopenharmony_ci#define evr27 27 7368c2ecf20Sopenharmony_ci#define evr28 28 7378c2ecf20Sopenharmony_ci#define evr29 29 7388c2ecf20Sopenharmony_ci#define evr30 30 7398c2ecf20Sopenharmony_ci#define evr31 31 7408c2ecf20Sopenharmony_ci 7418c2ecf20Sopenharmony_ci/* some stab codes */ 7428c2ecf20Sopenharmony_ci#define N_FUN 36 7438c2ecf20Sopenharmony_ci#define N_RSYM 64 7448c2ecf20Sopenharmony_ci#define N_SLINE 68 7458c2ecf20Sopenharmony_ci#define N_SO 100 7468c2ecf20Sopenharmony_ci 7478c2ecf20Sopenharmony_ci#define RFSCV .long 0x4c0000a4 7488c2ecf20Sopenharmony_ci 7498c2ecf20Sopenharmony_ci/* 7508c2ecf20Sopenharmony_ci * Create an endian fixup trampoline 7518c2ecf20Sopenharmony_ci * 7528c2ecf20Sopenharmony_ci * This starts with a "tdi 0,0,0x48" instruction which is 7538c2ecf20Sopenharmony_ci * essentially a "trap never", and thus akin to a nop. 7548c2ecf20Sopenharmony_ci * 7558c2ecf20Sopenharmony_ci * The opcode for this instruction read with the wrong endian 7568c2ecf20Sopenharmony_ci * however results in a b . + 8 7578c2ecf20Sopenharmony_ci * 7588c2ecf20Sopenharmony_ci * So essentially we use that trick to execute the following 7598c2ecf20Sopenharmony_ci * trampoline in "reverse endian" if we are running with the 7608c2ecf20Sopenharmony_ci * MSR_LE bit set the "wrong" way for whatever endianness the 7618c2ecf20Sopenharmony_ci * kernel is built for. 7628c2ecf20Sopenharmony_ci */ 7638c2ecf20Sopenharmony_ci 7648c2ecf20Sopenharmony_ci#ifdef CONFIG_PPC_BOOK3E 7658c2ecf20Sopenharmony_ci#define FIXUP_ENDIAN 7668c2ecf20Sopenharmony_ci#else 7678c2ecf20Sopenharmony_ci/* 7688c2ecf20Sopenharmony_ci * This version may be used in HV or non-HV context. 7698c2ecf20Sopenharmony_ci * MSR[EE] must be disabled. 7708c2ecf20Sopenharmony_ci */ 7718c2ecf20Sopenharmony_ci#define FIXUP_ENDIAN \ 7728c2ecf20Sopenharmony_ci tdi 0,0,0x48; /* Reverse endian of b . + 8 */ \ 7738c2ecf20Sopenharmony_ci b 191f; /* Skip trampoline if endian is good */ \ 7748c2ecf20Sopenharmony_ci .long 0xa600607d; /* mfmsr r11 */ \ 7758c2ecf20Sopenharmony_ci .long 0x01006b69; /* xori r11,r11,1 */ \ 7768c2ecf20Sopenharmony_ci .long 0x00004039; /* li r10,0 */ \ 7778c2ecf20Sopenharmony_ci .long 0x6401417d; /* mtmsrd r10,1 */ \ 7788c2ecf20Sopenharmony_ci .long 0x05009f42; /* bcl 20,31,$+4 */ \ 7798c2ecf20Sopenharmony_ci .long 0xa602487d; /* mflr r10 */ \ 7808c2ecf20Sopenharmony_ci .long 0x14004a39; /* addi r10,r10,20 */ \ 7818c2ecf20Sopenharmony_ci .long 0xa6035a7d; /* mtsrr0 r10 */ \ 7828c2ecf20Sopenharmony_ci .long 0xa6037b7d; /* mtsrr1 r11 */ \ 7838c2ecf20Sopenharmony_ci .long 0x2400004c; /* rfid */ \ 7848c2ecf20Sopenharmony_ci191: 7858c2ecf20Sopenharmony_ci 7868c2ecf20Sopenharmony_ci/* 7878c2ecf20Sopenharmony_ci * This version that may only be used with MSR[HV]=1 7888c2ecf20Sopenharmony_ci * - Does not clear MSR[RI], so more robust. 7898c2ecf20Sopenharmony_ci * - Slightly smaller and faster. 7908c2ecf20Sopenharmony_ci */ 7918c2ecf20Sopenharmony_ci#define FIXUP_ENDIAN_HV \ 7928c2ecf20Sopenharmony_ci tdi 0,0,0x48; /* Reverse endian of b . + 8 */ \ 7938c2ecf20Sopenharmony_ci b 191f; /* Skip trampoline if endian is good */ \ 7948c2ecf20Sopenharmony_ci .long 0xa600607d; /* mfmsr r11 */ \ 7958c2ecf20Sopenharmony_ci .long 0x01006b69; /* xori r11,r11,1 */ \ 7968c2ecf20Sopenharmony_ci .long 0x05009f42; /* bcl 20,31,$+4 */ \ 7978c2ecf20Sopenharmony_ci .long 0xa602487d; /* mflr r10 */ \ 7988c2ecf20Sopenharmony_ci .long 0x14004a39; /* addi r10,r10,20 */ \ 7998c2ecf20Sopenharmony_ci .long 0xa64b5a7d; /* mthsrr0 r10 */ \ 8008c2ecf20Sopenharmony_ci .long 0xa64b7b7d; /* mthsrr1 r11 */ \ 8018c2ecf20Sopenharmony_ci .long 0x2402004c; /* hrfid */ \ 8028c2ecf20Sopenharmony_ci191: 8038c2ecf20Sopenharmony_ci 8048c2ecf20Sopenharmony_ci#endif /* !CONFIG_PPC_BOOK3E */ 8058c2ecf20Sopenharmony_ci 8068c2ecf20Sopenharmony_ci#endif /* __ASSEMBLY__ */ 8078c2ecf20Sopenharmony_ci 8088c2ecf20Sopenharmony_ci/* 8098c2ecf20Sopenharmony_ci * Helper macro for exception table entries 8108c2ecf20Sopenharmony_ci */ 8118c2ecf20Sopenharmony_ci#define EX_TABLE(_fault, _target) \ 8128c2ecf20Sopenharmony_ci stringify_in_c(.section __ex_table,"a";)\ 8138c2ecf20Sopenharmony_ci stringify_in_c(.balign 4;) \ 8148c2ecf20Sopenharmony_ci stringify_in_c(.long (_fault) - . ;) \ 8158c2ecf20Sopenharmony_ci stringify_in_c(.long (_target) - . ;) \ 8168c2ecf20Sopenharmony_ci stringify_in_c(.previous) 8178c2ecf20Sopenharmony_ci 8188c2ecf20Sopenharmony_ci#ifdef CONFIG_PPC_FSL_BOOK3E 8198c2ecf20Sopenharmony_ci#define BTB_FLUSH(reg) \ 8208c2ecf20Sopenharmony_ci lis reg,BUCSR_INIT@h; \ 8218c2ecf20Sopenharmony_ci ori reg,reg,BUCSR_INIT@l; \ 8228c2ecf20Sopenharmony_ci mtspr SPRN_BUCSR,reg; \ 8238c2ecf20Sopenharmony_ci isync; 8248c2ecf20Sopenharmony_ci#else 8258c2ecf20Sopenharmony_ci#define BTB_FLUSH(reg) 8268c2ecf20Sopenharmony_ci#endif /* CONFIG_PPC_FSL_BOOK3E */ 8278c2ecf20Sopenharmony_ci 8288c2ecf20Sopenharmony_ci#endif /* _ASM_POWERPC_PPC_ASM_H */ 829