binman: Drop microcode features from ifdtool

Now that binman supports creating images with microcode, drop the code from
ifdtool.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Tested-by: Bin Meng <bmeng.cn@gmail.com>
master
Simon Glass 8 years ago
parent b215fbd868
commit 68af100224
  1. 254
      tools/ifdtool.c

@ -33,16 +33,9 @@
#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;
};
/**
@ -760,219 +753,6 @@ static int write_data(char *image, int size, unsigned int addr,
return write_size;
}
static int scan_ucode(const void *blob, char *ucode_base, int *countp,
const char **datap, int *data_sizep)
{
const char *data = NULL;
int node, count;
int data_size;
char *ucode;
for (node = 0, count = 0, ucode = ucode_base; node >= 0; count++) {
node = fdt_node_offset_by_compatible(blob, node,
"intel,microcode");
if (node < 0)
break;
data = fdt_getprop(blob, node, "data", &data_size);
if (!data) {
debug("Missing microcode data in FDT '%s': %s\n",
fdt_get_name(blob, node, NULL),
fdt_strerror(data_size));
return -ENOENT;
}
if (ucode_base)
memcpy(ucode, data, data_size);
ucode += data_size;
}
if (countp)
*countp = count;
if (datap)
*datap = data;
if (data_sizep)
*data_sizep = data_size;
return ucode - ucode_base;
}
static int remove_ucode(char *blob)
{
int node, count;
int ret;
/* Keep going until we find no more microcode to remove */
do {
for (node = 0, count = 0; node >= 0;) {
int ret;
node = fdt_node_offset_by_compatible(blob, node,
"intel,microcode");
if (node < 0)
break;
ret = fdt_delprop(blob, node, "data");
/*
* -FDT_ERR_NOTFOUND means we already removed the
* data for this one, so we just continue.
* 0 means we did remove it, so offsets may have
* changed and we need to restart our scan.
* Anything else indicates an error we should report.
*/
if (ret == -FDT_ERR_NOTFOUND)
continue;
else if (!ret)
node = 0;
else
return ret;
}
} while (count);
/* Pack down to remove excees space */
ret = fdt_pack(blob);
if (ret)
return ret;
return fdt_totalsize(blob);
}
static int write_ucode(char *image, int size, struct input_file *fdt,
int fdt_size, unsigned int ucode_ptr,
int collate_ucode)
{
const char *data = NULL;
char *ucode_buf;
const void *blob;
char *ucode_base;
uint32_t *ptr;
int ucode_size;
int data_size;
int offset;
int count;
int ret;
blob = (void *)image + (uint32_t)(fdt->addr + size);
debug("DTB at %lx\n", (char *)blob - image);
/* Find out about the micrcode we have */
ucode_size = scan_ucode(blob, NULL, &count, &data, &data_size);
if (ucode_size < 0)
return ucode_size;
if (!count) {
debug("No microcode found in FDT\n");
return -ENOENT;
}
if (count > 1 && !collate_ucode) {
fprintf(stderr,
"Cannot handle multiple microcode blocks - please use -C flag to collate them\n");
return -EMLINK;
}
/*
* Collect the microcode into a buffer, remove it from the device
* tree and place it immediately above the (now smaller) device tree.
*/
if (collate_ucode && count > 1) {
ucode_buf = malloc(ucode_size);
if (!ucode_buf) {
fprintf(stderr,
"Out of memory for microcode (%d bytes)\n",
ucode_size);
return -ENOMEM;
}
ret = scan_ucode(blob, ucode_buf, NULL, NULL, NULL);
if (ret < 0)
return ret;
/* Remove the microcode from the device tree */
ret = remove_ucode((char *)blob);
if (ret < 0) {
debug("Could not remove FDT microcode: %s\n",
fdt_strerror(ret));
return -EINVAL;
}
debug("Collated %d microcode block(s)\n", count);
debug("Device tree reduced from %x to %x bytes\n",
fdt_size, ret);
fdt_size = ret;
/*
* Place microcode area immediately above the FDT, aligned
* to a 16-byte boundary.
*/
ucode_base = (char *)(((unsigned long)blob + fdt_size + 15) &
~15);
data = ucode_base;
data_size = ucode_size;
memcpy(ucode_base, ucode_buf, ucode_size);
free(ucode_buf);
}
offset = (uint32_t)(ucode_ptr + size);
ptr = (void *)image + offset;
ptr[0] = (data - image) - size;
ptr[1] = data_size;
debug("Wrote microcode pointer at %x: addr=%x, size=%x\n", ucode_ptr,
ptr[0], ptr[1]);
return (collate_ucode ? data + data_size : (char *)blob + fdt_size) -
image;
}
/**
* 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,
int collate_ucode, int *offset_uboot_top,
int *offset_uboot_start)
{
int uboot_size, fdt_size;
int uboot_top;
uboot_size = write_data(image, size, uboot->addr, uboot->fname, 0, 0);
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);
fdt_size = write_data(image, size, fdt->addr, fdt->fname, 0, 0);
if (fdt_size < 0)
return fdt_size;
uboot_top = (uint32_t)(fdt->addr + size) + fdt_size;
if (ucode_ptr) {
uboot_top = write_ucode(image, size, fdt, fdt_size, ucode_ptr,
collate_ucode);
if (uboot_top < 0)
return uboot_top;
}
if (offset_uboot_top && offset_uboot_start) {
*offset_uboot_top = uboot_top;
*offset_uboot_start = (uint32_t)(uboot->addr + size);
}
return 0;
}
static void print_version(void)
{
printf("ifdtool v%s -- ", IFDTOOL_VERSION);
@ -1034,7 +814,7 @@ int main(int argc, char *argv[])
int mode_dump = 0, mode_extract = 0, mode_inject = 0;
int mode_spifreq = 0, mode_em100 = 0, mode_locked = 0;
int mode_unlocked = 0, mode_write = 0, mode_write_descriptor = 0;
int create = 0, collate_ucode = 0;
int create = 0;
char *region_type_string = NULL, *inject_fname = NULL;
char *desc_fname = NULL, *addr_str = NULL;
int region_type = -1, inputfreq = 0;
@ -1047,14 +827,12 @@ int main(int argc, char *argv[])
char *outfile = NULL;
struct stat buf;
int size = 0;
unsigned int ucode_ptr = 0;
bool have_uboot = false;
int bios_fd;
char *image;
int ret;
static struct option long_options[] = {
{"create", 0, NULL, 'c'},
{"collate-microcode", 0, NULL, 'C'},
{"dump", 0, NULL, 'd'},
{"descriptor", 1, NULL, 'D'},
{"em100", 0, NULL, 'e'},
@ -1062,7 +840,6 @@ int main(int argc, char *argv[])
{"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'},
@ -1073,15 +850,12 @@ int main(int argc, char *argv[])
{0, 0, 0, 0}
};
while ((opt = getopt_long(argc, argv, "cCdD: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':
create = 1;
break;
case 'C':
collate_ucode = 1;
break;
case 'd':
mode_dump = 1;
break;
@ -1119,9 +893,6 @@ int main(int argc, char *argv[])
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);
@ -1166,12 +937,6 @@ int main(int argc, char *argv[])
exit(EXIT_FAILURE);
}
ifile->addr = strtoll(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;
wr_num++;
} else {
fprintf(stderr,
@ -1302,18 +1067,9 @@ int main(int argc, char *argv[])
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, collate_ucode,
&offset_uboot_top,
&offset_uboot_start);
} else {
ret = write_data(image, size, ifile->addr,
ifile->fname, offset_uboot_top,
offset_uboot_start);
}
ret = write_data(image, size, ifile->addr,
ifile->fname, offset_uboot_top,
offset_uboot_start);
if (ret < 0)
break;
}

Loading…
Cancel
Save