Commit f8c1260f authored by Paul Mackerras's avatar Paul Mackerras

PPC32: Update the alignment exception handler for POWER4 processors

parent a9a23cb3
...@@ -21,11 +21,11 @@ struct aligninfo { ...@@ -21,11 +21,11 @@ struct aligninfo {
unsigned char flags; unsigned char flags;
}; };
#if defined(CONFIG_4xx) #if defined(CONFIG_4xx) || defined(CONFIG_POWER4)
#define OPCD(inst) (((inst) & 0xFC000000) >> 26) #define OPCD(inst) (((inst) & 0xFC000000) >> 26)
#define RS(inst) (((inst) & 0x03E00000) >> 21) #define RS(inst) (((inst) & 0x03E00000) >> 21)
#define RA(inst) (((inst) & 0x001F0000) >> 16) #define RA(inst) (((inst) & 0x001F0000) >> 16)
#define IS_DFORM(code) ((code) >= 32 && (code) <= 55) #define IS_XFORM(code) ((code) == 31)
#endif #endif
#define INVALID { 0, 0 } #define INVALID { 0, 0 }
...@@ -61,9 +61,9 @@ static struct aligninfo aligninfo[128] = { ...@@ -61,9 +61,9 @@ static struct aligninfo aligninfo[128] = {
{ 4, ST+F+S }, /* 00 0 1010: stfs */ { 4, ST+F+S }, /* 00 0 1010: stfs */
{ 8, ST+F }, /* 00 0 1011: stfd */ { 8, ST+F }, /* 00 0 1011: stfd */
INVALID, /* 00 0 1100 */ INVALID, /* 00 0 1100 */
INVALID, /* 00 0 1101 */ INVALID, /* 00 0 1101: ld/ldu/lwa */
INVALID, /* 00 0 1110 */ INVALID, /* 00 0 1110 */
INVALID, /* 00 0 1111 */ INVALID, /* 00 0 1111: std/stdu */
{ 4, LD+U }, /* 00 1 0000: lwzu */ { 4, LD+U }, /* 00 1 0000: lwzu */
INVALID, /* 00 1 0001 */ INVALID, /* 00 1 0001 */
{ 4, ST+U }, /* 00 1 0010: stwu */ { 4, ST+U }, /* 00 1 0010: stwu */
...@@ -80,12 +80,12 @@ static struct aligninfo aligninfo[128] = { ...@@ -80,12 +80,12 @@ static struct aligninfo aligninfo[128] = {
INVALID, /* 00 1 1101 */ INVALID, /* 00 1 1101 */
INVALID, /* 00 1 1110 */ INVALID, /* 00 1 1110 */
INVALID, /* 00 1 1111 */ INVALID, /* 00 1 1111 */
INVALID, /* 01 0 0000 */ INVALID, /* 01 0 0000: ldx */
INVALID, /* 01 0 0001 */ INVALID, /* 01 0 0001 */
INVALID, /* 01 0 0010 */ INVALID, /* 01 0 0010: stdx */
INVALID, /* 01 0 0011 */ INVALID, /* 01 0 0011 */
INVALID, /* 01 0 0100 */ INVALID, /* 01 0 0100 */
INVALID, /* 01 0 0101: lwax?? */ INVALID, /* 01 0 0101: lwax */
INVALID, /* 01 0 0110 */ INVALID, /* 01 0 0110 */
INVALID, /* 01 0 0111 */ INVALID, /* 01 0 0111 */
{ 0, LD+HARD }, /* 01 0 1000: lswx */ { 0, LD+HARD }, /* 01 0 1000: lswx */
...@@ -96,12 +96,12 @@ static struct aligninfo aligninfo[128] = { ...@@ -96,12 +96,12 @@ static struct aligninfo aligninfo[128] = {
INVALID, /* 01 0 1101 */ INVALID, /* 01 0 1101 */
INVALID, /* 01 0 1110 */ INVALID, /* 01 0 1110 */
INVALID, /* 01 0 1111 */ INVALID, /* 01 0 1111 */
INVALID, /* 01 1 0000 */ INVALID, /* 01 1 0000: ldux */
INVALID, /* 01 1 0001 */ INVALID, /* 01 1 0001 */
INVALID, /* 01 1 0010 */ INVALID, /* 01 1 0010: stdux */
INVALID, /* 01 1 0011 */ INVALID, /* 01 1 0011 */
INVALID, /* 01 1 0100 */ INVALID, /* 01 1 0100 */
INVALID, /* 01 1 0101: lwaux?? */ INVALID, /* 01 1 0101: lwaux */
INVALID, /* 01 1 0110 */ INVALID, /* 01 1 0110 */
INVALID, /* 01 1 0111 */ INVALID, /* 01 1 0111 */
INVALID, /* 01 1 1000 */ INVALID, /* 01 1 1000 */
...@@ -157,9 +157,9 @@ static struct aligninfo aligninfo[128] = { ...@@ -157,9 +157,9 @@ static struct aligninfo aligninfo[128] = {
{ 4, ST+F+S }, /* 11 0 1010: stfsx */ { 4, ST+F+S }, /* 11 0 1010: stfsx */
{ 8, ST+F }, /* 11 0 1011: stfdx */ { 8, ST+F }, /* 11 0 1011: stfdx */
INVALID, /* 11 0 1100 */ INVALID, /* 11 0 1100 */
INVALID, /* 11 0 1101 */ INVALID, /* 11 0 1101: lmd */
INVALID, /* 11 0 1110 */ INVALID, /* 11 0 1110 */
INVALID, /* 11 0 1111 */ INVALID, /* 11 0 1111: stmd */
{ 4, LD+U }, /* 11 1 0000: lwzux */ { 4, LD+U }, /* 11 1 0000: lwzux */
INVALID, /* 11 1 0001 */ INVALID, /* 11 1 0001 */
{ 4, ST+U }, /* 11 1 0010: stwux */ { 4, ST+U }, /* 11 1 0010: stwux */
...@@ -184,7 +184,7 @@ int ...@@ -184,7 +184,7 @@ int
fix_alignment(struct pt_regs *regs) fix_alignment(struct pt_regs *regs)
{ {
int instr, nb, flags; int instr, nb, flags;
#if defined(CONFIG_4xx) #if defined(CONFIG_4xx) || defined(CONFIG_POWER4)
int opcode, f1, f2, f3; int opcode, f1, f2, f3;
#endif #endif
int i, t; int i, t;
...@@ -199,9 +199,11 @@ fix_alignment(struct pt_regs *regs) ...@@ -199,9 +199,11 @@ fix_alignment(struct pt_regs *regs)
CHECK_FULL_REGS(regs); CHECK_FULL_REGS(regs);
#if defined(CONFIG_4xx) #if defined(CONFIG_4xx) || defined(CONFIG_POWER4)
/* The 4xx-family processors have no DSISR register, /* The 4xx-family processors have no DSISR register,
* so we emulate it. * so we emulate it.
* The POWER4 has a DSISR register but doesn't set it on
* an alignment fault. -- paulus
*/ */
instr = *((unsigned int *)regs->nip); instr = *((unsigned int *)regs->nip);
...@@ -209,7 +211,7 @@ fix_alignment(struct pt_regs *regs) ...@@ -209,7 +211,7 @@ fix_alignment(struct pt_regs *regs)
reg = RS(instr); reg = RS(instr);
areg = RA(instr); areg = RA(instr);
if (IS_DFORM(opcode)) { if (!IS_XFORM(opcode)) {
f1 = 0; f1 = 0;
f2 = (instr & 0x04000000) >> 26; f2 = (instr & 0x04000000) >> 26;
f3 = (instr & 0x78000000) >> 27; f3 = (instr & 0x78000000) >> 27;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment