#include <asm/thread_info.h>
 #include <asm/asm-offsets.h>
 
+#ifdef CONFIG_8xx
+#define ISYNC_8xx isync
+#else
+#define ISYNC_8xx
+#endif
        .text
 
        .align  5
        subi    r4,r4,1
        blelr-
 00:    lbz     r5,0(r3)
-       eieio
-       stbu    r5,1(r4)
+01:    eieio
+02:    stbu    r5,1(r4)
+       ISYNC_8xx
+       .section .fixup,"ax"
+03:    blr
+       .text
+       .section __ex_table, "a"
+               .align 2
+               .long 00b, 03b
+               .long 01b, 03b
+               .long 02b, 03b
+       .text
        bdnz    00b
        blr
 
        subi    r4,r4,1
        blelr-
 00:    lbzu    r5,1(r4)
-       stb     r5,0(r3)
-       eieio
+01:    stb     r5,0(r3)
+02:    eieio
+       ISYNC_8xx
+       .section .fixup,"ax"
+03:    blr
+       .text
+       .section __ex_table, "a"
+               .align 2
+               .long 00b, 03b
+               .long 01b, 03b
+               .long 02b, 03b
+       .text
        bdnz    00b
        blr
 
        subi    r4,r4,2
        blelr-
 00:    lhbrx   r5,0,r3
-       eieio
-       sthu    r5,2(r4)
+01:    eieio
+02:    sthu    r5,2(r4)
+       ISYNC_8xx
+       .section .fixup,"ax"
+03:    blr
+       .text
+       .section __ex_table, "a"
+               .align 2
+               .long 00b, 03b
+               .long 01b, 03b
+               .long 02b, 03b
+       .text
        bdnz    00b
        blr
 
        subi    r4,r4,2
        blelr-
 00:    lhzu    r5,2(r4)
-       eieio
-       sthbrx  r5,0,r3
+01:    eieio
+02:    sthbrx  r5,0,r3
+       ISYNC_8xx
+       .section .fixup,"ax"
+03:    blr
+       .text
+       .section __ex_table, "a"
+               .align 2
+               .long 00b, 03b
+               .long 01b, 03b
+               .long 02b, 03b
+       .text
        bdnz    00b
        blr
 
        subi    r4,r4,4
        blelr-
 00:    lwbrx   r5,0,r3
-       eieio
-       stwu    r5,4(r4)
+01:    eieio
+02:    stwu    r5,4(r4)
+       ISYNC_8xx
+       .section .fixup,"ax"
+03:    blr
+       .text
+       .section __ex_table, "a"
+               .align 2
+               .long 00b, 03b
+               .long 01b, 03b
+               .long 02b, 03b
+       .text
        bdnz    00b
        blr
 
        subi    r4,r4,4
        blelr-
 00:    lwzu    r5,4(r4)
-       stwbrx  r5,0,r3
-       eieio
+01:    stwbrx  r5,0,r3
+02:    eieio
+       ISYNC_8xx
+       .section .fixup,"ax"
+03:    blr
+       .text
+       .section __ex_table, "a"
+               .align 2
+               .long 00b, 03b
+               .long 01b, 03b
+               .long 02b, 03b
+       .text
        bdnz    00b
        blr
 
        subi    r4,r4,2
        blelr-
 00:    lhz     r5,0(r3)
-       eieio
-       sthu    r5,2(r4)
+01:    eieio
+02:    sthu    r5,2(r4)
+       ISYNC_8xx
+       .section .fixup,"ax"
+03:    blr
+       .text
+       .section __ex_table, "a"
+               .align 2
+               .long 00b, 03b
+               .long 01b, 03b
+               .long 02b, 03b
+       .text
        bdnz    00b
        blr
 
        subi    r4,r4,2
        blelr-
 00:    lhzu    r5,2(r4)
