All of lore.kernel.org
 help / color / mirror / Atom feed
* DBE/IBE handling incompatibility
@ 2002-06-17 11:33 Ladislav Michl
  2002-06-19 16:47 ` Maciej W. Rozycki
  0 siblings, 1 reply; 22+ messages in thread
From: Ladislav Michl @ 2002-06-17 11:33 UTC (permalink / raw)
  To: linux-mips

hi,

i'd like to release GIO64 bus support. Before doing so DBE/IBE handling
should be done in the same fashion for both mips and mips64 (*). Currently
mips is using handler in handler via dbe_board_handler and ibe_board_handler 
which are not used anywhere while mips64 is using BUILD_HANDLER macro defined
in include/asm-mips64/exception.h (see arch/mips64/sgi-ip27/ip27-dbe-glue.S)
Unfortunately I have nearly zero knowledge of MIPS assembler, so I'm
unable to code mips way same as mips64 is... Help from someone more
experienced will be greatly appreciated :-)

(*) How GIO device detection works? each IP22 machine contains three GIO bus
slots. GIO device provides information about itself in first (three) word(s)
of address space it occupies. The only way how to detect GIO card is
trying to read word from it's base address. If DBE exception is generated 
then there is definitely no card present, otherwise read value encodes 
information about device.

	ladis

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: DBE/IBE handling incompatibility
  2002-06-17 11:33 DBE/IBE handling incompatibility Ladislav Michl
@ 2002-06-19 16:47 ` Maciej W. Rozycki
  2002-06-25  0:36   ` Ladislav Michl
  0 siblings, 1 reply; 22+ messages in thread
From: Maciej W. Rozycki @ 2002-06-19 16:47 UTC (permalink / raw)
  To: Ladislav Michl; +Cc: linux-mips

On Mon, 17 Jun 2002, Ladislav Michl wrote:

> i'd like to release GIO64 bus support. Before doing so DBE/IBE handling
> should be done in the same fashion for both mips and mips64 (*). Currently
> mips is using handler in handler via dbe_board_handler and ibe_board_handler 
> which are not used anywhere while mips64 is using BUILD_HANDLER macro defined
> in include/asm-mips64/exception.h (see arch/mips64/sgi-ip27/ip27-dbe-glue.S)
> Unfortunately I have nearly zero knowledge of MIPS assembler, so I'm
> unable to code mips way same as mips64 is... Help from someone more
> experienced will be greatly appreciated :-)

 I'm going to work on unifying and extending the code a bit once I have my
64-bit world running, so don't worry about the divergence between the
ports. 

 Don't rely in dbe_board_handler and ibe_board_handler -- they are
system-specific backends that shouldn't be touched unless you want to
handle the exceptions in a system-specific way (e.g. to report ECC errors
from a memory controller).  Also expect the handlers to get rewritten so
that search_dbe_table() gets invoked unconditionally, before a
system-specific backend.

> (*) How GIO device detection works? each IP22 machine contains three GIO bus
> slots. GIO device provides information about itself in first (three) word(s)
> of address space it occupies. The only way how to detect GIO card is
> trying to read word from it's base address. If DBE exception is generated 
> then there is definitely no card present, otherwise read value encodes 
> information about device.

 Use get_dbe() from <asm/paccess.h> for reading data with an additional
DBE status.  For a simple example see drivers/mtd/devices/ms02-nv.c.  The
macro is used in a somewhat more complex way in drivers/tc/tc.c as well --
this bit of code fits your situation quite closely (here probing
TURBOchannel bus slots).  The macro works in modules as well. 

-- 
+  Maciej W. Rozycki, Technical University of Gdansk, Poland   +
+--------------------------------------------------------------+
+        e-mail: macro@ds2.pg.gda.pl, PGP key available        +

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: DBE/IBE handling incompatibility
  2002-06-19 16:47 ` Maciej W. Rozycki
@ 2002-06-25  0:36   ` Ladislav Michl
  2002-06-25 11:55     ` Maciej W. Rozycki
  0 siblings, 1 reply; 22+ messages in thread
From: Ladislav Michl @ 2002-06-25  0:36 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: linux-mips

On Wed, Jun 19, 2002 at 06:47:05PM +0200, Maciej W. Rozycki wrote:
>  Don't rely in dbe_board_handler and ibe_board_handler -- they are
> system-specific backends that shouldn't be touched unless you want to
> handle the exceptions in a system-specific way (e.g. to report ECC errors
> from a memory controller).

MC sends an interrupt whenever bus or parity errors occur. In addition, if the
error happened during a CPU read, it also asserts the bus error pin on the R4K.
so once one access nonexistent memory on Indy first DBE is generated followed
by Bus Error interupt (IRQ 6). When GIO status register is cleared inside DBE
handler, irq is not delivered.

> Also expect the handlers to get rewritten so that search_dbe_table() gets 
> invoked unconditionally, before a system-specific backend.

i don't want to use these handlers, i'd like to write it mips64 way.

> Use get_dbe() from <asm/paccess.h> for reading data with an additional
> DBE status.  For a simple example see drivers/mtd/devices/ms02-nv.c.  The
> macro is used in a somewhat more complex way in drivers/tc/tc.c as well --
> this bit of code fits your situation quite closely (here probing
> TURBOchannel bus slots).  The macro works in modules as well.

that does't work. i used folowing pseudocode:

my_get_dbe()
  nofault = 1;
  ret = get_dbe(*val, (unsigned int *) addr);
  __asm__ __volatile__("nop;nop;nop;nop");
  nofault = 0;
	
my_do_buserr()
  save_and_clear_buserr();
  if (nofault) {
    nofault = 0;
    return;
  }
  panic();

when calling my_get_dbe for nonexistent address it enters my_do_buserr
and returns "somewhere" causing machine to freeze. calling
save_and_clear_buserr() from board specific DBE handler works as
expected. is there better solution or i missed anything important?

thanks,
	ladis

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: DBE/IBE handling incompatibility
  2002-06-25  0:36   ` Ladislav Michl
@ 2002-06-25 11:55     ` Maciej W. Rozycki
  2002-06-26 11:51       ` [patch] linux: DBE/IBE handling rewrite Maciej W. Rozycki
  0 siblings, 1 reply; 22+ messages in thread
From: Maciej W. Rozycki @ 2002-06-25 11:55 UTC (permalink / raw)
  To: Ladislav Michl, Ralf Baechle; +Cc: linux-mips

On Tue, 25 Jun 2002, Ladislav Michl wrote:

> >  Don't rely in dbe_board_handler and ibe_board_handler -- they are
> > system-specific backends that shouldn't be touched unless you want to
> > handle the exceptions in a system-specific way (e.g. to report ECC errors
> > from a memory controller).
> 
> MC sends an interrupt whenever bus or parity errors occur. In addition, if the
> error happened during a CPU read, it also asserts the bus error pin on the R4K.
> so once one access nonexistent memory on Indy first DBE is generated followed
> by Bus Error interupt (IRQ 6). When GIO status register is cleared inside DBE
> handler, irq is not delivered.

 So you want both a system-specific DBE handler and a DBE detection in a
driver, right?

> > Also expect the handlers to get rewritten so that search_dbe_table() gets 
> > invoked unconditionally, before a system-specific backend.
> 
> i don't want to use these handlers, i'd like to write it mips64 way.

 The MIPS way is the right one and I'll fix MIPS64 as soon as I get it
fixed much enough to boot into the single-user mode on my system.  They
have to be identical, because there are drivers that work both on MIPS and
MIPS64 and expect consistent semantics. 

 A cleanup hook will be provided to let system-specific code do whatever
is needed to discard saved DBE state regardless -- I didn't add it so far
as I haven't managed to get at it yet. 

> > Use get_dbe() from <asm/paccess.h> for reading data with an additional
> > DBE status.  For a simple example see drivers/mtd/devices/ms02-nv.c.  The
> > macro is used in a somewhat more complex way in drivers/tc/tc.c as well --
> > this bit of code fits your situation quite closely (here probing
> > TURBOchannel bus slots).  The macro works in modules as well.
> 
> that does't work. i used folowing pseudocode:
> 
> my_get_dbe()
>   nofault = 1;
>   ret = get_dbe(*val, (unsigned int *) addr);
>   __asm__ __volatile__("nop;nop;nop;nop");
>   nofault = 0;
> 	
> my_do_buserr()
>   save_and_clear_buserr();
>   if (nofault) {
>     nofault = 0;
>     return;
>   }
>   panic();
> 
> when calling my_get_dbe for nonexistent address it enters my_do_buserr
> and returns "somewhere" causing machine to freeze. calling
> save_and_clear_buserr() from board specific DBE handler works as
> expected. is there better solution or i missed anything important?

 Well, that's not the right approach -- you are trying to work around the
current MIPS64 brokenness.  The handler for DBE and IBE in
arch/mips*/kernel/traps.c is intended to look more or less as follows: 

asmlinkage void do_be(struct pt_regs *regs)
{
	unsigned long new_epc;
	unsigned long fixup = 0;
	int data = regs->cp0_cause & 4;

	if (data && !user_mode(regs))
		fixup = search_dbe_table(regs->cp0_epc);

	if (be_board_handler)
		fixup = be_board_handler(regs, fixup);

	if (fixup) {
		new_epc = fixup_exception(dpf_reg, fixup,
					  regs->cp0_epc);
		regs->cp0_epc = new_epc;
		return;
	}

	/*
	 * Assume it would be too dangerous to continue ...
	 */
	printk(KERN_ALERT "%s bus error, epc == %08lx, ra == %08lx\n",
	       data ? "Data" : "Instruction",
	       regs->cp0_epc, regs->regs[31]);
	die_if_kernel("Oops", regs);
	force_sig(SIGBUS, current);
}

 This way, the fixup search is invoked first and a system-specific handler
can judge whether to let the fixup be invoked or a serious failure
happened and the system should act appropriately.  The handler can do
whatever actions are needed (e.g. clear error status data in system
registers, report ECC syndromes, etc.) for the system for both cases.

 I'll code it shortly.  Ralf, I hope it's not too unreasonable.

  Maciej

-- 
+  Maciej W. Rozycki, Technical University of Gdansk, Poland   +
+--------------------------------------------------------------+
+        e-mail: macro@ds2.pg.gda.pl, PGP key available        +

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [patch] linux: DBE/IBE handling rewrite
  2002-06-25 11:55     ` Maciej W. Rozycki
