X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=util%2Fnvramtool%2Fcmos_ops.c;h=91c9f451ac1482fb888a2060ca8e1165507633ad;hb=c31c4de681738fc264333cb12aecdb995b119a94;hp=170e944678b8c952b8a764604253dd4f598696f7;hpb=cbb5ba8633c2ad143366c3bc367f8c4f6434c084;p=coreboot.git diff --git a/util/nvramtool/cmos_ops.c b/util/nvramtool/cmos_ops.c index 170e94467..91c9f451a 100644 --- a/util/nvramtool/cmos_ops.c +++ b/util/nvramtool/cmos_ops.c @@ -1,6 +1,5 @@ /*****************************************************************************\ * cmos_ops.c - * $Id$ ***************************************************************************** * Copyright (C) 2002-2005 The Regents of the University of California. * Produced at the Lawrence Livermore National Laboratory. @@ -26,33 +25,34 @@ * * 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., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. \*****************************************************************************/ #include "common.h" #include "cmos_ops.h" #include "cmos_lowlevel.h" -static int prepare_cmos_op_common (const cmos_entry_t *e); +static int prepare_cmos_op_common(const cmos_entry_t * e); /**************************************************************************** * prepare_cmos_op_common * * Perform a few checks common to both reads and writes. ****************************************************************************/ -static int prepare_cmos_op_common (const cmos_entry_t *e) - { int result; +static int prepare_cmos_op_common(const cmos_entry_t * e) +{ + int result; - if (e->config == CMOS_ENTRY_RESERVED) - /* Access to reserved parameters is not permitted. */ - return CMOS_OP_RESERVED; + if (e->config == CMOS_ENTRY_RESERVED) + /* Access to reserved parameters is not permitted. */ + return CMOS_OP_RESERVED; - if ((result = verify_cmos_op(e->bit, e->length)) != OK) - return result; + if ((result = verify_cmos_op(e->bit, e->length, e->config)) != OK) + return result; - assert(e->length > 0); - return OK; - } + assert(e->length > 0); + return OK; +} /**************************************************************************** * prepare_cmos_read @@ -61,23 +61,25 @@ static int prepare_cmos_op_common (const cmos_entry_t *e) * sanity checking on 'e'. If a problem was found with e, return an error * code. Else return OK. ****************************************************************************/ -int prepare_cmos_read (const cmos_entry_t *e) - { int result; +int prepare_cmos_read(const cmos_entry_t * e) +{ + int result; - if ((result = prepare_cmos_op_common(e)) != OK) - return result; + if ((result = prepare_cmos_op_common(e)) != OK) + return result; - switch (e->config) - { case CMOS_ENTRY_ENUM: - case CMOS_ENTRY_HEX: - break; + switch (e->config) { + case CMOS_ENTRY_ENUM: + case CMOS_ENTRY_HEX: + case CMOS_ENTRY_STRING: + break; - default: - BUG(); - } + default: + BUG(); + } - return OK; - } + return OK; +} /**************************************************************************** * prepare_cmos_write @@ -87,69 +89,78 @@ int prepare_cmos_read (const cmos_entry_t *e) * checking on 'value_str'. On error, return an error code. Else store the * numeric equivalent of 'value_str' in '*value' and return OK. ****************************************************************************/ -int prepare_cmos_write (const cmos_entry_t *e, const char value_str[], - unsigned long long *value) - { const cmos_enum_t *q; - unsigned long long out; - const char *p; - int negative, result, found_one; - - if ((result = prepare_cmos_op_common(e)) != OK) - return result; - - switch (e->config) - { case CMOS_ENTRY_ENUM: - /* Make sure the user's input corresponds to a valid option. */ - for (q = first_cmos_enum_id(e->config_id), found_one = 0; - q != NULL; - q = next_cmos_enum_id(q)) - { found_one = 1; - - if (!strncmp(q->text, value_str, CMOS_MAX_TEXT_LENGTH)) - break; - } - - if (!found_one) - return CMOS_OP_NO_MATCHING_ENUM; - - if (q == NULL) - return CMOS_OP_BAD_ENUM_VALUE; - - out = q->value; - break; - - case CMOS_ENTRY_HEX: - /* See if the first character of 'value_str' (excluding any initial - * whitespace) is a minus sign. - */ - for (p = value_str; isspace(*p); p++); - negative = (*p == '-'); - - out = strtoull(value_str, (char **) &p, 0); - - if (*p) - return CMOS_OP_INVALID_INT; - - /* If we get this far, the user specified a valid integer. However - * we do not currently support the use of negative numbers as CMOS - * parameter values. - */ - if (negative) - return CMOS_OP_NEGATIVE_INT; - - break; - - default: - BUG(); - } - - if ((e->length < (8 * sizeof(*value))) && - (out >= (1ull << e->length))) - return CMOS_OP_VALUE_TOO_WIDE; - - *value = out; - return OK; - } +int prepare_cmos_write(const cmos_entry_t * e, const char value_str[], + unsigned long long *value) +{ + const cmos_enum_t *q; + unsigned long long out; + const char *p; + char *memory; + int negative, result, found_one; + + if ((result = prepare_cmos_op_common(e)) != OK) + return result; + + switch (e->config) { + case CMOS_ENTRY_ENUM: + /* Make sure the user's input corresponds to a valid option. */ + for (q = first_cmos_enum_id(e->config_id), found_one = 0; + q != NULL; q = next_cmos_enum_id(q)) { + found_one = 1; + + if (!strncmp(q->text, value_str, CMOS_MAX_TEXT_LENGTH)) + break; + } + + if (!found_one) + return CMOS_OP_NO_MATCHING_ENUM; + + if (q == NULL) + return CMOS_OP_BAD_ENUM_VALUE; + + out = q->value; + break; + + case CMOS_ENTRY_HEX: + /* See if the first character of 'value_str' (excluding + * any initial whitespace) is a minus sign. + */ + for (p = value_str; isspace((int)(unsigned char)*p); p++) ; + negative = (*p == '-'); + + out = strtoull(value_str, (char **)&p, 0); + + if (*p) + return CMOS_OP_INVALID_INT; + + /* If we get this far, the user specified a valid integer. + * However we do not currently support the use of negative + * numbers as CMOS parameter values. + */ + if (negative) + return CMOS_OP_NEGATIVE_INT; + + break; + + case CMOS_ENTRY_STRING: + if (e->length < (8 * strlen(value_str))) + return CMOS_OP_VALUE_TOO_WIDE; + memory = malloc(e->length / 8); + memset(memory, 0, e->length / 8); + strcpy(memory, value_str); + out = (unsigned long)memory; + break; + + default: + BUG(); + } + + if ((e->length < (8 * sizeof(*value))) && (out >= (1ull << e->length))) + return CMOS_OP_VALUE_TOO_WIDE; + + *value = out; + return OK; +} /**************************************************************************** * cmos_checksum_read @@ -157,14 +168,15 @@ int prepare_cmos_write (const cmos_entry_t *e, const char value_str[], * Read the checksum for the coreboot parameters stored in CMOS and return * this value. ****************************************************************************/ -uint16_t cmos_checksum_read (void) - { uint16_t lo, hi; +uint16_t cmos_checksum_read(void) +{ + uint16_t lo, hi; - /* The checksum is stored in a big-endian format. */ - hi = cmos_read_byte(cmos_checksum_index); - lo = cmos_read_byte(cmos_checksum_index + 1); - return (hi << 8) + lo; - } + /* The checksum is stored in a big-endian format. */ + hi = cmos_read_byte(cmos_checksum_index); + lo = cmos_read_byte(cmos_checksum_index + 1); + return (hi << 8) + lo; +} /**************************************************************************** * cmos_checksum_write @@ -172,15 +184,16 @@ uint16_t cmos_checksum_read (void) * Set the checksum for the coreboot parameters stored in CMOS to * 'checksum'. ****************************************************************************/ -void cmos_checksum_write (uint16_t checksum) - { unsigned char lo, hi; +void cmos_checksum_write(uint16_t checksum) +{ + unsigned char lo, hi; - /* The checksum is stored in a big-endian format. */ - hi = (unsigned char) (checksum >> 8); - lo = (unsigned char) (checksum & 0x00ff); - cmos_write_byte(cmos_checksum_index, hi); - cmos_write_byte(cmos_checksum_index + 1, lo); - } + /* The checksum is stored in a big-endian format. */ + hi = (unsigned char)(checksum >> 8); + lo = (unsigned char)(checksum & 0x00ff); + cmos_write_byte(cmos_checksum_index, hi); + cmos_write_byte(cmos_checksum_index + 1, lo); +} /**************************************************************************** * cmos_checksum_compute @@ -188,16 +201,17 @@ void cmos_checksum_write (uint16_t checksum) * Compute a checksum for the coreboot parameter values currently stored in * CMOS and return this checksum. ****************************************************************************/ -uint16_t cmos_checksum_compute (void) - { unsigned i, sum; +uint16_t cmos_checksum_compute(void) +{ + unsigned i, sum; - sum = 0; + sum = 0; - for (i = cmos_checksum_start; i <= cmos_checksum_end; i++) - sum += cmos_read_byte(i); + for (i = cmos_checksum_start; i <= cmos_checksum_end; i++) + sum += cmos_read_byte(i); - return ~((uint16_t) (sum & 0xffff)); - } + return (uint16_t)(sum & 0xffff); +} /**************************************************************************** * cmos_checksum_verify @@ -205,17 +219,18 @@ uint16_t cmos_checksum_compute (void) * Verify that the coreboot CMOS checksum is valid. If checksum is not * valid then print warning message and exit. ****************************************************************************/ -void cmos_checksum_verify (void) - { uint16_t computed, actual; - - set_iopl(3); - computed = cmos_checksum_compute(); - actual = cmos_checksum_read(); - set_iopl(0); - - if (computed != actual) - { fprintf(stderr, "%s: Warning: Coreboot CMOS checksum is bad.\n", - prog_name); - exit(1); - } - } +void cmos_checksum_verify(void) +{ + uint16_t computed, actual; + + set_iopl(3); + computed = cmos_checksum_compute(); + actual = cmos_checksum_read(); + set_iopl(0); + + if (computed != actual) { + fprintf(stderr, "%s: Warning: Coreboot CMOS checksum is bad.\n", + prog_name); + exit(1); + } +}