File: | util/amdfwtool/amdfwtool.c |
Warning: | line 1614, column 3 Potential leak of memory pointed to by 'ctx.amd_psp_fw_table_clean' |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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 | ||||
92 | static 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 | */ | |||
130 | static 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 | ||||
162 | amd_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 | ||||
260 | amd_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 | ||||
267 | amd_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 | ||||
393 | static 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 | ||||
409 | static 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 | ||||
425 | static 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 | ||||
440 | void 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 | ||||
450 | static 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 | ||||
470 | static 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 | ||||
476 | static 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 | ||||
501 | static 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 | ||||
511 | static 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 | ||||
524 | static 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 | ||||
606 | static 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 | ||||
633 | static 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 | ||||
660 | static 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 | ||||
698 | static 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 | ||||
737 | static 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 | ||||
765 | static 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 */ | |||
789 | static 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 | ||||
805 | static 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 | ||||
817 | static 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 | ||||
841 | static 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 | ||||
884 | static 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 | ||||
936 | static 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 | ||||
1086 | static 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 | ||||
1117 | static 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 | ||||
1140 | static 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 | ||||
1160 | static 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 | ||||
1171 | int 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 | ||||
1182 | static 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 | ||||
1211 | static 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 | } | |||
1249 | static 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 | ||||
1473 | static 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 | ||||
1545 | void 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 | ||||
1572 | static 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 | ||||
1584 | int 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) { | |||
| ||||
1600 | return retval; | |||
1601 | } | |||
1602 | ||||
1603 | if (cb_config.use_combo) { | |||
1604 | ctx.amd_psp_fw_table_clean = malloc(sizeof(amd_psp_fw_table)); | |||
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) { | |||
1614 | fprintf(stderrstderr, "Error: Failed to allocate memory\n"); | |||
| ||||
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 | } |