diff --git a/usr.sbin/ofwdump/Makefile b/usr.sbin/ofwdump/Makefile new file mode 100644 index 000000000000..4cbc3e051865 --- /dev/null +++ b/usr.sbin/ofwdump/Makefile @@ -0,0 +1,8 @@ +# $FreeBSD$ + +PROG= ofwdump +MAN= ofwdump.8 +SRCS= ofwdump.c ofw_util.c +WARNS?= 5 + +.include diff --git a/usr.sbin/ofwdump/ofw_util.c b/usr.sbin/ofwdump/ofw_util.c new file mode 100644 index 000000000000..e6fca8c5c9ff --- /dev/null +++ b/usr.sbin/ofwdump/ofw_util.c @@ -0,0 +1,259 @@ +/*- + * Copyright (c) 2002 by Thomas Moestl . + * 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 OR CONTRIBUTORS 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 +__FBSDID("$FreeBSD$"); + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "pathnames.h" +#include "ofw_util.h" + +/* Constants controlling the layout of the output. */ +#define LVLINDENT 2 +#define NAMEINDENT 2 +#define DUMPINDENT 4 +#define CHARSPERLINE 60 +#define BYTESPERLINE (CHARSPERLINE / 3) + +/* Maximum supported property size. */ +#define PROPBUFLEN 1024 + +#define OFW_IOCTL(fd, cmd, val) do { \ + if (ioctl(fd, cmd, val) == -1) \ + err(1, "ioctl(..., " #cmd ", ...) failed"); \ +} while (0) + +int +ofw_open(void) +{ + int fd; + + if ((fd = open(PATH_DEV_OPENFIRM, O_RDONLY)) == -1) + err(1, "could not open " PATH_DEV_OPENFIRM); + return (fd); +} + +void +ofw_close(int fd) +{ + + close(fd); +} + +phandle_t +ofw_root(int fd) +{ + + return (ofw_peer(fd, 0)); +} + +phandle_t +ofw_peer(int fd, phandle_t node) +{ + phandle_t rv; + + rv = node; + OFW_IOCTL(fd, OFIOCGETNEXT, &rv); + return (rv); +} + +phandle_t +ofw_child(int fd, phandle_t node) +{ + phandle_t rv; + + rv = node; + OFW_IOCTL(fd, OFIOCGETCHILD, &rv); + return (rv); +} + +phandle_t +ofw_finddevice(int fd, char *name) +{ + struct ofiocdesc d; + + d.of_nodeid = 0; + d.of_namelen = strlen(name); + d.of_name = name; + d.of_buflen = 0; + d.of_buf = NULL; + if (ioctl(fd, OFIOCFINDDEVICE, &d) == -1) { + if (errno == ENOENT) + err(2, "Node '%s' not found", name); + else + err(1, "ioctl(..., OFIOCFINDDEVICE, ...) failed"); + } + return (d.of_nodeid); +} + +int +ofw_firstprop(int fd, phandle_t node, char *buf, int buflen) +{ + + return (ofw_nextprop(fd, node, NULL, buf, buflen)); +} + +int +ofw_nextprop(int fd, phandle_t node, char *prev, char *buf, int buflen) +{ + struct ofiocdesc d; + + d.of_nodeid = node; + d.of_namelen = prev != NULL ? strlen(prev) : 0; + d.of_name = prev; + d.of_buflen = buflen; + d.of_buf = buf; + if (ioctl(fd, OFIOCNEXTPROP, &d) == -1) { + if (errno == ENOENT) + return (0); + else + err(1, "ioctl(..., OFIOCNEXTPROP, ...) failed"); + } + return (d.of_buflen); +} + +int +ofw_getprop(int fd, phandle_t node, const char *name, void *buf, int buflen) +{ + struct ofiocdesc d; + + d.of_nodeid = node; + d.of_namelen = strlen(name); + d.of_name = name; + d.of_buflen = buflen; + d.of_buf = buf; + OFW_IOCTL(fd, OFIOCGET, &d); + return (d.of_buflen); +} + +static void +ofw_indent(int level) +{ + int i; + + for (i = 0; i < level; i++) + putchar(' '); +} + +static void +ofw_dump_properties(int fd, phandle_t n, int level, char *pmatch, int raw, + int str) +{ + static char pbuf[PROPBUFLEN]; + static char visbuf[PROPBUFLEN * 4 + 1]; + static char printbuf[CHARSPERLINE + 1]; + char prop[32]; + int nlen, len, i, j, max, vlen; + unsigned int b; + + for (nlen = ofw_firstprop(fd, n, prop, sizeof(prop)); nlen != 0; + nlen = ofw_nextprop(fd, n, prop, prop, sizeof(prop))) { + if (pmatch != NULL && strcmp(pmatch, prop) != 0) + continue; + len = ofw_getprop(fd, n, prop, pbuf, sizeof(pbuf) - 1); + if (raw) + write(STDOUT_FILENO, pbuf, len); + else if (str) { + pbuf[len] = '\0'; + printf("%s\n", pbuf); + } else { + ofw_indent(level * LVLINDENT + NAMEINDENT); + printf("%s:\n", prop); + /* Print in hex. */ + for (i = 0; i < len; i += BYTESPERLINE) { + max = len - i; + max = max > BYTESPERLINE ? BYTESPERLINE : max; + ofw_indent(level * LVLINDENT + DUMPINDENT); + for (j = 0; j < max; j++) { + b = (unsigned char)pbuf[i + j]; + printf("%02x ", b); + } + printf("\n"); + } + /* + * strvis() and print if it looks like it is + * zero-terminated. + */ + if (pbuf[len - 1] == '\0' && + strlen(pbuf) == (unsigned)len - 1) { + vlen = strvis(visbuf, pbuf, VIS_TAB | VIS_NL); + for (i = 0; i < vlen; i += CHARSPERLINE) { + ofw_indent(level * LVLINDENT + + DUMPINDENT); + strlcpy(printbuf, &visbuf[i], + sizeof(printbuf)); + printf("'%s'\n", printbuf); + } + } + } + } +} + +static void +ofw_dump_node(int fd, phandle_t n, int level, int rec, int prop, char *pmatch, + int raw, int str) +{ + static char nbuf[PROPBUFLEN]; + phandle_t c; + + if (!(raw || str)) { + ofw_indent(level * LVLINDENT); + printf("Node %#lx", (unsigned long)n); + if (ofw_getprop(fd, n, "name", nbuf, sizeof(nbuf) - 1) > 0) + printf(": %s\n", nbuf); + else + putchar('\n'); + } + if (prop) + ofw_dump_properties(fd, n, level, pmatch, raw, str); + if (rec) { + for (c = ofw_child(fd, n); c != 0; c = ofw_peer(fd, c)) { + ofw_dump_node(fd, c, level + 1, rec, prop, pmatch, + raw, str); + } + } +} + +void +ofw_dump(int fd, char *start, int rec, int prop, char *pmatch, int raw, int str) +{ + phandle_t n; + + n = start == NULL ? ofw_root(fd) : ofw_finddevice(fd, start); + ofw_dump_node(fd, n, 0, rec, prop, pmatch, raw, str); +} + diff --git a/usr.sbin/ofwdump/ofw_util.h b/usr.sbin/ofwdump/ofw_util.h new file mode 100644 index 000000000000..9c03ce64b416 --- /dev/null +++ b/usr.sbin/ofwdump/ofw_util.h @@ -0,0 +1,48 @@ +/*- + * Copyright (c) 2002 by Thomas Moestl . + * 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 OR CONTRIBUTORS 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. + * + * $FreeBSD$ + */ + +#ifndef OFW_UTIL_H +#define OFW_UTIL_H + +#include + +int ofw_open(void); +void ofw_close(int); + +phandle_t ofw_root(int); +phandle_t ofw_peer(int, phandle_t); +phandle_t ofw_child(int, phandle_t); +phandle_t ofw_finddevice(int, char *); + +int ofw_firstprop(int, phandle_t, char *, int); +int ofw_nextprop(int, phandle_t, char *, char *, int); +int ofw_getprop(int, phandle_t, const char *, void *, int); + +void ofw_dump(int, char *, int, int, char *, int, int); + +#endif /* OFW_UTIL_H */ + diff --git a/usr.sbin/ofwdump/ofwdump.8 b/usr.sbin/ofwdump/ofwdump.8 new file mode 100644 index 000000000000..6dc7cb442f6f --- /dev/null +++ b/usr.sbin/ofwdump/ofwdump.8 @@ -0,0 +1,104 @@ +.\" Copyright (c) 2002 by Thomas Moestl . +.\" 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 OR CONTRIBUTORS 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. +.\" +.\" $FreeBSD$ +.\" +.Dd October 18, 2002 +.Dt OFWDUMP 8 +.Os +.Sh NAME +.Nm ofwdump +.Nd examine the OpenFirmware device tree +.Sh SYNOPSIS +.Nm +.Fl a +.Op Fl p | P Ar property +.Op Fl R | S +.Nm +.Op Fl p | P Ar property +.Op Fl r +.Op Fl R | S +.Op Fl - +.Ar nodes +.Sh DESCRIPTION +The +.Nm +utility is used to examine the OpenFirmware device tree. +In the first synopsis form, the complete device tree is printed; in the +second form, only the selected +.Ar nodes +will be examined. +.Pp +The following options are available: +.Bl -tag -width ".Fl P Ar property" +.It Fl a +Print the complete device tree. +.It Fl p +Print all available properties. +.It Fl P Ar property +Only print properties of the given name. +.It Fl R +Print properties in +.Dq raw +format, i.e. omit all headings and indentation and just write the +property values unaltered to the standard output. This is intended +to be used with the +.Fl P +option to extract the value of a single property. +.It Fl S +Print properties as strings; this is analogous to the +.Fl R +option, except that each property is only output to the first +.Dv NUL +character, and that newline is appended to each. +.It Fl r +Recursively print all children of the specified nodes. +.El +.Sh EXAMPLES +Print the complete device tree: +.Pp +.Dl ofwdump -a +.Pp +Print the complete device subtree of the +.Dq Li /pci +node, including all available properties: +.Pp +.Dl ofwdump -pr /pci +.Pp +Print the +.Dq Li compatible +property of the +.Dq Li /pci +node as plain string: +.Pp +.Dl ofwdump -P compatible -S /pci +.Pp +.Sh HISTORY +The +.Nm +utility first appeared in +.Fx 5.0 . +.Sh AUTHORS +.Nm +was written by +.An Thomas Moestl Aq tmm@FreeBSD.org . diff --git a/usr.sbin/ofwdump/ofwdump.c b/usr.sbin/ofwdump/ofwdump.c new file mode 100644 index 000000000000..792f8fe8a62c --- /dev/null +++ b/usr.sbin/ofwdump/ofwdump.c @@ -0,0 +1,106 @@ +/*- + * Copyright (c) 2002 by Thomas Moestl . + * 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 OR CONTRIBUTORS 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 +__FBSDID("$FreeBSD$"); + +#include +#include +#include + +#include "ofw_util.h" + +void usage(void); + +void +usage(void) +{ + + fprintf(stderr, + "usage: ofwdump -a [-p | -P property] [-R | -S]\n" + " ofwdump [-p | -P property] [-r] [-R | -S] [--] nodes\n"); + exit(1); +} + +int +main(int argc, char *argv[]) +{ + int opt, i, fd; + int aflag, pflag, rflag, Rflag, Sflag; + char *Parg; + + aflag = pflag = rflag = Rflag = Sflag = 0; + Parg = NULL; + while ((opt = getopt(argc, argv, "-aprP:RS")) != -1) { + if (opt == '-') + break; + switch (opt) { + case 'a': + aflag = 1; + rflag = 1; + break; + case 'p': + if (Parg != NULL) + usage(); + pflag = 1; + break; + case 'r': + rflag = 1; + break; + case 'P': + if (pflag) + usage(); + pflag = 1; + Parg = optarg; + break; + case 'R': + if (Sflag) + usage(); + Rflag = 1; + break; + case 'S': + if (Rflag) + usage(); + Sflag = 1; + break; + default: + usage(); + } + } + argc -= optind; + argv += optind; + + fd = ofw_open(); + if (aflag) { + if (argc != 0) + usage(); + ofw_dump(fd, NULL, rflag, pflag, Parg, Rflag, Sflag); + } else { + for (i = 0; i < argc; i++) + ofw_dump(fd, argv[i], rflag, pflag, Parg, Rflag, Sflag); + } + ofw_close(fd); + return (0); +} diff --git a/usr.sbin/ofwdump/pathnames.h b/usr.sbin/ofwdump/pathnames.h new file mode 100644 index 000000000000..32f5fe624db6 --- /dev/null +++ b/usr.sbin/ofwdump/pathnames.h @@ -0,0 +1,30 @@ +/*- + * Copyright (c) 2002 by Thomas Moestl . + * 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 OR CONTRIBUTORS 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. + * + * $FreeBSD$ + */ + +#include + +#define PATH_DEV_OPENFIRM _PATH_DEV "openfirm"