Bug Summary

File:util/amdfwtool/amdfwtool.c
Warning:line 1614, column 3
Potential leak of memory pointed to by 'ctx.amd_psp_fw_table_clean'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name amdfwtool.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -pic-is-pie -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/home/coreboot/node-root/workspace/coreboot_scanbuild -resource-dir /opt/xgcc/lib/clang/17 -I /home/coreboot/node-root/workspace/coreboot_scanbuild/src/commonlib/bsd/include -D _GNU_SOURCE -internal-isystem /opt/xgcc/lib/clang/17/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/13/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -source-date-epoch 1715206807 -O2 -fdebug-compilation-dir=/home/coreboot/node-root/workspace/coreboot_scanbuild -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-opt-analyze-headers -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /cb-build/coreboot_scanbuild.0/sharedutils-scanbuildtmp/2024-05-09-073003-3820391-1 -x c /home/coreboot/node-root/workspace/coreboot_scanbuild/util/amdfwtool/amdfwtool.c
1/* SPDX-License-Identifier: GPL-2.0-only */
2
3/*
4 * ROMSIG At ROMBASE + 0x[0,2,4,8]20000:
5 * 0 4 8 C
6 * +------------+---------------+----------------+------------+
7 * | 0x55AA55AA |EC ROM Address |GEC ROM Address |USB3 ROM |
8 * +------------+---------------+----------------+------------+
9 * | PSPDIR ADDR|PSPDIR ADDR(C) | BDT ADDR 0 | BDT ADDR 1 |
10 * +------------+---------------+----------------+------------+
11 * | BDT ADDR 2 | | BDT ADDR 3(C) | |
12 * +------------+---------------+----------------+------------+
13 * (C): Could be a combo header
14 *
15 * EC ROM should be 64K aligned.
16 *
17 * PSP directory (Where "PSPDIR ADDR" points)
18 * +------------+---------------+----------------+------------+
19 * | 'PSP$' | Fletcher | Count | Reserved |
20 * +------------+---------------+----------------+------------+
21 * | 0 | size | Base address | Reserved | Pubkey
22 * +------------+---------------+----------------+------------+
23 * | 1 | size | Base address | Reserved | Bootloader
24 * +------------+---------------+----------------+------------+
25 * | 8 | size | Base address | Reserved | Smu Firmware
26 * +------------+---------------+----------------+------------+
27 * | 3 | size | Base address | Reserved | Recovery Firmware
28 * +------------+---------------+----------------+------------+
29 * | |
30 * | |
31 * | Other PSP Firmware |
32 * | |
33 * +------------+---------------+----------------+------------+
34 * | 40 | size | Base address | Reserved |---+
35 * +------------+---------------+----------------+------------+ |
36 * :or 48(A/B A): size : Base address : Reserved : |
37 * + - - + - - + - - + - - + |
38 * : 4A(A/B B): size : Base address : Reserved : |
39 * +------------+---------------+----------------+------------+ |
40 * (A/B A) & (A/B B): Similar as 40, pointing to PSP level 2 |
41 * for A/B recovery |
42 * |
43 * |
44 * +------------+---------------+----------------+------------+ |
45 * | '2LP$' | Fletcher | Count | Reserved |<--+
46 * +------------+---------------+----------------+------------+
47 * | |
48 * | |
49 * | PSP Firmware |
50 * | (2nd-level is not required on all families) |
51 * | |
52 * +------------+---------------+----------------+------------+
53 * BIOS Directory Table (BDT) is similar
54 *
55 * PSP Combo directory
56 * +------------+---------------+----------------+------------+
57 * | 'PSP2' | Fletcher | Count |Look up mode|
58 * +------------+---------------+----------------+------------+
59 * | R e s e r v e d |
60 * +------------+---------------+----------------+------------+
61 * | ID-Sel | PSP ID | PSPDIR ADDR | | 1st PSP directory
62 * +------------+---------------+----------------+------------+
63 * | ID-Sel | PSP ID | PSPDIR ADDR | | 2nd PSP directory
64 * +------------+---------------+----------------+------------+
65 * | |
66 * | Other PSP |
67 * | |
68 * +------------+---------------+----------------+------------+
69 * BDT Combo is similar
70 */
71
72#include <commonlib/bsd/helpers.h>
73#include <fcntl.h>
74#include <errno(*__errno_location ()).h>
75#include <limits.h>
76#include <stdbool.h>
77#include <stdio.h>
78#include <sys/stat.h>
79#include <sys/types.h>
80#include <unistd.h>
81#include <string.h>
82#include <stdlib.h>
83#include <libgen.h>
84#include <stdint.h>
85
86#include "amdfwtool.h"
87
88#define AMD_ROMSIG_OFFSET0x20000 0x20000
89
90#define _MAX(A, B)(((A) > (B)) ? (A) : (B)) (((A) > (B)) ? (A) : (B))
91
92static void output_manifest(int manifest_fd, amd_fw_entry *fw_entry);
93
94/*
95 * Beginning with Family 15h Models 70h-7F, a.k.a Stoney Ridge, the PSP
96 * can support an optional "combo" implementation. If the PSP sees the
97 * PSP2 cookie, it interprets the table as a roadmap to additional PSP
98 * tables. Using this, support for multiple product generations may be
99 * built into one image. If the PSP$ cookie is found, the table is a
100 * normal directory table.
101 *
102 * Modern generations supporting the combo directories require the
103 * pointer to be at offset 0x14 of the Embedded Firmware Structure,
104 * regardless of the type of directory used. The --use-combo
105 * argument enforces this placement.
106 *
107 * TODO: Future work may require fully implementing the PSP_COMBO feature.
108 */
109
110/*
111 * Creates the OSI Fletcher checksum. See 8473-1, Appendix C, section C.3.
112 * The checksum field of the passed PDU does not need to be reset to zero.
113 *
114 * The "Fletcher Checksum" was proposed in a paper by John G. Fletcher of
115 * Lawrence Livermore Labs. The Fletcher Checksum was proposed as an
116 * alternative to cyclical redundancy checks because it provides error-
117 * detection properties similar to cyclical redundancy checks but at the
118 * cost of a simple summation technique. Its characteristics were first
119 * published in IEEE Transactions on Communications in January 1982. One
120 * version has been adopted by ISO for use in the class-4 transport layer
121 * of the network protocol.
122 *
123 * This program expects:
124 * stdin: The input file to compute a checksum for. The input file
125 * not be longer than 256 bytes.
126 * stdout: Copied from the input file with the Fletcher's Checksum
127 * inserted 8 bytes after the beginning of the file.
128 * stderr: Used to print out error messages.
129 */
130static uint32_t fletcher32(const void *data, int length)
131{
132 uint32_t c0;
133 uint32_t c1;
134 uint32_t checksum;
135 int index;
136 const uint16_t *pptr = data;
137
138 length /= 2;
139
140 c0 = 0xFFFF;
141 c1 = 0xFFFF;
142
143 while (length) {
144 index = length >= 359 ? 359 : length;
145 length -= index;
146 do {
147 c0 += *(pptr++);
148 c1 += c0;
149 } while (--index);
150 c0 = (c0 & 0xFFFF) + (c0 >> 16);
151 c1 = (c1 & 0xFFFF) + (c1 >> 16);
152 }
153
154 /* Sums[0,1] mod 64K + overflow */
155 c0 = (c0 & 0xFFFF) + (c0 >> 16);
156 c1 = (c1 & 0xFFFF) + (c1 >> 16);
157 checksum = (c1 << 16) | c0;
158
159 return checksum;
160}
161
162amd_fw_entry amd_psp_fw_table[] = {
163 { .type = AMD_FW_PSP_PUBKEY, .level = PSP_BOTH((1 << 0) | (1 << 1)) | PSP_LVL2_AB(1 << 3), .skip_hashing = true1 },
164 { .type = AMD_FW_PSP_BOOTLOADER, .level = PSP_BOTH((1 << 0) | (1 << 1)) | PSP_LVL2_AB(1 << 3),
165 .generate_manifest = true1 },
166 { .type = AMD_FW_PSP_SECURED_OS, .level = PSP_LVL2(1 << 1) | PSP_LVL2_AB(1 << 3) },
167 { .type = AMD_FW_PSP_RECOVERY, .level = PSP_LVL1(1 << 0) },
168 { .type = AMD_FW_PSP_NVRAM, .level = PSP_LVL2(1 << 1) | PSP_LVL2_AB(1 << 3) },
169 { .type = AMD_FW_PSP_RTM_PUBKEY, .level = PSP_BOTH((1 << 0) | (1 << 1)) },
170 { .type = AMD_FW_PSP_SMU_FIRMWARE, .subprog = 0, .level = PSP_BOTH((1 << 0) | (1 << 1)) | PSP_LVL2_AB(1 << 3),
171 .generate_manifest = true1 },
172 { .type = AMD_FW_PSP_SMU_FIRMWARE, .subprog = 1, .level = PSP_BOTH((1 << 0) | (1 << 1)) | PSP_LVL2_AB(1 << 3) },
173 { .type = AMD_FW_PSP_SMU_FIRMWARE, .subprog = 2, .level = PSP_BOTH((1 << 0) | (1 << 1)) | PSP_LVL2_AB(1 << 3) },
174 { .type = AMD_FW_PSP_SECURED_DEBUG, .level = PSP_LVL2(1 << 1) | PSP_LVL2_AB(1 << 3),
175 .skip_hashing = true1 },
176 { .type = AMD_FW_ABL_PUBKEY, .level = PSP_BOTH((1 << 0) | (1 << 1)) | PSP_BOTH_AB((1 << 2) | (1 << 3)) },
177 { .type = AMD_PSP_FUSE_CHAIN, .level = PSP_LVL2(1 << 1) | PSP_LVL2_AB(1 << 3) },
178 { .type = AMD_FW_PSP_TRUSTLETS, .level = PSP_LVL2(1 << 1) | PSP_LVL2_AB(1 << 3) },
179 { .type = AMD_FW_PSP_TRUSTLETKEY, .level = PSP_LVL2(1 << 1) | PSP_LVL2_AB(1 << 3) },
180 { .type = AMD_FW_PSP_SMU_FIRMWARE2, .level = PSP_BOTH((1 << 0) | (1 << 1)) | PSP_LVL2_AB(1 << 3) },
181 { .type = AMD_FW_PSP_SMU_FIRMWARE2, .subprog = 1, .level = PSP_BOTH((1 << 0) | (1 << 1)) | PSP_LVL2_AB(1 << 3) },
182 { .type = AMD_FW_PSP_SMU_FIRMWARE2, .subprog = 2, .level = PSP_BOTH((1 << 0) | (1 << 1)) | PSP_LVL2_AB(1 << 3) },
183 { .type = AMD_BOOT_DRIVER, .level = PSP_BOTH((1 << 0) | (1 << 1)) | PSP_LVL2_AB(1 << 3) },
184 { .type = AMD_SOC_DRIVER, .level = PSP_BOTH((1 << 0) | (1 << 1)) | PSP_LVL2_AB(1 << 3) },
185 { .type = AMD_DEBUG_DRIVER, .level = PSP_BOTH((1 << 0) | (1 << 1)) | PSP_LVL2_AB(1 << 3) },
186 { .type = AMD_INTERFACE_DRIVER, .level = PSP_BOTH((1 << 0) | (1 << 1)) | PSP_LVL2_AB(1 << 3) },
187 { .type = AMD_DEBUG_UNLOCK, .level = PSP_LVL2(1 << 1) | PSP_LVL2_AB(1 << 3) },
188 { .type = AMD_HW_IPCFG, .subprog = 0, .level = PSP_LVL2(1 << 1) | PSP_LVL2_AB(1 << 3) },
189 { .type = AMD_HW_IPCFG, .subprog = 1, .level = PSP_LVL2(1 << 1) | PSP_LVL2_AB(1 << 3) },
190 { .type = AMD_WRAPPED_IKEK, .level = PSP_BOTH((1 << 0) | (1 << 1)) | PSP_LVL2_AB(1 << 3), .skip_hashing = true1 },
191 { .type = AMD_TOKEN_UNLOCK, .level = PSP_BOTH((1 << 0) | (1 << 1)) | PSP_LVL2_AB(1 << 3) },
192 { .type = AMD_SEC_GASKET, .subprog = 0, .level = PSP_BOTH((1 << 0) | (1 << 1)) | PSP_LVL2_AB(1 << 3) },
193 { .type = AMD_SEC_GASKET, .subprog = 1, .level = PSP_BOTH((1 << 0) | (1 << 1)) | PSP_LVL2_AB(1 << 3) },
194 { .type = AMD_SEC_GASKET, .subprog = 2, .level = PSP_BOTH((1 << 0) | (1 << 1)) | PSP_LVL2_AB(1 << 3) },
195 { .type = AMD_MP2_FW, .subprog = 0, .level = PSP_LVL2(1 << 1) | PSP_LVL2_AB(1 << 3) },
196 { .type = AMD_MP2_FW, .subprog = 1, .level = PSP_LVL2(1 << 1) | PSP_LVL2_AB(1 << 3) },
197 { .type = AMD_MP2_FW, .subprog = 2, .level = PSP_LVL2(1 << 1) | PSP_LVL2_AB(1 << 3) },
198 { .type = AMD_DRIVER_ENTRIES, .level = PSP_LVL2(1 << 1) | PSP_LVL2_AB(1 << 3) },
199 { .type = AMD_FW_KVM_IMAGE, .level = PSP_LVL2(1 << 1) | PSP_LVL2_AB(1 << 3) },
200 { .type = AMD_FW_MP5, .subprog = 0, .level = PSP_BOTH((1 << 0) | (1 << 1)) | PSP_BOTH_AB((1 << 2) | (1 << 3)) },
201 { .type = AMD_FW_MP5, .subprog = 1, .level = PSP_BOTH((1 << 0) | (1 << 1)) | PSP_BOTH_AB((1 << 2) | (1 << 3)) },
202 { .type = AMD_FW_MP5, .subprog = 2, .level = PSP_BOTH((1 << 0) | (1 << 1)) | PSP_BOTH_AB((1 << 2) | (1 << 3)) },
203 { .type = AMD_S0I3_DRIVER, .level = PSP_LVL2(1 << 1) | PSP_LVL2_AB(1 << 3) },
204 { .type = AMD_ABL0, .level = PSP_BOTH((1 << 0) | (1 << 1)) | PSP_LVL2_AB(1 << 3),
205 .generate_manifest = true1 },
206 { .type = AMD_ABL1, .level = PSP_BOTH((1 << 0) | (1 << 1)) | PSP_LVL2_AB(1 << 3) },
207 { .type = AMD_ABL2, .level = PSP_BOTH((1 << 0) | (1 << 1)) | PSP_LVL2_AB(1 << 3) },
208 { .type = AMD_ABL3, .level = PSP_BOTH((1 << 0) | (1 << 1)) | PSP_LVL2_AB(1 << 3) },
209 { .type = AMD_ABL4, .level = PSP_BOTH((1 << 0) | (1 << 1)) | PSP_LVL2_AB(1 << 3) },
210 { .type = AMD_ABL5, .level = PSP_BOTH((1 << 0) | (1 << 1)) | PSP_LVL2_AB(1 << 3) },
211 { .type = AMD_ABL6, .level = PSP_BOTH((1 << 0) | (1 << 1)) | PSP_LVL2_AB(1 << 3) },
212 { .type = AMD_ABL7, .level = PSP_BOTH((1 << 0) | (1 << 1)) | PSP_LVL2_AB(1 << 3) },
213 { .type = AMD_SEV_DATA, .level = PSP_LVL2(1 << 1) | PSP_LVL2_AB(1 << 3) },
214 { .type = AMD_SEV_CODE, .level = PSP_LVL2(1 << 1) | PSP_LVL2_AB(1 << 3) },
215 { .type = AMD_FW_PSP_WHITELIST, .level = PSP_LVL2(1 << 1) | PSP_LVL2_AB(1 << 3) },
216 { .type = AMD_VBIOS_BTLOADER, .level = PSP_BOTH((1 << 0) | (1 << 1)) | PSP_LVL2_AB(1 << 3) },
217 { .type = AMD_FW_DXIO, .level = PSP_BOTH((1 << 0) | (1 << 1)) | PSP_BOTH_AB((1 << 2) | (1 << 3)) },
218 { .type = AMD_FW_USB_PHY, .level = PSP_LVL2(1 << 1) | PSP_LVL2_AB(1 << 3) },
219 { .type = AMD_FW_TOS_SEC_POLICY, .level = PSP_BOTH((1 << 0) | (1 << 1)) | PSP_LVL2_AB(1 << 3) },
220 { .type = AMD_FW_DRTM_TA, .level = PSP_LVL2(1 << 1) | PSP_LVL2_AB(1 << 3) },
221 { .type = AMD_FW_KEYDB_BL, .level = PSP_BOTH((1 << 0) | (1 << 1)) | PSP_LVL2_AB(1 << 3) },
222 { .type = AMD_FW_KEYDB_TOS, .level = PSP_LVL2(1 << 1) | PSP_LVL2_AB(1 << 3) },
223 { .type = AMD_FW_PSP_VERSTAGE, .level = PSP_BOTH((1 << 0) | (1 << 1)) | PSP_LVL2_AB(1 << 3) },
224 { .type = AMD_FW_VERSTAGE_SIG, .level = PSP_BOTH((1 << 0) | (1 << 1)) | PSP_LVL2_AB(1 << 3) },
225 { .type = AMD_RPMC_NVRAM, .level = PSP_LVL2(1 << 1) | PSP_LVL2_AB(1 << 3) },
226 { .type = AMD_FW_SPL, .level = PSP_LVL2(1 << 1) | PSP_LVL2_AB(1 << 3) },
227 { .type = AMD_FW_DMCU_ERAM, .level = PSP_LVL2(1 << 1) | PSP_LVL2_AB(1 << 3) },
228 { .type = AMD_FW_DMCU_ISR, .level = PSP_LVL2(1 << 1) | PSP_LVL2_AB(1 << 3) },
229 { .type = AMD_FW_MSMU, .level = PSP_LVL2(1 << 1) | PSP_LVL2_AB(1 << 3) },
230 { .type = AMD_FW_SPIROM_CFG, .level = PSP_LVL2(1 << 1) | PSP_LVL2_AB(1 << 3) },
231 { .type = AMD_FW_MPIO, .level = PSP_LVL2(1 << 1) | PSP_LVL2_AB(1 << 3) },
232 { .type = AMD_FW_PSP_SMUSCS, .level = PSP_BOTH((1 << 0) | (1 << 1)) | PSP_LVL2_AB(1 << 3) },
233 { .type = AMD_FW_DMCUB, .level = PSP_LVL2(1 << 1) | PSP_LVL2_AB(1 << 3) },
234 { .type = AMD_FW_PSP_BOOTLOADER_AB, .level = PSP_LVL2(1 << 1) | PSP_LVL2_AB(1 << 3),
235 .generate_manifest = true1 },
236 { .type = AMD_RIB, .subprog = 0, .level = PSP_LVL2(1 << 1) | PSP_LVL2_AB(1 << 3) },
237 { .type = AMD_RIB, .subprog = 1, .level = PSP_LVL2(1 << 1) | PSP_LVL2_AB(1 << 3) },
238 { .type = AMD_FW_MPDMA_TF, .level = PSP_BOTH((1 << 0) | (1 << 1)) | PSP_BOTH_AB((1 << 2) | (1 << 3)) },
239 { .type = AMD_TA_IKEK, .level = PSP_BOTH((1 << 0) | (1 << 1)) | PSP_LVL2_AB(1 << 3), .skip_hashing = true1 },
240 { .type = AMD_FW_GMI3_PHY, .level = PSP_BOTH((1 << 0) | (1 << 1)) | PSP_BOTH_AB((1 << 2) | (1 << 3)) },
241 { .type = AMD_FW_MPDMA_PM, .level = PSP_BOTH((1 << 0) | (1 << 1)) | PSP_BOTH_AB((1 << 2) | (1 << 3)) },
242 { .type = AMD_FW_AMF_SRAM, .level = PSP_LVL2(1 << 1) | PSP_LVL2_AB(1 << 3) },
243 { .type = AMD_FW_AMF_DRAM, .inst = 0, .level = PSP_LVL2(1 << 1) | PSP_LVL2_AB(1 << 3) },
244 { .type = AMD_FW_AMF_DRAM, .inst = 1, .level = PSP_LVL2(1 << 1) | PSP_LVL2_AB(1 << 3) },
245 { .type = AMD_FW_FCFG_TABLE, .level = PSP_LVL2(1 << 1) | PSP_LVL2_AB(1 << 3) },
246 { .type = AMD_FW_AMF_WLAN, .inst = 0, .level = PSP_LVL2(1 << 1) | PSP_LVL2_AB(1 << 3) },
247 { .type = AMD_FW_AMF_WLAN, .inst = 1, .level = PSP_LVL2(1 << 1) | PSP_LVL2_AB(1 << 3) },
248 { .type = AMD_FW_AMF_MFD, .level = PSP_LVL2(1 << 1) | PSP_LVL2_AB(1 << 3) },
249 { .type = AMD_TA_IKEK, .level = PSP_BOTH((1 << 0) | (1 << 1)) | PSP_LVL2_AB(1 << 3), .skip_hashing = true1 },
250 { .type = AMD_FW_MPCCX, .level = PSP_LVL2(1 << 1) | PSP_LVL2_AB(1 << 3) },
251 { .type = AMD_FW_LSDMA, .level = PSP_LVL2(1 << 1) | PSP_LVL2_AB(1 << 3) },
252 { .type = AMD_FW_C20_MP, .level = PSP_BOTH((1 << 0) | (1 << 1)) | PSP_LVL2_AB(1 << 3) },
253 { .type = AMD_FW_MINIMSMU, .inst = 0, .level = PSP_BOTH((1 << 0) | (1 << 1)) | PSP_LVL2_AB(1 << 3) },
254 { .type = AMD_FW_MINIMSMU, .inst = 1, .level = PSP_BOTH((1 << 0) | (1 << 1)) | PSP_LVL2_AB(1 << 3) },
255 { .type = AMD_FW_SRAM_FW_EXT, .level = PSP_LVL2(1 << 1) | PSP_LVL2_AB(1 << 3) },
256 { .type = AMD_FW_UMSMU, .level = PSP_LVL2(1 << 1) | PSP_LVL2_AB(1 << 3) },
257 { .type = AMD_FW_INVALID },
258};
259
260amd_fw_entry amd_fw_table[] = {
261 { .type = AMD_FW_XHCI },
262 { .type = AMD_FW_IMC },
263 { .type = AMD_FW_GEC },
264 { .type = AMD_FW_INVALID },
265};
266
267amd_bios_entry amd_bios_table[] = {
268 { .type = AMD_BIOS_RTM_PUBKEY, .inst = 0, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
269 { .type = AMD_BIOS_SIG, .inst = 0, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
270 { .type = AMD_BIOS_APCB, .inst = 0, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
271 { .type = AMD_BIOS_APCB, .inst = 1, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
272 { .type = AMD_BIOS_APCB, .inst = 2, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
273 { .type = AMD_BIOS_APCB, .inst = 3, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
274 { .type = AMD_BIOS_APCB, .inst = 4, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
275 { .type = AMD_BIOS_APCB, .inst = 5, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
276 { .type = AMD_BIOS_APCB, .inst = 6, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
277 { .type = AMD_BIOS_APCB, .inst = 7, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
278 { .type = AMD_BIOS_APCB, .inst = 8, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
279 { .type = AMD_BIOS_APCB, .inst = 9, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
280 { .type = AMD_BIOS_APCB, .inst = 10, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
281 { .type = AMD_BIOS_APCB, .inst = 11, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
282 { .type = AMD_BIOS_APCB, .inst = 12, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
283 { .type = AMD_BIOS_APCB, .inst = 13, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
284 { .type = AMD_BIOS_APCB, .inst = 14, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
285 { .type = AMD_BIOS_APCB, .inst = 15, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
286 { .type = AMD_BIOS_APCB_BK, .inst = 0, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
287 { .type = AMD_BIOS_APCB_BK, .inst = 1, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
288 { .type = AMD_BIOS_APCB_BK, .inst = 2, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
289 { .type = AMD_BIOS_APCB_BK, .inst = 3, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
290 { .type = AMD_BIOS_APCB_BK, .inst = 4, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
291 { .type = AMD_BIOS_APCB_BK, .inst = 5, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
292 { .type = AMD_BIOS_APCB_BK, .inst = 6, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
293 { .type = AMD_BIOS_APCB_BK, .inst = 7, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
294 { .type = AMD_BIOS_APCB_BK, .inst = 8, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
295 { .type = AMD_BIOS_APCB_BK, .inst = 9, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
296 { .type = AMD_BIOS_APCB_BK, .inst = 10, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
297 { .type = AMD_BIOS_APCB_BK, .inst = 11, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
298 { .type = AMD_BIOS_APCB_BK, .inst = 12, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
299 { .type = AMD_BIOS_APCB_BK, .inst = 13, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
300 { .type = AMD_BIOS_APCB_BK, .inst = 14, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
301 { .type = AMD_BIOS_APCB_BK, .inst = 15, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
302 { .type = AMD_BIOS_APOB, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
303 { .type = AMD_BIOS_BIN,
304 .reset = 1, .copy = 1, .zlib = 1, .inst = 0, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
305 { .type = AMD_BIOS_APOB_NV, .level = BDT_LVL2(1 << 1) },
306 { .type = AMD_BIOS_PMUI, .inst = 1, .subpr = 0, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
307 { .type = AMD_BIOS_PMUD, .inst = 1, .subpr = 0, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
308 { .type = AMD_BIOS_PMUI, .inst = 2, .subpr = 0, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
309 { .type = AMD_BIOS_PMUD, .inst = 2, .subpr = 0, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
310 { .type = AMD_BIOS_PMUI, .inst = 3, .subpr = 0, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
311 { .type = AMD_BIOS_PMUD, .inst = 3, .subpr = 0, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
312 { .type = AMD_BIOS_PMUI, .inst = 4, .subpr = 0, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
313 { .type = AMD_BIOS_PMUD, .inst = 4, .subpr = 0, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
314 { .type = AMD_BIOS_PMUI, .inst = 5, .subpr = 0, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
315 { .type = AMD_BIOS_PMUD, .inst = 5, .subpr = 0, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
316 { .type = AMD_BIOS_PMUI, .inst = 6, .subpr = 0, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
317 { .type = AMD_BIOS_PMUD, .inst = 6, .subpr = 0, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
318 { .type = AMD_BIOS_PMUI, .inst = 7, .subpr = 0, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
319 { .type = AMD_BIOS_PMUD, .inst = 7, .subpr = 0, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
320 { .type = AMD_BIOS_PMUI, .inst = 9, .subpr = 0, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
321 { .type = AMD_BIOS_PMUD, .inst = 9, .subpr = 0, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
322 { .type = AMD_BIOS_PMUI, .inst = 10, .subpr = 0, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
323 { .type = AMD_BIOS_PMUD, .inst = 10, .subpr = 0, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
324 { .type = AMD_BIOS_PMUI, .inst = 11, .subpr = 0, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
325 { .type = AMD_BIOS_PMUD, .inst = 11, .subpr = 0, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
326 { .type = AMD_BIOS_PMUI, .inst = 12, .subpr = 0, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
327 { .type = AMD_BIOS_PMUD, .inst = 12, .subpr = 0, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
328 { .type = AMD_BIOS_PMUI, .inst = 13, .subpr = 0, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
329 { .type = AMD_BIOS_PMUD, .inst = 13, .subpr = 0, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
330 { .type = AMD_BIOS_PMUI, .inst = 1, .subpr = 1, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
331 { .type = AMD_BIOS_PMUD, .inst = 1, .subpr = 1, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
332 { .type = AMD_BIOS_PMUI, .inst = 2, .subpr = 1, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
333 { .type = AMD_BIOS_PMUD, .inst = 2, .subpr = 1, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
334 { .type = AMD_BIOS_PMUI, .inst = 3, .subpr = 1, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
335 { .type = AMD_BIOS_PMUD, .inst = 3, .subpr = 1, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
336 { .type = AMD_BIOS_PMUI, .inst = 4, .subpr = 1, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
337 { .type = AMD_BIOS_PMUD, .inst = 4, .subpr = 1, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
338 { .type = AMD_BIOS_PMUI, .inst = 5, .subpr = 1, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
339 { .type = AMD_BIOS_PMUD, .inst = 5, .subpr = 1, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
340 { .type = AMD_BIOS_PMUI, .inst = 6, .subpr = 1, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
341 { .type = AMD_BIOS_PMUD, .inst = 6, .subpr = 1, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
342 { .type = AMD_BIOS_PMUI, .inst = 7, .subpr = 1, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
343 { .type = AMD_BIOS_PMUD, .inst = 7, .subpr = 1, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
344 { .type = AMD_BIOS_PMUI, .inst = 9, .subpr = 1, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
345 { .type = AMD_BIOS_PMUD, .inst = 9, .subpr = 1, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
346 { .type = AMD_BIOS_PMUI, .inst = 10, .subpr = 1, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
347 { .type = AMD_BIOS_PMUD, .inst = 10, .subpr = 1, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
348 { .type = AMD_BIOS_PMUI, .inst = 11, .subpr = 1, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
349 { .type = AMD_BIOS_PMUD, .inst = 11, .subpr = 1, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
350 { .type = AMD_BIOS_PMUI, .inst = 12, .subpr = 1, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
351 { .type = AMD_BIOS_PMUD, .inst = 12, .subpr = 1, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
352 { .type = AMD_BIOS_PMUI, .inst = 13, .subpr = 1, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
353 { .type = AMD_BIOS_PMUD, .inst = 13, .subpr = 1, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
354 { .type = AMD_BIOS_UCODE, .inst = 0, .level = BDT_LVL2(1 << 1) },
355 { .type = AMD_BIOS_UCODE, .inst = 1, .level = BDT_LVL2(1 << 1) },
356 { .type = AMD_BIOS_UCODE, .inst = 2, .level = BDT_LVL2(1 << 1) },
357 { .type = AMD_BIOS_UCODE, .inst = 3, .level = BDT_LVL2(1 << 1) },
358 { .type = AMD_BIOS_UCODE, .inst = 4, .level = BDT_LVL2(1 << 1) },
359 { .type = AMD_BIOS_UCODE, .inst = 5, .level = BDT_LVL2(1 << 1) },
360 { .type = AMD_BIOS_UCODE, .inst = 6, .level = BDT_LVL2(1 << 1) },
361 { .type = AMD_BIOS_MP2_CFG, .level = BDT_LVL2(1 << 1) },
362 { .type = AMD_BIOS_PSP_SHARED_MEM, .inst = 0, .level = BDT_BOTH((1 << 0) | (1 << 1)) },
363 { .type = AMD_BIOS_INVALID },
364};
365
366#define RUN_BASE(ctx)(0xFFFFFFFF - (ctx).rom_size + 1) (0xFFFFFFFF - (ctx).rom_size + 1)
367#define RUN_OFFSET_MODE(ctx, offset, mode)((mode) == AMD_ADDR_PHYSICAL ? (0xFFFFFFFF - (ctx).rom_size +
1) + (offset) : ((mode) == AMD_ADDR_REL_BIOS ? (offset) : ((
mode) == AMD_ADDR_REL_TAB ? (offset) - (ctx).current_table : (
offset))))
\
368 ((mode) == AMD_ADDR_PHYSICAL ? RUN_BASE(ctx)(0xFFFFFFFF - (ctx).rom_size + 1) + (offset) : \
369 ((mode) == AMD_ADDR_REL_BIOS ? (offset) : \
370 ((mode) == AMD_ADDR_REL_TAB ? (offset) - (ctx).current_table : (offset))))
371#define RUN_OFFSET(ctx, offset)(((ctx).address_mode) == AMD_ADDR_PHYSICAL ? (0xFFFFFFFF - ((
ctx)).rom_size + 1) + ((offset)) : (((ctx).address_mode) == AMD_ADDR_REL_BIOS
? ((offset)) : (((ctx).address_mode) == AMD_ADDR_REL_TAB ? (
(offset)) - ((ctx)).current_table : ((offset)))))
RUN_OFFSET_MODE((ctx), (offset), (ctx).address_mode)(((ctx).address_mode) == AMD_ADDR_PHYSICAL ? (0xFFFFFFFF - ((
ctx)).rom_size + 1) + ((offset)) : (((ctx).address_mode) == AMD_ADDR_REL_BIOS
? ((offset)) : (((ctx).address_mode) == AMD_ADDR_REL_TAB ? (
(offset)) - ((ctx)).current_table : ((offset)))))
372#define RUN_TO_OFFSET(ctx, run)((ctx).address_mode == AMD_ADDR_PHYSICAL ? (run) - (0xFFFFFFFF
- (ctx).rom_size + 1) : (run))
((ctx).address_mode == AMD_ADDR_PHYSICAL ? \
373 (run) - RUN_BASE(ctx)(0xFFFFFFFF - (ctx).rom_size + 1) : (run)) /* TODO: */
374#define RUN_CURRENT(ctx)((((ctx)).address_mode) == AMD_ADDR_PHYSICAL ? (0xFFFFFFFF - (
((ctx))).rom_size + 1) + (((ctx).current)) : ((((ctx)).address_mode
) == AMD_ADDR_REL_BIOS ? (((ctx).current)) : ((((ctx)).address_mode
) == AMD_ADDR_REL_TAB ? (((ctx).current)) - (((ctx))).current_table
: (((ctx).current)))))
RUN_OFFSET((ctx), (ctx).current)((((ctx)).address_mode) == AMD_ADDR_PHYSICAL ? (0xFFFFFFFF - (
((ctx))).rom_size + 1) + (((ctx).current)) : ((((ctx)).address_mode
) == AMD_ADDR_REL_BIOS ? (((ctx).current)) : ((((ctx)).address_mode
) == AMD_ADDR_REL_TAB ? (((ctx).current)) - (((ctx))).current_table
: (((ctx).current)))))
375/* The mode in entry can not be higher than the header's.
376 For example, if table mode is 0, all the entry mode will be 0. */
377#define RUN_CURRENT_MODE(ctx, mode)(((ctx).address_mode < (mode) ? (ctx).address_mode : (mode
)) == AMD_ADDR_PHYSICAL ? (0xFFFFFFFF - ((ctx)).rom_size + 1)
+ ((ctx).current) : (((ctx).address_mode < (mode) ? (ctx)
.address_mode : (mode)) == AMD_ADDR_REL_BIOS ? ((ctx).current
) : (((ctx).address_mode < (mode) ? (ctx).address_mode : (
mode)) == AMD_ADDR_REL_TAB ? ((ctx).current) - ((ctx)).current_table
: ((ctx).current))))
RUN_OFFSET_MODE((ctx), (ctx).current, \(((ctx).address_mode < (mode) ? (ctx).address_mode : (mode
)) == AMD_ADDR_PHYSICAL ? (0xFFFFFFFF - ((ctx)).rom_size + 1)
+ ((ctx).current) : (((ctx).address_mode < (mode) ? (ctx)
.address_mode : (mode)) == AMD_ADDR_REL_BIOS ? ((ctx).current
) : (((ctx).address_mode < (mode) ? (ctx).address_mode : (
mode)) == AMD_ADDR_REL_TAB ? ((ctx).current) - ((ctx)).current_table
: ((ctx).current))))
378 (ctx).address_mode < (mode) ? (ctx).address_mode : (mode))(((ctx).address_mode < (mode) ? (ctx).address_mode : (mode
)) == AMD_ADDR_PHYSICAL ? (0xFFFFFFFF - ((ctx)).rom_size + 1)
+ ((ctx).current) : (((ctx).address_mode < (mode) ? (ctx)
.address_mode : (mode)) == AMD_ADDR_REL_BIOS ? ((ctx).current
) : (((ctx).address_mode < (mode) ? (ctx).address_mode : (
mode)) == AMD_ADDR_REL_TAB ? ((ctx).current) - ((ctx)).current_table
: ((ctx).current))))
379#define BUFF_OFFSET(ctx, offset)((void *)((ctx).rom + (offset))) ((void *)((ctx).rom + (offset)))
380#define BUFF_CURRENT(ctx)((void *)(((ctx)).rom + ((ctx).current))) BUFF_OFFSET((ctx), (ctx).current)((void *)(((ctx)).rom + ((ctx).current)))
381#define BUFF_TO_RUN(ctx, ptr)((((ctx)).address_mode) == AMD_ADDR_PHYSICAL ? (0xFFFFFFFF - (
((ctx))).rom_size + 1) + ((((char *)(ptr) - (ctx).rom))) : ((
((ctx)).address_mode) == AMD_ADDR_REL_BIOS ? ((((char *)(ptr)
- (ctx).rom))) : ((((ctx)).address_mode) == AMD_ADDR_REL_TAB
? ((((char *)(ptr) - (ctx).rom))) - (((ctx))).current_table :
((((char *)(ptr) - (ctx).rom))))))
RUN_OFFSET((ctx), ((char *)(ptr) - (ctx).rom))((((ctx)).address_mode) == AMD_ADDR_PHYSICAL ? (0xFFFFFFFF - (
((ctx))).rom_size + 1) + ((((char *)(ptr) - (ctx).rom))) : ((
((ctx)).address_mode) == AMD_ADDR_REL_BIOS ? ((((char *)(ptr)
- (ctx).rom))) : ((((ctx)).address_mode) == AMD_ADDR_REL_TAB
? ((((char *)(ptr) - (ctx).rom))) - (((ctx))).current_table :
((((char *)(ptr) - (ctx).rom))))))
382#define BUFF_TO_RUN_MODE(ctx, ptr, mode)(((ctx).address_mode < (mode) ? (ctx).address_mode : (mode
)) == AMD_ADDR_PHYSICAL ? (0xFFFFFFFF - ((ctx)).rom_size + 1)
+ (((char *)(ptr) - (ctx).rom)) : (((ctx).address_mode < (
mode) ? (ctx).address_mode : (mode)) == AMD_ADDR_REL_BIOS ? (
((char *)(ptr) - (ctx).rom)) : (((ctx).address_mode < (mode
) ? (ctx).address_mode : (mode)) == AMD_ADDR_REL_TAB ? (((char
*)(ptr) - (ctx).rom)) - ((ctx)).current_table : (((char *)(ptr
) - (ctx).rom)))))
RUN_OFFSET_MODE((ctx), ((char *)(ptr) - (ctx).rom), \(((ctx).address_mode < (mode) ? (ctx).address_mode : (mode
)) == AMD_ADDR_PHYSICAL ? (0xFFFFFFFF - ((ctx)).rom_size + 1)
+ (((char *)(ptr) - (ctx).rom)) : (((ctx).address_mode < (
mode) ? (ctx).address_mode : (mode)) == AMD_ADDR_REL_BIOS ? (
((char *)(ptr) - (ctx).rom)) : (((ctx).address_mode < (mode
) ? (ctx).address_mode : (mode)) == AMD_ADDR_REL_TAB ? (((char
*)(ptr) - (ctx).rom)) - ((ctx)).current_table : (((char *)(ptr
) - (ctx).rom)))))
383 (ctx).address_mode < (mode) ? (ctx).address_mode : (mode))(((ctx).address_mode < (mode) ? (ctx).address_mode : (mode
)) == AMD_ADDR_PHYSICAL ? (0xFFFFFFFF - ((ctx)).rom_size + 1)
+ (((char *)(ptr) - (ctx).rom)) : (((ctx).address_mode < (
mode) ? (ctx).address_mode : (mode)) == AMD_ADDR_REL_BIOS ? (
((char *)(ptr) - (ctx).rom)) : (((ctx).address_mode < (mode
) ? (ctx).address_mode : (mode)) == AMD_ADDR_REL_TAB ? (((char
*)(ptr) - (ctx).rom)) - ((ctx)).current_table : (((char *)(ptr
) - (ctx).rom)))))
384#define BUFF_ROOM(ctx)((ctx).rom_size - (ctx).current) ((ctx).rom_size - (ctx).current)
385/* Only set the address mode in entry if the table is mode 2. */
386#define SET_ADDR_MODE(table, mode)((table)->header.additional_info_fields.address_mode == AMD_ADDR_REL_TAB
? (mode) : 0)
\
387 ((table)->header.additional_info_fields.address_mode == \
388 AMD_ADDR_REL_TAB ? (mode) : 0)
389#define SET_ADDR_MODE_BY_TABLE(table)(((table))->header.additional_info_fields.address_mode == AMD_ADDR_REL_TAB
? ((table)->header.additional_info_fields.address_mode) :
0)
\
390 SET_ADDR_MODE((table), (table)->header.additional_info_fields.address_mode)(((table))->header.additional_info_fields.address_mode == AMD_ADDR_REL_TAB
? ((table)->header.additional_info_fields.address_mode) :
0)
391
392
393static void free_psp_firmware_filenames(amd_fw_entry *fw_table)
394{
395 amd_fw_entry *index;
396
397 for (index = fw_table; index->type != AMD_FW_INVALID; index++) {
398 if (index->filename &&
399 index->type != AMD_FW_VERSTAGE_SIG &&
400 index->type != AMD_FW_PSP_VERSTAGE &&
401 index->type != AMD_FW_SPL &&
402 index->type != AMD_FW_PSP_WHITELIST) {
403 free(index->filename);
404 index->filename = NULL((void*)0);
405 }
406 }
407}
408
409static void free_bdt_firmware_filenames(amd_bios_entry *fw_table)
410{
411 amd_bios_entry *index;
412
413 for (index = fw_table; index->type != AMD_BIOS_INVALID; index++) {
414 if (index->filename &&
415 index->type != AMD_BIOS_APCB &&
416 index->type != AMD_BIOS_BIN &&
417 index->type != AMD_BIOS_APCB_BK &&
418 index->type != AMD_BIOS_UCODE) {
419 free(index->filename);
420 index->filename = NULL((void*)0);
421 }
422 }
423}
424
425static void amdfwtool_cleanup(context *ctx)
426{
427 free(ctx->rom);
428 ctx->rom = NULL((void*)0);
429
430 /* Free the filename. */
431 free_psp_firmware_filenames(amd_psp_fw_table);
432 free_bdt_firmware_filenames(amd_bios_table);
433
434 free(ctx->amd_psp_fw_table_clean);
435 ctx->amd_psp_fw_table_clean = NULL((void*)0);
436 free(ctx->amd_bios_table_clean);
437 ctx->amd_bios_table_clean = NULL((void*)0);
438}
439
440void assert_fw_entry(uint32_t count, uint32_t max, context *ctx)
441{
442 if (count >= max) {
443 fprintf(stderrstderr, "Error: BIOS entries (%d) exceeds max allowed items "
444 "(%d)\n", count, max);
445 amdfwtool_cleanup(ctx);
446 exit(1);
447 }
448}
449
450static void set_current_pointer(context *ctx, uint32_t value)
451{
452 if (ctx->current_pointer_saved != 0xFFFFFFFF &&
453 ctx->current_pointer_saved != ctx->current) {
454 fprintf(stderrstderr, "Error: The pointer is changed elsewhere\n");
455 amdfwtool_cleanup(ctx);
456 exit(1);
457 }
458
459 ctx->current = value;
460
461 if (ctx->current > ctx->rom_size) {
462 fprintf(stderrstderr, "Error: Packing data causes overflow\n");
463 amdfwtool_cleanup(ctx);
464 exit(1);
465 }
466
467 ctx->current_pointer_saved = ctx->current;
468}
469
470static void adjust_current_pointer(context *ctx, uint32_t add, uint32_t align)
471{
472 /* Get */
473 set_current_pointer(ctx, ALIGN_UP(ctx->current + add, align)((((ctx->current + add))+((__typeof__((ctx->current + add
)))((align))-1UL))&~((__typeof__((ctx->current + add))
)((align))-1UL))
);
474}
475
476static void *new_psp_dir(context *ctx, int multi, uint32_t cookie)
477{
478 void *ptr;
479
480 /*
481 * Force both onto boundary when multi. Primary table is after
482 * updatable table, so alignment ensures primary can stay intact
483 * if secondary is reprogrammed.
484 */
485 if (multi)
486 adjust_current_pointer(ctx, 0, TABLE_ERASE_ALIGNMENT(((0x1000U) > (0x1000U)) ? (0x1000U) : (0x1000U)));
487 else
488 adjust_current_pointer(ctx, 0, TABLE_ALIGNMENT0x1000U);
489
490 ptr = BUFF_CURRENT(*ctx)((void *)(((*ctx)).rom + ((*ctx).current)));
491 ((psp_directory_header *)ptr)->cookie = cookie;
492 ((psp_directory_header *)ptr)->num_entries = 0;
493 ((psp_directory_header *)ptr)->additional_info = 0;
494 ((psp_directory_header *)ptr)->additional_info_fields.address_mode = ctx->address_mode;
495 adjust_current_pointer(ctx,
496 sizeof(psp_directory_header) + MAX_PSP_ENTRIES0xff * sizeof(psp_directory_entry),
497 1);
498 return ptr;
499}
500
501static void *new_ish_dir(context *ctx)
502{
503 void *ptr;
504 adjust_current_pointer(ctx, 0, TABLE_ALIGNMENT0x1000U);
505 ptr = BUFF_CURRENT(*ctx)((void *)(((*ctx)).rom + ((*ctx).current)));
506 adjust_current_pointer(ctx, TABLE_ALIGNMENT0x1000U, 1);
507
508 return ptr;
509}
510
511static void *new_combo_dir(context *ctx, uint32_t cookie)
512{
513 void *ptr;
514
515 adjust_current_pointer(ctx, 0, TABLE_ALIGNMENT0x1000U);
516 ptr = BUFF_CURRENT(*ctx)((void *)(((*ctx)).rom + ((*ctx).current)));
517 ((psp_combo_header *)ptr)->cookie = cookie;
518 adjust_current_pointer(ctx,
519 sizeof(psp_combo_header) + MAX_COMBO_ENTRIES2 * sizeof(psp_combo_entry),
520 1);
521 return ptr;
522}
523
524static void fill_dir_header(void *directory, uint32_t count, context *ctx)
525{
526 psp_combo_directory *cdir = directory;
527 psp_directory_table *dir = directory;
528 bios_directory_table *bdir = directory;
529 /* The cookies have same offsets. */
530 uint32_t cookie = ((psp_directory_table *)directory)->header.cookie;
531 uint32_t table_size = 0;
532
533 if (ctx == NULL((void*)0) || directory == NULL((void*)0)) {
534 fprintf(stderrstderr, "Calling %s with NULL pointers\n", __func__);
535 return;
536 }
537
538 /* The table size needs to be 0x1000 aligned. So align the end of table. */
539 adjust_current_pointer(ctx, 0, TABLE_ALIGNMENT0x1000U);
540
541 switch (cookie) {
542 case PSP2_COOKIE0x50535032:
543 case BHD2_COOKIE0x44484232:
544 /* lookup mode is hardcoded for now. */
545 cdir->header.lookup = 1;
546 cdir->header.num_entries = count;
547 cdir->header.reserved[0] = 0;
548 cdir->header.reserved[1] = 0;
549 /* checksum everything that comes after the Checksum field */
550 cdir->header.checksum = fletcher32(&cdir->header.num_entries,
551 count * sizeof(psp_combo_entry)
552 + sizeof(cdir->header.num_entries)
553 + sizeof(cdir->header.lookup)
554 + 2 * sizeof(cdir->header.reserved[0]));
555 break;
556 case PSP_COOKIE0x50535024:
557 case PSPL2_COOKIE0x324c5024:
558 /* The table size is only set once. Later calls only update
559 * the count and fletcher. So does the BIOS table. */
560 if (dir->header.additional_info_fields.dir_size == 0) {
561 table_size = ctx->current - ctx->current_table;
562 if ((table_size % TABLE_ALIGNMENT0x1000U) != 0 &&
563 (table_size / TABLE_ALIGNMENT0x1000U) != 0) {
564 fprintf(stderrstderr, "The PSP table size should be 4K aligned\n");
565 amdfwtool_cleanup(ctx);
566 exit(1);
567 }
568 dir->header.additional_info_fields.dir_size =
569 table_size / TABLE_ALIGNMENT0x1000U;
570 }
571 dir->header.num_entries = count;
572 dir->header.additional_info_fields.spi_block_size = 1;
573 dir->header.additional_info_fields.base_addr = 0;
574 /* checksum everything that comes after the Checksum field */
575 dir->header.checksum = fletcher32(&dir->header.num_entries,
576 count * sizeof(psp_directory_entry)
577 + sizeof(dir->header.num_entries)
578 + sizeof(dir->header.additional_info));
579 break;
580 case BHD_COOKIE0x44484224:
581 case BHDL2_COOKIE0x324c4224:
582 if (bdir->header.additional_info_fields.dir_size == 0) {
583 table_size = ctx->current - ctx->current_table;
584 if ((table_size % TABLE_ALIGNMENT0x1000U) != 0 &&
585 table_size / TABLE_ALIGNMENT0x1000U != 0) {
586 fprintf(stderrstderr, "The BIOS table size should be 4K aligned\n");
587 amdfwtool_cleanup(ctx);
588 exit(1);
589 }
590 bdir->header.additional_info_fields.dir_size =
591 table_size / TABLE_ALIGNMENT0x1000U;
592 }
593 bdir->header.num_entries = count;
594 bdir->header.additional_info_fields.spi_block_size = 1;
595 bdir->header.additional_info_fields.base_addr = 0;
596 /* checksum everything that comes after the Checksum field */
597 bdir->header.checksum = fletcher32(&bdir->header.num_entries,
598 count * sizeof(bios_directory_entry)
599 + sizeof(bdir->header.num_entries)
600 + sizeof(bdir->header.additional_info));
601 break;
602 }
603
604}
605
606static void fill_psp_directory_to_efs(embedded_firmware *amd_romsig, void *pspdir,
607 context *ctx, amd_cb_config *cb_config)
608{
609 switch (cb_config->soc_id) {
610 case PLATFORM_UNKNOWN:
611 amd_romsig->psp_directory =
612 BUFF_TO_RUN_MODE(*ctx, pspdir, AMD_ADDR_REL_BIOS)(((*ctx).address_mode < (AMD_ADDR_REL_BIOS) ? (*ctx).address_mode
: (AMD_ADDR_REL_BIOS)) == AMD_ADDR_PHYSICAL ? (0xFFFFFFFF - (
(*ctx)).rom_size + 1) + (((char *)(pspdir) - (*ctx).rom)) : (
((*ctx).address_mode < (AMD_ADDR_REL_BIOS) ? (*ctx).address_mode
: (AMD_ADDR_REL_BIOS)) == AMD_ADDR_REL_BIOS ? (((char *)(pspdir
) - (*ctx).rom)) : (((*ctx).address_mode < (AMD_ADDR_REL_BIOS
) ? (*ctx).address_mode : (AMD_ADDR_REL_BIOS)) == AMD_ADDR_REL_TAB
? (((char *)(pspdir) - (*ctx).rom)) - ((*ctx)).current_table
: (((char *)(pspdir) - (*ctx).rom)))))
;
613 break;
614 case PLATFORM_CEZANNE:
615 case PLATFORM_MENDOCINO:
616 case PLATFORM_PHOENIX:
617 case PLATFORM_GLINDA:
618 case PLATFORM_CARRIZO:
619 case PLATFORM_STONEYRIDGE:
620 case PLATFORM_RAVEN:
621 case PLATFORM_PICASSO:
622 case PLATFORM_LUCIENNE:
623 case PLATFORM_RENOIR:
624 case PLATFORM_GENOA:
625 default:
626 /* for combo, it is also combo_psp_directory */
627 amd_romsig->new_psp_directory =
628 BUFF_TO_RUN_MODE(*ctx, pspdir, AMD_ADDR_REL_BIOS)(((*ctx).address_mode < (AMD_ADDR_REL_BIOS) ? (*ctx).address_mode
: (AMD_ADDR_REL_BIOS)) == AMD_ADDR_PHYSICAL ? (0xFFFFFFFF - (
(*ctx)).rom_size + 1) + (((char *)(pspdir) - (*ctx).rom)) : (
((*ctx).address_mode < (AMD_ADDR_REL_BIOS) ? (*ctx).address_mode
: (AMD_ADDR_REL_BIOS)) == AMD_ADDR_REL_BIOS ? (((char *)(pspdir
) - (*ctx).rom)) : (((*ctx).address_mode < (AMD_ADDR_REL_BIOS
) ? (*ctx).address_mode : (AMD_ADDR_REL_BIOS)) == AMD_ADDR_REL_TAB
? (((char *)(pspdir) - (*ctx).rom)) - ((*ctx)).current_table
: (((char *)(pspdir) - (*ctx).rom)))))
;
629 break;
630 }
631}
632
633static void fill_bios_directory_to_efs(embedded_firmware *amd_romsig, void *biosdir,
634 context *ctx, amd_cb_config *cb_config)
635{
636 switch (cb_config->soc_id) {
637 case PLATFORM_RENOIR:
638 case PLATFORM_LUCIENNE:
639 case PLATFORM_CEZANNE:
640 case PLATFORM_GENOA:
641 if (!cb_config->recovery_ab)
642 amd_romsig->bios3_entry =
643 BUFF_TO_RUN_MODE(*ctx, biosdir, AMD_ADDR_REL_BIOS)(((*ctx).address_mode < (AMD_ADDR_REL_BIOS) ? (*ctx).address_mode
: (AMD_ADDR_REL_BIOS)) == AMD_ADDR_PHYSICAL ? (0xFFFFFFFF - (
(*ctx)).rom_size + 1) + (((char *)(biosdir) - (*ctx).rom)) : (
((*ctx).address_mode < (AMD_ADDR_REL_BIOS) ? (*ctx).address_mode
: (AMD_ADDR_REL_BIOS)) == AMD_ADDR_REL_BIOS ? (((char *)(biosdir
) - (*ctx).rom)) : (((*ctx).address_mode < (AMD_ADDR_REL_BIOS
) ? (*ctx).address_mode : (AMD_ADDR_REL_BIOS)) == AMD_ADDR_REL_TAB
? (((char *)(biosdir) - (*ctx).rom)) - ((*ctx)).current_table
: (((char *)(biosdir) - (*ctx).rom)))))
;
644 break;
645 case PLATFORM_MENDOCINO:
646 case PLATFORM_PHOENIX:
647 case PLATFORM_GLINDA:
648 break;
649 case PLATFORM_CARRIZO:
650 case PLATFORM_STONEYRIDGE:
651 case PLATFORM_RAVEN:
652 case PLATFORM_PICASSO:
653 default:
654 amd_romsig->bios1_entry =
655 BUFF_TO_RUN_MODE(*ctx, biosdir, AMD_ADDR_REL_BIOS)(((*ctx).address_mode < (AMD_ADDR_REL_BIOS) ? (*ctx).address_mode
: (AMD_ADDR_REL_BIOS)) == AMD_ADDR_PHYSICAL ? (0xFFFFFFFF - (
(*ctx)).rom_size + 1) + (((char *)(biosdir) - (*ctx).rom)) : (
((*ctx).address_mode < (AMD_ADDR_REL_BIOS) ? (*ctx).address_mode
: (AMD_ADDR_REL_BIOS)) == AMD_ADDR_REL_BIOS ? (((char *)(biosdir
) - (*ctx).rom)) : (((*ctx).address_mode < (AMD_ADDR_REL_BIOS
) ? (*ctx).address_mode : (AMD_ADDR_REL_BIOS)) == AMD_ADDR_REL_TAB
? (((char *)(biosdir) - (*ctx).rom)) - ((*ctx)).current_table
: (((char *)(biosdir) - (*ctx).rom)))))
;
656 break;
657 }
658}
659
660static uint32_t get_psp_id(enum platform soc_id)
661{
662 uint32_t psp_id;
663 switch (soc_id) {
664 case PLATFORM_RAVEN:
665 case PLATFORM_PICASSO:
666 psp_id = 0xBC0A0000;
667 break;
668 case PLATFORM_RENOIR:
669 case PLATFORM_LUCIENNE:
670 psp_id = 0xBC0C0000;
671 break;
672 case PLATFORM_CEZANNE:
673 psp_id = 0xBC0C0140;
674 break;
675 case PLATFORM_MENDOCINO:
676 psp_id = 0xBC0D0900;
677 break;
678 case PLATFORM_STONEYRIDGE:
679 psp_id = 0x10220B00;
680 break;
681 case PLATFORM_GLINDA:
682 psp_id = 0xBC0E0200;
683 break;
684 case PLATFORM_PHOENIX:
685 psp_id = 0xBC0D0400;
686 break;
687 case PLATFORM_GENOA:
688 psp_id = 0xBC0C0111;
689 break;
690 case PLATFORM_CARRIZO:
691 default:
692 psp_id = 0;
693 break;
694 }
695 return psp_id;
696}
697
698static void integrate_firmwares(context *ctx,
699 embedded_firmware *romsig,
700 amd_fw_entry *fw_table)
701{
702 ssize_t bytes;
703 uint32_t i;
704
705 adjust_current_pointer(ctx, 0, BLOB_ALIGNMENT0x100U);
706
707 for (i = 0; fw_table[i].type != AMD_FW_INVALID; i++) {
708 if (fw_table[i].filename != NULL((void*)0)) {
709 switch (fw_table[i].type) {
710 case AMD_FW_IMC:
711 adjust_current_pointer(ctx, 0, 0x10000U);
712 romsig->imc_entry = RUN_CURRENT(*ctx)((((*ctx)).address_mode) == AMD_ADDR_PHYSICAL ? (0xFFFFFFFF -
(((*ctx))).rom_size + 1) + (((*ctx).current)) : ((((*ctx)).address_mode
) == AMD_ADDR_REL_BIOS ? (((*ctx).current)) : ((((*ctx)).address_mode
) == AMD_ADDR_REL_TAB ? (((*ctx).current)) - (((*ctx))).current_table
: (((*ctx).current)))))
;
713 break;
714 case AMD_FW_GEC:
715 romsig->gec_entry = RUN_CURRENT(*ctx)((((*ctx)).address_mode) == AMD_ADDR_PHYSICAL ? (0xFFFFFFFF -
(((*ctx))).rom_size + 1) + (((*ctx).current)) : ((((*ctx)).address_mode
) == AMD_ADDR_REL_BIOS ? (((*ctx).current)) : ((((*ctx)).address_mode
) == AMD_ADDR_REL_TAB ? (((*ctx).current)) - (((*ctx))).current_table
: (((*ctx).current)))))
;
716 break;
717 case AMD_FW_XHCI:
718 romsig->xhci_entry = RUN_CURRENT(*ctx)((((*ctx)).address_mode) == AMD_ADDR_PHYSICAL ? (0xFFFFFFFF -
(((*ctx))).rom_size + 1) + (((*ctx).current)) : ((((*ctx)).address_mode
) == AMD_ADDR_REL_BIOS ? (((*ctx).current)) : ((((*ctx)).address_mode
) == AMD_ADDR_REL_TAB ? (((*ctx).current)) - (((*ctx))).current_table
: (((*ctx).current)))))
;
719 break;
720 default:
721 /* Error */
722 break;
723 }
724
725 bytes = copy_blob(BUFF_CURRENT(*ctx)((void *)(((*ctx)).rom + ((*ctx).current))),
726 fw_table[i].filename, BUFF_ROOM(*ctx)((*ctx).rom_size - (*ctx).current));
727 if (bytes < 0) {
728 amdfwtool_cleanup(ctx);
729 exit(1);
730 }
731
732 adjust_current_pointer(ctx, bytes, BLOB_ALIGNMENT0x100U);
733 }
734 }
735}
736
737static void output_manifest(int manifest_fd, amd_fw_entry *fw_entry)
738{
739 struct amd_fw_header hdr;
740 int blob_fd;
741 ssize_t bytes;
742
743 blob_fd = open(fw_entry->filename, O_RDONLY00);
744 if (blob_fd < 0) {
745 fprintf(stderrstderr, "Error opening file: %s: %s\n",
746 fw_entry->filename, strerror(errno(*__errno_location ())));
747 return;
748 }
749
750 bytes = read(blob_fd, &hdr, sizeof(hdr));
751 if (bytes != sizeof(hdr)) {
752 close(blob_fd);
753 fprintf(stderrstderr, "Error while reading %s\n", fw_entry->filename);
754 return;
755 }
756
757 dprintf(manifest_fd, "type: 0x%02x ver:%02x.%02x.%02x.%02x\n",
758 fw_entry->type, hdr.version[3], hdr.version[2],
759 hdr.version[1], hdr.version[0]);
760
761 close(blob_fd);
762
763}
764
765static void dump_blob_version(char *manifest_file, amd_fw_entry *fw_table)
766{
767 amd_fw_entry *index;
768 int manifest_fd;
769
770 manifest_fd = open(manifest_file, O_WRONLY01 | O_CREAT0100 | O_TRUNC01000, 0666);
771 if (manifest_fd < 0) {
772 fprintf(stderrstderr, "Error opening file: %s: %s\n",
773 manifest_file, strerror(errno(*__errno_location ())));
774 return;
775 }
776
777 for (index = fw_table; index->type != AMD_FW_INVALID; index++) {
778 if (!(index->filename))
779 continue;
780
781 if (index->generate_manifest == true1)
782 output_manifest(manifest_fd, index);
783 }
784
785 close(manifest_fd);
786}
787
788/* For debugging */
789static void dump_psp_firmwares(amd_fw_entry *fw_table)
790{
791 amd_fw_entry *index;
792
793 printf("PSP firmware components:\n");
794 for (index = fw_table; index->type != AMD_FW_INVALID; index++) {
795 if (index->type == AMD_PSP_FUSE_CHAIN)
796 printf(" %2x: level=%x, subprog=%x, inst=%x\n",
797 index->type, index->level, index->subprog, index->inst);
798 else if (index->filename)
799 printf(" %2x: level=%x, subprog=%x, inst=%x, %s\n",
800 index->type, index->level, index->subprog, index->inst,
801 index->filename);
802 }
803}
804
805static void dump_bdt_firmwares(amd_bios_entry *fw_table)
806{
807 amd_bios_entry *index;
808
809 printf("BIOS Directory Table (BDT) components:\n");
810 for (index = fw_table; index->type != AMD_BIOS_INVALID; index++) {
811 if (index->filename)
812 printf(" %2x: level=%x, %s\n",
813 index->type, index->level, index->filename);
814 }
815}
816
817static void dump_image_addresses(context *ctx)
818{
819 printf("romsig offset:%lx\n", BUFF_TO_RUN(*ctx, ctx->amd_romsig_ptr)((((*ctx)).address_mode) == AMD_ADDR_PHYSICAL ? (0xFFFFFFFF -
(((*ctx))).rom_size + 1) + ((((char *)(ctx->amd_romsig_ptr
) - (*ctx).rom))) : ((((*ctx)).address_mode) == AMD_ADDR_REL_BIOS
? ((((char *)(ctx->amd_romsig_ptr) - (*ctx).rom))) : ((((
*ctx)).address_mode) == AMD_ADDR_REL_TAB ? ((((char *)(ctx->
amd_romsig_ptr) - (*ctx).rom))) - (((*ctx))).current_table : (
(((char *)(ctx->amd_romsig_ptr) - (*ctx).rom))))))
);
820 printf("PSP L1 offset:%lx\n", BUFF_TO_RUN(*ctx, ctx->pspdir)((((*ctx)).address_mode) == AMD_ADDR_PHYSICAL ? (0xFFFFFFFF -
(((*ctx))).rom_size + 1) + ((((char *)(ctx->pspdir) - (*ctx
).rom))) : ((((*ctx)).address_mode) == AMD_ADDR_REL_BIOS ? ((
((char *)(ctx->pspdir) - (*ctx).rom))) : ((((*ctx)).address_mode
) == AMD_ADDR_REL_TAB ? ((((char *)(ctx->pspdir) - (*ctx).
rom))) - (((*ctx))).current_table : ((((char *)(ctx->pspdir
) - (*ctx).rom))))))
);
821 if (ctx->pspdir2 != NULL((void*)0))
822 printf("PSP L2(A) offset:%lx\n", BUFF_TO_RUN(*ctx, ctx->pspdir2)((((*ctx)).address_mode) == AMD_ADDR_PHYSICAL ? (0xFFFFFFFF -
(((*ctx))).rom_size + 1) + ((((char *)(ctx->pspdir2) - (*
ctx).rom))) : ((((*ctx)).address_mode) == AMD_ADDR_REL_BIOS ?
((((char *)(ctx->pspdir2) - (*ctx).rom))) : ((((*ctx)).address_mode
) == AMD_ADDR_REL_TAB ? ((((char *)(ctx->pspdir2) - (*ctx)
.rom))) - (((*ctx))).current_table : ((((char *)(ctx->pspdir2
) - (*ctx).rom))))))
);
823 if (ctx->ish_a_dir != NULL((void*)0))
824 printf("ISHA offset:%lx\n", BUFF_TO_RUN(*ctx, ctx->ish_a_dir)((((*ctx)).address_mode) == AMD_ADDR_PHYSICAL ? (0xFFFFFFFF -
(((*ctx))).rom_size + 1) + ((((char *)(ctx->ish_a_dir) - (
*ctx).rom))) : ((((*ctx)).address_mode) == AMD_ADDR_REL_BIOS ?
((((char *)(ctx->ish_a_dir) - (*ctx).rom))) : ((((*ctx)).
address_mode) == AMD_ADDR_REL_TAB ? ((((char *)(ctx->ish_a_dir
) - (*ctx).rom))) - (((*ctx))).current_table : ((((char *)(ctx
->ish_a_dir) - (*ctx).rom))))))
);
825 if (ctx->ish_b_dir != NULL((void*)0))
826 printf("ISHB offset:%lx\n", BUFF_TO_RUN(*ctx, ctx->ish_b_dir)((((*ctx)).address_mode) == AMD_ADDR_PHYSICAL ? (0xFFFFFFFF -
(((*ctx))).rom_size + 1) + ((((char *)(ctx->ish_b_dir) - (
*ctx).rom))) : ((((*ctx)).address_mode) == AMD_ADDR_REL_BIOS ?
((((char *)(ctx->ish_b_dir) - (*ctx).rom))) : ((((*ctx)).
address_mode) == AMD_ADDR_REL_TAB ? ((((char *)(ctx->ish_b_dir
) - (*ctx).rom))) - (((*ctx))).current_table : ((((char *)(ctx
->ish_b_dir) - (*ctx).rom))))))
);
827 if (ctx->pspdir2_b != NULL((void*)0))
828 printf("PSP L2B offset:%lx\n", BUFF_TO_RUN(*ctx, ctx->pspdir2_b)((((*ctx)).address_mode) == AMD_ADDR_PHYSICAL ? (0xFFFFFFFF -
(((*ctx))).rom_size + 1) + ((((char *)(ctx->pspdir2_b) - (
*ctx).rom))) : ((((*ctx)).address_mode) == AMD_ADDR_REL_BIOS ?
((((char *)(ctx->pspdir2_b) - (*ctx).rom))) : ((((*ctx)).
address_mode) == AMD_ADDR_REL_TAB ? ((((char *)(ctx->pspdir2_b
) - (*ctx).rom))) - (((*ctx))).current_table : ((((char *)(ctx
->pspdir2_b) - (*ctx).rom))))))
);
829 if (ctx->biosdir != NULL((void*)0))
830 printf("BHD offset:%lx\n", BUFF_TO_RUN(*ctx, ctx->biosdir)((((*ctx)).address_mode) == AMD_ADDR_PHYSICAL ? (0xFFFFFFFF -
(((*ctx))).rom_size + 1) + ((((char *)(ctx->biosdir) - (*
ctx).rom))) : ((((*ctx)).address_mode) == AMD_ADDR_REL_BIOS ?
((((char *)(ctx->biosdir) - (*ctx).rom))) : ((((*ctx)).address_mode
) == AMD_ADDR_REL_TAB ? ((((char *)(ctx->biosdir) - (*ctx)
.rom))) - (((*ctx))).current_table : ((((char *)(ctx->biosdir
) - (*ctx).rom))))))
);
831 if (ctx->biosdir2 != NULL((void*)0))
832 printf("BHD L2(A) offset:%lx\n", BUFF_TO_RUN(*ctx, ctx->biosdir2)((((*ctx)).address_mode) == AMD_ADDR_PHYSICAL ? (0xFFFFFFFF -
(((*ctx))).rom_size + 1) + ((((char *)(ctx->biosdir2) - (
*ctx).rom))) : ((((*ctx)).address_mode) == AMD_ADDR_REL_BIOS ?
((((char *)(ctx->biosdir2) - (*ctx).rom))) : ((((*ctx)).address_mode
) == AMD_ADDR_REL_TAB ? ((((char *)(ctx->biosdir2) - (*ctx
).rom))) - (((*ctx))).current_table : ((((char *)(ctx->biosdir2
) - (*ctx).rom))))))
);
833 if (ctx->biosdir2_b != NULL((void*)0))
834 printf("BHD L2B offset:%lx\n", BUFF_TO_RUN(*ctx, ctx->biosdir2_b)((((*ctx)).address_mode) == AMD_ADDR_PHYSICAL ? (0xFFFFFFFF -
(((*ctx))).rom_size + 1) + ((((char *)(ctx->biosdir2_b) -
(*ctx).rom))) : ((((*ctx)).address_mode) == AMD_ADDR_REL_BIOS
? ((((char *)(ctx->biosdir2_b) - (*ctx).rom))) : ((((*ctx
)).address_mode) == AMD_ADDR_REL_TAB ? ((((char *)(ctx->biosdir2_b
) - (*ctx).rom))) - (((*ctx))).current_table : ((((char *)(ctx
->biosdir2_b) - (*ctx).rom))))))
);
835 if (ctx->psp_combo_dir != NULL((void*)0))
836 printf("PSP combo offset:%lx\n", BUFF_TO_RUN(*ctx, ctx->psp_combo_dir)((((*ctx)).address_mode) == AMD_ADDR_PHYSICAL ? (0xFFFFFFFF -
(((*ctx))).rom_size + 1) + ((((char *)(ctx->psp_combo_dir
) - (*ctx).rom))) : ((((*ctx)).address_mode) == AMD_ADDR_REL_BIOS
? ((((char *)(ctx->psp_combo_dir) - (*ctx).rom))) : ((((*
ctx)).address_mode) == AMD_ADDR_REL_TAB ? ((((char *)(ctx->
psp_combo_dir) - (*ctx).rom))) - (((*ctx))).current_table : (
(((char *)(ctx->psp_combo_dir) - (*ctx).rom))))))
);
837 if (ctx->bhd_combo_dir != NULL((void*)0))
838 printf("BHD combo offset:%lx\n", BUFF_TO_RUN(*ctx, ctx->bhd_combo_dir)((((*ctx)).address_mode) == AMD_ADDR_PHYSICAL ? (0xFFFFFFFF -
(((*ctx))).rom_size + 1) + ((((char *)(ctx->bhd_combo_dir
) - (*ctx).rom))) : ((((*ctx)).address_mode) == AMD_ADDR_REL_BIOS
? ((((char *)(ctx->bhd_combo_dir) - (*ctx).rom))) : ((((*
ctx)).address_mode) == AMD_ADDR_REL_TAB ? ((((char *)(ctx->
bhd_combo_dir) - (*ctx).rom))) - (((*ctx))).current_table : (
(((char *)(ctx->bhd_combo_dir) - (*ctx).rom))))))
);
839}
840
841static void integrate_psp_ab(context *ctx, psp_directory_table *pspdir,
842 psp_directory_table *pspdir2, ish_directory_table *ish,
843 amd_fw_type ab, enum platform soc_id)
844{
845 uint32_t count;
846 uint32_t current_table_save;
847
848 current_table_save = ctx->current_table;
849 ctx->current_table = BUFF_TO_RUN_MODE(*ctx, pspdir, AMD_ADDR_REL_BIOS)(((*ctx).address_mode < (AMD_ADDR_REL_BIOS) ? (*ctx).address_mode
: (AMD_ADDR_REL_BIOS)) == AMD_ADDR_PHYSICAL ? (0xFFFFFFFF - (
(*ctx)).rom_size + 1) + (((char *)(pspdir) - (*ctx).rom)) : (
((*ctx).address_mode < (AMD_ADDR_REL_BIOS) ? (*ctx).address_mode
: (AMD_ADDR_REL_BIOS)) == AMD_ADDR_REL_BIOS ? (((char *)(pspdir
) - (*ctx).rom)) : (((*ctx).address_mode < (AMD_ADDR_REL_BIOS
) ? (*ctx).address_mode : (AMD_ADDR_REL_BIOS)) == AMD_ADDR_REL_TAB
? (((char *)(pspdir) - (*ctx).rom)) - ((*ctx)).current_table
: (((char *)(pspdir) - (*ctx).rom)))))
;
850 count = pspdir->header.num_entries;
851 assert_fw_entry(count, MAX_PSP_ENTRIES0xff, ctx);
852 pspdir->entries[count].type = (uint8_t)ab;
853 pspdir->entries[count].subprog = 0;
854 pspdir->entries[count].rsvd = 0;
855 if (ish != NULL((void*)0)) {
856 ish->pl2_location = BUFF_TO_RUN_MODE(*ctx, pspdir2, AMD_ADDR_REL_BIOS)(((*ctx).address_mode < (AMD_ADDR_REL_BIOS) ? (*ctx).address_mode
: (AMD_ADDR_REL_BIOS)) == AMD_ADDR_PHYSICAL ? (0xFFFFFFFF - (
(*ctx)).rom_size + 1) + (((char *)(pspdir2) - (*ctx).rom)) : (
((*ctx).address_mode < (AMD_ADDR_REL_BIOS) ? (*ctx).address_mode
: (AMD_ADDR_REL_BIOS)) == AMD_ADDR_REL_BIOS ? (((char *)(pspdir2
) - (*ctx).rom)) : (((*ctx).address_mode < (AMD_ADDR_REL_BIOS
) ? (*ctx).address_mode : (AMD_ADDR_REL_BIOS)) == AMD_ADDR_REL_TAB
? (((char *)(pspdir2) - (*ctx).rom)) - ((*ctx)).current_table
: (((char *)(pspdir2) - (*ctx).rom)))))
;
857 ish->boot_priority = ab == AMD_FW_RECOVERYAB_A ? 0xFFFFFFFF : 1;
858 ish->update_retry_count = 2;
859 ish->glitch_retry_count = 0;
860 ish->psp_id = get_psp_id(soc_id);
861 ish->checksum = fletcher32(&ish->boot_priority,
862 sizeof(ish_directory_table) - sizeof(uint32_t));
863 pspdir->entries[count].addr =
864 BUFF_TO_RUN_MODE(*ctx, ish, AMD_ADDR_REL_BIOS)(((*ctx).address_mode < (AMD_ADDR_REL_BIOS) ? (*ctx).address_mode
: (AMD_ADDR_REL_BIOS)) == AMD_ADDR_PHYSICAL ? (0xFFFFFFFF - (
(*ctx)).rom_size + 1) + (((char *)(ish) - (*ctx).rom)) : (((*
ctx).address_mode < (AMD_ADDR_REL_BIOS) ? (*ctx).address_mode
: (AMD_ADDR_REL_BIOS)) == AMD_ADDR_REL_BIOS ? (((char *)(ish
) - (*ctx).rom)) : (((*ctx).address_mode < (AMD_ADDR_REL_BIOS
) ? (*ctx).address_mode : (AMD_ADDR_REL_BIOS)) == AMD_ADDR_REL_TAB
? (((char *)(ish) - (*ctx).rom)) - ((*ctx)).current_table : (
((char *)(ish) - (*ctx).rom)))))
;
865 pspdir->entries[count].address_mode =
866 SET_ADDR_MODE(pspdir, AMD_ADDR_REL_BIOS)((pspdir)->header.additional_info_fields.address_mode == AMD_ADDR_REL_TAB
? (AMD_ADDR_REL_BIOS) : 0)
;
867 pspdir->entries[count].size = TABLE_ALIGNMENT0x1000U;
868 } else {
869 pspdir->entries[count].addr =
870 BUFF_TO_RUN_MODE(*ctx, pspdir2, AMD_ADDR_REL_BIOS)(((*ctx).address_mode < (AMD_ADDR_REL_BIOS) ? (*ctx).address_mode
: (AMD_ADDR_REL_BIOS)) == AMD_ADDR_PHYSICAL ? (0xFFFFFFFF - (
(*ctx)).rom_size + 1) + (((char *)(pspdir2) - (*ctx).rom)) : (
((*ctx).address_mode < (AMD_ADDR_REL_BIOS) ? (*ctx).address_mode
: (AMD_ADDR_REL_BIOS)) == AMD_ADDR_REL_BIOS ? (((char *)(pspdir2
) - (*ctx).rom)) : (((*ctx).address_mode < (AMD_ADDR_REL_BIOS
) ? (*ctx).address_mode : (AMD_ADDR_REL_BIOS)) == AMD_ADDR_REL_TAB
? (((char *)(pspdir2) - (*ctx).rom)) - ((*ctx)).current_table
: (((char *)(pspdir2) - (*ctx).rom)))))
;
871 pspdir->entries[count].address_mode =
872 SET_ADDR_MODE(pspdir, AMD_ADDR_REL_BIOS)((pspdir)->header.additional_info_fields.address_mode == AMD_ADDR_REL_TAB
? (AMD_ADDR_REL_BIOS) : 0)
;
873 pspdir->entries[count].size = _MAX(TABLE_ALIGNMENT,(((0x1000U) > (pspdir2->header.num_entries * sizeof(psp_directory_entry
) + sizeof(psp_directory_header))) ? (0x1000U) : (pspdir2->
header.num_entries * sizeof(psp_directory_entry) + sizeof(psp_directory_header
)))
874 pspdir2->header.num_entries *(((0x1000U) > (pspdir2->header.num_entries * sizeof(psp_directory_entry
) + sizeof(psp_directory_header))) ? (0x1000U) : (pspdir2->
header.num_entries * sizeof(psp_directory_entry) + sizeof(psp_directory_header
)))
875 sizeof(psp_directory_entry) +(((0x1000U) > (pspdir2->header.num_entries * sizeof(psp_directory_entry
) + sizeof(psp_directory_header))) ? (0x1000U) : (pspdir2->
header.num_entries * sizeof(psp_directory_entry) + sizeof(psp_directory_header
)))
876 sizeof(psp_directory_header))(((0x1000U) > (pspdir2->header.num_entries * sizeof(psp_directory_entry
) + sizeof(psp_directory_header))) ? (0x1000U) : (pspdir2->
header.num_entries * sizeof(psp_directory_entry) + sizeof(psp_directory_header
)))
;
877 }
878
879 count++;
880 fill_dir_header(pspdir, count, ctx);
881 ctx->current_table = current_table_save;
882}
883
884static void integrate_psp_levels(context *ctx,
885 amd_cb_config *cb_config)
886{
887 uint32_t current_table_save;
888 bool_Bool recovery_ab = cb_config->recovery_ab;
889 unsigned int count;
890 psp_directory_table *pspdir, *pspdir2, *pspdir2_b;
891 bool_Bool use_only_a = (cb_config->soc_id == PLATFORM_PHOENIX); /* TODO: b:285390041 */
892
893 pspdir = ctx->pspdir;
894 pspdir2 = ctx->pspdir2;
895 pspdir2_b = ctx->pspdir2_b;
896 count = pspdir->header.num_entries;
897
898 current_table_save = ctx->current_table;
899 ctx->current_table = BUFF_TO_RUN_MODE(*ctx, pspdir, AMD_ADDR_REL_BIOS)(((*ctx).address_mode < (AMD_ADDR_REL_BIOS) ? (*ctx).address_mode
: (AMD_ADDR_REL_BIOS)) == AMD_ADDR_PHYSICAL ? (0xFFFFFFFF - (
(*ctx)).rom_size + 1) + (((char *)(pspdir) - (*ctx).rom)) : (
((*ctx).address_mode < (AMD_ADDR_REL_BIOS) ? (*ctx).address_mode
: (AMD_ADDR_REL_BIOS)) == AMD_ADDR_REL_BIOS ? (((char *)(pspdir
) - (*ctx).rom)) : (((*ctx).address_mode < (AMD_ADDR_REL_BIOS
) ? (*ctx).address_mode : (AMD_ADDR_REL_BIOS)) == AMD_ADDR_REL_TAB
? (((char *)(pspdir) - (*ctx).rom)) - ((*ctx)).current_table
: (((char *)(pspdir) - (*ctx).rom)))))
;
900 if (recovery_ab && (pspdir2 != NULL((void*)0))) {
901 if (cb_config->need_ish) { /* Need ISH */
902 ctx->ish_a_dir = new_ish_dir(ctx);
903 if (pspdir2_b != NULL((void*)0))
904 ctx->ish_b_dir = new_ish_dir(ctx);
905 }
906 integrate_psp_ab(ctx, pspdir, pspdir2, ctx->ish_a_dir,
907 AMD_FW_RECOVERYAB_A, cb_config->soc_id);
908 if (pspdir2_b != NULL((void*)0))
909 integrate_psp_ab(ctx, pspdir, pspdir2_b, ctx->ish_b_dir,
910 use_only_a ? AMD_FW_RECOVERYAB_A : AMD_FW_RECOVERYAB_B,
911 cb_config->soc_id);
912 else
913 integrate_psp_ab(ctx, pspdir, pspdir2, ctx->ish_a_dir,
914 use_only_a ? AMD_FW_RECOVERYAB_A : AMD_FW_RECOVERYAB_B,
915 cb_config->soc_id);
916
917 } else if (pspdir2 != NULL((void*)0)) {
918 assert_fw_entry(count, MAX_PSP_ENTRIES0xff, ctx);
919 pspdir->entries[count].type = AMD_FW_L2_PTR;
920 pspdir->entries[count].subprog = 0;
921 pspdir->entries[count].rsvd = 0;
922 pspdir->entries[count].size = sizeof(pspdir2->header)
923 + pspdir2->header.num_entries
924 * sizeof(psp_directory_entry);
925
926 pspdir->entries[count].addr =
927 BUFF_TO_RUN_MODE(*ctx, pspdir2, AMD_ADDR_REL_BIOS)(((*ctx).address_mode < (AMD_ADDR_REL_BIOS) ? (*ctx).address_mode
: (AMD_ADDR_REL_BIOS)) == AMD_ADDR_PHYSICAL ? (0xFFFFFFFF - (
(*ctx)).rom_size + 1) + (((char *)(pspdir2) - (*ctx).rom)) : (
((*ctx).address_mode < (AMD_ADDR_REL_BIOS) ? (*ctx).address_mode
: (AMD_ADDR_REL_BIOS)) == AMD_ADDR_REL_BIOS ? (((char *)(pspdir2
) - (*ctx).rom)) : (((*ctx).address_mode < (AMD_ADDR_REL_BIOS
) ? (*ctx).address_mode : (AMD_ADDR_REL_BIOS)) == AMD_ADDR_REL_TAB
? (((char *)(pspdir2) - (*ctx).rom)) - ((*ctx)).current_table
: (((char *)(pspdir2) - (*ctx).rom)))))
;
928 pspdir->entries[count].address_mode =
929 SET_ADDR_MODE(pspdir, AMD_ADDR_REL_BIOS)((pspdir)->header.additional_info_fields.address_mode == AMD_ADDR_REL_TAB
? (AMD_ADDR_REL_BIOS) : 0)
;
930 count++;
931 fill_dir_header(pspdir, count, ctx);
932 }
933 ctx->current_table = current_table_save;
934}
935
936static void integrate_psp_firmwares(context *ctx,
937 amd_fw_entry *fw_table,
938 uint32_t cookie,
939 amd_cb_config *cb_config)
940{
941 ssize_t bytes;
942 unsigned int i, count;
943 int level;
944 uint32_t size;
945 psp_directory_table *pspdir;
946 uint64_t addr;
947 uint32_t current_table_save;
948 bool_Bool recovery_ab = cb_config->recovery_ab;
949
950 /* This function can create a primary table, a secondary table, or a
951 * flattened table which contains all applicable types. These if-else
952 * statements infer what the caller intended. If a 2nd-level cookie
953 * is passed, clearly a 2nd-level table is intended. However, a
954 * 1st-level cookie may indicate level 1 or flattened.
955 */
956 pspdir = new_psp_dir(ctx, cb_config->multi_level, cookie);
957
958 if (cookie == PSP_COOKIE0x50535024)
959 ctx->pspdir = pspdir;
960 else if (cookie == PSPL2_COOKIE0x324c5024) {
961 if (ctx->pspdir2 == NULL((void*)0))
962 ctx->pspdir2 = pspdir;
963 else if (ctx->pspdir2_b == NULL((void*)0))
964 ctx->pspdir2_b = pspdir;
965 }
966
967 if (!cb_config->multi_level)
968 level = PSP_BOTH((1 << 0) | (1 << 1));
969 else if (cookie == PSPL2_COOKIE0x324c5024)
970 level = PSP_LVL2(1 << 1);
971 else if (cookie == PSP_COOKIE0x50535024)
972 level = PSP_LVL1(1 << 0);
973 else
974 level = PSP_BOTH((1 << 0) | (1 << 1));
975
976 if (recovery_ab) {
977 if (cookie == PSPL2_COOKIE0x324c5024)
978 level = PSP_LVL2_AB(1 << 3);
979 else if (cookie == PSP_COOKIE0x50535024)
980 level = PSP_LVL1_AB(1 << 2);
981 else
982 level = PSP_BOTH_AB((1 << 2) | (1 << 3));
983 }
984 current_table_save = ctx->current_table;
985 ctx->current_table = BUFF_TO_RUN_MODE(*ctx, pspdir, AMD_ADDR_REL_BIOS)(((*ctx).address_mode < (AMD_ADDR_REL_BIOS) ? (*ctx).address_mode
: (AMD_ADDR_REL_BIOS)) == AMD_ADDR_PHYSICAL ? (0xFFFFFFFF - (
(*ctx)).rom_size + 1) + (((char *)(pspdir) - (*ctx).rom)) : (
((*ctx).address_mode < (AMD_ADDR_REL_BIOS) ? (*ctx).address_mode
: (AMD_ADDR_REL_BIOS)) == AMD_ADDR_REL_BIOS ? (((char *)(pspdir
) - (*ctx).rom)) : (((*ctx).address_mode < (AMD_ADDR_REL_BIOS
) ? (*ctx).address_mode : (AMD_ADDR_REL_BIOS)) == AMD_ADDR_REL_TAB
? (((char *)(pspdir) - (*ctx).rom)) - ((*ctx)).current_table
: (((char *)(pspdir) - (*ctx).rom)))))
;
986 adjust_current_pointer(ctx, 0, TABLE_ALIGNMENT0x1000U);
987
988 for (i = 0, count = 0; fw_table[i].type != AMD_FW_INVALID; i++) {
989 if (!(fw_table[i].level & level))
990 continue;
991
992 assert_fw_entry(count, MAX_PSP_ENTRIES0xff, ctx);
993
994 if (fw_table[i].type == AMD_TOKEN_UNLOCK) {
995 if (!fw_table[i].other)
996 continue;
997 adjust_current_pointer(ctx, 0, ERASE_ALIGNMENT0x1000U);
998 pspdir->entries[count].type = fw_table[i].type;
999 pspdir->entries[count].size = 4096; /* TODO: doc? */
1000 pspdir->entries[count].addr = RUN_CURRENT(*ctx)((((*ctx)).address_mode) == AMD_ADDR_PHYSICAL ? (0xFFFFFFFF -
(((*ctx))).rom_size + 1) + (((*ctx).current)) : ((((*ctx)).address_mode
) == AMD_ADDR_REL_BIOS ? (((*ctx).current)) : ((((*ctx)).address_mode
) == AMD_ADDR_REL_TAB ? (((*ctx).current)) - (((*ctx))).current_table
: (((*ctx).current)))))
;
1001 pspdir->entries[count].address_mode = SET_ADDR_MODE_BY_TABLE(pspdir)(((pspdir))->header.additional_info_fields.address_mode ==
AMD_ADDR_REL_TAB ? ((pspdir)->header.additional_info_fields
.address_mode) : 0)
;
1002 pspdir->entries[count].subprog = fw_table[i].subprog;
1003 pspdir->entries[count].rsvd = 0;
1004 adjust_current_pointer(ctx, 4096, 0x100U);
1005 count++;
1006 } else if (fw_table[i].type == AMD_PSP_FUSE_CHAIN) {
1007 pspdir->entries[count].type = fw_table[i].type;
1008 pspdir->entries[count].subprog = fw_table[i].subprog;
1009 pspdir->entries[count].rsvd = 0;
1010 pspdir->entries[count].size = 0xFFFFFFFF;
1011 pspdir->entries[count].addr = fw_table[i].other;
1012 pspdir->entries[count].address_mode = 0;
1013 count++;
1014 } else if (fw_table[i].type == AMD_FW_PSP_NVRAM) {
1015 if (fw_table[i].filename == NULL((void*)0)) {
1016 if (fw_table[i].size == 0)
1017 continue;
1018 size = fw_table[i].size;
1019 addr = fw_table[i].dest;
1020 if (addr != ALIGN_UP(addr, ERASE_ALIGNMENT)((((addr))+((__typeof__((addr)))((0x1000U))-1UL))&~((__typeof__
((addr)))((0x1000U))-1UL))
) {
1021 fprintf(stderrstderr,
1022 "Error: PSP NVRAM section not aligned with erase block size.\n\n");
1023 amdfwtool_cleanup(ctx);
1024 exit(1);
1025 }
1026 } else {
1027 adjust_current_pointer(ctx, 0, ERASE_ALIGNMENT0x1000U);
1028 bytes = copy_blob(BUFF_CURRENT(*ctx)((void *)(((*ctx)).rom + ((*ctx).current))),
1029 fw_table[i].filename, BUFF_ROOM(*ctx)((*ctx).rom_size - (*ctx).current));
1030 if (bytes <= 0) {
1031 amdfwtool_cleanup(ctx);
1032 exit(1);
1033 }
1034
1035 size = ALIGN_UP(bytes, ERASE_ALIGNMENT)((((bytes))+((__typeof__((bytes)))((0x1000U))-1UL))&~((__typeof__
((bytes)))((0x1000U))-1UL))
;
1036 addr = RUN_CURRENT(*ctx)((((*ctx)).address_mode) == AMD_ADDR_PHYSICAL ? (0xFFFFFFFF -
(((*ctx))).rom_size + 1) + (((*ctx).current)) : ((((*ctx)).address_mode
) == AMD_ADDR_REL_BIOS ? (((*ctx).current)) : ((((*ctx)).address_mode
) == AMD_ADDR_REL_TAB ? (((*ctx).current)) - (((*ctx))).current_table
: (((*ctx).current)))))
;
1037 adjust_current_pointer(ctx, bytes, BLOB_ERASE_ALIGNMENT(((0x100U) > (0x1000U)) ? (0x100U) : (0x1000U)));
1038 }
1039
1040 pspdir->entries[count].type = fw_table[i].type;
1041 pspdir->entries[count].subprog = fw_table[i].subprog;
1042 pspdir->entries[count].rsvd = 0;
1043 pspdir->entries[count].size = size;
1044 pspdir->entries[count].addr = addr;
1045
1046 pspdir->entries[count].address_mode =
1047 SET_ADDR_MODE(pspdir, AMD_ADDR_REL_BIOS)((pspdir)->header.additional_info_fields.address_mode == AMD_ADDR_REL_TAB
? (AMD_ADDR_REL_BIOS) : 0)
;
1048
1049 count++;
1050 } else if (fw_table[i].filename != NULL((void*)0)) {
1051 if (fw_table[i].addr_signed) {
1052 pspdir->entries[count].addr =
1053 RUN_OFFSET(*ctx, fw_table[i].addr_signed)(((*ctx).address_mode) == AMD_ADDR_PHYSICAL ? (0xFFFFFFFF - (
(*ctx)).rom_size + 1) + ((fw_table[i].addr_signed)) : (((*ctx
).address_mode) == AMD_ADDR_REL_BIOS ? ((fw_table[i].addr_signed
)) : (((*ctx).address_mode) == AMD_ADDR_REL_TAB ? ((fw_table[
i].addr_signed)) - ((*ctx)).current_table : ((fw_table[i].addr_signed
)))))
;
1054 pspdir->entries[count].address_mode =
1055 SET_ADDR_MODE_BY_TABLE(pspdir)(((pspdir))->header.additional_info_fields.address_mode ==
AMD_ADDR_REL_TAB ? ((pspdir)->header.additional_info_fields
.address_mode) : 0)
;
1056 bytes = fw_table[i].file_size;
1057 } else {
1058 bytes = copy_blob(BUFF_CURRENT(*ctx)((void *)(((*ctx)).rom + ((*ctx).current))),
1059 fw_table[i].filename, BUFF_ROOM(*ctx)((*ctx).rom_size - (*ctx).current));
1060 if (bytes < 0) {
1061 amdfwtool_cleanup(ctx);
1062 exit(1);
1063 }
1064 pspdir->entries[count].addr = RUN_CURRENT(*ctx)((((*ctx)).address_mode) == AMD_ADDR_PHYSICAL ? (0xFFFFFFFF -
(((*ctx))).rom_size + 1) + (((*ctx).current)) : ((((*ctx)).address_mode
) == AMD_ADDR_REL_BIOS ? (((*ctx).current)) : ((((*ctx)).address_mode
) == AMD_ADDR_REL_TAB ? (((*ctx).current)) - (((*ctx))).current_table
: (((*ctx).current)))))
;
1065 pspdir->entries[count].address_mode =
1066 SET_ADDR_MODE_BY_TABLE(pspdir)(((pspdir))->header.additional_info_fields.address_mode ==
AMD_ADDR_REL_TAB ? ((pspdir)->header.additional_info_fields
.address_mode) : 0)
;
1067 adjust_current_pointer(ctx, bytes, BLOB_ALIGNMENT0x100U);
1068 }
1069
1070 pspdir->entries[count].type = fw_table[i].type;
1071 pspdir->entries[count].subprog = fw_table[i].subprog;
1072 pspdir->entries[count].rsvd = 0;
1073 pspdir->entries[count].inst = fw_table[i].inst;
1074 pspdir->entries[count].size = (uint32_t)bytes;
1075
1076 count++;
1077 } else {
1078 /* This APU doesn't have this firmware. */
1079 }
1080 }
1081
1082 fill_dir_header(pspdir, count, ctx);
1083 ctx->current_table = current_table_save;
1084}
1085
1086static void add_psp_firmware_entry(context *ctx,
1087 psp_directory_table *pspdir,
1088 void *table, amd_fw_type type, uint32_t size)
1089{
1090 uint32_t count = pspdir->header.num_entries;
1091 uint32_t index;
1092 uint32_t current_table_save;
1093
1094 current_table_save = ctx->current_table;
1095 ctx->current_table = BUFF_TO_RUN_MODE(*ctx, pspdir, AMD_ADDR_REL_BIOS)(((*ctx).address_mode < (AMD_ADDR_REL_BIOS) ? (*ctx).address_mode
: (AMD_ADDR_REL_BIOS)) == AMD_ADDR_PHYSICAL ? (0xFFFFFFFF - (
(*ctx)).rom_size + 1) + (((char *)(pspdir) - (*ctx).rom)) : (
((*ctx).address_mode < (AMD_ADDR_REL_BIOS) ? (*ctx).address_mode
: (AMD_ADDR_REL_BIOS)) == AMD_ADDR_REL_BIOS ? (((char *)(pspdir
) - (*ctx).rom)) : (((*ctx).address_mode < (AMD_ADDR_REL_BIOS
) ? (*ctx).address_mode : (AMD_ADDR_REL_BIOS)) == AMD_ADDR_REL_TAB
? (((char *)(pspdir) - (*ctx).rom)) - ((*ctx)).current_table
: (((char *)(pspdir) - (*ctx).rom)))))
;
1096
1097 /* If there is an entry of "type", replace it. */
1098 for (index = 0; index < count; index++) {
1099 if (pspdir->entries[index].type == (uint8_t)type)
1100 break;
1101 }
1102
1103 assert_fw_entry(count, MAX_PSP_ENTRIES0xff, ctx);
1104 pspdir->entries[index].type = (uint8_t)type;
1105 pspdir->entries[index].subprog = 0;
1106 pspdir->entries[index].rsvd = 0;
1107 pspdir->entries[index].addr = BUFF_TO_RUN(*ctx, table)((((*ctx)).address_mode) == AMD_ADDR_PHYSICAL ? (0xFFFFFFFF -
(((*ctx))).rom_size + 1) + ((((char *)(table) - (*ctx).rom))
) : ((((*ctx)).address_mode) == AMD_ADDR_REL_BIOS ? ((((char *
)(table) - (*ctx).rom))) : ((((*ctx)).address_mode) == AMD_ADDR_REL_TAB
? ((((char *)(table) - (*ctx).rom))) - (((*ctx))).current_table
: ((((char *)(table) - (*ctx).rom))))))
;
1108 pspdir->entries[index].address_mode = SET_ADDR_MODE_BY_TABLE(pspdir)(((pspdir))->header.additional_info_fields.address_mode ==
AMD_ADDR_REL_TAB ? ((pspdir)->header.additional_info_fields
.address_mode) : 0)
;
1109 pspdir->entries[index].size = size;
1110 if (index == count)
1111 count++;
1112
1113 fill_dir_header(pspdir, count, ctx);
1114 ctx->current_table = current_table_save;
1115}
1116
1117static void *new_bios_dir(context *ctx, bool_Bool multi, uint32_t cookie)
1118{
1119 void *ptr;
1120
1121 /*
1122 * Force both onto boundary when multi. Primary table is after
1123 * updatable table, so alignment ensures primary can stay intact
1124 * if secondary is reprogrammed.
1125 */
1126 if (multi)
1127 adjust_current_pointer(ctx, 0, TABLE_ERASE_ALIGNMENT(((0x1000U) > (0x1000U)) ? (0x1000U) : (0x1000U)));
1128 else
1129 adjust_current_pointer(ctx, 0, TABLE_ALIGNMENT0x1000U);
1130 ptr = BUFF_CURRENT(*ctx)((void *)(((*ctx)).rom + ((*ctx).current)));
1131 ((bios_directory_hdr *) ptr)->cookie = cookie;
1132 ((bios_directory_hdr *) ptr)->additional_info = 0;
1133 ((bios_directory_hdr *) ptr)->additional_info_fields.address_mode = ctx->address_mode;
1134 adjust_current_pointer(ctx,
1135 sizeof(bios_directory_hdr) + MAX_BIOS_ENTRIES0x2f * sizeof(bios_directory_entry),
1136 1);
1137 return ptr;
1138}
1139
1140static int locate_bdt2_bios(bios_directory_table *level2,
1141 uint64_t *source, uint32_t *size)
1142{
1143 uint32_t i;
1144
1145 *source = 0;
1146 *size = 0;
1147 if (!level2)
1148 return 0;
1149
1150 for (i = 0 ; i < level2->header.num_entries ; i++) {
1151 if (level2->entries[i].type == AMD_BIOS_BIN) {
1152 *source = level2->entries[i].source;
1153 *size = level2->entries[i].size;
1154 return 1;
1155 }
1156 }
1157 return 0;
1158}
1159
1160static int have_bios_tables(amd_bios_entry *table)
1161{
1162 int i;
1163
1164 for (i = 0 ; table[i].type != AMD_BIOS_INVALID; i++) {
1165 if (table[i].level & BDT_LVL1(1 << 0) && table[i].filename)
1166 return 1;
1167 }
1168 return 0;
1169}
1170
1171int find_bios_entry(amd_bios_type type)
1172{
1173 int i;
1174
1175 for (i = 0; amd_bios_table[i].type != AMD_BIOS_INVALID; i++) {
1176 if (amd_bios_table[i].type == type)
1177 return i;
1178 }
1179 return -1;
1180}
1181
1182static void add_bios_apcb_bk_entry(bios_directory_table *biosdir, unsigned int idx,
1183 int inst, uint32_t size, uint64_t source)
1184{
1185 int i;
1186
1187 for (i = 0; amd_bios_table[i].type != AMD_BIOS_INVALID; i++) {
1188 if (amd_bios_table[i].type == AMD_BIOS_APCB_BK &&
1189 amd_bios_table[i].inst == inst)
1190 break;
1191 }
1192
1193 if (amd_bios_table[i].type != AMD_BIOS_APCB_BK)
1194 return;
1195
1196 biosdir->entries[idx].type = amd_bios_table[i].type;
1197 biosdir->entries[idx].region_type = amd_bios_table[i].region_type;
1198 biosdir->entries[idx].dest = amd_bios_table[i].dest ?
1199 amd_bios_table[i].dest : (uint64_t)-1;
1200 biosdir->entries[idx].reset = amd_bios_table[i].reset;
1201 biosdir->entries[idx].copy = amd_bios_table[i].copy;
1202 biosdir->entries[idx].ro = amd_bios_table[i].ro;
1203 biosdir->entries[idx].compressed = amd_bios_table[i].zlib;
1204 biosdir->entries[idx].inst = amd_bios_table[i].inst;
1205 biosdir->entries[idx].subprog = amd_bios_table[i].subpr;
1206 biosdir->entries[idx].size = size;
1207 biosdir->entries[idx].source = source;
1208 biosdir->entries[idx].address_mode = SET_ADDR_MODE_BY_TABLE(biosdir)(((biosdir))->header.additional_info_fields.address_mode ==
AMD_ADDR_REL_TAB ? ((biosdir)->header.additional_info_fields
.address_mode) : 0)
;
1209}
1210
1211static void integrate_bios_levels(context *ctx, amd_cb_config *cb_config)
1212{
1213 unsigned int count;
1214 uint32_t current_table_save;
1215
1216 if (cb_config->recovery_ab) {
1217 add_psp_firmware_entry(ctx, ctx->pspdir2, ctx->biosdir2,
1218 AMD_FW_BIOS_TABLE, TABLE_ALIGNMENT0x1000U);
1219 if (ctx->pspdir2_b != NULL((void*)0))
1220 add_psp_firmware_entry(ctx, ctx->pspdir2_b,
1221 ctx->biosdir2_b, AMD_FW_BIOS_TABLE,
1222 TABLE_ALIGNMENT0x1000U);
1223 } else if (ctx->biosdir2) {
1224 current_table_save = ctx->current_table;
1225 ctx->current_table = BUFF_TO_RUN_MODE(*ctx, ctx->biosdir, AMD_ADDR_REL_BIOS)(((*ctx).address_mode < (AMD_ADDR_REL_BIOS) ? (*ctx).address_mode
: (AMD_ADDR_REL_BIOS)) == AMD_ADDR_PHYSICAL ? (0xFFFFFFFF - (
(*ctx)).rom_size + 1) + (((char *)(ctx->biosdir) - (*ctx).
rom)) : (((*ctx).address_mode < (AMD_ADDR_REL_BIOS) ? (*ctx
).address_mode : (AMD_ADDR_REL_BIOS)) == AMD_ADDR_REL_BIOS ? (
((char *)(ctx->biosdir) - (*ctx).rom)) : (((*ctx).address_mode
< (AMD_ADDR_REL_BIOS) ? (*ctx).address_mode : (AMD_ADDR_REL_BIOS
)) == AMD_ADDR_REL_TAB ? (((char *)(ctx->biosdir) - (*ctx)
.rom)) - ((*ctx)).current_table : (((char *)(ctx->biosdir)
- (*ctx).rom)))))
;
1226 count = ctx->biosdir->header.num_entries;
1227 assert_fw_entry(count, MAX_BIOS_ENTRIES0x2f, ctx);
1228 ctx->biosdir->entries[count].type = AMD_BIOS_L2_PTR;
1229 ctx->biosdir->entries[count].region_type = 0;
1230 ctx->biosdir->entries[count].size =
1231 + MAX_BIOS_ENTRIES0x2f
1232 * sizeof(bios_directory_entry);
1233 ctx->biosdir->entries[count].source =
1234 BUFF_TO_RUN(*ctx, ctx->biosdir2)((((*ctx)).address_mode) == AMD_ADDR_PHYSICAL ? (0xFFFFFFFF -
(((*ctx))).rom_size + 1) + ((((char *)(ctx->biosdir2) - (
*ctx).rom))) : ((((*ctx)).address_mode) == AMD_ADDR_REL_BIOS ?
((((char *)(ctx->biosdir2) - (*ctx).rom))) : ((((*ctx)).address_mode
) == AMD_ADDR_REL_TAB ? ((((char *)(ctx->biosdir2) - (*ctx
).rom))) - (((*ctx))).current_table : ((((char *)(ctx->biosdir2
) - (*ctx).rom))))))
;
1235 ctx->biosdir->entries[count].address_mode =
1236 SET_ADDR_MODE(ctx->biosdir, AMD_ADDR_REL_BIOS)((ctx->biosdir)->header.additional_info_fields.address_mode
== AMD_ADDR_REL_TAB ? (AMD_ADDR_REL_BIOS) : 0)
;
1237 ctx->biosdir->entries[count].subprog = 0;
1238 ctx->biosdir->entries[count].inst = 0;
1239 ctx->biosdir->entries[count].copy = 0;
1240 ctx->biosdir->entries[count].compressed = 0;
1241 ctx->biosdir->entries[count].dest = -1;
1242 ctx->biosdir->entries[count].reset = 0;
1243 ctx->biosdir->entries[count].ro = 0;
1244 count++;
1245 fill_dir_header(ctx->biosdir, count, ctx);
1246 ctx->current_table = current_table_save;
1247 }
1248}
1249static void integrate_bios_firmwares(context *ctx,
1250 amd_bios_entry *fw_table,
1251 uint32_t cookie,
1252 amd_cb_config *cb_config)
1253{
1254 ssize_t bytes;
1255 unsigned int i, count;
1256 int level;
1257 int apob_idx;
1258 uint32_t size;
1259 uint64_t source;
1260 uint32_t current_table_save;
1261 bios_directory_table *biosdir;
1262
1263 biosdir = new_bios_dir(ctx, cb_config->multi_level, cookie);
1264
1265 if (cookie == BHD_COOKIE0x44484224)
1266 ctx->biosdir = biosdir;
1267 else if (cookie == BHDL2_COOKIE0x324c4224) {
1268 if (ctx->biosdir2 == NULL((void*)0))
1269 ctx->biosdir2 = biosdir;
1270 else if (ctx->biosdir2_b == NULL((void*)0))
1271 ctx->biosdir2_b = biosdir;
1272 }
1273
1274 /* This function can create a primary table, a secondary table, or a
1275 * flattened table which contains all applicable types. These if-else
1276 * statements infer what the caller intended. If a 2nd-level cookie
1277 * is passed, clearly a 2nd-level table is intended. However, a
1278 * 1st-level cookie may indicate level 1 or flattened.
1279 */
1280 if (!cb_config->multi_level)
1281 level = BDT_BOTH((1 << 0) | (1 << 1));
1282 else if (cookie == BHDL2_COOKIE0x324c4224)
1283 level = BDT_LVL2(1 << 1);
1284 else if (cookie == BHD_COOKIE0x44484224)
1285 level = BDT_LVL1(1 << 0);
1286 else
1287 level = BDT_BOTH((1 << 0) | (1 << 1));
1288
1289 current_table_save = ctx->current_table;
1290 ctx->current_table = BUFF_TO_RUN_MODE(*ctx, biosdir, AMD_ADDR_REL_BIOS)(((*ctx).address_mode < (AMD_ADDR_REL_BIOS) ? (*ctx).address_mode
: (AMD_ADDR_REL_BIOS)) == AMD_ADDR_PHYSICAL ? (0xFFFFFFFF - (
(*ctx)).rom_size + 1) + (((char *)(biosdir) - (*ctx).rom)) : (
((*ctx).address_mode < (AMD_ADDR_REL_BIOS) ? (*ctx).address_mode
: (AMD_ADDR_REL_BIOS)) == AMD_ADDR_REL_BIOS ? (((char *)(biosdir
) - (*ctx).rom)) : (((*ctx).address_mode < (AMD_ADDR_REL_BIOS
) ? (*ctx).address_mode : (AMD_ADDR_REL_BIOS)) == AMD_ADDR_REL_TAB
? (((char *)(biosdir) - (*ctx).rom)) - ((*ctx)).current_table
: (((char *)(biosdir) - (*ctx).rom)))))
;
1291 adjust_current_pointer(ctx, 0, TABLE_ALIGNMENT0x1000U);
1292
1293 for (i = 0, count = 0; fw_table[i].type != AMD_BIOS_INVALID; i++) {
1294 if (!(fw_table[i].level & level))
1295 continue;
1296 if (fw_table[i].filename == NULL((void*)0) && (
1297 fw_table[i].type != AMD_BIOS_SIG &&
1298 fw_table[i].type != AMD_BIOS_APOB &&
1299 fw_table[i].type != AMD_BIOS_APOB_NV &&
1300 fw_table[i].type != AMD_BIOS_L2_PTR &&
1301 fw_table[i].type != AMD_BIOS_BIN &&
1302 fw_table[i].type != AMD_BIOS_PSP_SHARED_MEM))
1303 continue;
1304
1305 /* BIOS Directory items may have additional requirements */
1306
1307 /* SIG needs a size, else no choice but to skip */
1308 if (fw_table[i].type == AMD_BIOS_SIG && !fw_table[i].size)
1309 continue;
1310
1311 /* Check APOB_NV requirements */
1312 if (fw_table[i].type == AMD_BIOS_APOB_NV) {
1313 if (!fw_table[i].size && !fw_table[i].src)
1314 continue; /* APOB_NV not used */
1315 if (fw_table[i].src && !fw_table[i].size) {
1316 fprintf(stderrstderr, "Error: APOB NV address provided, but no size\n");
1317 amdfwtool_cleanup(ctx);
1318 exit(1);
1319 }
1320 /* If the APOB isn't used, APOB_NV isn't used either */
1321 apob_idx = find_bios_entry(AMD_BIOS_APOB);
1322 if (apob_idx < 0 || !fw_table[apob_idx].dest)
1323 continue; /* APOV NV not supported */
1324 }
1325
1326 /* APOB_DATA needs destination */
1327 if (fw_table[i].type == AMD_BIOS_APOB && !fw_table[i].dest) {
1328 fprintf(stderrstderr, "Error: APOB destination not provided\n");
1329 amdfwtool_cleanup(ctx);
1330 exit(1);
1331 }
1332
1333 /* BIOS binary must have destination and uncompressed size. If
1334 * no filename given, then user must provide a source address.
1335 */
1336 if (fw_table[i].type == AMD_BIOS_BIN) {
1337 if (!fw_table[i].dest || !fw_table[i].size) {
1338 fprintf(stderrstderr, "Error: BIOS binary destination and uncompressed size are required\n");
1339 amdfwtool_cleanup(ctx);
1340 exit(1);
1341 }
1342 if (!fw_table[i].filename && !fw_table[i].src) {
1343 fprintf(stderrstderr, "Error: BIOS binary assumed outside amdfw.rom but no source address given\n");
1344 amdfwtool_cleanup(ctx);
1345 exit(1);
1346 }
1347 }
1348
1349 /* PSP_SHARED_MEM needs a destination and size */
1350 if (fw_table[i].type == AMD_BIOS_PSP_SHARED_MEM &&
1351 (!fw_table[i].dest || !fw_table[i].size))
1352 continue;
1353 assert_fw_entry(count, MAX_BIOS_ENTRIES0x2f, ctx);
1354
1355 biosdir->entries[count].type = fw_table[i].type;
1356 biosdir->entries[count].region_type = fw_table[i].region_type;
1357 biosdir->entries[count].dest = fw_table[i].dest ?
1358 fw_table[i].dest : (uint64_t)-1;
1359 biosdir->entries[count].reset = fw_table[i].reset;
1360 biosdir->entries[count].copy = fw_table[i].copy;
1361 biosdir->entries[count].ro = fw_table[i].ro;
1362 biosdir->entries[count].compressed = fw_table[i].zlib;
1363 biosdir->entries[count].inst = fw_table[i].inst;
1364 biosdir->entries[count].subprog = fw_table[i].subpr;
1365
1366 switch (fw_table[i].type) {
1367 case AMD_BIOS_SIG:
1368 /* Reserve size bytes within amdfw.rom */
1369 biosdir->entries[count].size = fw_table[i].size;
1370 biosdir->entries[count].source = RUN_CURRENT(*ctx)((((*ctx)).address_mode) == AMD_ADDR_PHYSICAL ? (0xFFFFFFFF -
(((*ctx))).rom_size + 1) + (((*ctx).current)) : ((((*ctx)).address_mode
) == AMD_ADDR_REL_BIOS ? (((*ctx).current)) : ((((*ctx)).address_mode
) == AMD_ADDR_REL_TAB ? (((*ctx).current)) - (((*ctx))).current_table
: (((*ctx).current)))))
;
1371 biosdir->entries[count].address_mode =
1372 SET_ADDR_MODE_BY_TABLE(biosdir)(((biosdir))->header.additional_info_fields.address_mode ==
AMD_ADDR_REL_TAB ? ((biosdir)->header.additional_info_fields
.address_mode) : 0)
;
1373 memset(BUFF_CURRENT(*ctx)((void *)(((*ctx)).rom + ((*ctx).current))), 0xff,
1374 biosdir->entries[count].size);
1375 adjust_current_pointer(ctx, biosdir->entries[count].size, 0x100U);
1376 break;
1377 case AMD_BIOS_APOB:
1378 biosdir->entries[count].size = fw_table[i].size;
1379 biosdir->entries[count].source = fw_table[i].src;
1380 biosdir->entries[count].address_mode = SET_ADDR_MODE_BY_TABLE(biosdir)(((biosdir))->header.additional_info_fields.address_mode ==
AMD_ADDR_REL_TAB ? ((biosdir)->header.additional_info_fields
.address_mode) : 0)
;
1381 break;
1382 case AMD_BIOS_APOB_NV:
1383 if (fw_table[i].src) {
1384 /* If source is given, use that and its size */
1385 biosdir->entries[count].source = fw_table[i].src;
1386 biosdir->entries[count].address_mode =
1387 SET_ADDR_MODE(biosdir, AMD_ADDR_REL_BIOS)((biosdir)->header.additional_info_fields.address_mode == AMD_ADDR_REL_TAB
? (AMD_ADDR_REL_BIOS) : 0)
;
1388 biosdir->entries[count].size = fw_table[i].size;
1389 } else {
1390 /* Else reserve size bytes within amdfw.rom */
1391 adjust_current_pointer(ctx, 0, ERASE_ALIGNMENT0x1000U);
1392 biosdir->entries[count].source = RUN_CURRENT(*ctx)((((*ctx)).address_mode) == AMD_ADDR_PHYSICAL ? (0xFFFFFFFF -
(((*ctx))).rom_size + 1) + (((*ctx).current)) : ((((*ctx)).address_mode
) == AMD_ADDR_REL_BIOS ? (((*ctx).current)) : ((((*ctx)).address_mode
) == AMD_ADDR_REL_TAB ? (((*ctx).current)) - (((*ctx))).current_table
: (((*ctx).current)))))
;
1393 biosdir->entries[count].address_mode =
1394 SET_ADDR_MODE(biosdir, AMD_ADDR_REL_BIOS)((biosdir)->header.additional_info_fields.address_mode == AMD_ADDR_REL_TAB
? (AMD_ADDR_REL_BIOS) : 0)
;
1395 biosdir->entries[count].size = ALIGN_UP(((((fw_table[i].size))+((__typeof__((fw_table[i].size)))((0x1000U
))-1UL))&~((__typeof__((fw_table[i].size)))((0x1000U))-1UL
))
1396 fw_table[i].size, ERASE_ALIGNMENT)((((fw_table[i].size))+((__typeof__((fw_table[i].size)))((0x1000U
))-1UL))&~((__typeof__((fw_table[i].size)))((0x1000U))-1UL
))
;
1397 memset(BUFF_CURRENT(*ctx)((void *)(((*ctx)).rom + ((*ctx).current))), 0xff,
1398 biosdir->entries[count].size);
1399 adjust_current_pointer(ctx, biosdir->entries[count].size, 1);
1400 }
1401 break;
1402 case AMD_BIOS_BIN:
1403 /* Don't make a 2nd copy, point to the same one */
1404 if (level == BDT_LVL1(1 << 0) && locate_bdt2_bios(ctx->biosdir2, &source, &size)) {
1405 biosdir->entries[count].source = source;
1406 biosdir->entries[count].address_mode =
1407 SET_ADDR_MODE(biosdir, AMD_ADDR_REL_BIOS)((biosdir)->header.additional_info_fields.address_mode == AMD_ADDR_REL_TAB
? (AMD_ADDR_REL_BIOS) : 0)
;
1408 biosdir->entries[count].size = size;
1409 break;
1410 }
1411
1412 /* level 2, or level 1 and no copy found in level 2 */
1413 biosdir->entries[count].source = fw_table[i].src;
1414 biosdir->entries[count].address_mode =
1415 SET_ADDR_MODE(biosdir, AMD_ADDR_REL_BIOS)((biosdir)->header.additional_info_fields.address_mode == AMD_ADDR_REL_TAB
? (AMD_ADDR_REL_BIOS) : 0)
;
1416 biosdir->entries[count].dest = fw_table[i].dest;
1417 biosdir->entries[count].size = fw_table[i].size;
1418
1419 if (!fw_table[i].filename)
1420 break;
1421
1422 bytes = copy_blob(BUFF_CURRENT(*ctx)((void *)(((*ctx)).rom + ((*ctx).current))),
1423 fw_table[i].filename, BUFF_ROOM(*ctx)((*ctx).rom_size - (*ctx).current));
1424 if (bytes <= 0) {
1425 amdfwtool_cleanup(ctx);
1426 exit(1);
1427 }
1428
1429 biosdir->entries[count].source =
1430 RUN_CURRENT_MODE(*ctx, AMD_ADDR_REL_BIOS)(((*ctx).address_mode < (AMD_ADDR_REL_BIOS) ? (*ctx).address_mode
: (AMD_ADDR_REL_BIOS)) == AMD_ADDR_PHYSICAL ? (0xFFFFFFFF - (
(*ctx)).rom_size + 1) + ((*ctx).current) : (((*ctx).address_mode
< (AMD_ADDR_REL_BIOS) ? (*ctx).address_mode : (AMD_ADDR_REL_BIOS
)) == AMD_ADDR_REL_BIOS ? ((*ctx).current) : (((*ctx).address_mode
< (AMD_ADDR_REL_BIOS) ? (*ctx).address_mode : (AMD_ADDR_REL_BIOS
)) == AMD_ADDR_REL_TAB ? ((*ctx).current) - ((*ctx)).current_table
: ((*ctx).current))))
;
1431 biosdir->entries[count].address_mode =
1432 SET_ADDR_MODE(biosdir, AMD_ADDR_REL_BIOS)((biosdir)->header.additional_info_fields.address_mode == AMD_ADDR_REL_TAB
? (AMD_ADDR_REL_BIOS) : 0)
;
1433
1434 adjust_current_pointer(ctx, bytes, 0x100U);
1435 break;
1436 case AMD_BIOS_PSP_SHARED_MEM:
1437 biosdir->entries[count].dest = fw_table[i].dest;
1438 biosdir->entries[count].size = fw_table[i].size;
1439 break;
1440
1441 default: /* everything else is copied from input */
1442 if (fw_table[i].type == AMD_BIOS_APCB ||
1443 fw_table[i].type == AMD_BIOS_APCB_BK)
1444 adjust_current_pointer(ctx, 0, ERASE_ALIGNMENT0x1000U);
1445 bytes = copy_blob(BUFF_CURRENT(*ctx)((void *)(((*ctx)).rom + ((*ctx).current))),
1446 fw_table[i].filename, BUFF_ROOM(*ctx)((*ctx).rom_size - (*ctx).current));
1447 if (bytes <= 0) {
1448 amdfwtool_cleanup(ctx);
1449 exit(1);
1450 }
1451
1452 biosdir->entries[count].size = (uint32_t)bytes;
1453 biosdir->entries[count].source = RUN_CURRENT(*ctx)((((*ctx)).address_mode) == AMD_ADDR_PHYSICAL ? (0xFFFFFFFF -
(((*ctx))).rom_size + 1) + (((*ctx).current)) : ((((*ctx)).address_mode
) == AMD_ADDR_REL_BIOS ? (((*ctx).current)) : ((((*ctx)).address_mode
) == AMD_ADDR_REL_TAB ? (((*ctx).current)) - (((*ctx))).current_table
: (((*ctx).current)))))
;
1454 biosdir->entries[count].address_mode = SET_ADDR_MODE_BY_TABLE(biosdir)(((biosdir))->header.additional_info_fields.address_mode ==
AMD_ADDR_REL_TAB ? ((biosdir)->header.additional_info_fields
.address_mode) : 0)
;
1455
1456 adjust_current_pointer(ctx, bytes, 0x100U);
1457 if (fw_table[i].type == AMD_BIOS_APCB && !cb_config->have_apcb_bk) {
1458 size = biosdir->entries[count].size;
1459 source = biosdir->entries[count].source;
1460 count++;
1461 add_bios_apcb_bk_entry(biosdir, count, fw_table[i].inst, size, source);
1462 }
1463 break;
1464 }
1465
1466 count++;
1467 }
1468
1469 fill_dir_header(biosdir, count, ctx);
1470 ctx->current_table = current_table_save;
1471}
1472
1473static int set_efs_table(uint8_t soc_id, amd_cb_config *cb_config,
1474 embedded_firmware *amd_romsig)
1475{
1476 if ((cb_config->efs_spi_readmode == 0xFF) || (cb_config->efs_spi_speed == 0xFF)) {
1477 fprintf(stderrstderr, "Error: EFS read mode and SPI speed must be set\n");
1478 return 1;
1479 }
1480
1481 /* amd_romsig->efs_gen introduced after RAVEN/PICASSO.
1482 * Leave as 0xffffffff for first gen */
1483 if (cb_config->second_gen) {
1484 amd_romsig->efs_gen.gen = EFS_SECOND_GEN0;
1485 amd_romsig->efs_gen.reserved = 0;
1486 } else {
1487 amd_romsig->efs_gen.gen = EFS_BEFORE_SECOND_GEN1;
1488 amd_romsig->efs_gen.reserved = ~0;
1489 }
1490
1491 switch (soc_id) {
1492 case PLATFORM_CARRIZO:
1493 case PLATFORM_STONEYRIDGE:
1494 amd_romsig->spi_readmode_f15_mod_60_6f = cb_config->efs_spi_readmode;
1495 amd_romsig->fast_speed_new_f15_mod_60_6f = cb_config->efs_spi_speed;
1496 break;
1497 case PLATFORM_RAVEN:
1498 case PLATFORM_PICASSO:
1499 amd_romsig->spi_readmode_f17_mod_00_2f = cb_config->efs_spi_readmode;
1500 amd_romsig->spi_fastspeed_f17_mod_00_2f = cb_config->efs_spi_speed;
1501 switch (cb_config->efs_spi_micron_flag) {
1502 case 0:
1503 amd_romsig->qpr_dummy_cycle_f17_mod_00_2f = 0xff;
1504 break;
1505 case 1:
1506 amd_romsig->qpr_dummy_cycle_f17_mod_00_2f = 0xa;
1507 break;
1508 default:
1509 fprintf(stderrstderr, "Error: EFS Micron flag must be correctly set.\n\n");
1510 return 1;
1511 }
1512 break;
1513 case PLATFORM_RENOIR:
1514 case PLATFORM_LUCIENNE:
1515 case PLATFORM_CEZANNE:
1516 case PLATFORM_MENDOCINO:
1517 case PLATFORM_PHOENIX:
1518 case PLATFORM_GLINDA:
1519 case PLATFORM_GENOA:
1520 amd_romsig->spi_readmode_f17_mod_30_3f = cb_config->efs_spi_readmode;
1521 amd_romsig->spi_fastspeed_f17_mod_30_3f = cb_config->efs_spi_speed;
1522 switch (cb_config->efs_spi_micron_flag) {
1523 case 0:
1524 amd_romsig->micron_detect_f17_mod_30_3f = 0xff;
1525 break;
1526 case 1:
1527 amd_romsig->micron_detect_f17_mod_30_3f = 0xaa;
1528 break;
1529 case 2:
1530 amd_romsig->micron_detect_f17_mod_30_3f = 0x55;
1531 break;
1532 default:
1533 fprintf(stderrstderr, "Error: EFS Micron flag must be correctly set.\n\n");
1534 return 1;
1535 }
1536 break;
1537 case PLATFORM_UNKNOWN:
1538 default:
1539 fprintf(stderrstderr, "Error: Invalid SOC name.\n\n");
1540 return 1;
1541 }
1542 return 0;
1543}
1544
1545void open_process_config(char *config, amd_cb_config *cb_config)
1546{
1547 FILE *config_handle;
1548
1549 if (config) {
1550 config_handle = fopen(config, "r");
1551 if (config_handle == NULL((void*)0)) {
1552 fprintf(stderrstderr, "Can not open file %s for reading: %s\n",
1553 config, strerror(errno(*__errno_location ())));
1554 exit(1);
1555 }
1556 if (process_config(config_handle, cb_config) == 0) {
1557 fprintf(stderrstderr, "Configuration file %s parsing error\n",
1558 config);
1559 fclose(config_handle);
1560 exit(1);
1561 }
1562 fclose(config_handle);
1563 }
1564
1565 /* For debug. */
1566 if (cb_config->debug) {
1567 dump_psp_firmwares(amd_psp_fw_table);
1568 dump_bdt_firmwares(amd_bios_table);
1569 }
1570}
1571
1572static bool_Bool is_initial_alignment_required(enum platform soc_id)
1573{
1574 switch (soc_id) {
1575 case PLATFORM_MENDOCINO:
1576 case PLATFORM_PHOENIX:
1577 case PLATFORM_GLINDA:
1578 return false0;
1579 default:
1580 return true1;
1581 }
1582}
1583
1584int main(int argc, char **argv)
1585{
1586 int retval = 0;
1587 int combo_index = 0;
1588 int targetfd;
1589 context ctx = { 0 };
1590 uint32_t romsig_offset;
1591 amd_cb_config cb_config = {
1592 .efs_spi_readmode = 0xff, .efs_spi_speed = 0xff, .efs_spi_micron_flag = 0xff
1593 };
1594
1595 ctx.current_pointer_saved = 0xFFFFFFFF;
1596
1597 retval = amdfwtool_getopt(argc, argv, &cb_config, &ctx);
1598
1599 if (retval) {
1
Assuming 'retval' is 0
2
Taking false branch
1600 return retval;
1601 }
1602
1603 if (cb_config.use_combo) {
3
Assuming field 'use_combo' is true
4
Taking true branch
1604 ctx.amd_psp_fw_table_clean = malloc(sizeof(amd_psp_fw_table));
5
Memory is allocated
1605 ctx.amd_bios_table_clean = malloc(sizeof(amd_bios_table));
1606 memcpy(ctx.amd_psp_fw_table_clean, amd_psp_fw_table, sizeof(amd_psp_fw_table));
1607 memcpy(ctx.amd_bios_table_clean, amd_bios_table, sizeof(amd_bios_table));
1608 }
1609
1610 open_process_config(cb_config.config, &cb_config);
1611
1612 ctx.rom = malloc(ctx.rom_size);
1613 if (!ctx.rom) {
6
Assuming field 'rom' is null
7
Taking true branch
1614 fprintf(stderrstderr, "Error: Failed to allocate memory\n");
8
Potential leak of memory pointed to by 'ctx.amd_psp_fw_table_clean'
1615 return 1;
1616 }
1617 memset(ctx.rom, 0xFF, ctx.rom_size);
1618
1619 romsig_offset = cb_config.efs_location ? cb_config.efs_location : AMD_ROMSIG_OFFSET0x20000;
1620 set_current_pointer(&ctx, romsig_offset);
1621
1622 ctx.amd_romsig_ptr = BUFF_OFFSET(ctx, romsig_offset)((void *)((ctx).rom + (romsig_offset)));
1623 ctx.amd_romsig_ptr->signature = EMBEDDED_FW_SIGNATURE0x55aa55aa;
1624 ctx.amd_romsig_ptr->imc_entry = 0;
1625 ctx.amd_romsig_ptr->gec_entry = 0;
1626 ctx.amd_romsig_ptr->xhci_entry = 0;
1627
1628 if (cb_config.soc_id != PLATFORM_UNKNOWN) {
1629 retval = set_efs_table(cb_config.soc_id, &cb_config, ctx.amd_romsig_ptr);
1630 if (retval) {
1631 fprintf(stderrstderr, "ERROR: Failed to initialize EFS table!\n");
1632 return retval;
1633 }
1634 } else {
1635 fprintf(stderrstderr, "WARNING: No SOC name specified.\n");
1636 }
1637
1638 if (cb_config.need_ish)
1639 ctx.address_mode = AMD_ADDR_REL_TAB;
1640 else if (cb_config.second_gen)
1641 ctx.address_mode = AMD_ADDR_REL_BIOS;
1642 else
1643 ctx.address_mode = AMD_ADDR_PHYSICAL;
1644
1645 if (cb_config.efs_location != cb_config.body_location)
1646 set_current_pointer(&ctx, cb_config.body_location);
1647 else
1648 set_current_pointer(&ctx, romsig_offset + sizeof(embedded_firmware));
1649
1650 integrate_firmwares(&ctx, ctx.amd_romsig_ptr, amd_fw_table);
1651
1652 if (is_initial_alignment_required(cb_config.soc_id)) {
1653 /* TODO: Check for older platforms. */
1654 adjust_current_pointer(&ctx, 0, 0x10000U);
1655 }
1656 ctx.current_table = 0;
1657
1658 /* If the tool is invoked with command-line options to keep the signed PSP
1659 binaries separate, process the signed binaries first. */
1660 if (cb_config.signed_output_file && cb_config.signed_start_addr)
1661 process_signed_psp_firmwares(cb_config.signed_output_file,
1662 amd_psp_fw_table,
1663 cb_config.signed_start_addr,
1664 cb_config.soc_id);
1665
1666 if (cb_config.use_combo) {
1667 ctx.psp_combo_dir = new_combo_dir(&ctx, PSP2_COOKIE0x50535032);
1668
1669 adjust_current_pointer(&ctx, 0, 0x1000U);
1670
1671 if (!cb_config.recovery_ab)
1672 ctx.bhd_combo_dir = new_combo_dir(&ctx, BHD2_COOKIE0x44484232);
1673 }
1674
1675 combo_index = 0;
1676 if (cb_config.config)
1677 cb_config.combo_config[0] = cb_config.config;
1678
1679 do {
1680 if (cb_config.use_combo && cb_config.debug)
1681 printf("Processing %dth combo entry\n", combo_index);
1682
1683 ctx.pspdir = NULL((void*)0);
1684 ctx.pspdir2 = NULL((void*)0);
1685 ctx.pspdir2_b = NULL((void*)0);
1686 ctx.biosdir = NULL((void*)0);
1687 ctx.biosdir2 = NULL((void*)0);
1688 ctx.biosdir2_b = NULL((void*)0);
1689 ctx.ish_a_dir = NULL((void*)0);
1690 ctx.ish_b_dir = NULL((void*)0);
1691 /* for non-combo image, combo_config[0] == config, and
1692 * it already is processed. Actually "combo_index >
1693 * 0" is enough. Put both of them here to make sure
1694 * and make it clear this will not affect non-combo
1695 * case.
1696 */
1697 if (cb_config.use_combo && combo_index > 0) {
1698 /* Restore the table as clean data. */
1699 memcpy(amd_psp_fw_table, ctx.amd_psp_fw_table_clean,
1700 sizeof(amd_psp_fw_table));
1701 memcpy(amd_bios_table, ctx.amd_bios_table_clean,
1702 sizeof(amd_bios_table));
1703 assert_fw_entry(combo_index, MAX_COMBO_ENTRIES2, &ctx);
1704 open_process_config(cb_config.combo_config[combo_index], &cb_config);
1705
1706 /* In most cases, the address modes are same. */
1707 if (cb_config.need_ish)
1708 ctx.address_mode = AMD_ADDR_REL_TAB;
1709 else if (cb_config.second_gen)
1710 ctx.address_mode = AMD_ADDR_REL_BIOS;
1711 else
1712 ctx.address_mode = AMD_ADDR_PHYSICAL;
1713
1714 register_apcb_combo(&cb_config, combo_index, &ctx);
1715 }
1716
1717 if (cb_config.multi_level) {
1718 /* Do 2nd PSP directory followed by 1st */
1719 integrate_psp_firmwares(&ctx,
1720 amd_psp_fw_table, PSPL2_COOKIE0x324c5024, &cb_config);
1721 if (cb_config.recovery_ab && !cb_config.recovery_ab_single_copy) {
1722 /* Create a copy of PSP Directory 2 in the backup slot B.
1723 Related biosdir2_b copy will be created later. */
1724 integrate_psp_firmwares(&ctx,
1725 amd_psp_fw_table, PSPL2_COOKIE0x324c5024, &cb_config);
1726 } else {
1727 /*
1728 * Either the platform is using only
1729 * one slot or B is same as above
1730 * directories for A. Skip creating
1731 * pspdir2_b here to save flash space.
1732 * Related biosdir2_b will be skipped
1733 * automatically.
1734 */
1735 ctx.pspdir2_b = NULL((void*)0); /* More explicitly */
1736 }
1737 integrate_psp_firmwares(&ctx,
1738 amd_psp_fw_table, PSP_COOKIE0x50535024, &cb_config);
1739 integrate_psp_levels(&ctx, &cb_config);
1740 } else {
1741 /* flat: PSP 1 cookie and no pointer to 2nd table */
1742 integrate_psp_firmwares(&ctx,
1743 amd_psp_fw_table, PSP_COOKIE0x50535024, &cb_config);
1744 }
1745
1746 if (!cb_config.use_combo) {
1747 fill_psp_directory_to_efs(ctx.amd_romsig_ptr, ctx.pspdir, &ctx, &cb_config);
1748 } else {
1749 fill_psp_directory_to_efs(ctx.amd_romsig_ptr, ctx.psp_combo_dir, &ctx, &cb_config);
1750 /* 0 -Compare PSP ID, 1 -Compare chip family ID */
1751 assert_fw_entry(combo_index, MAX_COMBO_ENTRIES2, &ctx);
1752 ctx.psp_combo_dir->entries[combo_index].id_sel = 0;
1753 ctx.psp_combo_dir->entries[combo_index].id = get_psp_id(cb_config.soc_id);
1754 ctx.psp_combo_dir->entries[combo_index].lvl2_addr =
1755 BUFF_TO_RUN_MODE(ctx, ctx.pspdir, AMD_ADDR_REL_BIOS)(((ctx).address_mode < (AMD_ADDR_REL_BIOS) ? (ctx).address_mode
: (AMD_ADDR_REL_BIOS)) == AMD_ADDR_PHYSICAL ? (0xFFFFFFFF - (
(ctx)).rom_size + 1) + (((char *)(ctx.pspdir) - (ctx).rom)) :
(((ctx).address_mode < (AMD_ADDR_REL_BIOS) ? (ctx).address_mode
: (AMD_ADDR_REL_BIOS)) == AMD_ADDR_REL_BIOS ? (((char *)(ctx
.pspdir) - (ctx).rom)) : (((ctx).address_mode < (AMD_ADDR_REL_BIOS
) ? (ctx).address_mode : (AMD_ADDR_REL_BIOS)) == AMD_ADDR_REL_TAB
? (((char *)(ctx.pspdir) - (ctx).rom)) - ((ctx)).current_table
: (((char *)(ctx.pspdir) - (ctx).rom)))))
;
1756
1757 fill_dir_header(ctx.psp_combo_dir, combo_index + 1, &ctx);
1758 }
1759
1760 if (have_bios_tables(amd_bios_table)) {
1761 if (cb_config.multi_level) {
1762 /* Do 2nd level BIOS directory followed by 1st */
1763 integrate_bios_firmwares(&ctx,
1764 amd_bios_table, BHDL2_COOKIE0x324c4224, &cb_config);
1765 if (cb_config.recovery_ab) {
1766 if (ctx.pspdir2_b != NULL((void*)0)) {
1767 integrate_bios_firmwares(&ctx,
1768 amd_bios_table, BHDL2_COOKIE0x324c4224,
1769 &cb_config);
1770 }
1771 } else {
1772 integrate_bios_firmwares(&ctx,
1773 amd_bios_table, BHD_COOKIE0x44484224, &cb_config);
1774 }
1775 integrate_bios_levels(&ctx, &cb_config);
1776 } else {
1777 /* flat: BHD1 cookie and no pointer to 2nd table */
1778 integrate_bios_firmwares(&ctx,
1779 amd_bios_table, BHD_COOKIE0x44484224, &cb_config);
1780 }
1781 if (!cb_config.use_combo) {
1782 fill_bios_directory_to_efs(ctx.amd_romsig_ptr, ctx.biosdir,
1783 &ctx, &cb_config);
1784 } else if (ctx.bhd_combo_dir != NULL((void*)0)) {
1785 /* In recovery A/B mode, there isn't a BHD combo directory.
1786 * Instead, the BIOS tables level 2 are linked by PSP tables.
1787 */
1788 fill_bios_directory_to_efs(ctx.amd_romsig_ptr, ctx.bhd_combo_dir,
1789 &ctx, &cb_config);
1790 assert_fw_entry(combo_index, MAX_COMBO_ENTRIES2, &ctx);
1791 ctx.bhd_combo_dir->entries[combo_index].id_sel = 0;
1792 ctx.bhd_combo_dir->entries[combo_index].id =
1793 get_psp_id(cb_config.soc_id);
1794 ctx.bhd_combo_dir->entries[combo_index].lvl2_addr =
1795 BUFF_TO_RUN_MODE(ctx, ctx.biosdir, AMD_ADDR_REL_BIOS)(((ctx).address_mode < (AMD_ADDR_REL_BIOS) ? (ctx).address_mode
: (AMD_ADDR_REL_BIOS)) == AMD_ADDR_PHYSICAL ? (0xFFFFFFFF - (
(ctx)).rom_size + 1) + (((char *)(ctx.biosdir) - (ctx).rom)) :
(((ctx).address_mode < (AMD_ADDR_REL_BIOS) ? (ctx).address_mode
: (AMD_ADDR_REL_BIOS)) == AMD_ADDR_REL_BIOS ? (((char *)(ctx
.biosdir) - (ctx).rom)) : (((ctx).address_mode < (AMD_ADDR_REL_BIOS
) ? (ctx).address_mode : (AMD_ADDR_REL_BIOS)) == AMD_ADDR_REL_TAB
? (((char *)(ctx.biosdir) - (ctx).rom)) - ((ctx)).current_table
: (((char *)(ctx.biosdir) - (ctx).rom)))))
;
1796
1797 fill_dir_header(ctx.bhd_combo_dir, combo_index + 1, &ctx);
1798 }
1799 }
1800 if (cb_config.debug)
1801 dump_image_addresses(&ctx);
1802 } while (cb_config.use_combo && ++combo_index < MAX_COMBO_ENTRIES2 &&
1803 cb_config.combo_config[combo_index] != NULL((void*)0));
1804
1805 targetfd = open(cb_config.output, O_RDWR02 | O_CREAT0100 | O_TRUNC01000, 0666);
1806 if (targetfd >= 0) {
1807 uint32_t offset = cb_config.efs_location;
1808 uint32_t bytes = cb_config.efs_location == cb_config.body_location ?
1809 ctx.current - offset : sizeof(embedded_firmware);
1810 uint32_t ret_bytes;
1811
1812 ret_bytes = write_from_buf_to_file(targetfd, BUFF_OFFSET(ctx, offset)((void *)((ctx).rom + (offset))), bytes);
1813 if (bytes != ret_bytes) {
1814 fprintf(stderrstderr, "Error: Writing to file %s failed\n", cb_config.output);
1815 retval = 1;
1816 }
1817 close(targetfd);
1818 } else {
1819 fprintf(stderrstderr, "Error: could not open file: %s\n", cb_config.output);
1820 retval = 1;
1821 }
1822
1823 if (cb_config.efs_location != cb_config.body_location) {
1824 ssize_t bytes;
1825
1826 bytes = write_body(cb_config.output, BUFF_OFFSET(ctx, cb_config.body_location)((void *)((ctx).rom + (cb_config.body_location))),
1827 ctx.current - cb_config.body_location);
1828 if (bytes != ctx.current - cb_config.body_location) {
1829 fprintf(stderrstderr, "Error: Writing body\n");
1830 retval = 1;
1831 }
1832 }
1833
1834 if (cb_config.manifest_file) {
1835 dump_blob_version(cb_config.manifest_file, amd_psp_fw_table);
1836 }
1837
1838 amdfwtool_cleanup(&ctx);
1839 return retval;
1840}