nvramtool.c

Go to the documentation of this file.
00001 /*****************************************************************************\
00002  * nvramtool.c
00003  *****************************************************************************
00004  *  Copyright (C) 2002-2005 The Regents of the University of California.
00005  *  Produced at the Lawrence Livermore National Laboratory.
00006  *  Written by Dave Peterson <dsp@llnl.gov> <dave_peterson@pobox.com>.
00007  *  UCRL-CODE-2003-012
00008  *  All rights reserved.
00009  *
00010  *  This file is part of nvramtool, a utility for reading/writing coreboot
00011  *  parameters and displaying information from the coreboot table.
00012  *  For details, see http://coreboot.org/nvramtool.
00013  *
00014  *  Please also read the file DISCLAIMER which is included in this software
00015  *  distribution.
00016  *
00017  *  This program is free software; you can redistribute it and/or modify it
00018  *  under the terms of the GNU General Public License (as published by the
00019  *  Free Software Foundation) version 2, dated June 1991.
00020  *
00021  *  This program is distributed in the hope that it will be useful, but
00022  *  WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
00023  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the terms and
00024  *  conditions of the GNU General Public License for more details.
00025  *
00026  *  You should have received a copy of the GNU General Public License along
00027  *  with this program; if not, write to the Free Software Foundation, Inc.,
00028  *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
00029 \*****************************************************************************/
00030 
00031 #include "common.h"
00032 #include "opts.h"
00033 #include "lbtable.h"
00034 #include "layout.h"
00035 #include "layout_file.h"
00036 #include "input_file.h"
00037 #include "cmos_ops.h"
00038 #include "cmos_lowlevel.h"
00039 #include "reg_expr.h"
00040 #include "hexdump.h"
00041 
00042 typedef void (*op_fn_t) (void);
00043 
00044 static void op_show_version (void);
00045 static void op_show_usage (void);
00046 static void op_lbtable_show_info (void);
00047 static void op_lbtable_dump (void);
00048 static void op_show_param_values (void);
00049 static void op_cmos_show_one_param (void);
00050 static void op_cmos_show_all_params (void);
00051 static void op_cmos_set_one_param (void);
00052 static void op_cmos_set_params_stdin (void);
00053 static void op_cmos_set_params_file (void);
00054 static void op_cmos_checksum (void);
00055 static void op_show_layout (void);
00056 static void op_write_cmos_dump (void);
00057 static void op_read_cmos_dump (void);
00058 static void op_show_cmos_hex_dump (void);
00059 static void op_show_cmos_dumpfile (void);
00060 static int list_one_param (const char name[], int show_name);
00061 static int list_all_params (void);
00062 static void list_param_enums (const char name[]);
00063 static void set_one_param (const char name[], const char value[]);
00064 static void set_params (FILE *f);
00065 static void parse_assignment (char arg[], const char **name,
00066                               const char **value);
00067 static int list_cmos_entry (const cmos_entry_t *e, int show_name);
00068 static uint16_t convert_checksum_value (const char value[]);
00069 
00070 static const op_fn_t op_fns[] =
00071  { op_show_version,
00072    op_show_usage,
00073    op_lbtable_show_info,
00074    op_lbtable_dump,
00075    op_show_param_values,
00076    op_cmos_show_one_param,
00077    op_cmos_show_all_params,
00078    op_cmos_set_one_param,
00079    op_cmos_set_params_stdin,
00080    op_cmos_set_params_file,
00081    op_cmos_checksum,
00082    op_show_layout,
00083    op_write_cmos_dump,
00084    op_read_cmos_dump,
00085    op_show_cmos_hex_dump,
00086    op_show_cmos_dumpfile
00087  };
00088 
00089 static const hexdump_format_t cmos_dump_format =
00090  { 16, 2, "", " | ", " ", " | ", '.', NULL };
00091 
00092 /****************************************************************************
00093  * main
00094  ****************************************************************************/
00095 int main (int argc, char *argv[])
00096  { cmos_layout_get_fn_t fn;
00097 
00098    parse_nvramtool_args(argc, argv);
00099 
00100    if (nvramtool_op_modifiers[NVRAMTOOL_MOD_USE_CMOS_LAYOUT_FILE].found)
00101     { set_layout_filename(
00102             nvramtool_op_modifiers[NVRAMTOOL_MOD_USE_CMOS_LAYOUT_FILE].param);
00103       fn = get_layout_from_file;
00104     }
00105    else
00106       fn = get_layout_from_cmos_table;
00107 
00108    register_cmos_layout_get_fn(fn);
00109    op_fns[nvramtool_op.op]();
00110    return 0;
00111  }
00112 
00113 /****************************************************************************
00114  * op_show_version
00115  *
00116  * -v
00117  *
00118  * Show version information for this program.
00119  ****************************************************************************/
00120 static void op_show_version (void)
00121  { printf("This is %s version %s.\n", prog_name, prog_version); }
00122 
00123 /****************************************************************************
00124  * op_show_usage
00125  *
00126  * -h
00127  *
00128  * Show a usage message for this program.
00129  ****************************************************************************/
00130 static void op_show_usage (void)
00131  { usage(stdout); }
00132 
00133 /****************************************************************************
00134  * op_lbtable_show_info
00135  *
00136  * -l [ARG]
00137  *
00138  * If ARG is present, show coreboot table information specified by ARG.
00139  * Else show all possible values for ARG.
00140  ****************************************************************************/
00141 static void op_lbtable_show_info (void)
00142  { if (nvramtool_op.param == NULL)
00143       list_lbtable_choices();
00144    else
00145     { get_lbtable();
00146       list_lbtable_item(nvramtool_op.param);
00147     }
00148  }
00149 
00150 /****************************************************************************
00151  * op_lbtable_dump
00152  *
00153  * -d
00154  *
00155  * Do low-level dump of coreboot table.
00156  ****************************************************************************/
00157 static void op_lbtable_dump (void)
00158  { get_lbtable();
00159    dump_lbtable();
00160  }
00161 
00162 /****************************************************************************
00163  * op_show_param_values
00164  *
00165  * -e NAME option
00166  *
00167  * Show all possible values for parameter NAME.
00168  ****************************************************************************/
00169 static void op_show_param_values (void)
00170  { get_cmos_layout();
00171    list_param_enums(nvramtool_op.param);
00172  }
00173 
00174 /****************************************************************************
00175  * op_cmos_show_one_param
00176  *
00177  * [-n] -r NAME
00178  *
00179  * Show parameter NAME.  If -n is specified, show value only.  Else show name
00180  * and value.
00181  ****************************************************************************/
00182 static void op_cmos_show_one_param (void)
00183  { int result;
00184 
00185    get_cmos_layout();
00186    result = list_one_param(nvramtool_op.param,
00187                   !nvramtool_op_modifiers[NVRAMTOOL_MOD_SHOW_VALUE_ONLY].found);
00188    cmos_checksum_verify();
00189 
00190    if (result)
00191       exit(1);
00192  }
00193 
00194 /****************************************************************************
00195  * op_cmos_show_all_params
00196  *
00197  * -a
00198  *
00199  * Show names and values for all parameters.
00200  ****************************************************************************/
00201 static void op_cmos_show_all_params (void)
00202  { int result;
00203 
00204    get_cmos_layout();
00205    result = list_all_params();
00206    cmos_checksum_verify();
00207 
00208    if (result)
00209       exit(1);
00210  }
00211 
00212 /****************************************************************************
00213  * op_cmos_set_one_param
00214  *
00215  * -w NAME=VALUE
00216  *
00217  * Set parameter NAME to VALUE.
00218  ****************************************************************************/
00219 static void op_cmos_set_one_param (void)
00220  { const char *name, *value;
00221 
00222    get_cmos_layout();
00223 
00224    /* Separate 'NAME=VALUE' syntax into two strings representing NAME and
00225     * VALUE.
00226     */
00227    parse_assignment(nvramtool_op.param, &name, &value);
00228 
00229    set_one_param(name, value);
00230  }
00231 
00232 /****************************************************************************
00233  * op_cmos_set_params_stdin
00234  *
00235  * -i
00236  *
00237  * Set parameters according to standard input.
00238  ****************************************************************************/
00239 static void op_cmos_set_params_stdin (void)
00240  { get_cmos_layout();
00241    set_params(stdin);
00242  }
00243 
00244 /****************************************************************************
00245  * op_cmos_set_params_file
00246  *
00247  * -p INPUT_FILE
00248  *
00249  * Set parameters according to INPUT_FILE.
00250  ****************************************************************************/
00251 static void op_cmos_set_params_file (void)
00252  { FILE *f;
00253 
00254    if ((f = fopen(nvramtool_op.param, "r")) == NULL)
00255     { fprintf(stderr, "%s: Can not open file %s for reading: %s\n",
00256               prog_name, nvramtool_op.param, strerror(errno));
00257       exit(1);
00258     }
00259 
00260    get_cmos_layout();
00261    set_params(f);
00262    fclose(f);
00263  }
00264 
00265 /****************************************************************************
00266  * op_cmos_checksum
00267  *
00268  * -c [VALUE]
00269  *
00270  * If VALUE is present, set coreboot CMOS checksum to VALUE.  Else show
00271  * checksum value.
00272  ****************************************************************************/
00273 static void op_cmos_checksum (void)
00274  { uint16_t checksum;
00275 
00276    get_cmos_layout();
00277 
00278    if (nvramtool_op.param == NULL)
00279     { set_iopl(3);
00280       checksum = cmos_checksum_read();
00281       set_iopl(0);
00282       printf("0x%x\n", checksum);
00283     }
00284    else
00285     { checksum = convert_checksum_value(nvramtool_op.param);
00286       set_iopl(3);
00287       cmos_checksum_write(checksum);
00288       set_iopl(0);
00289     }
00290  }
00291 
00292 /****************************************************************************
00293  * op_show_layout
00294  *
00295  * -Y
00296  *
00297  * Write CMOS layout information to standard output.
00298  ****************************************************************************/
00299 static void op_show_layout (void)
00300  { get_cmos_layout();
00301    write_cmos_layout(stdout);
00302  }
00303 
00304 /****************************************************************************
00305  * op_write_cmos_dump
00306  *
00307  * -b OUTPUT_FILE
00308  *
00309  * Write the contents of CMOS memory to a binary file.
00310  ****************************************************************************/
00311 static void op_write_cmos_dump (void)
00312  { unsigned char data[CMOS_SIZE];
00313    FILE *f;
00314 
00315    if ((f = fopen(nvramtool_op.param, "w")) == NULL)
00316     { fprintf(stderr, "%s: Can not open file %s for writing: %s\n",
00317               prog_name, nvramtool_op.param, strerror(errno));
00318       exit(1);
00319     }
00320 
00321    set_iopl(3);
00322    cmos_read_all(data);
00323    set_iopl(0);
00324 
00325    if (fwrite(data, 1, CMOS_SIZE, f) != CMOS_SIZE)
00326     { fprintf(stderr, "%s: Error writing CMOS data to file %s: %s\n",
00327               prog_name, nvramtool_op.param, strerror(errno));
00328       exit(1);
00329     }
00330 
00331    fclose(f);
00332  }
00333 
00334 /****************************************************************************
00335  * op_read_cmos_dump
00336  *
00337  * -B INPUT_FILE
00338  *
00339  * Read binary data from a file and write the data to CMOS memory.
00340  ****************************************************************************/
00341 static void op_read_cmos_dump (void)
00342  { unsigned char data[CMOS_SIZE];
00343    size_t nr_bytes;
00344    FILE *f;
00345 
00346    if ((f = fopen(nvramtool_op.param, "r")) == NULL)
00347     { fprintf(stderr, "%s: Can not open file %s for reading: %s\n",
00348               prog_name, nvramtool_op.param, strerror(errno));
00349       exit(1);
00350     }
00351 
00352    if ((nr_bytes = fread(data, 1, CMOS_SIZE, f)) != CMOS_SIZE)
00353     { fprintf(stderr, "%s: Error: Only able to read %d bytes of CMOS data "
00354               "from file %s.  CMOS data is unchanged.\n", prog_name,
00355               (int) nr_bytes, nvramtool_op.param);
00356       exit(1);
00357     }
00358 
00359    fclose(f);
00360    set_iopl(3);
00361    cmos_write_all(data);
00362    set_iopl(0);
00363  }
00364 
00365 /****************************************************************************
00366  * op_show_cmos_hex_dump
00367  *
00368  * -x
00369  *
00370  * Write a hex dump of CMOS memory to standard output.
00371  ****************************************************************************/
00372 static void op_show_cmos_hex_dump (void)
00373  { unsigned char data[CMOS_SIZE];
00374 
00375    set_iopl(3);
00376    cmos_read_all(data);
00377    set_iopl(0);
00378    hexdump(data, CMOS_SIZE, 0, stdout, &cmos_dump_format);
00379  }
00380 
00381 /****************************************************************************
00382  * op_show_cmos_dumpfile
00383  *
00384  * -X DUMP_FILE
00385  *
00386  * Read binary data from a file (presumably a CMOS dump file) and display a
00387  * hex dump of the CMOS data from the file.
00388  ****************************************************************************/
00389 static void op_show_cmos_dumpfile (void)
00390  { unsigned char data[CMOS_SIZE];
00391    size_t nr_bytes;
00392    FILE *f;
00393 
00394    if ((f = fopen(nvramtool_op.param, "r")) == NULL)
00395     { fprintf(stderr, "%s: Can not open file %s for reading: %s\n",
00396               prog_name, nvramtool_op.param, strerror(errno));
00397       exit(1);
00398     }
00399 
00400    nr_bytes = fread(data, 1, CMOS_SIZE, f);
00401    fclose(f);
00402    hexdump(data, nr_bytes, 0, stdout, &cmos_dump_format);
00403  }
00404 
00405 /****************************************************************************
00406  * list_one_param
00407  *
00408  * Attempt to list one CMOS parameter given by 'name'.  'show_name' is a
00409  * boolean value indicating whether the parameter name should be displayed
00410  * along with its value.  Return 1 if error was encountered.  Else return OK.
00411  ****************************************************************************/
00412 static int list_one_param (const char name[], int show_name)
00413  { const cmos_entry_t *e;
00414 
00415    if (is_checksum_name(name) || ((e = find_cmos_entry(name)) == NULL))
00416     { fprintf(stderr, "%s: CMOS parameter %s not found.\n", prog_name, name);
00417       exit(1);
00418     }
00419 
00420    if (e->config == CMOS_ENTRY_RESERVED)
00421     { fprintf(stderr, "%s: Parameter %s is reserved.\n", prog_name, name);
00422       exit(1);
00423     }
00424 
00425    return (list_cmos_entry(e, show_name) != 0);
00426  }
00427 
00428 /****************************************************************************
00429  * list_all_params
00430  *
00431  * Attempt to list all CMOS parameters.  Return 1 if error was encountered.
00432  * Else return OK.
00433  ****************************************************************************/
00434 static int list_all_params (void)
00435  { const cmos_entry_t *e;
00436    int result;
00437 
00438    result = OK;
00439 
00440    for (e = first_cmos_entry(); e != NULL; e = next_cmos_entry(e))
00441     { if ((e->config == CMOS_ENTRY_RESERVED) || is_checksum_name(e->name))
00442          continue;
00443 
00444       if (list_cmos_entry(e, TRUE))
00445          result = 1;
00446     }
00447 
00448    return result;
00449  }
00450 
00451 /****************************************************************************
00452  * list_param_enums
00453  *
00454  * List all possible values for CMOS parameter given by 'name'.
00455  ****************************************************************************/
00456 static void list_param_enums (const char name[])
00457  { const cmos_entry_t *e;
00458    const cmos_enum_t *p;
00459 
00460    if (is_checksum_name(name) || (e = find_cmos_entry(name)) == NULL)
00461     { fprintf(stderr, "%s: CMOS parameter %s not found.\n", prog_name, name);
00462       exit(1);
00463     }
00464 
00465    switch (e->config)
00466     { case CMOS_ENTRY_ENUM:
00467          for (p = first_cmos_enum_id(e->config_id);
00468               p != NULL;
00469               p = next_cmos_enum_id(p))
00470             printf("%s\n", p->text);
00471 
00472          break;
00473 
00474       case CMOS_ENTRY_HEX:
00475          printf("Parameter %s requires a %u-bit unsigned integer.\n", name,
00476                 e->length);
00477          break;
00478 
00479       case CMOS_ENTRY_STRING:
00480          printf("Parameter %s requires a %u-byte string.\n", name,
00481                 e->length / 8);
00482          break;
00483 
00484       case CMOS_ENTRY_RESERVED:
00485          printf("Parameter %s is reserved.\n", name);
00486          break;
00487 
00488       default:
00489          BUG();
00490     }
00491  }
00492 
00493 /****************************************************************************
00494  * set_one_param
00495  *
00496  * Set the CMOS parameter given by 'name' to 'value'.  The 'name' parameter
00497  * is case-sensitive.  If we are setting an enum parameter, then 'value' is
00498  * interpreted as a case-sensitive string that must match the option name
00499  * exactly.  If we are setting a 'hex' parameter, then 'value' is treated as
00500  * a string representation of an unsigned integer that may be specified in
00501  * decimal, hex, or octal.
00502  ****************************************************************************/
00503 static void set_one_param (const char name[], const char value[])
00504  { const cmos_entry_t *e;
00505    unsigned long long n;
00506 
00507    if (is_checksum_name(name) || (e = find_cmos_entry(name)) == NULL)
00508     { fprintf(stderr, "%s: CMOS parameter %s not found.", prog_name, name);
00509       exit(1);
00510     }
00511 
00512    switch (prepare_cmos_write(e, value, &n))
00513     { case OK:
00514          break;
00515 
00516       case CMOS_OP_BAD_ENUM_VALUE:
00517          fprintf(stderr, "%s: Bad value for parameter %s.", prog_name, name);
00518          goto fail;
00519 
00520       case CMOS_OP_NEGATIVE_INT:
00521          fprintf(stderr,
00522                  "%s: This program does not support assignment of negative "
00523                  "numbers to coreboot parameters.", prog_name);
00524          goto fail;
00525 
00526       case CMOS_OP_INVALID_INT:
00527          fprintf(stderr, "%s: %s is not a valid integer.", prog_name, value);
00528          goto fail;
00529 
00530       case CMOS_OP_RESERVED:
00531          fprintf(stderr,
00532                  "%s: Can not modify reserved coreboot parameter %s.",
00533                  prog_name, name);
00534          goto fail;
00535 
00536       case CMOS_OP_VALUE_TOO_WIDE:
00537          fprintf(stderr,
00538                  "%s: Can not write value %s to CMOS parameter %s that is "
00539                  "only %d bits wide.", prog_name, value, name, e->length);
00540          goto fail;
00541 
00542       case CMOS_OP_NO_MATCHING_ENUM:
00543          fprintf(stderr,
00544                  "%s: coreboot parameter %s has no matching enums.",
00545                  prog_name, name);
00546          goto fail;
00547 
00548       case CMOS_AREA_OUT_OF_RANGE:
00549          fprintf(stderr,
00550                  "%s: The CMOS area specified by the layout info for "
00551                  "coreboot parameter %s is out of range.", prog_name, name);
00552          goto fail;
00553 
00554       case CMOS_AREA_OVERLAPS_RTC:
00555          fprintf(stderr,
00556                  "%s: The CMOS area specified by the layout info for "
00557                  "coreboot parameter %s overlaps the realtime clock area.",
00558                  prog_name, name);
00559          goto fail;
00560 
00561       case CMOS_AREA_TOO_WIDE:
00562          fprintf(stderr,
00563                  "%s: The CMOS area specified by the layout info for "
00564                  "coreboot parameter %s is too wide.",
00565                  prog_name, name);
00566          goto fail;
00567 
00568       default:
00569          fprintf(stderr,
00570                  "%s: Unknown error encountered while attempting to modify "
00571                  "coreboot parameter %s.", prog_name, name);
00572          goto fail;
00573     }
00574 
00575    /* write the value to nonvolatile RAM */
00576    set_iopl(3);
00577    cmos_write(e, n);
00578    cmos_checksum_write(cmos_checksum_compute());
00579    set_iopl(0);
00580    return;
00581 
00582 fail:
00583    fprintf(stderr, "  CMOS write not performed.\n");
00584    exit(1);
00585  }
00586 
00587 /****************************************************************************
00588  * set_params
00589  *
00590  * Set coreboot parameters according to the contents of file 'f'.
00591  ****************************************************************************/
00592 static void set_params (FILE *f)
00593  { /* First process the input file.  Then perform writes only if there were
00594     * no problems processing the input.  Either all values will be written
00595     * successfully or no values will be written.
00596     */
00597    do_cmos_writes(process_input_file(f));
00598  }
00599 
00600 /****************************************************************************
00601  * parse_assignment
00602  *
00603  * Parse the string 'arg' (which supposedly represents an assignment) into a
00604  * NAME and a VALUE.  If 'arg' does not conform to the proper assignment
00605  * syntax, exit with a usage message.  Otherwise, on return, 'arg' is broken
00606  * into substrings representing NAME and VALUE, and *name and *value are set
00607  * to point to these two substrings.
00608  ****************************************************************************/
00609 static void parse_assignment (char arg[], const char **name,
00610                               const char **value)
00611  { static const size_t N_MATCHES = 4;
00612    regmatch_t match[N_MATCHES];
00613    regex_t assignment;
00614 
00615    compile_reg_exprs(REG_EXTENDED | REG_NEWLINE, 1, assignment_regex,
00616                      &assignment);
00617 
00618    /* Does 'arg' conform to proper assignment syntax?  If not, exit with a
00619     * usage message.
00620     */
00621    if (regexec(&assignment, arg, N_MATCHES, match, 0))
00622       usage(stderr);
00623 
00624    /* Ok, we found a valid assignment.  Break it into two strings
00625     * representing NAME and VALUE.
00626     */
00627    arg[match[1].rm_eo] = '\0';
00628    arg[match[2].rm_eo] = '\0';
00629    *name = &arg[match[1].rm_so];
00630    *value = &arg[match[2].rm_so];
00631 
00632    free_reg_exprs(1, &assignment);
00633  }
00634 
00635 /****************************************************************************
00636  * list_cmos_entry
00637  *
00638  * Attempt to list the CMOS entry represented by 'e'.  'show_name' is a
00639  * boolean value indicating whether the parameter name should be displayed
00640  * along with its value.  On success, return OK.  On error, print an error
00641  * message and return 1.
00642  ****************************************************************************/
00643 static int list_cmos_entry (const cmos_entry_t *e, int show_name)
00644  { const cmos_enum_t *p;
00645    unsigned long long value;
00646 
00647    /* sanity check CMOS entry */
00648    switch (prepare_cmos_read(e))
00649     { case OK:
00650          break;
00651 
00652       case CMOS_OP_RESERVED:
00653          BUG();
00654 
00655       case CMOS_AREA_OUT_OF_RANGE:
00656          fprintf(stderr, "%s: Can not read coreboot parameter %s because "
00657                  "layout info specifies out of range CMOS area.\n", prog_name,
00658                  e->name);
00659          return 1;
00660 
00661       case CMOS_AREA_OVERLAPS_RTC:
00662          fprintf(stderr, "%s: Can not read coreboot parameter %s because "
00663                  "layout info specifies CMOS area that overlaps realtime "
00664                  "clock area.\n", prog_name, e->name);
00665          return 1;
00666 
00667       case CMOS_AREA_TOO_WIDE:
00668          fprintf(stderr, "%s: Can not read coreboot parameter %s because "
00669                  "layout info specifies CMOS area that is too wide.\n",
00670                  prog_name, e->name);
00671          return 1;
00672 
00673       default:
00674          fprintf(stderr, "%s: Unknown error encountered while attempting to "
00675                  "read coreboot parameter %s\n", prog_name, e->name);
00676          return 1;
00677     }
00678 
00679    /* read the value from CMOS */
00680    set_iopl(3);
00681    value = cmos_read(e);
00682    set_iopl(0);
00683 
00684    /* display the value */
00685    switch (e->config)
00686     { case CMOS_ENTRY_ENUM:
00687          if ((p = find_cmos_enum(e->config_id, value)) == NULL)
00688           { if (show_name)
00689                printf("# Bad value -> %s = 0x%llx\n", e->name, value);
00690             else
00691                printf("Bad value -> 0x%llx\n", value);
00692           }
00693          else
00694           { if (show_name)
00695                printf("%s = %s\n", e->name, p->text);
00696             else
00697                printf("%s\n", p->text);
00698           }
00699 
00700          break;
00701 
00702       case CMOS_ENTRY_HEX:
00703          if (show_name)
00704             printf("%s = 0x%llx\n", e->name, value);
00705          else
00706             printf("0x%llx\n", value);
00707 
00708          break;
00709 
00710       case CMOS_ENTRY_STRING:
00711          if (show_name)
00712             printf("%s = %s\n", e->name, (char *)(unsigned long)value);
00713          else
00714             printf("%s\n", (char *)(unsigned long)value);
00715 
00716          free((void *)(unsigned long)value);
00717 
00718          break;
00719 
00720       case CMOS_ENTRY_RESERVED:
00721       default:
00722          BUG();
00723     }
00724 
00725    return OK;
00726  }
00727 
00728 /****************************************************************************
00729  * convert_checksum_value
00730  *
00731  * 'value' is the string representation of a checksum value that the user
00732  * wishes to set using the -c option.  Convert the string to a 16-bit
00733  * unsigned integer and return the result.  Exit with an error message if
00734  * 'value' is invalid.
00735  ****************************************************************************/
00736 static uint16_t convert_checksum_value (const char value[])
00737  { unsigned long n;
00738    const char *p;
00739    uint16_t result;
00740    int negative;
00741 
00742    for (p = value; isspace(*p); p++);
00743 
00744    negative = (*p == '-');
00745    n = strtoul(value, (char **) &p, 0);
00746 
00747    if (*p)
00748     { fprintf(stderr, "%s: Checksum value %s is not a valid integer.\n",
00749               prog_name, value);
00750       exit(1);
00751     }
00752 
00753    if (negative)
00754     { fprintf(stderr,
00755               "%s: Checksum must be an unsigned integer.\n", prog_name);
00756       exit(1);
00757     }
00758 
00759    result = (uint16_t) n;
00760 
00761    if (result != n)
00762     { fprintf(stderr,
00763               "%s: Checksum value must fit within 16 bits.\n", prog_name);
00764       exit(1);
00765     }
00766 
00767    return result;
00768  }

Generated on Wed Jan 7 14:14:26 2009 for coreboot by  doxygen 1.5.5