1
0
mirror of https://review.coreboot.org/flashrom.git synced 2025-04-26 22:52:34 +02:00
flashrom/layout.c
Stefan Tauner eb58257b96 Add a bunch of new/tested stuff and various small changes 14
Tested Mainboards:
OK:
 - ASUS M3A78-EH
   http://www.flashrom.org/pipermail/flashrom/2010-October/005297.html
 - ASUS P2B-LS
   http://www.flashrom.org/pipermail/flashrom/2010-November/005506.html
 - Biostar TA790GX A3+
   http://paste.flashrom.org/view.php?id=1350
 - ECS 848P-A7
   http://www.flashrom.org/pipermail/flashrom/2011-January/005781.html
 - GIGABYTE GA-G41MT-S2PT
   Reported on IRC
 - GIGABYTE GA-H77-D3H
   Reported and tested by Alexander Gordeev on IRC.
 - Gigabyte GA-X79-UD5
   http://www.flashrom.org/pipermail/flashrom/2012-August/009811.html
 - Shuttle FN78S
   http://www.flashrom.org/pipermail/flashrom/2012-August/009714.html
 - VIA EITX-3000
   Reported on IRC by Tuju

NOT OK:
 - Dell PowerEdge C6220 (0HYFFG)
   http://www.flashrom.org/pipermail/flashrom/2012-September/009900.html
 - Foxconn Q45M
   http://www.flashrom.org/pipermail/flashrom/2012-September/009923.html
 - MSI MS-7309 (K9N6SGM-V)
   http://www.flashrom.org/pipermail/flashrom/2012-August/009712.html
 - Supermicro X9QRi-F+
   http://www.flashrom.org/pipermail/flashrom/2012-September/009887.html
 - ZOTAC H61-ITX WiFi (H61ITX-A-E)
   http://www.flashrom.org/pipermail/flashrom/2012-August/009649.html

ASUS CUSL2-C has been tested to be working with the board enable once
implemented for the TUSL2-C board. They seem to have the same PCI IDs
as shown in the links below. Since only the CUSL2-C board enable has been
tested yet, we distinguish the two by DMI strings.
http://paste.flashrom.org/view.php?id=1393
http://www.flashrom.org/pipermail/flashrom/attachments/20091206/ddca2c6c/attachment-0002.eml

Tested flash chips:
 - Set EMST F25L008A to PREW (+PREW)
   http://www.flashrom.org/pipermail/flashrom/2012-August/009714.html
 - Set GigaDevice GD25Q64 to PREW (+PREW)
   http://git.chromium.org/gitweb/?p=chromiumos/third_party/flashrom.git;a=commit;h=9e8ef49b1f626c2197e131fba6c5b65c8af4eeea
 - Set Macronix MX25L12805 to P (+P)
   http://www.flashrom.org/pipermail/flashrom/2012-September/009887.html
 - Set SST SST49LF003A/B to PREW (+EW)
   http://paste.flashrom.org/view.php?id=467
 - Set Winbond W49V002FA to PREW (+EW)
   http://www.flashrom.org/pipermail/flashrom/2011-January/005781.html

Tested chipsets:
 - Intel X79 (0x1d41)
   http://www.flashrom.org/pipermail/flashrom/2012-August/009811.html

Board enables:
 - add ASUS P4P800-X
   Created by Idwer Vollering and tested by Mingsen Bao:
   http://paste.flashrom.org/view.php?id=467
 - add DMI string to P4P800-VM

Miscellaneous:
 - Add remaining Intel 7 series chipset (LPC) PCI IDs
 - Add generic SPI detection for chips from Winbond
 - Minor manpage changes
 - Minor other cleanups
 - Escape full stops after abbreviations in the manpage.
 - Add ICH9 and successors to spi_get_valid_read_addr

Corresponding to flashrom svn r1601.

Signed-off-by: Stefan Tauner <stefan.tauner@alumni.tuwien.ac.at>
Acked-by: Stefan Tauner <stefan.tauner@alumni.tuwien.ac.at>
2012-09-21 12:52:50 +00:00

