Message ID | 1436318742-13490-1-git-send-email-sam.mj@au1.ibm.com (mailing list archive) |
---|---|
State | Not Applicable |
Headers | show |
Hi Sam, > Older big-endian ppc64 kernels don't include the FIXUP_ENDIAN check, > meaning if we kexec from a little-endian kernel the target kernel will > fail to boot. > Returning to big-endian before we enter the target kernel ensures that > the target kernel can boot whether or not it includes FIXUP_ENDIAN. Thanks! I wonder if we can do something simpler, and always enter via rfid. Avoids the need for the endian trampoline. Something like: mtsrr0 r4 mfmsr r5 clrrdi r5,r5,1 /* Clear MSR_LE */ mtsrr1 r5 li r5,0 rfid Anton
On 08/07/15 11:56, Anton Blanchard wrote: > Hi Sam, > >> Older big-endian ppc64 kernels don't include the FIXUP_ENDIAN check, >> meaning if we kexec from a little-endian kernel the target kernel will >> fail to boot. >> Returning to big-endian before we enter the target kernel ensures that >> the target kernel can boot whether or not it includes FIXUP_ENDIAN. > > Thanks! > > I wonder if we can do something simpler, and always enter via rfid. > Avoids the need for the endian trampoline. Something like: > > mtsrr0 r4 > > mfmsr r5 > clrrdi r5,r5,1 /* Clear MSR_LE */ > mtsrr1 r5 > > li r5,0 > > rfid > > Anton > Ah that's a neat idea, I'll test and send a V2. Cheers, Sam
diff --git a/kexec_trampoline.S b/kexec_trampoline.S index a3eb314..29537ab 100644 --- a/kexec_trampoline.S +++ b/kexec_trampoline.S @@ -41,6 +41,8 @@ #define r7 7 #define r8 8 #define r9 9 +#define r10 10 +#define r11 11 #ifdef __powerpc64__ #define LOAD ld @@ -50,8 +52,10 @@ #if defined(__LITTLE_ENDIAN__) #define STWX_BE stwbrx +#define BCTR .long 0x2004804e #elif defined(__BIG_ENDIAN__) #define STWX_BE stwx +#define BCTR bctr #else #error no endianness defined! #endif @@ -89,7 +93,10 @@ start: li r5,0 mtctr r4 - bctr + + RESET_ENDIAN + + BCTR . = KERNEL_ADDR_OFFSET kernel_addr: diff --git a/kexec_trampoline.h b/kexec_trampoline.h index 6485c88..909953b 100644 --- a/kexec_trampoline.h +++ b/kexec_trampoline.h @@ -27,7 +27,20 @@ /* Fixed offset in device tree for storing the physical ID of the boot CPU */ #define DT_CPU_OFFSET 28 -#ifndef __ASSEMBLY__ +#ifdef __ASSEMBLY__ +#define RESET_ENDIAN \ + mfmsr r9; \ + clrldi. r10,r9,63; \ + beq $+36; /* Already big-endian */ \ + bcl 20,31,$+4; \ + mflr r10; \ + addi r10,r10,28; \ + mfmsr r11; \ + xori r11,r11,1; \ + mtsrr0 r10; \ + mtsrr1 r11; \ + rfid; +#else extern char __trampoline_start[]; extern char __trampoline_end[]; @@ -48,6 +61,6 @@ static inline void trampoline_set_device_tree(void *p, unsigned long addr) *v = addr; } -#endif +#endif /* !__ASSEMBLY__ */ #endif
Older big-endian ppc64 kernels don't include the FIXUP_ENDIAN check, meaning if we kexec from a little-endian kernel the target kernel will fail to boot. Returning to big-endian before we enter the target kernel ensures that the target kernel can boot whether or not it includes FIXUP_ENDIAN. Signed-off-by: Samuel Mendoza-Jonas <sam.mj@au1.ibm.com> --- kexec_trampoline.S | 9 ++++++++- kexec_trampoline.h | 17 +++++++++++++++-- 2 files changed, 23 insertions(+), 3 deletions(-)