1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #define __SIMPLE_DEVICE__
6 #include <console/console.h>
7 #include <device/device.h>
8 #include <device/mmio.h>
9 #include <device/pci_def.h>
10 #include <device/pci_ops.h>
12 #include <intelblocks/cse.h>
13 #include <intelblocks/systemagent.h>
14 #include <intelblocks/vtd.h>
15 #include <security/vboot/misc.h>
16 #include <soc/hsphy.h>
17 #include <soc/iomap.h>
18 #include <soc/pci_devs.h>
22 #define HASHALG_SHA1 0x00000001
23 #define HASHALG_SHA256 0x00000002
24 #define HASHALG_SHA384 0x00000003
25 #define HASHALG_SHA512 0x00000004
27 #define MAX_HASH_SIZE VB2_SHA512_DIGEST_SIZE
28 #define GET_IP_FIRMWARE_CMD 0x21
29 #define HSPHY_PAYLOAD_SIZE (32*KiB)
31 #define CPU_PID_PCIE_PHYX16_BROADCAST 0x55
36 uint8_t digest
[MAX_HASH_SIZE
];
40 struct ip_push_model
{
46 static int heci_get_hsphy_payload(void *buf
, uint32_t *buf_size
, uint8_t *hash_buf
,
47 uint8_t *hash_alg
, uint32_t *status
)
51 struct heci_ip_load_request
{
55 uint32_t dram_base_low
;
56 uint32_t dram_base_high
;
61 .group_id
= MKHI_GROUP_ID_BUP_COMMON
,
62 .command
= GET_IP_FIRMWARE_CMD
,
66 .dram_base_low
= (uintptr_t)buf
,
68 .memory_size
= *buf_size
,
72 struct heci_ip_load_response
{
74 uint32_t payload_size
;
78 uint8_t hash
[MAX_HASH_SIZE
];
81 if (!buf
|| !buf_size
|| !hash_buf
|| !hash_alg
) {
82 printk(BIOS_ERR
, "%s: Invalid parameters\n", __func__
);
86 reply_size
= sizeof(reply
);
87 memset(&reply
, 0, reply_size
);
89 printk(BIOS_DEBUG
, "HECI: Sending Get IP firmware command\n");
91 if (heci_send_receive(&msg
, sizeof(msg
), &reply
, &reply_size
, HECI_MKHI_ADDR
)) {
92 printk(BIOS_ERR
, "HECI: Get IP firmware failed\n");
96 if (reply
.hdr
.result
) {
97 printk(BIOS_ERR
, "HECI: Get IP firmware response invalid\n");
98 *status
= reply
.status
;
99 printk(BIOS_DEBUG
, "HECI response:\n");
100 hexdump(&reply
, sizeof(reply
));
104 *buf_size
= reply
.payload_size
;
105 *hash_alg
= reply
.hash_type
;
106 *status
= reply
.status
;
107 memcpy(hash_buf
, reply
.hash
, MAX_HASH_SIZE
);
109 printk(BIOS_DEBUG
, "HECI: Get IP firmware success. Response:\n");
110 printk(BIOS_DEBUG
, " Payload size = 0x%x\n", *buf_size
);
111 printk(BIOS_DEBUG
, " Hash type used for signing payload = 0x%x\n", *hash_alg
);
116 static bool verify_hsphy_hash(void *buf
, uint32_t buf_size
, uint8_t *hash_buf
, uint8_t hash_alg
)
118 struct vb2_hash hash
;
122 hash
.algo
= VB2_HASH_SHA256
;
125 hash
.algo
= VB2_HASH_SHA384
;
128 hash
.algo
= VB2_HASH_SHA512
;
132 printk(BIOS_ERR
, "Hash alg %d not supported, trying SHA384\n", hash_alg
);
133 hash
.algo
= VB2_HASH_SHA384
;
137 memcpy(hash
.raw
, hash_buf
, vb2_digest_size(hash
.algo
));
139 if (vb2_hash_verify(vboot_hwcrypto_allowed(), buf
, buf_size
, &hash
) != VB2_SUCCESS
)
145 static void upload_hsphy_to_cpu_pcie(void *buf
, uint32_t buf_size
)
148 struct ip_push_model
*push_model
= (struct ip_push_model
*)buf
;
150 while (i
< buf_size
) {
151 i
+= sizeof(*push_model
);
153 if ((push_model
->address
== 0) && (push_model
->count
== 0))
154 break; // End of file
156 for (j
= 0; j
< push_model
->count
; j
++) {
157 REGBAR32(CPU_PID_PCIE_PHYX16_BROADCAST
,
158 push_model
->address
) = push_model
->data
[j
];
159 i
+= sizeof(uint32_t);
162 push_model
= (struct ip_push_model
*)(buf
+ i
);
166 static bool hsphy_cache_valid(struct hsphy_cache
*hsphy_fw_cache
)
168 if (!hsphy_fw_cache
) {
169 printk(BIOS_WARNING
, "Failed to mmap HSPHY cache\n");
173 if (hsphy_fw_cache
->hsphy_size
== 0 ||
174 hsphy_fw_cache
->hsphy_size
> HSPHY_PAYLOAD_SIZE
||
175 hsphy_fw_cache
->hash_algo
<= HASHALG_SHA1
||
176 hsphy_fw_cache
->hash_algo
> HASHALG_SHA512
)
179 if (!verify_hsphy_hash(hsphy_fw_cache
->hsphy_fw
, hsphy_fw_cache
->hsphy_size
,
180 hsphy_fw_cache
->digest
, hsphy_fw_cache
->hash_algo
))
186 static bool load_hsphy_from_cache(void)
188 struct region_device rdev
;
189 struct hsphy_cache
*hsphy_fw_cache
;
191 if (fmap_locate_area_as_rdev("HSPHY_FW", &rdev
) < 0) {
192 printk(BIOS_ERR
, "HSPHY: Cannot find HSPHY_FW region\n");
196 hsphy_fw_cache
= (struct hsphy_cache
*)rdev_mmap_full(&rdev
);
198 if (!hsphy_cache_valid(hsphy_fw_cache
)) {
199 printk(BIOS_ERR
, "HSPHY: HSPHY cache invalid\n");
201 rdev_munmap(&rdev
, hsphy_fw_cache
);
205 printk(BIOS_INFO
, "Loading HSPHY FW from cache\n");
206 upload_hsphy_to_cpu_pcie(hsphy_fw_cache
->hsphy_fw
, hsphy_fw_cache
->hsphy_size
);
208 rdev_munmap(&rdev
, hsphy_fw_cache
);
213 static void cache_hsphy_fw_in_flash(void *buf
, uint32_t buf_size
, uint8_t *hash_buf
,
216 struct region_device rdev
;
217 struct hsphy_cache
*hsphy_fw_cache
;
220 if (!buf
|| buf_size
== 0 || buf_size
> (HSPHY_PAYLOAD_SIZE
- sizeof(*hsphy_fw_cache
))
221 || !hash_buf
|| hash_alg
<= HASHALG_SHA1
|| hash_alg
> HASHALG_SHA512
) {
222 printk(BIOS_ERR
, "Invalid parameters, HSPHY will not be cached in flash.\n");
226 /* Locate the area as RO rdev, otherwise mmap will fail */
227 if (fmap_locate_area_as_rdev("HSPHY_FW", &rdev
) < 0) {
228 printk(BIOS_ERR
, "HSPHY: Could not find HSPHY_FW region\n");
229 printk(BIOS_ERR
, "HSPHY will not be cached in flash\n");
233 hsphy_fw_cache
= (struct hsphy_cache
*)rdev_mmap_full(&rdev
);
235 if (hsphy_cache_valid(hsphy_fw_cache
)) {
236 /* If the cache is valid, check the buffer against the cache hash */
237 if (verify_hsphy_hash(buf
, buf_size
, hsphy_fw_cache
->digest
,
238 hsphy_fw_cache
->hash_algo
)) {
239 printk(BIOS_INFO
, "HSPHY: cache does not need update\n");
240 rdev_munmap(&rdev
, hsphy_fw_cache
);
243 printk(BIOS_INFO
, "HSPHY: cache needs update\n");
246 printk(BIOS_INFO
, "HSPHY: cache invalid, updating\n");
249 if (region_device_sz(&rdev
) < (buf_size
+ sizeof(*hsphy_fw_cache
))) {
250 printk(BIOS_ERR
, "HSPHY: HSPHY_FW region too small: %zx < %zx\n",
251 region_device_sz(&rdev
), buf_size
+ sizeof(*hsphy_fw_cache
));
252 printk(BIOS_ERR
, "HSPHY will not be cached in flash\n");
253 rdev_munmap(&rdev
, hsphy_fw_cache
);
257 rdev_munmap(&rdev
, hsphy_fw_cache
);
258 hsphy_fw_cache
= malloc(sizeof(*hsphy_fw_cache
));
260 if (!hsphy_fw_cache
) {
261 printk(BIOS_ERR
, "HSPHY: Could not allocate memory for HSPHY cache buffer\n");
262 printk(BIOS_ERR
, "HSPHY will not be cached in flash\n");
266 hsphy_fw_cache
->hsphy_size
= buf_size
;
267 hsphy_fw_cache
->hash_algo
= hash_alg
;
271 hash_alg
= VB2_HASH_SHA256
;
274 hash_alg
= VB2_HASH_SHA384
;
277 hash_alg
= VB2_HASH_SHA512
;
281 memset(hsphy_fw_cache
->digest
, 0, sizeof(hsphy_fw_cache
->digest
));
282 memcpy(hsphy_fw_cache
->digest
, hash_buf
, vb2_digest_size(hash_alg
));
284 /* Now that we want to write to flash, locate the area as RW rdev */
285 if (fmap_locate_area_as_rdev_rw("HSPHY_FW", &rdev
) < 0) {
286 printk(BIOS_ERR
, "HSPHY: Could not find HSPHY_FW region\n");
287 printk(BIOS_ERR
, "HSPHY will not be cached in flash\n");
288 free(hsphy_fw_cache
);
292 if (rdev_eraseat(&rdev
, 0, region_device_sz(&rdev
)) < 0) {
293 printk(BIOS_ERR
, "Failed to erase HSPHY cache region\n");
294 free(hsphy_fw_cache
);
298 ret
= rdev_writeat(&rdev
, hsphy_fw_cache
, 0, sizeof(*hsphy_fw_cache
));
299 if (ret
!= sizeof(*hsphy_fw_cache
)) {
300 printk(BIOS_ERR
, "Failed to write HSPHY cache metadata\n");
301 free(hsphy_fw_cache
);
305 ret
= rdev_writeat(&rdev
, buf
, sizeof(*hsphy_fw_cache
), buf_size
);
306 if (ret
!= buf_size
) {
307 printk(BIOS_ERR
, "Failed to write HSPHY FW to cache\n");
308 free(hsphy_fw_cache
);
312 printk(BIOS_INFO
, "HSPHY cached to flash successfully\n");
314 free(hsphy_fw_cache
);
317 static void *allocate_hsphy_buf(void)
322 if (CONFIG(ENABLE_EARLY_DMA_PROTECTION
)) {
323 hsphy_buf
= vtd_get_dma_buffer(&dma_buf_size
);
324 if (!hsphy_buf
|| dma_buf_size
< HSPHY_PAYLOAD_SIZE
) {
325 printk(BIOS_ERR
, "DMA protection enabled but DMA buffer does not"
326 " exist or is too small\n");
330 /* Rather impossible scenario, but check alignment anyways */
331 if (!IS_ALIGNED((uintptr_t)hsphy_buf
, 4 * KiB
) &&
332 (HSPHY_PAYLOAD_SIZE
+ 4 * KiB
) <= dma_buf_size
)
333 hsphy_buf
= (void *)ALIGN_UP((uintptr_t)hsphy_buf
, 4 * KiB
);
335 /* Align the buffer to page size, otherwise the HECI command will fail */
336 hsphy_buf
= memalign(4 * KiB
, HSPHY_PAYLOAD_SIZE
);
339 printk(BIOS_ERR
, "Failed to allocate memory for HSPHY blob\n");
347 void load_and_init_hsphy(void)
350 uint8_t hsphy_hash
[MAX_HASH_SIZE
] = { 0 };
352 uint32_t buf_size
= HSPHY_PAYLOAD_SIZE
;
353 pci_devfn_t dev
= PCH_DEV_CSE
;
354 const uint16_t pci_cmd_bme_mem
= PCI_COMMAND_MASTER
| PCI_COMMAND_MEMORY
;
357 if (!is_devfn_enabled(SA_DEVFN_CPU_PCIE1_0
) &&
358 !is_devfn_enabled(SA_DEVFN_CPU_PCIE1_1
)) {
359 printk(BIOS_DEBUG
, "All HSPHY ports disabled, skipping HSPHY loading\n");
364 * Try to get HSPHY payload from CSME first, so we can always keep our
365 * HSPHY cache up to date. If we cannot allocate the buffer for it, the
366 * cache is our last resort.
368 hsphy_buf
= allocate_hsphy_buf();
370 printk(BIOS_ERR
, "Could not allocate memory for HSPHY blob\n");
371 if (CONFIG(INCLUDE_HSPHY_IN_FMAP
)) {
372 printk(BIOS_INFO
, "Trying to load HSPHY FW from cache\n");
373 if (load_hsphy_from_cache()) {
374 printk(BIOS_INFO
, "Successfully loaded HSPHY FW from cache\n");
377 printk(BIOS_ERR
, "Failed to load HSPHY FW from cache\n");
379 printk(BIOS_ERR
, "Aborting HSPHY FW loading, PCIe Gen5 won't work.\n");
383 memset(hsphy_buf
, 0, HSPHY_PAYLOAD_SIZE
);
386 * If CSME is not present, try cached HSPHY FW. We still want to use
387 * CSME just in case CSME is updated along with HSPHY FW, so that we
388 * can update our cache if needed.
390 if (!is_cse_enabled()) {
391 if (CONFIG(INCLUDE_HSPHY_IN_FMAP
)) {
392 printk(BIOS_INFO
, "Trying to load HSPHY FW from cache"
393 " because CSME is not enabled or not visible\n");
394 if (load_hsphy_from_cache()) {
395 printk(BIOS_INFO
, "Successfully loaded HSPHY FW from cache\n");
398 printk(BIOS_ERR
, "Failed to load HSPHY FW from cache\n");
400 printk(BIOS_ERR
, "%s: CSME not enabled or not visible, but required\n",
402 printk(BIOS_ERR
, "Aborting HSPHY FW loading, PCIe Gen5 won't work.\n");
403 if (!CONFIG(ENABLE_EARLY_DMA_PROTECTION
))
408 /* Ensure BAR, BME and memory space are enabled */
409 if ((pci_read_config16(dev
, PCI_COMMAND
) & pci_cmd_bme_mem
) != pci_cmd_bme_mem
)
410 pci_or_config16(dev
, PCI_COMMAND
, pci_cmd_bme_mem
);
413 if (pci_read_config32(dev
, PCI_BASE_ADDRESS_0
) == 0) {
414 pci_and_config16(dev
, PCI_COMMAND
, ~pci_cmd_bme_mem
);
415 pci_write_config32(dev
, PCI_BASE_ADDRESS_0
, HECI1_BASE_ADDRESS
);
416 pci_or_config16(dev
, PCI_COMMAND
, pci_cmd_bme_mem
);
419 /* Try to get HSPHY payload from CSME and cache it if possible. */
420 if (!heci_get_hsphy_payload(hsphy_buf
, &buf_size
, hsphy_hash
, &hash_type
, &status
)) {
421 if (verify_hsphy_hash(hsphy_buf
, buf_size
, hsphy_hash
, hash_type
)) {
422 upload_hsphy_to_cpu_pcie(hsphy_buf
, buf_size
);
423 if (CONFIG(INCLUDE_HSPHY_IN_FMAP
))
424 cache_hsphy_fw_in_flash(hsphy_buf
, buf_size
, hsphy_hash
,
427 if (!CONFIG(ENABLE_EARLY_DMA_PROTECTION
))
431 printk(BIOS_ERR
, "Failed to verify HSPHY FW hash.\n");
434 printk(BIOS_ERR
, "Failed to get HSPHY FW over HECI.\n");
437 if (!CONFIG(ENABLE_EARLY_DMA_PROTECTION
))
440 /* We failed to get HSPHY payload from CSME, cache is our last chance. */
441 if (CONFIG(INCLUDE_HSPHY_IN_FMAP
) && load_hsphy_from_cache()) {
442 printk(BIOS_INFO
, "Successfully loaded HSPHY FW from cache\n");
446 printk(BIOS_ERR
, "Failed to load HSPHY FW, PCIe Gen5 won't work.\n");