Skip site navigation (1)Skip section navigation (2)
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>