diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2009-05-28 18:03:56 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2009-05-28 18:03:56 +0000 |
commit | f9ad4e9f53ef46de80f9a4cd65ea1704aedd4b9d (patch) | |
tree | de499372b8f04f2bd0250aa1bb46d2e5de8cd8df /sys | |
parent | ad2921a3a87c3bbfb5123fcc871494b1e9f31c5f (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.c | 40 | ||||
-rw-r--r-- | sys/arch/sgi/sgi/machdep.c | 38 |
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; |