Move CLI portion of nvramtool into cli/ subdirectory as first step towards librarization.

Also: update one regex wrapper user.

Signed-off-by: Patrick Georgi <patrick.georgi@secunet.com>
Acked-by: Stefan Reinauer <stefan.reinauer@coreboot.org>


git-svn-id: svn://svn.coreboot.org/coreboot/trunk@6310 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
This commit is contained in:
Patrick Georgi
2011-01-28 07:47:10 +00:00
committed by Patrick Georgi
parent c7ca3e5ca4
commit c6d2b09f76
5 changed files with 10 additions and 7 deletions

View File

@@ -0,0 +1,254 @@
.\"***************************************************************************\
.\" nvramtool.8
.\"***************************************************************************
.\" Copyright (C) 2002, 2003 The Regents of the University of California.
.\" Produced at the Lawrence Livermore National Laboratory.
.\" Written by David S. Peterson <dsp@llnl.gov> <dave_peterson@pobox.com>.
.\" UCRL-CODE-2003-012
.\" All rights reserved.
.\"
.\" This file is part of nvramtool, a utility for reading/writing coreboot
.\" parameters and displaying information from the coreboot table.
.\" For details, see http://coreboot.org/nvramtool.
.\"
.\" Please also read the file DISCLAIMER which is included in this software
.\" distribution.
.\"
.\" This program is free software; you can redistribute it and/or modify it
.\" under the terms of the GNU General Public License (as published by the
.\" Free Software Foundation) version 2, dated June 1991.
.\"
.\" This program is distributed in the hope that it will be useful, but
.\" WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
.\" conditions of the GNU General Public License for more details.
.\"
.\" You should have received a copy of the GNU General Public License along
.\" with this program; if not, write to the Free Software Foundation, Inc.,
.\" 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
.\"***************************************************************************/
.TH NVRAMTOOL 8 "September 2008"
.SH NAME
nvramtool \- read/write coreboot-related information
.SH SYNOPSIS
.B "nvramtool [OPTS] [-n] -r NAME"
.br
.B "nvramtool [OPTS] -e NAME"
.br
.B "nvramtool [OPTS] -a"
.br
.B "nvramtool [OPTS] -w NAME=VALUE"
.br
.B "nvramtool [OPTS] -p INPUT_FILE"
.br
.B "nvramtool [OPTS] -i"
.br
.B "nvramtool [OPTS] -c [VALUE]"
.br
.B "nvramtool [OPTS] -l [ARG]"
.br
.B "nvramtool [OPTS] -d"
.br
.B "nvramtool [OPTS] -Y"
.br
.B "nvramtool [OPTS] -b OUTPUT_FILE"
.br
.B "nvramtool [OPTS] -B INPUT_FILE"
.br
.B "nvramtool [OPTS] -x"
.br
.B "nvramtool [OPTS] -X DUMPFILE"
.br
.B "nvramtool [OPTS] -v"
.br
.B "nvramtool [OPTS] -h"
.SH DESCRIPTION
.B "nvramtool"
is a utility for reading/writing coreboot parameters and displaying
information from the coreboot table.
The coreboot table resides in low physical memory. It is created at boot
time by coreboot, and contains various system information such as the type
of mainboard in use. It specifies locations in the CMOS (nonvolatile RAM)
where the coreboot parameters are stored.
This program is intended for (x86-based) systems that use coreboot. For
information about coreboot, see
.br
http://www.coreboot.org/.
.SH PARAMETERS
.TP
.B "[-n] -r NAME"
Show the value of the coreboot parameter given by
.B "NAME."
If
.B "-n"
is specified, show only the value. Otherwise show both parameter name and
value.
.TP
.B "-e NAME"
Show all possible values for parameter given by
.B "NAME."
.TP
.B "-a"
Show the names and values for all coreboot parameters.
.TP
.B "-w NAME=VALUE"
Assign
.B "VALUE"
to coreboot parameter given by
.B "NAME."
.TP
.B "-p INPUT_FILE"
Assign values to coreboot parameters according to the contents of
.B "INPUT_FILE."
The format of this file is described below.
.TP
.B "-i"
This is similar to the
.B "-p"
option, except that the contents of the input file are taken from standard
input.
.TP
.B "-c [VALUE]"
If
.B "VALUE"
is present then set the CMOS checksum for the coreboot parameters to
.B "VALUE."
Otherwise, show the checksum value.
.TP
.B "-l [ARG]"
If
.B "ARG"
is present then show information from the coreboot table as specified by
.B "ARG."
Otherwise show all possible values for
.B "ARG."
.TP
.B "-d"
Do a low-level dump of the coreboot table.
.TP
.B "-Y"
Write CMOS layout information to standard output. If redirected to a file,
the layout information may be used as input for the
.B "'-y LAYOUT_FILE'"
option (see below).
.TP
.B "-b OUTPUT_FILE"
Write the contents of CMOS memory to the binary file
.B "OUTPUT_FILE."
The first 14 bytes of
.B "OUTPUT_FILE"
do not contain actual CMOS data, and are always written as zeros. This is
because the first 14 bytes of the CMOS area do not contain CMOS memory. These
bytes are involved with the functioning of the real time clock.
.TP
.B "-B INPUT_FILE"
Read binary data from
.B "INPUT_FILE"
and write the data to CMOS memory. The first 14 bytes of
.B "INPUT_FILE"
are skipped and data is written to CMOS starting at the 15th byte of the CMOS
area. This is because the first 14 bytes of the CMOS area do not contain CMOS
memory. These bytes are involved with the functioning of the real time clock.
.TP
.B "-x"
Show a hex dump of all CMOS data. The first 14 bytes of the dump do not
contain actual CMOS data, and are always shown as zeros. This is because the
first 14 bytes of the CMOS area do not contain CMOS memory. These bytes are
involved with the functioning of the real time clock.
.TP
.B "-X DUMPFILE"
Read binary data from
.B "DUMPFILE"
(presumably a CMOS dumpfile created using the
.B "-b OUTPUT_FILE"
option) and show a hex dump of the data.
.TP
.B "-v"
Show version information for this program.
.TP
.B "-h"
Show a help message for this program.
.SH "OPTIONS"
In all cases above,
.B "[OPTS]"
evaluates to the following:
.B " [-y LAYOUT_FILE | -t]"
The
.B "'-y LAYOUT_FILE'"
option tells nvramtool to obtain CMOS layout information from the contents of
.B "LAYOUT_FILE."
Likewise, the
.B "'-t'"
option tells nvramtool to obtain CMOS layout information from the CMOS option
table (contained within the coreboot table). If neither option is
specified, the CMOS option table is used by default.
.B "LAYOUT_FILE"
follows the format of the
.B "cmos.layout"
files provided by coreboot.
If the coreboot installed on your system was built without specifying
.B "CONFIG_HAVE_OPTION_TABLE,"
then the coreboot table will not contain a CMOS option table. In this case,
the
.B "'-y LAYOUT_FILE'"
option must be used.
These two options are silently ignored when used in combination with other
options (such as
.B "-h,"
for instance) for which they are not applicable.
.SH FILE FORMAT
For the
.B "-p"
option,
.B "INPUT_FILE"
must consist of a sequence of lines such that each line is either a blank
line, a comment, or an assignment. A blank line consists only of zero or
more whitespace characters (spaces and tabs). A comment is constructed as
follows:
.B " [ws]#[text]"
Here,
.B "[ws]"
indicates optional whitespace characters and
.B "[text]"
indicates optional text. Blank lines and comments are both ignored. An
assignment is constructed as follows:
.B " [ws]NAME[ws]=[ws]VALUE[ws]"
Here,
.B "NAME"
is the name of a coreboot parameter and
.B "VALUE"
is the value that will be assigned to
.B "NAME."
.B "VALUE"
is allowed to contain whitespace characters, but it must begin and end with
nonwhitespace characters. Note that each comment must appear on a line by
itself. If you attempt to add a comment to the end of an assignment, then the
comment will be interpreted as part of
.B "VALUE."
It is useful to observe that the output produced by both the
.B "-a"
and the
.B "'[-n] NAME'"
options (without
.B "-n"
specified) adheres to this file format.
.SH BUGS
This program does not implement any type of synchronization to ensure that
different processes don't stomp on each other when trying to access the
nonvolatile RAM simultaneously. Therefore, corruption of the BIOS parameter
values may occur if multiple instances of this program are executed
concurrently.
.SH AUTHORS
David S. Peterson <dsp@llnl.gov> <dave_peterson@pobox.com>
.br
Stefan Reinauer <stepan@coresystems.de>

