Date: Mon, 25 Apr 2011 23:51:26 +0000 (UTC) From: Marcel Moolenaar <marcel@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r221043 - projects/altix/sys/ia64/sgisn Message-ID: <201104252351.p3PNpQHF097825@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: marcel Date: Mon Apr 25 23:51:26 2011 New Revision: 221043 URL: http://svn.freebsd.org/changeset/base/221043 Log: More WIP dumping: o In sgisn_pcib.c setup a timeout to monitor the value of the int. status register and print its value when it has changed. Print the values of the IRR registers to see if there's a discrepancy between the I/O controller and the CPU. o In sgisn_shub.c, intercept resource related methods and pass them up to nexus as if coming from the shub controller. This avoids panics and makes bus_set_resource() work for the console driver. It's kinda klugy, but has a good bang-for-the-buck ratio. o Implement sgisn_shub_write_ivar for SHUB_IVAR_EVENT and clear the event bits given by value. o In sgisn_console.c, implement the RX interrupt. This actually works. We can type the alternate break sequence and break into the kernel debugger. Yay! Modified: projects/altix/sys/ia64/sgisn/sgisn_console.c projects/altix/sys/ia64/sgisn/sgisn_pcib.c projects/altix/sys/ia64/sgisn/sgisn_shub.c projects/altix/sys/ia64/sgisn/sgisn_shub.h Modified: projects/altix/sys/ia64/sgisn/sgisn_console.c ============================================================================== --- projects/altix/sys/ia64/sgisn/sgisn_console.c Mon Apr 25 23:38:52 2011 (r221042) +++ projects/altix/sys/ia64/sgisn/sgisn_console.c Mon Apr 25 23:51:26 2011 (r221043) @@ -27,12 +27,15 @@ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); +#include "opt_comconsole.h" + #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> #include <sys/bus.h> #include <sys/cons.h> #include <sys/interrupt.h> +#include <sys/kdb.h> #include <sys/module.h> #include <sys/rman.h> #include <sys/tty.h> @@ -47,6 +50,7 @@ struct sncon_softc { void *sc_icookie; void *sc_softih; int sc_irid; + int sc_altbrk; }; static char sncon_name[] = "sncon"; @@ -206,9 +210,9 @@ sncon_tty_param(struct tty *tp, struct t * Device section. */ -static int sncon_attach(device_t); -static int sncon_detach(device_t); -static int sncon_probe(device_t); +static int sncon_attach(device_t); +static int sncon_detach(device_t); +static int sncon_probe(device_t); static device_method_t sncon_methods[] = { DEVMETHOD(device_attach, sncon_attach), @@ -230,6 +234,56 @@ DRIVER_MODULE(sncon, shub, sncon_driver, static void sncon_rx_intr(void *arg) { + struct sncon_softc *sc = arg; + struct ia64_sal_result r; + struct tty *tp; + int ch, count; + + count = 0; + tp = sc->sc_tp; + tty_lock(tp); + do { + r = ia64_sal_entry(SAL_SGISN_POLL, 0, 0, 0, 0, 0, 0, 0); + if (r.sal_status || r.sal_result[0] == 0) + break; + + r = ia64_sal_entry(SAL_SGISN_GETC, 0, 0, 0, 0, 0, 0, 0); + if (r.sal_status != 0) + break; + + ch = r.sal_result[0]; + +#if defined(KDB) && defined(ALT_BREAK_TO_DEBUGGER) + do { + int kdb; + kdb = kdb_alt_break(ch, &sc->sc_altbrk); + if (kdb != 0) { + switch (kdb) { + case KDB_REQ_DEBUGGER: + kdb_enter(KDB_WHY_BREAK, + "Break sequence on console"); + break; + case KDB_REQ_PANIC: + kdb_panic("Panic sequence on console"); + break; + case KDB_REQ_REBOOT: + kdb_reboot(); + break; + } + } + } while (0); +#endif + + ttydisc_rint(tp, ch, 0); + count++; + } while (count < 128); + if (count > 0) + ttydisc_rint_done(tp); + tty_unlock(tp); + + /* Acknowledge handling of Shub event. */ + BUS_WRITE_IVAR(device_get_parent(sc->sc_dev), sc->sc_dev, + SHUB_IVAR_EVENT, SHUB_EVENT_CONSOLE); } static void @@ -248,11 +302,6 @@ sncon_attach(device_t dev) sc->sc_dev = dev; do { - /* Enable RX interrupts. */ - r = ia64_sal_entry(SAL_SGISN_CON_INTR, 2, 1, 0, 0, 0, 0, 0); - if (r.sal_status != 0) - break; - sc->sc_irid = 0; sc->sc_ires = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->sc_irid, RF_ACTIVE | RF_SHAREABLE); @@ -270,10 +319,9 @@ sncon_attach(device_t dev) } } while (0); - if (sc->sc_ires == NULL) { - /* Disable RX interrupts. */ - r = ia64_sal_entry(SAL_SGISN_CON_INTR, 2, 0, 0, 0, 0, 0, 0); - } + /* Enable or disable RX interrupts appropriately. */ + r = ia64_sal_entry(SAL_SGISN_CON_INTR, 2, + (sc->sc_ires != NULL) ? 1 : 0, 0, 0, 0, 0, 0); swi_add(&tty_intr_event, sncon_name, sncon_tx_intr, sc, SWI_TTY, INTR_TYPE_TTY, &sc->sc_softih); @@ -300,13 +348,13 @@ sncon_detach(device_t dev) tty_rel_gone(tp); if (sc->sc_ires != NULL) { + /* Disable RX interrupts. */ + r = ia64_sal_entry(SAL_SGISN_CON_INTR, 2, 0, 0, 0, 0, 0, 0); + bus_teardown_intr(dev, sc->sc_ires, sc->sc_icookie); bus_release_resource(dev, SYS_RES_IRQ, sc->sc_irid, sc->sc_ires); } - - /* Disable Tx & Rx interrupts. */ - r = ia64_sal_entry(SAL_SGISN_CON_INTR, 2, 0, 0, 0, 0, 0, 0); return (0); } @@ -314,12 +362,17 @@ static int sncon_probe(device_t dev) { struct ia64_sal_result r; + int error; r = ia64_sal_entry(SAL_SGISN_SN_INFO, 0, 0, 0, 0, 0, 0, 0); if (r.sal_status != 0) return (ENXIO); - bus_set_resource(dev, SYS_RES_IRQ, 0, 0xe9, 1); + error = bus_set_resource(dev, SYS_RES_IRQ, 0, 0xe9, 1); + if (error) { + device_printf(dev, "Can't set IRQ (error=%d)\n", error); + return (error); + } device_set_desc_copy(dev, "SGI L1 console"); return (0); } Modified: projects/altix/sys/ia64/sgisn/sgisn_pcib.c ============================================================================== --- projects/altix/sys/ia64/sgisn/sgisn_pcib.c Mon Apr 25 23:38:52 2011 (r221042) +++ projects/altix/sys/ia64/sgisn/sgisn_pcib.c Mon Apr 25 23:51:26 2011 (r221043) @@ -264,6 +264,24 @@ sgisn_pcib_probe(device_t dev) return (BUS_PROBE_DEFAULT); } +static void +sgisn_pcib_callout(void *arg) +{ + static u_long islast = ~0UL; + struct sgisn_pcib_softc *sc = arg; + u_long is; + + is = bus_space_read_8(sc->sc_tag, sc->sc_hndl, PIC_REG_INT_STATUS); + if (is != islast) { + islast = is; + printf("XXX: %s: INTR status = %lu, IRR=%#lx:%#lx:%#lx:%#lx\n", + __func__, is, ia64_get_irr0(), ia64_get_irr1(), + ia64_get_irr2(), ia64_get_irr3()); + } + + timeout(sgisn_pcib_callout, sc, hz); +} + static int sgisn_pcib_attach(device_t dev) { @@ -306,6 +324,8 @@ sgisn_pcib_attach(device_t dev) sgisn_pcib_scan(sc, sc->sc_busnr, sgisn_pcib_maxslots(dev)); #endif + timeout(sgisn_pcib_callout, sc, hz); + device_add_child(dev, "pci", -1); return (bus_generic_attach(dev)); } Modified: projects/altix/sys/ia64/sgisn/sgisn_shub.c ============================================================================== --- projects/altix/sys/ia64/sgisn/sgisn_shub.c Mon Apr 25 23:38:52 2011 (r221042) +++ projects/altix/sys/ia64/sgisn/sgisn_shub.c Mon Apr 25 23:51:26 2011 (r221043) @@ -72,28 +72,38 @@ static int sgisn_shub_probe(device_t); static int sgisn_shub_activate_resource(device_t, device_t, int, int, struct resource *); -static int sgisn_shub_read_ivar(device_t, device_t, int, uintptr_t *); -static int sgisn_shub_write_ivar(device_t, device_t, int, uintptr_t); static struct resource *sgisn_shub_alloc_resource(device_t, device_t, int, int *, u_long, u_long, u_long, u_int); +static void sgisn_shub_delete_resource(device_t, device_t, int, int); +static int sgisn_shub_get_resource(device_t, device_t, int, int, u_long *, + u_long *); +static int sgisn_shub_read_ivar(device_t, device_t, int, uintptr_t *); +static int sgisn_shub_release_resource(device_t, device_t, int, int, + struct resource *); +static int sgisn_shub_set_resource(device_t, device_t, int, int, u_long, + u_long); +static int sgisn_shub_write_ivar(device_t, device_t, int, uintptr_t); /* * Bus interface definitions. */ static device_method_t sgisn_shub_methods[] = { /* Device interface */ + DEVMETHOD(device_attach, sgisn_shub_attach), DEVMETHOD(device_identify, sgisn_shub_identify), DEVMETHOD(device_probe, sgisn_shub_probe), - DEVMETHOD(device_attach, sgisn_shub_attach), /* Bus interface */ - DEVMETHOD(bus_read_ivar, sgisn_shub_read_ivar), - DEVMETHOD(bus_write_ivar, sgisn_shub_write_ivar), + DEVMETHOD(bus_read_ivar, sgisn_shub_read_ivar), + DEVMETHOD(bus_write_ivar, sgisn_shub_write_ivar), DEVMETHOD(bus_print_child, bus_generic_print_child), - DEVMETHOD(bus_alloc_resource, sgisn_shub_alloc_resource), - DEVMETHOD(bus_release_resource, bus_generic_release_resource), DEVMETHOD(bus_activate_resource, sgisn_shub_activate_resource), + DEVMETHOD(bus_alloc_resource, sgisn_shub_alloc_resource), DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), + DEVMETHOD(bus_delete_resource, sgisn_shub_delete_resource), + DEVMETHOD(bus_get_resource, sgisn_shub_get_resource), + DEVMETHOD(bus_release_resource, sgisn_shub_release_resource), + DEVMETHOD(bus_set_resource, sgisn_shub_set_resource), DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), @@ -193,6 +203,53 @@ sgisn_shub_activate_resource(device_t de return (EDOOFUS); } +static struct resource * +sgisn_shub_alloc_resource(device_t dev, device_t child, int type, int *rid, + u_long start, u_long end, u_long count, u_int flags) +{ + struct resource *res; + + res = bus_alloc_resource(dev, type, rid, start, end, count, flags); + return (res); +} + +static void +sgisn_shub_delete_resource(device_t dev, device_t child, int type, int rid) +{ + + bus_delete_resource(dev, type, rid); +} + +static int +sgisn_shub_get_resource(device_t dev, device_t child, int type, int rid, + u_long *startp, u_long *countp) +{ + int error; + + error = bus_get_resource(dev, type, rid, startp, countp); + return (error); +} + +static int +sgisn_shub_release_resource(device_t dev, device_t child, int type, int rid, + struct resource *r) +{ + int error; + + error = bus_release_resource(dev, type, rid, r); + return (error); +} + +static int +sgisn_shub_set_resource(device_t dev, device_t child, int type, int rid, + u_long start, u_long count) +{ + int error; + + error = bus_set_resource(dev, type, rid, start, count); + return (error); +} + #if 0 static void sgisn_shub_dump_sn_info(struct ia64_sal_result *r) @@ -476,17 +533,17 @@ sgisn_shub_read_ivar(device_t dev, devic static int sgisn_shub_write_ivar(device_t dev, device_t child, int which, uintptr_t value) { -// XXX struct sgisn_shub_softc *sc = device_get_softc(dev); - - return (ENOENT); -} + struct sgisn_shub_softc *sc = device_get_softc(dev); + uint64_t ev; -static struct resource * -sgisn_shub_alloc_resource(device_t dev, device_t child, int type, int *rid, - u_long start, u_long end, u_long count, u_int flags) -{ - struct resource *res; + if (which != SHUB_IVAR_EVENT) + return (ENOENT); - res = bus_alloc_resource(dev, type, rid, start, end, count, flags); - return (res); + ev = bus_space_read_8(sc->sc_tag, sc->sc_hndl, SHUB_MMR_EVENT); + if (ev & value) + bus_space_write_8(sc->sc_tag, sc->sc_hndl, SHUB_MMR_EVENT_WR, + value); + device_printf(dev, "XXX: %s: child=%p, event=%lx, mask=%lx\n", + __func__, child, ev, value); + return (0); } Modified: projects/altix/sys/ia64/sgisn/sgisn_shub.h ============================================================================== --- projects/altix/sys/ia64/sgisn/sgisn_shub.h Mon Apr 25 23:38:52 2011 (r221042) +++ projects/altix/sys/ia64/sgisn/sgisn_shub.h Mon Apr 25 23:51:26 2011 (r221043) @@ -39,6 +39,7 @@ #define SHUB_MMR_RTC3_ICFG 0x10001680 #define SHUB_MMR_RTC3_IENA 0x10001700 #define SHUB_MMR_EVENT 0x10010000 +#define SHUB_MMR_EVENT_WR 0x10010008 #define SHUB_MMR_IPI_ACC 0x10060480 #define SHUB_MMR_ID 0x10060580 #define SHUB_MMR_PTC_CFG0 0x101a0000
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201104252351.p3PNpQHF097825>