diff options
author | Brandon Bergren <bdragon@FreeBSD.org> | 2020-09-23 04:09:02 +0000 |
---|---|---|
committer | Brandon Bergren <bdragon@FreeBSD.org> | 2020-09-23 04:09:02 +0000 |
commit | d20d17f6d4b023acff418314805e21839246da09 (patch) | |
tree | 6d2c8574d73cecec20e8cf8538c683de58aae962 | |
parent | af22c7e495e00a61f7dee7367a1f19917151990b (diff) | |
download | src-d20d17f6d4b023acff418314805e21839246da09.tar.gz src-d20d17f6d4b023acff418314805e21839246da09.zip |
[PowerPC64LE] Fix RTAS LE calls in pseries.
Similar to OPAL calls, switch to big endian to do calls to RTAS.
(Missed this one when I was doing the bulk commit of PowerPC64LE support.)
Sponsored by: Tag1 Consulting, Inc.
Notes
Notes:
svn path=/head/; revision=366063
-rw-r--r-- | sys/powerpc/ofw/ofwcall64.S | 20 | ||||
-rw-r--r-- | sys/powerpc/ofw/rtas.c | 13 |
2 files changed, 27 insertions, 6 deletions
diff --git a/sys/powerpc/ofw/ofwcall64.S b/sys/powerpc/ofw/ofwcall64.S index 3230cdf79c37..8a25c1a878bb 100644 --- a/sys/powerpc/ofw/ofwcall64.S +++ b/sys/powerpc/ofw/ofwcall64.S @@ -296,9 +296,29 @@ ASENTRY_NOPROF(rtascall) std %r6,16(%r1) /* Save MSR */ std %r9,24(%r1) /* Save reference PC for high 32 bits */ +#ifdef __LITTLE_ENDIAN__ + /* Atomic context switch w/ endian change */ + li %r7, 0 + mtmsrd %r7, 1 /* Clear PSL_EE|PSL_RI */ + addis %r7,%r2,TOC_REF(rtasmsr)@ha + ld %r7,TOC_REF(rtasmsr)@l(%r7) + ld %r7,0(%r7) + mtsrr0 %r5 + mtsrr1 %r7 + LOAD_LR_NIA +1: + mflr %r5 + addi %r5, %r5, (2f-1b) + mtlr %r5 + li %r5, 0 + rfid +2: + RETURN_TO_NATIVE_ENDIAN +#else /* Finally, branch to RTAS */ mtctr %r5 bctrl +#endif /* * Reload stack pointer, MSR, reg PC from the reg save area in r1. We diff --git a/sys/powerpc/ofw/rtas.c b/sys/powerpc/ofw/rtas.c index 89bcef26bf7d..65f5ffbdc21a 100644 --- a/sys/powerpc/ofw/rtas.c +++ b/sys/powerpc/ofw/rtas.c @@ -29,6 +29,7 @@ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); +#include <sys/endian.h> #include <sys/param.h> #include <sys/kernel.h> #include <sys/lock.h> @@ -90,7 +91,7 @@ rtas_setup(void *junk) /* RTAS must be called with everything turned off in MSR */ rtasmsr = mfmsr(); - rtasmsr &= ~(PSL_IR | PSL_DR | PSL_EE | PSL_SE); + rtasmsr &= ~(PSL_IR | PSL_DR | PSL_EE | PSL_SE | PSL_LE); #ifdef __powerpc64__ rtasmsr &= ~PSL_SF; #endif @@ -215,17 +216,17 @@ rtas_call_method(cell_t token, int nargs, int nreturns, ...) if (!rtas_exists() || nargs + nreturns > 12) return (-1); - args.token = token; + args.token = htobe32(token); va_start(ap, nreturns); mtx_lock_spin(&rtas_mtx); rtas_bounce_offset = 0; - args.nargs = nargs; - args.nreturns = nreturns; + args.nargs = htobe32(nargs); + args.nreturns = htobe32(nreturns); for (n = 0; n < nargs; n++) - args.args_n_results[n] = va_arg(ap, cell_t); + args.args_n_results[n] = htobe32(va_arg(ap, cell_t)); argsptr = rtas_real_map(&args, sizeof(args)); @@ -250,7 +251,7 @@ rtas_call_method(cell_t token, int nargs, int nreturns, ...) return (result); for (n = nargs; n < nargs + nreturns; n++) - *va_arg(ap, cell_t *) = args.args_n_results[n]; + *va_arg(ap, cell_t *) = be32toh(args.args_n_results[n]); return (result); } |