@ 2002-06-26 11:51       ` Maciej W. Rozycki
  2002-06-26 12:05         ` Ralf Baechle
  2002-06-26 17:17         ` [patch] linux: DBE/IBE handling rewrite Jun Sun
  0 siblings, 2 replies; 22+ messages in thread
From: Maciej W. Rozycki @ 2002-06-26 11:51 UTC (permalink / raw)
  To: Ladislav Michl, Ralf Baechle; +Cc: linux-mips

On Tue, 25 Jun 2002, Maciej W. Rozycki wrote:

>  This way, the fixup search is invoked first and a system-specific handler
> can judge whether to let the fixup be invoked or a serious failure
> happened and the system should act appropriately.  The handler can do
> whatever actions are needed (e.g. clear error status data in system
> registers, report ECC syndromes, etc.) for the system for both cases.

 OK, here is the code.  I wrote it a bit differently from what I
considered yesterday, as fixup doesn't seem useful for a system-specific
handler.  With the following code only a boolean flag is passed informing
whether a fixup is available and the handler can decide how to treat an
error, based on the state passed as arguments and possibly additional one
obtained from system-specific resources.  Both MIPS and MIPS64 are handled
in the same way.  For MIPS64 it means a removal of duplicated similar code
as well.  I adjusted some SGI-specific code appropriately, but platform
maintainers will have to check if bus_error_init() stubs are OK for them.

 Ralf, OK to apply?

  Maciej

-- 
+  Maciej W. Rozycki, Technical University of Gdansk, Poland   +
+--------------------------------------------------------------+
+        e-mail: macro@ds2.pg.gda.pl, PGP key available        +

patch-mips-2.4.18-20020625-be-5
diff -up --recursive --new-file linux-mips-2.4.18-20020625.macro/arch/mips/cobalt/setup.c linux-mips-2.4.18-20020625/arch/mips/cobalt/setup.c
--- linux-mips-2.4.18-20020625.macro/arch/mips/cobalt/setup.c	2002-01-07 03:33:54.000000000 +0000
+++ linux-mips-2.4.18-20020625/arch/mips/cobalt/setup.c	2002-06-26 11:21:15.000000000 +0000
@@ -25,6 +25,7 @@
 #include <asm/pci.h>
 #include <asm/processor.h>
 #include <asm/reboot.h>
+#include <asm/traps.h>
 
 extern void cobalt_machine_restart(char *command);
 extern void cobalt_machine_halt(void);
@@ -71,6 +72,10 @@ static void __init cobalt_timer_setup(st
 	*((volatile unsigned long *) GALILEO_CPU_MASK) = (unsigned long) 0x00000100; 
 }
 
+
+void __init bus_error_init(void) { /* nothing */ }
+
+
 int cobalt_serial_present;
 int cobalt_serial_type;
 int cobalt_is_raq;
diff -up --recursive --new-file linux-mips-2.4.18-20020625.macro/arch/mips/ddb5074/setup.c linux-mips-2.4.18-20020625/arch/mips/ddb5074/setup.c
--- linux-mips-2.4.18-20020625.macro/arch/mips/ddb5074/setup.c	2001-11-26 05:25:59.000000000 +0000
+++ linux-mips-2.4.18-20020625/arch/mips/ddb5074/setup.c	2002-06-26 11:21:24.000000000 +0000
@@ -25,6 +25,7 @@
 #include <asm/gdb-stub.h>
 #include <asm/nile4.h>
 #include <asm/ddb5074.h>
+#include <asm/traps.h>
 
 
 #ifdef CONFIG_REMOTE_DEBUG
@@ -91,6 +92,10 @@ static void __init ddb_time_init(struct 
 		          IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4);
 }
 
+
+void __init bus_error_init(void) { /* nothing */ }
+
+
 void __init ddb_setup(void)
 {
 	extern int panic_timeout;
diff -up --recursive --new-file linux-mips-2.4.18-20020625.macro/arch/mips/ddb5xxx/ddb5476/setup.c linux-mips-2.4.18-20020625/arch/mips/ddb5xxx/ddb5476/setup.c
--- linux-mips-2.4.18-20020625.macro/arch/mips/ddb5xxx/ddb5476/setup.c	2002-02-04 05:27:22.000000000 +0000
+++ linux-mips-2.4.18-20020625/arch/mips/ddb5xxx/ddb5476/setup.c	2002-06-26 11:21:56.000000000 +0000
@@ -25,6 +25,7 @@
 #include <asm/gdb-stub.h>
 #include <asm/time.h>
 #include <asm/debug.h>
+#include <asm/traps.h>
 
 #include <asm/ddb5xxx/ddb5xxx.h>
 
@@ -138,6 +139,10 @@ static struct {
 	{ "Nile 4", DDB_BASE, DDB_BASE + DDB_SIZE - 1, IORESOURCE_BUSY}
 };
 
+
+void __init bus_error_init(void) { /* nothing */ }
+
+
 static void ddb5476_board_init(void);
 extern void ddb5476_irq_setup(void);
 extern void (*irq_setup)(void);
diff -up --recursive --new-file linux-mips-2.4.18-20020625.macro/arch/mips/ddb5xxx/ddb5477/setup.c linux-mips-2.4.18-20020625/arch/mips/ddb5xxx/ddb5477/setup.c
--- linux-mips-2.4.18-20020625.macro/arch/mips/ddb5xxx/ddb5477/setup.c	2001-12-27 05:27:16.000000000 +0000
+++ linux-mips-2.4.18-20020625/arch/mips/ddb5xxx/ddb5477/setup.c	2002-06-26 11:22:25.000000000 +0000
@@ -32,6 +32,7 @@
 #include <asm/reboot.h>
 #include <asm/gdb-stub.h>
 #include <asm/debug.h>
+#include <asm/traps.h>
 
 #include <asm/ddb5xxx/ddb5xxx.h>
 
@@ -117,6 +118,10 @@ static void __init ddb_timer_setup(struc
 #endif
 }
 
+
+void __init bus_error_init(void) { /* nothing */ }
+
+
 static void ddb5477_board_init(void);
 extern void ddb5477_irq_setup(void);
 
diff -up --recursive --new-file linux-mips-2.4.18-20020625.macro/arch/mips/dec/setup.c linux-mips-2.4.18-20020625/arch/mips/dec/setup.c
--- linux-mips-2.4.18-20020625.macro/arch/mips/dec/setup.c	2002-05-30 02:57:37.000000000 +0000
+++ linux-mips-2.4.18-20020625/arch/mips/dec/setup.c	2002-06-25 18:05:05.000000000 +0000
@@ -24,6 +24,7 @@
 #include <asm/irq_cpu.h>
 #include <asm/mipsregs.h>
 #include <asm/reboot.h>
+#include <asm/traps.h>
 
 #include <asm/dec/interrupts.h>
 #include <asm/dec/kn01.h>
@@ -113,6 +114,16 @@ static void __init dec_time_init(struct 
 	setup_irq(dec_interrupt[DEC_IRQ_RTC], irq);
 }
 
+
+/*
+ * Bus error (DBE/IBE exceptions and memory interrupts) handling
+ * setup.  Nothing for now.
+ */
+void __init bus_error_init(void)
+{
+}
+
+
 void __init decstation_setup(void)
 {
 	board_time_init = dec_time_init;
diff -up --recursive --new-file linux-mips-2.4.18-20020625.macro/arch/mips/galileo-boards/ev64120/setup.c linux-mips-2.4.18-20020625/arch/mips/galileo-boards/ev64120/setup.c
--- linux-mips-2.4.18-20020625.macro/arch/mips/galileo-boards/ev64120/setup.c	2001-12-13 05:27:47.000000000 +0000
+++ linux-mips-2.4.18-20020625/arch/mips/galileo-boards/ev64120/setup.c	2002-06-26 11:25:04.000000000 +0000
@@ -51,6 +51,7 @@
 #include <asm/ptrace.h>
 #include <asm/reboot.h>
 #include <asm/mc146818rtc.h>
+#include <asm/traps.h>
 #include <linux/version.h>
 #include <linux/bootmem.h>
 
@@ -105,6 +106,10 @@ struct rtc_ops galileo_rtc_ops = {
 	&galileo_rtc_bcd_mode
 };
 
+
+void __init bus_error_init(void) { /* nothing */ }
+
+
 /********************************************************************
  *ev64120_setup -
  *
diff -up --recursive --new-file linux-mips-2.4.18-20020625.macro/arch/mips/gt64120/momenco_ocelot/setup.c linux-mips-2.4.18-20020625/arch/mips/gt64120/momenco_ocelot/setup.c
--- linux-mips-2.4.18-20020625.macro/arch/mips/gt64120/momenco_ocelot/setup.c	2002-02-07 05:27:13.000000000 +0000
+++ linux-mips-2.4.18-20020625/arch/mips/gt64120/momenco_ocelot/setup.c	2002-06-26 11:26:58.000000000 +0000
@@ -59,6 +59,7 @@
 #include <asm/ptrace.h>
 #include <asm/reboot.h>
 #include <asm/mc146818rtc.h>
+#include <asm/traps.h>
 #include <linux/version.h>
 #include <linux/bootmem.h>
 #include <linux/blk.h>
@@ -83,6 +84,10 @@ static char reset_reason;
 
 static void __init setup_l3cache(unsigned long size);
 
+
+void __init bus_error_init(void) { /* nothing */ }
+
+
 void __init momenco_ocelot_setup(void)
 {
 	void (*l3func)(unsigned long)=KSEG1ADDR(&setup_l3cache);
diff -up --recursive --new-file linux-mips-2.4.18-20020625.macro/arch/mips/ite-boards/generic/it8172_setup.c linux-mips-2.4.18-20020625/arch/mips/ite-boards/generic/it8172_setup.c
--- linux-mips-2.4.18-20020625.macro/arch/mips/ite-boards/generic/it8172_setup.c	2001-11-27 05:26:05.000000000 +0000
+++ linux-mips-2.4.18-20020625/arch/mips/ite-boards/generic/it8172_setup.c	2002-06-26 11:32:13.000000000 +0000
@@ -40,6 +40,7 @@
 #include <asm/irq.h>
 #include <asm/mipsregs.h>
 #include <asm/reboot.h>
+#include <asm/traps.h>
 #include <asm/it8172/it8172.h>
 #include <asm/it8712.h>
 #ifdef CONFIG_PC_KEYB
@@ -114,6 +115,9 @@ struct {
 #endif
 
 
+void __init bus_error_init(void) { /* nothing */ }
+
+
 void __init it8172_init_ram_resource(unsigned long memsize)
 {
 	it8172_resources.ram.end = memsize;
diff -up --recursive --new-file linux-mips-2.4.18-20020625.macro/arch/mips/jazz/setup.c linux-mips-2.4.18-20020625/arch/mips/jazz/setup.c
--- linux-mips-2.4.18-20020625.macro/arch/mips/jazz/setup.c	2001-12-12 05:27:26.000000000 +0000
+++ linux-mips-2.4.18-20020625/arch/mips/jazz/setup.c	2002-06-26 11:32:42.000000000 +0000
@@ -28,6 +28,7 @@
 #include <asm/reboot.h>
 #include <asm/io.h>
 #include <asm/pgtable.h>
+#include <asm/traps.h>
 
 /*
  * Initial irq handlers.
@@ -80,6 +81,10 @@ static void __init jazz_irq_setup(void)
 	i8259_setup_irq(2, &irq2);
 }
 
+
+void __init bus_error_init(void) { /* nothing */ }
+
+
 void __init jazz_setup(void)
 {
 	/* Map 0xe0000000 -> 0x0:800005C0, 0xe0010000 -> 0x1:30000580 */
diff -up --recursive --new-file linux-mips-2.4.18-20020625.macro/arch/mips/jmr3927/rbhma3100/setup.c linux-mips-2.4.18-20020625/arch/mips/jmr3927/rbhma3100/setup.c
--- linux-mips-2.4.18-20020625.macro/arch/mips/jmr3927/rbhma3100/setup.c	2002-02-23 05:28:27.000000000 +0000
+++ linux-mips-2.4.18-20020625/arch/mips/jmr3927/rbhma3100/setup.c	2002-06-26 11:36:26.000000000 +0000
@@ -55,6 +55,7 @@
 #include <asm/gdb-stub.h>
 #include <asm/jmr3927/jmr3927.h>
 #include <asm/mipsregs.h>
+#include <asm/traps.h>
 
 /* Tick Timer divider */
 #define JMR3927_TIMER_CCD	0	/* 1/2 */
@@ -182,6 +183,10 @@ unsigned long jmr3927_do_gettimeoffset(v
        return res;
 }                                         
 
+
+void __init bus_error_init(void) { /* nothing */ }
+
+
 #if defined(CONFIG_BLK_DEV_INITRD)
 extern unsigned long __rd_start, __rd_end, initrd_start, initrd_end;
 #endif 
diff -up --recursive --new-file linux-mips-2.4.18-20020625.macro/arch/mips/kernel/entry.S linux-mips-2.4.18-20020625/arch/mips/kernel/entry.S
--- linux-mips-2.4.18-20020625.macro/arch/mips/kernel/entry.S	2002-04-16 02:57:34.000000000 +0000
+++ linux-mips-2.4.18-20020625/arch/mips/kernel/entry.S	2002-06-25 16:39:19.000000000 +0000
@@ -236,8 +236,8 @@ EXPORT(exception_count_##exception);    
 
 		BUILD_HANDLER(adel,ade,ade,silent)		/* #4  */
 		BUILD_HANDLER(ades,ade,ade,silent)		/* #5  */
-		BUILD_HANDLER(ibe,ibe,cli,silent)		/* #6  */
-		BUILD_HANDLER(dbe,dbe,cli,silent)		/* #7  */
+		BUILD_HANDLER(ibe,be,cli,silent)		/* #6  */
+		BUILD_HANDLER(dbe,be,cli,silent)		/* #7  */
 		BUILD_HANDLER(bp,bp,sti,silent)			/* #9  */
 		BUILD_HANDLER(ri,ri,sti,silent)			/* #10 */
 		BUILD_HANDLER(cpu,cpu,sti,silent)		/* #11 */
diff -up --recursive --new-file linux-mips-2.4.18-20020625.macro/arch/mips/kernel/traps.c linux-mips-2.4.18-20020625/arch/mips/kernel/traps.c
--- linux-mips-2.4.18-20020625.macro/arch/mips/kernel/traps.c	2002-05-28 10:13:03.000000000 +0000
+++ linux-mips-2.4.18-20020625/arch/mips/kernel/traps.c	2002-06-25 19:38:02.000000000 +0000
@@ -10,6 +10,7 @@
  *
  * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
  * Copyright (C) 2000, 01 MIPS Technologies, Inc.
+ * Copyright (C) 2002  Maciej W. Rozycki
  */
 #include <linux/config.h>
 #include <linux/init.h>
@@ -32,6 +33,7 @@
 #include <asm/siginfo.h>
 #include <asm/watch.h>
 #include <asm/system.h>
+#include <asm/traps.h>
 #include <asm/uaccess.h>
 #include <asm/mmu_context.h>
 
@@ -66,8 +68,7 @@ extern int fpu_emulator_cop1Handler(stru
 
 char watch_available = 0;
 
-void (*ibe_board_handler)(struct pt_regs *regs);
-void (*dbe_board_handler)(struct pt_regs *regs);
+int (*be_board_handler)(struct pt_regs *regs, int is_fixup);
 
 int kstack_depth_to_print = 24;
 
@@ -417,20 +418,35 @@ search_dbe_table(unsigned long addr)
 #endif
 }
 
-static void default_be_board_handler(struct pt_regs *regs)
+asmlinkage void do_be(struct pt_regs *regs)
 {
 	unsigned long new_epc;
-	unsigned long fixup;
+	unsigned long fixup = 0;
 	int data = regs->cp0_cause & 4;
+	int action = MIPS_BE_FATAL;
 
-	if (data && !user_mode(regs)) {
+	if (data && !user_mode(regs))
 		fixup = search_dbe_table(regs->cp0_epc);
+
+	if (fixup)
+		action = MIPS_BE_FIXUP;
+
+	if (be_board_handler)
+		action = be_board_handler(regs, fixup != 0);
+
+	switch (action) {
+	case MIPS_BE_DISCARD:
+		return;
+	case MIPS_BE_FIXUP:
 		if (fixup) {
 			new_epc = fixup_exception(dpf_reg, fixup,
 						  regs->cp0_epc);
 			regs->cp0_epc = new_epc;
 			return;
 		}
+		break;
+	default:
+		break;
 	}
 
 	/*
@@ -443,16 +459,6 @@ static void default_be_board_handler(str
 	force_sig(SIGBUS, current);
 }
 
-asmlinkage void do_ibe(struct pt_regs *regs)
-{
-	ibe_board_handler(regs);
-}
-
-asmlinkage void do_dbe(struct pt_regs *regs)
-{
-	dbe_board_handler(regs);
-}
-
 asmlinkage void do_ov(struct pt_regs *regs)
 {
 	if (compute_return_epc(regs))
@@ -950,6 +956,13 @@ void __init trap_init(void)
 	 */
 	parity_protection_init();
 
+	/*
+	 * The Data Bus Errors / Instruction Bus Errors are signaled
+	 * by external hardware.  Therefore these two exceptions
+	 * may have board specific handlers.
+	 */
+	bus_error_init();
+
 	set_except_vector(1, handle_mod);
 	set_except_vector(2, handle_tlbl);
 	set_except_vector(3, handle_tlbs);
@@ -958,13 +971,11 @@ void __init trap_init(void)
 
 	/*
 	 * The Data Bus Error/ Instruction Bus Errors are signaled
-	 * by external hardware.  Therefore these two expection have
-	 * board specific handlers.
+	 * by external hardware.  Therefore these two exceptions
+	 * may have board specific handlers.
 	 */
 	set_except_vector(6, handle_ibe);
 	set_except_vector(7, handle_dbe);
-	ibe_board_handler = default_be_board_handler;
-	dbe_board_handler = default_be_board_handler;
 
 	set_except_vector(8, handle_sys);
 	set_except_vector(9, handle_bp);
diff -up --recursive --new-file linux-mips-2.4.18-20020625.macro/arch/mips/mips-boards/atlas/atlas_setup.c linux-mips-2.4.18-20020625/arch/mips/mips-boards/atlas/atlas_setup.c
--- linux-mips-2.4.18-20020625.macro/arch/mips/mips-boards/atlas/atlas_setup.c	2002-01-25 05:26:36.000000000 +0000
+++ linux-mips-2.4.18-20020625/arch/mips/mips-boards/atlas/atlas_setup.c	2002-06-26 11:36:59.000000000 +0000
@@ -31,6 +31,7 @@
 #include <asm/mips-boards/atlasint.h>
 #include <asm/gt64120.h>
 #include <asm/time.h>
+#include <asm/traps.h>
 
 #if defined(CONFIG_SERIAL_CONSOLE) || defined(CONFIG_PROM_CONSOLE)
 extern void console_setup(char *, int *);
diff -up --recursive --new-file linux-mips-2.4.18-20020625.macro/arch/mips/mips-boards/malta/malta_setup.c linux-mips-2.4.18-20020625/arch/mips/mips-boards/malta/malta_setup.c
--- linux-mips-2.4.18-20020625.macro/arch/mips/mips-boards/malta/malta_setup.c	2002-05-09 02:57:10.000000000 +0000
+++ linux-mips-2.4.18-20020625/arch/mips/mips-boards/malta/malta_setup.c	2002-06-26 11:37:27.000000000 +0000
@@ -37,6 +37,7 @@
 #endif
 #include <asm/dma.h>
 #include <asm/time.h>
+#include <asm/traps.h>
 #ifdef CONFIG_PC_KEYB
 #include <asm/keyboard.h>
 #endif
diff -up --recursive --new-file linux-mips-2.4.18-20020625.macro/arch/mips/philips/nino/setup.c linux-mips-2.4.18-20020625/arch/mips/philips/nino/setup.c
--- linux-mips-2.4.18-20020625.macro/arch/mips/philips/nino/setup.c	2002-05-30 02:57:50.000000000 +0000
+++ linux-mips-2.4.18-20020625/arch/mips/philips/nino/setup.c	2002-06-26 11:38:05.000000000 +0000
@@ -19,6 +19,7 @@
 #include <asm/irq.h>
 #include <asm/reboot.h>
 #include <asm/time.h>
+#include <asm/traps.h>
 #include <asm/tx3912.h>
 
 static void nino_machine_restart(char *command)
@@ -81,6 +82,10 @@ static __init void nino_timer_setup(stru
 	setup_irq(0, irq);
 }
 
+
+void __init bus_error_init(void) { /* nothing */ }
+
+
 void __init nino_setup(void)
 {
 	extern void nino_irq_setup(void);
diff -up --recursive --new-file linux-mips-2.4.18-20020625.macro/arch/mips/sgi-ip22/ip22-setup.c linux-mips-2.4.18-20020625/arch/mips/sgi-ip22/ip22-setup.c
--- linux-mips-2.4.18-20020625.macro/arch/mips/sgi-ip22/ip22-setup.c	2002-05-13 02:57:38.000000000 +0000
+++ linux-mips-2.4.18-20020625/arch/mips/sgi-ip22/ip22-setup.c	2002-06-26 11:41:03.000000000 +0000
@@ -28,6 +28,7 @@
 #include <asm/sgi/sgint23.h>
 #include <asm/time.h>
 #include <asm/gdb-stub.h>
+#include <asm/traps.h>
 
 #ifdef CONFIG_REMOTE_DEBUG
 extern void rs_kgdb_hook(int);
diff -up --recursive --new-file linux-mips-2.4.18-20020625.macro/arch/mips/sni/setup.c linux-mips-2.4.18-20020625/arch/mips/sni/setup.c
--- linux-mips-2.4.18-20020625.macro/arch/mips/sni/setup.c	2001-11-26 05:26:01.000000000 +0000
+++ linux-mips-2.4.18-20020625/arch/mips/sni/setup.c	2002-06-26 11:39:42.000000000 +0000
@@ -31,6 +31,7 @@
 #include <asm/reboot.h>
 #include <asm/sni.h>
 #include <asm/time.h>
+#include <asm/traps.h>
 
 extern void sni_machine_restart(char *command);
 extern void sni_machine_halt(void);
@@ -49,6 +50,10 @@ static void __init sni_rm200_pci_time_in
 	setup_irq(0, irq);
 }
 
+
+void __init bus_error_init(void) { /* nothing */ }
+
+
 extern unsigned char sni_map_isa_cache;
 
 /*
diff -up --recursive --new-file linux-mips-2.4.18-20020625.macro/arch/mips64/kernel/r4k_genex.S linux-mips-2.4.18-20020625/arch/mips64/kernel/r4k_genex.S
--- linux-mips-2.4.18-20020625.macro/arch/mips64/kernel/r4k_genex.S	2002-02-23 05:28:29.000000000 +0000
+++ linux-mips-2.4.18-20020625/arch/mips64/kernel/r4k_genex.S	2002-06-25 16:48:31.000000000 +0000
@@ -20,8 +20,8 @@
 
 	BUILD_HANDLER adel ade ade silent		/* #4  */
 	BUILD_HANDLER ades ade ade silent		/* #5  */
-	BUILD_HANDLER ibe ibe cli silent		/* #6  */
-	BUILD_HANDLER dbe dbe cli silent		/* #7  */
+	BUILD_HANDLER ibe be cli silent			/* #6  */
+	BUILD_HANDLER dbe be cli silent			/* #7  */
 	BUILD_HANDLER bp bp sti silent			/* #9  */
 	BUILD_HANDLER ri ri sti silent			/* #10 */
 	BUILD_HANDLER cpu cpu sti silent		/* #11 */
diff -up --recursive --new-file linux-mips-2.4.18-20020625.macro/arch/mips64/kernel/traps.c linux-mips-2.4.18-20020625/arch/mips64/kernel/traps.c
--- linux-mips-2.4.18-20020625.macro/arch/mips64/kernel/traps.c	2002-06-20 02:57:37.000000000 +0000
+++ linux-mips-2.4.18-20020625/arch/mips64/kernel/traps.c	2002-06-25 19:43:46.000000000 +0000
@@ -7,6 +7,7 @@
  * Copyright (C) 1995, 1996 Paul M. Antoine
  * Copyright (C) 1998 Ulf Carlsson
  * Copyright (C) 1999 Silicon Graphics, Inc.
+ * Copyright (C) 2002  Maciej W. Rozycki
  */
 #include <linux/config.h>
 #include <linux/init.h>
@@ -23,10 +24,10 @@
 #include <asm/module.h>
 #include <asm/pgtable.h>
 #include <asm/io.h>
-#include <asm/paccess.h>
 #include <asm/ptrace.h>
 #include <asm/watch.h>
 #include <asm/system.h>
+#include <asm/traps.h>
 #include <asm/uaccess.h>
 #include <asm/mmu_context.h>
 #include <asm/cachectl.h>
@@ -55,6 +56,8 @@ void fpu_emulator_init_fpu(void);
 char watch_available = 0;
 char dedicated_iv_available = 0;
 
+int (*be_board_handler)(struct pt_regs *regs, int is_fixup);
+
 int kstack_depth_to_print = 24;
 
 /*
@@ -272,7 +275,8 @@ search_one_table(const struct exception_
 
 extern spinlock_t modlist_lock;
 
-unsigned long search_dbe_table(unsigned long addr)
+static inline unsigned long
+search_dbe_table(unsigned long addr)
 {
 	unsigned long ret = 0;
 
@@ -308,26 +312,45 @@ unsigned long search_dbe_table(unsigned 
 #endif
 }
 
-/* Default data and instruction bus error handlers.  */
-void do_ibe(struct pt_regs *regs)
+asmlinkage void do_be(struct pt_regs *regs)
 {
-	die("Got ibe\n", regs);
-}
+	unsigned long new_epc;
+	unsigned long fixup = 0;
+	int data = regs->cp0_cause & 4;
+	int action = MIPS_BE_FATAL;
 
-void do_dbe(struct pt_regs *regs)
-{
-	unsigned long fixup;
+	if (data && !user_mode(regs))
+		fixup = search_dbe_table(regs->cp0_epc);
+
+	if (fixup)
+		action = MIPS_BE_FIXUP;
 
-	fixup = search_dbe_table(regs->cp0_epc);
-	if (fixup) {
-		long new_epc;
+	if (be_board_handler)
+		action = be_board_handler(regs, fixup != 0);
 
-		new_epc = fixup_exception(dpf_reg, fixup, regs->cp0_epc);
-		regs->cp0_epc = new_epc;
+	switch (action) {
+	case MIPS_BE_DISCARD:
 		return;
+	case MIPS_BE_FIXUP:
+		if (fixup) {
+			new_epc = fixup_exception(dpf_reg, fixup,
+						  regs->cp0_epc);
+			regs->cp0_epc = new_epc;
+			return;
+		}
+		break;
+	default:
+		break;
 	}
 
-	die("Got dbe\n", regs);
+	/*
+	 * Assume it would be too dangerous to continue ...
+	 */
+	printk(KERN_ALERT "%s bus error, epc == %08lx, ra == %08lx\n",
+	       data ? "Data" : "Instruction",
+	       regs->cp0_epc, regs->regs[31]);
+	die_if_kernel("Oops", regs);
+	force_sig(SIGBUS, current);
 }
 
 void do_ov(struct pt_regs *regs)
@@ -634,7 +657,6 @@ void __init trap_init(void)
 	extern char except_vec2_generic, except_vec2_sb1;
 	extern char except_vec3_generic, except_vec3_r4000;
 	extern char except_vec4;
-	extern void bus_error_init(void);
 	unsigned long i;
 	int dummy;
 
@@ -666,6 +688,13 @@ void __init trap_init(void)
 		set_except_vector(24, handle_mcheck);
 
 	/*
+	 * The Data Bus Errors / Instruction Bus Errors are signaled
+	 * by external hardware.  Therefore these two exceptions
+	 * may have board specific handlers.
+	 */
+	bus_error_init();
+
+	/*
 	 * Handling the following exceptions depends mostly of the cpu type
 	 */
 	switch(mips_cpu.cputype) {
@@ -713,18 +742,6 @@ void __init trap_init(void)
 		set_except_vector(6, handle_ibe);
 		set_except_vector(7, handle_dbe);
 
-		/*
-		 * If nothing uses the DBE protection mechanism this is
-		 * necessary to get the kernel to link.
-		 */
-		get_dbe(dummy, (int *)KSEG0);
-
-		/*
-		 * DBE / IBE handlers may be overridden by system specific
-		 * handlers.
-		 */
-		bus_error_init();
-
 		set_except_vector(8, handle_sys);
 		set_except_vector(9, handle_bp);
 		set_except_vector(10, handle_ri);
diff -up --recursive --new-file linux-mips-2.4.18-20020625.macro/arch/mips64/sgi-ip27/Makefile linux-mips-2.4.18-20020625/arch/mips64/sgi-ip27/Makefile
--- linux-mips-2.4.18-20020625.macro/arch/mips64/sgi-ip27/Makefile	2002-01-25 05:27:27.000000000 +0000
+++ linux-mips-2.4.18-20020625/arch/mips64/sgi-ip27/Makefile	2002-06-25 18:07:47.000000000 +0000
@@ -11,9 +11,8 @@ O_TARGET = ip27.o
 
 export-objs		= ip27-rtc.o
 
-obj-y	:= ip27-berr.o ip27-console.o ip27-dbe-glue.o ip27-irq.o ip27-init.o \
-	   ip27-irq-glue.o ip27-klconfig.o ip27-klnuma.o ip27-memory.o \
-	   ip27-nmi.o ip27-pci.o ip27-pci-dma.o ip27-reset.o ip27-setup.o \
-	   ip27-timer.o
+obj-y	:= ip27-berr.o ip27-console.o ip27-irq.o ip27-init.o ip27-irq-glue.o \
+	   ip27-klconfig.o ip27-klnuma.o ip27-memory.o ip27-nmi.o ip27-pci.o \
+	   ip27-pci-dma.o ip27-reset.o ip27-setup.o ip27-timer.o
 
 include $(TOPDIR)/Rules.make
diff -up --recursive --new-file linux-mips-2.4.18-20020625.macro/arch/mips64/sgi-ip27/ip27-berr.c linux-mips-2.4.18-20020625/arch/mips64/sgi-ip27/ip27-berr.c
--- linux-mips-2.4.18-20020625.macro/arch/mips64/sgi-ip27/ip27-berr.c	2002-01-25 05:27:27.000000000 +0000
+++ linux-mips-2.4.18-20020625/arch/mips64/sgi-ip27/ip27-berr.c	2002-06-25 19:45:12.000000000 +0000
@@ -5,6 +5,7 @@
  *
  * Copyright (C) 1994, 1995, 1996, 1999, 2000 by Ralf Baechle
  * Copyright (C) 1999, 2000 by Silicon Graphics
+ * Copyright (C) 2002  Maciej W. Rozycki
  */
 #include <linux/init.h>
 #include <linux/kernel.h>
@@ -14,24 +15,12 @@
 #include <asm/sn/addrs.h>
 #include <asm/sn/arch.h>
 #include <asm/sn/sn0/hub.h>
+#include <asm/traps.h>
 #include <asm/uaccess.h>
-#include <asm/paccess.h>
 
 extern void dump_tlb_addr(unsigned long addr);
 extern void dump_tlb_all(void);
 
-extern asmlinkage void handle_ip27_ibe(void);
-extern asmlinkage void handle_ip27_dbe(void);
-
-void do_ip27_ibe(struct pt_regs *regs)
-{
-	printk("Got ibe at 0x%lx\n", regs->cp0_epc);
-	show_regs(regs);
-	dump_tlb_addr(regs->cp0_epc);
-	force_sig(SIGBUS, current);
-	while(1);
-}
-
 static void dump_hub_information(unsigned long errst0, unsigned long errst1)
 {
 	static char *err_type[2][8] = {
@@ -65,21 +54,17 @@ static void dump_hub_information(unsigne
 		? : "invalid");
 }
 
-void do_ip27_dbe(struct pt_regs *regs)
+int be_ip27_handler(struct pt_regs *regs, int is_fixup)
 {
-	unsigned long fixup, errst0, errst1;
+	unsigned long errst0, errst1;
+	int data = regs->cp0_cause & 4;
 	int cpu = LOCAL_HUB_L(PI_CPU_NUM);
 
-	fixup = search_dbe_table(regs->cp0_epc);
-	if (fixup) {
-		long new_epc;
-
-		new_epc = fixup_exception(dpf_reg, fixup, regs->cp0_epc);
-		regs->cp0_epc = new_epc;
-		return;
-	}
+	if (is_fixup)
+		return MIPS_BE_FIXUP;
 
-	printk("Slice %c got dbe at 0x%lx\n", 'A' + cpu, regs->cp0_epc);
+	printk("Slice %c got %cbe at 0x%lx\n", 'A' + cpu, data ? 'd' : 'i',
+	       regs->cp0_epc);
 	printk("Hub information:\n");
 	printk("ERR_INT_PEND = 0x%06lx\n", LOCAL_HUB_L(PI_ERR_INT_PEND));
 	errst0 = LOCAL_HUB_L(cpu ? PI_ERR_STATUS0_B : PI_ERR_STATUS0_A);
@@ -97,8 +82,7 @@ void __init bus_error_init(void)
 	int cpu = LOCAL_HUB_L(PI_CPU_NUM);
 	int cpuoff = cpu << 8;
 
-	set_except_vector(6, handle_ip27_ibe);
-	set_except_vector(7, handle_ip27_dbe);
+	be_board_handler = be_ip27_handler;
 
 	LOCAL_HUB_S(PI_ERR_INT_PEND,
 	            cpu ? PI_ERR_CLEAR_ALL_B : PI_ERR_CLEAR_ALL_A);
diff -up --recursive --new-file linux-mips-2.4.18-20020625.macro/arch/mips64/sgi-ip27/ip27-dbe-glue.S linux-mips-2.4.18-20020625/arch/mips64/sgi-ip27/ip27-dbe-glue.S
--- linux-mips-2.4.18-20020625.macro/arch/mips64/sgi-ip27/ip27-dbe-glue.S	2002-01-24 23:14:27.000000000 +0000
+++ linux-mips-2.4.18-20020625/arch/mips64/sgi-ip27/ip27-dbe-glue.S	1970-01-01 00:00:00.000000000 +0000
@@ -1,20 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1994 - 1999 by Ralf Baechle
- * Copyright (C) 1999 Silicon Graphics
- *
- * Low level exception handling
- */
-#define __ASSEMBLY__
-#include <linux/init.h>
-#include <asm/asm.h>
-#include <asm/regdef.h>
-#include <asm/fpregdef.h>
-#include <asm/mipsregs.h>
-#include <asm/exception.h>
-
-	BUILD_HANDLER ip27_ibe ip27_ibe cli silent		/* #6  */
-	BUILD_HANDLER ip27_dbe ip27_dbe cli silent		/* #7  */
diff -up --recursive --new-file linux-mips-2.4.18-20020625.macro/arch/mips64/sgi-ip32/Makefile linux-mips-2.4.18-20020625/arch/mips64/sgi-ip32/Makefile
--- linux-mips-2.4.18-20020625.macro/arch/mips64/sgi-ip32/Makefile	2002-01-25 05:27:27.000000000 +0000
+++ linux-mips-2.4.18-20020625/arch/mips64/sgi-ip32/Makefile	2002-06-25 17:52:20.000000000 +0000
@@ -17,8 +17,8 @@ O_TARGET := ip32-kern.a
 
 all: ip32-kern.a ip32-irq-glue.o
 
-obj-y	+= ip32-rtc.o ip32-setup.o ip32-irq.o ip32-irq-glue.o ip32-timer.o \
-	   crime.o ip32-reset.o
+obj-y	+= ip32-berr.o ip32-rtc.o ip32-setup.o ip32-irq.o ip32-irq-glue.o \
+	   ip32-timer.o crime.o ip32-reset.o
 
 obj-$(CONFIG_PCI)   += ip32-pci.o
 
diff -up --recursive --new-file linux-mips-2.4.18-20020625.macro/arch/mips64/sgi-ip32/ip32-berr.c linux-mips-2.4.18-20020625/arch/mips64/sgi-ip32/ip32-berr.c
--- linux-mips-2.4.18-20020625.macro/arch/mips64/sgi-ip32/ip32-berr.c	2001-08-24 18:10:59.000000000 +0000
+++ linux-mips-2.4.18-20020625/arch/mips64/sgi-ip32/ip32-berr.c	2002-06-25 19:46:03.000000000 +0000
@@ -5,78 +5,24 @@
  *
  * Copyright (C) 1994, 1995, 1996, 1999, 2000 by Ralf Baechle
  * Copyright (C) 1999, 2000 by Silicon Graphics
+ * Copyright (C) 2002  Maciej W. Rozycki
  */
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <asm/traps.h>
 #include <asm/uaccess.h>
-#include <asm/paccess.h>
 #include <asm/addrspace.h>
 #include <asm/ptrace.h>
 
-/* XXX I have no idea what this does --kmw */
-
-extern asmlinkage void handle_ibe(void);
-extern asmlinkage void handle_dbe(void);
-
-extern const struct exception_table_entry __start___dbe_table[];
-extern const struct exception_table_entry __stop___dbe_table[];
-
-static inline unsigned long
-search_one_table(const struct exception_table_entry *first,
-                 const struct exception_table_entry *last,
-                 unsigned long value)
+int
+be_ip32_handler(struct pt_regs *regs, int is_fixup)
 {
-	while (first <= last) {
-		const struct exception_table_entry *mid;
-		long diff;
+	int data = regs->cp0_cause & 4;
 
-		mid = (last - first) / 2 + first;
-		diff = mid->insn - value;
-		if (diff == 0)
-			return mid->nextinsn;
-		else if (diff < 0)
-			first = mid+1;
-		else
-			last = mid-1;
-	}
-	return 0;
-}
-
-static inline unsigned long
-search_dbe_table(unsigned long addr)
-{
-	unsigned long ret;
+	if (is_fixup)
+		return MIPS_BE_FIXUP;
 
-	/* There is only the kernel to search.  */
-	ret = search_one_table(__start___dbe_table, __stop___dbe_table-1, addr);
-	if (ret) return ret;
-
-	return 0;
-}
-
-void do_ibe(struct pt_regs *regs)
-{
-	printk("Got ibe at 0x%lx\n", regs->cp0_epc);
-	show_regs(regs);
-	dump_tlb_addr(regs->cp0_epc);
-	force_sig(SIGBUS, current);
-	while(1);
-}
-
-void do_dbe(struct pt_regs *regs)
-{
-	unsigned long fixup;
-
-	fixup = search_dbe_table(regs->cp0_epc);
-	if (fixup) {
-		long new_epc;
-
-		new_epc = fixup_exception(dpf_reg, fixup, regs->cp0_epc);
-		regs->cp0_epc = new_epc;
-		return;
-	}
-
-	printk("Got dbe at 0x%lx\n", regs->cp0_epc);
+	printk("Got %cbe at 0x%lx\n", data ? 'd' : 'i', regs->cp0_epc);
 	show_regs(regs);
 	dump_tlb_all();
 	while(1);
@@ -86,12 +32,5 @@ void do_dbe(struct pt_regs *regs)
 void __init
 bus_error_init(void)
 {
-	int dummy;
-
-	set_except_vector(6, handle_ibe);
-	set_except_vector(7, handle_dbe);
-
-	/* At this time nothing uses the DBE protection mechanism on the
-	   O2, so this here is needed to make the kernel link.  */
-	get_dbe(dummy, (int *)KSEG0);
+	be_board_handler = be_ip27_handler;
 }
diff -up --recursive --new-file linux-mips-2.4.18-20020625.macro/arch/mips64/sgi-ip32/ip32-setup.c linux-mips-2.4.18-20020625/arch/mips64/sgi-ip32/ip32-setup.c
--- linux-mips-2.4.18-20020625.macro/arch/mips64/sgi-ip32/ip32-setup.c	2002-05-30 02:57:51.000000000 +0000
+++ linux-mips-2.4.18-20020625/arch/mips64/sgi-ip32/ip32-setup.c	2002-06-25 17:52:58.000000000 +0000
@@ -60,10 +60,6 @@ static inline void str2eaddr(unsigned ch
 
 extern void ip32_time_init(void);
 
-void __init bus_error_init(void)
-{
-}
-
 void __init ip32_setup(void)
 {
 #ifdef CONFIG_SERIAL_CONSOLE
diff -up --recursive --new-file linux-mips-2.4.18-20020625.macro/include/asm-mips/traps.h linux-mips-2.4.18-20020625/include/asm-mips/traps.h
--- linux-mips-2.4.18-20020625.macro/include/asm-mips/traps.h	1970-01-01 00:00:00.000000000 +0000
+++ linux-mips-2.4.18-20020625/include/asm-mips/traps.h	2002-06-25 19:30:41.000000000 +0000
@@ -0,0 +1,27 @@
+/*
+ *	include/asm-mips/traps.h
+ *
+ *	Trap handling definitions.
+ *
+ *	Copyright (C) 2002  Maciej W. Rozycki
+ *
+ *	This program is free software; you can redistribute it and/or
+ *	modify it under the terms of the GNU General Public License
+ *	as published by the Free Software Foundation; either version
+ *	2 of the License, or (at your option) any later version.
+ */
+#ifndef __ASM_MIPS_TRAPS_H
+#define __ASM_MIPS_TRAPS_H
+
+/*
+ * Possible status responses for a be_board_handler backend.
+ */
+#define MIPS_BE_DISCARD	0		/* return with no action */
+#define MIPS_BE_FIXUP	1		/* return to the fixup code */
+#define MIPS_BE_FATAL	2		/* treat as an unrecoverable error */
+
+extern int (*be_board_handler)(struct pt_regs *regs, int is_fixup);
+
+extern void bus_error_init(void);
+
+#endif /* __ASM_MIPS_TRAPS_H */
diff -up --recursive --new-file linux-mips-2.4.18-20020625.macro/include/asm-mips64/traps.h linux-mips-2.4.18-20020625/include/asm-mips64/traps.h
--- linux-mips-2.4.18-20020625.macro/include/asm-mips64/traps.h	1970-01-01 00:00:00.000000000 +0000
+++ linux-mips-2.4.18-20020625/include/asm-mips64/traps.h	2002-06-25 19:31:45.000000000 +0000
@@ -0,0 +1,27 @@
+/*
+ *	include/asm-mips64/traps.h
+ *
+ *	Trap handling definitions.
+ *
+ *	Copyright (C) 2002  Maciej W. Rozycki
+ *
+ *	This program is free software; you can redistribute it and/or
+ *	modify it under the terms of the GNU General Public License
+ *	as published by the Free Software Foundation; either version
+ *	2 of the License, or (at your option) any later version.
+ */
+#ifndef __ASM_MIPS64_TRAPS_H
+#define __ASM_MIPS64_TRAPS_H
+
+/*
+ * Possible status responses for a be_board_handler backend.
+ */
+#define MIPS_BE_DISCARD	0		/* return with no action */
+#define MIPS_BE_FIXUP	1		/* return to the fixup code */
+#define MIPS_BE_FATAL	2		/* treat as an unrecoverable error */
+
+extern int (*be_board_handler)(struct pt_regs *regs, int is_fixup);
+
+extern void bus_error_init(void);
+
+#endif /* __ASM_MIPS64_TRAPS_H */

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [patch] linux: DBE/IBE handling rewrite
  2002-06-26 11:51       ` [patch] linux: DBE/IBE handling rewrite Maciej W. Rozycki
