2  * Copyright (C) 1995-1999 Gary Thomas, Paul Mackerras, Cort Dougan.
 
   4 #ifndef _ASM_POWERPC_PPC_ASM_H
 
   5 #define _ASM_POWERPC_PPC_ASM_H
 
   7 #include <linux/stringify.h>
 
   8 #include <asm/asm-compat.h>
 
  11 #error __FILE__ should only be used in assembler files
 
  14 #define SZL                     (BITS_PER_LONG/8)
 
  17  * Stuff for accurate CPU time accounting.
 
  18  * These macros handle transitions between user and system state
 
  19  * in exception entry and exit and accumulate time to the
 
  20  * user_time and system_time fields in the paca.
 
  23 #ifndef CONFIG_VIRT_CPU_ACCOUNTING
 
  24 #define ACCOUNT_CPU_USER_ENTRY(ra, rb)
 
  25 #define ACCOUNT_CPU_USER_EXIT(ra, rb)
 
  27 #define ACCOUNT_CPU_USER_ENTRY(ra, rb)                                  \
 
  28         beq     2f;                     /* if from kernel mode */       \
 
  30         mfspr   ra,SPRN_PURR;           /* get processor util. reg */   \
 
  31 END_FTR_SECTION_IFSET(CPU_FTR_PURR);                                    \
 
  33         MFTB(ra);                       /* or get TB if no PURR */      \
 
  34 END_FTR_SECTION_IFCLR(CPU_FTR_PURR);                                    \
 
  35         ld      rb,PACA_STARTPURR(r13);                                 \
 
  36         std     ra,PACA_STARTPURR(r13);                                 \
 
  37         subf    rb,rb,ra;               /* subtract start value */      \
 
  38         ld      ra,PACA_USER_TIME(r13);                                 \
 
  39         add     ra,ra,rb;               /* add on to user time */       \
 
  40         std     ra,PACA_USER_TIME(r13);                                 \
 
  43 #define ACCOUNT_CPU_USER_EXIT(ra, rb)                                   \
 
  45         mfspr   ra,SPRN_PURR;           /* get processor util. reg */   \
 
  46 END_FTR_SECTION_IFSET(CPU_FTR_PURR);                                    \
 
  48         MFTB(ra);                       /* or get TB if no PURR */      \
 
  49 END_FTR_SECTION_IFCLR(CPU_FTR_PURR);                                    \
 
  50         ld      rb,PACA_STARTPURR(r13);                                 \
 
  51         std     ra,PACA_STARTPURR(r13);                                 \
 
  52         subf    rb,rb,ra;               /* subtract start value */      \
 
  53         ld      ra,PACA_SYSTEM_TIME(r13);                               \
 
  54         add     ra,ra,rb;               /* add on to user time */       \
 
  55         std     ra,PACA_SYSTEM_TIME(r13);
 
  59  * Macros for storing registers into and loading registers from
 
  63 #define SAVE_GPR(n, base)       std     n,GPR0+8*(n)(base)
 
  64 #define REST_GPR(n, base)       ld      n,GPR0+8*(n)(base)
 
  65 #define SAVE_NVGPRS(base)       SAVE_8GPRS(14, base); SAVE_10GPRS(22, base)
 
  66 #define REST_NVGPRS(base)       REST_8GPRS(14, base); REST_10GPRS(22, base)
 
  68 #define SAVE_GPR(n, base)       stw     n,GPR0+4*(n)(base)
 
  69 #define REST_GPR(n, base)       lwz     n,GPR0+4*(n)(base)
 
  70 #define SAVE_NVGPRS(base)       SAVE_GPR(13, base); SAVE_8GPRS(14, base); \
 
  72 #define REST_NVGPRS(base)       REST_GPR(13, base); REST_8GPRS(14, base); \
 
  77 #define SAVE_2GPRS(n, base)     SAVE_GPR(n, base); SAVE_GPR(n+1, base)
 
  78 #define SAVE_4GPRS(n, base)     SAVE_2GPRS(n, base); SAVE_2GPRS(n+2, base)
 
  79 #define SAVE_8GPRS(n, base)     SAVE_4GPRS(n, base); SAVE_4GPRS(n+4, base)
 
  80 #define SAVE_10GPRS(n, base)    SAVE_8GPRS(n, base); SAVE_2GPRS(n+8, base)
 
  81 #define REST_2GPRS(n, base)     REST_GPR(n, base); REST_GPR(n+1, base)
 
  82 #define REST_4GPRS(n, base)     REST_2GPRS(n, base); REST_2GPRS(n+2, base)
 
  83 #define REST_8GPRS(n, base)     REST_4GPRS(n, base); REST_4GPRS(n+4, base)
 
  84 #define REST_10GPRS(n, base)    REST_8GPRS(n, base); REST_2GPRS(n+8, base)
 
  86 #define SAVE_FPR(n, base)       stfd    n,THREAD_FPR0+8*(n)(base)
 
  87 #define SAVE_2FPRS(n, base)     SAVE_FPR(n, base); SAVE_FPR(n+1, base)
 
  88 #define SAVE_4FPRS(n, base)     SAVE_2FPRS(n, base); SAVE_2FPRS(n+2, base)
 
  89 #define SAVE_8FPRS(n, base)     SAVE_4FPRS(n, base); SAVE_4FPRS(n+4, base)
 
  90 #define SAVE_16FPRS(n, base)    SAVE_8FPRS(n, base); SAVE_8FPRS(n+8, base)
 
  91 #define SAVE_32FPRS(n, base)    SAVE_16FPRS(n, base); SAVE_16FPRS(n+16, base)
 
  92 #define REST_FPR(n, base)       lfd     n,THREAD_FPR0+8*(n)(base)
 
  93 #define REST_2FPRS(n, base)     REST_FPR(n, base); REST_FPR(n+1, base)
 
  94 #define REST_4FPRS(n, base)     REST_2FPRS(n, base); REST_2FPRS(n+2, base)
 
  95 #define REST_8FPRS(n, base)     REST_4FPRS(n, base); REST_4FPRS(n+4, base)
 
  96 #define REST_16FPRS(n, base)    REST_8FPRS(n, base); REST_8FPRS(n+8, base)
 
  97 #define REST_32FPRS(n, base)    REST_16FPRS(n, base); REST_16FPRS(n+16, base)
 
  99 #define SAVE_VR(n,b,base)       li b,THREAD_VR0+(16*(n));  stvx n,b,base
 
 100 #define SAVE_2VRS(n,b,base)     SAVE_VR(n,b,base); SAVE_VR(n+1,b,base)
 
 101 #define SAVE_4VRS(n,b,base)     SAVE_2VRS(n,b,base); SAVE_2VRS(n+2,b,base)
 
 102 #define SAVE_8VRS(n,b,base)     SAVE_4VRS(n,b,base); SAVE_4VRS(n+4,b,base)
 
 103 #define SAVE_16VRS(n,b,base)    SAVE_8VRS(n,b,base); SAVE_8VRS(n+8,b,base)
 
 104 #define SAVE_32VRS(n,b,base)    SAVE_16VRS(n,b,base); SAVE_16VRS(n+16,b,base)
 
 105 #define REST_VR(n,b,base)       li b,THREAD_VR0+(16*(n)); lvx n,b,base
 
 106 #define REST_2VRS(n,b,base)     REST_VR(n,b,base); REST_VR(n+1,b,base)
 
 107 #define REST_4VRS(n,b,base)     REST_2VRS(n,b,base); REST_2VRS(n+2,b,base)
 
 108 #define REST_8VRS(n,b,base)     REST_4VRS(n,b,base); REST_4VRS(n+4,b,base)
 
 109 #define REST_16VRS(n,b,base)    REST_8VRS(n,b,base); REST_8VRS(n+8,b,base)
 
 110 #define REST_32VRS(n,b,base)    REST_16VRS(n,b,base); REST_16VRS(n+16,b,base)
 
 112 #define SAVE_EVR(n,s,base)      evmergehi s,s,n; stw s,THREAD_EVR0+4*(n)(base)
 
 113 #define SAVE_2EVRS(n,s,base)    SAVE_EVR(n,s,base); SAVE_EVR(n+1,s,base)
 
 114 #define SAVE_4EVRS(n,s,base)    SAVE_2EVRS(n,s,base); SAVE_2EVRS(n+2,s,base)
 
 115 #define SAVE_8EVRS(n,s,base)    SAVE_4EVRS(n,s,base); SAVE_4EVRS(n+4,s,base)
 
 116 #define SAVE_16EVRS(n,s,base)   SAVE_8EVRS(n,s,base); SAVE_8EVRS(n+8,s,base)
 
 117 #define SAVE_32EVRS(n,s,base)   SAVE_16EVRS(n,s,base); SAVE_16EVRS(n+16,s,base)
 
 118 #define REST_EVR(n,s,base)      lwz s,THREAD_EVR0+4*(n)(base); evmergelo n,s,n
 
 119 #define REST_2EVRS(n,s,base)    REST_EVR(n,s,base); REST_EVR(n+1,s,base)
 
 120 #define REST_4EVRS(n,s,base)    REST_2EVRS(n,s,base); REST_2EVRS(n+2,s,base)
 
 121 #define REST_8EVRS(n,s,base)    REST_4EVRS(n,s,base); REST_4EVRS(n+4,s,base)
 
 122 #define REST_16EVRS(n,s,base)   REST_8EVRS(n,s,base); REST_8EVRS(n+8,s,base)
 
 123 #define REST_32EVRS(n,s,base)   REST_16EVRS(n,s,base); REST_16EVRS(n+16,s,base)
 
 125 /* Macros to adjust thread priority for hardware multithreading */
 
 126 #define HMT_VERY_LOW    or      31,31,31        # very low priority
 
 127 #define HMT_LOW         or      1,1,1
 
 128 #define HMT_MEDIUM_LOW  or      6,6,6           # medium low priority
 
 129 #define HMT_MEDIUM      or      2,2,2
 
 130 #define HMT_MEDIUM_HIGH or      5,5,5           # medium high priority
 
 131 #define HMT_HIGH        or      3,3,3
 
 133 /* handle instructions that older assemblers may not know */
 
 134 #define RFCI            .long 0x4c000066        /* rfci instruction */
 
 135 #define RFDI            .long 0x4c00004e        /* rfdi instruction */
 
 136 #define RFMCI           .long 0x4c00004c        /* rfmci instruction */
 
 141 #define XGLUE(a,b) a##b
 
 142 #define GLUE(a,b) XGLUE(a,b)
 
 144 #define _GLOBAL(name) \
 
 148         .globl GLUE(.,name); \
 
 149         .section ".opd","aw"; \
 
 151         .quad GLUE(.,name); \
 
 152         .quad .TOC.@tocbase; \
 
 155         .type GLUE(.,name),@function; \
 
 158 #define _KPROBE(name) \
 
 159         .section ".kprobes.text","a"; \
 
 162         .globl GLUE(.,name); \
 
 163         .section ".opd","aw"; \
 
 165         .quad GLUE(.,name); \
 
 166         .quad .TOC.@tocbase; \
 
 169         .type GLUE(.,name),@function; \
 
 172 #define _STATIC(name) \
 
 175         .section ".opd","aw"; \
 
 177         .quad GLUE(.,name); \
 
 178         .quad .TOC.@tocbase; \
 
 181         .type GLUE(.,name),@function; \
 
 188         .stabs __stringify(n:F-1),N_FUN,0,0,n;\
 
 193         .section ".kprobes.text","a";   \
 
 200  * LOAD_REG_IMMEDIATE(rn, expr)
 
 201  *   Loads the value of the constant expression 'expr' into register 'rn'
 
 202  *   using immediate instructions only.  Use this when it's important not
 
 203  *   to reference other data (i.e. on ppc64 when the TOC pointer is not
 
 206  * LOAD_REG_ADDR(rn, name)
 
 207  *   Loads the address of label 'name' into register 'rn'.  Use this when
 
 208  *   you don't particularly need immediate instructions only, but you need
 
 209  *   the whole address in one register (e.g. it's a structure address and
 
 210  *   you want to access various offsets within it).  On ppc32 this is
 
 211  *   identical to LOAD_REG_IMMEDIATE.
 
 213  * LOAD_REG_ADDRBASE(rn, name)
 
 215  *   LOAD_REG_ADDRBASE loads part of the address of label 'name' into
 
 216  *   register 'rn'.  ADDROFF(name) returns the remainder of the address as
 
 217  *   a constant expression.  ADDROFF(name) is a signed expression < 16 bits
 
 218  *   in size, so is suitable for use directly as an offset in load and store
 
 219  *   instructions.  Use this when loading/storing a single word or less as:
 
 220  *      LOAD_REG_ADDRBASE(rX, name)
 
 221  *      ld      rY,ADDROFF(name)(rX)
 
 224 #define LOAD_REG_IMMEDIATE(reg,expr)            \
 
 225         lis     (reg),(expr)@highest;           \
 
 226         ori     (reg),(reg),(expr)@higher;      \
 
 227         rldicr  (reg),(reg),32,31;              \
 
 228         oris    (reg),(reg),(expr)@h;           \
 
 229         ori     (reg),(reg),(expr)@l;
 
 231 #define LOAD_REG_ADDR(reg,name)                 \
 
 232         ld      (reg),name@got(r2)
 
 234 #define LOAD_REG_ADDRBASE(reg,name)     LOAD_REG_ADDR(reg,name)
 
 235 #define ADDROFF(name)                   0
 
 237 /* offsets for stack frame layout */
 
 242 #define LOAD_REG_IMMEDIATE(reg,expr)            \
 
 243         lis     (reg),(expr)@ha;                \
 
 244         addi    (reg),(reg),(expr)@l;
 
 246 #define LOAD_REG_ADDR(reg,name)         LOAD_REG_IMMEDIATE(reg, name)
 
 248 #define LOAD_REG_ADDRBASE(reg, name)    lis     (reg),name@ha
 
 249 #define ADDROFF(name)                   name@l
 
 251 /* offsets for stack frame layout */
 
 256 /* various errata or part fixups */
 
 257 #ifdef CONFIG_PPC601_SYNC_FIX
 
 262 END_FTR_SECTION_IFSET(CPU_FTR_601)
 
 266 END_FTR_SECTION_IFSET(CPU_FTR_601)
 
 270 END_FTR_SECTION_IFSET(CPU_FTR_601)
 
 277 #ifdef CONFIG_PPC_CELL
 
 280 BEGIN_FTR_SECTION_NESTED(96);           \
 
 283 END_FTR_SECTION_NESTED(CPU_FTR_CELL_TB_BUG, CPU_FTR_CELL_TB_BUG, 96)
 
 285 #define MFTB(dest)                      mftb dest
 
 290 #else /* CONFIG_SMP */
 
 291 /* tlbsync is not implemented on 601 */
 
 296 END_FTR_SECTION_IFCLR(CPU_FTR_601)
 
 301  * This instruction is not implemented on the PPC 603 or 601; however, on
 
 302  * the 403GCX and 405GP tlbia IS defined and tlbie is not.
 
 303  * All of these instructions exist in the 8xx, they have magical powers,
 
 304  * and they must be used.
 
 307 #if !defined(CONFIG_4xx) && !defined(CONFIG_8xx)
 
 311         lis     r4,KERNELBASE@h;                \
 
 318 #ifdef CONFIG_IBM440EP_ERR42
 
 319 #define PPC440EP_ERR42 isync
 
 321 #define PPC440EP_ERR42
 
 325 #if defined(CONFIG_BOOKE)
 
 329 #define tophys(rd,rs)                           \
 
 332 #define tovirt(rd,rs)                           \
 
 335 #elif defined(CONFIG_PPC64)
 
 336 #define toreal(rd)              /* we can access c000... in real mode */
 
 339 #define tophys(rd,rs)                           \
 
 342 #define tovirt(rd,rs)                           \
 
 344         ori     rd,rd,((KERNELBASE>>48)&0xFFFF);\
 
 348  * On APUS (Amiga PowerPC cpu upgrade board), we don't know the
 
 349  * physical base address of RAM at compile time.
 
 351 #define toreal(rd)      tophys(rd,rd)
 
 352 #define fromreal(rd)    tovirt(rd,rd)
 
 354 #define tophys(rd,rs)                           \
 
 355 0:      addis   rd,rs,-KERNELBASE@h;            \
 
 356         .section ".vtop_fixup","aw";            \
 
 361 #define tovirt(rd,rs)                           \
 
 362 0:      addis   rd,rs,KERNELBASE@h;             \
 
 363         .section ".ptov_fixup","aw";            \
 
 371 #define MTMSRD(r)       mtmsrd  r
 
 374 #define FIX_SRR1(ra, rb)
 
 378 #define RFI             rfi; b .        /* Prevent prefetch past rfi */
 
 380 #define MTMSRD(r)       mtmsr   r
 
 384 #endif /* __KERNEL__ */
 
 386 /* The boring bits... */
 
 388 /* Condition Register Bit Fields */
 
 400 /* General Purpose Registers (GPRs) */
 
 436 /* Floating Point Registers (FPRs) */
 
 471 /* AltiVec Registers (VPRs) */
 
 506 /* SPE Registers (EVPRs) */
 
 541 /* some stab codes */
 
 547 #endif /*  __ASSEMBLY__ */
 
 549 #endif /* _ASM_POWERPC_PPC_ASM_H */