Pull asus into release branch
[pandora-kernel.git] / arch / powerpc / platforms / pseries / hvCall.S
index c00cfed..c1427b3 100644 (file)
 BEGIN_FTR_SECTION;                                             \
        mfspr   r0,SPRN_PURR;           /* get PURR and */      \
        std     r0,STK_PARM(r6)(r1);    /* save for later */    \
-END_FTR_SECTION_IFCLR(CPU_FTR_PURR);
+END_FTR_SECTION_IFSET(CPU_FTR_PURR);
        
 /*
  * postcall is performed immediately before function return which
- * allows liberal use of volatile registers.
+ * allows liberal use of volatile registers.  We branch around this
+ * in early init (eg when populating the MMU hashtable) by using an
+ * unconditional cpu feature.
  */
 #define HCALL_INST_POSTCALL                                    \
+BEGIN_FTR_SECTION;                                             \
+       b       1f;                                             \
+END_FTR_SECTION(0, 1);                                         \
        ld      r4,STK_PARM(r3)(r1);    /* validate opcode */   \
        cmpldi  cr7,r4,MAX_HCALL_OPCODE;                        \
        bgt-    cr7,1f;                                         \
@@ -43,7 +48,7 @@ BEGIN_FTR_SECTION;                                            \
        mfspr   r8,SPRN_PURR;           /* PURR after */        \
        ld      r6,STK_PARM(r6)(r1);    /* PURR before */       \
        subf    r6,r6,r8;               /* delta */             \
-END_FTR_SECTION_IFCLR(CPU_FTR_PURR);                           \
+END_FTR_SECTION_IFSET(CPU_FTR_PURR);                           \
        ld      r5,STK_PARM(r5)(r1);    /* timebase before */   \
        subf    r5,r5,r7;               /* time delta */        \
                                                                \
@@ -66,7 +71,7 @@ BEGIN_FTR_SECTION;                                            \
        ld      r7,HCALL_STAT_PURR(r4); /* PURR */              \
        add     r7,r7,r6;                                       \
        std     r7,HCALL_STAT_PURR(r4);                         \
-END_FTR_SECTION_IFCLR(CPU_FTR_PURR);                           \
+END_FTR_SECTION_IFSET(CPU_FTR_PURR);                           \
 1:
 #else
 #define HCALL_INST_PRECALL
@@ -123,6 +128,40 @@ _GLOBAL(plpar_hcall)
 
        blr                             /* return r3 = status */
 
+/*
+ * plpar_hcall_raw can be called in real mode. kexec/kdump need some
+ * hypervisor calls to be executed in real mode. So plpar_hcall_raw
+ * does not access the per cpu hypervisor call statistics variables,
+ * since these variables may not be present in the RMO region.
+ */
+_GLOBAL(plpar_hcall_raw)
+       HMT_MEDIUM
+
+       mfcr    r0
+       stw     r0,8(r1)
+
+       std     r4,STK_PARM(r4)(r1)     /* Save ret buffer */
+
+       mr      r4,r5
+       mr      r5,r6
+       mr      r6,r7
+       mr      r7,r8
+       mr      r8,r9
+       mr      r9,r10
+
+       HVSC                            /* invoke the hypervisor */
+
+       ld      r12,STK_PARM(r4)(r1)
+       std     r4,  0(r12)
+       std     r5,  8(r12)
+       std     r6, 16(r12)
+       std     r7, 24(r12)
+
+       lwz     r0,8(r1)
+       mtcrf   0xff,r0
+
+       blr                             /* return r3 = status */
+
 _GLOBAL(plpar_hcall9)
        HMT_MEDIUM
 
@@ -145,6 +184,7 @@ _GLOBAL(plpar_hcall9)
 
        HVSC                            /* invoke the hypervisor */
 
+       mr      r0,r12
        ld      r12,STK_PARM(r4)(r1)
        std     r4,  0(r12)
        std     r5,  8(r12)
@@ -154,7 +194,7 @@ _GLOBAL(plpar_hcall9)
        std     r9, 40(r12)
        std     r10,48(r12)
        std     r11,56(r12)
-       std     r12,64(r12)
+       std     r0, 64(r12)
 
        HCALL_INST_POSTCALL