diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2009-05-28 18:02:44 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2009-05-28 18:02:44 +0000 |
commit | ad2921a3a87c3bbfb5123fcc871494b1e9f31c5f (patch) | |
tree | bc578d16c25b84b39000ed80ba34115410f4b767 /sys/arch | |
parent | b9f233f48941ef2bbf4d31cf4e41b191a8b07a2d (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.h | 17 | ||||
-rw-r--r-- | sys/arch/sgi/sgi/ip27.h | 31 | ||||
-rw-r--r-- | sys/arch/sgi/sgi/ip27_machdep.c | 73 | ||||
-rw-r--r-- | sys/arch/sgi/sgi/machdep.c | 13 | ||||
-rw-r--r-- | sys/arch/sgi/xbow/hub.h | 22 |
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 |