@ 2002-06-26 12:05         ` Ralf Baechle
  2002-06-26 13:07           ` Maciej W. Rozycki
  2002-06-26 17:17         ` [patch] linux: DBE/IBE handling rewrite Jun Sun
  1 sibling, 1 reply; 22+ messages in thread
From: Ralf Baechle @ 2002-06-26 12:05 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: Ladislav Michl, linux-mips

On Wed, Jun 26, 2002 at 01:51:08PM +0200, Maciej W. Rozycki wrote:

> >  This way, the fixup search is invoked first and a system-specific handler
> > can judge whether to let the fixup be invoked or a serious failure
> > happened and the system should act appropriately.  The handler can do
> > whatever actions are needed (e.g. clear error status data in system
> > registers, report ECC syndromes, etc.) for the system for both cases.
> 
>  OK, here is the code.  I wrote it a bit differently from what I
> considered yesterday, as fixup doesn't seem useful for a system-specific
> handler.  With the following code only a boolean flag is passed informing
> whether a fixup is available and the handler can decide how to treat an
> error, based on the state passed as arguments and possibly additional one
> obtained from system-specific resources.  Both MIPS and MIPS64 are handled
> in the same way.  For MIPS64 it means a removal of duplicated similar code
> as well.  I adjusted some SGI-specific code appropriately, but platform
> maintainers will have to check if bus_error_init() stubs are OK for them.
> 
>  Ralf, OK to apply?

Certainly looks saner than what we're having right now.  Please apply.

  Ralf

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [patch] linux: DBE/IBE handling rewrite
  2002-06-26 12:05         ` Ralf Baechle
