libata: dev_config does not need ap and adev passing
[safe/jmp/linux-2.6] / include / asm-powerpc / ppc_asm.h
index 96367e0..fa083d8 100644 (file)
@@ -5,9 +5,55 @@
 #define _ASM_POWERPC_PPC_ASM_H
 
 #include <linux/stringify.h>
-#include <linux/config.h>
+#include <asm/asm-compat.h>
 
-#ifdef __ASSEMBLY__
+#ifndef __ASSEMBLY__
+#error __FILE__ should only be used in assembler files
+#else
+
+#define SZL                    (BITS_PER_LONG/8)
+
+/*
+ * Stuff for accurate CPU time accounting.
+ * These macros handle transitions between user and system state
+ * in exception entry and exit and accumulate time to the
+ * user_time and system_time fields in the paca.
+ */
+
+#ifndef CONFIG_VIRT_CPU_ACCOUNTING
+#define ACCOUNT_CPU_USER_ENTRY(ra, rb)
+#define ACCOUNT_CPU_USER_EXIT(ra, rb)
+#else
+#define ACCOUNT_CPU_USER_ENTRY(ra, rb)                                 \
+       beq     2f;                     /* if from kernel mode */       \
+BEGIN_FTR_SECTION;                                                     \
+       mfspr   ra,SPRN_PURR;           /* get processor util. reg */   \
+END_FTR_SECTION_IFSET(CPU_FTR_PURR);                                   \
+BEGIN_FTR_SECTION;                                                     \
+       MFTB(ra);                       /* or get TB if no PURR */      \
+END_FTR_SECTION_IFCLR(CPU_FTR_PURR);                                   \
+       ld      rb,PACA_STARTPURR(r13);                                 \
+       std     ra,PACA_STARTPURR(r13);                                 \
+       subf    rb,rb,ra;               /* subtract start value */      \
+       ld      ra,PACA_USER_TIME(r13);                                 \
+       add     ra,ra,rb;               /* add on to user time */       \
+       std     ra,PACA_USER_TIME(r13);                                 \
+2:
+
+#define ACCOUNT_CPU_USER_EXIT(ra, rb)                                  \
+BEGIN_FTR_SECTION;                                                     \
+       mfspr   ra,SPRN_PURR;           /* get processor util. reg */   \
+END_FTR_SECTION_IFSET(CPU_FTR_PURR);                                   \
+BEGIN_FTR_SECTION;                                                     \
+       MFTB(ra);                       /* or get TB if no PURR */      \
+END_FTR_SECTION_IFCLR(CPU_FTR_PURR);                                   \
+       ld      rb,PACA_STARTPURR(r13);                                 \
+       std     ra,PACA_STARTPURR(r13);                                 \
+       subf    rb,rb,ra;               /* subtract start value */      \
+       ld      ra,PACA_SYSTEM_TIME(r13);                               \
+       add     ra,ra,rb;               /* add on to user time */       \
+       std     ra,PACA_SYSTEM_TIME(r13);
+#endif
 
 /*
  * Macros for storing registers into and loading registers from
 #define REST_16EVRS(n,s,base)  REST_8EVRS(n,s,base); REST_8EVRS(n+8,s,base)
 #define REST_32EVRS(n,s,base)  REST_16EVRS(n,s,base); REST_16EVRS(n+16,s,base)
 
-/* Macros to adjust thread priority for Iseries hardware multithreading */
-#define HMT_VERY_LOW    or   31,31,31  # very low priority\n"
-#define HMT_LOW                or 1,1,1
-#define HMT_MEDIUM_LOW  or   6,6,6     # medium low priority\n"
-#define HMT_MEDIUM     or 2,2,2
-#define HMT_MEDIUM_HIGH or   5,5,5     # medium high priority\n"
-#define HMT_HIGH       or 3,3,3
+/* Macros to adjust thread priority for hardware multithreading */
+#define HMT_VERY_LOW   or      31,31,31        # very low priority
+#define HMT_LOW                or      1,1,1
+#define HMT_MEDIUM_LOW  or     6,6,6           # medium low priority
+#define HMT_MEDIUM     or      2,2,2
+#define HMT_MEDIUM_HIGH or     5,5,5           # medium high priority
+#define HMT_HIGH       or      3,3,3
 
 /* handle instructions that older assemblers may not know */
 #define RFCI           .long 0x4c000066        /* rfci instruction */
 #define RFDI           .long 0x4c00004e        /* rfdi instruction */
 #define RFMCI          .long 0x4c00004c        /* rfmci instruction */
 
