summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/conf/files1
-rw-r--r--sys/dev/uart/uart_cpu.h8
-rw-r--r--sys/dev/uart/uart_cpu_alpha.c16
-rw-r--r--sys/dev/uart/uart_cpu_amd64.c11
-rw-r--r--sys/dev/uart/uart_cpu_i386.c11
-rw-r--r--sys/dev/uart/uart_cpu_ia64.c54
-rw-r--r--sys/dev/uart/uart_cpu_pc98.c9
-rw-r--r--sys/dev/uart/uart_cpu_sparc64.c5
-rw-r--r--sys/dev/uart/uart_subr.c247
9 files changed, 305 insertions, 57 deletions
diff --git a/sys/conf/files b/sys/conf/files
index ae2a9ae..30cfa0b 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -748,6 +748,7 @@ dev/uart/uart_dev_i8251.c optional uart
dev/uart/uart_dev_ns8250.c optional uart
dev/uart/uart_dev_sab82532.c optional uart
dev/uart/uart_dev_z8530.c optional uart
+dev/uart/uart_subr.c optional uart
dev/uart/uart_tty.c optional uart
dev/ubsec/ubsec.c optional ubsec
#
diff --git a/sys/dev/uart/uart_cpu.h b/sys/dev/uart/uart_cpu.h
index f124aa7..462eb59 100644
--- a/sys/dev/uart/uart_cpu.h
+++ b/sys/dev/uart/uart_cpu.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003 Marcel Moolenaar
+ * Copyright (c) 2003, 2004 Marcel Moolenaar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -46,6 +46,9 @@ extern struct uart_ops uart_ns8250_ops;
extern struct uart_ops uart_sab82532_ops;
extern struct uart_ops uart_z8530_ops;
+extern bus_space_tag_t uart_bus_space_io;
+extern bus_space_tag_t uart_bus_space_mem;
+
/*
* Console and debug port device info.
*/
@@ -69,8 +72,9 @@ struct uart_devinfo {
int uart_cpu_eqres(struct uart_bas *, struct uart_bas *);
int uart_cpu_getdev(int, struct uart_devinfo *);
+int uart_getenv(int, struct uart_devinfo *);
-void uart_add_sysdev(struct uart_devinfo*);
+void uart_add_sysdev(struct uart_devinfo *);
/*
* Operations for low-level access to the UART. Primarily for use
diff --git a/sys/dev/uart/uart_cpu_alpha.c b/sys/dev/uart/uart_cpu_alpha.c
index 1d78d6a..a3a132f 100644
--- a/sys/dev/uart/uart_cpu_alpha.c
+++ b/sys/dev/uart/uart_cpu_alpha.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003 Marcel Moolenaar
+ * Copyright (c) 2003, 2004 Marcel Moolenaar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -39,6 +39,9 @@ __FBSDID("$FreeBSD$");
#include <dev/uart/uart.h>
#include <dev/uart/uart_cpu.h>
+bus_space_tag_t uart_bus_space_io;
+bus_space_tag_t uart_bus_space_mem;
+
int
uart_cpu_eqres(struct uart_bas *b1, struct uart_bas *b2)
{
@@ -52,6 +55,9 @@ uart_cpu_getdev(int devtype, struct uart_devinfo *di)
struct ctb *ctb;
unsigned int i, ivar;
+ uart_bus_space_io = busspace_isa_io;
+ uart_bus_space_mem = busspace_isa_mem;
+
if (devtype == UART_DEV_CONSOLE) {
ctb = (struct ctb *)(((caddr_t)hwrpb) + hwrpb->rpb_ctb_off);
if (ctb->ctb_term_type != CTB_PRINTERPORT)
@@ -59,7 +65,7 @@ uart_cpu_getdev(int devtype, struct uart_devinfo *di)
boothowto |= RB_SERIAL;
di->ops = uart_ns8250_ops;
di->bas.chan = 0;
- di->bas.bst = busspace_isa_io;
+ di->bas.bst = uart_bus_space_io;
if (bus_space_map(di->bas.bst, 0x3f8, 8, 0, &di->bas.bsh) != 0)
return (ENXIO);
di->bas.regshft = 0;
@@ -71,6 +77,10 @@ uart_cpu_getdev(int devtype, struct uart_devinfo *di)
return (0);
}
+ /* Check the environment. */
+ if (uart_getenv(devtype, di) == 0)
+ return (0);
+
/*
* Scan the hints. We only try units 0 to 3 (inclusive). This
* covers the ISA legacy where 4 UARTs had their resources
@@ -97,7 +107,7 @@ uart_cpu_getdev(int devtype, struct uart_devinfo *di)
*/
di->ops = uart_ns8250_ops;
di->bas.chan = 0;
- di->bas.bst = busspace_isa_io;
+ di->bas.bst = uart_bus_space_io;
if (bus_space_map(di->bas.bst, ivar, 8, 0, &di->bas.bsh) != 0)
continue;
di->bas.regshft = 0;
diff --git a/sys/dev/uart/uart_cpu_amd64.c b/sys/dev/uart/uart_cpu_amd64.c
index be0f619..c0270ae 100644
--- a/sys/dev/uart/uart_cpu_amd64.c
+++ b/sys/dev/uart/uart_cpu_amd64.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003 Marcel Moolenaar
+ * Copyright (c) 2003, 2004 Marcel Moolenaar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -36,6 +36,9 @@ __FBSDID("$FreeBSD$");
#include <dev/uart/uart.h>
#include <dev/uart/uart_cpu.h>
+bus_space_tag_t uart_bus_space_io = AMD64_BUS_SPACE_IO;
+bus_space_tag_t uart_bus_space_mem = AMD64_BUS_SPACE_MEM;
+
int
uart_cpu_eqres(struct uart_bas *b1, struct uart_bas *b2)
{
@@ -48,6 +51,10 @@ uart_cpu_getdev(int devtype, struct uart_devinfo *di)
{
unsigned int i, ivar;
+ /* Check the environment. */
+ if (uart_getenv(devtype, di) == 0)
+ return (0);
+
/*
* Scan the hints. We only try units 0 to 3 (inclusive). This
* covers the ISA legacy where 4 UARTs had their resources
@@ -76,7 +83,7 @@ uart_cpu_getdev(int devtype, struct uart_devinfo *di)
*/
di->ops = uart_ns8250_ops;
di->bas.chan = 0;
- di->bas.bst = AMD64_BUS_SPACE_IO;
+ di->bas.bst = uart_bus_space_io;
if (bus_space_map(di->bas.bst, ivar, 8, 0, &di->bas.bsh) != 0)
continue;
di->bas.regshft = 0;
diff --git a/sys/dev/uart/uart_cpu_i386.c b/sys/dev/uart/uart_cpu_i386.c
index 30b6e3a..93ca770 100644
--- a/sys/dev/uart/uart_cpu_i386.c
+++ b/sys/dev/uart/uart_cpu_i386.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003 Marcel Moolenaar
+ * Copyright (c) 2003, 2004 Marcel Moolenaar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -36,6 +36,9 @@ __FBSDID("$FreeBSD$");
#include <dev/uart/uart.h>
#include <dev/uart/uart_cpu.h>
+bus_space_tag_t uart_bus_space_io = I386_BUS_SPACE_IO;
+bus_space_tag_t uart_bus_space_mem = I386_BUS_SPACE_MEM;
+
int
uart_cpu_eqres(struct uart_bas *b1, struct uart_bas *b2)
{
@@ -48,6 +51,10 @@ uart_cpu_getdev(int devtype, struct uart_devinfo *di)
{
unsigned int i, ivar;
+ /* Check the environment. */
+ if (uart_getenv(devtype, di) == 0)
+ return (0);
+
/*
* Scan the hints. We only try units 0 to 3 (inclusive). This
* covers the ISA legacy where 4 UARTs had their resources
@@ -76,7 +83,7 @@ uart_cpu_getdev(int devtype, struct uart_devinfo *di)
*/
di->ops = uart_ns8250_ops;
di->bas.chan = 0;
- di->bas.bst = I386_BUS_SPACE_IO;
+ di->bas.bst = uart_bus_space_io;
if (bus_space_map(di->bas.bst, ivar, 8, 0, &di->bas.bsh) != 0)
continue;
di->bas.regshft = 0;
diff --git a/sys/dev/uart/uart_cpu_ia64.c b/sys/dev/uart/uart_cpu_ia64.c
index eeaea3b..6c3f380 100644
--- a/sys/dev/uart/uart_cpu_ia64.c
+++ b/sys/dev/uart/uart_cpu_ia64.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003 Marcel Moolenaar
+ * Copyright (c) 2003, 2004 Marcel Moolenaar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -39,6 +39,9 @@ __FBSDID("$FreeBSD$");
#include <dev/uart/uart.h>
#include <dev/uart/uart_cpu.h>
+bus_space_tag_t uart_bus_space_io = IA64_BUS_SPACE_IO;
+bus_space_tag_t uart_bus_space_mem = IA64_BUS_SPACE_MEM;
+
static int dig64_to_uart_parity[] = {
UART_PARITY_NONE, UART_PARITY_NONE, UART_PARITY_EVEN,
UART_PARITY_ODD, UART_PARITY_MARK, UART_PARITY_SPACE
@@ -57,7 +60,7 @@ uart_cpu_getdev(int devtype, struct uart_devinfo *di)
struct dig64_hcdp_table *tbl;
struct dig64_hcdp_entry *ent;
bus_addr_t addr;
- unsigned int i, ivar;
+ unsigned int i;
/*
* Use the DIG64 HCDP table if present.
@@ -80,7 +83,7 @@ uart_cpu_getdev(int devtype, struct uart_devinfo *di)
di->ops = uart_ns8250_ops;
di->bas.chan = 0;
di->bas.bst = (ent->address.addr_space == 0)
- ? IA64_BUS_SPACE_MEM : IA64_BUS_SPACE_IO;
+ ? uart_bus_space_mem : uart_bus_space_io;
if (bus_space_map(di->bas.bst, addr, 8, 0,
&di->bas.bsh) != 0)
continue;
@@ -98,47 +101,6 @@ uart_cpu_getdev(int devtype, struct uart_devinfo *di)
/* FALLTHROUGH */
}
- /*
- * Scan the hints for backward compatibility. We only try units
- * 0 to 3 (inclusive). This covers the ISA legacy where 4 UARTs
- * had their resources predefined.
- */
- for (i = 0; i < 4; i++) {
- if (resource_int_value("uart", i, "flags", &ivar))
- continue;
- if (devtype == UART_DEV_CONSOLE && !UART_FLAGS_CONSOLE(ivar))
- continue;
- if (devtype == UART_DEV_DBGPORT && !UART_FLAGS_DBGPORT(ivar))
- continue;
- /*
- * We have a possible device. Make sure it's enabled and
- * that we have an I/O port.
- */
- if (resource_int_value("uart", i, "disabled", &ivar) == 0 &&
- ivar != 0)
- continue;
- if (resource_int_value("uart", i, "port", &ivar) != 0 ||
- ivar == 0)
- continue;
- /*
- * Got it. Fill in the instance and return it. We only have
- * ns8250 and successors on i386.
- */
- di->ops = uart_ns8250_ops;
- di->bas.chan = 0;
- di->bas.bst = IA64_BUS_SPACE_IO;
- if (bus_space_map(di->bas.bst, ivar, 8, 0, &di->bas.bsh) != 0)
- continue;
- di->bas.regshft = 0;
- di->bas.rclk = 0;
- if (resource_int_value("uart", i, "baud", &ivar) != 0)
- ivar = 0;
- di->baudrate = ivar;
- di->databits = 8;
- di->stopbits = 1;
- di->parity = UART_PARITY_NONE;
- return (0);
- }
-
- return (ENXIO);
+ /* Check the environment. */
+ return (uart_getenv(devtype, di));
}
diff --git a/sys/dev/uart/uart_cpu_pc98.c b/sys/dev/uart/uart_cpu_pc98.c
index 4005a90..2446c4f 100644
--- a/sys/dev/uart/uart_cpu_pc98.c
+++ b/sys/dev/uart/uart_cpu_pc98.c
@@ -36,6 +36,9 @@ __FBSDID("$FreeBSD$");
#include <dev/uart/uart.h>
#include <dev/uart/uart_cpu.h>
+bus_space_tag_t uart_bus_space_io;
+bus_space_tag_t uart_bus_space_mem;
+
int
uart_cpu_eqres(struct uart_bas *b1, struct uart_bas *b2)
{
@@ -48,6 +51,10 @@ uart_cpu_getdev(int devtype, struct uart_devinfo *di)
{
unsigned int i, ivar, flags;
+ /* Check the environment. */
+ if (uart_getenv(devtype, di) == 0)
+ return (0);
+
/*
* There are 2 built-in serial ports on pc98 hardware. The
* first one is 8251 and the second one is I think an enhance
@@ -81,7 +88,7 @@ uart_cpu_getdev(int devtype, struct uart_devinfo *di)
else
di->ops = uart_i8251_ops;
di->bas.chan = 0;
- di->bas.bst = I386_BUS_SPACE_IO;
+ di->bas.bst = uart_bus_space_io;
if (bus_space_map(di->bas.bst, ivar, 8, 0, &di->bas.bsh) != 0)
continue;
di->bas.regshft = 0;
diff --git a/sys/dev/uart/uart_cpu_sparc64.c b/sys/dev/uart/uart_cpu_sparc64.c
index 0cada13..ea9c60d 100644
--- a/sys/dev/uart/uart_cpu_sparc64.c
+++ b/sys/dev/uart/uart_cpu_sparc64.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003 Marcel Moolenaar
+ * Copyright (c) 2003, 2004 Marcel Moolenaar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -39,6 +39,9 @@ __FBSDID("$FreeBSD$");
#include <dev/uart/uart.h>
#include <dev/uart/uart_cpu.h>
+bus_space_tag_t uart_bus_space_io;
+bus_space_tag_t uart_bus_space_mem;
+
static phandle_t uart_cpu_getdev_keyboard(phandle_t root);
static struct bus_space_tag bst_store[3];
diff --git a/sys/dev/uart/uart_subr.c b/sys/dev/uart/uart_subr.c
new file mode 100644
index 0000000..9a3cb85
--- /dev/null
+++ b/sys/dev/uart/uart_subr.c
@@ -0,0 +1,247 @@
+/*
+ * Copyright (c) 2004 Marcel Moolenaar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+
+#include <machine/bus.h>
+#include <machine/vmparam.h>
+
+#include <dev/uart/uart.h>
+#include <dev/uart/uart_cpu.h>
+
+#define UART_TAG_BR 0
+#define UART_TAG_CH 1
+#define UART_TAG_DB 2
+#define UART_TAG_DT 3
+#define UART_TAG_IO 4
+#define UART_TAG_MM 5
+#define UART_TAG_PA 6
+#define UART_TAG_RS 7
+#define UART_TAG_SB 8
+#define UART_TAG_XO 9
+
+static bus_addr_t
+uart_parse_addr(__const char **p)
+{
+ return (strtoul(*p, (char**)(uintptr_t)p, 0));
+}
+
+static long
+uart_parse_long(__const char **p)
+{
+ return (strtol(*p, (char**)(uintptr_t)p, 0));
+}
+
+static int
+uart_parse_parity(__const char **p)
+{
+ if (!strncmp(*p, "even", 4)) {
+ *p += 4;
+ return UART_PARITY_EVEN;
+ }
+ if (!strncmp(*p, "mark", 4)) {
+ *p += 4;
+ return UART_PARITY_MARK;
+ }
+ if (!strncmp(*p, "none", 4)) {
+ *p += 4;
+ return UART_PARITY_NONE;
+ }
+ if (!strncmp(*p, "odd", 3)) {
+ *p += 3;
+ return UART_PARITY_ODD;
+ }
+ if (!strncmp(*p, "space", 5)) {
+ *p += 5;
+ return UART_PARITY_SPACE;
+ }
+ return (-1);
+}
+
+static int
+uart_parse_tag(__const char **p)
+{
+ int tag;
+
+ if ((*p)[0] == 'b' && (*p)[1] == 'r') {
+ tag = UART_TAG_BR;
+ goto out;
+ }
+ if ((*p)[0] == 'c' && (*p)[1] == 'h') {
+ tag = UART_TAG_CH;
+ goto out;
+ }
+ if ((*p)[0] == 'd' && (*p)[1] == 'b') {
+ tag = UART_TAG_DB;
+ goto out;
+ }
+ if ((*p)[0] == 'd' && (*p)[1] == 't') {
+ tag = UART_TAG_DT;
+ goto out;
+ }
+ if ((*p)[0] == 'i' && (*p)[1] == 'o') {
+ tag = UART_TAG_IO;
+ goto out;
+ }
+ if ((*p)[0] == 'm' && (*p)[1] == 'm') {
+ tag = UART_TAG_MM;
+ goto out;
+ }
+ if ((*p)[0] == 'p' && (*p)[1] == 'a') {
+ tag = UART_TAG_PA;
+ goto out;
+ }
+ if ((*p)[0] == 'r' && (*p)[1] == 's') {
+ tag = UART_TAG_RS;
+ goto out;
+ }
+ if ((*p)[0] == 's' && (*p)[1] == 'b') {
+ tag = UART_TAG_SB;
+ goto out;
+ }
+ if ((*p)[0] == 'x' && (*p)[1] == 'o') {
+ tag = UART_TAG_XO;
+ goto out;
+ }
+ return (-1);
+
+out:
+ *p += 2;
+ if ((*p)[0] != ':')
+ return (-1);
+ (*p)++;
+ return (tag);
+}
+
+/*
+ * Parse a device specification. The specification is a list of attributes
+ * seperated by commas. Each attribute is a tag-value pair with the tag and
+ * value seperated by a colon. Supported tags are:
+ *
+ * br = Baudrate
+ * ch = Channel
+ * db = Data bits
+ * dt = Device type
+ * io = I/O port address
+ * mm = Memory mapped I/O address
+ * pa = Parity
+ * rs = Register shift
+ * sb = Stopbits
+ * xo = Device clock (xtal oscillator)
+ *
+ * The io and mm tags are mutually exclusive.
+ */
+
+int
+uart_getenv(int devtype, struct uart_devinfo *di)
+{
+ __const char *spec;
+ bus_addr_t addr = ~0U;
+
+ /*
+ * Check the environment variables "hw.uart.console" and
+ * "hw.uart.dbgport". These variables, when present, specify
+ * which UART port is to be used as serial console or debug
+ * port (resp).
+ */
+ if (devtype == UART_DEV_CONSOLE)
+ spec = getenv("hw.uart.console");
+ else if (devtype == UART_DEV_DBGPORT)
+ spec = getenv("hw.uart.dbgport");
+ else
+ return (ENXIO);
+
+ /* Set defaults. */
+ di->ops = uart_ns8250_ops;
+ di->bas.chan = 0;
+ di->bas.regshft = 0;
+ di->bas.rclk = 0;
+ di->baudrate = 0;
+ di->databits = 8;
+ di->stopbits = 1;
+ di->parity = UART_PARITY_NONE;
+
+ /* Parse the attributes. */
+ while (1) {
+ switch (uart_parse_tag(&spec)) {
+ case UART_TAG_BR:
+ di->baudrate = uart_parse_long(&spec);
+ break;
+ case UART_TAG_CH:
+ di->bas.chan = uart_parse_long(&spec);
+ break;
+ case UART_TAG_DB:
+ di->databits = uart_parse_long(&spec);
+ break;
+ case UART_TAG_DT:
+ return (EINVAL); /* XXX not yet implemented. */
+ break;
+ case UART_TAG_IO:
+ di->bas.bst = uart_bus_space_io;
+ addr = uart_parse_addr(&spec);
+ break;
+ case UART_TAG_MM:
+ di->bas.bst = uart_bus_space_mem;
+ addr = uart_parse_addr(&spec);
+ break;
+ case UART_TAG_PA:
+ di->parity = uart_parse_parity(&spec);
+ break;
+ case UART_TAG_RS:
+ di->bas.regshft = uart_parse_long(&spec);
+ break;
+ case UART_TAG_SB:
+ di->stopbits = uart_parse_long(&spec);
+ break;
+ case UART_TAG_XO:
+ di->bas.rclk = uart_parse_long(&spec);
+ break;
+ default:
+ return (EINVAL);
+ }
+ if (*spec == '\0')
+ break;
+ if (*spec != ',')
+ return (EINVAL);
+ spec++;
+ }
+
+ /*
+ * If we still have an invalid address, the specification must be
+ * missing an I/O port or memory address. We don't like that.
+ */
+ if (addr == ~0U)
+ return (EINVAL);
+ /* XXX the size of the mapping depends on the UART class. */
+ if (bus_space_map(di->bas.bst, addr, 8, 0, &di->bas.bsh) != 0)
+ return (EINVAL);
+ return (0);
+}
OpenPOWER on IntegriCloud