@ 2002-06-26 13:07           ` Maciej W. Rozycki
  2002-06-26 17:21             ` Jun Sun
  2002-06-26 20:59             ` [patch] GIO bus support Ladislav Michl
  0 siblings, 2 replies; 22+ messages in thread
From: Maciej W. Rozycki @ 2002-06-26 13:07 UTC (permalink / raw)
  To: Ralf Baechle; +Cc: Ladislav Michl, linux-mips

On Wed, 26 Jun 2002, Ralf Baechle wrote:

> Certainly looks saner than what we're having right now.  Please apply.

 Done.

-- 
+  Maciej W. Rozycki, Technical University of Gdansk, Poland   +
+--------------------------------------------------------------+
+        e-mail: macro@ds2.pg.gda.pl, PGP key available        +

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [patch] linux: DBE/IBE handling rewrite
  2002-06-26 11:51       ` [patch] linux: DBE/IBE handling rewrite Maciej W. Rozycki
  2002-06-26 12:05         ` Ralf Baechle
@ 2002-06-26 17:17         ` Jun Sun
  2002-06-27 11:51           ` Maciej W. Rozycki
  1 sibling, 1 reply; 22+ messages in thread
From: Jun Sun @ 2002-06-26 17:17 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: Ladislav Michl, Ralf Baechle, linux-mips


I suggest we have a function pointer called board_bus_error_init, which is 
initialized to a NULL function.  Any board that wishes to override it can do 
so in <board>_setup() routine.

With more amd more MIPS boards poping up, the more friendly board interface is 
the better.

Jun

Maciej W. Rozycki wrote:

> On Tue, 25 Jun 2002, Maciej W. Rozycki wrote:
> 
> 
>> This way, the fixup search is invoked first and a system-specific handler
>>can judge whether to let the fixup be invoked or a serious failure
>>happened and the system should act appropriately.  The handler can do
>>whatever actions are needed (e.g. clear error status data in system
>>registers, report ECC syndromes, etc.) for the system for both cases.
>>
> 
>  OK, here is the code.  I wrote it a bit differently from what I
> considered yesterday, as fixup doesn't seem useful for a system-specific
> handler.  With the following code only a boolean flag is passed informing
> whether a fixup is available and the handler can decide how to treat an
> error, based on the state passed as arguments and possibly additional one
> obtained from system-specific resources.  Both MIPS and MIPS64 are handled
> in the same way.  For MIPS64 it means a removal of duplicated similar code
> as well.  I adjusted some SGI-specific code appropriately, but platform
> maintainers will have to check if bus_error_init() stubs are OK for them.
> 
>  Ralf, OK to apply?
> 
>   Maciej
> 
> 

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [patch] linux: DBE/IBE handling rewrite
  2002-06-26 13:07           ` Maciej W. Rozycki
@ 2002-06-26 17:21             ` Jun Sun
  2002-06-27 12:00               ` Maciej W. Rozycki
  2002-06-26 20:59             ` [patch] GIO bus support Ladislav Michl
  1 sibling, 1 reply; 22+ messages in thread
From: Jun Sun @ 2002-06-26 17:21 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: Ralf Baechle, Ladislav Michl, linux-mips

Maciej W. Rozycki wrote:

> On Wed, 26 Jun 2002, Ralf Baechle wrote:
> 
> 
>>Certainly looks saner than what we're having right now.  Please apply.
>>
> 
>  Done.
> 
> 

Why do I have a sense we are under a dictatorship rather than a democratic 
community?  :-(

Jun

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [patch] GIO bus support
  2002-06-26 13:07           ` Maciej W. Rozycki
  2002-06-26 17:21             ` Jun Sun
@ 2002-06-26 20:59             ` Ladislav Michl
  2002-06-26 23:46               ` Ralf Baechle
  2002-06-27 12:21               ` [patch] GIO bus support Maciej W. Rozycki
  1 sibling, 2 replies; 22+ messages in thread
