==== //depot/user/simokawa/firewire/sys/dev/dcons/dcons_crom.c#10 - /home/p4/firewire/sys/dev/dcons/dcons_crom.c ==== @@ -62,6 +62,14 @@ #include +#define EXPOSE_IDT 1 + +#if (defined(__i386__) || defined(__amd64__)) && defined(EXPOSE_IDT) +#include +#include +#include +#include /* for idt */ +#endif static bus_addr_t dcons_paddr; #if __FreeBSD_version >= 500000 @@ -107,7 +115,23 @@ } #ifndef NEED_NEW_DRIVER +#define EXPOSE_IDT 1 +#if (defined(__i386__) || defined(__amd64__)) && defined(EXPOSE_IDT) static void +dcons_crom_expose_idt(struct dcons_crom_softc *sc) +{ + static off_t idt_paddr; + + /* XXX */ + idt_paddr = (char *)idt - (char *)KERNBASE; + +#define DCONS_CSR_IDT_HI 0x3c +#define DCONS_CSR_IDT_LO 0x3d + crom_add_entry(&sc->unit, DCONS_CSR_IDT_HI, ADDR_HI(idt_paddr)); + crom_add_entry(&sc->unit, DCONS_CSR_IDT_LO, ADDR_LO(idt_paddr)); +} +#endif +static void dcons_crom_post_busreset(void *arg) { struct dcons_crom_softc *sc; @@ -127,6 +151,9 @@ 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) + dcons_crom_expose_idt(sc); +#endif } #endif ==== //depot/user/simokawa/firewire/usr.sbin/dconschat/dconschat.c#8 - /home/p4/firewire/usr.sbin/dconschat/dconschat.c ==== @@ -87,6 +87,7 @@ kvm_t *kd; int kq; off_t paddr; + off_t idt; #define F_READY (1 << 1) #define F_RD_ONLY (1 << 2) #define F_ALT_BREAK (1 << 3) @@ -145,6 +146,18 @@ } static void +dconschat_reset_target(struct dcons_state *dc) +{ + char zeros[PAGE_SIZE]; + if (dc->idt == 0) + return; + + bzero(&zeros[0], PAGE_SIZE); + printf("\n[dconschat reset target(idt=0x%zx)...]\r\n", dc->idt); + dwrite(dc, (void *)zeros, PAGE_SIZE, dc->idt); +} + +static void dconschat_cleanup(int sig) { struct dcons_state *dc; @@ -154,9 +167,9 @@ tcsetattr(STDIN_FILENO, TCSADRAIN, &dc->tsave); if (sig > 0) - printf("\n[dconschat exiting with signal %d ...]\n", sig); + printf("\n[dconschat exiting with signal %d ...]\r\n", sig); else - printf("\n[dconschat exiting...]\n"); + printf("\n[dconschat exiting...]\r\n"); exit(0); } @@ -166,7 +179,7 @@ { off_t addr; int i, state = 0; - u_int32_t buf, hi = 0, lo = 0; + u_int32_t buf, hi = 0, lo = 0, idt_hi = 0, idt_lo = 0; struct csrreg *reg; reg = (struct csrreg *)&buf; @@ -193,21 +206,35 @@ state = 2; break; case 2: - if (reg->key == DCONS_CSR_KEY_HI) + switch (reg->key) { + case DCONS_CSR_KEY_HI: hi = reg->val; - else if (reg->key == DCONS_CSR_KEY_LO) { + break; + case DCONS_CSR_KEY_LO: lo = reg->val; + break; + case 0x3c: + idt_hi = reg->val; + break; + case 0x3d: + idt_lo = reg->val; goto out; + break; + case 0x81: + break; + default: + state = 0; } break; } } - /* not found */ - return (-1); out: if (verbose) printf("addr: %06x %06x\n", hi, lo); dc->paddr = ((off_t)hi << 24) | lo; + dc->idt = ((off_t)idt_hi << 24) | idt_lo; + if (dc->paddr == 0) + return (-1); return (0); } #endif @@ -654,6 +681,8 @@ dc->escape_state = STATE0; if (*sp == '.') dconschat_cleanup(0); + else if (*sp == 'R') + dconschat_reset_target(dc); } if (*sp == KEY_CR) dc->escape_state = STATE1;