Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 9 Jun 2012 14:12:41 GMT
From:      Robert Watson <rwatson@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 212527 for review
Message-ID:  <201206091412.q59ECfXw072784@skunkworks.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/@@212527?ac=10

Change 212527 by rwatson@rwatson_svr_ctsrd_mipsbuild on 2012/06/09 14:12:32

	Rework the Altera JTAG UART device driver to use FreeBSD's bus(9)
	primitives at the TTY layer, and allow multiple instances to be
	configured using device.hints.  The low-level console portion of
	the driver continues to be aware of the MIPS physically mapped
	segment and UART address for the first UART device; however, the
	TTY layer is now portable and multiple instances can be
	configured.  The default BERI.hints configures each of three
	JTAG UARTs in our demonstration DE4 setup, hung off of the Nexus.
	
	Some care is required to ensure that interactions between the
	two layers work correctly, such that the TTY for a low-level
	console borrow the console-layer lock and buffer, whereas TTY
	instances aren't bound to a console instance maintain their own
	lock and buffer.
	
	It is now possible to enable the ttyu1 and ttyu2 entries in 
	/etc/ttys and use multiple terminal instances.  
	
	Further driver changes are required to better handle the case
	where there's no JTAG client using a JTAG UART (which can lead to
	stalling), and to move to interrupt-driven operation at the TTY
	layer instead of polling.

Affected files ...

.. //depot/projects/ctsrd/beribsd/src/sys/dev/altera/jtag_uart/altera_jtag_uart.h#2 edit
.. //depot/projects/ctsrd/beribsd/src/sys/dev/altera/jtag_uart/altera_jtag_uart_cons.c#2 edit
.. //depot/projects/ctsrd/beribsd/src/sys/dev/altera/jtag_uart/altera_jtag_uart_nexus.c#1 add
.. //depot/projects/ctsrd/beribsd/src/sys/dev/altera/jtag_uart/altera_jtag_uart_tty.c#2 edit
.. //depot/projects/ctsrd/beribsd/src/sys/mips/beri/files.beri#16 edit
.. //depot/projects/ctsrd/beribsd/src/sys/mips/conf/BERI_DE4.hints#5 edit

Differences ...

==== //depot/projects/ctsrd/beribsd/src/sys/dev/altera/jtag_uart/altera_jtag_uart.h#2 (text+ko) ====

@@ -31,27 +31,92 @@
 #ifndef _DEV_ALTERA_JTAG_UART_H_
 #define	_DEV_ALTERA_JTAG_UART_H_
 
-#define	AJU_TTYNAME	"ttyu0"
+struct altera_jtag_uart_softc {
+	device_t		 ajus_dev;
+	int			 ajus_unit;
+
+	/*
+	 * Hardware resources.
+	 */
+	struct resource		*ajus_mem_res;
+	int			 ajus_mem_rid;
+
+	/*
+	 * TTY resources.
+	 */
+	struct tty		*ajus_ttyp;
+	int			 ajus_alt_break_state;
+
+	/*
+	 * Driver resources.
+	 */
+	struct mtx		*ajus_lockp;
+	struct mtx		 ajus_lock;
+	struct callout		 ajus_callout;
+
+	/*
+	 * One-character buffer required because it's not possible to peek at
+	 * the input FIFO without reading it.
+	 */
+	int			 ajus_buffer_valid;
+	int			*ajus_buffer_validp;
+	uint8_t			 ajus_buffer_data;
+	uint8_t			*ajus_buffer_datap;
+};
+
+#define	AJU_TTYNAME	"ttyu"
 
-#define	AJU_LOCK_INIT()		mtx_init(&aj_uart_lock, "aj_uart_lock",	\
-				    NULL, MTX_SPIN)
+/*
+ * Because tty-level use of the I/O ports completes with low-level console
+ * use, spinlocks must be employed here.
+ */
+#define	AJU_CONSOLE_LOCK_INIT() do {					\
+	mtx_init(&aju_cons_lock, "aju_cons_lock", NULL, MTX_SPIN);	\
+} while (0)
 
-#define	AJU_LOCK() do {							\
+#define	AJU_CONSOLE_LOCK() do {						\
 	if (!kdb_active)						\
-		mtx_lock_spin(&aj_uart_lock);				\
+		mtx_lock_spin(&aju_cons_lock);				\
 } while (0)
 
