coreboot-kgpe-d16/util/flashrom/layout.c
Peter Stuge 646eb245e6 flashrom: Force read unknown flash chips
When flash chip detection fails, it is still useful and possible to read the
flash chip contents. If no flash chip is found in normal probes and the
-f -r -c CHIPNAME options are given, a successful probe for the specified
chip is forced, and then flashrom reads the flash chip using either the read
function for the specified chip, or if there is none, a simple memcpy().

The patch also moves the global variable int force in flashrom.c into main()
and passes it as a parameter to layout.c:show_id(), which was the only other
function that used the variable. This is needed to avoid confusion with the
new parameter int force which is added to flashrom.c:probe_flash() and used
to force probe success for the chip named in char *chip_to_probe.

Signed-off-by: Peter Stuge <peter@stuge.se>
Acked-by: Ward Vandewege <ward@gnu.org>


git-svn-id: svn://svn.coreboot.org/coreboot/trunk@3367 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
2008-06-18 02:08:40 +00:00

210 lines
5.2 KiB
C

/*
* This file is part of the flashrom project.
*
* Copyright (C) 2005-2008 coresystems GmbH
* (Written by Stefan Reinauer <stepan@coresystems.de> for coresystems GmbH)
*
* 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 of the License.
*
* 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
* 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include "flash.h"
char *mainboard_vendor = NULL;
char *mainboard_part = NULL;
int romimages = 0;
#define MAX_ROMLAYOUT 16
typedef struct {
unsigned int start;
unsigned int end;
unsigned int included;
char name[256];
} romlayout_t;
romlayout_t rom_entries[MAX_ROMLAYOUT];
static char *def_name = "DEFAULT";
int show_id(uint8_t *bios, int size, int force)
{
unsigned int *walk;
walk = (unsigned int *)(bios + size - 0x10);
walk--;
if ((*walk) == 0 || ((*walk) & 0x3ff) != 0) {
/* We might have an Nvidia chipset bios
* which stores the id information at a
* different location.
*/
walk = (unsigned int *)(bios + size - 0x80);
walk--;
}
if ((*walk) == 0 || ((*walk) & 0x3ff) != 0) {
printf("Flash image seems to be a legacy BIOS. Disabling checks.\n");
mainboard_vendor = def_name;
mainboard_part = def_name;
return 0;
}
printf_debug("coreboot last image size "
"(not ROM size) is %d bytes.\n", *walk);
walk--;
mainboard_part = strdup((const char *)(bios + size - *walk));
walk--;
mainboard_vendor = strdup((const char *)(bios + size - *walk));
printf_debug("Manufacturer: %s\n", mainboard_vendor);
printf_debug("Mainboard ID: %s\n", mainboard_part);
/*
* If lb_vendor is not set, the coreboot table was
* not found. Nor was -mVENDOR:PART specified
*/
if (!lb_vendor || !lb_part) {
printf("Note: If the following flash access fails, "
"you might need to specify -m <vendor>:<mainboard>.\n");
return 0;
}
/* These comparisons are case insensitive to make things
* a little less user^Werror prone.
*/
if (!strcasecmp(mainboard_vendor, lb_vendor) &&
!strcasecmp(mainboard_part, lb_part)) {
printf_debug("This firmware image matches "
"this motherboard.\n");
} else {
if (force) {
printf("WARNING: This firmware image does not "
"seem to fit to this machine - forcing it.\n");
} else {
printf("ERROR: Your firmware image (%s:%s) does not "
"appear to\n be correct for the detected "
"mainboard (%s:%s)\n\nOverride with --force if you "
"are absolutely sure that you\nare using a correct "
"image for this mainboard or override\nthe detected "
"values with --mainboard <vendor>:<mainboard>.\n\n",
mainboard_vendor, mainboard_part, lb_vendor,
lb_part);
exit(1);
}
}
return 0;
}
int read_romlayout(char *name)
{
FILE *romlayout;
char tempstr[256];
int i;
romlayout = fopen(name, "r");
if (!romlayout) {
fprintf(stderr, "ERROR: Could not open ROM layout (%s).\n",
name);
return -1;
}
while (!feof(romlayout)) {
char *tstr1, *tstr2;
fscanf(romlayout, "%s %s\n", tempstr,
rom_entries[romimages].name);
#if 0
// fscanf does not like arbitrary comments like that :( later
if (tempstr[0] == '#') {
continue;
}
#endif
tstr1 = strtok(tempstr, ":");
tstr2 = strtok(NULL, ":");
rom_entries[romimages].start = strtol(tstr1, (char **)NULL, 16);
rom_entries[romimages].end = strtol(tstr2, (char **)NULL, 16);
rom_entries[romimages].included = 0;
romimages++;
}
for (i = 0; i < romimages; i++) {
printf_debug("romlayout %08x - %08x named %s\n",
rom_entries[i].start,
rom_entries[i].end, rom_entries[i].name);
}
fclose(romlayout);
return 0;
}
int find_romentry(char *name)
{
int i;
if (!romimages)
return -1;
printf("Looking for \"%s\"... ", name);
for (i = 0; i < romimages; i++) {
if (!strcmp(rom_entries[i].name, name)) {
rom_entries[i].included = 1;
printf("found.\n");
return i;
}
}
printf("not found.\n"); // Not found. Error.
return -1;
}
int handle_romentries(uint8_t *buffer, uint8_t *content)
{
int i;
// This function does not safe flash write cycles.
//
// Also it does not cope with overlapping rom layout
// sections.
// example:
// 00000000:00008fff gfxrom
// 00009000:0003ffff normal
// 00040000:0007ffff fallback
// 00000000:0007ffff all
//
// If you'd specify -i all the included flag of all other
// sections is still 0, so no changes will be made to the
// flash. Same thing if you specify -i normal -i all only
// normal will be updated and the rest will be kept.
for (i = 0; i < romimages; i++) {
if (rom_entries[i].included)
continue;
memcpy(buffer + rom_entries[i].start,
content + rom_entries[i].start,
rom_entries[i].end - rom_entries[i].start);
}
return 0;
}