From: Ladislav Michl @ 2002-06-26 20:59 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: Guido Guenther, Ralf Baechle, linux-mips

On Wed, Jun 26, 2002 at 03:07:13PM +0200, Maciej W. Rozycki wrote:
> On Wed, 26 Jun 2002, Ralf Baechle wrote:
> 
> > Certainly looks saner than what we're having right now.  Please apply.
> 
>  Done.

You rock Maciej (but Jun is right ;-)) So here it is. This patch introduces
basic support for GIO bus found SGI IP22 machines. I put it into
arch/mips/sgi-ip22/ directory rather than to drivers/gio/, because the
only machine with GIO bus supported by linux is Indy and Indigo2. GIO
devices are detected early - this allows to use gio_find_device() in
newport_con.c to make it more robust.

Here is proc listing (I have Newport XL in gfx slot):
ladis@indy:~$ cat /proc/gio
GIO devices found:
  Slot GFX, DeviceId 0x04
      BaseAddr 0x1f000000, MapSize 0x00400000

I'd like to hear optinion from someone more experienced to make it as
well parseable as possible - it will be used by XFree driver.

Please see ip22_baddr() function, i did my best, but it still looks
ungly :-(

	ladis

Following patch is generated against linux_2_4 brach a while ago

--- /dev/null	Mon Mar  4 10:32:31 2002
+++ linux/include/asm/sgi/sgigio.h	Wed Jun 26 02:12:23 2002
@@ -0,0 +1,69 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * sgigio.h: Definitions for GIO bus found on SGI IP22 (and others by linux
+ *           unsupported) machines.
+ *
+ * Copyright (C) 2002 Ladislav Michl
+ */
+#ifndef _ASM_SGI_SGIGIO_H
+#define _ASM_SGI_SGIGIO_H
+
+/*
+ * There is 10MB of GIO address space for GIO64 slot devices
+ * slot#   slot type address range            size
+ * -----   --------- ----------------------- -----
+ *   0     GFX       0x1f000000 - 0x1f3fffff   4MB
+ *   1     EXP0      0x1f400000 - 0x1f5fffff   2MB
+ *   2     EXP1      0x1f600000 - 0x1f9fffff   4MB
+ *
+ * There are un-slotted devices, HPC, I/O and misc devices, which are grouped 
+ * into the HPC address space.
+ *   -     MISC      0x1fb00000 - 0x1fbfffff   1MB
+ *      
+ * Following space is reserved and unused
+ *   -     RESERVED  0x18000000 - 0x1effffff 112MB
+ *
+ * The GIO specification tends to use slot numbers while the MC specification 
+ * tends to use slot types.
+ *
+ * slot0  - the "graphics" (GFX) slot but there is no requirement that 
+ *          a graphics dev may only use this slot
+ * slot1  - this is the "expansion"-slot 0 (EXP0), do not confuse with 
+ *          slot 0 (GFX).
+ * slot2  - this is the "expansion"-slot 1 (EXP1), do not confuse with 
+ *          slot 1 (EXP0).
+ */
+
+#define GIO_SLOT_GFX	0
+#define GIO_SLOT_GIO1	1
+#define GIO_SLOT_GIO2	2
+#define GIO_NUM_SLOTS	3
+
+#define GIO_ANY_ID	0xff
+
+#define GIO_VALID_ID_ONLY	0x01
+#define GIO_IFACE_64		0x02
+#define GIO_HAS_ROM		0x04
+
+struct gio_dev {
+	unsigned char	device;
+	unsigned char	revision;
+	unsigned short	vendor;
+	unsigned char	flags;
+
+	unsigned char	slot_number;
+	unsigned long	base_addr;
+	unsigned int	map_size;
+	
+	char		*name;
+	char		slot_name[5];
+};
+
+extern struct gio_dev* gio_find_device(unsigned char device, const struct gio_dev *from);
+
+extern void sgigio_init(void);
+
+#endif /* _ASM_SGI_SGIGIO_H */
--- /dev/null	Mon Mar  4 10:32:31 2002
+++ linux/arch/mips/sgi-ip22/ip22-gio.c	Wed Jun 26 02:11:01 2002
@@ -0,0 +1,152 @@
+/* 
+ * ip22-gio.c: Support for GIO64 bus (inspired by PCI code)
+ * 
+ * Copyright (C) 2002 Ladislav Michl
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/proc_fs.h>
+
+#include <asm/sgi/sgimc.h>
+#include <asm/sgi/sgigio.h>
+
+#define GIO_PIO_MAP_BASE	0x1f000000L
+#define GIO_PIO_MAP_SIZE	(16 * 1024*1024)
+
+#define GIO_ADDR_GFX		0x1f000000L
+#define GIO_ADDR_GIO1		0x1f400000L
+#define GIO_ADDR_GIO2		0x1f600000L
+
+#define GIO_GFX_MAP_SIZE	(4 * 1024*1024)
+#define GIO_GIO1_MAP_SIZE	(2 * 1024*1024)
+#define GIO_GIO2_MAP_SIZE	(4 * 1024*1024)
+
+#define GIO_NO_DEVICE		0x80
+
+static struct gio_dev gio_slot[GIO_NUM_SLOTS] = {
+	{
+		0,
+		0,
+		0,
+		GIO_NO_DEVICE,
+		GIO_SLOT_GFX,
+		GIO_ADDR_GFX,
+		GIO_GFX_MAP_SIZE,
+		NULL,
+		"GFX"
+	},
+	{
+		0,
+		0,
+		0,
+		GIO_NO_DEVICE,
+		GIO_SLOT_GIO1,
+		GIO_ADDR_GIO1,
+		GIO_GIO1_MAP_SIZE,
+		NULL,
+		"EXP0"
+	},
+	{
+		0,
+		0,
+		0,
+		GIO_NO_DEVICE,
+		GIO_SLOT_GIO2,
+		GIO_ADDR_GIO2,
+		GIO_GIO2_MAP_SIZE,
+		NULL,
+		"EXP1"
+	}
+};
+
+static int gio_read_proc(char *buf, char **start, off_t off,
+			 int count, int *eof, void *data)
+{
+	int i;
+	char *p = buf;
+	
+	p += sprintf(p, "GIO devices found:\n");
+	for (i = 0; i < GIO_NUM_SLOTS; i++) {
+		if (gio_slot[i].flags & GIO_NO_DEVICE)
+			continue;
+		p += sprintf(p, "  Slot %s, DeviceId 0x%02x\n",
+			     gio_slot[i].slot_name, gio_slot[i].device);
+		p += sprintf(p, "    BaseAddr 0x%08lx, MapSize 0x%08x\n",
+			     gio_slot[i].base_addr, gio_slot[i].map_size);
+	}
+	
+	return p - buf;
+}
+
+void create_gio_proc_entry(void)
+{
+	create_proc_read_entry("gio", 0, NULL, gio_read_proc, NULL);
+}
+
+/**
+ * gio_find_device - begin or continue searching for a GIO device by device id
+ * @device: GIO device id to match, or %GIO_ANY_ID to match all device ids
+ * @from: Previous GIO device found in search, or %NULL for new search.
+ *
+ * Iterates through the list of known GIO devices. If a GIO device is found
+ * with a matching @device, a pointer to its device structure is returned. 
+ * Otherwise, %NULL is returned.
+ * A new search is initiated by passing %NULL to the @from argument.
+ * Otherwise if @from is not %NULL, searches continue from next device.
+ */
+struct gio_dev *
+gio_find_device(unsigned char device, const struct gio_dev *from)
+{
+	int i;
+	
+	for (i = (from) ? from->slot_number : 0; i < GIO_NUM_SLOTS; i++)
+		if (!(gio_slot[i].flags & GIO_NO_DEVICE) && 
+		   (device == GIO_ANY_ID || device == gio_slot[i].device))
+			return &gio_slot[i];
+	
+	return NULL;
+}
+
+#define GIO_IDCODE(x)		(x & 0x7f)
+#define GIO_ALL_BITS_VALID	0x80
+#define GIO_REV(x)		((x >> 8) & 0xff)
+#define GIO_GIO_SIZE_64		0x10000
+#define GIO_ROM_PRESENT		0x20000
+#define GIO_VENDOR_CODE(x)	((x >> 18) & 0x3fff)
+
+extern int ip22_baddr(unsigned int *val, unsigned long addr);
+
+/** 
+ * sgigio_init - scan the GIO space and figure out what hardware is actually
+ * present.
+ */
+void __init sgigio_init(void)
+{
+	unsigned int i, id, found = 0;
+
+	printk("GIO: Scanning for GIO cards...\n");
+	for (i = 0; i < GIO_NUM_SLOTS; i++) {
+		if (ip22_baddr(&id, KSEG1ADDR(gio_slot[i].base_addr)))
+			continue;
+
+		found = 1;
+		gio_slot[i].device = GIO_IDCODE(id);
+		if (id & GIO_ALL_BITS_VALID) {
+			gio_slot[i].revision = GIO_REV(id);
+			gio_slot[i].vendor = GIO_VENDOR_CODE(id);
+			gio_slot[i].flags =
+				(id & GIO_GIO_SIZE_64) ? GIO_IFACE_64 : 0 |
+				(id & GIO_ROM_PRESENT) ? GIO_HAS_ROM : 0;
+		} else
+			gio_slot[i].flags = GIO_VALID_ID_ONLY;
+
+		printk("GIO: Card 0x%02x @ 0x%08lx\n", gio_slot[i].device,
+			gio_slot[i].base_addr);
+	}
+	
+	if (!found)
+		printk("GIO: No GIO cards present.\n");
+}
--- /dev/null	Mon Mar  4 10:32:31 2002
+++ linux/arch/mips/sgi-ip22/ip22-berr.c	Wed Jun 26 02:06:56 2002
@@ -0,0 +1,78 @@
+/*
+ * ip22-berr.c: Bus error handling.
+ *
+ * Copyright (C) 2002 Ladislav Michl
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+#include <asm/addrspace.h>
+#include <asm/system.h>
+#include <asm/traps.h>
+#include <asm/branch.h>
+#include <asm/sgi/sgimc.h>
+#include <asm/sgi/sgihpc.h>
+
+unsigned int cpu_err_stat;	/* Status reg for CPU */
+unsigned int gio_err_stat;	/* Status reg for GIO */
+unsigned int cpu_err_addr;	/* Error address reg for CPU */
+unsigned int gio_err_addr;	/* Error address reg for GIO */
+
+volatile int nofault;
+
+static void save_and_clear_buserr(void)
+{
+	/* save memory controler's error status registers */ 
+	cpu_err_addr = mcmisc_regs->cerr;
+	cpu_err_stat = mcmisc_regs->cstat;
+	gio_err_addr = mcmisc_regs->gerr;
+	gio_err_stat = mcmisc_regs->gstat;
+
+	mcmisc_regs->cstat = mcmisc_regs->gstat = 0;
+}
+
+/*
+ * MC sends an interrupt whenever bus or parity errors occur. In addition, 
+ * if the error happened during a CPU read, it also asserts the bus error 
+ * pin on the R4K. Code in bus error handler save the MC bus error registers
+ * and then clear the interrupt when this happens.
+ */
+
+void be_ip22_interrupt(int irq, struct pt_regs *regs)
+{
+	save_and_clear_buserr();
+	printk(KERN_ALERT "Bus error, epc == %08lx, ra == %08lx\n",
+	       regs->cp0_epc, regs->regs[31]);
+	die_if_kernel("Oops", regs);
+	force_sig(SIGBUS, current);
+}
+
+int be_ip22_handler(struct pt_regs *regs, int is_fixup)
+{
+	save_and_clear_buserr();
+	if (nofault) {
+		nofault = 0;
+		compute_return_epc(regs);
+		return MIPS_BE_DISCARD;
+	}
+	return MIPS_BE_FIXUP;
+}
+
+int ip22_baddr(unsigned int *val, unsigned long addr)
+{
+	nofault = 1;
+	*val = *(volatile unsigned int *) addr;
+	__asm__ __volatile__("nop;nop;nop;nop");
+	if (nofault) {
+		nofault = 0;
+		return 0;
+	}
+	return -EFAULT;
+}
+
+void __init bus_error_init(void)
+{
+	be_board_handler = be_ip22_handler;
+}
Index: linux/arch/mips/sgi-ip22/ip22-int.c
===================================================================
RCS file: /cvs/linux/arch/mips/sgi-ip22/ip22-int.c,v
retrieving revision 1.2.2.2
diff -u -r1.2.2.2 ip22-int.c
--- linux/arch/mips/sgi-ip22/ip22-int.c	2002/06/26 11:48:54	1.2.2.2
+++ linux/arch/mips/sgi-ip22/ip22-int.c	2002/06/26 20:41:03
@@ -16,8 +16,8 @@
 #include <linux/signal.h>
 #include <linux/sched.h>
 #include <linux/interrupt.h>
+#include <linux/irq.h>
 
-#include <asm/irq.h>
 #include <asm/mipsregs.h>
 #include <asm/addrspace.h>
 #include <asm/gdb-stub.h>
@@ -279,6 +279,8 @@
 	return;	
 }
 
+extern void be_ip22_interrupt(int irq, struct pt_regs *regs);
+
 void indy_buserror_irq(struct pt_regs *regs)
 {
 	int cpu = smp_processor_id();
@@ -286,9 +288,7 @@
 
 	irq_enter(cpu, irq);
 	kstat.irqs[cpu][irq]++;
-	die("Got a bus error IRQ, shouldn't happen yet\n", regs);
-	printk("Spinning...\n");
-	while(1);
+	be_ip22_interrupt(irq, regs);
 	irq_exit(cpu, irq);
 }
 
@@ -305,9 +305,8 @@
 	{ no_action, SA_INTERRUPT, 0, "mappable1 cascade", NULL, NULL };
 #endif
 
-extern int setup_irq(unsigned int irq, struct irqaction *irqaction);
-extern void mips_cpu_irq_init(u32 irq_base);
-	
+extern void mips_cpu_irq_init(unsigned int irq_base);
+
 void __init init_IRQ(void)
 {
 	int i;
Index: linux/arch/mips/sgi-ip22/ip22-mc.c
===================================================================
RCS file: /cvs/linux/arch/mips/sgi-ip22/ip22-mc.c,v
retrieving revision 1.1.2.2
diff -u -r1.1.2.2 ip22-mc.c
--- linux/arch/mips/sgi-ip22/ip22-mc.c	2002/06/26 11:44:49	1.1.2.2
+++ linux/arch/mips/sgi-ip22/ip22-mc.c	2002/06/26 20:42:55
@@ -4,20 +4,21 @@
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  * Copyright (C) 1999 Andrew R. Baker (andrewb@uab.edu) - Indigo2 changes
  */
+
 #include <linux/init.h>
 #include <linux/kernel.h>
 
 #include <asm/addrspace.h>
 #include <asm/ptrace.h>
+#include <asm/sgialib.h>
 #include <asm/sgi/sgimc.h>
 #include <asm/sgi/sgihpc.h>
-#include <asm/sgialib.h>
 
 /* #define DEBUG_SGIMC */
 
 struct sgimc_misc_ctrl *mcmisc_regs;
-u32 *rpsscounter;
 struct sgimc_dma_ctrl *dmactrlregs;
+u32 *rpsscounter;
 
 static inline char *mconfig_string(unsigned long val)
 {
@@ -42,7 +43,7 @@
 
 	default:
 		return "wheee, unknown";
-	};
+	}
 }
 
 void __init sgimc_init(void)