-#define	AJU_LOCK_ASSERT() do {						\
+#define	AJU_CONSOLE_LOCK_ASSERT() {					\
 	if (!kdb_active)						\
-		mtx_assert(&aj_uart_lock, MA_OWNED);			\
+		mtx_assert(&aju_cons_lock, MA_OWNED);			\
 } while (0)
 
-#define	AJU_UNLOCK() do {						\
+#define	AJU_CONSOLE_UNLOCK() do {					\
 	if (!kdb_active)						\
-		mtx_unlock_spin(&aj_uart_lock);				\
+		mtx_unlock_spin(&aju_cons_lock);			\
+} while (0)
+
+#define	AJU_LOCK_INIT(sc) do {						\
+	mtx_init(&(sc)->ajus_lock, "aju_lock", NULL, MTX_SPIN);		\
+} while (0)
+
+#define	AJU_LOCK_DESTROY(sc) do {					\
+	mtx_destroy(&(sc)->ajus_lock);					\
+} while (0)
+
+#define	AJU_LOCK(sc) do {						\
+	mtx_lock_spin((sc)->ajus_lockp);				\
+} while (0)
+
+#define	AJU_LOCK_ASSERT(sc) do {					\
+	mtx_assert((sc)->ajus_lockp, MA_OWNED);				\
+} while (0)
+
+#define	AJU_UNLOCK(sc) do {						\
+	mtx_unlock_spin((sc)->ajus_lockp);				\
 } while (0)
 
-extern struct mtx	aj_uart_lock;
+/*
+ * When a TTY-level Altera JTAG UART instance is also the low-level console,
+ * the TTY layer borrows the console-layer lock and buffer rather than using
+ * its own.
+ */
+extern struct mtx	aju_cons_lock;
+extern char  		aju_cons_buffer_data;
+extern int		aju_cons_buffer_valid;
 
 /*
  * Base physical address of the JTAG UART in BERI.
@@ -106,11 +171,9 @@
 #define	ALTERA_JTAG_UART_CONTROL_WSPACE_SHIFT	16
 
 /*
- * Low-level console routines currently used by the tty layer.
+ * Driver attachment functions for Nexus.
  */
-int	aj_uart_writable(void);
-int	aj_uart_readable(void);
-void	aj_uart_write(char ch);
-char	aj_uart_read(void);
+void	altera_jtag_uart_attach(struct altera_jtag_uart_softc *sc);
+void	altera_jtag_uart_detach(struct altera_jtag_uart_softc *sc);
 
 #endif /* _DEV_ALTERA_JTAG_UART_H_ */

==== //depot/projects/ctsrd/beribsd/src/sys/dev/altera/jtag_uart/altera_jtag_uart_cons.c#2 (text+ko) ====

@@ -35,32 +35,51 @@
 #include <sys/cons.h>
 #include <sys/endian.h>
 #include <sys/kdb.h>
-#include <sys/systm.h>
 #include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
 #include <sys/reboot.h>
+#include <sys/systm.h>
 #include <sys/tty.h>
 
 #include <ddb/ddb.h>
 
 #include <dev/altera/jtag_uart/altera_jtag_uart.h>
 
-struct mtx	aj_uart_lock;
+/*
+ * One-byte buffer as we can't check whether the UART is readable without
+ * actually reading from it, synchronised by a spinlock; this lock also
+ * synchronises access to the I/O ports for non-atomic sequences.  These
+ * symbols are public so that the TTY layer can use them when working on an
+ * instance of the UART that is also a low-level console.
+ */
+char		aju_cons_buffer_data;
+int		aju_cons_buffer_valid;
+struct mtx	aju_cons_lock;
 
 /*
  * Low-level console driver functions.
  */
