summaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorMahesh Salgaonkar <mahesh@linux.vnet.ibm.com>2014-07-31 18:17:52 +0530
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2014-08-05 16:34:01 +1000
commitdb97efffb80652f7f879bc1d4837cbc84dc32557 (patch)
tree2773bb77bd188d2d087d2707a9ac05a395039a77 /arch
parentbbdb760d8d477f0a57e3f2394e352ccc6f5e9961 (diff)
downloadlinux-db97efffb80652f7f879bc1d4837cbc84dc32557.tar.gz
linux-db97efffb80652f7f879bc1d4837cbc84dc32557.tar.bz2
linux-db97efffb80652f7f879bc1d4837cbc84dc32557.zip
powerpc/book3s: Fix endianess issue for HMI handling on napping cpus.
(NOTE: This patch depends on upstream HMI handling patchset at https://lists.ozlabs.org/pipermail/linuxppc-dev/2014-July/119731.html) The current HMI handling on napping cpus does not take care of endianess issue. On LE host kernel when we wake up from nap due to HMI interrupt we would checkstop while jumping into opal call. There is a similar issue in case of fast sleep wakeup where the code invokes opal_resync_tb opal call without handling LE issue. This patch fixes that as well. With this patch applied, HMIs handling on LE host kernel works fine. Signed-off-by: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/powerpc/kernel/idle_power7.S49
1 files changed, 37 insertions, 12 deletions
diff --git a/arch/powerpc/kernel/idle_power7.S b/arch/powerpc/kernel/idle_power7.S
index 06305f653ab1..be05841396cf 100644
--- a/arch/powerpc/kernel/idle_power7.S
+++ b/arch/powerpc/kernel/idle_power7.S
@@ -135,6 +135,39 @@ _GLOBAL(power7_sleep)
b power7_powersave_common
/* No return */
+/*
+ * Make opal call in realmode. This is a generic function to be called
+ * from realmode from reset vector. It handles endianess.
+ *
+ * r13 - paca pointer
+ * r1 - stack pointer
+ * r3 - opal token
+ */
+opal_call_realmode:
+ mflr r12
+ std r12,_LINK(r1)
+ ld r2,PACATOC(r13)
+ /* Set opal return address */
+ LOAD_REG_ADDR(r0,return_from_opal_call)
+ mtlr r0
+ /* Handle endian-ness */
+ li r0,MSR_LE
+ mfmsr r12
+ andc r12,r12,r0
+ mtspr SPRN_HSRR1,r12
+ mr r0,r3 /* Move opal token to r0 */
+ LOAD_REG_ADDR(r11,opal)
+ ld r12,8(r11)
+ ld r2,0(r11)
+ mtspr SPRN_HSRR0,r12
+ hrfid
+
+return_from_opal_call:
+ FIXUP_ENDIAN
+ ld r0,_LINK(r1)
+ mtlr r0
+ blr
+
#define CHECK_HMI_INTERRUPT \
mfspr r0,SPRN_SRR1; \
BEGIN_FTR_SECTION_NESTED(66); \
@@ -148,12 +181,8 @@ ALT_FTR_SECTION_END_NESTED_IFSET(CPU_FTR_ARCH_207S, 66); \
ld r2,PACATOC(r13); \
ld r1,PACAR1(r13); \
std r3,ORIG_GPR3(r1); /* Save original r3 */ \
- li r0,OPAL_HANDLE_HMI; \
- LOAD_REG_ADDR(r11,opal); \
- ld r12,8(r11); \
- ld r2,0(r11); \
- mtctr r12; \
- bctrl; \
+ li r3,OPAL_HANDLE_HMI; /* Pass opal token argument*/ \
+ bl opal_call_realmode; \
ld r3,ORIG_GPR3(r1); /* Restore original r3 */ \
20: nop;
@@ -166,12 +195,8 @@ BEGIN_FTR_SECTION
CHECK_HMI_INTERRUPT
END_FTR_SECTION_IFSET(CPU_FTR_HVMODE)
/* Time base re-sync */
- li r0,OPAL_RESYNC_TIMEBASE
- LOAD_REG_ADDR(r11,opal);
- ld r12,8(r11);
- ld r2,0(r11);
- mtctr r12
- bctrl
+ li r3,OPAL_RESYNC_TIMEBASE
+ bl opal_call_realmode;
/* TODO: Check r3 for failure */