blob: 46fcc431c0df570e193a3d7d007878befcde420f [file] [log] [blame]
Uwe Hermann75f51072008-03-04 16:29:54 +00001/*
2 * This file is part of the flashrom project.
3 *
4 * Copyright (C) 2005-2008 coresystems GmbH
5 * (Written by Stefan Reinauer <stepan@coresystems.de> for coresystems GmbH)
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
Ollie Lho184a4042005-11-26 21:55:36 +000021#include <stdio.h>
22#include <stdlib.h>
23#include <string.h>
24#include <stdint.h>
Uwe Hermann0846f892007-08-23 13:34:59 +000025#include "flash.h"
Ollie Lho184a4042005-11-26 21:55:36 +000026
Uwe Hermanna7e05482007-05-09 10:17:44 +000027char *mainboard_vendor = NULL;
28char *mainboard_part = NULL;
29int romimages = 0;
Ollie Lho184a4042005-11-26 21:55:36 +000030
31extern int force;
32
33#define MAX_ROMLAYOUT 16
34
35typedef struct {
36 unsigned int start;
37 unsigned int end;
38 unsigned int included;
39 char name[256];
40} romlayout_t;
41
42romlayout_t rom_entries[MAX_ROMLAYOUT];
43
44static char *def_name = "DEFAULT";
45
Ollie Lho184a4042005-11-26 21:55:36 +000046int show_id(uint8_t *bios, int size)
47{
48 unsigned int *walk;
49
Uwe Hermanna7e05482007-05-09 10:17:44 +000050 walk = (unsigned int *)(bios + size - 0x10);
51 walk--;
Ollie Lho184a4042005-11-26 21:55:36 +000052
Uwe Hermanna7e05482007-05-09 10:17:44 +000053 if ((*walk) == 0 || ((*walk) & 0x3ff) != 0) {
Ollie Lho184a4042005-11-26 21:55:36 +000054 /* We might have an Nvidia chipset bios
55 * which stores the id information at a
56 * different location.
57 */
Uwe Hermanna7e05482007-05-09 10:17:44 +000058 walk = (unsigned int *)(bios + size - 0x80);
59 walk--;
Ollie Lho184a4042005-11-26 21:55:36 +000060 }
Uwe Hermanna7e05482007-05-09 10:17:44 +000061
62 if ((*walk) == 0 || ((*walk) & 0x3ff) != 0) {
Uwe Hermannac309342007-10-10 17:42:20 +000063 printf("Flash image seems to be a legacy BIOS. Disabling checks.\n");
Uwe Hermanna7e05482007-05-09 10:17:44 +000064 mainboard_vendor = def_name;
65 mainboard_part = def_name;
Ollie Lho184a4042005-11-26 21:55:36 +000066 return 0;
67 }
Uwe Hermanna7e05482007-05-09 10:17:44 +000068
Stefan Reinauere3f3e2e2008-01-18 15:33:10 +000069 printf_debug("coreboot last image size "
Uwe Hermanna502dce2007-10-17 23:55:15 +000070 "(not ROM size) is %d bytes.\n", *walk);
Uwe Hermanna7e05482007-05-09 10:17:44 +000071
72 walk--;
73 mainboard_part = strdup((const char *)(bios + size - *walk));
74 walk--;
75 mainboard_vendor = strdup((const char *)(bios + size - *walk));
Uwe Hermanna502dce2007-10-17 23:55:15 +000076 printf_debug("Manufacturer: %s\n", mainboard_vendor);
77 printf_debug("Mainboard ID: %s\n", mainboard_part);
Stefan Reinauer3a431602005-12-18 18:40:46 +000078
79 /*
Stefan Reinauere3f3e2e2008-01-18 15:33:10 +000080 * If lb_vendor is not set, the coreboot table was
Stefan Reinauer3a431602005-12-18 18:40:46 +000081 * not found. Nor was -mVENDOR:PART specified
82 */
83
Uwe Hermanna7e05482007-05-09 10:17:44 +000084 if (!lb_vendor || !lb_part) {
Stefan Reinauer3a431602005-12-18 18:40:46 +000085 printf("Note: If the following flash access fails, "
Uwe Hermanna502dce2007-10-17 23:55:15 +000086 "you might need to specify -m <vendor>:<mainboard>.\n");
Stefan Reinauer3a431602005-12-18 18:40:46 +000087 return 0;
88 }
Uwe Hermanna7e05482007-05-09 10:17:44 +000089
Stefan Reinauere3705282005-12-18 16:41:10 +000090 /* These comparisons are case insensitive to make things
91 * a little less user^Werror prone.
92 */
Stefan Reinauer3a431602005-12-18 18:40:46 +000093
Uwe Hermanna7e05482007-05-09 10:17:44 +000094 if (!strcasecmp(mainboard_vendor, lb_vendor) &&
95 !strcasecmp(mainboard_part, lb_part)) {
Stefan Reinauer3a431602005-12-18 18:40:46 +000096 printf_debug("This firmware image matches "
Uwe Hermannac309342007-10-10 17:42:20 +000097 "this motherboard.\n");
Ollie Lho184a4042005-11-26 21:55:36 +000098 } else {
Uwe Hermanna7e05482007-05-09 10:17:44 +000099 if (force) {
Ollie Lho184a4042005-11-26 21:55:36 +0000100 printf("WARNING: This firmware image does not "
Uwe Hermannac309342007-10-10 17:42:20 +0000101 "seem to fit to this machine - forcing it.\n");
Ollie Lho184a4042005-11-26 21:55:36 +0000102 } else {
Stefan Reinauer3a431602005-12-18 18:40:46 +0000103 printf("ERROR: Your firmware image (%s:%s) does not "
Uwe Hermanna7e05482007-05-09 10:17:44 +0000104 "appear to\n be correct for the detected "
105 "mainboard (%s:%s)\n\nOverride with --force if you "
106 "are absolutely sure that you\nare using a correct "
107 "image for this mainboard or override\nthe detected "
Uwe Hermannac309342007-10-10 17:42:20 +0000108 "values with --mainboard <vendor>:<mainboard>.\n\n",
Uwe Hermanna7e05482007-05-09 10:17:44 +0000109 mainboard_vendor, mainboard_part, lb_vendor,
110 lb_part);
Ollie Lho184a4042005-11-26 21:55:36 +0000111 exit(1);
112 }
113 }
Uwe Hermanna7e05482007-05-09 10:17:44 +0000114
Ollie Lho184a4042005-11-26 21:55:36 +0000115 return 0;
116}
117
Uwe Hermanna7e05482007-05-09 10:17:44 +0000118int read_romlayout(char *name)
Ollie Lho184a4042005-11-26 21:55:36 +0000119{
120 FILE *romlayout;
121 char tempstr[256];
122 int i;
123
Uwe Hermanna7e05482007-05-09 10:17:44 +0000124 romlayout = fopen(name, "r");
125
126 if (!romlayout) {
Uwe Hermanna502dce2007-10-17 23:55:15 +0000127 fprintf(stderr, "ERROR: Could not open ROM layout (%s).\n",
Uwe Hermanna7e05482007-05-09 10:17:44 +0000128 name);
Ollie Lho184a4042005-11-26 21:55:36 +0000129 return -1;
130 }
Uwe Hermanna7e05482007-05-09 10:17:44 +0000131
132 while (!feof(romlayout)) {
Ollie Lho184a4042005-11-26 21:55:36 +0000133 char *tstr1, *tstr2;
Uwe Hermanna7e05482007-05-09 10:17:44 +0000134 fscanf(romlayout, "%s %s\n", tempstr,
135 rom_entries[romimages].name);
Ollie Lho184a4042005-11-26 21:55:36 +0000136#if 0
137 // fscanf does not like arbitrary comments like that :( later
Uwe Hermanna7e05482007-05-09 10:17:44 +0000138 if (tempstr[0] == '#') {
Ollie Lho184a4042005-11-26 21:55:36 +0000139 continue;
140 }
141#endif
Uwe Hermanna7e05482007-05-09 10:17:44 +0000142 tstr1 = strtok(tempstr, ":");
143 tstr2 = strtok(NULL, ":");
144 rom_entries[romimages].start = strtol(tstr1, (char **)NULL, 16);
145 rom_entries[romimages].end = strtol(tstr2, (char **)NULL, 16);
146 rom_entries[romimages].included = 0;
Ollie Lho184a4042005-11-26 21:55:36 +0000147 romimages++;
148 }
Uwe Hermanna7e05482007-05-09 10:17:44 +0000149
150 for (i = 0; i < romimages; i++) {
151 printf_debug("romlayout %08x - %08x named %s\n",
152 rom_entries[i].start,
153 rom_entries[i].end, rom_entries[i].name);
Ollie Lho184a4042005-11-26 21:55:36 +0000154 }
155
156 fclose(romlayout);
Uwe Hermannffec5f32007-08-23 16:08:21 +0000157
Uwe Hermanna7e05482007-05-09 10:17:44 +0000158 return 0;
Ollie Lho184a4042005-11-26 21:55:36 +0000159}
160
161int find_romentry(char *name)
162{
163 int i;
164
Uwe Hermanna7e05482007-05-09 10:17:44 +0000165 if (!romimages)
166 return -1;
Ollie Lho184a4042005-11-26 21:55:36 +0000167
168 printf("Looking for \"%s\"... ", name);
Uwe Hermanna7e05482007-05-09 10:17:44 +0000169
170 for (i = 0; i < romimages; i++) {
171 if (!strcmp(rom_entries[i].name, name)) {
172 rom_entries[i].included = 1;
Uwe Hermannac309342007-10-10 17:42:20 +0000173 printf("found.\n");
Ollie Lho184a4042005-11-26 21:55:36 +0000174 return i;
175 }
176 }
Uwe Hermanna502dce2007-10-17 23:55:15 +0000177 printf("not found.\n"); // Not found. Error.
Uwe Hermannffec5f32007-08-23 16:08:21 +0000178
Ollie Lho184a4042005-11-26 21:55:36 +0000179 return -1;
180}
181
182int handle_romentries(uint8_t *buffer, uint8_t *content)
183{
184 int i;
185
186 // This function does not safe flash write cycles.
187 //
188 // Also it does not cope with overlapping rom layout
189 // sections.
190 // example:
191 // 00000000:00008fff gfxrom
192 // 00009000:0003ffff normal
193 // 00040000:0007ffff fallback
194 // 00000000:0007ffff all
195 //
196 // If you'd specify -i all the included flag of all other
197 // sections is still 0, so no changes will be made to the
198 // flash. Same thing if you specify -i normal -i all only
199 // normal will be updated and the rest will be kept.
200
Uwe Hermanna7e05482007-05-09 10:17:44 +0000201 for (i = 0; i < romimages; i++) {
202
203 if (rom_entries[i].included)
Ollie Lho184a4042005-11-26 21:55:36 +0000204 continue;
Uwe Hermanna7e05482007-05-09 10:17:44 +0000205
206 memcpy(buffer + rom_entries[i].start,
207 content + rom_entries[i].start,
208 rom_entries[i].end - rom_entries[i].start);
Ollie Lho184a4042005-11-26 21:55:36 +0000209 }
210
211 return 0;
212}