-static cn_probe_t	aj_uart_cnprobe;
-static cn_init_t	aj_uart_cninit;
-static cn_term_t	aj_uart_cnterm;
-static cn_getc_t	aj_uart_cngetc;
-static cn_putc_t	aj_uart_cnputc;
-static cn_grab_t	aj_uart_cngrab;
-static cn_ungrab_t	aj_uart_cnungrab;
+static cn_probe_t	aju_cnprobe;
+static cn_init_t	aju_cninit;
+static cn_term_t	aju_cnterm;
+static cn_getc_t	aju_cngetc;
+static cn_putc_t	aju_cnputc;
+static cn_grab_t	aju_cngrab;
+static cn_ungrab_t	aju_cnungrab;
 
 /*
- * I/O routines lifted from Deimos.
+ * I/O routines lifted from Deimos.  This is not only MIPS-specific, but also
+ * BERI-specific, as we're hard coding the the address at which we expect to
+ * find the Altera JTAG UART and using it unconditionally.  We use these
+ * low-level routines so that we can perform console I/O long before newbus
+ * has initialised and devices have attached.  The TTY layer of the driver
+ * knows about this, and uses the console-layer spinlock instead of the
+ * TTY-layer lock to avoid confusion between layers for the console UART.
  *
- * XXXRW: Should be using FreeBSD's bus routines here.
+ * XXXRW: The only place this inter-layer behaviour breaks down is if the
+ * low-level console is used for polled read while the TTY driver is also
+ * looking for input.  Probably we should also share buffers between layers.
  */
 #define	MIPS_XKPHYS_UNCACHED_BASE	0x9000000000000000
 
@@ -108,18 +127,11 @@
 }
 
 /*
- * One-byte buffer as we can't check whether the UART is readable without
- * actually reading from it.
- */
-static char	buffer_data;
-static int	buffer_valid;
-
-/*
  * Low-level read and write register routines; the Altera UART is little
  * endian, so we byte swap 32-bit reads and writes.
  */
 static inline uint32_t
