summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2009-05-28 18:02:44 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2009-05-28 18:02:44 +0000
commitad2921a3a87c3bbfb5123fcc871494b1e9f31c5f (patch)
treebc578d16c25b84b39000ed80ba34115410f4b767 /sys/arch
parentb9f233f48941ef2bbf4d31cf4e41b191a8b07a2d (diff)
Handle NMI interrupts on IP27/IP35, gives us a change to play with ddb,
and then restart system (NMI on these systems aren't intended to be recoverable).
Diffstat (limited to 'sys/arch')
-rw-r--r--sys/arch/sgi/include/mnode.h17
-rw-r--r--sys/arch/sgi/sgi/ip27.h31
-rw-r--r--sys/arch/sgi/sgi/ip27_machdep.c73
-rw-r--r--sys/arch/sgi/sgi/machdep.c13
-rw-r--r--sys/arch/sgi/xbow/hub.h22
5 files changed, 139 insertions, 17 deletions
diff --git a/sys/arch/sgi/include/mnode.h b/sys/arch/sgi/include/mnode.h
index d180632e968..5b832aa19e5 100644
--- a/sys/arch/sgi/include/mnode.h
+++ b/sys/arch/sgi/include/mnode.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: mnode.h,v 1.4 2009/05/27 19:00:15 miod Exp $ */
+/* $OpenBSD: mnode.h,v 1.5 2009/05/28 18:02:41 miod Exp $ */
/*
* Copyright (c) 2004 Opsycon AB (www.opsycon.se / www.opsycon.com)
@@ -345,6 +345,21 @@ typedef struct klttydev_s {
struct terminal_data *ttydev_cfg; /* driver fills up this */
} klttydev_t;
+/* KLNMI header addressed by IP27_KLNMI_HDR(node) */
+#define IP27_KLNMI_HDR(n) \
+ IP27_UNCAC_ADDR(kl_nmi_t *, n, IP27_KLD_NMI(n)->offset)
+
+#define NMI_MAGIC 0x0048414d4d455201 /* \x00HAMMER\x01 */
+
+typedef struct kl_nmi {
+ uint64_t magic; /* NMI_MAGIC */
+ uint64_t flags;
+ uint64_t cb; /* callback function */
+ uint64_t cb_complement; /* two's complement of above */
+ uint64_t cb_arg; /* callback arg */
+ uint64_t master; /* nonzero if master node */
+} kl_nmi_t;
+
/* H U B */
/* ===== */
diff --git a/sys/arch/sgi/sgi/ip27.h b/sys/arch/sgi/sgi/ip27.h
new file mode 100644
index 00000000000..73cecf6a167
--- /dev/null
+++ b/sys/arch/sgi/sgi/ip27.h
@@ -0,0 +1,31 @@
+/* $OpenBSD: ip27.h,v 1.1 2009/05/28 18:02:43 miod Exp $ */
+
+/*
+ * Copyright (c) 2009 Miodrag Vallat.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * Non-XBow related IP27 and IP35 definitions
+ */
+
+/* NMI register save areas */
+
+#define IP27_NMI_KREGS_BASE 0x11400
+#define IP27_NMI_KREGS_SIZE 0x200 /* per CPU */
+#define IP27_NMI_EFRAME_BASE 0x11800
+
+#define IP35_NMI_KREGS_BASE 0x9000
+#define IP35_NMI_KREGS_SIZE 0x400 /* per CPU */
+#define IP35_NMI_EFRAME_BASE 0xa000
diff --git a/sys/arch/sgi/sgi/ip27_machdep.c b/sys/arch/sgi/sgi/ip27_machdep.c
index e811e452115..624d4aa935e 100644
--- a/sys/arch/sgi/sgi/ip27_machdep.c
+++ b/sys/arch/sgi/sgi/ip27_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip27_machdep.c,v 1.8 2009/05/27 19:00:19 miod Exp $ */
+/* $OpenBSD: ip27_machdep.c,v 1.9 2009/05/28 18:02:43 miod Exp $ */
/*
* Copyright (c) 2008, 2009 Miodrag Vallat.
@@ -24,9 +24,11 @@
#include <sys/systm.h>
#include <sys/device.h>
#include <sys/malloc.h>
+#include <sys/reboot.h>
#include <sys/tty.h>
#include <mips64/arcbios.h>
+#include <mips64/archtype.h>
#include <machine/autoconf.h>
#include <machine/bus.h>
@@ -36,12 +38,11 @@
#include <uvm/uvm_extern.h>
+#include <sgi/sgi/ip27.h>
#include <sgi/xbow/hub.h>
#include <sgi/xbow/xbow.h>
#include <sgi/xbow/xbridgereg.h>
-#include <sgi/pci/iocreg.h>
-
#include <dev/ic/comvar.h>
paddr_t ip27_widget_short(int16_t, u_int);
@@ -49,6 +50,7 @@ paddr_t ip27_widget_long(int16_t, u_int);
int ip27_widget_id(int16_t, u_int, uint32_t *);
static paddr_t io_base;
+static int ip35 = 0;
int ip27_hub_intr_register(int, int, int *);
int ip27_hub_intr_establish(int (*)(void *), void *, int, int,
@@ -58,12 +60,18 @@ intrmask_t ip27_hub_intr_handler(intrmask_t, struct trap_frame *);
void ip27_hub_intr_makemasks(void);
void ip27_hub_do_pending_int(int);
+void ip27_nmi(void *);
+
void
ip27_setup()
{
+ kl_nmi_t *nmi;
+
uncached_base = PHYS_TO_XKPHYS_UNCACHED(0, SP_NC);
io_base = PHYS_TO_XKPHYS_UNCACHED(0, SP_IO);
+ ip35 = sys_config.system_type == SGI_O300;
+
xbow_widget_short = ip27_widget_short;
xbow_widget_long = ip27_widget_long;
xbow_widget_id = ip27_widget_id;
@@ -117,6 +125,21 @@ ip27_setup()
(void)IP27_LHUB_L(HUB_IR0);
(void)IP27_LHUB_L(HUB_IR1);
/* XXX do the other two cpus on IP35 */
+
+ /*
+ * Setup NMI handler.
+ */
+ nmi = IP27_KLNMI_HDR(0);
+ nmi->magic = NMI_MAGIC;
+ nmi->cb = (vaddr_t)ip27_nmi;
+ nmi->cb_complement = ~nmi->cb;
+ nmi->cb_arg = 0;
+
+ /*
+ * Set up Node 0's HUB.
+ */
+ IP27_LHUB_S(PI_REGION_PRESENT, 1);
+ IP27_LHUB_S(PI_CALIAS_SIZE, PI_CALIAS_SIZE_0);
}
/*
@@ -430,3 +453,47 @@ hw_setintrmask(intrmask_t m)
IP27_LHUB_S(HUB_CPU0_IMR0, ip27_hub_intrmask & ~((uint64_t)m));
(void)IP27_LHUB_L(HUB_IR0);
}
+
+void
+ip27_nmi(void *arg)
+{
+ vaddr_t regs_offs;
+ register_t *regs, epc;
+ struct trap_frame nmi_frame;
+ extern int kdb_trap(int, struct trap_frame *);
+
+ /*
+ * Build a ddb frame from the registers saved in the NMI KREGS
+ * area.
+ */
+
+ if (ip35)
+ regs_offs = IP35_NMI_KREGS_BASE; /* XXX assumes cpu0 */
+ else
+ regs_offs = IP27_NMI_KREGS_BASE; /* XXX assumes cpu0 */
+ regs = IP27_UNCAC_ADDR(register_t *, 0, regs_offs);
+
+ memset(&nmi_frame, 0xff, sizeof nmi_frame);
+
+ /* general registers */
+ memcpy(&nmi_frame.zero, regs, 32 * sizeof(register_t));
+ regs += 32;
+ nmi_frame.sr = *regs++; /* COP_0_STATUS_REG */
+ nmi_frame.cause = *regs++; /* COP_0_CAUSE_REG */
+ nmi_frame.pc = *regs++;
+ nmi_frame.badvaddr = *regs++; /* COP_0_BAD_VADDR */
+ epc = *regs++; /* COP_0_EXC_PC */
+ regs++; /* COP_0_CACHE_ERR */
+ regs++; /* NMI COP_0_STATUS_REG */
+
+ setsr(getsr() & ~SR_BOOT_EXC_VEC);
+#ifdef DDB
+ printf("NMI\n");
+ (void)kdb_trap(-1, &nmi_frame);
+#else
+ printf("NMI, PC = %p RA = %p SR = %08x EPC = %p\n",
+ nmi_frame.pc, nmi_frame.ra, nmi_frame.sr, epc);
+#endif
+ printf("Resetting system...\n");
+ boot(RB_USERREQ);
+}
diff --git a/sys/arch/sgi/sgi/machdep.c b/sys/arch/sgi/sgi/machdep.c
index 503f421585e..a52edd3d379 100644
--- a/sys/arch/sgi/sgi/machdep.c
+++ b/sys/arch/sgi/sgi/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.68 2009/05/25 17:10:40 miod Exp $ */
+/* $OpenBSD: machdep.c,v 1.69 2009/05/28 18:02:43 miod Exp $ */
/*
* Copyright (c) 2003-2004 Opsycon AB (www.opsycon.se / www.opsycon.com)
@@ -486,17 +486,6 @@ mips_init(int argc, void *argv, caddr_t boot_esym)
tlb_flush(sys_config.cpu[0].tlbsize);
tlb_set_wired(sys_config.cpu[0].tlbwired);
-#if defined(TGT_ORIGIN200) || defined(TGT_ORIGIN2000)
- /*
- * If an IP27 or IP35 system set up Node 0's HUB.
- */
- if (sys_config.system_type == SGI_O200 ||
- sys_config.system_type == SGI_O300) {
- IP27_LHUB_S(PI_REGION_PRESENT, 1);
- IP27_LHUB_S(PI_CALIAS_SIZE, PI_CALIAS_SIZE_0);
- }
-#endif
-
/*
* Get a console, very early but after initial mapping setup.
*/
diff --git a/sys/arch/sgi/xbow/hub.h b/sys/arch/sgi/xbow/hub.h
index 8a3df72fa12..6fdde4d341c 100644
--- a/sys/arch/sgi/xbow/hub.h
+++ b/sys/arch/sgi/xbow/hub.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: hub.h,v 1.1 2009/04/15 18:45:41 miod Exp $ */
+/* $OpenBSD: hub.h,v 1.2 2009/05/28 18:02:43 miod Exp $ */
/*
* Copyright (c) 2009 Miodrag Vallat.
@@ -24,6 +24,10 @@
* HUB space (very incomplete)
*/
+/*
+ * HUB PI
+ */
+
#define HUB_CPU_NUMBER 0x00000020
#define HUB_CPU0_PRESENT 0x00000040
@@ -40,3 +44,19 @@
#define HUB_CPU0_IMR1 0x000000b0
#define HUB_CPU1_IMR0 0x000000b8
#define HUB_CPU1_IMR1 0x000000c0
+
+
+/*
+ * HUB NI
+ */
+
+#define HUB_NI_IP27 0x00600000
+#define HUB_NI_IP35 0x00680000
+
+#define HUB_NI_STATUS 0x00000000
+#define HUB_NI_RESET 0x00000008
+#define RESET_ACTION 0x01
+#define RESET_PORT 0x02
+#define RESET_LOCAL 0x04
+#define HUB_NI_RESET_ENABLE 0x00000010
+#define RESET_ENABLE 0x01