View File

@@ -0,0 +1,863 @@
/*****************************************************************************\
* nvramtool.c
*****************************************************************************
* Copyright (C) 2002-2005 The Regents of the University of California.
* Produced at the Lawrence Livermore National Laboratory.
* Written by Dave Peterson <dsp@llnl.gov> <dave_peterson@pobox.com>.
* UCRL-CODE-2003-012
* All rights reserved.
*
* This file is part of nvramtool, a utility for reading/writing coreboot
* parameters and displaying information from the coreboot table.
* For details, see http://coreboot.org/nvramtool.
*
* Please also read the file DISCLAIMER which is included in this software
* distribution.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License (as published by the
* Free Software Foundation) version 2, dated June 1991.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
* conditions of the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
\*****************************************************************************/
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include "common.h"
#include "opts.h"
#include "lbtable.h"
#include "layout.h"
#include "layout_file.h"
#include "input_file.h"
#include "cmos_ops.h"
#include "cmos_lowlevel.h"
#include "reg_expr.h"
#include "hexdump.h"
#include "cbfs.h"
typedef void (*op_fn_t) (void);
static void op_show_version(void);
static void op_show_usage(void);
static void op_lbtable_show_info(void);
static void op_lbtable_dump(void);
static void op_show_param_values(void);
static void op_cmos_show_one_param(void);
static void op_cmos_show_all_params(void);
static void op_cmos_set_one_param(void);
static void op_cmos_set_params_stdin(void);
static void op_cmos_set_params_file(void);
static void op_cmos_checksum(void);
static void op_show_layout(void);
static void op_write_cmos_dump(void);
static void op_read_cmos_dump(void);
static void op_show_cmos_hex_dump(void);
static void op_show_cmos_dumpfile(void);
static int list_one_param(const char name[], int show_name);
static int list_all_params(void);
static void list_param_enums(const char name[]);
static void set_one_param(const char name[], const char value[]);
static void set_params(FILE * f);
static void parse_assignment(char arg[], const char **name, const char **value);
static int list_cmos_entry(const cmos_entry_t * e, int show_name);
static uint16_t convert_checksum_value(const char value[]);
static const op_fn_t op_fns[] = { op_show_version,
op_show_usage,
op_lbtable_show_info,
op_lbtable_dump,
op_show_param_values,
op_cmos_show_one_param,
op_cmos_show_all_params,
op_cmos_set_one_param,
op_cmos_set_params_stdin,
op_cmos_set_params_file,
op_cmos_checksum,
op_show_layout,
op_write_cmos_dump,
op_read_cmos_dump,
op_show_cmos_hex_dump,
op_show_cmos_dumpfile
};
static const hexdump_format_t cmos_dump_format =
{ 16, 2, "", " | ", " ", " | ", '.' };
/****************************************************************************
* main
****************************************************************************/
int main(int argc, char *argv[])
{
void *cmos_default = NULL;
cmos_layout_get_fn_t fn = get_layout_from_cmos_table;
parse_nvramtool_args(argc, argv);
if (nvramtool_op_modifiers[NVRAMTOOL_MOD_USE_CMOS_LAYOUT_FILE].found) {
set_layout_filename(nvramtool_op_modifiers
[NVRAMTOOL_MOD_USE_CMOS_LAYOUT_FILE].param);
fn = get_layout_from_file;
} else if (nvramtool_op_modifiers[NVRAMTOOL_MOD_USE_CMOS_OPT_TABLE].found) {
fn = get_layout_from_cmos_table;
} else if (nvramtool_op_modifiers[NVRAMTOOL_MOD_USE_CBFS_FILE].found) {
open_cbfs(nvramtool_op_modifiers[NVRAMTOOL_MOD_USE_CBFS_FILE].param);
if (!nvramtool_op_modifiers[NVRAMTOOL_MOD_USE_CMOS_FILE].found) {
cmos_default = cbfs_find_file("cmos.default", CBFS_COMPONENT_CMOS_DEFAULT, NULL);
if (cmos_default == NULL) {
fprintf(stderr, "Need a cmos.default in the CBFS image or separate cmos file (-D).\n");
exit(1);
}
}
}
if (nvramtool_op_modifiers[NVRAMTOOL_MOD_USE_CMOS_FILE].found) {
int fd;
struct stat fd_stat;
if ((fd = open(nvramtool_op_modifiers[NVRAMTOOL_MOD_USE_CMOS_FILE].param, O_RDWR | O_CREAT, 0666)) < 0) {
fprintf(stderr, "Couldn't open '%s'\n", nvramtool_op_modifiers[NVRAMTOOL_MOD_USE_CMOS_FILE].param);
exit(1);
}
if (fstat(fd, &fd_stat) == -1) {
fprintf(stderr, "Couldn't stat '%s'\n", nvramtool_op_modifiers[NVRAMTOOL_MOD_USE_CMOS_FILE].param);
exit(1);
}
if (fd_stat.st_size < 128) {
lseek(fd, 127, SEEK_SET);
write(fd, "\0", 1);
fsync(fd);
}
cmos_default = mmap(NULL, 128, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (cmos_default == MAP_FAILED) {
fprintf(stderr, "Couldn't map '%s'\n", nvramtool_op_modifiers[NVRAMTOOL_MOD_USE_CMOS_FILE].param);
exit(1);
}
}
if (cmos_default) {
select_hal(HAL_MEMORY, cmos_default);
fn = get_layout_from_cbfs_file;
}
register_cmos_layout_get_fn(fn);
op_fns[nvramtool_op.op] ();
return 0;
}
/****************************************************************************
* op_show_version
*
* -v
*
* Show version information for this program.
****************************************************************************/
static void op_show_version(void)
{
printf("This is %s version %s.\n", prog_name, prog_version);
}
/****************************************************************************
* op_show_usage
*
* -h
*
* Show a usage message for this program.
****************************************************************************/
static void op_show_usage(void)
{
usage(stdout);
}
/****************************************************************************
* op_lbtable_show_info
*
* -l [ARG]
*
* If ARG is present, show coreboot table information specified by ARG.
* Else show all possible values for ARG.
****************************************************************************/
static void op_lbtable_show_info(void)
{
if (nvramtool_op.param == NULL)
list_lbtable_choices();
else {
get_lbtable();
list_lbtable_item(nvramtool_op.param);
}
}
/****************************************************************************
* op_lbtable_dump
*
* -d
*
* Do low-level dump of coreboot table.
****************************************************************************/
static void op_lbtable_dump(void)
{
get_lbtable();
dump_lbtable();
}
/****************************************************************************
* op_show_param_values
*
* -e NAME option
*
* Show all possible values for parameter NAME.
****************************************************************************/
static void op_show_param_values(void)
{
get_cmos_layout();
list_param_enums(nvramtool_op.param);
}
/****************************************************************************
* op_cmos_show_one_param
*
* [-n] -r NAME
*
* Show parameter NAME. If -n is specified, show value only. Else show name
* and value.
****************************************************************************/
static void op_cmos_show_one_param(void)
{
int result;
get_cmos_layout();
result = list_one_param(nvramtool_op.param,
!nvramtool_op_modifiers
[NVRAMTOOL_MOD_SHOW_VALUE_ONLY].found);
cmos_checksum_verify();
if (result)
exit(1);
}
/****************************************************************************
* op_cmos_show_all_params
*
* -a
*
* Show names and values for all parameters.
****************************************************************************/
static void op_cmos_show_all_params(void)
{
int result;
get_cmos_layout();
result = list_all_params();
cmos_checksum_verify();
if (result)
exit(1);
}
/****************************************************************************
* op_cmos_set_one_param
*
* -w NAME=VALUE
*
* Set parameter NAME to VALUE.
****************************************************************************/
static void op_cmos_set_one_param(void)
{
const char *name, *value;
get_cmos_layout();
/* Separate 'NAME=VALUE' syntax into two strings representing NAME and
* VALUE.
*/
parse_assignment(nvramtool_op.param, &name, &value);
set_one_param(name, value);
}
/****************************************************************************
* op_cmos_set_params_stdin
*
* -i
*
* Set parameters according to standard input.
****************************************************************************/
static void op_cmos_set_params_stdin(void)
{
get_cmos_layout();
set_params(stdin);
}
/****************************************************************************
* op_cmos_set_params_file
*
* -p INPUT_FILE
*
* Set parameters according to INPUT_FILE.
****************************************************************************/
static void op_cmos_set_params_file(void)
{
FILE *f;
if ((f = fopen(nvramtool_op.param, "r")) == NULL) {
fprintf(stderr, "%s: Can not open file %s for reading: %s\n",
prog_name, nvramtool_op.param, strerror(errno));
exit(1);
}
get_cmos_layout();
set_params(f);
fclose(f);
}
/****************************************************************************
* op_cmos_checksum
*
* -c [VALUE]
*
* If VALUE is present, set coreboot CMOS checksum to VALUE. Else show
* checksum value.
****************************************************************************/
static void op_cmos_checksum(void)
{
uint16_t checksum;
get_cmos_layout();
if (nvramtool_op.param == NULL) {
set_iopl(3);
checksum = cmos_checksum_read();
set_iopl(0);
printf("0x%x\n", checksum);
} else {
checksum = convert_checksum_value(nvramtool_op.param);
set_iopl(3);
cmos_checksum_write(checksum);
set_iopl(0);
}
}
/****************************************************************************
* op_show_layout
*
* -Y
*
* Write CMOS layout information to standard output.
****************************************************************************/
static void op_show_layout(void)
{
get_cmos_layout();
write_cmos_layout(stdout);
}
/****************************************************************************
* op_write_cmos_dump
*
* -b OUTPUT_FILE
*
* Write the contents of CMOS memory to a binary file.
****************************************************************************/
static void op_write_cmos_dump(void)
{
unsigned char data[CMOS_SIZE];
FILE *f;
if ((f = fopen(nvramtool_op.param, "w")) == NULL) {
fprintf(stderr, "%s: Can not open file %s for writing: %s\n",
prog_name, nvramtool_op.param, strerror(errno));
exit(1);
}
set_iopl(3);
cmos_read_all(data);
set_iopl(0);
if (fwrite(data, 1, CMOS_SIZE, f) != CMOS_SIZE) {
fprintf(stderr, "%s: Error writing CMOS data to file %s: %s\n",
prog_name, nvramtool_op.param, strerror(errno));
exit(1);
}
fclose(f);
}
/****************************************************************************
* op_read_cmos_dump
*
* -B INPUT_FILE
*
* Read binary data from a file and write the data to CMOS memory.
****************************************************************************/
static void op_read_cmos_dump(void)
{
unsigned char data[CMOS_SIZE];
size_t nr_bytes;
FILE *f;
if ((f = fopen(nvramtool_op.param, "r")) == NULL) {
fprintf(stderr, "%s: Can not open file %s for reading: %s\n",
prog_name, nvramtool_op.param, strerror(errno));
exit(1);
}
if ((nr_bytes = fread(data, 1, CMOS_SIZE, f)) != CMOS_SIZE) {
fprintf(stderr,
"%s: Error: Only able to read %d bytes of CMOS data "
"from file %s. CMOS data is unchanged.\n", prog_name,
(int)nr_bytes, nvramtool_op.param);
exit(1);
}
fclose(f);
set_iopl(3);
cmos_write_all(data);
set_iopl(0);
}
/****************************************************************************
* op_show_cmos_hex_dump
*
* -x
*
* Write a hex dump of CMOS memory to standard output.
****************************************************************************/
static void op_show_cmos_hex_dump(void)
{
unsigned char data[CMOS_SIZE];
set_iopl(3);
cmos_read_all(data);
set_iopl(0);
hexdump(data, CMOS_SIZE, 0, stdout, &cmos_dump_format);
}
/****************************************************************************
* op_show_cmos_dumpfile
*
* -X DUMP_FILE
*
* Read binary data from a file (presumably a CMOS dump file) and display a
* hex dump of the CMOS data from the file.
****************************************************************************/
static void op_show_cmos_dumpfile(void)
{
unsigned char data[CMOS_SIZE];
size_t nr_bytes;
FILE *f;
if ((f = fopen(nvramtool_op.param, "r")) == NULL) {
fprintf(stderr, "%s: Can not open file %s for reading: %s\n",
prog_name, nvramtool_op.param, strerror(errno));
exit(1);
}
nr_bytes = fread(data, 1, CMOS_SIZE, f);
fclose(f);
hexdump(data, nr_bytes, 0, stdout, &cmos_dump_format);
}
/****************************************************************************
* list_one_param
*
* Attempt to list one CMOS parameter given by 'name'. 'show_name' is a
* boolean value indicating whether the parameter name should be displayed
* along with its value. Return 1 if error was encountered. Else return OK.
****************************************************************************/
static int list_one_param(const char name[], int show_name)
{
const cmos_entry_t *e;
if (is_checksum_name(name) || ((e = find_cmos_entry(name)) == NULL)) {
fprintf(stderr, "%s: CMOS parameter %s not found.\n", prog_name,
name);
exit(1);
}
if (e->config == CMOS_ENTRY_RESERVED) {
fprintf(stderr, "%s: Parameter %s is reserved.\n", prog_name,
name);
exit(1);
}
return (list_cmos_entry(e, show_name) != 0);
}
/****************************************************************************
* list_all_params
*
* Attempt to list all CMOS parameters. Return 1 if error was encountered.
* Else return OK.
****************************************************************************/
static int list_all_params(void)
{
const cmos_entry_t *e;
int result;
result = OK;
for (e = first_cmos_entry(); e != NULL; e = next_cmos_entry(e)) {
if ((e->config == CMOS_ENTRY_RESERVED)
|| is_checksum_name(e->name))
continue;
if (list_cmos_entry(e, TRUE))
result = 1;
}
return result;
}
/****************************************************************************
* list_param_enums
*
* List all possible values for CMOS parameter given by 'name'.
****************************************************************************/
static void list_param_enums(const char name[])
{
const cmos_entry_t *e;
const cmos_enum_t *p;
if (is_checksum_name(name) || (e = find_cmos_entry(name)) == NULL) {
fprintf(stderr, "%s: CMOS parameter %s not found.\n", prog_name,
name);
exit(1);
}
switch (e->config) {
case CMOS_ENTRY_ENUM:
for (p = first_cmos_enum_id(e->config_id);
p != NULL; p = next_cmos_enum_id(p))
printf("%s\n", p->text);
break;
case CMOS_ENTRY_HEX:
printf("Parameter %s requires a %u-bit unsigned integer.\n",
name, e->length);
break;
case CMOS_ENTRY_STRING:
printf("Parameter %s requires a %u-byte string.\n", name,
e->length / 8);
break;
case CMOS_ENTRY_RESERVED:
printf("Parameter %s is reserved.\n", name);
break;
default:
BUG();
}
}
/****************************************************************************
* set_one_param
*
* Set the CMOS parameter given by 'name' to 'value'. The 'name' parameter
* is case-sensitive. If we are setting an enum parameter, then 'value' is
* interpreted as a case-sensitive string that must match the option name
* exactly. If we are setting a 'hex' parameter, then 'value' is treated as
* a string representation of an unsigned integer that may be specified in
* decimal, hex, or octal.
****************************************************************************/
static void set_one_param(const char name[], const char value[])
{
const cmos_entry_t *e;
unsigned long long n;
if (is_checksum_name(name) || (e = find_cmos_entry(name)) == NULL) {
fprintf(stderr, "%s: CMOS parameter %s not found.", prog_name,
name);
exit(1);
}
switch (prepare_cmos_write(e, value, &n)) {
case OK:
break;
case CMOS_OP_BAD_ENUM_VALUE:
fprintf(stderr, "%s: Bad value for parameter %s.", prog_name,
name);
goto fail;
case CMOS_OP_NEGATIVE_INT:
fprintf(stderr,
"%s: This program does not support assignment of negative "
"numbers to coreboot parameters.", prog_name);
goto fail;
case CMOS_OP_INVALID_INT:
fprintf(stderr, "%s: %s is not a valid integer.", prog_name,
value);
goto fail;
case CMOS_OP_RESERVED:
fprintf(stderr,
"%s: Can not modify reserved coreboot parameter %s.",
prog_name, name);
goto fail;
case CMOS_OP_VALUE_TOO_WIDE:
fprintf(stderr,
"%s: Can not write value %s to CMOS parameter %s that is "
"only %d bits wide.", prog_name, value, name,
e->length);
goto fail;
case CMOS_OP_NO_MATCHING_ENUM:
fprintf(stderr,
"%s: coreboot parameter %s has no matching enums.",
prog_name, name);
goto fail;
case CMOS_AREA_OUT_OF_RANGE:
fprintf(stderr,
"%s: The CMOS area specified by the layout info for "
"coreboot parameter %s is out of range.", prog_name,
name);
goto fail;
case CMOS_AREA_OVERLAPS_RTC:
fprintf(stderr,
"%s: The CMOS area specified by the layout info for "
"coreboot parameter %s overlaps the realtime clock area.",
prog_name, name);
goto fail;
case CMOS_AREA_TOO_WIDE:
fprintf(stderr,
"%s: The CMOS area specified by the layout info for "
"coreboot parameter %s is too wide.", prog_name, name);
goto fail;
default:
fprintf(stderr,
"%s: Unknown error encountered while attempting to modify "
"coreboot parameter %s.", prog_name, name);
goto fail;
}
/* write the value to nonvolatile RAM */
set_iopl(3);
cmos_write(e, n);
cmos_checksum_write(cmos_checksum_compute());
set_iopl(0);
return;
fail:
fprintf(stderr, " CMOS write not performed.\n");
exit(1);
}
/****************************************************************************
* set_params
*
* Set coreboot parameters according to the contents of file 'f'.
****************************************************************************/
static void set_params(FILE * f)
{ /* First process the input file. Then perform writes only if there were
* no problems processing the input. Either all values will be written
* successfully or no values will be written.
*/
do_cmos_writes(process_input_file(f));
}
/****************************************************************************
* parse_assignment
*
* Parse the string 'arg' (which supposedly represents an assignment) into a
* NAME and a VALUE. If 'arg' does not conform to the proper assignment
* syntax, exit with a usage message. Otherwise, on return, 'arg' is broken
* into substrings representing NAME and VALUE, and *name and *value are set
* to point to these two substrings.
****************************************************************************/
static void parse_assignment(char arg[], const char **name, const char **value)
{
static const size_t N_MATCHES = 4;
regmatch_t match[N_MATCHES];
regex_t assignment;
compile_reg_expr(REG_EXTENDED | REG_NEWLINE, assignment_regex, &assignment);
/* Does 'arg' conform to proper assignment syntax? If not, exit with a
* usage message.
*/
if (regexec(&assignment, arg, N_MATCHES, match, 0))
usage(stderr);
/* Ok, we found a valid assignment. Break it into two strings
* representing NAME and VALUE.
*/
arg[match[1].rm_eo] = '\0';
arg[match[2].rm_eo] = '\0';
*name = &arg[match[1].rm_so];
*value = &arg[match[2].rm_so];
regfree(&assignment);
}
/****************************************************************************
* list_cmos_entry
*
* Attempt to list the CMOS entry represented by 'e'. 'show_name' is a
* boolean value indicating whether the parameter name should be displayed
* along with its value. On success, return OK. On error, print an error
* message and return 1.
****************************************************************************/
static int list_cmos_entry(const cmos_entry_t * e, int show_name)
{
const cmos_enum_t *p;
unsigned long long value;
char *w;
/* sanity check CMOS entry */
switch (prepare_cmos_read(e)) {
case OK:
break;
case CMOS_OP_RESERVED:
BUG();
case CMOS_AREA_OUT_OF_RANGE:
fprintf(stderr,
"%s: Can not read coreboot parameter %s because "
"layout info specifies out of range CMOS area.\n",
prog_name, e->name);
return 1;
case CMOS_AREA_OVERLAPS_RTC:
fprintf(stderr,
"%s: Can not read coreboot parameter %s because "
"layout info specifies CMOS area that overlaps realtime "
"clock area.\n", prog_name, e->name);
return 1;
case CMOS_AREA_TOO_WIDE:
fprintf(stderr,
"%s: Can not read coreboot parameter %s because "
"layout info specifies CMOS area that is too wide.\n",
prog_name, e->name);
return 1;
default:
fprintf(stderr,
"%s: Unknown error encountered while attempting to "
"read coreboot parameter %s\n", prog_name, e->name);
return 1;
}
/* read the value from CMOS */
set_iopl(3);
value = cmos_read(e);
set_iopl(0);
/* display the value */
switch (e->config) {
case CMOS_ENTRY_ENUM:
if ((p = find_cmos_enum(e->config_id, value)) == NULL) {
if (show_name)
printf("# Bad value -> %s = 0x%llx\n", e->name,
value);
else
printf("Bad value -> 0x%llx\n", value);
} else {
if (show_name)
printf("%s = %s\n", e->name, p->text);
else
printf("%s\n", p->text);
}
break;
case CMOS_ENTRY_HEX:
if (show_name)
printf("%s = 0x%llx\n", e->name, value);
else
printf("0x%llx\n", value);
break;
case CMOS_ENTRY_STRING:
w = (char *)(unsigned long)value;
while (*w) {
if(!isprint(*w)) {
if (show_name)
printf("# Bad value -> %s\n", e->name);
else
printf("Bad value\n");
break;
}
w++;
}
if (!*w) {
if (show_name)
printf("%s = %s\n", e->name,
(char *)(unsigned long)value);
else
printf("%s\n", (char *)(unsigned long)value);
}
free((void *)(unsigned long)value);
break;
case CMOS_ENTRY_RESERVED:
default:
BUG();
}
return OK;
}
/****************************************************************************
* convert_checksum_value
*
* 'value' is the string representation of a checksum value that the user
* wishes to set using the -c option. Convert the string to a 16-bit
* unsigned integer and return the result. Exit with an error message if
* 'value' is invalid.
****************************************************************************/
static uint16_t convert_checksum_value(const char value[])
{
unsigned long n;
const char *p;
uint16_t result;
int negative;
for (p = value; isspace(*p); p++) ;
negative = (*p == '-');
n = strtoul(value, (char **)&p, 0);
if (*p) {
fprintf(stderr,
"%s: Checksum value %s is not a valid integer.\n",
prog_name, value);
exit(1);
}
if (negative) {
fprintf(stderr,
"%s: Checksum must be an unsigned integer.\n",
prog_name);
exit(1);
}
result = (uint16_t) n;
if (result != n) {
fprintf(stderr,
"%s: Checksum value must fit within 16 bits.\n",
prog_name);
exit(1);
}
return result;
}

259
util/nvramtool/cli/opts.c Normal file
View File

@@ -0,0 +1,259 @@
/*****************************************************************************\
* opts.c
*****************************************************************************
* Copyright (C) 2002-2005 The Regents of the University of California.
* Produced at the Lawrence Livermore National Laboratory.
* Written by Dave Peterson <dsp@llnl.gov> <dave_peterson@pobox.com>.
* UCRL-CODE-2003-012
* All rights reserved.
*
* This file is part of nvramtool, a utility for reading/writing coreboot
* parameters and displaying information from the coreboot table.
* For details, see http://coreboot.org/nvramtool.
*
* Please also read the file DISCLAIMER which is included in this software
* distribution.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License (as published by the
* Free Software Foundation) version 2, dated June 1991.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
* conditions of the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
\*****************************************************************************/
#include "common.h"
#include "opts.h"
nvramtool_op_info_t nvramtool_op;
nvramtool_op_modifier_info_t nvramtool_op_modifiers[NVRAMTOOL_NUM_OP_MODIFIERS];
static char *handle_optional_arg(int argc, char *argv[]);
static void register_op(int *op_found, nvramtool_op_t op, char op_param[]);
static void register_op_modifier(nvramtool_op_modifier_t mod, char mod_param[]);
static void resolve_op_modifiers(void);
static void sanity_check_args(void);
static const char getopt_string[] = "-ab:B:c::C:dD:e:hil::np:r:tvw:xX:y:Y";
/****************************************************************************
* parse_nvramtool_args
*
* Parse command line arguments.
****************************************************************************/
void parse_nvramtool_args(int argc, char *argv[])
{
nvramtool_op_modifier_info_t *mod_info;
int i, op_found;
char c;
for (i = 0, mod_info = nvramtool_op_modifiers;
i < NVRAMTOOL_NUM_OP_MODIFIERS; i++, mod_info++) {
mod_info->found = FALSE;
mod_info->found_seq = 0;
mod_info->param = NULL;
}
op_found = FALSE;
opterr = 0;
do {
switch (c = getopt(argc, argv, getopt_string)) {
case 'a':
register_op(&op_found,
NVRAMTOOL_OP_CMOS_SHOW_ALL_PARAMS, NULL);
break;
case 'b':
register_op(&op_found, NVRAMTOOL_OP_WRITE_CMOS_DUMP,
optarg);
break;
case 'B':
register_op(&op_found, NVRAMTOOL_OP_READ_CMOS_DUMP,
optarg);
break;
case 'c':
register_op(&op_found, NVRAMTOOL_OP_CMOS_CHECKSUM,
handle_optional_arg(argc, argv));
break;
case 'C':
register_op_modifier(NVRAMTOOL_MOD_USE_CBFS_FILE,
optarg);
break;
case 'd':
register_op(&op_found, NVRAMTOOL_OP_LBTABLE_DUMP, NULL);
break;
case 'D':
register_op_modifier(NVRAMTOOL_MOD_USE_CMOS_FILE,
optarg);
break;
case 'e':
register_op(&op_found, NVRAMTOOL_OP_SHOW_PARAM_VALUES,
optarg);
break;
case 'h':
register_op(&op_found, NVRAMTOOL_OP_SHOW_USAGE, NULL);
break;
case 'i':
register_op(&op_found,
NVRAMTOOL_OP_CMOS_SET_PARAMS_STDIN, NULL);
break;
case 'l':
register_op(&op_found, NVRAMTOOL_OP_LBTABLE_SHOW_INFO,
handle_optional_arg(argc, argv));
break;
case 'n':
register_op_modifier(NVRAMTOOL_MOD_SHOW_VALUE_ONLY,
NULL);
break;
case 'p':
register_op(&op_found,
NVRAMTOOL_OP_CMOS_SET_PARAMS_FILE, optarg);
break;
case 'r':
register_op(&op_found, NVRAMTOOL_OP_CMOS_SHOW_ONE_PARAM,
optarg);
break;
case 't':
register_op_modifier(NVRAMTOOL_MOD_USE_CMOS_OPT_TABLE,
NULL);
break;
case 'v':
register_op(&op_found, NVRAMTOOL_OP_SHOW_VERSION, NULL);
break;
case 'w':
register_op(&op_found, NVRAMTOOL_OP_CMOS_SET_ONE_PARAM,
optarg);
break;
case 'x':
register_op(&op_found, NVRAMTOOL_OP_SHOW_CMOS_HEX_DUMP,
NULL);
break;
case 'X':
register_op(&op_found, NVRAMTOOL_OP_SHOW_CMOS_DUMPFILE,
optarg);
break;
case 'y':
register_op_modifier(NVRAMTOOL_MOD_USE_CMOS_LAYOUT_FILE,
optarg);
break;
case 'Y':
register_op(&op_found, NVRAMTOOL_OP_SHOW_LAYOUT, NULL);
break;
case -1: /* no more command line args */
break;
case '?': /* unknown option found */
case 1: /* nonoption command line arg found */
default:
usage(stderr);
break;
}
} while (c != -1);
if (!op_found)
usage(stderr);
resolve_op_modifiers();
sanity_check_args();
}
/****************************************************************************
* handle_optional_arg
*
* Handle a command line option with an optional argument.
****************************************************************************/
static char *handle_optional_arg(int argc, char *argv[])
{
char *arg;
if (optarg != NULL) {
/* optional arg is present and arg was specified as
* "-zarg" (with no whitespace between "z" and "arg"),
* where -z is the option and "arg" is the value of the
* optional arg
*/
return optarg;
}
if ((argv[optind] == NULL) || (argv[optind][0] == '-'))
return NULL;
arg = argv[optind]; /* optional arg is present */
/* This call to getopt yields the optional arg we just found,
* which we want to skip.
*/
getopt(argc, argv, getopt_string);
return arg;
}
/****************************************************************************
* register_op
*
* Store the user's selection of which operation this program should perform.
****************************************************************************/
static void register_op(int *op_found, nvramtool_op_t op, char op_param[])
{
if (*op_found && (op != nvramtool_op.op))
usage(stderr);
*op_found = TRUE;
nvramtool_op.op = op;
nvramtool_op.param = op_param;
}
/****************************************************************************
* register_op_modifier
*
* Store information regarding an optional argument specified in addition to
* the user's selection of which operation this program should perform.
****************************************************************************/
static void register_op_modifier(nvramtool_op_modifier_t mod, char mod_param[])
{
static int found_seq = 0;
nvramtool_op_modifier_info_t *mod_info;
mod_info = &nvramtool_op_modifiers[mod];
mod_info->found = TRUE;
mod_info->found_seq = ++found_seq;
mod_info->param = mod_param;
}
/****************************************************************************
* resolve_op_modifiers
*
* If the user specifies multiple arguments that conflict with each other,
* the last specified argument overrides previous conflicting arguments.
****************************************************************************/
static void resolve_op_modifiers(void)
{
if (nvramtool_op_modifiers[NVRAMTOOL_MOD_USE_CMOS_LAYOUT_FILE].found &&
nvramtool_op_modifiers[NVRAMTOOL_MOD_USE_CMOS_OPT_TABLE].found) {
if (nvramtool_op_modifiers[NVRAMTOOL_MOD_USE_CMOS_LAYOUT_FILE].found_seq >
nvramtool_op_modifiers[NVRAMTOOL_MOD_USE_CMOS_OPT_TABLE].found_seq)
nvramtool_op_modifiers
[NVRAMTOOL_MOD_USE_CMOS_OPT_TABLE].found = FALSE;
else
nvramtool_op_modifiers
[NVRAMTOOL_MOD_USE_CMOS_LAYOUT_FILE].found = FALSE;
}
}
/****************************************************************************
* sanity_check_args
*
* Perform sanity checking on command line arguments.
****************************************************************************/
static void sanity_check_args(void)
{
if ((nvramtool_op_modifiers[NVRAMTOOL_MOD_SHOW_VALUE_ONLY].found) &&
(nvramtool_op.op != NVRAMTOOL_OP_CMOS_SHOW_ONE_PARAM))
usage(stderr);
}

79
util/nvramtool/cli/opts.h Normal file
View File

@@ -0,0 +1,79 @@
/*****************************************************************************\
* opts.h
*****************************************************************************
* Copyright (C) 2002-2005 The Regents of the University of California.
* Produced at the Lawrence Livermore National Laboratory.
* Written by Dave Peterson <dsp@llnl.gov> <dave_peterson@pobox.com>.
* UCRL-CODE-2003-012
* All rights reserved.
*
* This file is part of nvramtool, a utility for reading/writing coreboot
* parameters and displaying information from the coreboot table.
* For details, see http://coreboot.org/nvramtool.
*
* Please also read the file DISCLAIMER which is included in this software
* distribution.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License (as published by the
* Free Software Foundation) version 2, dated June 1991.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
* conditions of the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
\*****************************************************************************/
#ifndef OPTS_H
#define OPTS_H
#include "common.h"
typedef enum { NVRAMTOOL_OP_SHOW_VERSION = 0,
NVRAMTOOL_OP_SHOW_USAGE,
NVRAMTOOL_OP_LBTABLE_SHOW_INFO,
NVRAMTOOL_OP_LBTABLE_DUMP,
NVRAMTOOL_OP_SHOW_PARAM_VALUES,
NVRAMTOOL_OP_CMOS_SHOW_ONE_PARAM,
NVRAMTOOL_OP_CMOS_SHOW_ALL_PARAMS,
NVRAMTOOL_OP_CMOS_SET_ONE_PARAM,
NVRAMTOOL_OP_CMOS_SET_PARAMS_STDIN,
NVRAMTOOL_OP_CMOS_SET_PARAMS_FILE,
NVRAMTOOL_OP_CMOS_CHECKSUM,
NVRAMTOOL_OP_SHOW_LAYOUT,
NVRAMTOOL_OP_WRITE_CMOS_DUMP,
NVRAMTOOL_OP_READ_CMOS_DUMP,
NVRAMTOOL_OP_SHOW_CMOS_HEX_DUMP,
NVRAMTOOL_OP_SHOW_CMOS_DUMPFILE
} nvramtool_op_t;
typedef struct {
nvramtool_op_t op;
char *param;
} nvramtool_op_info_t;
typedef enum { NVRAMTOOL_MOD_SHOW_VALUE_ONLY = 0,
NVRAMTOOL_MOD_USE_CMOS_LAYOUT_FILE,
NVRAMTOOL_MOD_USE_CBFS_FILE,
NVRAMTOOL_MOD_USE_CMOS_FILE,
NVRAMTOOL_MOD_USE_CMOS_OPT_TABLE,
NVRAMTOOL_NUM_OP_MODIFIERS /* must always be last */
} nvramtool_op_modifier_t;
typedef struct {
int found;
int found_seq;
char *param;
} nvramtool_op_modifier_info_t;
extern nvramtool_op_info_t nvramtool_op;
extern nvramtool_op_modifier_info_t nvramtool_op_modifiers[];
void parse_nvramtool_args(int argc, char *argv[]);
#endif /* OPTS_H */