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 {
unsigned char flags;
};
#if defined(CONFIG_4xx)
#if defined(CONFIG_4xx) || defined(CONFIG_POWER4)
#define OPCD(inst) (((inst) & 0xFC000000) >> 26)
#define RS(inst) (((inst) & 0x03E00000) >> 21)
#define RA(inst) (((inst) & 0x001F0000) >> 16)
#define IS_DFORM(code) ((code) >= 32 && (code) <= 55)
#define IS_XFORM(code) ((code) == 31)
#endif
#define INVALID { 0, 0 }
......@@ -61,9 +61,9 @@ static struct aligninfo aligninfo[128] = {
{ 4, ST+F+S }, /* 00 0 1010: stfs */
{ 8, ST+F }, /* 00 0 1011: stfd */
INVALID, /* 00 0 1100 */
INVALID, /* 00 0 1101 */
INVALID, /* 00 0 1101: ld/ldu/lwa */
INVALID, /* 00 0 1110 */
INVALID, /* 00 0 1111 */
INVALID, /* 00 0 1111: std/stdu */
{ 4, LD+U }, /* 00 1 0000: lwzu */
INVALID, /* 00 1 0001 */
{ 4, ST+U }, /* 00 1 0010: stwu */
......@@ -80,12 +80,12 @@ static struct aligninfo aligninfo[128] = {
INVALID, /* 00 1 1101 */
INVALID, /* 00 1 1110 */
INVALID, /* 00 1 1111 */
INVALID, /* 01 0 0000 */
INVALID, /* 01 0 0000: ldx */
INVALID, /* 01 0 0001 */
INVALID, /* 01 0 0010 */
INVALID, /* 01 0 0010: stdx */
INVALID, /* 01 0 0011 */
INVALID, /* 01 0 0100 */
INVALID, /* 01 0 0101: lwax?? */
INVALID, /* 01 0 0101: lwax */
INVALID, /* 01 0 0110 */
INVALID, /* 01 0 0111 */
{ 0, LD+HARD }, /* 01 0 1000: lswx */
......@@ -96,12 +96,12 @@ static struct aligninfo aligninfo[128] = {
INVALID, /* 01 0 1101 */
INVALID, /* 01 0 1110 */
INVALID, /* 01 0 1111 */
INVALID, /* 01 1 0000 */
INVALID, /* 01 1 0000: ldux */
INVALID, /* 01 1 0001 */
INVALID, /* 01 1 0010 */
INVALID, /* 01 1 0010: stdux */
INVALID, /* 01 1 0011 */
INVALID, /* 01 1 0100 */
INVALID, /* 01 1 0101: lwaux?? */
INVALID, /* 01 1 0101: lwaux */
INVALID, /* 01 1 0110 */
INVALID, /* 01 1 0111 */
INVALID, /* 01 1 1000 */
......@@ -157,9 +157,9 @@ static struct aligninfo aligninfo[128] = {
{ 4, ST+F+S }, /* 11 0 1010: stfsx */
{ 8, ST+F }, /* 11 0 1011: stfdx */
INVALID, /* 11 0 1100 */
INVALID, /* 11 0 1101 */
INVALID, /* 11 0 1101: lmd */
INVALID, /* 11 0 1110 */
INVALID, /* 11 0 1111 */
INVALID, /* 11 0 1111: stmd */
{ 4, LD+U }, /* 11 1 0000: lwzux */
INVALID, /* 11 1 0001 */
{ 4, ST+U }, /* 11 1 0010: stwux */
......@@ -184,7 +184,7 @@ int
fix_alignment(struct pt_regs *regs)
{
int instr, nb, flags;
#if defined(CONFIG_4xx)
#if defined(CONFIG_4xx) || defined(CONFIG_POWER4)
int opcode, f1, f2, f3;
#endif
int i, t;
......@@ -199,9 +199,11 @@ fix_alignment(struct pt_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,
* 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);
......@@ -209,7 +211,7 @@ fix_alignment(struct pt_regs *regs)
reg = RS(instr);
areg = RA(instr);
if (IS_DFORM(opcode)) {
if (!IS_XFORM(opcode)) {
f1 = 0;
f2 = (instr & 0x04000000) >> 26;
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