summaryrefslogtreecommitdiffstats
path: root/sys/dev/uart
diff options
context:
space:
mode:
authorian <ian@FreeBSD.org>2014-05-14 04:57:55 +0000
committerian <ian@FreeBSD.org>2014-05-14 04:57:55 +0000
commit4a602a895785693d5def6282dbd784066341e805 (patch)
tree93e1dc02422784a7958c97bfd024009d3b8817ff /sys/dev/uart
parent9277bb1a2b74a398eb2fd572785d2d6db451d8c1 (diff)
downloadFreeBSD-src-4a602a895785693d5def6282dbd784066341e805.zip
FreeBSD-src-4a602a895785693d5def6282dbd784066341e805.tar.gz
MFC r258259, r258798, r259010
Unify handling of illegal instruction faults between AIM and Book-E. Make uart_cpu_powerpc work on both FDT and OFW systems. Fix debug printfs in FPU_EMU to compile on powerpc64 and enable it for powerpc64.
Diffstat (limited to 'sys/dev/uart')
-rw-r--r--sys/dev/uart/uart_cpu_powerpc.c97
1 files changed, 77 insertions, 20 deletions
diff --git a/sys/dev/uart/uart_cpu_powerpc.c b/sys/dev/uart/uart_cpu_powerpc.c
index 997bdd8..44f6338 100644
--- a/sys/dev/uart/uart_cpu_powerpc.c
+++ b/sys/dev/uart/uart_cpu_powerpc.c
@@ -61,42 +61,96 @@ ofw_get_uart_console(phandle_t opts, phandle_t *result, const char *inputdev,
input = OF_finddevice(buf);
if (input == -1)
return (ENXIO);
- if (OF_getprop(opts, outputdev, buf, sizeof(buf)) == -1)
- return (ENXIO);
- if (OF_finddevice(buf) != input)
- return (ENXIO);
+
+ if (outputdev != NULL) {
+ if (OF_getprop(opts, outputdev, buf, sizeof(buf)) == -1)
+ return (ENXIO);
+ if (OF_finddevice(buf) != input)
+ return (ENXIO);
+ }
*result = input;
return (0);
}
+static int
+ofw_get_console_phandle_path(phandle_t node, phandle_t *result,
+ const char *prop)
+{
+ union {
+ char buf[64];
+ phandle_t ref;
+ } field;
+ phandle_t output;
+ ssize_t size;
+
+ size = OF_getproplen(node, prop);
+ if (size == -1)
+ return (ENXIO);
+ OF_getprop(node, prop, &field, sizeof(field));
+
+ /* This property might be a phandle or might be a path. Hooray. */
+
+ output = -1;
+ if (field.buf[size - 1] == 0)
+ output = OF_finddevice(field.buf);
+ if (output == -1 && size == 4)
+ output = OF_xref_phandle(field.ref);
+
+ if (output != -1) {
+ *result = output;
+ return (0);
+ }
+
+ return (ENXIO);
+}
+
int
uart_cpu_getdev(int devtype, struct uart_devinfo *di)
{
char buf[64];
struct uart_class *class;
- phandle_t input, opts;
+ phandle_t input, opts, chosen;
int error;
class = &uart_z8530_class;
if (class == NULL)
return (ENXIO);
- if ((opts = OF_finddevice("/options")) == -1)
- return (ENXIO);
+ opts = OF_finddevice("/options");
+ chosen = OF_finddevice("/chosen");
switch (devtype) {
case UART_DEV_CONSOLE:
- if (ofw_get_uart_console(opts, &input, "input-device",
- "output-device")) {
- /*
- * At least some G5 Xserves require that we
- * probe input-device-1 as well
- */
-
- if (ofw_get_uart_console(opts, &input, "input-device-1",
- "output-device-1"))
- return (ENXIO);
+ error = ENXIO;
+ if (chosen != -1 && error != 0)
+ error = ofw_get_uart_console(chosen, &input,
+ "stdout-path", NULL);
+ if (chosen != -1 && error != 0)
+ error = ofw_get_uart_console(chosen, &input,
+ "linux,stdout-path", NULL);
+ if (chosen != -1 && error != 0)
+ error = ofw_get_console_phandle_path(chosen, &input,
+ "stdout");
+ if (chosen != -1 && error != 0)
+ error = ofw_get_uart_console(chosen, &input,
+ "stdin-path", NULL);
+ if (chosen != -1 && error != 0)
+ error = ofw_get_console_phandle_path(chosen, &input,
+ "stdin");
+ if (opts != -1 && error != 0)
+ error = ofw_get_uart_console(opts, &input,
+ "input-device", "output-device");
+ if (opts != -1 && error != 0)
+ error = ofw_get_uart_console(opts, &input,
+ "input-device-1", "output-device-1");
+ if (error != 0) {
+ input = OF_finddevice("serial0"); /* Last ditch */
+ if (input == -1)
+ error = (ENXIO);
}
+
+ if (error != 0)
+ return (error);
break;
case UART_DEV_DBGPORT:
if (!getenv_string("hw.uart.dbgport", buf, sizeof(buf)))
@@ -113,14 +167,14 @@ uart_cpu_getdev(int devtype, struct uart_devinfo *di)
return (ENXIO);
if (strcmp(buf, "serial") != 0)
return (ENXIO);
- if (OF_getprop(input, "name", buf, sizeof(buf)) == -1)
+ if (OF_getprop(input, "compatible", buf, sizeof(buf)) == -1)
return (ENXIO);
- if (strcmp(buf, "ch-a") == 0) {
+ if (strncmp(buf, "chrp,es", 7) == 0) {
class = &uart_z8530_class;
di->bas.regshft = 4;
di->bas.chan = 1;
- } else if (strcmp(buf,"serial") == 0) {
+ } else if (strcmp(buf,"ns16550") == 0 || strcmp(buf,"ns8250") == 0) {
class = &uart_ns8250_class;
di->bas.regshft = 0;
di->bas.chan = 0;
@@ -139,9 +193,12 @@ uart_cpu_getdev(int devtype, struct uart_devinfo *di)
if (OF_getprop(input, "current-speed", &di->baudrate,
sizeof(di->baudrate)) == -1)
di->baudrate = 0;
+ OF_getprop(input, "reg-shift", &di->bas.regshft,
+ sizeof(di->bas.regshft));
di->databits = 8;
di->stopbits = 1;
di->parity = UART_PARITY_NONE;
return (0);
}
+
OpenPOWER on IntegriCloud