svn commit: r221043 - projects/altix/sys/ia64/sgisn
Marcel Moolenaar
marcel at FreeBSD.org
Mon Apr 25 23:51:27 UTC 2011
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
More information about the svn-src-projects
mailing list