Commit 55b6332e authored by Marcelo Tosatti's avatar Marcelo Tosatti Committed by Paul Mackerras

[PATCH] ppc32: handle access to non-present IO ports on 8xx

This adds exception table entries for I/O instructions on and
changes MachineCheckException() slightly to cover 8xx specifics (on
8xx the MCE can be generated while executing the IO access instruction
itself, which is not the case on PowerMac's, as the comment on traps.c
details).
Signed-off-by: default avatarMarcelo Tosatti <marcelo.tosatti@cyclades.com>
Signed-off-by: default avatarPaul Mackerras <paulus@samba.org>
parent c6d95044
...@@ -25,6 +25,11 @@ ...@@ -25,6 +25,11 @@
#include <asm/thread_info.h> #include <asm/thread_info.h>
#include <asm/asm-offsets.h> #include <asm/asm-offsets.h>
#ifdef CONFIG_8xx
#define ISYNC_8xx isync
#else
#define ISYNC_8xx
#endif
.text .text
.align 5 .align 5
...@@ -800,8 +805,18 @@ _GLOBAL(_insb) ...@@ -800,8 +805,18 @@ _GLOBAL(_insb)
subi r4,r4,1 subi r4,r4,1
blelr- blelr-
00: lbz r5,0(r3) 00: lbz r5,0(r3)
eieio 01: eieio
stbu r5,1(r4) 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 bdnz 00b
blr blr
...@@ -811,8 +826,18 @@ _GLOBAL(_outsb) ...@@ -811,8 +826,18 @@ _GLOBAL(_outsb)
subi r4,r4,1 subi r4,r4,1
blelr- blelr-
00: lbzu r5,1(r4) 00: lbzu r5,1(r4)
stb r5,0(r3) 01: stb r5,0(r3)
eieio 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 bdnz 00b
blr blr
...@@ -822,8 +847,18 @@ _GLOBAL(_insw) ...@@ -822,8 +847,18 @@ _GLOBAL(_insw)
subi r4,r4,2 subi r4,r4,2
blelr- blelr-
00: lhbrx r5,0,r3 00: lhbrx r5,0,r3
eieio 01: eieio
sthu r5,2(r4) 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 bdnz 00b
blr blr
...@@ -833,8 +868,18 @@ _GLOBAL(_outsw) ...@@ -833,8 +868,18 @@ _GLOBAL(_outsw)
subi r4,r4,2 subi r4,r4,2
blelr- blelr-
00: lhzu r5,2(r4) 00: lhzu r5,2(r4)
eieio 01: eieio
sthbrx r5,0,r3 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 bdnz 00b
blr blr
...@@ -844,8 +889,18 @@ _GLOBAL(_insl) ...@@ -844,8 +889,18 @@ _GLOBAL(_insl)
subi r4,r4,4 subi r4,r4,4
blelr- blelr-
00: lwbrx r5,0,r3 00: lwbrx r5,0,r3
eieio 01: eieio
stwu r5,4(r4) 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 bdnz 00b
blr blr
...@@ -855,8 +910,18 @@ _GLOBAL(_outsl) ...@@ -855,8 +910,18 @@ _GLOBAL(_outsl)
subi r4,r4,4 subi r4,r4,4
blelr- blelr-
00: lwzu r5,4(r4) 00: lwzu r5,4(r4)
stwbrx r5,0,r3 01: stwbrx r5,0,r3
eieio 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 bdnz 00b
blr blr
...@@ -867,8 +932,18 @@ _GLOBAL(_insw_ns) ...@@ -867,8 +932,18 @@ _GLOBAL(_insw_ns)
subi r4,r4,2 subi r4,r4,2
blelr- blelr-
00: lhz r5,0(r3) 00: lhz r5,0(r3)
eieio 01: eieio
sthu r5,2(r4) 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 bdnz 00b
blr blr
...@@ -879,8 +954,18 @@ _GLOBAL(_outsw_ns) ...@@ -879,8 +954,18 @@ _GLOBAL(_outsw_ns)
subi r4,r4,2 subi r4,r4,2
blelr- blelr-
00: lhzu r5,2(r4) 00: lhzu r5,2(r4)
sth r5,0(r3) 01: sth r5,0(r3)
eieio 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 bdnz 00b
blr blr
...@@ -891,8 +976,18 @@ _GLOBAL(_insl_ns) ...@@ -891,8 +976,18 @@ _GLOBAL(_insl_ns)
subi r4,r4,4 subi r4,r4,4
blelr- blelr-
00: lwz r5,0(r3) 00: lwz r5,0(r3)
eieio 01: eieio
stwu r5,4(r4) 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 bdnz 00b
blr blr
...@@ -903,8 +998,18 @@ _GLOBAL(_outsl_ns) ...@@ -903,8 +998,18 @@ _GLOBAL(_outsl_ns)
subi r4,r4,4 subi r4,r4,4
blelr- blelr-
00: lwzu r5,4(r4) 00: lwzu r5,4(r4)
stw r5,0(r3) 01: stw r5,0(r3)
eieio 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 bdnz 00b
blr blr
......
...@@ -159,7 +159,7 @@ void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr) ...@@ -159,7 +159,7 @@ void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr)
*/ */
static inline int check_io_access(struct pt_regs *regs) 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; unsigned long msr = regs->msr;
const struct exception_table_entry *entry; const struct exception_table_entry *entry;
unsigned int *nip = (unsigned int *)regs->nip; unsigned int *nip = (unsigned int *)regs->nip;
...@@ -178,7 +178,11 @@ static inline int check_io_access(struct pt_regs *regs) ...@@ -178,7 +178,11 @@ static inline int check_io_access(struct pt_regs *regs)
nip -= 2; nip -= 2;
else if (*nip == 0x4c00012c) /* isync */ else if (*nip == 0x4c00012c) /* isync */
--nip; --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 */ /* sync or twi */
unsigned int rb; unsigned int rb;
......
...@@ -237,9 +237,9 @@ static inline void __raw_writel(__u32 b, volatile void __iomem *addr) ...@@ -237,9 +237,9 @@ static inline void __raw_writel(__u32 b, volatile void __iomem *addr)
#define outsl(port, buf, nl) _outsl_ns((port)+___IO_BASE, (buf), (nl)) #define outsl(port, buf, nl) _outsl_ns((port)+___IO_BASE, (buf), (nl))
/* /*
* On powermacs, we will get a machine check exception if we * On powermacs and 8xx we will get a machine check exception
* try to read data from a non-existent I/O port. Because the * if we try to read data from a non-existent I/O port. Because
* machine check is an asynchronous exception, it isn't * the machine check is an asynchronous exception, it isn't
* well-defined which instruction SRR0 will point to when the * well-defined which instruction SRR0 will point to when the
* exception occurs. * exception occurs.
* With the sequence below (twi; isync; nop), we have found that * With the sequence below (twi; isync; nop), we have found that
...@@ -258,7 +258,7 @@ extern __inline__ unsigned int name(unsigned int port) \ ...@@ -258,7 +258,7 @@ extern __inline__ unsigned int name(unsigned int port) \
{ \ { \
unsigned int x; \ unsigned int x; \
__asm__ __volatile__( \ __asm__ __volatile__( \
op " %0,0,%1\n" \ "0:" op " %0,0,%1\n" \
"1: twi 0,%0,0\n" \ "1: twi 0,%0,0\n" \
"2: isync\n" \ "2: isync\n" \
"3: nop\n" \ "3: nop\n" \
...@@ -269,6 +269,7 @@ extern __inline__ unsigned int name(unsigned int port) \ ...@@ -269,6 +269,7 @@ extern __inline__ unsigned int name(unsigned int port) \
".previous\n" \ ".previous\n" \
".section __ex_table,\"a\"\n" \ ".section __ex_table,\"a\"\n" \
" .align 2\n" \ " .align 2\n" \
" .long 0b,5b\n" \
" .long 1b,5b\n" \ " .long 1b,5b\n" \
" .long 2b,5b\n" \ " .long 2b,5b\n" \
" .long 3b,5b\n" \ " .long 3b,5b\n" \
...@@ -282,11 +283,12 @@ extern __inline__ unsigned int name(unsigned int port) \ ...@@ -282,11 +283,12 @@ extern __inline__ unsigned int name(unsigned int port) \
extern __inline__ void name(unsigned int val, unsigned int port) \ extern __inline__ void name(unsigned int val, unsigned int port) \
{ \ { \
__asm__ __volatile__( \ __asm__ __volatile__( \
op " %0,0,%1\n" \ "0:" op " %0,0,%1\n" \
"1: sync\n" \ "1: sync\n" \
"2:\n" \ "2:\n" \
".section __ex_table,\"a\"\n" \ ".section __ex_table,\"a\"\n" \
" .align 2\n" \ " .align 2\n" \
" .long 0b,2b\n" \
" .long 1b,2b\n" \ " .long 1b,2b\n" \
".previous" \ ".previous" \
: : "r" (val), "r" (port + ___IO_BASE)); \ : : "r" (val), "r" (port + ___IO_BASE)); \
......
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