Subject: Re: How to use /dev/openfirm?
To: gabriel rosenkoetter <gr@eclipsed.net>
From: Nathan J. Williams <nathanw@MIT.EDU>
List: port-macppc
Date: 07/29/2001 18:38:41
--=-=-=
gabriel rosenkoetter <gr@eclipsed.net> writes:
> (If you end up finding documentation or working out the details
> yourself, writing something up for the mail archives and, ideally,
> the FAQ would rock.)
Well, there's not much documentation, but with a little UTSL'ing I was
able to produce the following program to walk the ofw tree and print
all devices (nodes?) and their properties.
Be warned that using the -n option (intended for doing things like
"walkopenfirm -n /pci@f2000000" will actually crash the system if you
don't feed it an exactly correct OFW path. I don't recommend it. I
also think this is a bug, but I don't even know whose bug it is
yet....
- Nathan
--=-=-=
Content-Disposition: attachment; filename=walkopenfirm.c
#include <ctype.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <dev/ofw/openfirmio.h>
#define OFWPATH "/dev/openfirm"
#define BUFSIZE 16384
static void usage(void);
void walkdev(int fd, char *name);
void walknode(int fd, int nodeid, int level);
void printprop(struct ofiocdesc *node, int level);
int
main(int argc, char *argv[])
{
int ofwfd;
char startnode[256];
int ch;
extern char *optarg;
extern int optind;
strcpy(startnode, "/");
while((ch = getopt(argc, argv, "n:")) != -1)
switch (ch) {
case 'n':
strcpy(startnode, optarg);
break;
case '?':
default:
usage();
}
argc += optind;
argv -= optind;
ofwfd = open(OFWPATH, O_RDONLY, 0);
if (ofwfd == -1)
err(EXIT_FAILURE, "Couldn't open %s", OFWPATH);
walkdev(ofwfd, startnode);
close(ofwfd);
return 0;
}
void
walkdev(int fd, char *name)
{
struct ofiocdesc node;
int ret;
node.of_nodeid = 0;
node.of_name = name;
node.of_namelen = strlen(name);
ret = ioctl(fd, OFIOCFINDDEVICE, &node);
if (ret == -1)
err(EXIT_FAILURE, "Couldn't find start node %s", name);
walknode(fd, node.of_nodeid, 0);
}
void
walknode(int fd, int nodeid, int level)
{
struct ofiocdesc ofc;
char buf1[BUFSIZE], buf2[BUFSIZE];
char *swap;
int childnodeid;
int ret;
ofc.of_namelen = BUFSIZE;
ofc.of_name = buf1;
ofc.of_buf = buf2;
while (nodeid != 0) {
/* Get information about the node */
ofc.of_nodeid = nodeid;
strcpy(ofc.of_name, "name");
ofc.of_namelen = strlen(ofc.of_name);
ofc.of_buflen = BUFSIZE;
ret = ioctl(fd, OFIOCGET, &ofc);
if (ret == -1)
err(EXIT_FAILURE, "Couldn't get name of %x", nodeid);
printf("%*sNode %s\n",
level, "", ofc.of_buf);
/* Get all the properties */
ofc.of_buflen = BUFSIZE;
while (ioctl(fd, OFIOCNEXTPROP, &ofc) == 0) {
ofc.of_buf[ofc.of_buflen] = '\0';
printf("%*s Property %-30s\n", level, "",
ofc.of_buf);
swap = ofc.of_name;
ofc.of_name = ofc.of_buf;
ofc.of_namelen = ofc.of_buflen;
ofc.of_buf = swap;
ofc.of_buflen = BUFSIZE;
ret = ioctl(fd, OFIOCGET, &ofc);
if (ret == -1)
err(EXIT_FAILURE, "Couldn't get value "
"of property %s", ofc.of_name);
printprop(&ofc, level);
ofc.of_buflen = BUFSIZE;
}
if (errno != ENOENT)
err(EXIT_FAILURE, "Error getting next property");
/* Find the child pointer and walk it */
childnodeid = nodeid;
ret = ioctl(fd, OFIOCGETCHILD, &childnodeid);
if (ret == -1)
err(EXIT_FAILURE, "Couldn't get child of %x", nodeid);
if (childnodeid != 0)
walknode(fd, childnodeid, level + 2);
/* Find the next sibling */
ret = ioctl(fd, OFIOCGETNEXT, &nodeid);
if (ret == -1)
err(EXIT_FAILURE, "Couldn't get sibling of %x",
nodeid);
}
}
void
printprop(struct ofiocdesc *node, int level)
{
int i, j;
char strbuf[17];
strbuf[16] = '\0';
for (i = 0; i < node->of_buflen; i += 16) {
printf("%*s", level + 2, "");
for (j = 0; j < 16; j++) {
if ((j % 4) == 0)
printf(" ");
if (i + j < node->of_buflen) {
printf("%02x", node->of_buf[i+j]);
strbuf[j] = isprint(node->of_buf[i+j]) ?
node->of_buf[i+j] : '.';
} else {
printf(" ");
strbuf[j] = ' ';
}
}
printf(" %s\n", strbuf);
}
}
static void
usage(void)
{
fprintf(stderr, "usage: walkopenfirm [-n startnode]\n");
exit(1);
}
--=-=-=--