+#ifdef __KERNEL__
 #ifdef CONFIG_PPC64
 
 #define XGLUE(a,b) a##b
@@ -150,62 +197,59 @@ n:
 #endif
 
 /* 
- * LOADADDR( rn, name )
- *   loads the address of 'name' into 'rn'
+ * LOAD_REG_IMMEDIATE(rn, expr)
+ *   Loads the value of the constant expression 'expr' into register 'rn'
+ *   using immediate instructions only.  Use this when it's important not
+ *   to reference other data (i.e. on ppc64 when the TOC pointer is not
+ *   valid).
+ *
+ * LOAD_REG_ADDR(rn, name)
+ *   Loads the address of label 'name' into register 'rn'.  Use this when
+ *   you don't particularly need immediate instructions only, but you need
+ *   the whole address in one register (e.g. it's a structure address and
+ *   you want to access various offsets within it).  On ppc32 this is
+ *   identical to LOAD_REG_IMMEDIATE.
  *
- * LOADBASE( rn, name )
- *   loads the address (less the low 16 bits) of 'name' into 'rn'
- *   suitable for base+disp addressing
+ * LOAD_REG_ADDRBASE(rn, name)
+ * ADDROFF(name)
+ *   LOAD_REG_ADDRBASE loads part of the address of label 'name' into
+ *   register 'rn'.  ADDROFF(name) returns the remainder of the address as
+ *   a constant expression.  ADDROFF(name) is a signed expression < 16 bits
+ *   in size, so is suitable for use directly as an offset in load and store
+ *   instructions.  Use this when loading/storing a single word or less as:
+ *      LOAD_REG_ADDRBASE(rX, name)
+ *      ld     rY,ADDROFF(name)(rX)
  */
 #ifdef __powerpc64__
-#define LOADADDR(rn,name) \
-       lis     rn,name##@highest;      \
-       ori     rn,rn,name##@higher;    \
-       rldicr  rn,rn,32,31;            \
-       oris    rn,rn,name##@h;         \
-       ori     rn,rn,name##@l
-
-#define LOADBASE(rn,name)              \
-       .section .toc,"aw";             \
-1:     .tc     name[TC],name;          \
-       .previous;                      \
-       ld      rn,1b@toc(r2)
-
-#define OFF(name)      0
-
-#define SET_REG_TO_CONST(reg, value)                   \
-       lis     reg,(((value)>>48)&0xFFFF);             \
-       ori     reg,reg,(((value)>>32)&0xFFFF);         \
-       rldicr  reg,reg,32,31;                          \
-       oris    reg,reg,(((value)>>16)&0xFFFF);         \
-       ori     reg,reg,((value)&0xFFFF);
-
-#define SET_REG_TO_LABEL(reg, label)                   \
-       lis     reg,(label)@highest;                    \
-       ori     reg,reg,(label)@higher;                 \
-       rldicr  reg,reg,32,31;                          \
-       oris    reg,reg,(label)@h;                      \
-       ori     reg,reg,(label)@l;
-
-/* operations for longs and pointers */
-#define LDL    ld
-#define STL    std
-#define CMPI   cmpdi
+#define LOAD_REG_IMMEDIATE(reg,expr)           \
+       lis     (reg),(expr)@highest;           \
+       ori     (reg),(reg),(expr)@higher;      \
+       rldicr  (reg),(reg),32,31;              \
+       oris    (reg),(reg),(expr)@h;           \
+       ori     (reg),(reg),(expr)@l;
+
+#define LOAD_REG_ADDR(reg,name)                        \
+       ld      (reg),name@got(r2)
+
+#define LOAD_REG_ADDRBASE(reg,name)    LOAD_REG_ADDR(reg,name)
+#define ADDROFF(name)                  0
+
+/* offsets for stack frame layout */
+#define LRSAVE 16
 
 #else /* 32-bit */
-#define LOADADDR(rn,name) \
-       lis     rn,name@ha;     \
-       addi    rn,rn,name@l
 