@@ -50,8 +51,8 @@
 	unsigned long tmpreg;
 
 	mcmisc_regs = (struct sgimc_misc_ctrl *)(KSEG1+0x1fa00000);
-	rpsscounter = (unsigned int *) (KSEG1 + 0x1fa01004);
-	dmactrlregs = (struct sgimc_dma_ctrl *) (KSEG1+0x1fa02000);
+	rpsscounter = (unsigned int *)(KSEG1+0x1fa01004);
+	dmactrlregs = (struct sgimc_dma_ctrl *)(KSEG1+0x1fa02000);
 
 	printk(KERN_INFO "MC: SGI memory controller Revision %d\n",
 	       (int) mcmisc_regs->systemid & SGIMC_SYSID_MASKREV);
@@ -81,7 +82,7 @@
 	/* Place the MC into a known state.  This must be done before
 	 * interrupts are first enabled etc.
 	 */
-
+	
 	/* Step 0: Make sure we turn off the watchdog in case it's
 	 *         still running (which might be the case after a
 	 *         soft reboot).
@@ -137,7 +138,7 @@
 	 *       revision on this machine.  You have been warned.
 	 */
 
-	/* First the basic invariants across all gio64 implementations. */
+	/* First the basic invariants across all GIO64 implementations. */
 	tmpreg = SGIMC_GIOPARM_HPC64;    /* All 1st HPC's interface at 64bits. */
 	tmpreg |= SGIMC_GIOPARM_ONEBUS;  /* Only one physical GIO bus exists. */
 
Index: linux/arch/mips/sgi-ip22/ip22-time.c
===================================================================
RCS file: /cvs/linux/arch/mips/sgi-ip22/ip22-time.c,v
retrieving revision 1.1.2.6
diff -u -r1.1.2.6 ip22-time.c
--- linux/arch/mips/sgi-ip22/ip22-time.c	2002/06/26 11:44:49	1.1.2.6
+++ linux/arch/mips/sgi-ip22/ip22-time.c	2002/06/26 20:47:22
@@ -20,6 +20,7 @@
 #include <asm/ds1286.h>
 #include <asm/sgialib.h>
 #include <asm/sgi/sgint23.h>
+#include <asm/sgi/sgigio.h>
 #include <asm/time.h>
 
 /*
@@ -179,6 +180,14 @@
 		(int) (r4k_tick / 5000), (int) (r4k_tick % 5000) / 50);
 
 	mips_counter_frequency = r4k_tick * HZ;	
+	
+	/* HACK ALERT! This get's called after traps initialization
+	 * We piggyback the initialization of GIO bus here even though
+	 * it is technically not related with the timer in any way.
+	 * Doing it from ip22_setup wouldn't work since traps aren't 
+	 * initialized yet.
+	 */
+	sgigio_init();
 }
 
 /* Generic SGI handler for (spurious) 8254 interrupts */
Index: linux/arch/mips/sgi-ip22/ip22-setup.c
===================================================================
RCS file: /cvs/linux/arch/mips/sgi-ip22/ip22-setup.c,v
retrieving revision 1.1.2.9
diff -u -r1.1.2.9 ip22-setup.c
--- linux/arch/mips/sgi-ip22/ip22-setup.c	2002/06/26 12:22:42	1.1.2.9
+++ linux/arch/mips/sgi-ip22/ip22-setup.c	2002/06/26 20:49:01
@@ -46,6 +46,7 @@
 extern struct rtc_ops indy_rtc_ops;
 extern void indy_reboot_setup(void);
 extern void sgi_volume_set(unsigned char);
+extern void create_gio_proc_entry(void);
 
 #define sgi_kh ((struct hpc_keyb *) &(hpc3mregs->kbdmouse0))
 
@@ -61,12 +62,18 @@
 static int sgi_request_irq(void (*handler)(int, void *, struct pt_regs *))
 {
 	/* Dirty hack, this get's called as a callback from the keyboard
-	   driver.  We piggyback the initialization of the front panel
-	   button handling on it even though they're technically not
-	   related with the keyboard driver in any way.  Doing it from
-	   indy_setup wouldn't work since kmalloc isn't initialized yet.  */
+	 * driver.  We piggyback the initialization of the front panel
+	 * button handling on it even though they're technically not
+	 * related with the keyboard driver in any way.  Doing it from
+	 * ip22_setup wouldn't work since kmalloc isn't initialized yet.
+	 */
 	indy_reboot_setup();
 
+	/* Ehm, well... once David used hack above, let's add yet another.
+	 * Register GIO bus proc entry here.
+	 */
+	create_gio_proc_entry();
+
 	return request_irq(SGI_KEYBD_IRQ, handler, 0, "keyboard", NULL);
 }
 
@@ -123,10 +130,6 @@
 	sgi_write_command,
 	sgi_read_status
 };
