Module Name: src
Committed By: skrll
Date: Wed Jul 25 07:26:18 UTC 2012
Modified Files:
src/sys/arch/evbarm/dev: plcom.c plcomreg.h plcomvar.h
src/sys/arch/evbarm/ifpga: ifpgareg.h plcom_ifpga.c
src/sys/arch/evbarm/integrator: integrator_machdep.c
Log Message:
Add support for the PL011 to plcom. Pull across a bunch of fixes from
com(4) while I'm here and do some other tidyup.
Tested on a RaspberryPi.
PL010 not tested.
To generate a diff of this commit:
cvs rdiff -u -r1.39 -r1.40 src/sys/arch/evbarm/dev/plcom.c
cvs rdiff -u -r1.3 -r1.4 src/sys/arch/evbarm/dev/plcomreg.h
cvs rdiff -u -r1.10 -r1.11 src/sys/arch/evbarm/dev/plcomvar.h
cvs rdiff -u -r1.3 -r1.4 src/sys/arch/evbarm/ifpga/ifpgareg.h
cvs rdiff -u -r1.13 -r1.14 src/sys/arch/evbarm/ifpga/plcom_ifpga.c
cvs rdiff -u -r1.68 -r1.69 \
src/sys/arch/evbarm/integrator/integrator_machdep.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/arch/evbarm/dev/plcom.c
diff -u src/sys/arch/evbarm/dev/plcom.c:1.39 src/sys/arch/evbarm/dev/plcom.c:1.40
--- src/sys/arch/evbarm/dev/plcom.c:1.39 Thu Jul 5 10:56:52 2012
+++ src/sys/arch/evbarm/dev/plcom.c Wed Jul 25 07:26:17 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: plcom.c,v 1.39 2012/07/05 10:56:52 skrll Exp $ */
+/* $NetBSD: plcom.c,v 1.40 2012/07/25 07:26:17 skrll Exp $ */
/*-
* Copyright (c) 2001 ARM Ltd
@@ -28,11 +28,11 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * Copyright (c) 1998, 1999 The NetBSD Foundation, Inc.
+ * Copyright (c) 1998, 1999, 2012 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
- * by Charles M. Hannum.
+ * by Charles M. Hannum and Nick Hudson.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -88,13 +88,13 @@
*/
/*
- * COM driver for the Prime Cell PL010 UART, which is similar to the 16C550,
- * but has a completely different programmer's model.
+ * COM driver for the Prime Cell PL010 and PL011 UARTs. Both are is similar to
+ * the 16C550, but have a completely different programmer's model.
* Derived from the NS16550AF com driver.
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: plcom.c,v 1.39 2012/07/05 10:56:52 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: plcom.c,v 1.40 2012/07/25 07:26:17 skrll Exp $");
#include "opt_plcom.h"
#include "opt_ddb.h"
@@ -103,9 +103,6 @@ __KERNEL_RCSID(0, "$NetBSD: plcom.c,v 1.
#include "opt_multiprocessor.h"
#include "rnd.h"
-#ifdef RND_COM
-#include <sys/rnd.h>
-#endif
/*
* Override cnmagic(9) macro before including <sys/systm.h>.
@@ -138,6 +135,9 @@ __KERNEL_RCSID(0, "$NetBSD: plcom.c,v 1.
#include <sys/kauth.h>
#include <sys/intr.h>
#include <sys/bus.h>
+#ifdef RND_COM
+#include <sys/rnd.h>
+#endif
#include <evbarm/dev/plcomreg.h>
#include <evbarm/dev/plcomvar.h>
@@ -148,7 +148,8 @@ static void plcom_enable_debugport (stru
void plcom_config (struct plcom_softc *);
void plcom_shutdown (struct plcom_softc *);
-int plcomspeed (long, long);
+int pl010comspeed (long, long);
+int pl011comspeed (long, long);
static u_char cflag2lcr (tcflag_t);
int plcomparam (struct tty *, struct termios *);
void plcomstart (struct tty *);
@@ -162,11 +163,10 @@ void tiocm_to_plcom (struct plcom_softc
int plcom_to_tiocm (struct plcom_softc *);
void plcom_iflush (struct plcom_softc *);
-int plcom_common_getc (dev_t, bus_space_tag_t, bus_space_handle_t);
-void plcom_common_putc (dev_t, bus_space_tag_t, bus_space_handle_t, int);
+int plcom_common_getc (dev_t, struct plcom_instance *);
+void plcom_common_putc (dev_t, struct plcom_instance *, int);
-int plcominit (bus_space_tag_t, bus_addr_t, int, int, tcflag_t,
- bus_space_handle_t *);
+int plcominit (struct plcom_instance *, int, int, tcflag_t);
dev_type_open(plcomopen);
dev_type_close(plcomclose);
@@ -189,6 +189,8 @@ integrate void plcom_stsoft (struct plco
integrate void plcom_schedrx (struct plcom_softc *);
void plcomdiag (void *);
+bool plcom_intstatus(struct plcom_instance *, u_int *);
+
extern struct cfdriver plcom_cd;
const struct cdevsw plcom_cdevsw = {
@@ -207,9 +209,9 @@ u_int plcom_rbuf_hiwat = (PLCOM_RING_SIZ
u_int plcom_rbuf_lowat = (PLCOM_RING_SIZE * 3) / 4;
static int plcomconsunit = -1;
-static bus_space_tag_t plcomconstag;
-static bus_space_handle_t plcomconsioh;
-static int plcomconsattached;
+static struct plcom_instance plcomcons_info;
+
+static int plcomconsattached;
static int plcomconsrate;
static tcflag_t plcomconscflag;
static struct cnm_state plcom_cnm_state;
@@ -226,16 +228,14 @@ static int ppscap =
#ifdef KGDB
#include <sys/kgdb.h>
-static int plcom_kgdb_unit;
-static bus_space_tag_t plcom_kgdb_iot;
-static bus_space_handle_t plcom_kgdb_ioh;
+static struct plcom_instance plcomkgdb_info;
static int plcom_kgdb_attached;
int plcom_kgdb_getc (void *);
void plcom_kgdb_putc (void *, int);
#endif /* KGDB */
-#define PLCOMUNIT_MASK 0x7ffff
+#define PLCOMUNIT_MASK 0x7ffff
#define PLCOMDIALOUT_MASK 0x80000
#define PLCOMUNIT(x) (minor(x) & PLCOMUNIT_MASK)
@@ -246,10 +246,58 @@ void plcom_kgdb_putc (void *, int);
#define BR BUS_SPACE_BARRIER_READ
#define BW BUS_SPACE_BARRIER_WRITE
-#define PLCOM_BARRIER(t, h, f) bus_space_barrier((t), (h), 0, PLCOM_UART_SIZE, (f))
+#define PLCOM_BARRIER(pi, f) \
+ bus_space_barrier((pi)->pi_iot, (pi)->pi_ioh, 0, (pi)->pi_size, (f))
+
+static uint8_t
+pread1(struct plcom_instance *pi, bus_size_t reg)
+{
+ if (!ISSET(pi->pi_flags, PLC_FLAG_32BIT_ACCESS))
+ return bus_space_read_1(pi->pi_iot, pi->pi_ioh, reg);
+
+ return bus_space_read_4(pi->pi_iot, pi->pi_ioh, reg & -4) >>
+ (8 * (reg & 3));
+}
+int nhcr;
+static void
+pwrite1(struct plcom_instance *pi, bus_size_t o, uint8_t val)
+{
+ if (!ISSET(pi->pi_flags, PLC_FLAG_32BIT_ACCESS)) {
+ bus_space_write_1(pi->pi_iot, pi->pi_ioh, o, val);
+ } else {
+ const size_t shift = 8 * (o & 3);
+ o &= -4;
+ uint32_t tmp = bus_space_read_4(pi->pi_iot, pi->pi_ioh, o);
+ tmp = (val << shift) | (tmp & ~(0xff << shift));
+ bus_space_write_4(pi->pi_iot, pi->pi_ioh, o, tmp);
+ }
+}
+
+static void
+pwritem1(struct plcom_instance *pi, bus_size_t o, const uint8_t *datap,
+ bus_size_t count)
+{
+ if (!ISSET(pi->pi_flags, PLC_FLAG_32BIT_ACCESS)) {
+ bus_space_write_multi_1(pi->pi_iot, pi->pi_ioh, o, datap, count);
+ } else {
+ KASSERT((o & 3) == 0);
+ while (count--) {
+ bus_space_write_4(pi->pi_iot, pi->pi_ioh, o, *datap++);
+ };
+ }
+}
+
+#define PREAD1(pi, reg) pread1(pi, reg)
+#define PREAD4(pi, reg) \
+ (bus_space_read_4((pi)->pi_iot, (pi)->pi_ioh, (reg)))
+
+#define PWRITE1(pi, reg, val) pwrite1(pi, reg, val)
+#define PWRITEM1(pi, reg, d, c) pwritem1(pi, reg, d, c)
+#define PWRITE4(pi, reg, val) \
+ (bus_space_write_4((pi)->pi_iot, (pi)->pi_ioh, (reg), (val)))
int
-plcomspeed(long speed, long frequency)
+pl010comspeed(long speed, long frequency)
{
#define divrnd(n, q) (((n)*2/(q)+1)/2) /* divide and round off */
@@ -274,6 +322,20 @@ plcomspeed(long speed, long frequency)
#undef divrnd
}
+int
+pl011comspeed(long speed, long frequency)
+{
+ int denom = 16 * speed;
+ int div = frequency / denom;
+ int rem = frequency % denom;
+
+ int ibrd = div << 6;
+ int fbrd = (((8 * rem) / speed) + 1) / 2;
+
+ /* Tolerance? */
+ return ibrd | fbrd;
+}
+
#ifdef PLCOM_DEBUG
int plcom_debug = 0;
@@ -301,7 +363,7 @@ plcomstatus(struct plcom_softc *sc, cons
}
#endif
-/* XXX this function is not used? */
+#if 0
int
plcomprobe1(bus_space_tag_t iot, bus_space_handle_t ioh)
{
@@ -327,6 +389,7 @@ plcomprobe1(bus_space_tag_t iot, bus_spa
return 1;
}
+#endif
/*
* No locking in this routine; it is only called during attach,
@@ -335,55 +398,106 @@ plcomprobe1(bus_space_tag_t iot, bus_spa
static void
plcom_enable_debugport(struct plcom_softc *sc)
{
+ struct plcom_instance *pi = &sc->sc_pi;
- /* Turn on line break interrupt, set carrier. */
- sc->sc_cr = PL010_CR_RIE | PL010_CR_RTIE | PL01X_CR_UARTEN;
- bus_space_write_1(sc->sc_iot, sc->sc_ioh, plcom_cr, sc->sc_cr);
+ sc->sc_cr = PL01X_CR_UARTEN;
SET(sc->sc_mcr, PL01X_MCR_DTR | PL01X_MCR_RTS);
- /* XXX device_unit() abuse */
- sc->sc_set_mcr(sc->sc_set_mcr_arg, device_unit(sc->sc_dev),
- sc->sc_mcr);
+
+ /* Turn on line break interrupt, set carrier. */
+ switch (pi->pi_type) {
+ case PLCOM_TYPE_PL010:
+ SET(sc->sc_cr, PL010_CR_RIE | PL010_CR_RTIE);
+ PWRITE1(pi, PL010COM_CR, sc->sc_cr);
+ if (sc->sc_set_mcr) {
+ /* XXX device_unit() abuse */
+ sc->sc_set_mcr(sc->sc_set_mcr_arg,
+ device_unit(sc->sc_dev), sc->sc_mcr);
+ }
+ break;
+ case PLCOM_TYPE_PL011:
+ sc->sc_imsc = PL011_INT_RX | PL011_INT_RT;
+ SET(sc->sc_cr, PL011_CR_RXE | PL011_CR_TXE);
+ SET(sc->sc_cr, PL011_MCR(sc->sc_mcr));
+ PWRITE4(pi, PL011COM_CR, sc->sc_cr);
+ PWRITE4(pi, PL011COM_IMSC, sc->sc_imsc);
+ break;
+ }
+
}
void
plcom_attach_subr(struct plcom_softc *sc)
{
- int unit = sc->sc_iounit;
- bus_space_tag_t iot = sc->sc_iot;
- bus_space_handle_t ioh = sc->sc_ioh;
+ struct plcom_instance *pi = &sc->sc_pi;
struct tty *tp;
+ aprint_naive("\n");
+
callout_init(&sc->sc_diag_callout, 0);
mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_HIGH);
+ switch (pi->pi_type) {
+ case PLCOM_TYPE_PL010:
+ case PLCOM_TYPE_PL011:
+ break;
+ default:
+ aprint_error_dev(sc->sc_dev,
+ "Unknown plcom type: %d\n", pi->pi_type);
+ return;
+ }
+
/* Disable interrupts before configuring the device. */
sc->sc_cr = 0;
+ sc->sc_imsc = 0;
- if (plcomconstag && unit == plcomconsunit) {
+ if (bus_space_is_equal(pi->pi_iot, plcomcons_info.pi_iot) &&
+ pi->pi_iobase == plcomcons_info.pi_iobase) {
plcomconsattached = 1;
- plcomconstag = iot;
- plcomconsioh = ioh;
-
/* Make sure the console is always "hardwired". */
delay(1000); /* wait for output to finish */
SET(sc->sc_hwflags, PLCOM_HW_CONSOLE);
SET(sc->sc_swflags, TIOCFLAG_SOFTCAR);
- /* Must re-enable the console immediately, or we will
- hang when trying to print. */
+ /*
+ * Must re-enable the console immediately, or we will
+ * hang when trying to print.
+ */
sc->sc_cr = PL01X_CR_UARTEN;
+ if (pi->pi_type == PLCOM_TYPE_PL011)
+ SET(sc->sc_cr, PL011_CR_RXE | PL011_CR_TXE);
}
- bus_space_write_1(iot, ioh, plcom_cr, sc->sc_cr);
-
- /* The PL010 has a 16-byte fifo, but the tx interrupt triggers when
- there is space for 8 more bytes. */
- sc->sc_fifolen = 8;
- printf("\n");
+ switch (pi->pi_type) {
+ case PLCOM_TYPE_PL010:
+ PWRITE1(pi, PL010COM_CR, sc->sc_cr);
+ break;
+
+ case PLCOM_TYPE_PL011:
+ PWRITE4(pi, PL011COM_CR, sc->sc_cr);
+ PWRITE4(pi, PL011COM_IMSC, sc->sc_imsc);
+ break;
+ }
+
+ if (sc->sc_fifolen == 0) {
+ switch (pi->pi_type) {
+ case PLCOM_TYPE_PL010:
+ /*
+ * The PL010 has a 16-byte fifo, but the tx interrupt
+ * triggers when there is space for 8 more bytes.
+ */
+ sc->sc_fifolen = 8;
+ break;
+ case PLCOM_TYPE_PL011:
+ /* Some revisions have a 32 byte TX FIFO */
+ sc->sc_fifolen = 16;
+ break;
+ }
+ }
+ aprint_normal("\n");
if (ISSET(sc->sc_hwflags, PLCOM_HW_TXFIFO_DISABLE)) {
sc->sc_fifolen = 1;
- printf("%s: txfifo disabled\n", device_xname(sc->sc_dev));
+ aprint_normal_dev(sc->sc_dev, "txfifo disabled\n");
}
if (sc->sc_fifolen > 1)
@@ -399,8 +513,8 @@ plcom_attach_subr(struct plcom_softc *sc
sc->sc_rbput = sc->sc_rbget = sc->sc_rbuf;
sc->sc_rbavail = plcom_rbuf_size;
if (sc->sc_rbuf == NULL) {
- printf("%s: unable to allocate ring buffer\n",
- device_xname(sc->sc_dev));
+ aprint_error_dev(sc->sc_dev,
+ "unable to allocate ring buffer\n");
return;
}
sc->sc_ebuf = sc->sc_rbuf + (plcom_rbuf_size << 1);
@@ -413,9 +527,9 @@ plcom_attach_subr(struct plcom_softc *sc
/* locate the major number */
maj = cdevsw_lookup_major(&plcom_cdevsw);
- cn_tab->cn_dev = makedev(maj, device_unit(sc->sc_dev));
+ tp->t_dev = cn_tab->cn_dev = makedev(maj, device_unit(sc->sc_dev));
- printf("%s: console\n", device_xname(sc->sc_dev));
+ aprint_normal_dev(sc->sc_dev, "console\n");
}
#ifdef KGDB
@@ -423,23 +537,28 @@ plcom_attach_subr(struct plcom_softc *sc
* Allow kgdb to "take over" this port. If this is
* the kgdb device, it has exclusive use.
*/
- if (iot == plcom_kgdb_iot && unit == plcom_kgdb_unit) {
- plcom_kgdb_attached = 1;
+ if (bus_space_is_equal(iot, plcomkgdb_info.pi_iot) &&
+ pi->pi_iobase == plcomkgdb_info.pi_iobase) {
+ if (!ISSET(sc->sc_hwflags, PLCOM_HW_CONSOLE)) {
+ plcom_kgdb_attached = 1;
- SET(sc->sc_hwflags, PLCOM_HW_KGDB);
- printf("%s: kgdb\n", device_xname(sc->sc_dev));
+ SET(sc->sc_hwflags, PLCOM_HW_KGDB);
+ }
+ aprint_normal_dev(sc->sc_dev, "kgdb\n");
}
#endif
sc->sc_si = softint_establish(SOFTINT_SERIAL, plcomsoft, sc);
#ifdef RND_COM
- rnd_attach_source(&sc->rnd_source, device_xname(sc->sc_dev)),
- RND_TYPE_TTY, 0);
+ rnd_attach_source(&sc->rnd_source, device_xname(sc->sc_dev),
+ RND_TYPE_TTY, 0);
#endif
- /* if there are no enable/disable functions, assume the device
- is always enabled */
+ /*
+ * if there are no enable/disable functions, assume the device
+ * is always enabled
+ */
if (!sc->enable)
sc->enabled = 1;
@@ -451,12 +570,21 @@ plcom_attach_subr(struct plcom_softc *sc
void
plcom_config(struct plcom_softc *sc)
{
- bus_space_tag_t iot = sc->sc_iot;
- bus_space_handle_t ioh = sc->sc_ioh;
+ struct plcom_instance *pi = &sc->sc_pi;
/* Disable interrupts before configuring the device. */
sc->sc_cr = 0;
- bus_space_write_1(iot, ioh, plcom_cr, sc->sc_cr);
+ sc->sc_imsc = 0;
+ switch (pi->pi_type) {
+ case PLCOM_TYPE_PL010:
+ PWRITE1(pi, PL010COM_CR, sc->sc_cr);
+ break;
+
+ case PLCOM_TYPE_PL011:
+ PWRITE4(pi, PL011COM_CR, sc->sc_cr);
+ PWRITE4(pi, PL011COM_IMSC, sc->sc_imsc);
+ break;
+ }
if (ISSET(sc->sc_hwflags, PLCOM_HW_CONSOLE|PLCOM_HW_KGDB))
plcom_enable_debugport(sc);
@@ -486,6 +614,15 @@ plcom_detach(device_t self, int flags)
mn |= PLCOMDIALOUT_MASK;
vdevgone(maj, mn, mn, VCHR);
+ if (sc->sc_rbuf == NULL) {
+ /*
+ * Ring buffer allocation failed in the plcom_attach_subr,
+ * only the tty is allocated, and nothing else.
+ */
+ tty_free(sc->sc_tty);
+ return 0;
+ }
+
/* Free the receive buffer. */
free(sc->sc_rbuf, M_DEVBUF);
@@ -500,6 +637,7 @@ plcom_detach(device_t self, int flags)
/* Unhook the entropy source. */
rnd_detach_source(&sc->rnd_source);
#endif
+ callout_destroy(&sc->sc_diag_callout);
/* Destroy the lock. */
mutex_destroy(&sc->sc_lock);
@@ -524,6 +662,7 @@ plcom_activate(device_t self, enum devac
void
plcom_shutdown(struct plcom_softc *sc)
{
+ struct plcom_instance *pi = &sc->sc_pi;
struct tty *tp = sc->sc_tty;
mutex_spin_enter(&sc->sc_lock);
@@ -553,13 +692,36 @@ plcom_shutdown(struct plcom_softc *sc)
mutex_spin_enter(&sc->sc_lock);
}
+ sc->sc_cr = 0;
+ sc->sc_imsc = 0;
/* Turn off interrupts. */
- if (ISSET(sc->sc_hwflags, PLCOM_HW_CONSOLE))
+ if (ISSET(sc->sc_hwflags, PLCOM_HW_CONSOLE)) {
/* interrupt on break */
- sc->sc_cr = PL010_CR_RIE | PL010_CR_RTIE | PL01X_CR_UARTEN;
- else
- sc->sc_cr = 0;
- bus_space_write_1(sc->sc_iot, sc->sc_ioh, plcom_cr, sc->sc_cr);
+
+ sc->sc_cr = PL01X_CR_UARTEN;
+ sc->sc_imsc = 0;
+ switch (pi->pi_type) {
+ case PLCOM_TYPE_PL010:
+ SET(sc->sc_cr, PL010_CR_RIE | PL010_CR_RTIE);
+ break;
+ case PLCOM_TYPE_PL011:
+ SET(sc->sc_cr, PL011_CR_RXE);
+ SET(sc->sc_imsc, PL011_INT_RT | PL011_INT_RX);
+ break;
+ }
+ }
+ switch (pi->pi_type) {
+ case PLCOM_TYPE_PL010:
+ SET(sc->sc_cr, PL010_CR_RIE | PL010_CR_RTIE);
+ PWRITE1(pi, PL010COM_CR, sc->sc_cr);
+ break;
+ case PLCOM_TYPE_PL011:
+ SET(sc->sc_cr, PL011_CR_RXE | PL011_CR_TXE);
+ SET(sc->sc_imsc, PL011_INT_RT | PL011_INT_RX);
+ PWRITE4(pi, PL011COM_CR, sc->sc_cr);
+ PWRITE4(pi, PL011COM_IMSC, sc->sc_imsc);
+ break;
+ }
mutex_spin_exit(&sc->sc_lock);
if (sc->disable) {
@@ -576,6 +738,7 @@ int
plcomopen(dev_t dev, int flag, int mode, struct lwp *l)
{
struct plcom_softc *sc;
+ struct plcom_instance *pi;
struct tty *tp;
int s;
int error;
@@ -588,6 +751,8 @@ plcomopen(dev_t dev, int flag, int mode,
if (!device_is_active(sc->sc_dev))
return ENXIO;
+ pi = &sc->sc_pi;
+
#ifdef KGDB
/*
* If this is the kgdb port, no other use is permitted.
@@ -614,8 +779,8 @@ plcomopen(dev_t dev, int flag, int mode,
if (sc->enable) {
if ((*sc->enable)(sc)) {
splx(s);
- printf("%s: device enable failed\n",
- device_xname(sc->sc_dev));
+ aprint_error_dev(sc->sc_dev,
+ "device enable failed\n");
return EIO;
}
mutex_spin_enter(&sc->sc_lock);
@@ -627,11 +792,23 @@ plcomopen(dev_t dev, int flag, int mode,
/* Turn on interrupts. */
/* IER_ERXRDY | IER_ERLS | IER_EMSC; */
- sc->sc_cr = PL010_CR_RIE | PL010_CR_RTIE | PL010_CR_MSIE | PL01X_CR_UARTEN;
- bus_space_write_1(sc->sc_iot, sc->sc_ioh, plcom_cr, sc->sc_cr);
-
/* Fetch the current modem control status, needed later. */
- sc->sc_msr = bus_space_read_1(sc->sc_iot, sc->sc_ioh, plcom_fr);
+ sc->sc_cr = PL01X_CR_UARTEN;
+ switch (pi->pi_type) {
+ case PLCOM_TYPE_PL010:
+ SET(sc->sc_cr,
+ PL010_CR_RIE | PL010_CR_RTIE | PL010_CR_MSIE);
+ PWRITE1(pi, PL010COM_CR, sc->sc_cr);
+ sc->sc_msr = PREAD1(pi, PL01XCOM_FR);
+ break;
+ case PLCOM_TYPE_PL011:
+ SET(sc->sc_cr, PL011_CR_RXE | PL011_CR_TXE);
+ SET(sc->sc_imsc, PL011_INT_RT | PL011_INT_RX |
+ PL011_INT_MSMASK);
+ PWRITE4(pi, PL011COM_IMSC, sc->sc_imsc);
+ sc->sc_msr = PREAD4(pi, PL01XCOM_FR);
+ break;
+ }
/* Clear PPS capture state on first open. */
@@ -646,7 +823,6 @@ plcomopen(dev_t dev, int flag, int mode,
* Initialize the termios status to the defaults. Add in the
* sticky bits from TIOCSFLAGS.
*/
- t.c_ispeed = 0;
if (ISSET(sc->sc_hwflags, PLCOM_HW_CONSOLE)) {
t.c_ospeed = plcomconsrate;
t.c_cflag = plcomconscflag;
@@ -654,6 +830,8 @@ plcomopen(dev_t dev, int flag, int mode,
t.c_ospeed = TTYDEF_SPEED;
t.c_cflag = TTYDEF_CFLAG;
}
+ t.c_ispeed = t.c_ospeed;
+
if (ISSET(sc->sc_swflags, TIOCFLAG_CLOCAL))
SET(t.c_cflag, CLOCAL);
if (ISSET(sc->sc_swflags, TIOCFLAG_CRTSCTS))
@@ -802,12 +980,16 @@ plcomioctl(dev_t dev, u_long cmd, void *
{
struct plcom_softc *sc =
device_lookup_private(&plcom_cd, PLCOMUNIT(dev));
- struct tty *tp = sc->sc_tty;
+ struct tty *tp;
int error;
+ if (sc == NULL)
+ return ENXIO;
if (PLCOM_ISALIVE(sc) == 0)
return EIO;
+ tp = sc->sc_tty;
+
error = (*tp->t_linesw->l_ioctl)(tp, cmd, data, flag, l);
if (error != EPASSTHROUGH)
return error;
@@ -817,6 +999,18 @@ plcomioctl(dev_t dev, u_long cmd, void *
return error;
error = 0;
+ switch (cmd) {
+ case TIOCSFLAGS:
+ error = kauth_authorize_device_tty(l->l_cred,
+ KAUTH_DEVICE_TTY_PRIVSET, tp);
+ break;
+ default:
+ /* nothing */
+ break;
+ }
+ if (error) {
+ return error;
+ }
mutex_spin_enter(&sc->sc_lock);
switch (cmd) {
@@ -841,10 +1035,6 @@ plcomioctl(dev_t dev, u_long cmd, void *
break;
case TIOCSFLAGS:
- error = kauth_authorize_device_tty(l->l_cred,
- KAUTH_DEVICE_TTY_PRIVSET, tp);
- if (error)
- break;
sc->sc_swflags = *(int *)data;
break;
@@ -1085,6 +1275,8 @@ plcom_to_tiocm(struct plcom_softc *sc)
SET(ttybits, TIOCM_CTS);
if (ISSET(plcombits, PL01X_MSR_DSR))
SET(ttybits, TIOCM_DSR);
+ if (ISSET(plcombits, PL011_MSR_RI))
+ SET(ttybits, TIOCM_RI);
if (sc->sc_cr != 0)
SET(ttybits, TIOCM_LE);
@@ -1127,13 +1319,21 @@ plcomparam(struct tty *tp, struct termio
{
struct plcom_softc *sc =
device_lookup_private(&plcom_cd, PLCOMUNIT(tp->t_dev));
- int ospeed;
+ struct plcom_instance *pi = &sc->sc_pi;
+ int ospeed = -1;
u_char lcr;
if (PLCOM_ISALIVE(sc) == 0)
return EIO;
- ospeed = plcomspeed(t->c_ospeed, sc->sc_frequency);
+ switch (pi->pi_type) {
+ case PLCOM_TYPE_PL010:
+ ospeed = pl010comspeed(t->c_ospeed, sc->sc_frequency);
+ break;
+ case PLCOM_TYPE_PL011:
+ ospeed = pl011comspeed(t->c_ospeed, sc->sc_frequency);
+ break;
+ }
/* Check requested parameters. */
if (ospeed < 0)
@@ -1224,11 +1424,19 @@ plcomparam(struct tty *tp, struct termio
SET(sc->sc_mcr, sc->sc_mcr_dtr);
#endif
- sc->sc_dlbl = ospeed;
- sc->sc_dlbh = ospeed >> 8;
+ switch (pi->pi_type) {
+ case PLCOM_TYPE_PL010:
+ sc->sc_ratel = ospeed & 0xff;
+ sc->sc_rateh = (ospeed >> 8) & 0xff;
+ break;
+ case PLCOM_TYPE_PL011:
+ sc->sc_ratel = ospeed & ((1 << 6) - 1);
+ sc->sc_rateh = ospeed >> 6;
+ break;
+ }
/* And copy to tty. */
- tp->t_ispeed = 0;
+ tp->t_ispeed = t->c_ospeed;
tp->t_ospeed = t->c_ospeed;
tp->t_cflag = t->c_cflag;
@@ -1285,8 +1493,7 @@ plcomparam(struct tty *tp, struct termio
void
plcom_iflush(struct plcom_softc *sc)
{
- bus_space_tag_t iot = sc->sc_iot;
- bus_space_handle_t ioh = sc->sc_ioh;
+ struct plcom_instance *pi = &sc->sc_pi;
#ifdef DIAGNOSTIC
int reg;
#endif
@@ -1297,40 +1504,56 @@ plcom_iflush(struct plcom_softc *sc)
#endif
timo = 50000;
/* flush any pending I/O */
- while (! ISSET(bus_space_read_1(iot, ioh, plcom_fr), PL01X_FR_RXFE)
+ while (! ISSET(PREAD1(pi, PL01XCOM_FR), PL01X_FR_RXFE)
&& --timo)
#ifdef DIAGNOSTIC
reg =
#else
(void)
#endif
- bus_space_read_1(iot, ioh, plcom_dr);
+ PREAD1(pi, PL01XCOM_DR);
#ifdef DIAGNOSTIC
if (!timo)
- printf("%s: plcom_iflush timeout %02x\n", device_xname(sc->sc_dev),
- reg);
+ aprint_error_dev(sc->sc_dev, ": %s timeout %02x\n", __func__,
+ reg);
#endif
}
void
plcom_loadchannelregs(struct plcom_softc *sc)
{
- bus_space_tag_t iot = sc->sc_iot;
- bus_space_handle_t ioh = sc->sc_ioh;
+ struct plcom_instance *pi = &sc->sc_pi;
/* XXXXX necessary? */
plcom_iflush(sc);
- bus_space_write_1(iot, ioh, plcom_cr, 0);
-
- bus_space_write_1(iot, ioh, plcom_dlbl, sc->sc_dlbl);
- bus_space_write_1(iot, ioh, plcom_dlbh, sc->sc_dlbh);
- bus_space_write_1(iot, ioh, plcom_lcr, sc->sc_lcr);
- /* XXX device_unit() abuse */
- sc->sc_set_mcr(sc->sc_set_mcr_arg, device_unit(sc->sc_dev),
- sc->sc_mcr_active = sc->sc_mcr);
-
- bus_space_write_1(iot, ioh, plcom_cr, sc->sc_cr);
+ switch (pi->pi_type) {
+ case PLCOM_TYPE_PL010:
+ PWRITE1(pi, PL010COM_CR, 0);
+ PWRITE1(pi, PL010COM_DLBL, sc->sc_ratel);
+ PWRITE1(pi, PL010COM_DLBH, sc->sc_rateh);
+ PWRITE1(pi, PL010COM_LCR, sc->sc_lcr);
+
+ /* XXX device_unit() abuse */
+ if (sc->sc_set_mcr)
+ sc->sc_set_mcr(sc->sc_set_mcr_arg,
+ device_unit(sc->sc_dev),
+ sc->sc_mcr_active = sc->sc_mcr);
+
+ PWRITE1(pi, PL010COM_CR, sc->sc_cr);
+ break;
+
+ case PLCOM_TYPE_PL011:
+ PWRITE4(pi, PL011COM_CR, 0);
+ PWRITE1(pi, PL011COM_FBRD, sc->sc_ratel);
+ PWRITE4(pi, PL011COM_IBRD, sc->sc_rateh);
+ PWRITE1(pi, PL011COM_LCRH, sc->sc_lcr);
+ sc->sc_mcr_active = sc->sc_mcr;
+ CLR(sc->sc_cr, PL011_MCR(PL01X_MCR_RTS | PL01X_MCR_DTR));
+ SET(sc->sc_cr, PL011_MCR(sc->sc_mcr_active));
+ PWRITE4(pi, PL011COM_CR, sc->sc_cr);
+ break;
+ }
}
int
@@ -1373,6 +1596,8 @@ plcomhwiflow(struct tty *tp, int block)
void
plcom_hwiflow(struct plcom_softc *sc)
{
+ struct plcom_instance *pi = &sc->sc_pi;
+
if (sc->sc_mcr_rts == 0)
return;
@@ -1383,9 +1608,19 @@ plcom_hwiflow(struct plcom_softc *sc)
SET(sc->sc_mcr, sc->sc_mcr_rts);
SET(sc->sc_mcr_active, sc->sc_mcr_rts);
}
- /* XXX device_unit() abuse */
- sc->sc_set_mcr(sc->sc_set_mcr_arg, device_unit(sc->sc_dev),
- sc->sc_mcr_active);
+ switch (pi->pi_type) {
+ case PLCOM_TYPE_PL010:
+ if (sc->sc_set_mcr)
+ /* XXX device_unit() abuse */
+ sc->sc_set_mcr(sc->sc_set_mcr_arg,
+ device_unit(sc->sc_dev), sc->sc_mcr_active);
+ break;
+ case PLCOM_TYPE_PL011:
+ CLR(sc->sc_cr, PL011_MCR(PL01X_MCR_RTS | PL01X_MCR_DTR));
+ SET(sc->sc_cr, PL011_MCR(sc->sc_mcr_active));
+ PWRITE4(pi, PL011COM_CR, sc->sc_cr);
+ break;
+ }
}
@@ -1394,8 +1629,7 @@ plcomstart(struct tty *tp)
{
struct plcom_softc *sc =
device_lookup_private(&plcom_cd, PLCOMUNIT(tp->t_dev));
- bus_space_tag_t iot = sc->sc_iot;
- bus_space_handle_t ioh = sc->sc_ioh;
+ struct plcom_instance *pi = &sc->sc_pi;
int s;
if (PLCOM_ISALIVE(sc) == 0)
@@ -1428,9 +1662,19 @@ plcomstart(struct tty *tp)
sc->sc_tx_busy = 1;
/* Enable transmit completion interrupts if necessary. */
- if (!ISSET(sc->sc_cr, PL010_CR_TIE)) {
- SET(sc->sc_cr, PL010_CR_TIE);
- bus_space_write_1(iot, ioh, plcom_cr, sc->sc_cr);
+ switch (pi->pi_type) {
+ case PLCOM_TYPE_PL010:
+ if (!ISSET(sc->sc_cr, PL010_CR_TIE)) {
+ SET(sc->sc_cr, PL010_CR_TIE);
+ PWRITE1(pi, PL010COM_CR, sc->sc_cr);
+ }
+ break;
+ case PLCOM_TYPE_PL011:
+ if (!ISSET(sc->sc_imsc, PL011_INT_TX)) {
+ SET(sc->sc_imsc, PL011_INT_TX);
+ PWRITE4(pi, PL011COM_IMSC, sc->sc_imsc);
+ }
+ break;
}
/* Output the first chunk of the contiguous buffer. */
@@ -1440,7 +1684,7 @@ plcomstart(struct tty *tp)
n = sc->sc_tbc;
if (n > sc->sc_fifolen)
n = sc->sc_fifolen;
- bus_space_write_multi_1(iot, ioh, plcom_dr, sc->sc_tba, n);
+ PWRITEM1(pi, PL01XCOM_DR, sc->sc_tba, n);
sc->sc_tbc -= n;
sc->sc_tba += n;
}
@@ -1494,6 +1738,7 @@ integrate void
plcom_rxsoft(struct plcom_softc *sc, struct tty *tp)
{
int (*rint) (int, struct tty *) = tp->t_linesw->l_rint;
+ struct plcom_instance *pi = &sc->sc_pi;
u_char *get, *end;
u_int cc, scc;
u_char rsr;
@@ -1568,8 +1813,18 @@ plcom_rxsoft(struct plcom_softc *sc, str
if (cc >= sc->sc_r_lowat) {
if (ISSET(sc->sc_rx_flags, RX_IBUF_OVERFLOWED)) {
CLR(sc->sc_rx_flags, RX_IBUF_OVERFLOWED);
- SET(sc->sc_cr, PL010_CR_RIE | PL010_CR_RTIE);
- bus_space_write_1(sc->sc_iot, sc->sc_ioh, plcom_cr, sc->sc_cr);
+ switch (pi->pi_type) {
+ case PLCOM_TYPE_PL010:
+ SET(sc->sc_cr,
+ PL010_CR_RIE | PL010_CR_RTIE);
+ PWRITE1(pi, PL010COM_CR, sc->sc_cr);
+ break;
+ case PLCOM_TYPE_PL011:
+ SET(sc->sc_imsc,
+ PL011_INT_RX | PL011_INT_RT);
+ PWRITE4(pi, PL011COM_IMSC, sc->sc_imsc);
+ break;
+ }
}
if (ISSET(sc->sc_rx_flags, RX_IBUF_BLOCKED)) {
CLR(sc->sc_rx_flags, RX_IBUF_BLOCKED);
@@ -1653,22 +1908,46 @@ plcomsoft(void *arg)
}
}
+bool
+plcom_intstatus(struct plcom_instance *pi, u_int *istatus)
+{
+ bool ret = false;
+ u_int stat = 0;
+
+ switch (pi->pi_type) {
+ case PLCOM_TYPE_PL010:
+ stat = PREAD1(pi, PL010COM_IIR);
+ ret = ISSET(stat, PL010_IIR_IMASK);
+ break;
+ case PLCOM_TYPE_PL011:
+ stat = PREAD4(pi, PL011COM_MIS);
+ ret = ISSET(stat, PL011_INT_ALLMASK);
+ break;
+ }
+ *istatus = stat;
+
+ return ret;
+}
+
int
plcomintr(void *arg)
{
struct plcom_softc *sc = arg;
- bus_space_tag_t iot = sc->sc_iot;
- bus_space_handle_t ioh = sc->sc_ioh;
+ struct plcom_instance *pi = &sc->sc_pi;
u_char *put, *end;
u_int cc;
- u_char rsr, iir;
+ u_int istatus = 0;
+ u_char rsr;
+ bool intr = false;
+
+ PLCOM_BARRIER(pi, BR | BW);
if (PLCOM_ISALIVE(sc) == 0)
return 0;
mutex_spin_enter(&sc->sc_lock);
- iir = bus_space_read_1(iot, ioh, plcom_iir);
- if (! ISSET(iir, PL010_IIR_IMASK)) {
+ intr = plcom_intstatus(pi, &istatus);
+ if (!intr) {
mutex_spin_exit(&sc->sc_lock);
return 0;
}
@@ -1678,21 +1957,21 @@ plcomintr(void *arg)
cc = sc->sc_rbavail;
do {
- u_char msr, delta, fr;
+ u_int msr = 0, delta, fr;
+ bool rxintr = false, txintr = false, msintr;
- fr = bus_space_read_1(iot, ioh, plcom_fr);
+ /* don't need RI here*/
+ fr = PREAD1(pi, PL01XCOM_FR);
if (!ISSET(fr, PL01X_FR_RXFE) &&
!ISSET(sc->sc_rx_flags, RX_IBUF_OVERFLOWED)) {
while (cc > 0) {
int cn_trapped = 0;
- put[0] = bus_space_read_1(iot, ioh,
- plcom_dr);
- rsr = bus_space_read_1(iot, ioh, plcom_rsr);
+ put[0] = PREAD1(pi, PL01XCOM_DR);
+ rsr = PREAD1(pi, PL01XCOM_RSR);
/* Clear any error status. */
if (ISSET(rsr, PL01X_RSR_ERROR))
- bus_space_write_1(iot, ioh, plcom_ecr,
- 0);
+ PWRITE1(pi, PL01XCOM_ECR, 0);
if (ISSET(rsr, PL01X_RSR_BE)) {
cn_trapped = 0;
cn_check_magic(sc->sc_tty->t_dev,
@@ -1710,11 +1989,10 @@ plcomintr(void *arg)
put[1] = rsr;
cn_trapped = 0;
- cn_check_magic(sc->sc_tty->t_dev,
- put[0], plcom_cnm_state);
+ cn_check_magic(sc->sc_tty->t_dev, put[0],
+ plcom_cnm_state);
if (cn_trapped) {
- fr = bus_space_read_1(iot, ioh,
- plcom_fr);
+ fr = PREAD1(pi, PL01XCOM_FR);
if (ISSET(fr, PL01X_FR_RXFE))
break;
@@ -1725,7 +2003,8 @@ plcomintr(void *arg)
put = sc->sc_rbuf;
cc--;
- fr = bus_space_read_1(iot, ioh, plcom_fr);
+ /* don't need RI here*/
+ fr = PREAD1(pi, PL01XCOM_FR);
if (ISSET(fr, PL01X_FR_RXFE))
break;
}
@@ -1757,26 +2036,68 @@ plcomintr(void *arg)
*/
if (!cc) {
SET(sc->sc_rx_flags, RX_IBUF_OVERFLOWED);
- CLR(sc->sc_cr, PL010_CR_RIE | PL010_CR_RTIE);
- bus_space_write_1(iot, ioh, plcom_cr,
- sc->sc_cr);
+ switch (pi->pi_type) {
+ case PLCOM_TYPE_PL010:
+ CLR(sc->sc_cr,
+ PL010_CR_RIE | PL010_CR_RTIE);
+ PWRITE1(pi, PL010COM_CR, sc->sc_cr);
+ break;
+ case PLCOM_TYPE_PL011:
+ CLR(sc->sc_imsc,
+ PL011_INT_RT | PL011_INT_RX);
+ PWRITE4(pi, PL011COM_IMSC, sc->sc_imsc);
+ break;
+ }
}
} else {
- if (ISSET(iir, PL010_IIR_RIS)) {
- bus_space_write_1(iot, ioh, plcom_cr, 0);
- delay(10);
- bus_space_write_1(iot, ioh, plcom_cr,
- sc->sc_cr);
- continue;
+ switch (pi->pi_type) {
+ case PLCOM_TYPE_PL010:
+ rxintr = ISSET(istatus, PL010_IIR_RIS);
+ if (rxintr) {
+ PWRITE1(pi, PL010COM_CR, 0);
+ delay(10);
+ PWRITE1(pi, PL010COM_CR, sc->sc_cr);
+ continue;
+ }
+ break;
+ case PLCOM_TYPE_PL011:
+ rxintr = ISSET(istatus, PL011_INT_RX);
+ if (rxintr) {
+ PWRITE4(pi, PL011COM_CR, 0);
+ delay(10);
+ PWRITE4(pi, PL011COM_CR, sc->sc_cr);
+ continue;
+ }
+ break;
}
}
- msr = bus_space_read_1(iot, ioh, plcom_fr);
+ switch (pi->pi_type) {
+ case PLCOM_TYPE_PL010:
+ msr = PREAD1(pi, PL01XCOM_FR);
+ break;
+ case PLCOM_TYPE_PL011:
+ msr = PREAD4(pi, PL01XCOM_FR);
+ break;
+ }
delta = msr ^ sc->sc_msr;
sc->sc_msr = msr;
+
/* Clear any pending modem status interrupt. */
- if (iir & PL010_IIR_MIS)
- bus_space_write_1(iot, ioh, plcom_icr, 0);
+ switch (pi->pi_type) {
+ case PLCOM_TYPE_PL010:
+ msintr = ISSET(istatus, PL010_IIR_MIS);
+ if (msintr) {
+ PWRITE1(pi, PL010COM_ICR, 0);
+ }
+ break;
+ case PLCOM_TYPE_PL011:
+ msintr = ISSET(istatus, PL011_INT_MSMASK);
+ if (msintr) {
+ PWRITE4(pi, PL011COM_ICR, PL011_INT_MSMASK);
+ }
+ break;
+ }
/*
* Pulse-per-second (PSS) signals on edge of DCD?
* Process these even if line discipline is ignoring DCD.
@@ -1847,14 +2168,24 @@ plcomintr(void *arg)
/*
* Done handling any receive interrupts. See if data
- * can be * transmitted as well. Schedule tx done
- * event if no data left * and tty was marked busy.
+ * can be transmitted as well. Schedule tx done
+ * event if no data left and tty was marked busy.
*/
- if (ISSET(iir, PL010_IIR_TIS)) {
+
+ switch (pi->pi_type) {
+ case PLCOM_TYPE_PL010:
+ txintr = ISSET(istatus, PL010_IIR_TIS);
+ break;
+ case PLCOM_TYPE_PL011:
+ txintr = ISSET(istatus, PL011_INT_TX);
+ break;
+ }
+ if (txintr) {
/*
* If we've delayed a parameter change, do it
* now, and restart * output.
*/
+// PWRITE4(pi, PL011COM_ICR, PL011_INT_TX);
if (sc->sc_heldchange) {
plcom_loadchannelregs(sc);
sc->sc_heldchange = 0;
@@ -1872,19 +2203,29 @@ plcomintr(void *arg)
n = sc->sc_tbc;
if (n > sc->sc_fifolen)
n = sc->sc_fifolen;
- bus_space_write_multi_1(iot, ioh, plcom_dr,
- sc->sc_tba, n);
+ PWRITEM1(pi, PL01XCOM_DR, sc->sc_tba, n);
sc->sc_tbc -= n;
sc->sc_tba += n;
} else {
/*
- * Disable transmit plcompletion
+ * Disable transmit completion
* interrupts if necessary.
*/
- if (ISSET(sc->sc_cr, PL010_CR_TIE)) {
- CLR(sc->sc_cr, PL010_CR_TIE);
- bus_space_write_1(iot, ioh, plcom_cr,
- sc->sc_cr);
+ switch (pi->pi_type) {
+ case PLCOM_TYPE_PL010:
+ if (ISSET(sc->sc_cr, PL010_CR_TIE)) {
+ CLR(sc->sc_cr, PL010_CR_TIE);
+ PWRITE1(pi, PL010COM_CR,
+ sc->sc_cr);
+ }
+ break;
+ case PLCOM_TYPE_PL011:
+ if (ISSET(sc->sc_imsc, PL011_INT_TX)) {
+ CLR(sc->sc_imsc, PL011_INT_TX);
+ PWRITE4(pi, PL011COM_IMSC,
+ sc->sc_imsc);
+ }
+ break;
}
if (sc->sc_tx_busy) {
sc->sc_tx_busy = 0;
@@ -1892,8 +2233,8 @@ plcomintr(void *arg)
}
}
}
- } while (ISSET((iir = bus_space_read_1(iot, ioh, plcom_iir)),
- PL010_IIR_IMASK));
+
+ } while (plcom_intstatus(pi, &istatus));
mutex_spin_exit(&sc->sc_lock);
@@ -1901,9 +2242,11 @@ plcomintr(void *arg)
softint_schedule(sc->sc_si);
#ifdef RND_COM
- rnd_add_uint32(&sc->rnd_source, iir | rsr);
+ rnd_add_uint32(&sc->rnd_source, istatus | rsr);
#endif
+ PLCOM_BARRIER(pi, BR | BW);
+
return 1;
}
@@ -1921,7 +2264,7 @@ static int plcom_readahead[MAX_READAHEAD
static int plcom_readaheadcount = 0;
int
-plcom_common_getc(dev_t dev, bus_space_tag_t iot, bus_space_handle_t ioh)
+plcom_common_getc(dev_t dev, struct plcom_instance *pi)
{
int s = splserial();
u_char stat, c;
@@ -1940,11 +2283,10 @@ plcom_common_getc(dev_t dev, bus_space_t
}
/* block until a character becomes available */
- while (ISSET(stat = bus_space_read_1(iot, ioh, plcom_fr), PL01X_FR_RXFE))
+ while (ISSET(stat = PREAD1(pi, PL01XCOM_FR), PL01X_FR_RXFE))
;
- c = bus_space_read_1(iot, ioh, plcom_dr);
- stat = bus_space_read_1(iot, ioh, plcom_iir);
+ c = PREAD1(pi, PL01XCOM_DR);
{
int cn_trapped = 0; /* unused */
#ifdef DDB
@@ -1958,33 +2300,31 @@ plcom_common_getc(dev_t dev, bus_space_t
}
void
-plcom_common_putc(dev_t dev, bus_space_tag_t iot, bus_space_handle_t ioh,
- int c)
+plcom_common_putc(dev_t dev, struct plcom_instance *pi, int c)
{
int s = splserial();
int timo;
int cin, stat;
if (plcom_readaheadcount < MAX_READAHEAD
- && !ISSET(stat = bus_space_read_1(iot, ioh, plcom_fr), PL01X_FR_RXFE)) {
+ && !ISSET(stat = PREAD1(pi, PL01XCOM_FR), PL01X_FR_RXFE)) {
int cn_trapped = 0;
- cin = bus_space_read_1(iot, ioh, plcom_dr);
- stat = bus_space_read_1(iot, ioh, plcom_iir);
+ cin = PREAD1(pi, PL01XCOM_DR);
cn_check_magic(dev, cin, plcom_cnm_state);
plcom_readahead[plcom_readaheadcount++] = cin;
}
/* wait for any pending transmission to finish */
timo = 150000;
- while (!ISSET(bus_space_read_1(iot, ioh, plcom_fr), PL01X_FR_TXFE) && --timo)
+ while (!ISSET(PREAD1(pi, PL01XCOM_FR), PL01X_FR_TXFE) && --timo)
continue;
- bus_space_write_1(iot, ioh, plcom_dr, c);
- PLCOM_BARRIER(iot, ioh, BR | BW);
+ PWRITE1(pi, PL01XCOM_DR, c);
+ PLCOM_BARRIER(pi, BR | BW);
/* wait for this transmission to complete */
timo = 1500000;
- while (!ISSET(bus_space_read_1(iot, ioh, plcom_fr), PL01X_FR_TXFE) && --timo)
+ while (!ISSET(PREAD1(pi, PL01XCOM_FR), PL01X_FR_TXFE) && --timo)
continue;
splx(s);
@@ -1994,20 +2334,49 @@ plcom_common_putc(dev_t dev, bus_space_t
* Initialize UART for use as console or KGDB line.
*/
int
-plcominit(bus_space_tag_t iot, bus_addr_t iobase, int rate, int frequency,
- tcflag_t cflag, bus_space_handle_t *iohp)
+plcominit(struct plcom_instance *pi, int rate, int frequency, tcflag_t cflag)
{
- bus_space_handle_t ioh;
+ u_char lcr;
- if (bus_space_map(iot, iobase, PLCOM_UART_SIZE, 0, &ioh))
+ switch (pi->pi_type) {
+ case PLCOM_TYPE_PL010:
+ if (pi->pi_size == 0)
+ pi->pi_size = PL010COM_UART_SIZE;
+ break;
+ case PLCOM_TYPE_PL011:
+ if (pi->pi_size == 0)
+ pi->pi_size = PL011COM_UART_SIZE;
+ break;
+ default:
+ panic("Unknown plcom type");
+ }
+
+ if (bus_space_map(pi->pi_iot, pi->pi_iobase, pi->pi_size, 0,
+ &pi->pi_ioh))
return ENOMEM; /* ??? */
- rate = plcomspeed(rate, frequency);
- bus_space_write_1(iot, ioh, plcom_cr, 0);
- bus_space_write_1(iot, ioh, plcom_dlbl, rate);
- bus_space_write_1(iot, ioh, plcom_dlbh, rate >> 8);
- bus_space_write_1(iot, ioh, plcom_lcr, cflag2lcr(cflag) | PL01X_LCR_FEN);
- bus_space_write_1(iot, ioh, plcom_cr, PL01X_CR_UARTEN);
+ lcr = cflag2lcr(cflag) | PL01X_LCR_FEN;
+ switch (pi->pi_type) {
+ case PLCOM_TYPE_PL010:
+ PWRITE1(pi, PL010COM_CR, 0);
+
+ rate = pl010comspeed(rate, frequency);
+ PWRITE1(pi, PL010COM_DLBL, (rate & 0xff));
+ PWRITE1(pi, PL010COM_DLBH, ((rate >> 8) & 0xff));
+ PWRITE1(pi, PL010COM_LCR, lcr);
+ PWRITE1(pi, PL010COM_CR, PL01X_CR_UARTEN);
+ break;
+ case PLCOM_TYPE_PL011:
+ PWRITE4(pi, PL011COM_CR, 0);
+
+ rate = pl011comspeed(rate, frequency);
+ PWRITE1(pi, PL011COM_FBRD, rate & ((1 << 6) - 1));
+ PWRITE4(pi, PL011COM_IBRD, rate >> 6);
+ PWRITE1(pi, PL011COM_LCRH, lcr);
+ PWRITE4(pi, PL011COM_CR,
+ PL01X_CR_UARTEN | PL011_CR_RXE | PL011_CR_TXE);
+ break;
+ }
#if 0
/* Ought to do something like this, but we have no sc to
@@ -2017,7 +2386,6 @@ plcominit(bus_space_tag_t iot, bus_addr_
PL01X_MCR_DTR | PL01X_MCR_RTS);
#endif
- *iohp = ioh;
return 0;
}
@@ -2029,14 +2397,15 @@ struct consdev plcomcons = {
NULL, NULL, NODEV, CN_NORMAL
};
-
int
-plcomcnattach(bus_space_tag_t iot, bus_addr_t iobase, int rate, int frequency,
+plcomcnattach(struct plcom_instance *pi, int rate, int frequency,
tcflag_t cflag, int unit)
{
int res;
- res = plcominit(iot, iobase, rate, frequency, cflag, &plcomconsioh);
+ plcomcons_info = *pi;
+
+ res = plcominit(&plcomcons_info, rate, frequency, cflag);
if (res)
return res;
@@ -2044,7 +2413,6 @@ plcomcnattach(bus_space_tag_t iot, bus_a
cn_init_magic(&plcom_cnm_state);
cn_set_magic("\047\001"); /* default magic is BREAK */
- plcomconstag = iot;
plcomconsunit = unit;
plcomconsrate = rate;
plcomconscflag = cflag;
@@ -2055,8 +2423,10 @@ plcomcnattach(bus_space_tag_t iot, bus_a
void
plcomcndetach(void)
{
- bus_space_unmap(plcomconstag, plcomconsioh, PLCOM_UART_SIZE);
- plcomconstag = NULL;
+
+ bus_space_unmap(plcomcons_info.pi_iot, plcomcons_info.pi_ioh,
+ plcomcons_info.pi_size);
+ plcomcons_info.pi_iot = NULL;
cn_tab = NULL;
}
@@ -2064,7 +2434,7 @@ plcomcndetach(void)
int
plcomcngetc(dev_t dev)
{
- return plcom_common_getc(dev, plcomconstag, plcomconsioh);
+ return plcom_common_getc(dev, &plcomcons_info);
}
/*
@@ -2073,7 +2443,7 @@ plcomcngetc(dev_t dev)
void
plcomcnputc(dev_t dev, int c)
{
- plcom_common_putc(dev, plcomconstag, plcomconsioh, c);
+ plcom_common_putc(dev, &plcomcons_info, c);
}
void
@@ -2084,23 +2454,25 @@ plcomcnpollc(dev_t dev, int on)
#ifdef KGDB
int
-plcom_kgdb_attach(bus_space_tag_t iot, bus_addr_t iobase, int rate,
- int frequency, tcflag_t cflag, int unit)
+plcom_kgdb_attach(struct plcom_instance *pi, int rate, int frequency,
+ tcflag_t cflag, int unit)
{
int res;
- if (iot == plcomconstag && iobase == plcomconsunit)
+ if (pi->pi_iot == plcomcons_info.pi_iot &&
+ pi->pi_iobase == plcomcons_info.pi_iobase)
return EBUSY; /* cannot share with console */
- res = plcominit(iot, iobase, rate, frequency, cflag, &plcom_kgdb_ioh);
+ res = plcominit(pi, rate, frequency, cflag);
if (res)
return res;
kgdb_attach(plcom_kgdb_getc, plcom_kgdb_putc, NULL);
kgdb_dev = 123; /* unneeded, only to satisfy some tests */
- plcom_kgdb_iot = iot;
- plcom_kgdb_unit = unit;
+ plcomkgdb_info.pi_iot = pi->pi_iot;
+ plcomkgdb_info.pi_ioh = pi->pi_ioh;
+ plcomkgdb_info.pi_iobase = pi->pi_iobase;
return 0;
}
@@ -2109,6 +2481,7 @@ plcom_kgdb_attach(bus_space_tag_t iot, b
int
plcom_kgdb_getc(void *arg)
{
+
return plcom_common_getc(NODEV, plcom_kgdb_iot, plcom_kgdb_ioh);
}
@@ -2123,17 +2496,19 @@ plcom_kgdb_putc(void *arg, int c)
/* helper function to identify the plcom ports used by
console or KGDB (and not yet autoconf attached) */
int
-plcom_is_console(bus_space_tag_t iot, int unit,
+plcom_is_console(bus_space_tag_t iot, bus_addr_t iobase,
bus_space_handle_t *ioh)
{
bus_space_handle_t help;
if (!plcomconsattached &&
- iot == plcomconstag && unit == plcomconsunit)
- help = plcomconsioh;
+ bus_space_is_equal(iot, plcomcons_info.pi_iot) &&
+ iobase == plcomcons_info.pi_iobase)
+ help = plcomcons_info.pi_ioh;
#ifdef KGDB
else if (!plcom_kgdb_attached &&
- iot == plcom_kgdb_iot && unit == plcom_kgdb_unit)
+ bus_space_is_equal(iot, plcomkgdb_info.pi_iot) &&
+ iobase == plcomkgdb_info.pi_iobase)
help = plcom_kgdb_ioh;
#endif
else
Index: src/sys/arch/evbarm/dev/plcomreg.h
diff -u src/sys/arch/evbarm/dev/plcomreg.h:1.3 src/sys/arch/evbarm/dev/plcomreg.h:1.4
--- src/sys/arch/evbarm/dev/plcomreg.h:1.3 Mon May 14 19:40:06 2012
+++ src/sys/arch/evbarm/dev/plcomreg.h Wed Jul 25 07:26:17 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: plcomreg.h,v 1.3 2012/05/14 19:40:06 skrll Exp $ */
+/* $NetBSD: plcomreg.h,v 1.4 2012/07/25 07:26:17 skrll Exp $ */
/*-
* Copyright (c) 2001 ARM Ltd
@@ -52,11 +52,12 @@
#define PL01X_CR_UARTEN 0x0001 /* Uart enable */
/* interrupt identification register */
-#define PL010_IIR_IMASK 0x0f
#define PL010_IIR_RTIS 0x08
#define PL010_IIR_TIS 0x04
#define PL010_IIR_RIS 0x02
#define PL010_IIR_MIS 0x01
+#define PL010_IIR_IMASK \
+ (PL010_IIR_RTIS | PL010_IIR_TIS | PL010_IIR_RIS | PL010_IIR_MIS)
/* line control register */
#define PL011_LCR_SPS 0x80 /* Stick parity select */
@@ -77,16 +78,18 @@
/* modem control register */
#define PL01X_MCR_RTS 0x02 /* Request To Send */
#define PL01X_MCR_DTR 0x01 /* Data Terminal Ready */
+#define PL011_MCR(mcr) ((mcr) << 10) /* MCR to CR bit values for PL011 */
/* receive status register */
#define PL01X_RSR_OE 0x08 /* Overrun Error */
#define PL01X_RSR_BE 0x04 /* Break */
#define PL01X_RSR_PE 0x02 /* Parity Error */
#define PL01X_RSR_FE 0x01 /* Framing Error */
-#define PL01X_RSR_ERROR (PL01X_RSR_OE | PL01X_RSR_BE | PL01X_RSR_PE | PL01X_RSR_FE)
+#define PL01X_RSR_ERROR \
+ (PL01X_RSR_OE | PL01X_RSR_BE | PL01X_RSR_PE | PL01X_RSR_FE)
/* flag register */
-#define PL01X_FR_RI 0x100 /* Ring Indicator */
+#define PL011_FR_RI 0x100 /* Ring Indicator */
#define PL01X_FR_TXFE 0x080 /* Transmit fifo empty */
#define PL01X_FR_RXFF 0x040 /* Recive fifo full */
#define PL01X_FR_TXFF 0x020 /* Transmit fifo full */
@@ -101,6 +104,7 @@
#define PL01X_MSR_DCD PL01X_FR_DCD
#define PL01X_MSR_DSR PL01X_FR_DSR
#define PL01X_MSR_CTS PL01X_FR_CTS
+#define PL011_MSR_RI PL011_FR_RI
/* All interrupt status/clear registers */
#define PL011_INT_OE 0x400
@@ -114,6 +118,12 @@
#define PL011_INT_DCD 0x004
#define PL011_INT_CTS 0x002
#define PL011_INT_RIR 0x001
+#define PL011_INT_MSMASK \
+ (PL011_INT_DSR | PL011_INT_DCD | PL011_INT_CTS | PL011_INT_RIR)
+
+#define PL011_INT_ALLMASK \
+ (PL011_INT_RT | PL011_INT_TX | PL011_INT_RX | PL011_INT_MSMASK)
+
/* DMA control registers */
#define PL011_DMA_ONERR 0x4
@@ -121,17 +131,27 @@
#define PL011_DMA_RXE 0x1
/* Register offsets */
-#define plcom_dr 0x00
-#define plcom_rsr 0x04
-#define plcom_ecr 0x04
-#define plcom_lcr 0x08
-#define plcom_dlbh 0x0c
-#define plcom_dlbl 0x10
-#define plcom_cr 0x14
-#define plcom_fr 0x18
-#define plcom_iir 0x1c
-#define plcom_icr 0x1c
-#define plcom_ilpr 0x20
+#define PL01XCOM_DR 0x00 /* Data Register */
+#define PL01XCOM_RSR 0x04 /* Receive status register */
+#define PL01XCOM_ECR 0x04 /* Error clear register - same as RSR */
+#define PL010COM_LCR 0x08 /* Line Control Register */
+#define PL010COM_DLBH 0x0c
+#define PL010COM_DLBL 0x10
+#define PL010COM_CR 0x14
+#define PL01XCOM_FR 0x18 /* Flag Register */
+#define PL010COM_IIR 0x1c
+#define PL010COM_ICR 0x1c
+#define PL01XCOM_ILPR 0x20 /* IrDA low-power control register */
+#define PL011COM_IBRD 0x24 /* Integer baud rate divisor register */
+#define PL011COM_FBRD 0x28 /* Fractional baud rate divisor register */
+#define PL011COM_LCRH 0x2c /* Line control register */
+#define PL011COM_CR 0x30 /* Control register */
+#define PL011COM_IFLS 0x34 /* Interrupt FIFO level select register */
+#define PL011COM_IMSC 0x38 /* Interrupt mask set/clear register */
+#define PL011COM_RIS 0x3c /* Raw interrupt status register */
+#define PL011COM_MIS 0x40 /* Masked interrupt status register */
+#define PL011COM_ICR 0x44 /* Interrupt clear register register */
+#define PL011COM_DMACR 0x48 /* DMA control register register */
-/* IFPGA specific */
-#define PLCOM_UART_SIZE 0x24
+#define PL010COM_UART_SIZE 0x100
+#define PL011COM_UART_SIZE 0x1000
Index: src/sys/arch/evbarm/dev/plcomvar.h
diff -u src/sys/arch/evbarm/dev/plcomvar.h:1.10 src/sys/arch/evbarm/dev/plcomvar.h:1.11
--- src/sys/arch/evbarm/dev/plcomvar.h:1.10 Sun May 20 10:28:44 2012
+++ src/sys/arch/evbarm/dev/plcomvar.h Wed Jul 25 07:26:18 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: plcomvar.h,v 1.10 2012/05/20 10:28:44 skrll Exp $ */
+/* $NetBSD: plcomvar.h,v 1.11 2012/07/25 07:26:18 skrll Exp $ */
/*
* Copyright (c) 1996 Christopher G. Demetriou. All rights reserved.
@@ -44,14 +44,16 @@
#include <sys/timepps.h>
#include <sys/simplelock.h>
-int plcomcnattach (bus_space_tag_t, bus_addr_t, int, int, tcflag_t, int);
+struct plcom_instance;
+
+int plcomcnattach (struct plcom_instance *, int, int, tcflag_t, int);
void plcomcndetach (void);
#ifdef KGDB
-int plcom_kgdb_attach (bus_space_tag_t, bus_addr_t, int, int, tcflag_t);
+int plcom_kgdb_attach (struct plcom_instance *, int, int, tcflag_t);
#endif
-int plcom_is_console (bus_space_tag_t, int, bus_space_handle_t *);
+int plcom_is_console (bus_space_tag_t, bus_addr_t, bus_space_handle_t *);
/* Hardware flag masks */
#define PLCOM_HW_NOIEN 0x01
@@ -66,18 +68,43 @@ int plcom_is_console (bus_space_tag_t,
/* Buffer size for character buffer */
#define PLCOM_RING_SIZE 2048
+struct plcom_instance {
+ u_int pi_type;
+#define PLCOM_TYPE_PL010 0
+#define PLCOM_TYPE_PL011 1
+
+ uint32_t pi_flags; /* flags for this PLCOM */
+#define PLC_FLAG_USE_DMA 0x0001
+#define PLC_FLAG_32BIT_ACCESS 0x0002
+
+ void *pi_cookie;
+
+ bus_space_tag_t pi_iot;
+ bus_space_handle_t pi_ioh;
+ bus_addr_t pi_iobase;
+ bus_addr_t pi_size;
+ struct plcom_registers *pi_regs;
+};
+
+struct plcomcons_info {
+ int rate;
+ int frequency;
+ int type;
+
+ tcflag_t cflag;
+};
+
struct plcom_softc {
device_t sc_dev;
- void *sc_si;
+
struct tty *sc_tty;
+ void *sc_si;
struct callout sc_diag_callout;
- bus_addr_t sc_iounit;
- int sc_frequency;
+ int sc_frequency;
- bus_space_tag_t sc_iot;
- bus_space_handle_t sc_ioh;
+ struct plcom_instance sc_pi;
u_int sc_overflows,
sc_floods,
@@ -112,12 +139,13 @@ struct plcom_softc {
sc_rx_ready;
volatile u_char sc_heldchange;
- volatile u_char sc_msr, sc_msr_delta, sc_msr_mask, sc_mcr,
- sc_mcr_active, sc_lcr, sc_cr, sc_dlbl, sc_dlbh;
+ volatile u_int sc_cr, sc_ratel, sc_rateh, sc_imsc;
+ volatile u_int sc_msr, sc_msr_delta, sc_msr_mask;
+ volatile u_char sc_mcr, sc_mcr_active, sc_lcr;
u_char sc_mcr_dtr, sc_mcr_rts, sc_msr_cts, sc_msr_dcd;
u_int sc_fifo;
- /* Support routine to program mcr lines, if present. */
+ /* Support routine to program mcr lines for PL010, if present. */
void (*sc_set_mcr)(void *, int, u_int);
void *sc_set_mcr_arg;
@@ -139,7 +167,9 @@ struct plcom_softc {
kmutex_t sc_lock;
};
+#if 0
int plcomprobe1 (bus_space_tag_t, bus_space_handle_t);
+#endif
int plcomintr (void *);
void plcom_attach_subr (struct plcom_softc *);
int plcom_detach (device_t, int);
Index: src/sys/arch/evbarm/ifpga/ifpgareg.h
diff -u src/sys/arch/evbarm/ifpga/ifpgareg.h:1.3 src/sys/arch/evbarm/ifpga/ifpgareg.h:1.4
--- src/sys/arch/evbarm/ifpga/ifpgareg.h:1.3 Sun Dec 11 12:17:09 2005
+++ src/sys/arch/evbarm/ifpga/ifpgareg.h Wed Jul 25 07:26:18 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: ifpgareg.h,v 1.3 2005/12/11 12:17:09 christos Exp $ */
+/* $NetBSD: ifpgareg.h,v 1.4 2012/07/25 07:26:18 skrll Exp $ */
/*
* Copyright (c) 2001 ARM Ltd
@@ -32,6 +32,7 @@
/* System clock defaults. */
#define IFPGA_UART_CLK 14745600 /* Uart REFCLK freq */
+#define IFPGA_UART_SIZE 0x24
/*
* IFPGA registers
Index: src/sys/arch/evbarm/ifpga/plcom_ifpga.c
diff -u src/sys/arch/evbarm/ifpga/plcom_ifpga.c:1.13 src/sys/arch/evbarm/ifpga/plcom_ifpga.c:1.14
--- src/sys/arch/evbarm/ifpga/plcom_ifpga.c:1.13 Sun May 20 10:28:44 2012
+++ src/sys/arch/evbarm/ifpga/plcom_ifpga.c Wed Jul 25 07:26:18 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: plcom_ifpga.c,v 1.13 2012/05/20 10:28:44 skrll Exp $ */
+/* $NetBSD: plcom_ifpga.c,v 1.14 2012/07/25 07:26:18 skrll Exp $ */
/*
* Copyright (c) 2001 ARM Ltd
@@ -32,7 +32,7 @@
/* Interface to plcom (PL010) serial driver. */
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: plcom_ifpga.c,v 1.13 2012/05/20 10:28:44 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: plcom_ifpga.c,v 1.14 2012/07/25 07:26:18 skrll Exp $");
#include <sys/types.h>
#include <sys/device.h>
@@ -75,24 +75,27 @@ plcom_ifpga_attach(device_t parent, devi
isc->sc_iot = ifa->ifa_iot;
isc->sc_ioh = ifa->ifa_sc_ioh;
+
sc->sc_dev = self;
- sc->sc_iounit = device_unit(sc->sc_dev);
+ sc->sc_pi.pi_type = PLCOM_TYPE_PL010;
+ sc->sc_pi.pi_iot = ifa->ifa_iot;
+ sc->sc_pi.pi_iobase = ifa->ifa_addr;
+ sc->sc_pi.pi_size = IFPGA_UART_SIZE;
sc->sc_frequency = IFPGA_UART_CLK;
- sc->sc_iot = ifa->ifa_iot;
sc->sc_hwflags = 0;
sc->sc_swflags = 0;
sc->sc_set_mcr = plcom_ifpga_set_mcr;
sc->sc_set_mcr_arg = (void *)isc;
- if (bus_space_map(ifa->ifa_iot, ifa->ifa_addr, PLCOM_UART_SIZE, 0,
- &sc->sc_ioh)) {
+ if (bus_space_map(ifa->ifa_iot, ifa->ifa_addr, IFPGA_UART_SIZE, 0,
+ &sc->sc_pi.pi_ioh)) {
printf("%s: unable to map device\n", device_xname(sc->sc_dev));
return;
}
plcom_attach_subr(sc);
- isc->sc_ih = ifpga_intr_establish(ifa->ifa_irq, IPL_SERIAL, plcomintr,
- sc);
+ isc->sc_ih = ifpga_intr_establish(ifa->ifa_irq, IPL_SERIAL,
+ plcomintr, sc);
if (isc->sc_ih == NULL)
panic("%s: cannot install interrupt handler",
device_xname(sc->sc_dev));
Index: src/sys/arch/evbarm/integrator/integrator_machdep.c
diff -u src/sys/arch/evbarm/integrator/integrator_machdep.c:1.68 src/sys/arch/evbarm/integrator/integrator_machdep.c:1.69
--- src/sys/arch/evbarm/integrator/integrator_machdep.c:1.68 Fri Jul 1 20:39:34 2011
+++ src/sys/arch/evbarm/integrator/integrator_machdep.c Wed Jul 25 07:26:18 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: integrator_machdep.c,v 1.68 2011/07/01 20:39:34 dyoung Exp $ */
+/* $NetBSD: integrator_machdep.c,v 1.69 2012/07/25 07:26:18 skrll Exp $ */
/*
* Copyright (c) 2001,2002 ARM Ltd
@@ -68,7 +68,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: integrator_machdep.c,v 1.68 2011/07/01 20:39:34 dyoung Exp $");
+__KERNEL_RCSID(0, "$NetBSD: integrator_machdep.c,v 1.69 2012/07/25 07:26:18 skrll Exp $");
#include "opt_ddb.h"
#include "opt_pmap_debug.h"
@@ -383,9 +383,6 @@ initarm(void *arg)
psize_t memsize;
vm_offset_t physical_freestart;
vm_offset_t physical_freeend;
-#if NPLCOM > 0 && defined(PLCONSOLE)
- static struct bus_space plcom_bus_space;
-#endif
/*
* Heads up ... Setup the CPU / MMU / TLB functions
@@ -402,13 +399,29 @@ initarm(void *arg)
*/
if (PLCOMCNUNIT == 0) {
+ static struct bus_space plcom_bus_space;
+ static struct plcom_instance ifpga_pi0 = {
+ .pi_type = PLCOM_TYPE_PL010,
+ .pi_iot = &plcom_bus_space,
+ .pi_size = IFPGA_UART_SIZE,
+ .pi_iobase = 0x0
+ };
+
ifpga_create_io_bs_tag(&plcom_bus_space, (void*)0xfd600000);
- plcomcnattach(&plcom_bus_space, 0, plcomcnspeed,
- IFPGA_UART_CLK, plcomcnmode, PLCOMCNUNIT);
+ plcomcnattach(&ifpga_pi0, plcomcnspeed, IFPGA_UART_CLK,
+ plcomcnmode, PLCOMCNUNIT);
} else if (PLCOMCNUNIT == 1) {
+ static struct bus_space plcom_bus_space;
+ static struct plcom_instance ifpga_pi1 = {
+ .pi_type = PLCOM_TYPE_PL010,
+ .pi_iot = &plcom_bus_space,
+ .pi_size = IFPGA_UART_SIZE,
+ .pi_iobase = 0x0
+ };
+
ifpga_create_io_bs_tag(&plcom_bus_space, (void*)0xfd700000);
- plcomcnattach(&plcom_bus_space, 0, plcomcnspeed,
- IFPGA_UART_CLK, plcomcnmode, PLCOMCNUNIT);
+ plcomcnattach(&ifpga_pi1, plcomcnspeed, IFPGA_UART_CLK,
+ plcomcnmode, PLCOMCNUNIT);
}
#endif
@@ -788,9 +801,6 @@ void
consinit(void)
{
static int consinit_called = 0;
-#if NPLCOM > 0 && defined(PLCONSOLE)
- static struct bus_space plcom_bus_space;
-#endif
#if 0
char *console = CONSDEVNAME;
#endif
@@ -802,17 +812,35 @@ consinit(void)
#if NPLCOM > 0 && defined(PLCONSOLE)
if (PLCOMCNUNIT == 0) {
+ static struct bus_space plcom_bus_space;
+ static struct plcom_instance ifpga_pi1 = {
+ .pi_type = PLCOM_TYPE_PL010,
+ .pi_iot = &plcom_bus_space,
+ .pi_size = IFPGA_UART_SIZE,
+ .pi_iobase = 0x0
+ };
+
ifpga_create_io_bs_tag(&plcom_bus_space,
(void*)UART0_BOOT_BASE);
- if (plcomcnattach(&plcom_bus_space, 0, plcomcnspeed,
- IFPGA_UART_CLK, plcomcnmode, PLCOMCNUNIT))
+
+ if (plcomcnattach(&ifpga_pi1, plcomcnspeed, IFPGA_UART_CLK,
+ plcomcnmode, PLCOMCNUNIT))
panic("can't init serial console");
return;
} else if (PLCOMCNUNIT == 1) {
+ static struct bus_space plcom_bus_space;
+ static struct plcom_instance ifpga_pi1 = {
+ .pi_type = PLCOM_TYPE_PL010,
+ .pi_iot = &plcom_bus_space,
+ .pi_size = IFPGA_UART_SIZE,
+ .pi_iobase = 0x0
+ };
+
ifpga_create_io_bs_tag(&plcom_bus_space,
(void*)UART0_BOOT_BASE);
- if (plcomcnattach(&plcom_bus_space, 0, plcomcnspeed,
- IFPGA_UART_CLK, plcomcnmode, PLCOMCNUNIT))
+
+ if (plcomcnattach(&ifpga_pi1, plcomcnspeed, IFPGA_UART_CLK,
+ plcomcnmode, PLCOMCNUNIT))
panic("can't init serial console");
return;
}