summaryrefslogtreecommitdiffstats
path: root/arch/mips/sgi
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/sgi')
-rw-r--r--arch/mips/sgi/kernel/indy_int.c64
-rw-r--r--arch/mips/sgi/kernel/setup.c53
2 files changed, 80 insertions, 37 deletions
diff --git a/arch/mips/sgi/kernel/indy_int.c b/arch/mips/sgi/kernel/indy_int.c
index 01a8c91a3..b29ff58c9 100644
--- a/arch/mips/sgi/kernel/indy_int.c
+++ b/arch/mips/sgi/kernel/indy_int.c
@@ -1,11 +1,13 @@
-/* $Id: indy_int.c,v 1.11 1999/01/04 16:03:56 ralf Exp $
+/* $Id: indy_int.c,v 1.12 1999/05/07 22:34:32 ulfc Exp $
*
* indy_int.c: Routines for generic manipulation of the INT[23] ASIC
* found on INDY workstations..
*
* Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
* Copyright (C) 1997, 1998 Ralf Baechle (ralf@gnu.org)
- * Copyright (C) 1999 Andrew R. Baker (andrewb@uab.edu) - Indigo2 changes
+ * Copyright (C) 1999 Andrew R. Baker (andrewb@uab.edu)
+ * - Indigo2 changes
+ * - Interrupt handling fixes
*/
#include <linux/config.h>
#include <linux/init.h>
@@ -36,6 +38,7 @@
#include <asm/sgihpc.h>
#include <asm/sgint23.h>
#include <asm/sgialib.h>
+#include <asm/gdb-stub.h>
/* #define DEBUG_SGINT */
@@ -52,10 +55,6 @@ static char lc3msk_to_irqnr[256];
extern asmlinkage void indyIRQ(void);
-#ifdef CONFIG_REMOTE_DEBUG
-extern void rs_kgdb_hook(int);
-#endif
-
unsigned int local_bh_count[NR_CPUS];
unsigned int local_irq_count[NR_CPUS];
unsigned long spurious_count = 0;
@@ -449,10 +448,23 @@ void indy_local0_irqdispatch(struct pt_regs *regs)
action = local_irq_action[irq];
}
+ /* if irq == 0, then the interrupt has already been cleared */
+ if ( irq == 0 ) { goto end; }
+ /* if action == NULL, then we do have a handler for the irq */
+ if ( action == NULL ) { goto no_handler; }
+
hardirq_enter(cpu);
kstat.irqs[0][irq + 16]++;
action->handler(irq, action->dev_id, regs);
hardirq_exit(cpu);
+ goto end;
+
+no_handler:
+ printk("No handler for local0 irq: %i\n", irq);
+
+end:
+ return;
+
}
void indy_local1_irqdispatch(struct pt_regs *regs)
@@ -473,10 +485,23 @@ void indy_local1_irqdispatch(struct pt_regs *regs)
irq = lc1msk_to_irqnr[mask];
action = local_irq_action[irq];
}
+ /* if irq == 0, then the interrupt has already been cleared */
+ /* not sure if it is needed here, but it is needed for local0 */
+ if ( irq == 0 ) { goto end; }
+ /* if action == NULL, then we do have a handler for the irq */
+ if ( action == NULL ) { goto no_handler; }
+
hardirq_enter(cpu);
kstat.irqs[0][irq + 24]++;
action->handler(irq, action->dev_id, regs);
hardirq_exit(cpu);
+ goto end;
+
+no_handler:
+ printk("No handler for local1 irq: %i\n", irq);
+
+end:
+ return;
}
void indy_buserror_irq(struct pt_regs *regs)
@@ -507,9 +532,6 @@ int probe_irq_off (unsigned long irqs)
__initfunc(void sgint_init(void))
{
int i;
-#ifdef CONFIG_REMOTE_DEBUG
- char *ctype;
-#endif
sgi_i2regs = (struct sgi_int2_regs *) (KSEG1 + SGI_INT2_BASE);
sgi_i3regs = (struct sgi_int3_regs *) (KSEG1 + SGI_INT3_BASE);
@@ -583,28 +605,4 @@ __initfunc(void sgint_init(void))
/* Now safe to set the exception vector. */
set_except_vector(0, indyIRQ);
-
-#ifdef CONFIG_REMOTE_DEBUG
- ctype = prom_getcmdline();
- for(i = 0; i < strlen(ctype); i++) {
- if(ctype[i]=='k' && ctype[i+1]=='g' &&
- ctype[i+2]=='d' && ctype[i+3]=='b' &&
- ctype[i+4]=='=' && ctype[i+5]=='t' &&
- ctype[i+6]=='t' && ctype[i+7]=='y' &&
- ctype[i+8]=='d' &&
- (ctype[i+9] == '1' || ctype[i+9] == '2')) {
- printk("KGDB: Using serial line /dev/ttyd%d for "
- "session\n", (ctype[i+9] - '0'));
- if(ctype[i+9]=='1')
- rs_kgdb_hook(1);
- else if(ctype[i+9]=='2')
- rs_kgdb_hook(0);
- else {
- printk("KGDB: whoops bogon tty line "
- "requested, disabling session\n");
- }
-
- }
- }
-#endif
}
diff --git a/arch/mips/sgi/kernel/setup.c b/arch/mips/sgi/kernel/setup.c
index 4ee8c01f7..bc64424e2 100644
--- a/arch/mips/sgi/kernel/setup.c
+++ b/arch/mips/sgi/kernel/setup.c
@@ -1,4 +1,4 @@
-/* $Id: setup.c,v 1.22 1999/04/10 12:21:30 ulfc Exp $
+/* $Id: setup.c,v 1.23 1999/05/07 18:00:17 ulfc Exp $
*
* setup.c: SGI specific setup, including init of the feature struct.
*
@@ -26,11 +26,23 @@
#include <asm/sgimc.h>
#include <asm/sgihpc.h>
#include <asm/sgint23.h>
+#include <asm/gdb-stub.h>
+
+#ifdef CONFIG_REMOTE_DEBUG
+extern void rs_kgdb_hook(int);
+extern void breakpoint(void);
+#endif
+
+#if defined(CONFIG_SERIAL_CONSOLE) || defined(CONFIG_PROM_CONSOLE)
+extern void console_setup(char *, int *);
+#endif
extern struct rtc_ops indy_rtc_ops;
void indy_reboot_setup(void);
void sgi_volume_set(unsigned char);
+static int remote_debug = 0;
+
#define sgi_kh ((struct hpc_keyb *) (KSEG1 + 0x1fbd9800 + 64))
#define KBD_STAT_IBF 0x02 /* Keyboard input buffer full */
@@ -109,6 +121,12 @@ struct kbd_ops sgi_kbd_ops = {
__initfunc(static void sgi_irq_setup(void))
{
sgint_init();
+
+#ifdef CONFIG_REMOTE_DEBUG
+ if (remote_debug)
+ set_debug_traps();
+ breakpoint(); /* you may move this line to whereever you want :-) */
+#endif
}
__initfunc(void sgi_setup(void))
@@ -116,6 +134,10 @@ __initfunc(void sgi_setup(void))
#ifdef CONFIG_SERIAL_CONSOLE
char *ctype;
#endif
+#ifdef CONFIG_REMOTE_DEBUG
+ char *kgdb_ttyd;
+#endif
+
irq_setup = sgi_irq_setup;
@@ -139,13 +161,35 @@ __initfunc(void sgi_setup(void))
ctype = prom_getenv("console");
if(*ctype == 'd') {
if(*(ctype+1)=='2')
- console_setup ("ttyS1");
+ console_setup ("ttyS1", NULL);
else
- console_setup ("ttyS0");
+ console_setup ("ttyS0", NULL);
}
#endif
+
+#ifdef CONFIG_REMOTE_DEBUG
+ kgdb_ttyd = prom_getcmdline();
+ if ((kgdb_ttyd = strstr(kgdb_ttyd, "kgdb=ttyd")) != NULL) {
+ int line;
+ kgdb_ttyd += strlen("kgdb=ttyd");
+ if (*kgdb_ttyd != '1' && *kgdb_ttyd != '2')
+ printk("KGDB: Uknown serial line /dev/ttyd%c, "
+ "falling back to /dev/ttyd1\n", *kgdb_ttyd);
+ line = *kgdb_ttyd == '2' ? 0 : 1;
+ printk("KGDB: Using serial line /dev/ttyd%d for session\n",
+ line ? 1 : 2);
+ rs_kgdb_hook(line);
+
+ prom_printf("KGDB: Using serial line /dev/ttyd%d for session, "
+ "please connect your debugger\n", line ? 1 : 2);
+
+ remote_debug = 1;
+ /* Breakpoints and stuff are in sgi_irq_setup() */
+ }
+#endif
+
#ifdef CONFIG_SGI_PROM_CONSOLE
- console_setup("ttyS0");
+ console_setup("ttyS0", NULL);
#endif
sgi_volume_set(simple_strtoul(prom_getenv("volume"), NULL, 10));
@@ -157,6 +201,7 @@ __initfunc(void sgi_setup(void))
conswitchp = &dummy_con;
#endif
#endif
+
rtc_ops = &indy_rtc_ops;
kbd_ops = &sgi_kbd_ops;
#ifdef CONFIG_PSMOUSE