]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - include/asm-powerpc/ppc_asm.h
[POWERPC] PS3: Fix sys manager build error
[linux-2.6-omap-h63xx.git] / include / asm-powerpc / ppc_asm.h
index 4efa71878fa987049c93f8519c56097b306bb756..fa083d8e46632807b5a206a5ab7fa528e7676fea 100644 (file)
@@ -1,11 +1,59 @@
 /*
  * Copyright (C) 1995-1999 Gary Thomas, Paul Mackerras, Cort Dougan.
  */
-
 #ifndef _ASM_POWERPC_PPC_ASM_H
 #define _ASM_POWERPC_PPC_ASM_H
 
-#ifdef __ASSEMBLY__
+#include <linux/stringify.h>
+#include <asm/asm-compat.h>
+
+#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
+#define GLUE(a,b) XGLUE(a,b)
+
+#define _GLOBAL(name) \
+       .section ".text"; \
+       .align 2 ; \
+       .globl name; \
+       .globl GLUE(.,name); \
+       .section ".opd","aw"; \
+name: \
+       .quad GLUE(.,name); \
+       .quad .TOC.@tocbase; \
+       .quad 0; \
+       .previous; \
+       .type GLUE(.,name),@function; \
+GLUE(.,name):
+
+#define _KPROBE(name) \
+       .section ".kprobes.text","a"; \
+       .align 2 ; \
+       .globl name; \
+       .globl GLUE(.,name); \
+       .section ".opd","aw"; \
+name: \
+       .quad GLUE(.,name); \
+       .quad .TOC.@tocbase; \
+       .quad 0; \
+       .previous; \
+       .type GLUE(.,name),@function; \
+GLUE(.,name):
+
+#define _STATIC(name) \
+       .section ".text"; \
+       .align 2 ; \
+       .section ".opd","aw"; \
+name: \
+       .quad GLUE(.,name); \
+       .quad .TOC.@tocbase; \
+       .quad 0; \
+       .previous; \
+       .type GLUE(.,name),@function; \
+GLUE(.,name):
+
+#else /* 32-bit */
+
+#define _GLOBAL(n)     \
+       .text;          \
+       .stabs __stringify(n:F-1),N_FUN,0,0,n;\
+       .globl n;       \
+n:
+
+#define _KPROBE(n)     \
+       .section ".kprobes.text","a";   \
+       .globl  n;      \
+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).
  *
- * LOADBASE( rn, name )
- *   loads the address (less the low 16 bits) of 'name' into 'rn'
- *   suitable for base+disp addressing
+ * 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.
+ *
+ * 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) \
-       lis     rn,name@highest;        \
-       ori     rn,rn,name@higher;      \
-       rldicr  rn,rn,32,31;            \
-       oris    rn,rn,name@ha
-
-
-#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;
+#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 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 LOAD_REG_ADDRBASE(reg, name)   lis     (reg),name@ha
+#define ADDROFF(name)                  name@l
+
+/* offsets for stack frame layout */
+#define LRSAVE 4
+
 #endif
 
 /* various errata or part fixups */
@@ -146,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
@@ -177,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
@@ -194,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
 
@@ -201,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";            \
@@ -233,31 +366,9 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601)
        .previous
 #endif
 
-/*
- * On 64-bit cpus, we use the rfid instruction instead of rfi, but
- * we then have to make sure we preserve the top 32 bits except for
- * the 64-bit mode bit, which we clear.
- */
-#if defined(CONFIG_PPC64BRIDGE)
-#define        FIX_SRR1(ra, rb)        \
-       mr      rb,ra;          \
-       mfmsr   ra;             \
-       clrldi  ra,ra,1;                /* turn off 64-bit mode */ \
-       rldimi  ra,rb,0,32
-#define        RFI             .long   0x4c000024      /* rfid instruction */
-#define MTMSRD(r)      .long   (0x7c000164 + ((r) << 21))      /* mtmsrd */
-#define CLR_TOP32(r)   rlwinm  (r),(r),0,0,31  /* clear top 32 bits */
-#elif defined(CONFIG_PPC64)
-/* Insert the high 32 bits of the MSR into what will be the new
-   MSR (via SRR1 and rfid)  This preserves the MSR.SF and MSR.ISF
-   bits. */
-
-#define FIX_SRR1(ra, rb)       \
-       mr      rb,ra;          \
-       mfmsr   ra;             \
-       rldimi  ra,rb,0,32
-
-#define CLR_TOP32(r)   rlwinm  (r),(r),0,0,31  /* clear top 32 bits */
+#ifdef CONFIG_PPC64
+#define RFI            rfid
+#define MTMSRD(r)      mtmsrd  r
 
 #else
 #define FIX_SRR1(ra, rb)
@@ -270,6 +381,8 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601)
 #define CLR_TOP32(r)
 #endif
 
+#endif /* __KERNEL__ */
+
 /* The boring bits... */
 
 /* Condition Register Bit Fields */
@@ -431,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 */