[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:
parent
24faccc241
commit
dadfbc2e60
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=366040
@ -57,7 +57,7 @@ opal_check(void)
|
|||||||
OF_getencprop(opal, "opal-entry-address", val, sizeof(val));
|
OF_getencprop(opal, "opal-entry-address", val, sizeof(val));
|
||||||
opal_entrypoint = ((uint64_t)val[0] << 32) | val[1];
|
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;
|
opal_initialized = 1;
|
||||||
|
|
||||||
|
@ -84,6 +84,10 @@ ASENTRY(opal_call)
|
|||||||
xori %r3,%r3,1
|
xori %r3,%r3,1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __LITTLE_ENDIAN__
|
||||||
|
mtsrr1 %r3
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Shift registers over */
|
/* Shift registers over */
|
||||||
mr %r3,%r4
|
mr %r3,%r4
|
||||||
mr %r4,%r5
|
mr %r4,%r5
|
||||||
@ -93,8 +97,23 @@ ASENTRY(opal_call)
|
|||||||
mr %r8,%r9
|
mr %r8,%r9
|
||||||
mr %r9,%r10
|
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 */
|
/* Call OPAL */
|
||||||
bctrl
|
bctrl
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Restore MSR */
|
/* Restore MSR */
|
||||||
mtmsrd %r31
|
mtmsrd %r31
|
||||||
|
Loading…
Reference in New Issue
Block a user