Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

[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
Loading
Loading
Loading
Loading
+125 −20
Original line number Diff line number Diff line
@@ -25,6 +25,11 @@
#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
@@ -800,8 +805,18 @@ _GLOBAL(_insb)
	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

@@ -811,8 +826,18 @@ _GLOBAL(_outsb)
	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

@@ -822,8 +847,18 @@ _GLOBAL(_insw)
	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

@@ -833,8 +868,18 @@ _GLOBAL(_outsw)
	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

@@ -844,8 +889,18 @@ _GLOBAL(_insl)
	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

@@ -855,8 +910,18 @@ _GLOBAL(_outsl)
	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

@@ -867,8 +932,18 @@ _GLOBAL(_insw_ns)
	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

@@ -879,8 +954,18 @@ _GLOBAL(_outsw_ns)
	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

@@ -891,8 +976,18 @@ _GLOBAL(_insl_ns)
	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

@@ -903,8 +998,18 @@ _GLOBAL(_outsl_ns)
	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

+6 −2
Original line number Diff line number Diff line
@@ -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)
{
#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;
@@ -178,7 +178,11 @@ static inline int check_io_access(struct pt_regs *regs)
			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;

+7 −5
Original line number Diff line number Diff line
@@ -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))

/*
 * 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
@@ -258,7 +258,7 @@ extern __inline__ unsigned int name(unsigned int port) \
{							\
	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"				\
@@ -269,6 +269,7 @@ extern __inline__ unsigned int name(unsigned int port) \
		".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"		\
@@ -282,11 +283,12 @@ extern __inline__ unsigned int name(unsigned int port) \
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));	\