-#define LOADBASE(rn,name)      \
-       lis     rn,name@ha
+#define LOAD_REG_IMMEDIATE(reg,expr)           \
+       lis     (reg),(expr)@ha;                \
+       addi    (reg),(reg),(expr)@l;
+
+#define LOAD_REG_ADDR(reg,name)                LOAD_REG_IMMEDIATE(reg, name)
 
-#define OFF(name)      name@l
+#define LOAD_REG_ADDRBASE(reg, name)   lis     (reg),name@ha
+#define ADDROFF(name)                  name@l
 
-/* operations for longs and pointers */
-#define LDL    lwz
-#define STL    stw
-#define CMPI   cmpwi
+/* offsets for stack frame layout */
+#define LRSAVE 4
 
 #endif
 
@@ -230,6 +274,16 @@ END_FTR_SECTION_IFSET(CPU_FTR_601)
 #define ISYNC_601
 #endif
 
+#ifdef CONFIG_PPC_CELL
+#define MFTB(dest)                     \
+90:    mftb  dest;                     \
+BEGIN_FTR_SECTION_NESTED(96);          \
+       cmpwi dest,0;                   \
+       beq-  90b;                      \
+END_FTR_SECTION_NESTED(CPU_FTR_CELL_TB_BUG, CPU_FTR_CELL_TB_BUG, 96)
+#else
+#define MFTB(dest)                     mftb dest
+#endif
 
 #ifndef CONFIG_SMP
 #define TLBSYNC
@@ -261,15 +315,6 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601)
 #endif
 
 
-#ifdef CONFIG_IBM405_ERR77
-#define PPC405_ERR77(ra,rb)    dcbt    ra, rb;
-#define        PPC405_ERR77_SYNC       sync;
-#else
-#define PPC405_ERR77(ra,rb)
-#define PPC405_ERR77_SYNC
-#endif
-
-
 #ifdef CONFIG_IBM440EP_ERR42
 #define PPC440EP_ERR42 isync
 #else
@@ -278,6 +323,9 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601)
 
 
 #if defined(CONFIG_BOOKE)
+#define toreal(rd)
+#define fromreal(rd)
+
 #define tophys(rd,rs)                          \
        addis   rd,rs,0
 
@@ -285,23 +333,24 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601)
        addis   rd,rs,0
 
 #elif defined(CONFIG_PPC64)
-/* PPPBBB - DRENG  If KERNELBASE is always 0xC0...,
- * Then we can easily do this with one asm insn. -Peter
- */
+#define toreal(rd)             /* we can access c000... in real mode */
+#define fromreal(rd)
+
 #define tophys(rd,rs)                           \
-        lis     rd,((KERNELBASE>>48)&0xFFFF);   \
-        rldicr  rd,rd,32,31;                    \
-        sub     rd,rs,rd
+       clrldi  rd,rs,2
 
 #define tovirt(rd,rs)                           \
-        lis     rd,((KERNELBASE>>48)&0xFFFF);   \
-        rldicr  rd,rd,32,31;                    \
-        add     rd,rs,rd
+       rotldi  rd,rs,16;                       \
+       ori     rd,rd,((KERNELBASE>>48)&0xFFFF);\
+       rotldi  rd,rd,48
 #else
 /*
  * On APUS (Amiga PowerPC cpu upgrade board), we don't know the
  * physical base address of RAM at compile time.
  */
+#define toreal(rd)     tophys(rd,rd)
+#define fromreal(rd)   tovirt(rd,rd)
+
 #define tophys(rd,rs)                          \
 0:     addis   rd,rs,-KERNELBASE@h;            \
        .section ".vtop_fixup","aw";            \
@@ -332,6 +381,8 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601)
 #define CLR_TOP32(r)
 #endif
 
+#endif /* __KERNEL__ */
+
 /* The boring bits... */
 
 /* Condition Register Bit Fields */
@@ -493,10 +544,6 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601)
 #define N_SLINE        68
 #define N_SO   100
 
-#define ASM_CONST(x) x
-#else
-  #define __ASM_CONST(x) x##UL
-  #define ASM_CONST(x) __ASM_CONST(x)
 #endif /*  __ASSEMBLY__ */
 
 #endif /* _ASM_POWERPC_PPC_ASM_H */