diff options
author | Paul Mackerras <paulus@samba.org> | 2005-11-11 06:36:34 -0500 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2005-11-11 06:36:34 -0500 |
commit | 548ccebc2a79c780724529948c79de0613f96776 (patch) | |
tree | aa905c14945e7afcc8f428564a38ee9f8108c87c /arch | |
parent | 22c841c9a465a6b29a6140fcc5dae9fdb3c8674d (diff) |
powerpc: Fix reading and writing SPRs from xmon on 32-bit
When we created the instructions to read/write SPRs in xmon, we were
setting up a ppc64-style procedure descriptor and calling that, which
doesn't work in 32-bit. For 32-bit a function pointer just points
to the instructions of the function. This fixes it to do the right
thing for both 32-bit and 64-bit.
Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/powerpc/xmon/xmon.c | 25 |
1 files changed, 18 insertions, 7 deletions
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index cfcb2a56d662..ef4356b29a97 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c | |||
@@ -1467,17 +1467,23 @@ read_spr(int n) | |||
1467 | { | 1467 | { |
1468 | unsigned int instrs[2]; | 1468 | unsigned int instrs[2]; |
1469 | unsigned long (*code)(void); | 1469 | unsigned long (*code)(void); |
1470 | unsigned long opd[3]; | ||
1471 | unsigned long ret = -1UL; | 1470 | unsigned long ret = -1UL; |
1471 | #ifdef CONFIG_PPC64 | ||
1472 | unsigned long opd[3]; | ||
1472 | 1473 | ||
1473 | instrs[0] = 0x7c6002a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6); | ||
1474 | instrs[1] = 0x4e800020; | ||
1475 | opd[0] = (unsigned long)instrs; | 1474 | opd[0] = (unsigned long)instrs; |
1476 | opd[1] = 0; | 1475 | opd[1] = 0; |
1477 | opd[2] = 0; | 1476 | opd[2] = 0; |
1477 | code = (unsigned long (*)(void)) opd; | ||
1478 | #else | ||
1479 | code = (unsigned long (*)(void)) instrs; | ||
1480 | #endif | ||
1481 | |||
1482 | /* mfspr r3,n; blr */ | ||
1483 | instrs[0] = 0x7c6002a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6); | ||
1484 | instrs[1] = 0x4e800020; | ||
1478 | store_inst(instrs); | 1485 | store_inst(instrs); |
1479 | store_inst(instrs+1); | 1486 | store_inst(instrs+1); |
1480 | code = (unsigned long (*)(void)) opd; | ||
1481 | 1487 | ||
1482 | if (setjmp(bus_error_jmp) == 0) { | 1488 | if (setjmp(bus_error_jmp) == 0) { |
1483 | catch_memory_errors = 1; | 1489 | catch_memory_errors = 1; |
@@ -1499,16 +1505,21 @@ write_spr(int n, unsigned long val) | |||
1499 | { | 1505 | { |
1500 | unsigned int instrs[2]; | 1506 | unsigned int instrs[2]; |
1501 | unsigned long (*code)(unsigned long); | 1507 | unsigned long (*code)(unsigned long); |
1508 | #ifdef CONFIG_PPC64 | ||
1502 | unsigned long opd[3]; | 1509 | unsigned long opd[3]; |
1503 | 1510 | ||
1504 | instrs[0] = 0x7c6003a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6); | ||
1505 | instrs[1] = 0x4e800020; | ||
1506 | opd[0] = (unsigned long)instrs; | 1511 | opd[0] = (unsigned long)instrs; |
1507 | opd[1] = 0; | 1512 | opd[1] = 0; |
1508 | opd[2] = 0; | 1513 | opd[2] = 0; |
1514 | code = (unsigned long (*)(unsigned long)) opd; | ||
1515 | #else | ||
1516 | code = (unsigned long (*)(unsigned long)) instrs; | ||
1517 | #endif | ||
1518 | |||
1519 | instrs[0] = 0x7c6003a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6); | ||
1520 | instrs[1] = 0x4e800020; | ||
1509 | store_inst(instrs); | 1521 | store_inst(instrs); |
1510 | store_inst(instrs+1); | 1522 | store_inst(instrs+1); |
1511 | code = (unsigned long (*)(unsigned long)) opd; | ||
1512 | 1523 | ||
1513 | if (setjmp(bus_error_jmp) == 0) { | 1524 | if (setjmp(bus_error_jmp) == 0) { |
1514 | catch_memory_errors = 1; | 1525 | catch_memory_errors = 1; |