-
-void __init bus_error_init(void)
-{
-}
 
 void __init ip22_setup(void)
 {

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [patch] GIO bus support
  2002-06-26 20:59             ` [patch] GIO bus support Ladislav Michl
@ 2002-06-26 23:46               ` Ralf Baechle
  2002-06-27 10:14                   ` jeff
  2002-06-27 12:21               ` [patch] GIO bus support Maciej W. Rozycki
  1 sibling, 1 reply; 22+ messages in thread
From: Ralf Baechle @ 2002-06-26 23:46 UTC (permalink / raw)
  To: Ladislav Michl; +Cc: Maciej W. Rozycki, Guido Guenther, linux-mips

On Wed, Jun 26, 2002 at 10:59:56PM +0200, Ladislav Michl wrote:

> I'd like to hear optinion from someone more experienced to make it as
> well parseable as possible - it will be used by XFree driver.
> 
> Please see ip22_baddr() function, i did my best, but it still looks
> ungly :-(
> 
> 	ladis
> 
> Following patch is generated against linux_2_4 brach a while ago
> 
> --- /dev/null	Mon Mar  4 10:32:31 2002
> +++ linux/include/asm/sgi/sgigio.h	Wed Jun 26 02:12:23 2002
                   ^^^^

*whap* :-)

  Ralf

^ permalink raw reply	[flat|nested] 22+ messages in thread

* FIR problem
@ 2002-06-27 10:14                   ` jeff
  0 siblings, 0 replies; 22+ messages in thread
From: jeff @ 2002-06-27 10:14 UTC (permalink / raw)
  To: linux-mips; +Cc: jeff_lee

Dear All,
    Is there anybody know how to use the DMA on Vr4131?
We want to drive the High Point 371 HDD driver and wnat
to enable DMA. Base on the specfication, Vr4131 has the
I/O <-> Memory DMA channel.
    Now the PIO mode is running good, but speed is too slow.

Thanks and best regs,

Jeff

^ permalink raw reply	[flat|nested] 22+ messages in thread

* FIR problem
@ 2002-06-27 10:14                   ` jeff
  0 siblings, 0 replies; 22+ messages in thread
From: jeff @ 2002-06-27 10:14 UTC (permalink / raw)
  To: linux-mips; +Cc: jeff_lee

Dear All,
    Is there anybody know how to use the DMA on Vr4131?
We want to drive the High Point 371 HDD driver and wnat
to enable DMA. Base on the specfication, Vr4131 has the
I/O <-> Memory DMA channel.
    Now the PIO mode is running good, but speed is too slow.

Thanks and best regs,

Jeff

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [patch] linux: DBE/IBE handling rewrite
  2002-06-26 17:17         ` [patch] linux: DBE/IBE handling rewrite Jun Sun
@ 2002-06-27 11:51           ` Maciej W. Rozycki
  0 siblings, 0 replies; 22+ messages in thread
From: Maciej W. Rozycki @ 2002-06-27 11:51 UTC (permalink / raw)
  To: Jun Sun; +Cc: Ladislav Michl, Ralf Baechle, linux-mips

On Wed, 26 Jun 2002, Jun Sun wrote:

> I suggest we have a function pointer called board_bus_error_init, which is 
> initialized to a NULL function.  Any board that wishes to override it can do 
> so in <board>_setup() routine.

 I thought about it (even started coding, but postponed the task), but I
didn't want to complicate things at the first approach.  Especially as
multiple-system support doesn't exist now and bits were already done this
way.  Feel free to improve the code -- I will look at it again when I am
writing a handler for DECstations, but I can't state exactly when, yet.

> With more amd more MIPS boards poping up, the more friendly board interface is 
> the better.

 I was thinking of the system identification problem today morning and I
believe I know how to detect a DECstation reliably. 

-- 
+  Maciej W. Rozycki, Technical University of Gdansk, Poland   +
+--------------------------------------------------------------+
+        e-mail: macro@ds2.pg.gda.pl, PGP key available        +

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [patch] linux: DBE/IBE handling rewrite
  2002-06-26 17:21             ` Jun Sun
@ 2002-06-27 12:00               ` Maciej W. Rozycki
  2002-06-27 17:12                 ` Jun Sun
  0 siblings, 1 reply; 22+ messages in thread
From: Maciej W. Rozycki @ 2002-06-27 12:00 UTC (permalink / raw)
  To: Jun Sun; +Cc: Ralf Baechle, Ladislav Michl, linux-mips

On Wed, 26 Jun 2002, Jun Sun wrote:

> Why do I have a sense we are under a dictatorship rather than a democratic 
> community?  :-(

 It's a pity you have such a feeling.  I'm looking forward to seeing a
better replacement from you.  But why didn't you fix the code earlier,
OTOH?

-- 
+  Maciej W. Rozycki, Technical University of Gdansk, Poland   +
+--------------------------------------------------------------+
+        e-mail: macro@ds2.pg.gda.pl, PGP key available        +

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [patch] GIO bus support
  2002-06-26 20:59             ` [patch] GIO bus support Ladislav Michl
  2002-06-26 23:46               ` Ralf Baechle
@ 2002-06-27 12:21               ` Maciej W. Rozycki
  2002-08-04 22:03                 ` Ladislav Michl
  2002-09-28 19:55                 ` Ladislav Michl
  1 sibling, 2 replies; 22+ messages in thread
From: Maciej W. Rozycki @ 2002-06-27 12:21 UTC (permalink / raw)
  To: Ladislav Michl; +Cc: Guido Guenther, Ralf Baechle, linux-mips

On Wed, 26 Jun 2002, Ladislav Michl wrote:

> +int be_ip22_handler(struct pt_regs *regs, int is_fixup)
> +{
> +	save_and_clear_buserr();
> +	if (nofault) {
> +		nofault = 0;
> +		compute_return_epc(regs);
> +		return MIPS_BE_DISCARD;
> +	}
> +	return MIPS_BE_FIXUP;
> +}

 I wouldn't use nofault -- it leads to reentrancy problems and I don't
think you really need it.  You probably need to code it like this:

{
	save_and_clear_buserr();

	return is_fixup ? MIPS_BE_FIXUP : MIPS_BE_FATAL;
}

unless:

1. There is a condition when for is_fixup true you should ignore the fixup
anyway (e.g. what the bus error logic reports is irrelevant to fixups). 
You should choose between MIPS_BE_FATAL and MIPS_BE_DISCARD then. 

2. There is a condition when for is_fixup false, an error is not fatal and
execution should get restarted.  You should return MIPS_BE_DISCARD then.


> +int ip22_baddr(unsigned int *val, unsigned long addr)
> +{
> +	nofault = 1;
> +	*val = *(volatile unsigned int *) addr;
> +	__asm__ __volatile__("nop;nop;nop;nop");
> +	if (nofault) {
> +		nofault = 0;
> +		return 0;
> +	}
> +	return -EFAULT;
> +}

 Why not simply:

{
	int err;

	err = get_dbe(*val, (volatile unsigned int *) addr);

	return err ? -EFAULT : 0;
}

It was designed exactly for this purpose.  You may consider using "u32" 
instead of "unsigned int" for hardware accesses to assure the type will
always be 32-bit.

  Maciej

-- 
+  Maciej W. Rozycki, Technical University of Gdansk, Poland   +
+--------------------------------------------------------------+
+        e-mail: macro@ds2.pg.gda.pl, PGP key available        +

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [patch] linux: DBE/IBE handling rewrite
  2002-06-27 12:00               ` Maciej W. Rozycki
@ 2002-06-27 17:12                 ` Jun Sun
  2002-06-27 18:29                   ` Maciej W. Rozycki
  0 siblings, 1 reply; 22+ messages in thread
From: Jun Sun @ 2002-06-27 17:12 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: Ralf Baechle, Ladislav Michl, linux-mips

Maciej W. Rozycki wrote:

> On Wed, 26 Jun 2002, Jun Sun wrote:
> 
> 
>>Why do I have a sense we are under a dictatorship rather than a democratic 
>>community?  :-(
>>
> 
>  It's a pity you have such a feeling.  I'm looking forward to seeing a
> better replacement from you.  But why didn't you fix the code earlier,
> OTOH?


You missed the point - I like to see some open discussions before any big 
changes to MIPS.  If you look back of all the significant changes made to the 
MIPS tree, you will see a high percentage of them went in without any open 
discussion or pre-warning.  It is this context that brought out :-(.  Not your 
patch per se.

Once in while I hop into other communities.  I get a feeling they appear to be 
doing better than us in this regard.  And I like that feeling.

Jun

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [patch] linux: DBE/IBE handling rewrite
  2002-06-27 17:12                 ` Jun Sun
@ 2002-06-27 18:29                   ` Maciej W. Rozycki
  2002-06-27 19:08                     ` Jun Sun
  0 siblings, 1 reply; 22+ messages in thread
From: Maciej W. Rozycki @ 2002-06-27 18:29 UTC (permalink / raw)
  To: Jun Sun; +Cc: Ralf Baechle, Ladislav Michl, linux-mips

On Thu, 27 Jun 2002, Jun Sun wrote:

> You missed the point - I like to see some open discussions before any big 
> changes to MIPS.  If you look back of all the significant changes made to the 

 Agreed.

> MIPS tree, you will see a high percentage of them went in without any open 

 I can't actually recall any significant changes recently (barring
platform additions I don't really track), certainly not since 2.4.  All I
observe are bug fixes, clean-ups and similar stuff.

> discussion or pre-warning.  It is this context that brought out :-(.  Not your 
> patch per se.

 If you suggest that this change qualifies as big, then I'd write you
exaggerate.  Anyway, I've sent a proposed function and then a real
implementation of bits that were broken "since forever".  Even the
previous clean-up, for 32-bit MIPS solely, was written by me -- apparently
nobody else was interested in the subsystem.

 Then you are aware of the changes.  You may look at the original and the
new code.  You may suggest improvements, fixes, etc.  The source tree is
not cast in stone -- any changes may get reverted, fixed, rewritten, etc. 

 Thus I think the context is clean. 

> Once in while I hop into other communities.  I get a feeling they appear to be 
> doing better than us in this regard.  And I like that feeling.

 Well, as you might have noticed I send unobvious patches here, asking for
comments (usually getting no response, unforunately).  I comment on
others' changes if I feel I have thoughts to express.  I don't sent
patches I consider obvious here -- if you worry of bad changes, then just
follow the CVS list.  I reply to commits I consider problematic when I
spot one, others do as well.

 I believe the arrangement here is as good as it can be.  Certainly it's
not worse than that of the linux-kernel list (with the official kernel you
usually know something got changed in the i386 or generic bits only after
your favourite non-i386 code doesn't work or even compile anymore).  The
volume is low, easy to follow.  I sometimes even worry it's too low -- as
if hardly anyone was interested.

  Maciej

-- 
+  Maciej W. Rozycki, Technical University of Gdansk, Poland   +
+--------------------------------------------------------------+
+        e-mail: macro@ds2.pg.gda.pl, PGP key available        +

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [patch] linux: DBE/IBE handling rewrite
  2002-06-27 18:29                   ` Maciej W. Rozycki
@ 2002-06-27 19:08                     ` Jun Sun
  2002-06-27 20:00                       ` Maciej W. Rozycki
  0 siblings, 1 reply; 22+ messages in thread
From: Jun Sun @ 2002-06-27 19:08 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: Ralf Baechle, Ladislav Michl, linux-mips

Maciej W. Rozycki wrote:

> On Thu, 27 Jun 2002, Jun Sun wrote:
> 
> 
>>You missed the point - I like to see some open discussions before any big 
>>changes to MIPS.  If you look back of all the significant changes made to the 
>>
> 
>  Agreed.
> 
> 
>>MIPS tree, you will see a high percentage of them went in without any open 
>>
> 
>  I can't actually recall any significant changes recently (barring
> platform additions I don't really track), certainly not since 2.4.  All I
> observe are bug fixes, clean-ups and similar stuff.
> 


Here are some of those on top of my mind.  And I am pretty sure I am missing 
others:

1) /proc/cpuinfo and some bootinfo.h change  (I think these two come from one 
change)
2) split of cache and tlb files
3) some kind of flush_cache_LSB() routines.


> 
>>discussion or pre-warning.  It is this context that brought out :-(.  Not your 
>>patch per se.
>>
> 
>  If you suggest that this change qualifies as big, then I'd write you
> exaggerate. 


It is not big logically.  However, outside all the boards that are in oss 
tree, I can safely say there are at least twenty MIPS porting efforts going on 
at various stages.  Next time those people sync up with oss, they will find 
the missing symbol of bus_error_init().


 Anyway, I've sent a proposed function and then a real
> implementation of bits that were broken "since forever".  Even the
> previous clean-up, for 32-bit MIPS solely, was written by me -- apparently
> nobody else was interested in the subsystem.
> 


It wasn't my intention to dampen your MIPS contribution.  In fact, I start to 
regret about my first email which now looks a little irresponsible.

If anything out of this thread can increase the awareness of open discussion 
and awareness of the existence of many boards which are not part of oss tree 
yet, I shall be happy.


Jun

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [patch] linux: DBE/IBE handling rewrite
  2002-06-27 19:08                     ` Jun Sun
@ 2002-06-27 20:00                       ` Maciej W. Rozycki
  0 siblings, 0 replies; 22+ messages in thread
From: Maciej W. Rozycki @ 2002-06-27 20:00 UTC (permalink / raw)
  To: Jun Sun; +Cc: Ralf Baechle, Ladislav Michl, linux-mips

On Thu, 27 Jun 2002, Jun Sun wrote:

> Here are some of those on top of my mind.  And I am pretty sure I am missing 
> others:
> 
> 1) /proc/cpuinfo and some bootinfo.h change  (I think these two come from one 
> change)

 Well, the addition of a FPU revision was my fault, but it was posted here
for discussion.  Now I am not completely satisfied with it, I admit, as
the implementation level is not reported -- only the revision.  I think
the implementation should be presented in a form of a textual name, like
it's done for the CPU, perhaps in a separate line.

 Others, I am not aware of.

> 2) split of cache and tlb files

 It was justified in my opinion.  Besides it was Ralf who did it, I
believe and that's his right of a MIPS maintainer, like Linus keeps the
right to change whatever he likes to within the kernel without asking
anyone.  That what makes someone a maintainer, after all.

> 3) some kind of flush_cache_LSB() routines.

 I can't recall, sorry.

> It is not big logically.  However, outside all the boards that are in oss 
> tree, I can safely say there are at least twenty MIPS porting efforts going on 
> at various stages.  Next time those people sync up with oss, they will find 
> the missing symbol of bus_error_init().

 Well, they get what they deserve for not releasing early.  Still, I'm
trying my best not to break others' work.  You wouldn't get that luxury
with the official kernel -- once a subsystem gets reorganized, only basic
bits (usually i386 and the platform the author is working on) get adjusted
and the rest is left broken until someone interested fixes it.  There is a
benefit, though -- that's actually a good determinator of bits no one is
interested anymore.  If a configuration keeps impossible to be compiled
for a long time, it's a sign it may probably be scheduled for a removal
soon. 

 OTOH, my private tree differs from the CVS by 36 patches now (a few less
as of today, as they got merged), which are awaiting an approval or are
unfinished or should really go to the official kernelor whatever and I can
live with that.  Occassionally I have to adjust them due to changes in the
CVS, but what's the deal? 

 Also when working on a change I usually don't switch kernels.  I let it
be finished, then try with a current snapshot, adjust as needed and only
then it's ready to be sent here and/or applied to the tree.  E.g. I'm
working on a serious update to the DECstation code and I use a snapshot
from May 30th.  Only when I consider it ready for merging I'll update its
working tree, even though I am already using a snapshot from Jun 25th for
other stuff.  Also I'll not wait for the update to be rock-solid -- I'll
merge it as soon as it's usable to some extent (unstable bits won't affect
existing code) and then I'll debug it myself as well as let others do that
if interested. 

 Plain and simple -- that's how the idea works.

> It wasn't my intention to dampen your MIPS contribution.  In fact, I start to 
> regret about my first email which now looks a little irresponsible.

 Not a problem -- we are all people after all and it's usually better to
express thoughts than to keep them inside.  This way you give others a
chance to clear the situation.

> If anything out of this thread can increase the awareness of open discussion 
> and awareness of the existence of many boards which are not part of oss tree 
> yet, I shall be happy.

 Well, I hope there will be benefits, as there usually are as a result of
good discussions.  For the writers of the external code I'd advise to try
merging as soon as they can, not only after code gets mature.  This way
others may try the code, comment on it and the code will have a chance to
be automatically adjusted whenever a more widespread change happens.  This
also minimizes a risk of a number of people working on the same problem in
parllel without knowing about one another.  There is hardly anything as
frustrating as duplicating somebody's work needlessly.

  Maciej

-- 
+  Maciej W. Rozycki, Technical University of Gdansk, Poland   +
+--------------------------------------------------------------+
+        e-mail: macro@ds2.pg.gda.pl, PGP key available        +

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [patch] GIO bus support
  2002-06-27 12:21               ` [patch] GIO bus support Maciej W. Rozycki
@ 2002-08-04 22:03                 ` Ladislav Michl
  2002-09-28 19:55                 ` Ladislav Michl
  1 sibling, 0 replies; 22+ messages in thread
From: Ladislav Michl @ 2002-08-04 22:03 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: Guido Guenther, linux-mips

On Thu, Jun 27, 2002 at 02:21:30PM +0200, Maciej W. Rozycki wrote:
> On Wed, 26 Jun 2002, Ladislav Michl wrote:
> 
> > +int be_ip22_handler(struct pt_regs *regs, int is_fixup)
> > +{
> > +	save_and_clear_buserr();
> > +	if (nofault) {
> > +		nofault = 0;
> > +		compute_return_epc(regs);
> > +		return MIPS_BE_DISCARD;
> > +	}
> > +	return MIPS_BE_FIXUP;
> > +}
> 
>  I wouldn't use nofault -- it leads to reentrancy problems and I don't
> think you really need it.  You probably need to code it like this:
> 
> {
> 	save_and_clear_buserr();
> 
> 	return is_fixup ? MIPS_BE_FIXUP : MIPS_BE_FATAL;
> }
> 
> unless:
> 
> 1. There is a condition when for is_fixup true you should ignore the fixup
> anyway (e.g. what the bus error logic reports is irrelevant to fixups). 
> You should choose between MIPS_BE_FATAL and MIPS_BE_DISCARD then. 
> 
> 2. There is a condition when for is_fixup false, an error is not fatal and
> execution should get restarted.  You should return MIPS_BE_DISCARD then.

You are probably right. Unfortunately I cannot verify following patch
(my Indy is currently dead). I hope there is enough brave men for this
dirty job :-)

	ladis

--- linux/arch/mips/sgi-ip22/ip22-berr.c.orig	Thu Aug  1 23:26:10 2002
+++ linux/arch/mips/sgi-ip22/ip22-berr.c	Sun Aug  4 23:03:34 2002
@@ -20,8 +20,6 @@
 unsigned int cpu_err_addr;	/* Error address reg for CPU */
 unsigned int gio_err_addr;	/* Error address reg for GIO */
 
-volatile int nofault;
-
 static void save_and_clear_buserr(void)
 {
 	/* save memory controler's error status registers */ 
@@ -33,6 +31,35 @@
 	mcmisc_regs->cstat = mcmisc_regs->gstat = 0;
 }
 
+#define GIO_ERRMASK	0xff00
+#define CPU_ERRMASK	0x3f00
+
+static void print_buserr(void)
+{
+	if (cpu_err_stat & CPU_ERRMASK)
+		printk(KERN_ALERT "CPU Error/Addr 0x%x<%s%s%s%s%s%s> 0x%08x\n",
+			cpu_err_stat,
+			cpu_err_stat & SGIMC_CSTAT_RD ? "RD " : "",
+			cpu_err_stat & SGIMC_CSTAT_PAR ? "PAR " : "",
+			cpu_err_stat & SGIMC_CSTAT_ADDR ? "ADDR " : "",
+			cpu_err_stat & SGIMC_CSTAT_SYSAD_PAR ? "SYSAD " : "",
+			cpu_err_stat & SGIMC_CSTAT_SYSCMD_PAR ? "SYSCMD " : "",
+			cpu_err_stat & SGIMC_CSTAT_BAD_DATA ? "BAD_DATA " : "",
+			cpu_err_addr);
+	if (gio_err_stat & GIO_ERRMASK)
+		printk(KERN_ALERT "GIO Error/Addr 0x%x:<%s%s%s%s%s%s%s%s> 0x08%x\n",
+			gio_err_stat,
+			gio_err_stat & SGIMC_GSTAT_RD ? "RD " : "",
+			gio_err_stat & SGIMC_GSTAT_WR ? "WR " : "",
+			gio_err_stat & SGIMC_GSTAT_TIME ? "TIME " : "",
+			gio_err_stat & SGIMC_GSTAT_PROM ? "PROM " : "",
+			gio_err_stat & SGIMC_GSTAT_ADDR ? "ADDR " : "",
+			gio_err_stat & SGIMC_GSTAT_BC ? "BC " : "",
+			gio_err_stat & SGIMC_GSTAT_PIO_RD ? "PIO_RD " : "",
+			gio_err_stat & SGIMC_GSTAT_PIO_WR ? "PIO_WR " : "",
+			gio_err_addr);
+}
+
 /*
  * MC sends an interrupt whenever bus or parity errors occur. In addition, 
  * if the error happened during a CPU read, it also asserts the bus error 
@@ -43,6 +70,7 @@
 void be_ip22_interrupt(int irq, struct pt_regs *regs)
 {
 	save_and_clear_buserr();
+	print_buserr();
 	printk(KERN_ALERT "Bus error, epc == %08lx, ra == %08lx\n",
 	       regs->cp0_epc, regs->regs[31]);
 	die_if_kernel("Oops", regs);
@@ -52,24 +80,10 @@
 int be_ip22_handler(struct pt_regs *regs, int is_fixup)
 {
 	save_and_clear_buserr();
-	if (nofault) {
-		nofault = 0;
-		compute_return_epc(regs);
-		return MIPS_BE_DISCARD;
-	}
-	return MIPS_BE_FIXUP;
-}
-
-int ip22_baddr(unsigned int *val, unsigned long addr)
-{
-	nofault = 1;
-	*val = *(volatile unsigned int *) addr;
-	__asm__ __volatile__("nop;nop;nop;nop");
-	if (nofault) {
-		nofault = 0;
-		return 0;
-	}
-	return -EFAULT;
+	if (is_fixup)
+		return MIPS_BE_FIXUP;
+	print_buserr();
+	return MIPS_BE_FATAL;
 }
 
 void __init bus_error_init(void)
--- linux/arch/mips/sgi-ip22/ip22-gio.c.orig	Thu Aug  1 23:26:23 2002
+++ linux/arch/mips/sgi-ip22/ip22-gio.c	Sun Aug  4 23:43:35 2002
@@ -11,6 +11,7 @@
 #include <linux/proc_fs.h>
 
 #include <asm/addrspace.h>
+#include <asm/paccess.h>
 #include <asm/sgi/sgimc.h>
 #include <asm/sgi/sgigio.h>
 
@@ -118,8 +119,6 @@
 #define GIO_ROM_PRESENT		0x20000
 #define GIO_VENDOR_CODE(x)	((x >> 18) & 0x3fff)
 
-extern int ip22_baddr(unsigned int *val, unsigned long addr);
-
 /** 
  * sgigio_init - scan the GIO space and figure out what hardware is actually
  * present.
@@ -128,9 +127,10 @@
 {
 	unsigned int i, id, found = 0;
 
-	printk("GIO: Scanning for GIO cards...\n");
+	printk("GIO: Probing bus...\n");
 	for (i = 0; i < GIO_NUM_SLOTS; i++) {
-		if (ip22_baddr(&id, KSEG1ADDR(gio_slot[i].base_addr)))
+		if (get_dbe(id, (volatile unsigned int *) 
+				 KSEG1ADDR(gio_slot[i].base_addr)))
 			continue;
 
 		found = 1;
--- linux/include/asm-mips/sgi/sgimc.h.orig	Sun Aug  4 22:16:03 2002
+++ linux/include/asm-mips/sgi/sgimc.h	Sun Aug  4 22:34:43 2002
@@ -128,11 +128,29 @@
 	volatile u32 cerr;         /* Error address reg for CPU */
 	u32 _unused22;
 	volatile u32 cstat;        /* Status reg for CPU */
+#define	SGIMC_CSTAT_RD		0x00000100	/* read parity error */
+#define	SGIMC_CSTAT_PAR		0x00000200	/* CPU parity error */
+#define	SGIMC_CSTAT_ADDR	0x00000400	/* memory bus error bad addr */
+#define	SGIMC_CSTAT_SYSAD_PAR	0x00000800	/* sysad parity error */
+#define	SGIMC_CSTAT_SYSCMD_PAR	0x00001000	/* syscmd parity error */
+#define	SGIMC_CSTAT_BAD_DATA	0x00002000	/* bad data identifier */
+#define	SGIMC_CSTAT_PAR_MASK	0x00001f00	/* parity error mask */
+#define	SGIMC_CSTAT_RD_PAR	(SGIMC_CSTAT_RD | SGIMC_CSTAT_PAR)
 	u32 _unused23;
 	volatile u32 gerr;         /* Error address reg for GIO */
 	u32 _unused24;
 	volatile u32 gstat;        /* Status reg for GIO */
-
+#define	SGIMC_GSTAT_RD		0x00000100	/* read parity error */
+#define	SGIMC_GSTAT_WR		0x00000200	/* write parity error */
+#define	SGIMC_GSTAT_TIME	0x00000400	/* GIO bus timed out */
+#define	SGIMC_GSTAT_PROM	0x00000800	/* write to PROM when PROM_EN
+						   not set */
+#define	SGIMC_GSTAT_ADDR	0x00001000	/* parity error on addr
+						   cycle */
+#define	SGIMC_GSTAT_BC		0x00002000	/* parity error on byte count
+						   cycle */
+#define SGIMC_GSTAT_PIO_RD	0x00004000	/* read data parity on pio */
+#define SGIMC_GSTAT_PIO_WR	0x00008000	/* write data parity on pio */
 	/* Special hard bus locking registers. */
 	u32 _unused25;
 	volatile unsigned char syssembit;    /* Uni-bit system semaphore */
@@ -146,13 +164,13 @@
 	/* GIO dma control registers. */
 	unsigned char _unused30[3];
 	u32 _unused31[14];
-	volatile u32 gio_dma_trans;/* DMA mask to translation GIO addrs */
+	volatile u32 gio_dma_trans;  /* DMA mask to translation GIO addrs */
 	u32 _unused32;
-	volatile u32 gio_dma_sbits;/* DMA GIO addr substitution bits */
+	volatile u32 gio_dma_sbits;  /* DMA GIO addr substitution bits */
 	u32 _unused33;
 	volatile u32 dma_intr_cause; /* DMA IRQ cause indicator bits */
 	u32 _unused34;
-	volatile u32 dma_ctrl;     /* Main DMA control reg */
+	volatile u32 dma_ctrl;       /* Main DMA control reg */
 
 	/* DMA TLB entry 0 */
 	u32 _unused35;
@@ -181,29 +199,29 @@
 
 /* MC misc control registers live at physical 0x1fa00000. */
 extern struct sgimc_misc_ctrl *mcmisc_regs;
-extern u32 *rpsscounter;          /* Chirps at 100ns */
+extern u32 *rpsscounter;           /* Chirps at 100ns */
 
 struct sgimc_dma_ctrl {
 	u32 _unused1;
-	volatile u32 maddronly;   /* Address DMA goes at */
+	volatile u32 maddronly;    /* Address DMA goes at */
 	u32 _unused2;
 	volatile u32 maddrpdeflts; /* Same as above, plus set defaults */
 	u32 _unused3;
-	volatile u32 dmasz;       /* DMA count */
+	volatile u32 dmasz;        /* DMA count */
 	u32 _unused4;
-	volatile u32 ssize;       /* DMA stride size */
+	volatile u32 ssize;        /* DMA stride size */
 	u32 _unused5;
-	volatile u32 gmaddronly;  /* Set GIO DMA but do not start trans */
+	volatile u32 gmaddronly;   /* Set GIO DMA but do not start trans */
 	u32 _unused6;
-	volatile u32 dmaddnpgo;   /* Set GIO DMA addr + start transfer */
+	volatile u32 dmaddnpgo;    /* Set GIO DMA addr + start transfer */
 	u32 _unused7;
-	volatile u32 dmamode;     /* DMA mode config bit settings */
+	volatile u32 dmamode;      /* DMA mode config bit settings */
 	u32 _unused8;
 	volatile u32 dmaccount;    /* Zoom and byte count for DMA */
 	u32 _unused9;
-	volatile u32 dmastart;    /* Pedal to the metal. */
+	volatile u32 dmastart;     /* Pedal to the metal. */
 	u32 _unused10;
-	volatile u32 dmarunning;  /* DMA op is in progress */
+	volatile u32 dmarunning;   /* DMA op is in progress */
 	u32 _unused11;
 
 	/* Set dma addr, defaults, and kick it */
--- linux/include/asm-mips64/sgi/sgimc.h.orig	Sun Aug  4 22:40:27 2002
+++ linux/include/asm-mips64/sgi/sgimc.h	Sun Aug  4 22:40:40 2002
@@ -128,11 +128,29 @@
 	volatile u32 cerr;         /* Error address reg for CPU */
 	u32 _unused22;
 	volatile u32 cstat;        /* Status reg for CPU */
+#define	SGIMC_CSTAT_RD		0x00000100	/* read parity error */
+#define	SGIMC_CSTAT_PAR		0x00000200	/* CPU parity error */
+#define	SGIMC_CSTAT_ADDR	0x00000400	/* memory bus error bad addr */
+#define	SGIMC_CSTAT_SYSAD_PAR	0x00000800	/* sysad parity error */
+#define	SGIMC_CSTAT_SYSCMD_PAR	0x00001000	/* syscmd parity error */
+#define	SGIMC_CSTAT_BAD_DATA	0x00002000	/* bad data identifier */
+#define	SGIMC_CSTAT_PAR_MASK	0x00001f00	/* parity error mask */
+#define	SGIMC_CSTAT_RD_PAR	(SGIMC_CSTAT_RD | SGIMC_CSTAT_PAR)
 	u32 _unused23;
 	volatile u32 gerr;         /* Error address reg for GIO */
 	u32 _unused24;
 	volatile u32 gstat;        /* Status reg for GIO */
-
+#define	SGIMC_GSTAT_RD		0x00000100	/* read parity error */
+#define	SGIMC_GSTAT_WR		0x00000200	/* write parity error */
+#define	SGIMC_GSTAT_TIME	0x00000400	/* GIO bus timed out */
+#define	SGIMC_GSTAT_PROM	0x00000800	/* write to PROM when PROM_EN
+						   not set */
+#define	SGIMC_GSTAT_ADDR	0x00001000	/* parity error on addr
+						   cycle */
+#define	SGIMC_GSTAT_BC		0x00002000	/* parity error on byte count
+						   cycle */
+#define SGIMC_GSTAT_PIO_RD	0x00004000	/* read data parity on pio */
+#define SGIMC_GSTAT_PIO_WR	0x00008000	/* write data parity on pio */
 	/* Special hard bus locking registers. */
 	u32 _unused25;
 	volatile unsigned char syssembit;    /* Uni-bit system semaphore */
@@ -146,13 +164,13 @@
 	/* GIO dma control registers. */
 	unsigned char _unused30[3];
 	u32 _unused31[14];
-	volatile u32 gio_dma_trans;/* DMA mask to translation GIO addrs */
+	volatile u32 gio_dma_trans;  /* DMA mask to translation GIO addrs */
 	u32 _unused32;
-	volatile u32 gio_dma_sbits;/* DMA GIO addr substitution bits */
+	volatile u32 gio_dma_sbits;  /* DMA GIO addr substitution bits */
 	u32 _unused33;
 	volatile u32 dma_intr_cause; /* DMA IRQ cause indicator bits */
 	u32 _unused34;
-	volatile u32 dma_ctrl;     /* Main DMA control reg */
+	volatile u32 dma_ctrl;       /* Main DMA control reg */
 
 	/* DMA TLB entry 0 */
 	u32 _unused35;
@@ -181,29 +199,29 @@
 
 /* MC misc control registers live at physical 0x1fa00000. */
 extern struct sgimc_misc_ctrl *mcmisc_regs;
-extern u32 *rpsscounter;          /* Chirps at 100ns */
+extern u32 *rpsscounter;           /* Chirps at 100ns */
 
 struct sgimc_dma_ctrl {
 	u32 _unused1;
-	volatile u32 maddronly;   /* Address DMA goes at */
+	volatile u32 maddronly;    /* Address DMA goes at */
 	u32 _unused2;
 	volatile u32 maddrpdeflts; /* Same as above, plus set defaults */
 	u32 _unused3;
-	volatile u32 dmasz;       /* DMA count */
+	volatile u32 dmasz;        /* DMA count */
 	u32 _unused4;
-	volatile u32 ssize;       /* DMA stride size */
+	volatile u32 ssize;        /* DMA stride size */
 	u32 _unused5;
-	volatile u32 gmaddronly;  /* Set GIO DMA but do not start trans */
+	volatile u32 gmaddronly;   /* Set GIO DMA but do not start trans */
 	u32 _unused6;
-	volatile u32 dmaddnpgo;   /* Set GIO DMA addr + start transfer */
+	volatile u32 dmaddnpgo;    /* Set GIO DMA addr + start transfer */
 	u32 _unused7;
-	volatile u32 dmamode;     /* DMA mode config bit settings */
+	volatile u32 dmamode;      /* DMA mode config bit settings */
 	u32 _unused8;
-	volatile u32 dmacount;    /* Zoom and byte count for DMA */
+	volatile u32 dmaccount;    /* Zoom and byte count for DMA */
 	u32 _unused9;
-	volatile u32 dmastart;    /* Pedal to the metal. */
+	volatile u32 dmastart;     /* Pedal to the metal. */
 	u32 _unused10;
-	volatile u32 dmarunning;  /* DMA op is in progress */
+	volatile u32 dmarunning;   /* DMA op is in progress */
 	u32 _unused11;
 
 	/* Set dma addr, defaults, and kick it */

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [patch] GIO bus support
  2002-06-27 12:21               ` [patch] GIO bus support Maciej W. Rozycki
  2002-08-04 22:03                 ` Ladislav Michl
@ 2002-09-28 19:55                 ` Ladislav Michl
  1 sibling, 0 replies; 22+ messages in thread
From: Ladislav Michl @ 2002-09-28 19:55 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: Guido Guenther, linux-mips

On Thu, Jun 27, 2002 at 02:21:30PM +0200, Maciej W. Rozycki wrote:
> On Wed, 26 Jun 2002, Ladislav Michl wrote:
> 
> > +int be_ip22_handler(struct pt_regs *regs, int is_fixup)
> > +{
> > +	save_and_clear_buserr();
> > +	if (nofault) {
> > +		nofault = 0;
> > +		compute_return_epc(regs);
> > +		return MIPS_BE_DISCARD;
> > +	}
> > +	return MIPS_BE_FIXUP;
> > +}
> 
>  I wouldn't use nofault -- it leads to reentrancy problems and I don't
> think you really need it.  You probably need to code it like this:
> 
> {
> 	save_and_clear_buserr();
> 
> 	return is_fixup ? MIPS_BE_FIXUP : MIPS_BE_FATAL;
> }
> 
> unless:
> 
> 1. There is a condition when for is_fixup true you should ignore the fixup
> anyway (e.g. what the bus error logic reports is irrelevant to fixups). 
> You should choose between MIPS_BE_FATAL and MIPS_BE_DISCARD then. 
> 
> 2. There is a condition when for is_fixup false, an error is not fatal and
> execution should get restarted.  You should return MIPS_BE_DISCARD then.

There are no such conditions (or I'm missing something). I wrote it as
you suggested:

int be_ip22_handler(struct pt_regs *regs, int is_fixup)
{
  DBG("BE exception (%s)\n", is_fixup ? "fixup" : "no fixup");
  save_and_clear_buserr();
  if (is_fixup)
    return MIPS_BE_FIXUP;
  print_buserr();
  return MIPS_BE_FATAL;
}

try to read status register

  addr = KSEG1ADDR(gio_slot_base_addr);
  DBG("get_dbe\n");
  if (!get_dbe(id, addr)) {
    ... ok
  }							

> > +int ip22_baddr(unsigned int *val, unsigned long addr)
> > +{
> > +	nofault = 1;
> > +	*val = *(volatile unsigned int *) addr;
> > +	__asm__ __volatile__("nop;nop;nop;nop");
> > +	if (nofault) {
> > +		nofault = 0;
> > +		return 0;
> > +	}
> > +	return -EFAULT;
> > +}
> 
>  Why not simply:
> 
> {
> 	int err;
> 
> 	err = get_dbe(*val, (volatile unsigned int *) addr);
> 
> 	return err ? -EFAULT : 0;
> }
> 
> It was designed exactly for this purpose.  You may consider using "u32" 
> instead of "unsigned int" for hardware accesses to assure the type will
> always be 32-bit.

This way gives following result:

get_dbe
BE exception (no fixup)

Dump of MC registers shows that timeout occurs when accessing nonexistant
memory. Of course it is posible return MIPS_BE_DISCARD than (and
regs->cp0_epc += 4), but how to force get_dbe fail then? Not mentioning
that in such case is better to avoid use of get_dbe... Suggestions are
welcome as always.

Thanks a lot,
	Ladis

^ permalink raw reply	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2002-09-28 20:07 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2002-06-17 11:33 DBE/IBE handling incompatibility Ladislav Michl
2002-06-19 16:47 ` Maciej W. Rozycki
2002-06-25  0:36   ` Ladislav Michl
2002-06-25 11:55     ` Maciej W. Rozycki
2002-06-26 11:51       ` [patch] linux: DBE/IBE handling rewrite Maciej W. Rozycki
2002-06-26 12:05         ` Ralf Baechle
2002-06-26 13:07           ` Maciej W. Rozycki
2002-06-26 17:21             ` Jun Sun
2002-06-27 12:00               ` Maciej W. Rozycki
2002-06-27 17:12                 ` Jun Sun
2002-06-27 18:29                   ` Maciej W. Rozycki
2002-06-27 19:08                     ` Jun Sun
2002-06-27 20:00                       ` Maciej W. Rozycki
2002-06-26 20:59             ` [patch] GIO bus support Ladislav Michl
2002-06-26 23:46               ` Ralf Baechle
2002-06-27 10:14                 ` FIR problem jeff
2002-06-27 10:14                   ` jeff
2002-06-27 12:21               ` [patch] GIO bus support Maciej W. Rozycki
2002-08-04 22:03                 ` Ladislav Michl
2002-09-28 19:55                 ` Ladislav Michl
2002-06-26 17:17         ` [patch] linux: DBE/IBE handling rewrite Jun Sun
2002-06-27 11:51           ` Maciej W. Rozycki

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.