-       sth     r5,0(r3)
-       eieio
+01:    sth     r5,0(r3)
+02:    eieio
+       ISYNC_8xx
+       .section .fixup,"ax"
+03:    blr
+       .text
+       .section __ex_table, "a"
+               .align 2
+               .long 00b, 03b
+               .long 01b, 03b
+               .long 02b, 03b
+       .text
        bdnz    00b
        blr
 
        subi    r4,r4,4
        blelr-
 00:    lwz     r5,0(r3)
-       eieio
-       stwu    r5,4(r4)
+01:    eieio
+02:    stwu    r5,4(r4)
+       ISYNC_8xx
+       .section .fixup,"ax"
+03:    blr
+       .text
+       .section __ex_table, "a"
+               .align 2
+               .long 00b, 03b
+               .long 01b, 03b
+               .long 02b, 03b
+       .text
        bdnz    00b
        blr
 
        subi    r4,r4,4
        blelr-
 00:    lwzu    r5,4(r4)
-       stw     r5,0(r3)
-       eieio
+01:    stw     r5,0(r3)
+02:    eieio
+       ISYNC_8xx
+       .section .fixup,"ax"
+03:    blr
+       .text
+       .section __ex_table, "a"
+               .align 2
+               .long 00b, 03b
+               .long 01b, 03b
+               .long 02b, 03b
+       .text
        bdnz    00b
        blr
 
 
  */
 static inline int check_io_access(struct pt_regs *regs)
 {
-#ifdef CONFIG_PPC_PMAC
+#if defined CONFIG_PPC_PMAC || defined CONFIG_8xx
        unsigned long msr = regs->msr;
        const struct exception_table_entry *entry;
        unsigned int *nip = (unsigned int *)regs->nip;
                        nip -= 2;
                else if (*nip == 0x4c00012c)    /* isync */
                        --nip;
-               if (*nip == 0x7c0004ac || (*nip >> 26) == 3) {
+               /* eieio from I/O string functions */
+               else if ((*nip) == 0x7c0006ac || *(nip+1) == 0x7c0006ac)
+                       nip += 2;
+               if (*nip == 0x7c0004ac || (*nip >> 26) == 3 ||
+                       (*(nip+1) >> 26) == 3) {
                        /* sync or twi */
                        unsigned int rb;
 
 
 #define outsl(port, buf, nl)   _outsl_ns((port)+___IO_BASE, (buf), (nl))
 
 /*
- * On powermacs, we will get a machine check exception if we
- * try to read data from a non-existent I/O port.  Because the
- * machine check is an asynchronous exception, it isn't
+ * On powermacs and 8xx we will get a machine check exception 
+ * if we try to read data from a non-existent I/O port. Because
+ * the machine check is an asynchronous exception, it isn't
  * well-defined which instruction SRR0 will point to when the
  * exception occurs.
  * With the sequence below (twi; isync; nop), we have found that
 {                                                      \
        unsigned int x;                                 \
        __asm__ __volatile__(                           \
-                       op "    %0,0,%1\n"              \
+               "0:"    op "    %0,0,%1\n"              \
                "1:     twi     0,%0,0\n"               \
                "2:     isync\n"                        \
                "3:     nop\n"                          \
                ".previous\n"                           \
                ".section __ex_table,\"a\"\n"           \
                "       .align  2\n"                    \
+               "       .long   0b,5b\n"                \
                "       .long   1b,5b\n"                \
                "       .long   2b,5b\n"                \
                "       .long   3b,5b\n"                \
 extern __inline__ void name(unsigned int val, unsigned int port) \
 {                                                      \
        __asm__ __volatile__(                           \
-               op " %0,0,%1\n"                         \
+               "0:" op " %0,0,%1\n"                    \
                "1:     sync\n"                         \
                "2:\n"                                  \
                ".section __ex_table,\"a\"\n"           \
                "       .align  2\n"                    \
+               "       .long   0b,2b\n"                \
                "       .long   1b,2b\n"                \
                ".previous"                             \
                : : "r" (val), "r" (port + ___IO_BASE));        \