From 36ade67007e0e93fb36a982f87e91bf12e2ed869 Mon Sep 17 00:00:00 2001 From: Patrick Georgi Date: Fri, 28 Jan 2011 07:56:39 +0000 Subject: Separate CMOS layout from lbtable handling Signed-off-by: Patrick Georgi Acked-by: Stefan Reinauer git-svn-id: svn://svn.coreboot.org/coreboot/trunk@6314 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1 --- util/nvramtool/lbtable.c | 419 ----------------------------------------------- 1 file changed, 419 deletions(-) (limited to 'util/nvramtool/lbtable.c') diff --git a/util/nvramtool/lbtable.c b/util/nvramtool/lbtable.c index 0ec25f8317..2ce43c50f9 100644 --- a/util/nvramtool/lbtable.c +++ b/util/nvramtool/lbtable.c @@ -63,22 +63,8 @@ static const struct lb_header *lbtable_scan(unsigned long start, unsigned long end, int *bad_header_count, int *bad_table_count); -static void process_cmos_table(void); -static void get_cmos_checksum_info(void); -static void try_convert_checksum_layout(cmos_checksum_layout_t * layout); -static void try_add_cmos_table_enum(cmos_enum_t * cmos_enum); -static void try_add_cmos_table_entry(cmos_entry_t * cmos_entry); static const struct lb_record *find_lbrec(uint32_t tag); static const char *lbrec_tag_to_str(uint32_t tag); -static const struct cmos_entries *first_cmos_table_entry(void); -static const struct cmos_entries *next_cmos_table_entry(const struct - cmos_entries *last); -static const struct cmos_enums *first_cmos_table_enum(void); -static const struct cmos_enums *next_cmos_table_enum - (const struct cmos_enums *last); -static const struct lb_record *first_cmos_rec(uint32_t tag); -static const struct lb_record *next_cmos_rec(const struct lb_record *last, - uint32_t tag); static void memory_print_fn(const struct lb_record *rec); static void mainboard_print_fn(const struct lb_record *rec); static void cmos_opt_table_print_fn(const struct lb_record *rec); @@ -316,21 +302,6 @@ void get_lbtable(void) exit(1); } -static void process_layout(void) -{ - if ((cmos_table) == NULL) { - fprintf(stderr, - "%s: CMOS option table not found in coreboot table. " - "Apparently, the coreboot installed on this system was " - "built without specifying CONFIG_HAVE_OPTION_TABLE.\n", - prog_name); - exit(1); - } - - process_cmos_table(); - get_cmos_checksum_info(); -} - /**************************************************************************** * get_layout_from_cmos_table * @@ -346,17 +317,6 @@ void get_layout_from_cmos_table(void) process_layout(); } -void get_layout_from_cbfs_file(void) -{ - static struct lb_header header; - u32 len; - cmos_table = cbfs_find_file("cmos_layout.bin", CBFS_COMPONENT_CMOS_LAYOUT, &len); - lbtable = &header; - header.header_bytes = (u32)cmos_table-(u32)lbtable; - header.table_bytes = ntohl(len); - process_layout(); -} - /**************************************************************************** * dump_lbtable * @@ -572,269 +532,6 @@ static const struct lb_header *lbtable_scan(unsigned long start, return NULL; } -/**************************************************************************** - * process_cmos_table - * - * Extract layout information from the CMOS option table and store it in our - * internal repository. - ****************************************************************************/ -static void process_cmos_table(void) -{ - const struct cmos_enums *p; - const struct cmos_entries *q; - cmos_enum_t cmos_enum; - cmos_entry_t cmos_entry; - - /* First add the enums. */ - for (p = first_cmos_table_enum(); p != NULL; - p = next_cmos_table_enum(p)) { - cmos_enum.config_id = p->config_id; - cmos_enum.value = p->value; - strncpy(cmos_enum.text, (char *)p->text, CMOS_MAX_TEXT_LENGTH); - cmos_enum.text[CMOS_MAX_TEXT_LENGTH] = '\0'; - try_add_cmos_table_enum(&cmos_enum); - } - - /* Now add the entries. We must add the entries after the enums because - * the entries are sanity checked against the enums as they are added. - */ - for (q = first_cmos_table_entry(); q != NULL; - q = next_cmos_table_entry(q)) { - cmos_entry.bit = q->bit; - cmos_entry.length = q->length; - - switch (q->config) { - case 'e': - cmos_entry.config = CMOS_ENTRY_ENUM; - break; - - case 'h': - cmos_entry.config = CMOS_ENTRY_HEX; - break; - - case 'r': - cmos_entry.config = CMOS_ENTRY_RESERVED; - break; - - case 's': - cmos_entry.config = CMOS_ENTRY_STRING; - break; - - default: - fprintf(stderr, - "%s: Entry in CMOS option table has unknown config " - "value.\n", prog_name); - exit(1); - } - - cmos_entry.config_id = q->config_id; - strncpy(cmos_entry.name, (char *)q->name, CMOS_MAX_NAME_LENGTH); - cmos_entry.name[CMOS_MAX_NAME_LENGTH] = '\0'; - try_add_cmos_table_entry(&cmos_entry); - } -} - -/**************************************************************************** - * get_cmos_checksum_info - * - * Get layout information for CMOS checksum. - ****************************************************************************/ -static void get_cmos_checksum_info(void) -{ - const cmos_entry_t *e; - struct cmos_checksum *checksum; - cmos_checksum_layout_t layout; - unsigned index, index2; - - checksum = (struct cmos_checksum *)find_lbrec(LB_TAG_OPTION_CHECKSUM); - - if (checksum == NULL) { - checksum = (struct cmos_checksum *)next_cmos_rec((const struct lb_record *)first_cmos_table_enum(), LB_TAG_OPTION_CHECKSUM); - } - - if (checksum != NULL) { /* We are lucky. The coreboot table hints us to the checksum. - * We might have to check the type field here though. - */ - layout.summed_area_start = checksum->range_start; - layout.summed_area_end = checksum->range_end; - layout.checksum_at = checksum->location; - try_convert_checksum_layout(&layout); - cmos_checksum_start = layout.summed_area_start; - cmos_checksum_end = layout.summed_area_end; - cmos_checksum_index = layout.checksum_at; - return; - } - - if ((e = find_cmos_entry(checksum_param_name)) == NULL) - return; - - /* If we get here, we are unlucky. The CMOS option table contains the - * location of the CMOS checksum. However, there is no information - * regarding which bytes of the CMOS area the checksum is computed over. - * Thus we have to hope our presets will be fine. - */ - - if (e->bit % 8) { - fprintf(stderr, - "%s: Error: CMOS checksum is not byte-aligned.\n", - prog_name); - exit(1); - } - - index = e->bit / 8; - index2 = index + 1; /* The CMOS checksum occupies 16 bits. */ - - if (verify_cmos_byte_index(index) || verify_cmos_byte_index(index2)) { - fprintf(stderr, - "%s: Error: CMOS checksum location out of range.\n", - prog_name); - exit(1); - } - - if (((index >= cmos_checksum_start) && (index <= cmos_checksum_end)) || - (((index2) >= cmos_checksum_start) - && ((index2) <= cmos_checksum_end))) { - fprintf(stderr, - "%s: Error: CMOS checksum overlaps checksummed area.\n", - prog_name); - exit(1); - } - - cmos_checksum_index = index; -} - -/**************************************************************************** - * try_convert_checksum_layout - * - * Perform sanity checking on CMOS checksum layout information and attempt to - * convert information from bit positions to byte positions. Return OK on - * success or an error code on failure. - ****************************************************************************/ -static void try_convert_checksum_layout(cmos_checksum_layout_t * layout) -{ - switch (checksum_layout_to_bytes(layout)) { - case OK: - return; - - case LAYOUT_SUMMED_AREA_START_NOT_ALIGNED: - fprintf(stderr, - "%s: CMOS checksummed area start is not byte-aligned.\n", - prog_name); - break; - - case LAYOUT_SUMMED_AREA_END_NOT_ALIGNED: - fprintf(stderr, - "%s: CMOS checksummed area end is not byte-aligned.\n", - prog_name); - break; - - case LAYOUT_CHECKSUM_LOCATION_NOT_ALIGNED: - fprintf(stderr, - "%s: CMOS checksum location is not byte-aligned.\n", - prog_name); - break; - - case LAYOUT_INVALID_SUMMED_AREA: - fprintf(stderr, - "%s: CMOS checksummed area end must be greater than " - "CMOS checksummed area start.\n", prog_name); - break; - - case LAYOUT_CHECKSUM_OVERLAPS_SUMMED_AREA: - fprintf(stderr, - "%s: CMOS checksum overlaps checksummed area.\n", - prog_name); - break; - - case LAYOUT_SUMMED_AREA_OUT_OF_RANGE: - fprintf(stderr, - "%s: CMOS checksummed area out of range.\n", prog_name); - break; - - case LAYOUT_CHECKSUM_LOCATION_OUT_OF_RANGE: - fprintf(stderr, - "%s: CMOS checksum location out of range.\n", - prog_name); - break; - - default: - BUG(); - } - - exit(1); -} - -/**************************************************************************** - * try_add_cmos_table_enum - * - * Attempt to add a CMOS enum to our internal repository. Exit with an error - * message on failure. - ****************************************************************************/ -static void try_add_cmos_table_enum(cmos_enum_t * cmos_enum) -{ - switch (add_cmos_enum(cmos_enum)) { - case OK: - return; - - case LAYOUT_DUPLICATE_ENUM: - fprintf(stderr, "%s: Duplicate enum %s found in CMOS option " - "table.\n", prog_name, cmos_enum->text); - break; - - default: - BUG(); - } - - exit(1); -} - -/**************************************************************************** - * try_add_cmos_table_entry - * - * Attempt to add a CMOS entry to our internal repository. Exit with an - * error message on failure. - ****************************************************************************/ -static void try_add_cmos_table_entry(cmos_entry_t * cmos_entry) -{ - const cmos_entry_t *conflict; - - switch (add_cmos_entry(cmos_entry, &conflict)) { - case OK: - return; - - case CMOS_AREA_OUT_OF_RANGE: - fprintf(stderr, - "%s: Bad CMOS option layout in CMOS option table entry " - "%s.\n", prog_name, cmos_entry->name); - break; - - case CMOS_AREA_TOO_WIDE: - fprintf(stderr, - "%s: Area too wide for CMOS option table entry %s.\n", - prog_name, cmos_entry->name); - break; - - case LAYOUT_ENTRY_OVERLAP: - fprintf(stderr, - "%s: CMOS option table entries %s and %s have overlapping " - "layouts.\n", prog_name, cmos_entry->name, - conflict->name); - break; - - case LAYOUT_ENTRY_BAD_LENGTH: - /* Silently ignore entries with zero length. Although this should - * never happen in practice, we should handle the case in a - * reasonable manner just to be safe. - */ - return; - - default: - BUG(); - } - - exit(1); -} - /**************************************************************************** * find_lbrec * @@ -934,122 +631,6 @@ static const char *lbrec_tag_to_str(uint32_t tag) return "UNKNOWN"; } -/**************************************************************************** - * first_cmos_table_entry - * - * Return a pointer to the first entry in the CMOS table that represents a - * CMOS parameter. Return NULL if CMOS table is empty. - ****************************************************************************/ -static const struct cmos_entries *first_cmos_table_entry(void) -{ - return (const struct cmos_entries *)first_cmos_rec(LB_TAG_OPTION); -} - -/**************************************************************************** - * next_cmos_table_entry - * - * Return a pointer to the next entry after 'last' in the CMOS table that - * represents a CMOS parameter. Return NULL if there are no more parameters. - ****************************************************************************/ -static const struct cmos_entries *next_cmos_table_entry(const struct - cmos_entries *last) -{ - return (const struct cmos_entries *) - next_cmos_rec((const struct lb_record *)last, LB_TAG_OPTION); -} - -/**************************************************************************** - * first_cmos_table_enum - * - * Return a pointer to the first entry in the CMOS table that represents a - * possible CMOS parameter value. Return NULL if the table does not contain - * any such entries. - ****************************************************************************/ -static const struct cmos_enums *first_cmos_table_enum(void) -{ - return (const struct cmos_enums *)first_cmos_rec(LB_TAG_OPTION_ENUM); -} - -/**************************************************************************** - * next_cmos_table_enum - * - * Return a pointer to the next entry after 'last' in the CMOS table that - * represents a possible CMOS parameter value. Return NULL if there are no - * more parameter values. - ****************************************************************************/ -static const struct cmos_enums *next_cmos_table_enum - (const struct cmos_enums *last) { - return (const struct cmos_enums *) - next_cmos_rec((const struct lb_record *)last, LB_TAG_OPTION_ENUM); -} - -/**************************************************************************** - * first_cmos_rec - * - * Return a pointer to the first entry in the CMOS table whose type matches - * 'tag'. Return NULL if CMOS table contains no such entry. - * - * Possible values for 'tag' are as follows: - * - * LB_TAG_OPTION: The entry represents a CMOS parameter. - * LB_TAG_OPTION_ENUM: The entry represents a possible value for a CMOS - * parameter of type 'enum'. - * - * The CMOS table tells us where in the nonvolatile RAM to look for CMOS - * parameter values and specifies their types as 'enum', 'hex', or - * 'reserved'. - ****************************************************************************/ -static const struct lb_record *first_cmos_rec(uint32_t tag) -{ - const char *p; - uint32_t bytes_processed, bytes_for_entries; - const struct lb_record *lbrec; - - p = ((const char *)cmos_table) + cmos_table->header_length; - bytes_for_entries = cmos_table->size - cmos_table->header_length; - - for (bytes_processed = 0; - bytes_processed < bytes_for_entries; - bytes_processed += lbrec->size) { - lbrec = (const struct lb_record *)&p[bytes_processed]; - - if (lbrec->tag == tag) - return lbrec; - } - - return NULL; -} - -/**************************************************************************** - * next_cmos_rec - * - * Return a pointer to the next entry after 'last' in the CMOS table whose - * type matches 'tag'. Return NULL if the table contains no more entries of - * this type. - ****************************************************************************/ -static const struct lb_record *next_cmos_rec(const struct lb_record *last, - uint32_t tag) -{ - const char *p; - uint32_t bytes_processed, bytes_for_entries, last_offset; - const struct lb_record *lbrec; - - p = ((const char *)cmos_table) + cmos_table->header_length; - bytes_for_entries = cmos_table->size - cmos_table->header_length; - last_offset = ((const char *)last) - p; - - for (bytes_processed = last_offset + last->size; - bytes_processed < bytes_for_entries; - bytes_processed += lbrec->size) { - lbrec = (const struct lb_record *)&p[bytes_processed]; - - if (lbrec->tag == tag) - return lbrec; - } - - return NULL; -} - /**************************************************************************** * memory_print_fn * -- cgit v1.2.3