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>
This commit is contained in:
parent
b215fbd868
commit
68af100224
254
tools/ifdtool.c
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…
Reference in New Issue