summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2009-05-28 18:03:56 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2009-05-28 18:03:56 +0000
commitf9ad4e9f53ef46de80f9a4cd65ea1704aedd4b9d (patch)
treede499372b8f04f2bd0250aa1bb46d2e5de8cd8df /sys
parentad2921a3a87c3bbfb5123fcc871494b1e9f31c5f (diff)
Poor man's reset code for IP27/IP35 where returning through ARCBios doesn't
work, even after restoring TLB and exception code.
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/sgi/sgi/ip27_machdep.c40
-rw-r--r--sys/arch/sgi/sgi/machdep.c38
2 files changed, 63 insertions, 15 deletions
diff --git a/sys/arch/sgi/sgi/ip27_machdep.c b/sys/arch/sgi/sgi/ip27_machdep.c
index 624d4aa935e..107e6fc8981 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.9 2009/05/28 18:02:43 miod Exp $ */
+/* $OpenBSD: ip27_machdep.c,v 1.10 2009/05/28 18:03:55 miod Exp $ */
/*
* Copyright (c) 2008, 2009 Miodrag Vallat.
@@ -45,10 +45,14 @@
#include <dev/ic/comvar.h>
+extern void (*md_halt)(int);
+
paddr_t ip27_widget_short(int16_t, u_int);
paddr_t ip27_widget_long(int16_t, u_int);
int ip27_widget_id(int16_t, u_int, uint32_t *);
+void ip27_halt(int);
+
static paddr_t io_base;
static int ip35 = 0;
@@ -76,6 +80,8 @@ ip27_setup()
xbow_widget_long = ip27_widget_long;
xbow_widget_id = ip27_widget_id;
+ md_halt = ip27_halt;
+
kl_init();
if (kl_n_mode != 0)
xbow_long_shift = 28;
@@ -196,6 +202,38 @@ ip27_widget_id(int16_t nasid, u_int widget, uint32_t *wid)
}
/*
+ * Reboot code
+ */
+
+void
+ip27_halt(int howto)
+{
+ /*
+ * Even if ARCBios TLB and exception vectors are restored,
+ * returning to ARCBios doesn't work.
+ *
+ * So, instead, send a reset through the network interface
+ * of the Hub space. Unfortunately there is no known way
+ * to tell the PROM which action we want it to take afterwards.
+ */
+
+ if (howto & RB_HALT) {
+ if (howto & RB_POWERDOWN)
+ return; /* caller will spin */
+ }
+
+ if (ip35) {
+ IP27_LHUB_S(HUB_NI_IP35 + HUB_NI_RESET_ENABLE, RESET_ENABLE);
+ IP27_LHUB_S(HUB_NI_IP35 + HUB_NI_RESET,
+ RESET_LOCAL | RESET_ACTION);
+ } else {
+ IP27_LHUB_S(HUB_NI_IP27 + HUB_NI_RESET_ENABLE, RESET_ENABLE);
+ IP27_LHUB_S(HUB_NI_IP27 + HUB_NI_RESET,
+ RESET_LOCAL | RESET_ACTION);
+ }
+}
+
+/*
* Local HUB interrupt handling routines
*/
diff --git a/sys/arch/sgi/sgi/machdep.c b/sys/arch/sgi/sgi/machdep.c
index a52edd3d379..db730e18e6d 100644
--- a/sys/arch/sgi/sgi/machdep.c
+++ b/sys/arch/sgi/sgi/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.69 2009/05/28 18:02:43 miod Exp $ */
+/* $OpenBSD: machdep.c,v 1.70 2009/05/28 18:03:55 miod Exp $ */
/*
* Copyright (c) 2003-2004 Opsycon AB (www.opsycon.se / www.opsycon.com)
@@ -137,8 +137,11 @@ caddr_t allocsys(caddr_t);
static void dobootopts(int, void *);
static int atoi(const char *, int, const char **);
+void arcbios_halt(int);
void build_trampoline(vaddr_t, vaddr_t);
+void (*md_halt)(int) = arcbios_halt;
+
/*
* Do all the stuff that locore normally does before calling main().
* Reset mapping and set up mapping to hardware and init "wired" reg.
@@ -951,26 +954,33 @@ haltsys:
doshutdownhooks();
if (howto & RB_HALT) {
- if (howto & RB_POWERDOWN) {
+ if (howto & RB_POWERDOWN)
printf("System Power Down.\n");
- delay(1000000);
- Bios_PowerDown();
- } else {
+ else
printf("System Halt.\n");
- delay(1000000);
- Bios_EnterInteractiveMode();
- }
- printf("Didn't want to die!!! Reset manually.\n");
- } else {
+ } else
printf("System restart.\n");
- delay(1000000);
- Bios_Reboot();
- printf("Restart failed!!! Reset manually.\n");
- }
+
+ delay(1000000);
+ md_halt(howto);
+
+ printf("Failed!!! Please reset manually.\n");
for (;;) ;
/*NOTREACHED*/
}
+void
+arcbios_halt(int howto)
+{
+ if (howto & RB_HALT) {
+ if (howto & RB_POWERDOWN)
+ Bios_PowerDown();
+ else
+ Bios_EnterInteractiveMode();
+ } else
+ Bios_Reboot();
+}
+
u_long dumpmag = 0x8fca0101; /* Magic number for savecore. */
int dumpsize = 0; /* Also for savecore. */
long dumplo = 0;