From 5f5cd9e4f2416485720aae4009f2bb7bd44d277a Mon Sep 17 00:00:00 2001 From: simokawa Date: Fri, 8 Jun 2007 04:33:25 +0000 Subject: Add the address of IDT in the configuration ROM. (i386/amd64 only) A change to dconschat(8) will follow so that it can bomb this address over FireWire to reset a wedged system. Though this method is just a hack and far from perfection, it should be useful if you don't want to go machine room just to reset or to power-cycle a machine without remote-managed power supply. And much better than doing: # fwcontrol -m target-eui64 # dd if=/dev/zero of=/dev/fwmem0.2 bs=1m --- sys/dev/dcons/dcons.h | 3 +++ sys/dev/dcons/dcons_crom.c | 24 ++++++++++++++++++++++++ 2 files changed, 27 insertions(+) (limited to 'sys') diff --git a/sys/dev/dcons/dcons.h b/sys/dev/dcons/dcons.h index daf9cb4..49ef869 100644 --- a/sys/dev/dcons/dcons.h +++ b/sys/dev/dcons/dcons.h @@ -65,6 +65,8 @@ struct dcons_buf { #define DCONS_CSR_VAL_VER 0x64636f /* "dco" */ #define DCONS_CSR_KEY_HI 0x3a #define DCONS_CSR_KEY_LO 0x3b +#define DCONS_CSR_KEY_RESET_HI 0x3c +#define DCONS_CSR_KEY_RESET_LO 0x3d #define DCONS_HEADER_SIZE sizeof(struct dcons_buf) #define DCONS_MAKE_PTR(x) htonl(((x)->gen << DCONS_GEN_SHIFT) | (x)->pos) @@ -88,6 +90,7 @@ struct dcons_ch { #define STATE0 0 #define STATE1 1 #define STATE2 2 +#define STATE3 3 #if defined(_KERNEL) || defined(_BOOT) struct dcons_softc { diff --git a/sys/dev/dcons/dcons_crom.c b/sys/dev/dcons/dcons_crom.c index 290c80a..290bb1e 100644 --- a/sys/dev/dcons/dcons_crom.c +++ b/sys/dev/dcons/dcons_crom.c @@ -62,6 +62,14 @@ #include +#define EXPOSE_IDT_ADDR 1 + +#if (defined(__i386__) || defined(__amd64__)) && defined(EXPOSE_IDT_ADDR) +#include +#include +#include +#include /* for idt */ +#endif static bus_addr_t dcons_paddr; #if __FreeBSD_version >= 500000 @@ -108,6 +116,19 @@ dcons_crom_probe(device_t dev) } #ifndef NEED_NEW_DRIVER +#if (defined(__i386__) || defined(__amd64__)) && defined(EXPOSE_IDT_ADDR) +static void +dcons_crom_expose_idt(struct dcons_crom_softc *sc) +{ + static off_t idt_paddr; + + /* XXX */ + idt_paddr = (char *)idt - (char *)KERNBASE; + + crom_add_entry(&sc->unit, DCONS_CSR_KEY_RESET_HI, ADDR_HI(idt_paddr)); + crom_add_entry(&sc->unit, DCONS_CSR_KEY_RESET_LO, ADDR_LO(idt_paddr)); +} +#endif static void dcons_crom_post_busreset(void *arg) { @@ -128,6 +149,9 @@ dcons_crom_post_busreset(void *arg) crom_add_simple_text(src, &sc->unit, &sc->ver, "dcons"); crom_add_entry(&sc->unit, DCONS_CSR_KEY_HI, ADDR_HI(dcons_paddr)); crom_add_entry(&sc->unit, DCONS_CSR_KEY_LO, ADDR_LO(dcons_paddr)); +#if (defined(__i386__) || defined(__amd64__)) && defined(EXPOSE_IDT_ADDR) + dcons_crom_expose_idt(sc); +#endif } #endif -- cgit v1.1