[coreboot-gerrit] Patch set updated for coreboot: amdfwtool: Add amdfwtool to combine AMD firmwares

Zheng Bao (zheng.bao@amd.com) gerrit at coreboot.org
Tue Nov 17 15:59:40 CET 2015


Zheng Bao (zheng.bao at amd.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/12419

-gerrit

commit 25c4c65755ab18b9c798f60782077945acb0d9f9
Author: Zheng Bao <fishbaozi at gmail.com>
Date:   Tue Nov 17 22:57:39 2015 +0800

    amdfwtool: Add amdfwtool to combine AMD firmwares
    
    Combine all needed AMD firmware into one single firmware, which going to
    be added as one single CBFS module.
    
    Change-Id: Ib044098c1837592b8f7e9c6a7da4ba3a32117e25
    Signed-off-by: Zheng Bao <fishbaozi at gmail.com>
---
 Makefile.inc               |   8 +-
 util/amdfwtool/Makefile    |  36 +++
 util/amdfwtool/amdfwtool.c | 534 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 574 insertions(+), 4 deletions(-)

diff --git a/Makefile.inc b/Makefile.inc
index b85a2cb..f5326ba 100644
--- a/Makefile.inc
+++ b/Makefile.inc
@@ -290,7 +290,7 @@ CFLAGS_common += -Os
 endif
 
 additional-dirs := $(objutil)/cbfstool $(objutil)/romcc $(objutil)/ifdtool \
-		   $(objutil)/ifdfake $(objutil)/options $(objutil)/fletcher \
+		   $(objutil)/ifdfake $(objutil)/options $(objutil)/amdfwtool \
 		   $(objutil)/cbootimage $(objutil)/bimgtool
 
 #######################################################################
@@ -348,10 +348,10 @@ $(IFDFAKE): $(top)/util/ifdfake/ifdfake.c
 	@printf "    HOSTCC     $(subst $(obj)/,,$(@))\n"
 	$(HOSTCC) $(HOSTCFLAGS) -o $@ $<
 
-FLETCHER:=$(objutil)/fletcher/fletcher
-$(FLETCHER): $(top)/util/fletcher/fletcher.c
+AMDFWTOOL:=$(objutil)/amdfwtool/amdfwtool
+$(AMDFWTOOL): $(top)/util/amdfwtool/amdfwtool.c
 	@printf "    HOSTCC     $(subst $(obj)/,,$(@))\n"
-	$(HOSTCC) $(HOSTCFLAGS) -o $@ $<
+	$(HOSTCC) $(HOSTCFLAGS) -DCONFIG_ROM_SIZE=$(CONFIG_ROM_SIZE) -o $@ $<
 
 CBOOTIMAGE:=$(objutil)/cbootimage/cbootimage
 
diff --git a/util/amdfwtool/Makefile b/util/amdfwtool/Makefile
new file mode 100644
index 0000000..f252066
--- /dev/null
+++ b/util/amdfwtool/Makefile
@@ -0,0 +1,36 @@
+#*****************************************************************************
+#
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in the
+#       documentation and/or other materials provided with the distribution.
+#     * Neither the name of Advanced Micro Devices, Inc. nor the names of
+#       its contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+#*****************************************************************************
+HOSTCC ?= cc
+
+amdfwtool_exe : amdfwtool.c
+	$(HOSTCC) amdfwtool.c -o amdfwtool
+
+amdfwtool : amdfwtool_exe
+
+clean:
+	@rm -f amdfwtool.o amdfwtool amdfwtool.exe
diff --git a/util/amdfwtool/amdfwtool.c b/util/amdfwtool/amdfwtool.c
new file mode 100644
index 0000000..f090411
--- /dev/null
+++ b/util/amdfwtool/amdfwtool.c
@@ -0,0 +1,534 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015 Advanced Micro Devices, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+/*
+ *  ROMSIG At ROMBASE + 0x20000:
+ *  +------------+---------------+----------------+------------+
+ *  | 0x55AA55AA |EC ROM Address |GEC ROM Address |USB3 ROM    |
+ *  +------------+---------------+----------------+------------+
+ *  | PSPDIR ADDR|PSP2DIR ADDR   |
+ *  +------------+---------------+
+ *  EC ROM should be 64K aligned.
+ *
+ *  PSP directory
+ *  +------------+---------------+----------------+------------+
+ *  | 'PSP$'     | Fletcher      |    Count       | Reserved   |
+ *  +------------+---------------+----------------+------------+
+ *  |  0         | size          | Base address   | Reserved   | Pubkey
+ *  +------------+---------------+----------------+------------+
+ *  |  1         | size          | Base address   | Reserved   | Bootloader
+ *  +------------+---------------+----------------+------------+
+ *  |  8         | size          | Base address   | Reserved   | Smu Firmware
+ *  +------------+---------------+----------------+------------+
+ *  |  3         | size          | Base address   | Reserved   | Recovery Firmware
+ *  +------------+---------------+----------------+------------+
+ *  |                                                          |
+ *  |                                                          |
+ *  |             Other PSP Firmware                           |
+ *  |                                                          |
+ *  |                                                          |
+ *  +------------+---------------+----------------+------------+
+ */
+
+
+#include <fcntl.h>
+#include <errno.h>
+#include <stdio.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <getopt.h>
+
+#ifndef CONFIG_ROM_SIZE
+#define CONFIG_ROM_SIZE 0x400000
+#endif
+
+#define ROM_BASE_ADDRESS  (0xFFFFFFFF - CONFIG_ROM_SIZE + 1)
+#define AMD_ROMSIG_OFFSET 0x20000
+
+#define ALIGN(val, by) (((val) + (by)-1)&~((by)-1))
+
+/*
+  Reserved for future.
+  TODO: PSP2 is for Combo BIOS, which is the idea that one image supports 2
+  kinds of APU.
+*/
+#define PSP2 1
+
+typedef unsigned int uint32_t;
+typedef unsigned char uint8_t;
+typedef unsigned short uint16_t;
+
+/*
+ * Creates the OSI Fletcher checksum. See 8473-1, Appendix C, section C.3.
+ * The checksum field of the passed PDU does not need to be reset to zero.
+ *
+ * The "Fletcher Checksum" was proposed in a paper by John G. Fletcher of
+ * Lawrence Livermore Labs.  The Fletcher Checksum was proposed as an
+ * alternative to cyclical redundancy checks because it provides error-
+ * detection properties similar to cyclical redundancy checks but at the
+ * cost of a simple summation technique.  Its characteristics were first
+ * published in IEEE Transactions on Communications in January 1982.  One
+ * version has been adopted by ISO for use in the class-4 transport layer
+ * of the network protocol.
+ *
+ * This program expects:
+ *    stdin:    The input file to compute a checksum for.  The input file
+ *              not be longer than 256 bytes.
+ *    stdout:   Copied from the input file with the Fletcher's Checksum
+ *              inserted 8 bytes after the beginning of the file.
+ *    stderr:   Used to print out error messages.
+ */
+uint32_t fletcher32 (const uint16_t *pptr, int length)
+{
+	uint32_t c0;
+	uint32_t c1;
+	uint32_t checksum;
+	int index;
+
+	c0 = 0xFFFF;
+	c1 = 0xFFFF;
+
+	for (index = 0; index < length; index++) {
+		/*
+		* Ignore the contents of the checksum field.
+		*/
+		c0 += *(pptr++);
+		c1 += c0;
+		if ((index % 360) == 0) {
+			c0 = (c0 & 0xFFFF) + (c0 >> 16);	// Sum0 modulo 65535 + the overflow
+			c1 = (c1 & 0xFFFF) + (c1 >> 16);	// Sum1 modulo 65535 + the overflow
+		}
+	}
+
+	c0 = (c0 & 0xFFFF) + (c0 >> 16);	// Sum0 modulo 65535 + the overflow
+	c1 = (c1 & 0xFFFF) + (c1 >> 16);	// Sum1 modulo 65535 + the overflow
+	checksum = (c1 << 16) | c0;
+
+	return checksum;
+}
+
+void usage()
+{
+	printf("Create AMD Firmware combination\n");
+}
+
+typedef enum _amd_fw_type {
+	AMD_FW_PSP_PUBKEY = 0,
+	AMD_FW_PSP_BOOTLOADER = 1,
+	AMD_FW_PSP_SMU_FIRMWARE = 8,
+	AMD_FW_PSP_RECOVERY = 3,
+	AMD_FW_PSP_RTM_PUBKEY = 5,
+	AMD_FW_PSP_SECURED_OS = 2,
+	AMD_FW_PSP_NVRAM = 4,
+	AMD_FW_PSP_SECURED_DEBUG = 9,
+	AMD_FW_PSP_TRUSTLETS = 12,
+	AMD_FW_PSP_TRUSTLETKEY = 13,
+	AMD_FW_PSP_SMU_FIRMWARE2 = 18,
+	AMD_PSP_FUSE_CHAIN = 11,
+	AMD_FW_PSP_SMUSCS = 95,
+
+	AMD_FW_IMC,
+	AMD_FW_GEC,
+	AMD_FW_XHCI,
+} amd_fw_type;
+
+typedef struct _amd_fw_entry {
+	amd_fw_type type;
+	char *filename;
+} amd_fw_entry;
+
+amd_fw_entry amd_psp_fw_table[] = {
+	{ .type = AMD_FW_PSP_PUBKEY },
+	{ .type = AMD_FW_PSP_BOOTLOADER },
+	{ .type = AMD_FW_PSP_SMU_FIRMWARE },
+	{ .type = AMD_FW_PSP_RECOVERY },
+	{ .type = AMD_FW_PSP_RTM_PUBKEY },
+	{ .type = AMD_FW_PSP_SECURED_OS },
+	{ .type = AMD_FW_PSP_NVRAM },
+	{ .type = AMD_FW_PSP_SECURED_DEBUG },
+	{ .type = AMD_FW_PSP_TRUSTLETS },
+	{ .type = AMD_FW_PSP_TRUSTLETKEY },
+	{ .type = AMD_FW_PSP_SMU_FIRMWARE2 },
+	{ .type = AMD_FW_PSP_SMUSCS },
+	{ .type = AMD_PSP_FUSE_CHAIN },
+};
+
+#if PSP2
+amd_fw_entry amd_psp2_fw_table[] = {
+	{ .type = AMD_FW_PSP_PUBKEY },
+	{ .type = AMD_FW_PSP_BOOTLOADER },
+	{ .type = AMD_FW_PSP_SMU_FIRMWARE },
+	{ .type = AMD_FW_PSP_RECOVERY },
+	{ .type = AMD_FW_PSP_RTM_PUBKEY },
+	{ .type = AMD_FW_PSP_SECURED_OS },
+	{ .type = AMD_FW_PSP_NVRAM },
+	{ .type = AMD_FW_PSP_SECURED_DEBUG },
+	{ .type = AMD_FW_PSP_TRUSTLETS },
+	{ .type = AMD_FW_PSP_TRUSTLETKEY },
+	{ .type = AMD_FW_PSP_SMU_FIRMWARE2 },
+	{ .type = AMD_FW_PSP_SMUSCS },
+	{ .type = AMD_PSP_FUSE_CHAIN },
+};
+#endif
+
+amd_fw_entry amd_fw_table[] = {
+	{ .type = AMD_FW_XHCI },
+	{ .type = AMD_FW_IMC },
+	{ .type = AMD_FW_GEC },
+};
+
+void fill_psp_head(uint32_t *pspdir, int count)
+{
+	pspdir[0] = 1347637284;	/* 'PSP$' */
+	pspdir[2] = count;		/* size */
+	pspdir[3] = 0;
+	pspdir[1] = fletcher32((uint16_t *)&pspdir[1], (count *16 + 16)/2 - 2);
+}
+
+uint32_t integerate_one_fw(void *base, uint32_t pos, uint32_t *romsig, int i)
+{
+	int fd;
+	struct stat fd_stat;
+
+	if (amd_fw_table[i].filename != NULL) {
+		fd = open (amd_fw_table[i].filename, O_RDONLY);
+		fstat(fd, &fd_stat);
+
+		switch (amd_fw_table[i].type) {
+		case AMD_FW_IMC:
+			pos = ALIGN(pos, 0x10000);
+			romsig[1] = pos + ROM_BASE_ADDRESS;
+			break;
+		case AMD_FW_GEC:
+			romsig[2] = pos + ROM_BASE_ADDRESS;
+			break;
+		case AMD_FW_XHCI:
+			romsig[3] = pos + ROM_BASE_ADDRESS;
+			break;
+		default:
+			/* Error */
+			break;
+		}
+
+		read (fd, base+pos, fd_stat.st_size);
+
+		pos += fd_stat.st_size;
+		pos = ALIGN(pos, 0x100);
+		close (fd);
+	}
+
+	return pos;
+}
+
+uint32_t integerate_one_psp(void *base, uint32_t pos, uint32_t *pspdir, int i)
+{
+	int fd;
+	struct stat fd_stat;
+
+	if (amd_psp_fw_table[i].type == AMD_PSP_FUSE_CHAIN) {
+		pspdir[4+4*i+0] = amd_psp_fw_table[i].type;
+		pspdir[4+4*i+1] = 0xFFFFFFFF;
+		pspdir[4+4*i+2] = 1;
+		pspdir[4+4*i+3] = 0;
+	} else if (amd_psp_fw_table[i].filename != NULL) {
+		pspdir[4+4*i+0] = amd_psp_fw_table[i].type;
+
+		fd = open (amd_psp_fw_table[i].filename, O_RDONLY);
+		fstat(fd, &fd_stat);
+		pspdir[4+4*i+1] = fd_stat.st_size;
+
+		pspdir[4+4*i+2] = pos + ROM_BASE_ADDRESS;
+		pspdir[4+4*i+3] = 0;
+
+		read (fd, base+pos, fd_stat.st_size);
+
+		pos += fd_stat.st_size;
+		pos = ALIGN(pos, 0x100);
+		close (fd);
+	} else {
+		/* This APU doesn't have this firmware. */
+	}
+
+	return pos;
+}
+
+static const char *optstring  = "x:i:g:p:b:s:r:k:o:n:d:t:u:w:m:h";
+static struct option long_options[] = {
+	{"xhci",         required_argument, 0, 'x' },
+	{"imc",          required_argument, 0, 'i' },
+	{"gec",          required_argument, 0, 'g' },
+	/* PSP */
+	{"pubkey",       required_argument, 0, 'p' },
+	{"bootloader",   required_argument, 0, 'b' },
+	{"smufirmware",  required_argument, 0, 's' },
+	{"recovery",     required_argument, 0, 'r' },
+	{"rtmpubkey",    required_argument, 0, 'k' },
+	{"secureos",     required_argument, 0, 'c' },
+	{"nvram",        required_argument, 0, 'n' },
+	{"securedebug",  required_argument, 0, 'd' },
+	{"trustlets",    required_argument, 0, 't' },
+	{"trustletkey",  required_argument, 0, 'u' },
+	{"smufirmware2", required_argument, 0, 'w' },
+	{"smuscs",       required_argument, 0, 'm' },
+
+	/* TODO: PSP2 */
+#if PSP2
+	{"pubkey2",       required_argument, 0, 'P' },
+	{"bootloader2",   required_argument, 0, 'B' },
+	{"smufirmware2",  required_argument, 0, 'S' },
+	{"recovery2",     required_argument, 0, 'R' },
+	{"rtmpubkey2",    required_argument, 0, 'K' },
+	{"secureos2",     required_argument, 0, 'C' },
+	{"nvram2",        required_argument, 0, 'N' },
+	{"securedebug2",  required_argument, 0, 'D' },
+	{"trustlets2",    required_argument, 0, 'T' },
+	{"trustletkey2",  required_argument, 0, 'U' },
+	{"smufirmware2_2",required_argument, 0, 'W' },
+	{"smuscs2",       required_argument, 0, 'M' },
+#endif
+
+	{"output",       required_argument, 0, 'o' },
+	{"help",         no_argument,       0, 'h' },
+
+	{NULL,           0,                 0,  0  }
+};
+
+void register_fw_filename(amd_fw_type type, char filename[], int pspflag)
+{
+	int i;
+
+	for (i = 0; i < sizeof(amd_fw_table)/sizeof(amd_fw_entry); i++) {
+		if (amd_fw_table[i].type == type) {
+			amd_fw_table[i].filename = filename;
+			return;
+		}
+	}
+
+	if (pspflag == 1) {
+		for (i = 0; i < sizeof(amd_psp_fw_table)/sizeof(amd_fw_entry); i++) {
+			if (amd_psp_fw_table[i].type == type) {
+				amd_psp_fw_table[i].filename = filename;
+				return;
+			}
+		}
+	}
+
+#if PSP2
+	if (pspflag == 2) {
+		for (i = 0; i < sizeof(amd_psp2_fw_table)/sizeof(amd_fw_entry); i++) {
+			if (amd_psp2_fw_table[i].type == type) {
+				amd_psp2_fw_table[i].filename = filename;
+				return;
+			}
+		}
+	}
+#endif
+}
+
+int main(int argc, char **argv)
+{
+	int c, count, pspflag = 0;
+#if PSP2
+	int psp2flag = 0;
+#endif
+	void *rom = NULL;
+	uint32_t current;
+	uint32_t *amd_romsig, *pspdir;
+
+	int targetfd;
+	char *output;
+
+	rom = malloc(CONFIG_ROM_SIZE);
+	memset (rom, 0xFF, CONFIG_ROM_SIZE);
+	if (!rom) {
+		return 1;
+	}
+
+	current = AMD_ROMSIG_OFFSET;
+	amd_romsig = rom + AMD_ROMSIG_OFFSET;
+	amd_romsig[0] = 0x55AA55AA; /* romsig */
+
+	current += 0x20;	    /* size of ROMSIG */
+
+	while (1) {
+		int optindex = 0;
+
+		c = getopt_long(argc, argv, optstring, long_options, &optindex);
+
+		if (c == -1)
+			break;
+
+		switch (c) {
+		case 'x':
+			register_fw_filename(AMD_FW_XHCI, optarg, 0);
+			break;
+		case 'i':
+			register_fw_filename(AMD_FW_IMC, optarg, 0);
+			break;
+		case 'g':
+			register_fw_filename(AMD_FW_GEC, optarg, 0);
+			break;
+		case 'p':
+			register_fw_filename(AMD_FW_PSP_PUBKEY, optarg, 1);
+			pspflag = 1;
+			break;
+		case 'b':
+			register_fw_filename(AMD_FW_PSP_BOOTLOADER, optarg, 1);
+			pspflag = 1;
+			break;
+		case 's':
+			register_fw_filename(AMD_FW_PSP_SMU_FIRMWARE, optarg, 1);
+			pspflag = 1;
+			break;
+		case 'r':
+			register_fw_filename(AMD_FW_PSP_RECOVERY, optarg, 1);
+			pspflag = 1;
+			break;
+		case 'k':
+			register_fw_filename(AMD_FW_PSP_RTM_PUBKEY, optarg, 1);
+			pspflag = 1;
+			break;
+		case 'c':
+			register_fw_filename(AMD_FW_PSP_SECURED_OS, optarg, 1);
+			pspflag = 1;
+			break;
+		case 'n':
+			register_fw_filename(AMD_FW_PSP_NVRAM, optarg, 1);
+			pspflag = 1;
+			break;
+		case 'd':
+			register_fw_filename(AMD_FW_PSP_SECURED_DEBUG, optarg, 1);
+			pspflag = 1;
+			break;
+		case 't':
+			register_fw_filename(AMD_FW_PSP_TRUSTLETS, optarg, 1);
+			pspflag = 1;
+			break;
+		case 'u':
+			register_fw_filename(AMD_FW_PSP_TRUSTLETKEY, optarg, 1);
+			pspflag = 1;
+			break;
+		case 'w':
+			register_fw_filename(AMD_FW_PSP_SMU_FIRMWARE2, optarg, 1);
+			pspflag = 1;
+			break;
+		case 'm':
+			register_fw_filename(AMD_FW_PSP_SMUSCS, optarg, 1);
+			pspflag = 1;
+			break;
+#if PSP2
+		case 'P':
+			register_fw_filename(AMD_FW_PSP_PUBKEY, optarg, 2);
+			psp2flag = 1;
+			break;
+		case 'B':
+			register_fw_filename(AMD_FW_PSP_BOOTLOADER, optarg, 2);
+			psp2flag = 1;
+			break;
+		case 'S':
+			register_fw_filename(AMD_FW_PSP_SMU_FIRMWARE, optarg, 2);
+			psp2flag = 1;
+			break;
+		case 'R':
+			register_fw_filename(AMD_FW_PSP_RECOVERY, optarg, 2);
+			psp2flag = 1;
+			break;
+		case 'K':
+			register_fw_filename(AMD_FW_PSP_RTM_PUBKEY, optarg, 2);
+			psp2flag = 1;
+			break;
+		case 'C':
+			register_fw_filename(AMD_FW_PSP_SECURED_OS, optarg, 2);
+			psp2flag = 1;
+			break;
+		case 'N':
+			register_fw_filename(AMD_FW_PSP_NVRAM, optarg, 2);
+			psp2flag = 1;
+			break;
+		case 'D':
+			register_fw_filename(AMD_FW_PSP_SECURED_DEBUG, optarg, 2);
+			psp2flag = 1;
+			break;
+		case 'T':
+			register_fw_filename(AMD_FW_PSP_TRUSTLETS, optarg, 2);
+			psp2flag = 1;
+			break;
+		case 'U':
+			register_fw_filename(AMD_FW_PSP_TRUSTLETKEY, optarg, 2);
+			psp2flag = 1;
+			break;
+		case 'W':
+			register_fw_filename(AMD_FW_PSP_SMU_FIRMWARE2, optarg, 2);
+			psp2flag = 1;
+			break;
+		case 'M':
+			register_fw_filename(AMD_FW_PSP_SMUSCS, optarg, 2);
+			psp2flag = 1;
+			break;
+#endif
+		case 'o':
+			output = optarg;
+			break;
+		case 'h':
+			usage();
+			return 1;
+		default:
+			break;
+		}
+	}
+
+	current = ALIGN(current, 0x100);
+	for (count = 0; count < sizeof(amd_fw_table) / sizeof(amd_fw_entry); count ++) {
+		current = integerate_one_fw(rom, current, amd_romsig, count);
+	}
+
+	if (pspflag == 1) {
+		current = ALIGN(current, 0x10000);
+		pspdir = rom + current;
+		amd_romsig[4] = current + ROM_BASE_ADDRESS;
+
+		current += 0x200;	/* Conservative size of pspdir */
+		for (count = 0; count < sizeof(amd_psp_fw_table) / sizeof(amd_fw_entry); count ++) {
+			current = integerate_one_psp(rom, current, pspdir, count);
+		}
+
+		fill_psp_head(pspdir, count);
+
+#if PSP2
+		if (psp2flag == 1) {
+			current = ALIGN(current, 0x10000);
+			pspdir = rom + current;
+			amd_romsig[5] = current + ROM_BASE_ADDRESS;
+			current += 0x200;	/* Conservative size of pspdir */
+
+			for (count = 0; count < sizeof(amd_psp2_fw_table) / sizeof(amd_fw_entry); count ++) {
+				current = integerate_one_psp(rom, current, pspdir, count);
+			}
+
+			fill_psp_head(pspdir, count);
+		}
+#endif
+	}
+
+	targetfd = open(output, O_RDWR | O_CREAT | O_TRUNC, 0666);
+	write(targetfd, amd_romsig, current - AMD_ROMSIG_OFFSET);
+	close(targetfd);
+	free(rom);
+
+	return 0;
+}



More information about the coreboot-gerrit mailing list