255 lines
6.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 <limits.h>
#include "flash.h"
#include "programmer.h"
static int romimages = 0;
#define MAX_ROMLAYOUT 32
typedef struct {
unsigned int start;
unsigned int end;
unsigned int included;
char name[256];
} romlayout_t;
/* include_args lists arguments specified at the command line with -i. They
* must be processed at some point so that desired regions are marked as
* "included" in the rom_entries list.
*/
static char *include_args[MAX_ROMLAYOUT];
static int num_include_args = 0; /* the number of valid entries. */
static romlayout_t rom_entries[MAX_ROMLAYOUT];
#ifndef __LIBPAYLOAD__
int read_romlayout(char *name)
{
FILE *romlayout;
char tempstr[256];
int i;
romlayout = fopen(name, "r");
if (!romlayout) {
msg_gerr("ERROR: Could not open ROM layout (%s).\n",
name);
return -1;
}
while (!feof(romlayout)) {
char *tstr1, *tstr2;
if (romimages >= MAX_ROMLAYOUT) {
msg_gerr("Maximum number of ROM images (%i) in layout "
"file reached.\n", MAX_ROMLAYOUT);
return 1;
}
if (2 != fscanf(romlayout, "%s %s\n", tempstr, rom_entries[romimages].name))
continue;
#if 0
// fscanf does not like arbitrary comments like that :( later
if (tempstr[0] == '#') {
continue;
}
#endif
tstr1 = strtok(tempstr, ":");
tstr2 = strtok(NULL, ":");
if (!tstr1 || !tstr2) {
msg_gerr("Error parsing layout file. Offending string: \"%s\"\n", tempstr);
fclose(romlayout);
return 1;
}
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++) {
msg_gdbg("romlayout %08x - %08x named %s\n",
rom_entries[i].start,
rom_entries[i].end, rom_entries[i].name);
}
fclose(romlayout);
return 0;
}
#endif
/* returns the index of the entry (or a negative value if it is not found) */
int find_include_arg(const char *const name)
{
unsigned int i;
for (i = 0; i < num_include_args; i++) {
if (!strcmp(include_args[i], name))
return i;
}
return -1;
}
/* register an include argument (-i) for later processing */
int register_include_arg(char *name)
{
if (num_include_args >= MAX_ROMLAYOUT) {
msg_gerr("Too many regions included (%i).\n", num_include_args);
return 1;
}
if (name == NULL) {
msg_gerr("<NULL> is a bad region name.\n");
return 1;
}
if (find_include_arg(name) != -1) {
msg_gerr("Duplicate region name: \"%s\".\n", name);
return 1;
}
include_args[num_include_args] = name;
num_include_args++;
return 0;
}
/* returns the index of the entry (or a negative value if it is not found) */
static int find_romentry(char *name)
{
int i;
if (!romimages)
return -1;
msg_gspew("Looking for region \"%s\"... ", name);
for (i = 0; i < romimages; i++) {
if (!strcmp(rom_entries[i].name, name)) {
rom_entries[i].included = 1;
msg_gspew("found.\n");
return i;
}
}
msg_gspew("not found.\n");
return -1;
}
/* process -i arguments
* returns 0 to indicate success, >0 to indicate failure
*/
int process_include_args(void)
{
int i;
unsigned int found = 0;
if (num_include_args == 0)
return 0;
/* User has specified an area, but no layout file is loaded. */
if (!romimages) {
msg_gerr("Region requested (with -i \"%s\"), "
"but no layout data is available.\n",
include_args[0]);
return 1;
}
for (i = 0; i < num_include_args; i++) {
if (find_romentry(include_args[i]) < 0) {
msg_gerr("Invalid region specified: \"%s\".\n",
include_args[i]);
return 1;
}
found++;
}
msg_ginfo("Using region%s: \"%s\"", num_include_args > 1 ? "s" : "",
include_args[0]);
for (i = 1; i < num_include_args; i++)
msg_ginfo(", \"%s\"", include_args[i]);
msg_ginfo(".\n");
return 0;
}
romlayout_t *get_next_included_romentry(unsigned int start)
{
int i;
unsigned int best_start = UINT_MAX;
romlayout_t *best_entry = NULL;
romlayout_t *cur;
/* First come, first serve for overlapping regions. */
for (i = 0; i < romimages; i++) {
cur = &rom_entries[i];
if (!cur->included)
continue;
/* Already past the current entry? */
if (start > cur->end)
continue;
/* Inside the current entry? */
if (start >= cur->start)
return cur;
/* Entry begins after start. */
if (best_start > cur->start) {
best_start = cur->start;
best_entry = cur;
}
}
return best_entry;
}
int handle_romentries(const struct flashctx *flash, uint8_t *oldcontents, uint8_t *newcontents)
{
unsigned int start = 0;
romlayout_t *entry;
unsigned int size = flash->chip->total_size * 1024;
/* If no regions were specified for inclusion, assume
* that the user wants to write the complete new image.
*/
if (num_include_args == 0)
return 0;
/* Non-included romentries are ignored.
* The union of all included romentries is used from the new image.
*/
while (start < size) {
entry = get_next_included_romentry(start);
/* No more romentries for remaining region? */
if (!entry) {
memcpy(newcontents + start, oldcontents + start,
size - start);
break;
}
/* For non-included region, copy from old content. */
if (entry->start > start)
memcpy(newcontents + start, oldcontents + start,
entry->start - start);
/* Skip to location after current romentry. */
start = entry->end + 1;
/* Catch overflow. */
if (!start)
break;
}
return 0;
}