From 75271fb340fc41a6efe7d24218933246718eea3f Mon Sep 17 00:00:00 2001 From: sam Date: Thu, 5 Feb 2009 18:15:20 +0000 Subject: [PATCH] add cfi test tool Sponsored by: Carlson Wireless Reviewed by: imp, Chris Andreson --- tools/tools/README | 1 + tools/tools/cfi/Makefile | 7 ++ tools/tools/cfi/cfi.c | 156 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 164 insertions(+) create mode 100644 tools/tools/cfi/Makefile create mode 100644 tools/tools/cfi/cfi.c diff --git a/tools/tools/README b/tools/tools/README index c00cf2a1638b..9190f6bddde9 100644 --- a/tools/tools/README +++ b/tools/tools/README @@ -12,6 +12,7 @@ ansify Convert K&R-style function definitions to ANSI style ath Tools specific to the Atheros 802.11 support backout_commit A tool for reading in a commit message and generating a script that will backout the commit. +cfi Common Flash Interface (CFI) tool commitsdb A tool for reconstructing commit history using md5 checksums of the commit logs. crypto Test and exercise tools related to the crypto framework diff --git a/tools/tools/cfi/Makefile b/tools/tools/cfi/Makefile new file mode 100644 index 000000000000..9e3bbef4110e --- /dev/null +++ b/tools/tools/cfi/Makefile @@ -0,0 +1,7 @@ +# $FreeBSD$ + +PROG= cfi +BINDIR= /usr/local/bin +NO_MAN= + +.include diff --git a/tools/tools/cfi/cfi.c b/tools/tools/cfi/cfi.c new file mode 100644 index 000000000000..5b20094f7d8e --- /dev/null +++ b/tools/tools/cfi/cfi.c @@ -0,0 +1,156 @@ +/*- + * Copyright (c) 2009 Sam Leffler, Errno Consulting + * 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, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any + * redistribution must be conditioned upon including a substantially + * similar Disclaimer requirement for further binary redistribution. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES. + * + * $FreeBSD$ + */ + +/* + * cfi [-f device] op + * (default device is /dev/cfi0). + */ +#include +#include +#include +#include + +#include +#include +#include + +const char *progname; +const char *dvname; + +static void +usage(void) +{ + int i; + + fprintf(stderr, "usage: %s [-f device] op...\n", progname); + fprintf(stderr, "where op's are:\n"); + fprintf(stderr, "fact\t\tread factory PR segment\n"); + fprintf(stderr, "oem\t\tread OEM segment\n"); + fprintf(stderr, "woem value\twrite OEM segment\n"); + fprintf(stderr, "plr\t\tread PLR\n"); + fprintf(stderr, "wplr\t\twrite PLR\n"); + exit(-1); +} + +static int +getfd(int mode) +{ + int fd = open(dvname, mode, 0); + if (fd < 0) + err(-1, "open"); + return fd; +} + +static uint64_t +getfactorypr(void) +{ + uint64_t v; + int fd = getfd(O_RDONLY); + if (ioctl(fd, CFIOCGFACTORYPR, &v) < 0) + err(-1, "ioctl(CFIOCGFACTORYPR)"); + close(fd); + return v; +} + +static uint64_t +getoempr(void) +{ + uint64_t v; + int fd = getfd(O_RDONLY); + if (ioctl(fd, CFIOCGOEMPR, &v) < 0) + err(-1, "ioctl(CFIOCGOEMPR)"); + close(fd); + return v; +} + +static void +setoempr(uint64_t v) +{ + int fd = getfd(O_WRONLY); + if (ioctl(fd, CFIOCSOEMPR, &v) < 0) + err(-1, "ioctl(CFIOCGOEMPR)"); + close(fd); +} + +static uint32_t +getplr(void) +{ + uint32_t plr; + int fd = getfd(O_RDONLY); + if (ioctl(fd, CFIOCGPLR, &plr) < 0) + err(-1, "ioctl(CFIOCGPLR)"); + close(fd); + return plr; +} + +static void +setplr(void) +{ + int fd = getfd(O_WRONLY); + if (ioctl(fd, CFIOCSPLR, 0) < 0) + err(-1, "ioctl(CFIOCPLR)"); + close(fd); +} + +int +main(int argc, char *argv[]) +{ + dvname = getenv("CFI"); + if (dvname == NULL) + dvname = "/dev/cfi0"; + progname = argv[0]; + if (argc > 1) { + if (strcmp(argv[1], "-f") == 0) { + if (argc < 2) + errx(1, "missing device name for -f option"); + dvname = argv[2]; + argc -= 2, argv += 2; + } else if (strcmp(argv[1], "-?") == 0) + usage(); + } + for (; argc > 1; argc--, argv++) { + if (strcasecmp(argv[1], "fact") == 0) { + printf("0x%llx\n", (unsigned long long) getfactorypr()); + } else if (strcasecmp(argv[1], "oem") == 0) { + printf("0x%llx\n", (unsigned long long) getoempr()); + } else if (strcasecmp(argv[1], "woem") == 0) { + if (argc < 2) + errx(1, "missing value for woem"); + setoempr((uint64_t) strtoull(argv[2], NULL, 0)); + argc--, argv++; + } else if (strcasecmp(argv[1], "plr") == 0) { + printf("0x%x\n", getplr()); + } else if (strcasecmp(argv[1], "wplr") == 0) { + setplr(); + } else + usage(); + } +}