diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2009-11-05 20:32:50 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2009-11-05 20:32:50 +0000 |
commit | 91278afb30123fa565d911dd57793d102f7a23c8 (patch) | |
tree | 4147241d17f76e6d24fa0b5ec813e1625ae76c3d | |
parent | c649240f9d10d50e67c6aeed38b727cc1604b555 (diff) |
Implement -r option that dunps the contents of a PCI ROM to file.
ok oga@
-rw-r--r-- | usr.sbin/pcidump/pcidump.8 | 17 | ||||
-rw-r--r-- | usr.sbin/pcidump/pcidump.c | 50 |
2 files changed, 60 insertions, 7 deletions
diff --git a/usr.sbin/pcidump/pcidump.8 b/usr.sbin/pcidump/pcidump.8 index 6602bc86c82..ebdf0a09d3e 100644 --- a/usr.sbin/pcidump/pcidump.8 +++ b/usr.sbin/pcidump/pcidump.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: pcidump.8,v 1.8 2009/06/05 19:19:02 deraadt Exp $ +.\" $OpenBSD: pcidump.8,v 1.9 2009/11/05 20:32:49 kettenis Exp $ .\" .\" Copyright (c) 2007 Paul de Weerd <weerd@weirdnet.nl> .\" @@ -14,7 +14,7 @@ .\" TORTIOUS ACTION, ARISING OUT OF .\" PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: June 5 2009 $ +.Dd $Mdocdate: November 5 2009 $ .Dt PCIDUMP 8 .Os .Sh NAME @@ -28,6 +28,12 @@ .Sm off .Op Ar bus : dev : func .Sm on +.Nm pcidump +.Fl r Ar file +.Op Fl d Ar pcidev +.Sm off +.Ar bus : dev : func +.Sm on .Sh DESCRIPTION The .Nm @@ -46,6 +52,13 @@ If specified without .Ar bus : dev : func , .Sm on all PCI devices in the domain will be shown. +.It Fl r Ar file +Reads the PCI ROM from the device specified by +.Sm off +.Ar bus : dev : func , +.Sm on +and writes its contents to +.Ar file . .It Fl v Shows detailed information about PCI devices. .It Fl x diff --git a/usr.sbin/pcidump/pcidump.c b/usr.sbin/pcidump/pcidump.c index 6b73c47c91f..c1fcfd39861 100644 --- a/usr.sbin/pcidump/pcidump.c +++ b/usr.sbin/pcidump/pcidump.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pcidump.c,v 1.19 2009/06/07 21:48:16 sobrado Exp $ */ +/* $OpenBSD: pcidump.c,v 1.20 2009/11/05 20:32:49 kettenis Exp $ */ /* * Copyright (c) 2006, 2007 David Gwynne <loki@animata.net> @@ -42,6 +42,7 @@ const char *str2busdevfunc(const char *, int *, int *, int *); int pci_nfuncs(int, int); int pci_read(int, int, int, u_int32_t, u_int32_t *); void dump_caplist(int, int, int, u_int8_t); +int dump_rom(int, int, int); __dead void usage(void) @@ -49,12 +50,13 @@ usage(void) extern char *__progname; fprintf(stderr, - "usage: %s [-v] [-x | -xx] [-d pcidev] [bus:dev:func]\n", + "usage: %s [-v] [-x | -xx] [-d pcidev] [-r file] [bus:dev:func]\n", __progname); exit(1); } int pcifd; +int romfd; int verbose = 0; int hex = 0; @@ -86,15 +88,20 @@ main(int argc, char *argv[]) int nfuncs; int bus, dev, func; char pcidev[MAXPATHLEN] = PCIDEV; + char *romfile = NULL; const char *errstr; int c, error = 0, dumpall = 1, domid = 0; - while ((c = getopt(argc, argv, "d:vx")) != -1) { + while ((c = getopt(argc, argv, "d:r:vx")) != -1) { switch (c) { case 'd': strlcpy(pcidev, optarg, sizeof(pcidev)); dumpall = 0; break; + case 'r': + romfile = optarg; + dumpall = 0; + break; case 'v': verbose = 1; break; @@ -108,9 +115,15 @@ main(int argc, char *argv[]) argc -= optind; argv += optind; - if (argc > 1) + if (argc > 1 || (romfile && argc != 1)) usage(); + if (romfile) { + romfd = open(romfile, O_WRONLY|O_CREAT|O_TRUNC, 0777); + if (romfd == -1) + err(1, "%s", romfile); + } + if (argc == 1) dumpall = 0; @@ -118,7 +131,6 @@ main(int argc, char *argv[]) pcifd = open(pcidev, O_RDONLY, 0777); if (pcifd == -1) err(1, "%s", pcidev); - printf("Domain %s:\n", pcidev); } else { for (;;) { snprintf(pcidev, 16, "/dev/pci%d", domid++); @@ -144,12 +156,15 @@ main(int argc, char *argv[]) nfuncs = pci_nfuncs(bus, dev); if (nfuncs == -1 || func > nfuncs) error = ENXIO; + else if (romfile) + error = dump_rom(bus, dev, func); else error = probe(bus, dev, func); if (error != 0) errx(1, "\"%s\": %s", argv[0], strerror(error)); } else { + printf("Domain %s:\n", pcidev); scanpcidomain(); } @@ -590,3 +605,28 @@ pci_read(int bus, int dev, int func, u_int32_t reg, u_int32_t *val) return (0); } + +int +dump_rom(int bus, int dev, int func) +{ + struct pci_rom rom; + + bzero(&rom, sizeof(rom)); + rom.pr_sel.pc_bus = bus; + rom.pr_sel.pc_dev = dev; + rom.pr_sel.pc_func = func; + if (ioctl(pcifd, PCIOCGETROMLEN, &rom)) + return (errno); + + rom.pr_rom = malloc(rom.pr_romlen); + if (rom.pr_rom == NULL) + return (ENOMEM); + + if (ioctl(pcifd, PCIOCGETROM, &rom)) + return (errno); + + if (write(romfd, rom.pr_rom, rom.pr_romlen) == -1) + return (errno); + + return (0); +} |