-aj_uart_data_read(void)
+aju_cons_data_read(void)
 {
 
 	return (mips_ioread_uint32le(mips_phys_to_uncached(BERI_UART_BASE +
@@ -127,7 +139,7 @@
 }
 
 static inline void
-aj_uart_data_write(uint32_t v)
+aju_cons_data_write(uint32_t v)
 {
 
 	mips_iowrite_uint32le(mips_phys_to_uncached(BERI_UART_BASE +
@@ -135,125 +147,117 @@
 }
 
 static inline uint32_t
-aj_uart_control_read(void)
+aju_cons_control_read(void)
 {
 
 	return (mips_ioread_uint32le(mips_phys_to_uncached(BERI_UART_BASE +
 	    ALTERA_JTAG_UART_CONTROL_OFF)));
 }
 
-static inline void
-aj_uart_control_write(uint32_t v)
-{
-
-	mips_iowrite_uint32le(mips_phys_to_uncached(BERI_UART_BASE +
-	    ALTERA_JTAG_UART_DATA_OFF), v);
-}
-
 /*
  * Slightly higher-level routines aware of buffering and flow control.
  */
-int
-aj_uart_writable(void)
+static int
+aju_cons_writable(void)
 {
 
-	return ((aj_uart_control_read() &
+	return ((aju_cons_control_read() &
 	    ALTERA_JTAG_UART_CONTROL_WSPACE) != 0);
 }
 
-int
-aj_uart_readable(void)
+static int
+aju_cons_readable(void)
 {
 	uint32_t v;
 
-	AJU_LOCK_ASSERT();
+	AJU_CONSOLE_LOCK_ASSERT();
 
-	if (buffer_valid)
+	if (aju_cons_buffer_valid)
 		return (1);
-	v = aj_uart_data_read();
+	v = aju_cons_data_read();
 	if ((v & ALTERA_JTAG_UART_DATA_RVALID) != 0) {
-		buffer_valid = 1;
-		buffer_data = (v & ALTERA_JTAG_UART_DATA_DATA);
+		aju_cons_buffer_valid = 1;
+		aju_cons_buffer_data = (v & ALTERA_JTAG_UART_DATA_DATA);
 		return (1);
 	}
 	return (0);
 }
 
-void
-aj_uart_write(char ch)
+static void
+aju_cons_write(char ch)
 {
 
-	AJU_LOCK_ASSERT();
+	AJU_CONSOLE_LOCK_ASSERT();
 
-	while (!aj_uart_writable());
-	aj_uart_data_write(ch);
+	while (!aju_cons_writable());
+	aju_cons_data_write(ch);
 }
 
-char
-aj_uart_read(void)
+static char
+aju_cons_read(void)
 {
 
-	AJU_LOCK_ASSERT();
+	AJU_CONSOLE_LOCK_ASSERT();
 
-	while (!aj_uart_readable());
-	buffer_valid = 0;
-	return (buffer_data);
+	while (!aju_cons_readable());
+	aju_cons_buffer_valid = 0;
+	return (aju_cons_buffer_data);
 }
 
 /*
  * Implementation of a FreeBSD low-level, polled console driver.
  */
 static void
-aj_uart_cnprobe(struct consdev *cp)
+aju_cnprobe(struct consdev *cp)
 {
 
-	sprintf(cp->cn_name, "ttyu0");
+	sprintf(cp->cn_name, "%s%d", AJU_TTYNAME, 0);
 	cp->cn_pri = (boothowto & RB_SERIAL) ? CN_REMOTE : CN_NORMAL;
 }
 
 static void
-aj_uart_cninit(struct consdev *cp)
+aju_cninit(struct consdev *cp)
 {
 
-	AJU_LOCK_INIT();
+	AJU_CONSOLE_LOCK_INIT();
 }
 
 static void
-aj_uart_cnterm(struct consdev *cp)
+aju_cnterm(struct consdev *cp)
 {
 
 }
 
 static int
-aj_uart_cngetc(struct consdev *cp)
+aju_cngetc(struct consdev *cp)
 {
 	int ret;
 
-	AJU_LOCK();
-	ret = aj_uart_read();
-	AJU_UNLOCK();
+	AJU_CONSOLE_LOCK();
+	ret = aju_cons_read();
+	AJU_CONSOLE_UNLOCK();
 	return (ret);
 }
 
 static void
-aj_uart_cnputc(struct consdev *cp, int c)
+aju_cnputc(struct consdev *cp, int c)
 {
 
-	AJU_LOCK();
-	aj_uart_write(c);
-	AJU_UNLOCK();
+	AJU_CONSOLE_LOCK();
+	aju_cons_write(c);
+	AJU_CONSOLE_UNLOCK();
 }
 
 static void
-aj_uart_cngrab(struct consdev *cp)
+aju_cngrab(struct consdev *cp)
 {
 
 }
 
 static void
-aj_uart_cnungrab(struct consdev *cp)
+aju_cnungrab(struct consdev *cp)
 {
 
 }
 
-CONSOLE_DRIVER(aj_uart);
+CONSOLE_DRIVER(aju);

==== //depot/projects/ctsrd/beribsd/src/sys/dev/altera/jtag_uart/altera_jtag_uart_tty.c#2 (text+ko) ====

@@ -32,9 +32,11 @@
 __FBSDID("$FreeBSD$");
 
 #include <sys/param.h>
+#include <sys/bus.h>
 #include <sys/cons.h>
 #include <sys/endian.h>
 #include <sys/kdb.h>
+#include <sys/rman.h>
 #include <sys/systm.h>
 #include <sys/kernel.h>
 #include <sys/reboot.h>
@@ -42,47 +44,110 @@
 
 #include <ddb/ddb.h>
 
+#include <machine/bus.h>
+
 #include <dev/altera/jtag_uart/altera_jtag_uart.h>
 
 /*
- * TTY-level fields.
+ * If one of the Altera JTAG UARTs is currently the system console, register
+ * it here.
  */
-static tsw_outwakeup_t	aj_uart_outwakeup;
+static struct altera_jtag_uart_softc	*aju_cons_sc;
+
+static tsw_outwakeup_t	aju_outwakeup;
+static void		aju_timeout(void *);
 
-static struct ttydevsw aj_uart_ttydevsw = {
+static struct ttydevsw aju_ttydevsw = {
 	.tsw_flags	= TF_NOPREFIX,
-	.tsw_outwakeup	= aj_uart_outwakeup,
+	.tsw_outwakeup	= aju_outwakeup,
 };
 
-static struct callout	aj_uart_callout;
-static u_int		aj_uart_polltime = 1;
-#ifdef KDB
-static int		aj_uart_alt_break_state;
-#endif
+/*
+ * Poll for new input every (aju_pollinterval) ticks.
+ */
+static u_int		aju_pollinterval = 1;
+
+/*
+ * Low-level read and write register routines; the Altera UART is little
+ * endian, so we byte swap 32-bit reads and writes.
+ */
+static inline uint32_t
+aju_data_read(struct altera_jtag_uart_softc *sc)
+{
+
+	return (le32toh(bus_read_4(sc->ajus_mem_res,
+	    ALTERA_JTAG_UART_DATA_OFF)));
+}
+
+static inline void
+aju_data_write(struct altera_jtag_uart_softc *sc, uint32_t v)
+{
+
+	bus_write_4(sc->ajus_mem_res, ALTERA_JTAG_UART_DATA_OFF, htole32(v));
+}
+
+static inline uint32_t
+aju_control_read(struct altera_jtag_uart_softc *sc)
+{
 
-static void		aj_uart_timeout(void *);
+	return (le32toh(bus_read_4(sc->ajus_mem_res,
+	    ALTERA_JTAG_UART_CONTROL_OFF)));
+}
 
 /*
- * TTY-level functions for aj_uart.
+ * Slightly higher-level routines aware of buffering and flow control.
  */
+static inline int
+aju_writable(struct altera_jtag_uart_softc *sc)
+{
+
+	return ((aju_control_read(sc) &
+	    ALTERA_JTAG_UART_CONTROL_WSPACE) != 0);
+}
+
+static inline int
+aju_readable(struct altera_jtag_uart_softc *sc)
+{
+	uint32_t v;
+
+	AJU_LOCK_ASSERT(sc);
+
+	if (*sc->ajus_buffer_validp)
+		return (1);
+	v = aju_data_read(sc);
+	if ((v & ALTERA_JTAG_UART_DATA_RVALID) != 0) {
+		*sc->ajus_buffer_validp = 1;
+		*sc->ajus_buffer_datap = (v & ALTERA_JTAG_UART_DATA_DATA);
+		return (1);
+	}
+	return (0);
+}
+
 static void
-aj_uart_ttyinit(void *unused)
+aju_write(struct altera_jtag_uart_softc *sc, char ch)
+{
+
+	AJU_LOCK_ASSERT(sc);
+
+	while (!aju_writable(sc));
+	aju_data_write(sc, ch);
+}
+
+static char
+aju_read(struct altera_jtag_uart_softc *sc)
 {
-	struct tty *tp;
+
+	AJU_LOCK_ASSERT(sc);
 
-	tp = tty_alloc(&aj_uart_ttydevsw, NULL);
-	tty_init_console(tp, 0);
-	tty_makedev(tp, NULL, "%s", AJU_TTYNAME);
-	callout_init(&aj_uart_callout, CALLOUT_MPSAFE);
-	callout_reset(&aj_uart_callout, aj_uart_polltime, aj_uart_timeout,
-	    tp);
+	while (!aju_readable(sc));
+	*sc->ajus_buffer_validp = 0;
+	return (*sc->ajus_buffer_datap);
 }
-SYSINIT(aj_uart_ttyinit, SI_SUB_CONFIGURE, SI_ORDER_MIDDLE, aj_uart_ttyinit,
-    NULL);
 
 static void
-aj_uart_outwakeup(struct tty *tp)
+aju_outwakeup(struct tty *tp)
 {
+	struct altera_jtag_uart_softc *sc;
 	int len;
 	u_char ch;
 
@@ -90,37 +155,81 @@
 	 * XXXRW: Would be nice not to do blocking writes to the UART here,
 	 * rescheduling on our timer tick if work remains to be done.
 	 */
+	sc = tty_softc(tp);
 	for (;;) {
 		len = ttydisc_getc(tp, &ch, sizeof(ch));
 		if (len == 0)
 			break;
-		AJU_LOCK();
-		aj_uart_write(ch);
-		AJU_UNLOCK();
+		AJU_LOCK(sc);
+		aju_write(sc, ch);
+		AJU_UNLOCK(sc);
 	}
 }
 
 static void
-aj_uart_timeout(void *v)
+aju_timeout(void *v)
 {
+	struct altera_jtag_uart_softc *sc;
 	struct tty *tp;
 	int c;
 
-	tp = v;
+	sc = v;
+	tp = sc->ajus_ttyp;
 	tty_lock(tp);
-	AJU_LOCK();
-	while (aj_uart_readable()) {
-		c = aj_uart_read();
-		AJU_UNLOCK();
+	AJU_LOCK(sc);
+	while (aju_readable(sc)) {
+		c = aju_read(sc);
+		AJU_UNLOCK(sc);
 #ifdef KDB
-		kdb_alt_break(c, &aj_uart_alt_break_state);
+		kdb_alt_break(c, &sc->ajus_alt_break_state);
 #endif
 		ttydisc_rint(tp, c, 0);
-		AJU_LOCK();
+		AJU_LOCK(sc);
 	}
-	AJU_UNLOCK();
+	AJU_UNLOCK(sc);
 	ttydisc_rint_done(tp);
 	tty_unlock(tp);
-	callout_reset(&aj_uart_callout, aj_uart_polltime, aj_uart_timeout,
-	    tp);
+	callout_reset(&sc->ajus_callout, aju_pollinterval, aju_timeout, sc);
+}
+
+void
+altera_jtag_uart_attach(struct altera_jtag_uart_softc *sc)
+{
+	struct tty *tp;
+
+	tp = sc->ajus_ttyp = tty_alloc(&aju_ttydevsw, sc);
+
+	/*
+	 * XXXRW: Currently, we detect the console solely based on it using a
+	 * reserved address, and borrow console-level locks and buffer if so.
+	 * Is there a better way?
+	 */
+	AJU_LOCK_INIT(sc);
+	if (rman_get_start(sc->ajus_mem_res) == BERI_UART_BASE) {
+		tty_init_console(tp, 0);
+		sc->ajus_lockp = &aju_cons_lock;
+		sc->ajus_buffer_validp = &aju_cons_buffer_valid;
+		sc->ajus_buffer_datap = &aju_cons_buffer_data;
+		aju_cons_sc = sc;
+	} else {
+		sc->ajus_lockp = &sc->ajus_lock;
+		sc->ajus_buffer_validp = &sc->ajus_buffer_valid;
+		sc->ajus_buffer_datap = &sc->ajus_buffer_data;
+	}
+	tty_makedev(tp, NULL, "%s%d", AJU_TTYNAME, sc->ajus_unit);
+	callout_init(&sc->ajus_callout, CALLOUT_MPSAFE);
+	callout_reset(&sc->ajus_callout, aju_pollinterval, aju_timeout, sc);
+}
+
+void
+altera_jtag_uart_detach(struct altera_jtag_uart_softc *sc)
+{
+	struct tty *tp = sc->ajus_ttyp;
+
+	if (sc == aju_cons_sc)
+		aju_cons_sc = NULL;
+	callout_drain(&sc->ajus_callout);
+	tty_lock(tp);
+	tty_rel_gone(tp);
+	AJU_LOCK_DESTROY(sc);
 }

==== //depot/projects/ctsrd/beribsd/src/sys/mips/beri/files.beri#16 (text+ko) ====

@@ -2,6 +2,7 @@
 dev/altera/avgen/altera_avgen.c		optional altera_avgen
 dev/altera/jtag_uart/altera_jtag_uart_cons.c	optional altera_jtag_uart
 dev/altera/jtag_uart/altera_jtag_uart_tty.c	optional altera_jtag_uart
+dev/altera/jtag_uart/altera_jtag_uart_nexus.c	optional altera_jtag_uart
 dev/altera/sdcard/altera_sdcard.c	optional altera_sdcard
 dev/altera/sdcard/altera_sdcard_disk.c	optional altera_sdcard
 dev/altera/sdcard/altera_sdcard_io.c	optional altera_sdcard

==== //depot/projects/ctsrd/beribsd/src/sys/mips/conf/BERI_DE4.hints#5 (text+ko) ====

@@ -1,6 +1,22 @@
 # $FreeBSD$
 
 #
+# Altera JTAG UARTs configured for console, debugging, and data putput on the
+# DE-4.
+#
+hint.altera_jtag_uart.0.at="nexus0"
+hint.altera_jtag_uart.0.maddr=0x7f000000
+hint.altera_jtag_uart.0.msize=0x40
+
+hint.altera_jtag_uart.1.at="nexus0"
+hint.altera_jtag_uart.1.maddr=0x7f001000
+hint.altera_jtag_uart.1.msize=0x40
+
+hint.altera_jtag_uart.2.at="nexus0"
+hint.altera_jtag_uart.2.maddr=0x7f002000
+hint.altera_jtag_uart.2.msize=0x40
+
+#
 # On-board DE4 and tPad SD Card IP core
 #
 hint.altera_sdcardc.0.at="nexus0"



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201206091412.q59ECfXw072784>