aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2014-10-30 01:19:13 -0400
committerMichael Ellerman <mpe@ellerman.id.au>2014-10-31 02:09:04 -0400
commit325e4114043469e5f9923d902b4d30bcc2be8163 (patch)
treef70b8aab18045f1e0edecce809ba02cbd5475e6b /arch
parent808be31426af57af22268ef0fcb42617beb3d15b (diff)
powerpc/powernv: Properly fix LPC debugfs endianness
Endian is hard, especially when I designed a stupid FW interface, and I should know better... oh well, this is attempt #2 at fixing this properly. This time it seems to work with all access sizes and I can run my flashing tool (which exercises all sort of access sizes and types to access the SPI controller in the BMC) just fine. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> CC: stable@vger.kernel.org Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Diffstat (limited to 'arch')
-rw-r--r--arch/powerpc/platforms/powernv/opal-lpc.c59
1 files changed, 59 insertions, 0 deletions
diff --git a/arch/powerpc/platforms/powernv/opal-lpc.c b/arch/powerpc/platforms/powernv/opal-lpc.c
index ad4b31df779a..e4169d68cb32 100644
--- a/arch/powerpc/platforms/powernv/opal-lpc.c
+++ b/arch/powerpc/platforms/powernv/opal-lpc.c
@@ -216,14 +216,54 @@ static ssize_t lpc_debug_read(struct file *filp, char __user *ubuf,
216 &data, len); 216 &data, len);
217 if (rc) 217 if (rc)
218 return -ENXIO; 218 return -ENXIO;
219
220 /*
221 * Now there is some trickery with the data returned by OPAL
222 * as it's the desired data right justified in a 32-bit BE
223 * word.
224 *
225 * This is a very bad interface and I'm to blame for it :-(
226 *
227 * So we can't just apply a 32-bit swap to what comes from OPAL,
228 * because user space expects the *bytes* to be in their proper
229 * respective positions (ie, LPC position).
230 *
231 * So what we really want to do here is to shift data right
232 * appropriately on a LE kernel.
233 *
234 * IE. If the LPC transaction has bytes B0, B1, B2 and B3 in that
235 * order, we have in memory written to by OPAL at the "data"
236 * pointer:
237 *
238 * Bytes: OPAL "data" LE "data"
239 * 32-bit: B0 B1 B2 B3 B0B1B2B3 B3B2B1B0
240 * 16-bit: B0 B1 0000B0B1 B1B00000
241 * 8-bit: B0 000000B0 B0000000
242 *
243 * So a BE kernel will have the leftmost of the above in the MSB
244 * and rightmost in the LSB and can just then "cast" the u32 "data"
245 * down to the appropriate quantity and write it.
246 *
247 * However, an LE kernel can't. It doesn't need to swap because a
248 * load from data followed by a store to user are going to preserve
249 * the byte ordering which is the wire byte order which is what the
250 * user wants, but in order to "crop" to the right size, we need to
251 * shift right first.
252 */
219 switch(len) { 253 switch(len) {
220 case 4: 254 case 4:
221 rc = __put_user((u32)data, (u32 __user *)ubuf); 255 rc = __put_user((u32)data, (u32 __user *)ubuf);
222 break; 256 break;
223 case 2: 257 case 2:
258#ifdef __LITTLE_ENDIAN__
259 data >>= 16;
260#endif
224 rc = __put_user((u16)data, (u16 __user *)ubuf); 261 rc = __put_user((u16)data, (u16 __user *)ubuf);
225 break; 262 break;
226 default: 263 default:
264#ifdef __LITTLE_ENDIAN__
265 data >>= 24;
266#endif
227 rc = __put_user((u8)data, (u8 __user *)ubuf); 267 rc = __put_user((u8)data, (u8 __user *)ubuf);
228 break; 268 break;
229 } 269 }
@@ -263,12 +303,31 @@ static ssize_t lpc_debug_write(struct file *filp, const char __user *ubuf,
263 else if (todo > 1 && (pos & 1) == 0) 303 else if (todo > 1 && (pos & 1) == 0)
264 len = 2; 304 len = 2;
265 } 305 }
306
307 /*
308 * Similarly to the read case, we have some trickery here but
309 * it's different to handle. We need to pass the value to OPAL in
310 * a register whose layout depends on the access size. We want
311 * to reproduce the memory layout of the user, however we aren't
312 * doing a load from user and a store to another memory location
313 * which would achieve that. Here we pass the value to OPAL via
314 * a register which is expected to contain the "BE" interpretation
315 * of the byte sequence. IE: for a 32-bit access, byte 0 should be
316 * in the MSB. So here we *do* need to byteswap on LE.
317 *
318 * User bytes: LE "data" OPAL "data"
319 * 32-bit: B0 B1 B2 B3 B3B2B1B0 B0B1B2B3
320 * 16-bit: B0 B1 0000B1B0 0000B0B1
321 * 8-bit: B0 000000B0 000000B0
322 */
266 switch(len) { 323 switch(len) {
267 case 4: 324 case 4:
268 rc = __get_user(data, (u32 __user *)ubuf); 325 rc = __get_user(data, (u32 __user *)ubuf);
326 data = cpu_to_be32(data);
269 break; 327 break;
270 case 2: 328 case 2:
271 rc = __get_user(data, (u16 __user *)ubuf); 329 rc = __get_user(data, (u16 __user *)ubuf);
330 data = cpu_to_be16(data);
272 break; 331 break;
273 default: 332 default:
274 rc = __get_user(data, (u8 __user *)ubuf); 333 rc = __get_user(data, (u8 __user *)ubuf);