Nico Huber has uploaded this change for review.

View Change

[WIP]util/fsp-defaults: Add tool to extract FSP UPDs from binaries

Change-Id: Ia1174e2df7a6b0a634ea6f784abae65137ffc8f7
Signed-off-by: Nico Huber <nico.huber@secunet.com>
---
A util/fsp-defaults/.gitignore
A util/fsp-defaults/Makefile
A util/fsp-defaults/fspdef.awk
A util/fsp-defaults/fspdef.h
A util/fsp-defaults/main.c
5 files changed, 213 insertions(+), 0 deletions(-)

git pull ssh://review.coreboot.org:29418/coreboot refs/changes/74/37674/1
diff --git a/util/fsp-defaults/.gitignore b/util/fsp-defaults/.gitignore
new file mode 100644
index 0000000..1f5666f
--- /dev/null
+++ b/util/fsp-defaults/.gitignore
@@ -0,0 +1,5 @@
+.fsp_inc
+.udk_base
+fspdef
+fspm.c
+fsps.c
diff --git a/util/fsp-defaults/Makefile b/util/fsp-defaults/Makefile
new file mode 100644
index 0000000..8adc0a9
--- /dev/null
+++ b/util/fsp-defaults/Makefile
@@ -0,0 +1,30 @@
+ifeq ($(UDK_BASE),)
+$(warning Need to specify UDK_BASE=)
+endif
+$(shell if [ "$(UDK_BASE)" != "$$(cat .udk_base 2>/dev/null)" ]; then echo "$(UDK_BASE)" >.udk_base; fi)
+
+ifeq ($(FSP_INC),)
+$(warning Need to specify FSP_INC=)
+endif
+$(shell if [ "$(FSP_INC)" != "$$(cat .fsp_inc 2>/dev/null)" ]; then echo "$(FSP_INC)" >.fsp_inc; fi)
+
+_CPPFLAGS = \
+ -I../../src/commonlib/include/ \
+ -I$(UDK_BASE)/MdePkg/Include/Ia32/ \
+ -I$(UDK_BASE)/MdePkg/Include/ \
+ -I$(UDK_BASE)/IntelFsp2Pkg/Include/ \
+ -I$(FSP_INC)/ \
+
+fspdef: main.c fspm.c fsps.c .fsp_inc .udk_base
+ gcc -m32 $(_CPPFLAGS) -o $@ $< fspm.c fsps.c
+
+fspm.c: $(FSP_INC)/FspmUpd.h fspdef.awk .fsp_inc .udk_base
+ gcc $(_CPPFLAGS) -E $< | gawk -f fspdef.awk > $@
+
+fsps.c: $(FSP_INC)/FspsUpd.h fspdef.awk .fsp_inc .udk_base
+ gcc $(_CPPFLAGS) -E $< | gawk -f fspdef.awk > $@
+
+clean:
+ rm -f fspm.c fsps.c fspdef
+
+.PHONY: clean
diff --git a/util/fsp-defaults/fspdef.awk b/util/fsp-defaults/fspdef.awk
new file mode 100644
index 0000000..07a9756
--- /dev/null
+++ b/util/fsp-defaults/fspdef.awk
@@ -0,0 +1,97 @@
+function process(field, width) {
+ printf("\tif (config->%s)\n", field);
+ printf("\t\tprintf(\"\\t\\t/* 0x%%04x */ .%s = 0x%%\"PRIx%s\",\\n\", offset + offsetof(typeof(*config), %s), config->%s);\n",
+ field, width, field, field);
+}
+
+function process_array(field, width) {
+ printf("\tfor (i = 0; i < ARRAY_SIZE(config->%s); ++i) {\n", field);
+ printf("\t\tif (config->%s[i])\n", field);
+ printf("\t\t\tbreak;\n");
+ printf("\t}\n");
+ printf("\tif (i < ARRAY_SIZE(config->%s)) {\n", field);
+ printf("\t\tprintf(\"\\t\\t/* 0x%%04x */ .%s = {\", offset + offsetof(typeof(*config), %s));\n",
+ field, field);
+ printf("\t\tfor (i = 0; i < ARRAY_SIZE(config->%s); ++i) {\n", field);
+ printf("\t\t\tif (i % 8 == 0)\n");
+ printf("\t\t\t\tprintf(\"\\n\\t\\t\\t\");\n");
+ printf("\t\t\tprintf(\"0x%%\"PRIx%s\",\", config->%s[i]);\n", width, field);
+ printf("\t\t\tif ((i + 1) % 8 != 0 && i != ARRAY_SIZE(config->%s) - 1)\n", field);
+ printf("\t\t\t\tprintf(\" \");\n");
+ printf("\t\t}\n");
+ printf("\t\tprintf(\"\\n\\t\\t},\\n\");\n");
+ printf("\t}\n");
+}
+
+function process_struct(cname, tname) {
+ printf("void process_%s(const size_t offset, const %s *const config)\n{\n", cname, tname);
+ printf("\tunsigned int i;\n");
+ printf("\tprintf(\"\\tstatic const %s default_%s = {\\n\");\n\n", tname, cname);
+ for (field in fields) {
+ if (field in arrays)
+ process_array(fields[field], widths[field]);
+ else
+ process(fields[field], widths[field]);
+ printf("\n");
+ }
+ printf("\tprintf(\"\\t};\\n\\n\");\n");
+ printf("}\n\n");
+}
+
+BEGIN {
+ gather = 0;
+
+ printf("#include <stdio.h>\n");
+ printf("#include <stddef.h>\n");
+ printf("#include <inttypes.h>\n");
+ printf("#include <commonlib/helpers.h>\n");
+ printf("#include <FspmUpd.h>\n");
+ printf("#include <FspsUpd.h>\n\n");
+ printf("#include \"fspdef.h\"\n\n");
+}
+
+/typedef struct {/ {
+ gather = 1;
+ field = 0;
+}
+
+# match single identifiers
+match($0, /(UINT|CHAR)([0-9]+) ([0-9a-zA-Z]+);/, matches) {
+ if (gather) {
+ fields[field] = matches[3];
+ widths[field] = matches[2];
+ ++field;
+ }
+}
+
+# match array identifiers
+match($0, /(UINT|CHAR)([0-9]+) ([0-9a-zA-Z]+)\[([0-9]+)\];/, matches) {
+ if (gather) {
+ fields[field] = matches[3];
+ widths[field] = matches[2];
+ arrays[field] = "dummy";
+ ++field;
+ }
+}
+
+/} FSP_M_CONFIG;/ {
+ process_struct("fsp_m_config", "FSP_M_CONFIG");
+}
+
+/} FSP_M_TEST_CONFIG;/ {
+ process_struct("fsp_m_tconfig", "FSP_M_TEST_CONFIG");
+}
+
+/} FSP_S_CONFIG;/ {
+ process_struct("fsp_s_config", "FSP_S_CONFIG");
+}
+
+/} FSP_S_TEST_CONFIG;/ {
+ process_struct("fsp_s_tconfig", "FSP_S_TEST_CONFIG");
+}
+
+/} .*;/ {
+ gather = 0;
+ delete fields;
+ delete arrays;
+}
diff --git a/util/fsp-defaults/fspdef.h b/util/fsp-defaults/fspdef.h
new file mode 100644
index 0000000..72d99ad
--- /dev/null
+++ b/util/fsp-defaults/fspdef.h
@@ -0,0 +1,12 @@
+#ifndef UTIL_FSP_DEFAULTS_FSPDEF_H
+#define UTIL_FSP_DEFAULTS_FSPDEF_H
+
+#include <FspmUpd.h>
+#include <FspsUpd.h>
+
+void process_fsp_m_config(size_t offset, const FSP_M_CONFIG *);
+void process_fsp_m_tconfig(size_t offset, const FSP_M_TEST_CONFIG *);
+void process_fsp_s_config(size_t offset, const FSP_S_CONFIG *);
+void process_fsp_s_tconfig(size_t offset, const FSP_S_TEST_CONFIG *);
+
+#endif /* UTIL_FSP_DEFAULTS_FSPDEF_H */
diff --git a/util/fsp-defaults/main.c b/util/fsp-defaults/main.c
new file mode 100644
index 0000000..eb4d2a9
--- /dev/null
+++ b/util/fsp-defaults/main.c
@@ -0,0 +1,69 @@
+#include <stdio.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <FspUpd.h>
+#include <FspmUpd.h>
+#include <FspsUpd.h>
+
+#include "fspdef.h"
+
+int main(const int argc, const char *const argv[])
+{
+ if (argc != 2) {
+ fprintf(stderr, "Usage: %s <path-to-FSP.fd>\n", argv[0]);
+ return 1;
+ }
+
+ const int fd = open(argv[1], O_RDONLY);
+ if (fd == -1) {
+ perror("Failed to open FSP.fd");
+ return 2;
+ }
+
+ struct stat stat;
+ if (fstat(fd, &stat)) {
+ perror("Failed to stat FSP.fd");
+ return 3;
+ }
+
+ const void *const fsp = mmap(NULL, stat.st_size, PROT_READ, MAP_SHARED, fd, 0);
+ close(fd);
+ if (fsp == MAP_FAILED) {
+ perror("Failed to map FSP.fd");
+ return 3;
+ }
+
+ const uint8_t *it, *const end = (const uint8_t *)fsp + stat.st_size;
+ for (it = fsp; it < end; ++it) {
+ const uint64_t *const sig = (const uint64_t *)it;
+ const FSPM_UPD *fspm;
+ const FSPS_UPD *fsps;
+ switch (*sig) {
+ case FSPM_UPD_SIGNATURE:
+ fspm = (const FSPM_UPD *)sig;
+ process_fsp_m_config(
+ offsetof(FSPM_UPD, FspmConfig),
+ &fspm->FspmConfig);
+ process_fsp_m_tconfig(
+ offsetof(FSPM_UPD, FspmTestConfig),
+ &fspm->FspmTestConfig);
+ break;
+ case FSPS_UPD_SIGNATURE:
+ fsps = (const FSPS_UPD *)sig;
+ process_fsp_s_config(
+ offsetof(FSPS_UPD, FspsConfig),
+ &fsps->FspsConfig);
+ process_fsp_s_tconfig(
+ offsetof(FSPS_UPD, FspsTestConfig),
+ &fsps->FspsTestConfig);
+ break;
+ }
+ }
+
+ munmap((void *)fsp, stat.st_size);
+ return 0;
+}

To view, visit change 37674. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Change-Id: Ia1174e2df7a6b0a634ea6f784abae65137ffc8f7
Gerrit-Change-Number: 37674
Gerrit-PatchSet: 1
Gerrit-Owner: Nico Huber <nico.h@gmx.de>
Gerrit-MessageType: newchange