[PowerPC64LE] LE opal_call() implementation

OPAL runs in big endian, so we need to rfid into it to switch endian
atomically when branching to it, and we need to do the
RETURN_TO_NATIVE_ENDIAN dance when it returns to us.

Sponsored by:	Tag1 Consulting, Inc.
This commit is contained in:
Brandon Bergren 2020-09-23 00:28:47 +00:00
parent 24faccc241
commit dadfbc2e60
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=366040
2 changed files with 20 additions and 1 deletions

View File

@ -57,7 +57,7 @@ opal_check(void)
OF_getencprop(opal, "opal-entry-address", val, sizeof(val));
opal_entrypoint = ((uint64_t)val[0] << 32) | val[1];
opal_msr = mfmsr() & ~(PSL_EE | PSL_IR | PSL_DR | PSL_SE);
opal_msr = mfmsr() & ~(PSL_EE | PSL_IR | PSL_DR | PSL_SE | PSL_LE);
opal_initialized = 1;

View File

@ -84,6 +84,10 @@ ASENTRY(opal_call)
xori %r3,%r3,1
#endif
#ifdef __LITTLE_ENDIAN__
mtsrr1 %r3
#endif
/* Shift registers over */
mr %r3,%r4
mr %r4,%r5
@ -93,8 +97,23 @@ ASENTRY(opal_call)
mr %r8,%r9
mr %r9,%r10
#ifdef __LITTLE_ENDIAN__
/* We need to rfid to switch endian. */
mfctr %r11
mtsrr0 %r11
LOAD_LR_NIA
1:
mflr %r11
addi %r11, %r11, (2f-1b)
mtlr %r11
/* Call OPAL */
rfid
2:
RETURN_TO_NATIVE_ENDIAN
#else
/* Call OPAL */
bctrl
#endif
/* Restore MSR */
mtmsrd %r31