+// SPDX-License-Identifier: GPL-2.0
/*
* ifdtool - Manage Intel Firmware Descriptor information
*
* Copyright 2014 Google, Inc
*
- * SPDX-License-Identifier: GPL-2.0
- *
* From Coreboot project, but it got a serious code clean-up
* and a few new features
*/
#include <assert.h>
#include <fcntl.h>
#include <getopt.h>
+#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
-#include <libfdt.h>
+#include <linux/libfdt.h>
#include "ifdtool.h"
#undef DEBUG
#define FLREG_BASE(reg) ((reg & 0x00000fff) << 12);
#define FLREG_LIMIT(reg) (((reg & 0x0fff0000) >> 4) | 0xfff);
-enum input_file_type_t {
- IF_normal,
- IF_fdt,
- IF_uboot,
-};
-
struct input_file {
char *fname;
unsigned int addr;
- enum input_file_type_t type;
};
/**
if (ret)
return ret;
dump_region(i, frba);
- if (region.size == 0)
+ if (region.size <= 0)
continue;
region_fd = open(region_filename(i),
O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR |
* 0xffffffff so use an address relative to that. For an
* 8MB ROM the start address is 0xfff80000.
* @write_fname: Filename to add to the image
+ * @offset_uboot_top: Offset of the top of U-Boot
+ * @offset_uboot_start: Offset of the start of U-Boot
* @return number of bytes written if OK, -ve on error
*/
static int write_data(char *image, int size, unsigned int addr,
- const char *write_fname)
+ const char *write_fname, int offset_uboot_top,
+ int offset_uboot_start)
{
int write_fd, write_size;
int offset;
return write_fd;
offset = (uint32_t)(addr + size);
+ if (offset_uboot_top) {
+ if (offset_uboot_start < offset &&
+ offset_uboot_top >= offset) {
+ fprintf(stderr, "U-Boot image overlaps with region '%s'\n",
+ write_fname);
+ fprintf(stderr,
+ "U-Boot finishes at offset %x, file starts at %x\n",
+ offset_uboot_top, offset);
+ return -EXDEV;
+ }
+ if (offset_uboot_start > offset &&
+ offset_uboot_start <= offset + write_size) {
+ fprintf(stderr, "U-Boot image overlaps with region '%s'\n",
+ write_fname);
+ fprintf(stderr,
+ "U-Boot starts at offset %x, file finishes at %x\n",
+ offset_uboot_start, offset + write_size);
+ return -EXDEV;
+ }
+ }
debug("Writing %s to offset %#x\n", write_fname, offset);
if (offset < 0 || offset + write_size > size) {
return write_size;
}
-/**
- * write_uboot() - Write U-Boot, device tree and microcode pointer
- *
- * This writes U-Boot into a place in the flash, followed by its device tree.
- * The microcode pointer is written so that U-Boot can find the microcode in
- * the device tree very early in boot.
- *
- * @image: Pointer to image
- * @size: Size of image in bytes
- * @uboot: Input file information for u-boot.bin
- * @fdt: Input file information for u-boot.dtb
- * @ucode_ptr: Address in U-Boot where the microcode pointer should be placed
- * @return 0 if OK, -ve on error
- */
-static int write_uboot(char *image, int size, struct input_file *uboot,
- struct input_file *fdt, unsigned int ucode_ptr)
-{
- const void *blob;
- const char *data;
- int uboot_size;
- uint32_t *ptr;
- int data_size;
- int offset;
- int node;
- int ret;
-
- uboot_size = write_data(image, size, uboot->addr, uboot->fname);
- if (uboot_size < 0)
- return uboot_size;
- fdt->addr = uboot->addr + uboot_size;
- debug("U-Boot size %#x, FDT at %#x\n", uboot_size, fdt->addr);
- ret = write_data(image, size, fdt->addr, fdt->fname);
- if (ret < 0)
- return ret;
-
- if (ucode_ptr) {
- blob = (void *)image + (uint32_t)(fdt->addr + size);
- debug("DTB at %lx\n", (char *)blob - image);
- node = fdt_node_offset_by_compatible(blob, 0,
- "intel,microcode");
- if (node < 0) {
- debug("No microcode found in FDT: %s\n",
- fdt_strerror(node));
- return -ENOENT;
- }
- data = fdt_getprop(blob, node, "data", &data_size);
- if (!data) {
- debug("No microcode data found in FDT: %s\n",
- fdt_strerror(data_size));
- return -ENOENT;
- }
- offset = ucode_ptr - uboot->addr;
- ptr = (void *)image + offset;
- ptr[0] = uboot->addr + (data - image);
- ptr[1] = data_size;
- debug("Wrote microcode pointer at %x: addr=%x, size=%x\n",
- ucode_ptr, ptr[0], ptr[1]);
- }
-
- return 0;
-}
-
static void print_version(void)
{
printf("ifdtool v%s -- ", IFDTOOL_VERSION);
printf("Copyright (C) 2014 Google Inc.\n\n");
- printf("SPDX-License-Identifier: GPL-2.0+\n");
+ printf("SPDX-License-Identifier: GPL-2.0+\n");
}
static void print_usage(const char *name)
char *outfile = NULL;
struct stat buf;
int size = 0;
- unsigned int ucode_ptr = 0;
bool have_uboot = false;
int bios_fd;
char *image;
{"fdt", 1, NULL, 'f'},
{"inject", 1, NULL, 'i'},
{"lock", 0, NULL, 'l'},
- {"microcode", 1, NULL, 'm'},
{"romsize", 1, NULL, 'r'},
{"spifreq", 1, NULL, 's'},
{"unlock", 0, NULL, 'u'},
{0, 0, 0, 0}
};
- while ((opt = getopt_long(argc, argv, "cdD:ef:hi:lm:r:s:uU:vw:x?",
+ while ((opt = getopt_long(argc, argv, "cdD:ef:hi:lr:s:uU:vw:x?",
long_options, &option_index)) != EOF) {
switch (opt) {
case 'c':
case 'l':
mode_locked = 1;
break;
- case 'm':
- ucode_ptr = strtoul(optarg, NULL, 0);
- break;
case 'r':
rom_size = strtol(optarg, NULL, 0);
debug("ROM size %d\n", rom_size);
print_usage(argv[0]);
exit(EXIT_FAILURE);
}
- ifile->addr = strtol(optarg, NULL, 0);
- ifile->type = opt == 'f' ? IF_fdt :
- opt == 'U' ? IF_uboot : IF_normal;
- if (ifile->type == IF_fdt)
- fdt = ifile;
- else if (ifile->type == IF_uboot)
- have_uboot = true;
+ ifile->addr = strtoll(optarg, NULL, 0);
wr_num++;
} else {
fprintf(stderr,
}
if (mode_write_descriptor)
- ret = write_data(image, size, -size, desc_fname);
+ ret = write_data(image, size, -size, desc_fname, 0, 0);
if (mode_inject)
ret = inject_region(image, size, region_type, inject_fname);
if (mode_write) {
+ int offset_uboot_top = 0;
+ int offset_uboot_start = 0;
+
for (wr_idx = 0; wr_idx < wr_num; wr_idx++) {
ifile = &input_file[wr_idx];
- if (ifile->type == IF_fdt) {
- continue;
- } else if (ifile->type == IF_uboot) {
- ret = write_uboot(image, size, ifile, fdt,
- ucode_ptr);
- } else {
- ret = write_data(image, size, ifile->addr,
- ifile->fname);
- }
+ ret = write_data(image, size, ifile->addr,
+ ifile->fname, offset_uboot_top,
+ offset_uboot_start);
if (ret < 0)
break;
}