diff --git a/src/arch/x86/Makefile.inc b/src/arch/x86/Makefile.inc index 8783d4bc02..d3b5e07f9f 100755 --- a/src/arch/x86/Makefile.inc +++ b/src/arch/x86/Makefile.inc @@ -128,18 +128,15 @@ bootsplash.jpg-type := bootsplash ####################################################################### # i386 specific tools +NVRAMTOOL:=$(objutil)/nvramtool/nvramtool -$(OPTION_TABLE_H): $(objutil)/options/build_opt_tbl $(top)/src/mainboard/$(MAINBOARDDIR)/cmos.layout +$(OPTION_TABLE_H): $(NVRAMTOOL) $(top)/src/mainboard/$(MAINBOARDDIR)/cmos.layout @printf " OPTION $(subst $(obj)/,,$(@))\n" - $(objutil)/options/build_opt_tbl --config $(top)/src/mainboard/$(MAINBOARDDIR)/cmos.layout --header $@ + $(NVRAMTOOL) -y $(top)/src/mainboard/$(MAINBOARDDIR)/cmos.layout -H $@ -$(obj)/cmos_layout.bin: $(objutil)/options/build_opt_tbl $(top)/src/mainboard/$(MAINBOARDDIR)/cmos.layout +$(obj)/cmos_layout.bin: $(NVRAMTOOL) $(top)/src/mainboard/$(MAINBOARDDIR)/cmos.layout @printf " OPTION $(subst $(obj)/,,$(@))\n" - $(objutil)/options/build_opt_tbl --config $(top)/src/mainboard/$(MAINBOARDDIR)/cmos.layout --binary $@ - -$(objutil)/options/build_opt_tbl: $(top)/util/options/build_opt_tbl.c $(top)/src/include/pc80/mc146818rtc.h $(top)/src/include/boot/coreboot_tables.h - @printf " HOSTCC $(subst $(obj)/,,$(@))\n" - $(HOSTCC) $(HOSTCFLAGS) $< -o $@ + $(NVRAMTOOL) -y $(top)/src/mainboard/$(MAINBOARDDIR)/cmos.layout -L $@ ####################################################################### # Build the coreboot_ram (stage 2) diff --git a/util/nvramtool/Makefile b/util/nvramtool/Makefile index a75c70da5c..2a143b7b47 100644 --- a/util/nvramtool/Makefile +++ b/util/nvramtool/Makefile @@ -30,7 +30,7 @@ CFLAGS = -O2 -g -Wall -W -I. CLI_OBJS = cli/nvramtool.o cli/opts.o OBJS = cmos_lowlevel.o cmos_ops.o common.o compute_ip_checksum.o \ - hexdump.o input_file.o layout.o accessors/layout-text.o accessors/layout-bin.o lbtable.o \ + hexdump.o input_file.o layout.o accessors/layout-common.o accessors/layout-text.o accessors/layout-bin.o lbtable.o \ reg_expr.o cbfs.o accessors/cmos-hw-unix.o accessors/cmos-mem.o OBJS += $(CLI_OBJS) diff --git a/util/nvramtool/Makefile.inc b/util/nvramtool/Makefile.inc index 25d447d93c..a70896c93b 100644 --- a/util/nvramtool/Makefile.inc +++ b/util/nvramtool/Makefile.inc @@ -31,7 +31,7 @@ endif nvramtoolobj := nvramtoolobj += cli/nvramtool.o cli/opts.o nvramtoolobj += cmos_lowlevel.o cmos_ops.o common.o compute_ip_checksum.o -nvramtoolobj += hexdump.o input_file.o layout.o accessors/layout-text.o accessors/layout-bin.o lbtable.o +nvramtoolobj += hexdump.o input_file.o layout.o accessors/layout-common.o accessors/layout-text.o accessors/layout-bin.o lbtable.o nvramtoolobj += reg_expr.o cbfs.o accessors/cmos-hw-unix.o accessors/cmos-mem.o $(objutil)/nvramtool $(objutil)/nvramtool/accessors $(objutil)/nvramtool/cli: diff --git a/util/nvramtool/accessors/layout-bin.c b/util/nvramtool/accessors/layout-bin.c index cf79646453..b910e358b6 100644 --- a/util/nvramtool/accessors/layout-bin.c +++ b/util/nvramtool/accessors/layout-bin.c @@ -1,6 +1,12 @@ /*****************************************************************************\ * lbtable.c ***************************************************************************** + * Copyright (C) 2012, Vikram Narayanan + * Unified build_opt_tbl and nvramtool + * build_opt_tbl.c + * Copyright (C) 2003 Eric Biederman (ebiederm@xmission.com) + * Copyright (C) 2007-2010 coresystems GmbH + * * Copyright (C) 2002-2005 The Regents of the University of California. * Produced at the Lawrence Livermore National Laboratory. * Written by Dave Peterson @@ -40,6 +46,7 @@ #include "cmos_lowlevel.h" #include "hexdump.h" #include "cbfs.h" +#include "layout-text.h" static void process_cmos_table(void); static void get_cmos_checksum_info(void); @@ -61,6 +68,8 @@ static const struct lb_record *next_cmos_rec(const struct lb_record *last, */ static const struct cmos_option_table *cmos_table = NULL; +#define ROUNDUP4(x) (x += (4 - (x % 4))) + void process_layout(void) { if ((cmos_table) == NULL) { @@ -83,6 +92,130 @@ void get_layout_from_cbfs_file(void) process_layout(); } +int write_cmos_layout_bin(FILE *f) +{ + const cmos_entry_t *cmos_entry; + const cmos_enum_t *cmos_enum; + cmos_checksum_layout_t layout; + struct cmos_option_table table; + struct cmos_entries entry; + struct cmos_enums cenum; + struct cmos_checksum csum; + size_t sum = 0; + int len; + + for (cmos_entry = first_cmos_entry(); cmos_entry != NULL; + cmos_entry = next_cmos_entry(cmos_entry)) { + + if (cmos_entry == first_cmos_entry()) { + sum += sizeof(table); + table.header_length = sizeof(table); + table.tag = LB_TAG_CMOS_OPTION_TABLE; + + if (fwrite((char *)&table, sizeof(table), 1, f) != 1) { + perror("Error writing image file"); + goto err; + } + } + + memset(&entry, 0, sizeof(entry)); + entry.tag = LB_TAG_OPTION; + entry.config = cmos_entry->config; + entry.config_id = (uint32_t)cmos_entry->config_id; + entry.bit = cmos_entry->bit; + entry.length = cmos_entry->length; + + if (!is_ident((char *)cmos_entry->name)) { + fprintf(stderr, + "Error - Name %s is an invalid identifier\n", + cmos_entry->name); + goto err; + } + + memcpy(entry.name, cmos_entry->name, strlen(cmos_entry->name)); + entry.name[strlen(cmos_entry->name)] = '\0'; + len = strlen(cmos_entry->name) + 1; + + if (len % 4) + ROUNDUP4(len); + + entry.size = sizeof(entry) - CMOS_MAX_NAME_LENGTH + len; + sum += entry.size; + if (fwrite((char *)&entry, entry.size, 1, f) != 1) { + perror("Error writing image file"); + goto err; + } + } + + for (cmos_enum = first_cmos_enum(); + cmos_enum != NULL; cmos_enum = next_cmos_enum(cmos_enum)) { + memset(&cenum, 0, sizeof(cenum)); + cenum.tag = LB_TAG_OPTION_ENUM; + memcpy(cenum.text, cmos_enum->text, strlen(cmos_enum->text)); + cenum.text[strlen(cmos_enum->text)] = '\0'; + len = strlen((char *)cenum.text) + 1; + + if (len % 4) + ROUNDUP4(len); + + cenum.config_id = cmos_enum->config_id; + cenum.value = cmos_enum->value; + cenum.size = sizeof(cenum) - CMOS_MAX_TEXT_LENGTH + len; + sum += cenum.size; + if (fwrite((char *)&cenum, cenum.size, 1, f) != 1) { + perror("Error writing image file"); + goto err; + } + } + + layout.summed_area_start = cmos_checksum_start; + layout.summed_area_end = cmos_checksum_end; + layout.checksum_at = cmos_checksum_index; + checksum_layout_to_bits(&layout); + + csum.tag = LB_TAG_OPTION_CHECKSUM; + csum.size = sizeof(csum); + csum.range_start = layout.summed_area_start; + csum.range_end = layout.summed_area_end; + csum.location = layout.checksum_at; + csum.type = CHECKSUM_PCBIOS; + sum += csum.size; + + if (fwrite((char *)&csum, csum.size, 1, f) != 1) { + perror("Error writing image file"); + goto err; + } + + if (fseek(f, sizeof(table.tag), SEEK_SET) != 0) { + perror("Error while seeking"); + goto err; + } + + if (fwrite((char *)&sum, sizeof(table.tag), 1, f) != 1) { + perror("Error writing image file"); + goto err; + } + return sum; + +err: + fclose(f); + exit(1); +} + +void write_cmos_output_bin(const char *binary_filename) +{ + FILE *fp; + + if ((fp = fopen(binary_filename, "wb")) == NULL) { + fprintf(stderr, + "%s: Can not open file %s for writing: " + "%s\n", prog_name, binary_filename, strerror(errno)); + exit(1); + } + write_cmos_layout_bin(fp); + fclose(fp); +} + /**************************************************************************** * get_layout_from_cmos_table * diff --git a/util/nvramtool/accessors/layout-common.c b/util/nvramtool/accessors/layout-common.c new file mode 100644 index 0000000000..0a99d3b89c --- /dev/null +++ b/util/nvramtool/accessors/layout-common.c @@ -0,0 +1,75 @@ +/*****************************************************************************\ + * layout_common.c + ***************************************************************************** + * Copyright (C) 2012, Vikram Narayanan + * Unified build_opt_tbl and nvramtool + * build_opt_tbl.c + * Copyright (C) 2003 Eric Biederman (ebiederm@xmission.com) + * Copyright (C) 2007-2010 coresystems GmbH + * + * 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 + +static int is_ident_nondigit(int c) +{ + int result; + switch(c) { + case 'A': case 'B': case 'C': case 'D': + case 'E': case 'F': case 'G': case 'H': + case 'I': case 'J': case 'K': case 'L': + case 'M': case 'N': case 'O': case 'P': + case 'Q': case 'R': case 'S': case 'T': + case 'U': case 'V': case 'W': case 'X': + case 'Y': case 'Z': + case 'a': case 'b': case 'c': case 'd': + case 'e': case 'f': case 'g': case 'h': + case 'i': case 'j': case 'k': case 'l': + case 'm': case 'n': case 'o': case 'p': + case 'q': case 'r': case 's': case 't': + case 'u': case 'v': case 'w': case 'x': + case 'y': case 'z': + case '_': + result = 1; + break; + default: + result = 0; + break; + } + return result; +} + +int is_ident(char *str) +{ + int result; + int ch; + ch = *str; + result = 0; + if (is_ident_nondigit(ch)) { + do { + str++; + ch = *str; + } while(ch && (is_ident_nondigit(ch) || (isdigit(ch)))); + result = (ch == '\0'); + } + return result; +} diff --git a/util/nvramtool/accessors/layout-text.c b/util/nvramtool/accessors/layout-text.c index cbe698c504..a06f560cee 100644 --- a/util/nvramtool/accessors/layout-text.c +++ b/util/nvramtool/accessors/layout-text.c @@ -1,6 +1,12 @@ /*****************************************************************************\ * layout-text.c ***************************************************************************** + * Copyright (C) 2012, Vikram Narayanan + * Unified build_opt_tbl and nvramtool + * build_opt_tbl.c + * Copyright (C) 2003 Eric Biederman (ebiederm@xmission.com) + * Copyright (C) 2007-2010 coresystems GmbH + * * Copyright (C) 2002-2005 The Regents of the University of California. * Produced at the Lawrence Livermore National Laboratory. * Written by Dave Peterson . @@ -218,6 +224,57 @@ void get_layout_from_file(void) fclose(f); } +void write_cmos_layout_header(const char *header_filename) +{ + FILE *fp; + const cmos_entry_t *cmos_entry; + cmos_checksum_layout_t layout; + + if ((fp = fopen(header_filename, "w+")) == NULL) { + fprintf(stderr, + "%s: Can't open file %s for writing: %s\n", + prog_name, header_filename, strerror(errno)); + exit(1); + } + + fprintf(fp, "/**\n * This is an autogenerated file. Do not EDIT.\n" + " * All changes made to this file will be lost.\n" + " * See mainboard's cmos.layout file.\n */\n" + "\n#ifndef __OPTION_TABLE_H\n" + "#define __OPTION_TABLE_H\n\n"); + + for (cmos_entry = first_cmos_entry(); cmos_entry != NULL; + cmos_entry = next_cmos_entry(cmos_entry)) { + + if (!is_ident((char *)cmos_entry->name)) { + fprintf(stderr, + "Error - Name %s is an invalid identifier\n", + cmos_entry->name); + fclose(fp); + exit(1); + } + + fprintf(fp, "#define CMOS_VSTART_%s\t%d\n", + cmos_entry->name, cmos_entry->bit); + fprintf(fp, "#define CMOS_VLEN_%s\t%d\n", + cmos_entry->name, cmos_entry->length); + } + + layout.summed_area_start = cmos_checksum_start; + layout.summed_area_end = cmos_checksum_end; + layout.checksum_at = cmos_checksum_index; + checksum_layout_to_bits(&layout); + + fprintf(fp, "\n#define LB_CKS_RANGE_START %d\n", + layout.summed_area_start / 8); + fprintf(fp, "#define LB_CKS_RANGE_END %d\n", + layout.summed_area_end / 8); + fprintf(fp, "#define LB_CKS_LOC %d\n", + layout.checksum_at / 8); + fprintf(fp, "\n#endif /* __OPTION_TABLE_H */\n"); + + fclose(fp); +} /**************************************************************************** * write_cmos_layout * diff --git a/util/nvramtool/accessors/layout-text.h b/util/nvramtool/accessors/layout-text.h index 21997e9a46..85628f7e5e 100644 --- a/util/nvramtool/accessors/layout-text.h +++ b/util/nvramtool/accessors/layout-text.h @@ -37,5 +37,8 @@ void set_layout_filename(const char filename[]); void get_layout_from_file(void); void write_cmos_layout(FILE * f); +void write_cmos_output_bin(const char *binary_filename); +void write_cmos_layout_header(const char *header_filename); +extern int is_ident(char *str); #endif /* LAYOUT_FILE_H */ diff --git a/util/nvramtool/cli/nvramtool.c b/util/nvramtool/cli/nvramtool.c index bcb10bbf34..f3fb16d1b1 100644 --- a/util/nvramtool/cli/nvramtool.c +++ b/util/nvramtool/cli/nvramtool.c @@ -62,6 +62,8 @@ 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 void op_write_cmos_layout_bin(void); +static void op_write_cmos_layout_header(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[]); @@ -86,9 +88,23 @@ static const op_fn_t op_fns[] = { op_show_version, op_write_cmos_dump, op_read_cmos_dump, op_show_cmos_hex_dump, - op_show_cmos_dumpfile + op_show_cmos_dumpfile, + op_write_cmos_layout_bin, + op_write_cmos_layout_header }; +static void op_write_cmos_layout_bin(void) +{ + get_layout_from_file(); + write_cmos_output_bin(nvramtool_op.param); +} + +static void op_write_cmos_layout_header(void) +{ + get_layout_from_file(); + write_cmos_layout_header(nvramtool_op.param); +} + static const hexdump_format_t cmos_dump_format = { 16, 2, "", " | ", " ", " | ", '.' }; diff --git a/util/nvramtool/cli/opts.c b/util/nvramtool/cli/opts.c index 49496495eb..8e920e8694 100644 --- a/util/nvramtool/cli/opts.c +++ b/util/nvramtool/cli/opts.c @@ -41,7 +41,7 @@ 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"; +static const char getopt_string[] = "-ab:B:c::C:dD:e:hH:iL:l::np:r:tvw:xX:y:Y"; /**************************************************************************** * parse_nvramtool_args @@ -100,6 +100,9 @@ void parse_nvramtool_args(int argc, char *argv[]) case 'h': register_op(&op_found, NVRAMTOOL_OP_SHOW_USAGE, NULL); break; + case 'H': + register_op(&op_found, NVRAMTOOL_OP_WRITE_HEADER_FILE, optarg); + break; case 'i': register_op(&op_found, NVRAMTOOL_OP_CMOS_SET_PARAMS_STDIN, NULL); @@ -108,6 +111,10 @@ void parse_nvramtool_args(int argc, char *argv[]) register_op(&op_found, NVRAMTOOL_OP_LBTABLE_SHOW_INFO, handle_optional_arg(argc, argv)); break; + case 'L': + register_op(&op_found, NVRAMTOOL_OP_WRITE_BINARY_FILE, + optarg); + break; case 'n': register_op_modifier(NVRAMTOOL_MOD_SHOW_VALUE_ONLY, NULL); diff --git a/util/nvramtool/cli/opts.h b/util/nvramtool/cli/opts.h index f46f254b88..a011ef1136 100644 --- a/util/nvramtool/cli/opts.h +++ b/util/nvramtool/cli/opts.h @@ -48,7 +48,9 @@ typedef enum { NVRAMTOOL_OP_SHOW_VERSION = 0, NVRAMTOOL_OP_WRITE_CMOS_DUMP, NVRAMTOOL_OP_READ_CMOS_DUMP, NVRAMTOOL_OP_SHOW_CMOS_HEX_DUMP, - NVRAMTOOL_OP_SHOW_CMOS_DUMPFILE + NVRAMTOOL_OP_SHOW_CMOS_DUMPFILE, + NVRAMTOOL_OP_WRITE_BINARY_FILE, + NVRAMTOOL_OP_WRITE_HEADER_FILE } nvramtool_op_t; typedef struct { diff --git a/util/nvramtool/common.c b/util/nvramtool/common.c index 91fcccc68b..15f8b0d5d1 100644 --- a/util/nvramtool/common.c +++ b/util/nvramtool/common.c @@ -98,6 +98,8 @@ void usage(FILE * outfile) "VALUE.\n" " -l [ARG]: Show coreboot table info for ARG, or " "all ARG choices.\n" + " -L OUTPUT_BIN Write CMOS layout file in binary format\n" + " -H OUTPUT_HDR Write CMOS layout file in header format\n" " -d: Show low-level dump of coreboot table.\n" " -Y: Show CMOS layout info.\n" " -b OUTPUT_FILE: Dump CMOS memory contents to file.\n" diff --git a/util/nvramtool/layout.h b/util/nvramtool/layout.h index d99275c031..082c31b47a 100644 --- a/util/nvramtool/layout.h +++ b/util/nvramtool/layout.h @@ -46,10 +46,10 @@ #define LAYOUT_CHECKSUM_LOCATION_OUT_OF_RANGE (LAYOUT_RESULT_START + 9) typedef enum { - CMOS_ENTRY_ENUM, - CMOS_ENTRY_HEX, - CMOS_ENTRY_STRING, - CMOS_ENTRY_RESERVED + CMOS_ENTRY_ENUM = 'e', + CMOS_ENTRY_HEX = 'h', + CMOS_ENTRY_STRING = 's', + CMOS_ENTRY_RESERVED = 'r', } cmos_entry_config_t; /* This represents a CMOS parameter. */