Home | History | Annotate | Download | only in tools
      1 // SPDX-License-Identifier: GPL-2.0
      2 /*
      3  * ifdtool - Manage Intel Firmware Descriptor information
      4  *
      5  * Copyright 2014 Google, Inc
      6  *
      7  * From Coreboot project, but it got a serious code clean-up
      8  * and a few new features
      9  */
     10 
     11 #include <assert.h>
     12 #include <fcntl.h>
     13 #include <getopt.h>
     14 #include <stdbool.h>
     15 #include <stdlib.h>
     16 #include <stdio.h>
     17 #include <string.h>
     18 #include <unistd.h>
     19 #include <sys/types.h>
     20 #include <sys/stat.h>
     21 #include <linux/libfdt.h>
     22 #include "ifdtool.h"
     23 
     24 #undef DEBUG
     25 
     26 #ifdef DEBUG
     27 #define debug(fmt, args...)	printf(fmt, ##args)
     28 #else
     29 #define debug(fmt, args...)
     30 #endif
     31 
     32 #define FD_SIGNATURE		0x0FF0A55A
     33 #define FLREG_BASE(reg)		((reg & 0x00000fff) << 12);
     34 #define FLREG_LIMIT(reg)	(((reg & 0x0fff0000) >> 4) | 0xfff);
     35 
     36 struct input_file {
     37 	char *fname;
     38 	unsigned int addr;
     39 };
     40 
     41 /**
     42  * find_fd() - Find the flash description in the ROM image
     43  *
     44  * @image:	Pointer to image
     45  * @size:	Size of image in bytes
     46  * @return pointer to structure, or NULL if not found
     47  */
     48 static struct fdbar_t *find_fd(char *image, int size)
     49 {
     50 	uint32_t *ptr, *end;
     51 
     52 	/* Scan for FD signature */
     53 	for (ptr = (uint32_t *)image, end = ptr + size / 4; ptr < end; ptr++) {
     54 		if (*ptr == FD_SIGNATURE)
     55 			break;
     56 	}
     57 
     58 	if (ptr == end) {
     59 		printf("No Flash Descriptor found in this image\n");
     60 		return NULL;
     61 	}
     62 
     63 	debug("Found Flash Descriptor signature at 0x%08lx\n",
     64 	      (char *)ptr - image);
     65 
     66 	return (struct fdbar_t *)ptr;
     67 }
     68 
     69 /**
     70  * get_region() - Get information about the selected region
     71  *
     72  * @frba:		Flash region list
     73  * @region_type:	Type of region (0..MAX_REGIONS-1)
     74  * @region:		Region information is written here
     75  * @return 0 if OK, else -ve
     76  */
     77 static int get_region(struct frba_t *frba, int region_type,
     78 		      struct region_t *region)
     79 {
     80 	if (region_type >= MAX_REGIONS) {
     81 		fprintf(stderr, "Invalid region type.\n");
     82 		return -1;
     83 	}
     84 
     85 	region->base = FLREG_BASE(frba->flreg[region_type]);
     86 	region->limit = FLREG_LIMIT(frba->flreg[region_type]);
     87 	region->size = region->limit - region->base + 1;
     88 
     89 	return 0;
     90 }
     91 
     92 static const char *region_name(int region_type)
     93 {
     94 	static const char *const regions[] = {
     95 		"Flash Descriptor",
     96 		"BIOS",
     97 		"Intel ME",
     98 		"GbE",
     99 		"Platform Data"
    100 	};
    101 
    102 	assert(region_type < MAX_REGIONS);
    103 
    104 	return regions[region_type];
    105 }
    106 
    107 static const char *region_filename(int region_type)
    108 {
    109 	static const char *const region_filenames[] = {
    110 		"flashregion_0_flashdescriptor.bin",
    111 		"flashregion_1_bios.bin",
    112 		"flashregion_2_intel_me.bin",
    113 		"flashregion_3_gbe.bin",
    114 		"flashregion_4_platform_data.bin"
    115 	};
    116 
    117 	assert(region_type < MAX_REGIONS);
    118 
    119 	return region_filenames[region_type];
    120 }
    121 
    122 static int dump_region(int num, struct frba_t *frba)
    123 {
    124 	struct region_t region;
    125 	int ret;
    126 
    127 	ret = get_region(frba, num, &region);
    128 	if (ret)
    129 		return ret;
    130 
    131 	printf("  Flash Region %d (%s): %08x - %08x %s\n",
    132 	       num, region_name(num), region.base, region.limit,
    133 	       region.size < 1 ? "(unused)" : "");
    134 
    135 	return ret;
    136 }
    137 
    138 static void dump_frba(struct frba_t *frba)
    139 {
    140 	int i;
    141 
    142 	printf("Found Region Section\n");
    143 	for (i = 0; i < MAX_REGIONS; i++) {
    144 		printf("FLREG%d:    0x%08x\n", i, frba->flreg[i]);
    145 		dump_region(i, frba);
    146 	}
    147 }
    148 
    149 static void decode_spi_frequency(unsigned int freq)
    150 {
    151 	switch (freq) {
    152 	case SPI_FREQUENCY_20MHZ:
    153 		printf("20MHz");
    154 		break;
    155 	case SPI_FREQUENCY_33MHZ:
    156 		printf("33MHz");
    157 		break;
    158 	case SPI_FREQUENCY_50MHZ:
    159 		printf("50MHz");
    160 		break;
    161 	default:
    162 		printf("unknown<%x>MHz", freq);
    163 	}
    164 }
    165 
    166 static void decode_component_density(unsigned int density)
    167 {
    168 	switch (density) {
    169 	case COMPONENT_DENSITY_512KB:
    170 		printf("512KiB");
    171 		break;
    172 	case COMPONENT_DENSITY_1MB:
    173 		printf("1MiB");
    174 		break;
    175 	case COMPONENT_DENSITY_2MB:
    176 		printf("2MiB");
    177 		break;
    178 	case COMPONENT_DENSITY_4MB:
    179 		printf("4MiB");
    180 		break;
    181 	case COMPONENT_DENSITY_8MB:
    182 		printf("8MiB");
    183 		break;
    184 	case COMPONENT_DENSITY_16MB:
    185 		printf("16MiB");
    186 		break;
    187 	default:
    188 		printf("unknown<%x>MiB", density);
    189 	}
    190 }
    191 
    192 static void dump_fcba(struct fcba_t *fcba)
    193 {
    194 	printf("\nFound Component Section\n");
    195 	printf("FLCOMP     0x%08x\n", fcba->flcomp);
    196 	printf("  Dual Output Fast Read Support:       %ssupported\n",
    197 	       (fcba->flcomp & (1 << 30)) ? "" : "not ");
    198 	printf("  Read ID/Read Status Clock Frequency: ");
    199 	decode_spi_frequency((fcba->flcomp >> 27) & 7);
    200 	printf("\n  Write/Erase Clock Frequency:         ");
    201 	decode_spi_frequency((fcba->flcomp >> 24) & 7);
    202 	printf("\n  Fast Read Clock Frequency:           ");
    203 	decode_spi_frequency((fcba->flcomp >> 21) & 7);
    204 	printf("\n  Fast Read Support:                   %ssupported",
    205 	       (fcba->flcomp & (1 << 20)) ? "" : "not ");
    206 	printf("\n  Read Clock Frequency:                ");
    207 	decode_spi_frequency((fcba->flcomp >> 17) & 7);
    208 	printf("\n  Component 2 Density:                 ");
    209 	decode_component_density((fcba->flcomp >> 3) & 7);
    210 	printf("\n  Component 1 Density:                 ");
    211 	decode_component_density(fcba->flcomp & 7);
    212 	printf("\n");
    213 	printf("FLILL      0x%08x\n", fcba->flill);
    214 	printf("  Invalid Instruction 3: 0x%02x\n",
    215 	       (fcba->flill >> 24) & 0xff);
    216 	printf("  Invalid Instruction 2: 0x%02x\n",
    217 	       (fcba->flill >> 16) & 0xff);
    218 	printf("  Invalid Instruction 1: 0x%02x\n",
    219 	       (fcba->flill >> 8) & 0xff);
    220 	printf("  Invalid Instruction 0: 0x%02x\n",
    221 	       fcba->flill & 0xff);
    222 	printf("FLPB       0x%08x\n", fcba->flpb);
    223 	printf("  Flash Partition Boundary Address: 0x%06x\n\n",
    224 	       (fcba->flpb & 0xfff) << 12);
    225 }
    226 
    227 static void dump_fpsba(struct fpsba_t *fpsba)
    228 {
    229 	int i;
    230 
    231 	printf("Found PCH Strap Section\n");
    232 	for (i = 0; i < MAX_STRAPS; i++)
    233 		printf("PCHSTRP%-2d:  0x%08x\n", i, fpsba->pchstrp[i]);
    234 }
    235 
    236 static const char *get_enabled(int flag)
    237 {
    238 	return flag ? "enabled" : "disabled";
    239 }
    240 
    241 static void decode_flmstr(uint32_t flmstr)
    242 {
    243 	printf("  Platform Data Region Write Access: %s\n",
    244 	       get_enabled(flmstr & (1 << 28)));
    245 	printf("  GbE Region Write Access:           %s\n",
    246 	       get_enabled(flmstr & (1 << 27)));
    247 	printf("  Intel ME Region Write Access:      %s\n",
    248 	       get_enabled(flmstr & (1 << 26)));
    249 	printf("  Host CPU/BIOS Region Write Access: %s\n",
    250 	       get_enabled(flmstr & (1 << 25)));
    251 	printf("  Flash Descriptor Write Access:     %s\n",
    252 	       get_enabled(flmstr & (1 << 24)));
    253 
    254 	printf("  Platform Data Region Read Access:  %s\n",
    255 	       get_enabled(flmstr & (1 << 20)));
    256 	printf("  GbE Region Read Access:            %s\n",
    257 	       get_enabled(flmstr & (1 << 19)));
    258 	printf("  Intel ME Region Read Access:       %s\n",
    259 	       get_enabled(flmstr & (1 << 18)));
    260 	printf("  Host CPU/BIOS Region Read Access:  %s\n",
    261 	       get_enabled(flmstr & (1 << 17)));
    262 	printf("  Flash Descriptor Read Access:      %s\n",
    263 	       get_enabled(flmstr & (1 << 16)));
    264 
    265 	printf("  Requester ID:                      0x%04x\n\n",
    266 	       flmstr & 0xffff);
    267 }
    268 
    269 static void dump_fmba(struct fmba_t *fmba)
    270 {
    271 	printf("Found Master Section\n");
    272 	printf("FLMSTR1:   0x%08x (Host CPU/BIOS)\n", fmba->flmstr1);
    273 	decode_flmstr(fmba->flmstr1);
    274 	printf("FLMSTR2:   0x%08x (Intel ME)\n", fmba->flmstr2);
    275 	decode_flmstr(fmba->flmstr2);
    276 	printf("FLMSTR3:   0x%08x (GbE)\n", fmba->flmstr3);
    277 	decode_flmstr(fmba->flmstr3);
    278 }
    279 
    280 static void dump_fmsba(struct fmsba_t *fmsba)
    281 {
    282 	int i;
    283 
    284 	printf("Found Processor Strap Section\n");
    285 	for (i = 0; i < 4; i++)
    286 		printf("????:      0x%08x\n", fmsba->data[0]);
    287 }
    288 
    289 static void dump_jid(uint32_t jid)
    290 {
    291 	printf("    SPI Component Device ID 1:          0x%02x\n",
    292 	       (jid >> 16) & 0xff);
    293 	printf("    SPI Component Device ID 0:          0x%02x\n",
    294 	       (jid >> 8) & 0xff);
    295 	printf("    SPI Component Vendor ID:            0x%02x\n",
    296 	       jid & 0xff);
    297 }
    298 
    299 static void dump_vscc(uint32_t vscc)
    300 {
    301 	printf("    Lower Erase Opcode:                 0x%02x\n",
    302 	       vscc >> 24);
    303 	printf("    Lower Write Enable on Write Status: 0x%02x\n",
    304 	       vscc & (1 << 20) ? 0x06 : 0x50);
    305 	printf("    Lower Write Status Required:        %s\n",
    306 	       vscc & (1 << 19) ? "Yes" : "No");
    307 	printf("    Lower Write Granularity:            %d bytes\n",
    308 	       vscc & (1 << 18) ? 64 : 1);
    309 	printf("    Lower Block / Sector Erase Size:    ");
    310 	switch ((vscc >> 16) & 0x3) {
    311 	case 0:
    312 		printf("256 Byte\n");
    313 		break;
    314 	case 1:
    315 		printf("4KB\n");
    316 		break;
    317 	case 2:
    318 		printf("8KB\n");
    319 		break;
    320 	case 3:
    321 		printf("64KB\n");
    322 		break;
    323 	}
    324 
    325 	printf("    Upper Erase Opcode:                 0x%02x\n",
    326 	       (vscc >> 8) & 0xff);
    327 	printf("    Upper Write Enable on Write Status: 0x%02x\n",
    328 	       vscc & (1 << 4) ? 0x06 : 0x50);
    329 	printf("    Upper Write Status Required:        %s\n",
    330 	       vscc & (1 << 3) ? "Yes" : "No");
    331 	printf("    Upper Write Granularity:            %d bytes\n",
    332 	       vscc & (1 << 2) ? 64 : 1);
    333 	printf("    Upper Block / Sector Erase Size:    ");
    334 	switch (vscc & 0x3) {
    335 	case 0:
    336 		printf("256 Byte\n");
    337 		break;
    338 	case 1:
    339 		printf("4KB\n");
    340 		break;
    341 	case 2:
    342 		printf("8KB\n");
    343 		break;
    344 	case 3:
    345 		printf("64KB\n");
    346 		break;
    347 	}
    348 }
    349 
    350 static void dump_vtba(struct vtba_t *vtba, int vtl)
    351 {
    352 	int i;
    353 	int num = (vtl >> 1) < 8 ? (vtl >> 1) : 8;
    354 
    355 	printf("ME VSCC table:\n");
    356 	for (i = 0; i < num; i++) {
    357 		printf("  JID%d:  0x%08x\n", i, vtba->entry[i].jid);
    358 		dump_jid(vtba->entry[i].jid);
    359 		printf("  VSCC%d: 0x%08x\n", i, vtba->entry[i].vscc);
    360 		dump_vscc(vtba->entry[i].vscc);
    361 	}
    362 	printf("\n");
    363 }
    364 
    365 static void dump_oem(uint8_t *oem)
    366 {
    367 	int i, j;
    368 	printf("OEM Section:\n");
    369 	for (i = 0; i < 4; i++) {
    370 		printf("%02x:", i << 4);
    371 		for (j = 0; j < 16; j++)
    372 			printf(" %02x", oem[(i<<4)+j]);
    373 		printf("\n");
    374 	}
    375 	printf("\n");
    376 }
    377 
    378 /**
    379  * dump_fd() - Display a dump of the full flash description
    380  *
    381  * @image:	Pointer to image
    382  * @size:	Size of image in bytes
    383  * @return 0 if OK, -1 on error
    384  */
    385 static int dump_fd(char *image, int size)
    386 {
    387 	struct fdbar_t *fdb = find_fd(image, size);
    388 
    389 	if (!fdb)
    390 		return -1;
    391 
    392 	printf("FLMAP0:    0x%08x\n", fdb->flmap0);
    393 	printf("  NR:      %d\n", (fdb->flmap0 >> 24) & 7);
    394 	printf("  FRBA:    0x%x\n", ((fdb->flmap0 >> 16) & 0xff) << 4);
    395 	printf("  NC:      %d\n", ((fdb->flmap0 >> 8) & 3) + 1);
    396 	printf("  FCBA:    0x%x\n", ((fdb->flmap0) & 0xff) << 4);
    397 
    398 	printf("FLMAP1:    0x%08x\n", fdb->flmap1);
    399 	printf("  ISL:     0x%02x\n", (fdb->flmap1 >> 24) & 0xff);
    400 	printf("  FPSBA:   0x%x\n", ((fdb->flmap1 >> 16) & 0xff) << 4);
    401 	printf("  NM:      %d\n", (fdb->flmap1 >> 8) & 3);
    402 	printf("  FMBA:    0x%x\n", ((fdb->flmap1) & 0xff) << 4);
    403 
    404 	printf("FLMAP2:    0x%08x\n", fdb->flmap2);
    405 	printf("  PSL:     0x%04x\n", (fdb->flmap2 >> 8) & 0xffff);
    406 	printf("  FMSBA:   0x%x\n", ((fdb->flmap2) & 0xff) << 4);
    407 
    408 	printf("FLUMAP1:   0x%08x\n", fdb->flumap1);
    409 	printf("  Intel ME VSCC Table Length (VTL):        %d\n",
    410 	       (fdb->flumap1 >> 8) & 0xff);
    411 	printf("  Intel ME VSCC Table Base Address (VTBA): 0x%06x\n\n",
    412 	       (fdb->flumap1 & 0xff) << 4);
    413 	dump_vtba((struct vtba_t *)
    414 			(image + ((fdb->flumap1 & 0xff) << 4)),
    415 			(fdb->flumap1 >> 8) & 0xff);
    416 	dump_oem((uint8_t *)image + 0xf00);
    417 	dump_frba((struct frba_t *)(image + (((fdb->flmap0 >> 16) & 0xff)
    418 			<< 4)));
    419 	dump_fcba((struct fcba_t *)(image + (((fdb->flmap0) & 0xff) << 4)));
    420 	dump_fpsba((struct fpsba_t *)
    421 			(image + (((fdb->flmap1 >> 16) & 0xff) << 4)));
    422 	dump_fmba((struct fmba_t *)(image + (((fdb->flmap1) & 0xff) << 4)));
    423 	dump_fmsba((struct fmsba_t *)(image + (((fdb->flmap2) & 0xff) << 4)));
    424 
    425 	return 0;
    426 }
    427 
    428 /**
    429  * write_regions() - Write each region from an image to its own file
    430  *
    431  * The filename to use in each case is fixed - see region_filename()
    432  *
    433  * @image:	Pointer to image
    434  * @size:	Size of image in bytes
    435  * @return 0 if OK, -ve on error
    436  */
    437 static int write_regions(char *image, int size)
    438 {
    439 	struct fdbar_t *fdb;
    440 	struct frba_t *frba;
    441 	int ret = 0;
    442 	int i;
    443 
    444 	fdb =  find_fd(image, size);
    445 	if (!fdb)
    446 		return -1;
    447 
    448 	frba = (struct frba_t *)(image + (((fdb->flmap0 >> 16) & 0xff) << 4));
    449 
    450 	for (i = 0; i < MAX_REGIONS; i++) {
    451 		struct region_t region;
    452 		int region_fd;
    453 
    454 		ret = get_region(frba, i, &region);
    455 		if (ret)
    456 			return ret;
    457 		dump_region(i, frba);
    458 		if (region.size <= 0)
    459 			continue;
    460 		region_fd = open(region_filename(i),
    461 				 O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR |
    462 				 S_IWUSR | S_IRGRP | S_IROTH);
    463 		if (write(region_fd, image + region.base, region.size) !=
    464 				region.size) {
    465 			perror("Error while writing");
    466 			ret = -1;
    467 		}
    468 		close(region_fd);
    469 	}
    470 
    471 	return ret;
    472 }
    473 
    474 static int perror_fname(const char *fmt, const char *fname)
    475 {
    476 	char msg[strlen(fmt) + strlen(fname) + 1];
    477 
    478 	sprintf(msg, fmt, fname);
    479 	perror(msg);
    480 
    481 	return -1;
    482 }
    483 
    484 /**
    485  * write_image() - Write the image to a file
    486  *
    487  * @filename:	Filename to use for the image
    488  * @image:	Pointer to image
    489  * @size:	Size of image in bytes
    490  * @return 0 if OK, -ve on error
    491  */
    492 static int write_image(char *filename, char *image, int size)
    493 {
    494 	int new_fd;
    495 
    496 	debug("Writing new image to %s\n", filename);
    497 
    498 	new_fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR |
    499 		      S_IWUSR | S_IRGRP | S_IROTH);
    500 	if (new_fd < 0)
    501 		return perror_fname("Could not open file '%s'", filename);
    502 	if (write(new_fd, image, size) != size)
    503 		return perror_fname("Could not write file '%s'", filename);
    504 	close(new_fd);
    505 
    506 	return 0;
    507 }
    508 
    509 /**
    510  * set_spi_frequency() - Set the SPI frequency to use when booting
    511  *
    512  * Several frequencies are supported, some of which work with fast devices.
    513  * For SPI emulators, the slowest (SPI_FREQUENCY_20MHZ) is often used. The
    514  * Intel boot system uses this information somehow on boot.
    515  *
    516  * The image is updated with the supplied value
    517  *
    518  * @image:	Pointer to image
    519  * @size:	Size of image in bytes
    520  * @freq:	SPI frequency to use
    521  */
    522 static void set_spi_frequency(char *image, int size, enum spi_frequency freq)
    523 {
    524 	struct fdbar_t *fdb = find_fd(image, size);
    525 	struct fcba_t *fcba;
    526 
    527 	fcba = (struct fcba_t *)(image + (((fdb->flmap0) & 0xff) << 4));
    528 
    529 	/* clear bits 21-29 */
    530 	fcba->flcomp &= ~0x3fe00000;
    531 	/* Read ID and Read Status Clock Frequency */
    532 	fcba->flcomp |= freq << 27;
    533 	/* Write and Erase Clock Frequency */
    534 	fcba->flcomp |= freq << 24;
    535 	/* Fast Read Clock Frequency */
    536 	fcba->flcomp |= freq << 21;
    537 }
    538 
    539 /**
    540  * set_em100_mode() - Set a SPI frequency that will work with Dediprog EM100
    541  *
    542  * @image:	Pointer to image
    543  * @size:	Size of image in bytes
    544  */
    545 static void set_em100_mode(char *image, int size)
    546 {
    547 	struct fdbar_t *fdb = find_fd(image, size);
    548 	struct fcba_t *fcba;
    549 
    550 	fcba = (struct fcba_t *)(image + (((fdb->flmap0) & 0xff) << 4));
    551 	fcba->flcomp &= ~(1 << 30);
    552 	set_spi_frequency(image, size, SPI_FREQUENCY_20MHZ);
    553 }
    554 
    555 /**
    556  * lock_descriptor() - Lock the NE descriptor so it cannot be updated
    557  *
    558  * @image:	Pointer to image
    559  * @size:	Size of image in bytes
    560  */
    561 static void lock_descriptor(char *image, int size)
    562 {
    563 	struct fdbar_t *fdb = find_fd(image, size);
    564 	struct fmba_t *fmba;
    565 
    566 	/*
    567 	 * TODO: Dynamically take Platform Data Region and GbE Region into
    568 	 * account.
    569 	 */
    570 	fmba = (struct fmba_t *)(image + (((fdb->flmap1) & 0xff) << 4));
    571 	fmba->flmstr1 = 0x0a0b0000;
    572 	fmba->flmstr2 = 0x0c0d0000;
    573 	fmba->flmstr3 = 0x08080118;
    574 }
    575 
    576 /**
    577  * unlock_descriptor() - Lock the NE descriptor so it can be updated
    578  *
    579  * @image:	Pointer to image
    580  * @size:	Size of image in bytes
    581  */
    582 static void unlock_descriptor(char *image, int size)
    583 {
    584 	struct fdbar_t *fdb = find_fd(image, size);
    585 	struct fmba_t *fmba;
    586 
    587 	fmba = (struct fmba_t *)(image + (((fdb->flmap1) & 0xff) << 4));
    588 	fmba->flmstr1 = 0xffff0000;
    589 	fmba->flmstr2 = 0xffff0000;
    590 	fmba->flmstr3 = 0x08080118;
    591 }
    592 
    593 /**
    594  * open_for_read() - Open a file for reading
    595  *
    596  * @fname:	Filename to open
    597  * @sizep:	Returns file size in bytes
    598  * @return 0 if OK, -1 on error
    599  */
    600 int open_for_read(const char *fname, int *sizep)
    601 {
    602 	int fd = open(fname, O_RDONLY);
    603 	struct stat buf;
    604 
    605 	if (fd == -1)
    606 		return perror_fname("Could not open file '%s'", fname);
    607 	if (fstat(fd, &buf) == -1)
    608 		return perror_fname("Could not stat file '%s'", fname);
    609 	*sizep = buf.st_size;
    610 	debug("File %s is %d bytes\n", fname, *sizep);
    611 
    612 	return fd;
    613 }
    614 
    615 /**
    616  * inject_region() - Add a file to an image region
    617  *
    618  * This puts a file into a particular region of the flash. Several pre-defined
    619  * regions are used.
    620  *
    621  * @image:		Pointer to image
    622  * @size:		Size of image in bytes
    623  * @region_type:	Region where the file should be added
    624  * @region_fname:	Filename to add to the image
    625  * @return 0 if OK, -ve on error
    626  */
    627 int inject_region(char *image, int size, int region_type, char *region_fname)
    628 {
    629 	struct fdbar_t *fdb = find_fd(image, size);
    630 	struct region_t region;
    631 	struct frba_t *frba;
    632 	int region_size;
    633 	int offset = 0;
    634 	int region_fd;
    635 	int ret;
    636 
    637 	if (!fdb)
    638 		exit(EXIT_FAILURE);
    639 	frba = (struct frba_t *)(image + (((fdb->flmap0 >> 16) & 0xff) << 4));
    640 
    641 	ret = get_region(frba, region_type, &region);
    642 	if (ret)
    643 		return -1;
    644 	if (region.size <= 0xfff) {
    645 		fprintf(stderr, "Region %s is disabled in target. Not injecting.\n",
    646 			region_name(region_type));
    647 		return -1;
    648 	}
    649 
    650 	region_fd = open_for_read(region_fname, &region_size);
    651 	if (region_fd < 0)
    652 		return region_fd;
    653 
    654 	if ((region_size > region.size) ||
    655 	    ((region_type != 1) && (region_size > region.size))) {
    656 		fprintf(stderr, "Region %s is %d(0x%x) bytes. File is %d(0x%x)  bytes. Not injecting.\n",
    657 			region_name(region_type), region.size,
    658 			region.size, region_size, region_size);
    659 		return -1;
    660 	}
    661 
    662 	if ((region_type == 1) && (region_size < region.size)) {
    663 		fprintf(stderr, "Region %s is %d(0x%x) bytes. File is %d(0x%x) bytes. Padding before injecting.\n",
    664 			region_name(region_type), region.size,
    665 			region.size, region_size, region_size);
    666 		offset = region.size - region_size;
    667 		memset(image + region.base, 0xff, offset);
    668 	}
    669 
    670 	if (size < region.base + offset + region_size) {
    671 		fprintf(stderr, "Output file is too small. (%d < %d)\n",
    672 			size, region.base + offset + region_size);
    673 		return -1;
    674 	}
    675 
    676 	if (read(region_fd, image + region.base + offset, region_size)
    677 							!= region_size) {
    678 		perror("Could not read file");
    679 		return -1;
    680 	}
    681 
    682 	close(region_fd);
    683 
    684 	debug("Adding %s as the %s section\n", region_fname,
    685 	      region_name(region_type));
    686 
    687 	return 0;
    688 }
    689 
    690 /**
    691  * write_data() - Write some raw data into a region
    692  *
    693  * This puts a file into a particular place in the flash, ignoring the
    694  * regions. Be careful not to overwrite something important.
    695  *
    696  * @image:		Pointer to image
    697  * @size:		Size of image in bytes
    698  * @addr:		x86 ROM address to put file. The ROM ends at
    699  *			0xffffffff so use an address relative to that. For an
    700  *			8MB ROM the start address is 0xfff80000.
    701  * @write_fname:	Filename to add to the image
    702  * @offset_uboot_top:	Offset of the top of U-Boot
    703  * @offset_uboot_start:	Offset of the start of U-Boot
    704  * @return number of bytes written if OK, -ve on error
    705  */
    706 static int write_data(char *image, int size, unsigned int addr,
    707 		      const char *write_fname, int offset_uboot_top,
    708 		      int offset_uboot_start)
    709 {
    710 	int write_fd, write_size;
    711 	int offset;
    712 
    713 	write_fd = open_for_read(write_fname, &write_size);
    714 	if (write_fd < 0)
    715 		return write_fd;
    716 
    717 	offset = (uint32_t)(addr + size);
    718 	if (offset_uboot_top) {
    719 		if (offset_uboot_start < offset &&
    720 		    offset_uboot_top >= offset) {
    721 			fprintf(stderr, "U-Boot image overlaps with region '%s'\n",
    722 				write_fname);
    723 			fprintf(stderr,
    724 				"U-Boot finishes at offset %x, file starts at %x\n",
    725 				offset_uboot_top, offset);
    726 			return -EXDEV;
    727 		}
    728 		if (offset_uboot_start > offset &&
    729 		    offset_uboot_start <= offset + write_size) {
    730 			fprintf(stderr, "U-Boot image overlaps with region '%s'\n",
    731 				write_fname);
    732 			fprintf(stderr,
    733 				"U-Boot starts at offset %x, file finishes at %x\n",
    734 				offset_uboot_start, offset + write_size);
    735 			return -EXDEV;
    736 		}
    737 	}
    738 	debug("Writing %s to offset %#x\n", write_fname, offset);
    739 
    740 	if (offset < 0 || offset + write_size > size) {
    741 		fprintf(stderr, "Output file is too small. (%d < %d)\n",
    742 			size, offset + write_size);
    743 		return -1;
    744 	}
    745 
    746 	if (read(write_fd, image + offset, write_size) != write_size) {
    747 		perror("Could not read file");
    748 		return -1;
    749 	}
    750 
    751 	close(write_fd);
    752 
    753 	return write_size;
    754 }
    755 
    756 static void print_version(void)
    757 {
    758 	printf("ifdtool v%s -- ", IFDTOOL_VERSION);
    759 	printf("Copyright (C) 2014 Google Inc.\n\n");
    760 	printf("SPDX-License-Identifier: GPL-2.0+\n");
    761 }
    762 
    763 static void print_usage(const char *name)
    764 {
    765 	printf("usage: %s [-vhdix?] <filename> [<outfile>]\n", name);
    766 	printf("\n"
    767 	       "   -d | --dump:                      dump intel firmware descriptor\n"
    768 	       "   -x | --extract:                   extract intel fd modules\n"
    769 	       "   -i | --inject <region>:<module>   inject file <module> into region <region>\n"
    770 	       "   -w | --write <addr>:<file>        write file to appear at memory address <addr>\n"
    771 	       "                                     multiple files can be written simultaneously\n"
    772 	       "   -s | --spifreq <20|33|50>         set the SPI frequency\n"
    773 	       "   -e | --em100                      set SPI frequency to 20MHz and disable\n"
    774 	       "                                     Dual Output Fast Read Support\n"
    775 	       "   -l | --lock                       Lock firmware descriptor and ME region\n"
    776 	       "   -u | --unlock                     Unlock firmware descriptor and ME region\n"
    777 	       "   -r | --romsize                    Specify ROM size\n"
    778 	       "   -D | --write-descriptor <file>    Write descriptor at base\n"
    779 	       "   -c | --create                     Create a new empty image\n"
    780 	       "   -v | --version:                   print the version\n"
    781 	       "   -h | --help:                      print this help\n\n"
    782 	       "<region> is one of Descriptor, BIOS, ME, GbE, Platform\n"
    783 	       "\n");
    784 }
    785 
    786 /**
    787  * get_two_words() - Convert a string into two words separated by :
    788  *
    789  * The supplied string is split at ':', two substrings are allocated and
    790  * returned.
    791  *
    792  * @str:	String to split
    793  * @firstp:	Returns first string
    794  * @secondp:	Returns second string
    795  * @return 0 if OK, -ve if @str does not have a :
    796  */
    797 static int get_two_words(const char *str, char **firstp, char **secondp)
    798 {
    799 	const char *p;
    800 
    801 	p = strchr(str, ':');
    802 	if (!p)
    803 		return -1;
    804 	*firstp = strdup(str);
    805 	(*firstp)[p - str] = '\0';
    806 	*secondp = strdup(p + 1);
    807 
    808 	return 0;
    809 }
    810 
    811 int main(int argc, char *argv[])
    812 {
    813 	int opt, option_index = 0;
    814 	int mode_dump = 0, mode_extract = 0, mode_inject = 0;
    815 	int mode_spifreq = 0, mode_em100 = 0, mode_locked = 0;
    816 	int mode_unlocked = 0, mode_write = 0, mode_write_descriptor = 0;
    817 	int create = 0;
    818 	char *region_type_string = NULL, *inject_fname = NULL;
    819 	char *desc_fname = NULL, *addr_str = NULL;
    820 	int region_type = -1, inputfreq = 0;
    821 	enum spi_frequency spifreq = SPI_FREQUENCY_20MHZ;
    822 	struct input_file input_file[WRITE_MAX], *ifile, *fdt = NULL;
    823 	unsigned char wr_idx, wr_num = 0;
    824 	int rom_size = -1;
    825 	bool write_it;
    826 	char *filename;
    827 	char *outfile = NULL;
    828 	struct stat buf;
    829 	int size = 0;
    830 	bool have_uboot = false;
    831 	int bios_fd;
    832 	char *image;
    833 	int ret;
    834 	static struct option long_options[] = {
    835 		{"create", 0, NULL, 'c'},
    836 		{"dump", 0, NULL, 'd'},
    837 		{"descriptor", 1, NULL, 'D'},
    838 		{"em100", 0, NULL, 'e'},
    839 		{"extract", 0, NULL, 'x'},
    840 		{"fdt", 1, NULL, 'f'},
    841 		{"inject", 1, NULL, 'i'},
    842 		{"lock", 0, NULL, 'l'},
    843 		{"romsize", 1, NULL, 'r'},
    844 		{"spifreq", 1, NULL, 's'},
    845 		{"unlock", 0, NULL, 'u'},
    846 		{"uboot", 1, NULL, 'U'},
    847 		{"write", 1, NULL, 'w'},
    848 		{"version", 0, NULL, 'v'},
    849 		{"help", 0, NULL, 'h'},
    850 		{0, 0, 0, 0}
    851 	};
    852 
    853 	while ((opt = getopt_long(argc, argv, "cdD:ef:hi:lr:s:uU:vw:x?",
    854 				  long_options, &option_index)) != EOF) {
    855 		switch (opt) {
    856 		case 'c':
    857 			create = 1;
    858 			break;
    859 		case 'd':
    860 			mode_dump = 1;
    861 			break;
    862 		case 'D':
    863 			mode_write_descriptor = 1;
    864 			desc_fname = optarg;
    865 			break;
    866 		case 'e':
    867 			mode_em100 = 1;
    868 			break;
    869 		case 'i':
    870 			if (get_two_words(optarg, &region_type_string,
    871 					  &inject_fname)) {
    872 				print_usage(argv[0]);
    873 				exit(EXIT_FAILURE);
    874 			}
    875 			if (!strcasecmp("Descriptor", region_type_string))
    876 				region_type = 0;
    877 			else if (!strcasecmp("BIOS", region_type_string))
    878 				region_type = 1;
    879 			else if (!strcasecmp("ME", region_type_string))
    880 				region_type = 2;
    881 			else if (!strcasecmp("GbE", region_type_string))
    882 				region_type = 3;
    883 			else if (!strcasecmp("Platform", region_type_string))
    884 				region_type = 4;
    885 			if (region_type == -1) {
    886 				fprintf(stderr, "No such region type: '%s'\n\n",
    887 					region_type_string);
    888 				print_usage(argv[0]);
    889 				exit(EXIT_FAILURE);
    890 			}
    891 			mode_inject = 1;
    892 			break;
    893 		case 'l':
    894 			mode_locked = 1;
    895 			break;
    896 		case 'r':
    897 			rom_size = strtol(optarg, NULL, 0);
    898 			debug("ROM size %d\n", rom_size);
    899 			break;
    900 		case 's':
    901 			/* Parse the requested SPI frequency */
    902 			inputfreq = strtol(optarg, NULL, 0);
    903 			switch (inputfreq) {
    904 			case 20:
    905 				spifreq = SPI_FREQUENCY_20MHZ;
    906 				break;
    907 			case 33:
    908 				spifreq = SPI_FREQUENCY_33MHZ;
    909 				break;
    910 			case 50:
    911 				spifreq = SPI_FREQUENCY_50MHZ;
    912 				break;
    913 			default:
    914 				fprintf(stderr, "Invalid SPI Frequency: %d\n",
    915 					inputfreq);
    916 				print_usage(argv[0]);
    917 				exit(EXIT_FAILURE);
    918 			}
    919 			mode_spifreq = 1;
    920 			break;
    921 		case 'u':
    922 			mode_unlocked = 1;
    923 			break;
    924 		case 'v':
    925 			print_version();
    926 			exit(EXIT_SUCCESS);
    927 			break;
    928 		case 'w':
    929 		case 'U':
    930 		case 'f':
    931 			ifile = &input_file[wr_num];
    932 			mode_write = 1;
    933 			if (wr_num < WRITE_MAX) {
    934 				if (get_two_words(optarg, &addr_str,
    935 						  &ifile->fname)) {
    936 					print_usage(argv[0]);
    937 					exit(EXIT_FAILURE);
    938 				}
    939 				ifile->addr = strtoll(optarg, NULL, 0);
    940 				wr_num++;
    941 			} else {
    942 				fprintf(stderr,
    943 					"The number of files to write simultaneously exceeds the limitation (%d)\n",
    944 					WRITE_MAX);
    945 			}
    946 			break;
    947 		case 'x':
    948 			mode_extract = 1;
    949 			break;
    950 		case 'h':
    951 		case '?':
    952 		default:
    953 			print_usage(argv[0]);
    954 			exit(EXIT_SUCCESS);
    955 			break;
    956 		}
    957 	}
    958 
    959 	if (mode_locked == 1 && mode_unlocked == 1) {
    960 		fprintf(stderr, "Locking/Unlocking FD and ME are mutually exclusive\n");
    961 		exit(EXIT_FAILURE);
    962 	}
    963 
    964 	if (mode_inject == 1 && mode_write == 1) {
    965 		fprintf(stderr, "Inject/Write are mutually exclusive\n");
    966 		exit(EXIT_FAILURE);
    967 	}
    968 
    969 	if ((mode_dump + mode_extract + mode_inject +
    970 		(mode_spifreq | mode_em100 | mode_unlocked |
    971 		 mode_locked)) > 1) {
    972 		fprintf(stderr, "You may not specify more than one mode.\n\n");
    973 		print_usage(argv[0]);
    974 		exit(EXIT_FAILURE);
    975 	}
    976 
    977 	if ((mode_dump + mode_extract + mode_inject + mode_spifreq +
    978 	     mode_em100 + mode_locked + mode_unlocked + mode_write +
    979 	     mode_write_descriptor) == 0 && !create) {
    980 		fprintf(stderr, "You need to specify a mode.\n\n");
    981 		print_usage(argv[0]);
    982 		exit(EXIT_FAILURE);
    983 	}
    984 
    985 	if (create && rom_size == -1) {
    986 		fprintf(stderr, "You need to specify a rom size when creating.\n\n");
    987 		exit(EXIT_FAILURE);
    988 	}
    989 
    990 	if (optind + 1 != argc) {
    991 		fprintf(stderr, "You need to specify a file.\n\n");
    992 		print_usage(argv[0]);
    993 		exit(EXIT_FAILURE);
    994 	}
    995 
    996 	if (have_uboot && !fdt) {
    997 		fprintf(stderr,
    998 			"You must supply a device tree file for U-Boot\n\n");
    999 		print_usage(argv[0]);
   1000 		exit(EXIT_FAILURE);
   1001 	}
   1002 
   1003 	filename = argv[optind];
   1004 	if (optind + 2 != argc)
   1005 		outfile = argv[optind + 1];
   1006 
   1007 	if (create)
   1008 		bios_fd = open(filename, O_WRONLY | O_CREAT, 0666);
   1009 	else
   1010 		bios_fd = open(filename, outfile ? O_RDONLY : O_RDWR);
   1011 
   1012 	if (bios_fd == -1) {
   1013 		perror("Could not open file");
   1014 		exit(EXIT_FAILURE);
   1015 	}
   1016 
   1017 	if (!create) {
   1018 		if (fstat(bios_fd, &buf) == -1) {
   1019 			perror("Could not stat file");
   1020 			exit(EXIT_FAILURE);
   1021 		}
   1022 		size = buf.st_size;
   1023 	}
   1024 
   1025 	debug("File %s is %d bytes\n", filename, size);
   1026 
   1027 	if (rom_size == -1)
   1028 		rom_size = size;
   1029 
   1030 	image = malloc(rom_size);
   1031 	if (!image) {
   1032 		printf("Out of memory.\n");
   1033 		exit(EXIT_FAILURE);
   1034 	}
   1035 
   1036 	memset(image, '\xff', rom_size);
   1037 	if (!create && read(bios_fd, image, size) != size) {
   1038 		perror("Could not read file");
   1039 		exit(EXIT_FAILURE);
   1040 	}
   1041 	if (size != rom_size) {
   1042 		debug("ROM size changed to %d bytes\n", rom_size);
   1043 		size = rom_size;
   1044 	}
   1045 
   1046 	write_it = true;
   1047 	ret = 0;
   1048 	if (mode_dump) {
   1049 		ret = dump_fd(image, size);
   1050 		write_it = false;
   1051 	}
   1052 
   1053 	if (mode_extract) {
   1054 		ret = write_regions(image, size);
   1055 		write_it = false;
   1056 	}
   1057 
   1058 	if (mode_write_descriptor)
   1059 		ret = write_data(image, size, -size, desc_fname, 0, 0);
   1060 
   1061 	if (mode_inject)
   1062 		ret = inject_region(image, size, region_type, inject_fname);
   1063 
   1064 	if (mode_write) {
   1065 		int offset_uboot_top = 0;
   1066 		int offset_uboot_start = 0;
   1067 
   1068 		for (wr_idx = 0; wr_idx < wr_num; wr_idx++) {
   1069 			ifile = &input_file[wr_idx];
   1070 			ret = write_data(image, size, ifile->addr,
   1071 					 ifile->fname, offset_uboot_top,
   1072 					 offset_uboot_start);
   1073 			if (ret < 0)
   1074 				break;
   1075 		}
   1076 	}
   1077 
   1078 	if (mode_spifreq)
   1079 		set_spi_frequency(image, size, spifreq);
   1080 
   1081 	if (mode_em100)
   1082 		set_em100_mode(image, size);
   1083 
   1084 	if (mode_locked)
   1085 		lock_descriptor(image, size);
   1086 
   1087 	if (mode_unlocked)
   1088 		unlock_descriptor(image, size);
   1089 
   1090 	if (write_it) {
   1091 		if (outfile) {
   1092 			ret = write_image(outfile, image, size);
   1093 		} else {
   1094 			if (lseek(bios_fd, 0, SEEK_SET)) {
   1095 				perror("Error while seeking");
   1096 				ret = -1;
   1097 			}
   1098 			if (write(bios_fd, image, size) != size) {
   1099 				perror("Error while writing");
   1100 				ret = -1;
   1101 			}
   1102 		}
   1103 	}
   1104 
   1105 	free(image);
   1106 	close(bios_fd);
   1107 
   1108 	return ret < 0 ? 1 : 0;
   1109 }
   1110