summaryrefslogtreecommitdiff
path: root/src/soc
diff options
context:
space:
mode:
authorMichał Żygowski <michal.zygowski@3mdeb.com>2022-10-19 09:55:18 +0200
committerPaul Fagerburg <pfagerburg@chromium.org>2023-03-17 13:54:09 +0000
commita49945e4b728fe8f6c43ed0fd73f9fc86fd3c475 (patch)
tree727913f5f1529695366fb29c9fd987dcae703cb0 /src/soc
parent5f05ee2a0a735971bdfc94779fd624e6413d988f (diff)
soc/intel/alderlake/hsphy.c: Handle case with DMA protection
The HSPHY firmware must be downloaded to DMA-allowed host address space. Check for DMA buffer presence and use it as the buffer for HSPHY firmware to be downloaded from CSME. TEST=Successfully load HSPHY firmware to CPU on MSI PRO Z690-A DDR4 with DMA protection enabled. Signed-off-by: Michał Żygowski <michal.zygowski@3mdeb.com> Change-Id: I88edda26a027b557eeaba80426a5b7be7199507d Reviewed-on: https://review.coreboot.org/c/coreboot/+/68556 Reviewed-by: Michał Kopeć <michal.kopec@3mdeb.com> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Diffstat (limited to 'src/soc')
-rw-r--r--src/soc/intel/alderlake/hsphy.c44
1 files changed, 31 insertions, 13 deletions
diff --git a/src/soc/intel/alderlake/hsphy.c b/src/soc/intel/alderlake/hsphy.c
index 9d41600e0f..dacb64399d 100644
--- a/src/soc/intel/alderlake/hsphy.c
+++ b/src/soc/intel/alderlake/hsphy.c
@@ -10,6 +10,7 @@
#include <device/pci_ops.h>
#include <intelblocks/cse.h>
#include <intelblocks/systemagent.h>
+#include <intelblocks/vtd.h>
#include <security/vboot/misc.h>
#include <soc/hsphy.h>
#include <soc/iomap.h>
@@ -161,6 +162,7 @@ void load_and_init_hsphy(void)
uint8_t hsphy_hash[MAX_HASH_SIZE] = { 0 };
uint8_t hash_type;
uint32_t buf_size = HSPHY_PAYLOAD_SIZE;
+ size_t dma_buf_size;
pci_devfn_t dev = PCH_DEV_CSE;
const uint16_t pci_cmd_bme_mem = PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
uint32_t status;
@@ -171,13 +173,30 @@ void load_and_init_hsphy(void)
return;
}
- /* Align the buffer to page size, otherwise the HECI command will fail */
- hsphy_buf = memalign(4 * KiB, HSPHY_PAYLOAD_SIZE);
+ if (CONFIG(ENABLE_EARLY_DMA_PROTECTION)) {
+ hsphy_buf = vtd_get_dma_buffer(&dma_buf_size);
+ if (!hsphy_buf || dma_buf_size < HSPHY_PAYLOAD_SIZE) {
+ printk(BIOS_ERR, "DMA protection enabled but DMA buffer does not"
+ " exist or is too small\n");
+ printk(BIOS_ERR, "Aborting HSPHY firmware loading, "
+ "PCIe Gen5 won't work.\n");
+ return;
+ }
- if (!hsphy_buf) {
- printk(BIOS_ERR, "Could not allocate memory for HSPHY blob\n");
- printk(BIOS_ERR, "Aborting HSPHY firmware loading, PCIe Gen5 won't work.\n");
- return;
+ /* Rather impossible scenario, but check alignment anyways */
+ if (!IS_ALIGNED((uintptr_t)hsphy_buf, 4 * KiB) &&
+ (HSPHY_PAYLOAD_SIZE + 4 * KiB) <= dma_buf_size)
+ hsphy_buf = (void *)ALIGN_UP((uintptr_t)hsphy_buf, 4 * KiB);
+ } else {
+ /* Align the buffer to page size, otherwise the HECI command will fail */
+ hsphy_buf = memalign(4 * KiB, HSPHY_PAYLOAD_SIZE);
+
+ if (!hsphy_buf) {
+ printk(BIOS_ERR, "Could not allocate memory for HSPHY blob\n");
+ printk(BIOS_ERR, "Aborting HSPHY firmware loading, "
+ "PCIe Gen5 won't work.\n");
+ return;
+ }
}
memset(hsphy_buf, 0, HSPHY_PAYLOAD_SIZE);
@@ -186,8 +205,7 @@ void load_and_init_hsphy(void)
printk(BIOS_ERR, "%s: CSME not enabled or not visible, but required\n",
__func__);
printk(BIOS_ERR, "Aborting HSPHY firmware loading, PCIe Gen5 won't work.\n");
- free(hsphy_buf);
- return;
+ goto hsphy_exit;
}
/* Ensure BAR, BME and memory space are enabled */
@@ -203,17 +221,17 @@ void load_and_init_hsphy(void)
if (heci_get_hsphy_payload(hsphy_buf, &buf_size, hsphy_hash, &hash_type, &status)) {
printk(BIOS_ERR, "Aborting HSPHY firmware loading, PCIe Gen5 won't work.\n");
- free(hsphy_buf);
- return;
+ goto hsphy_exit;
}
if (verify_hsphy_hash(hsphy_buf, buf_size, hsphy_hash, hash_type)) {
printk(BIOS_ERR, "Aborting HSPHY firmware loading, PCIe Gen5 won't work.\n");
- free(hsphy_buf);
- return;
+ goto hsphy_exit;
}
upload_hsphy_to_cpu_pcie(hsphy_buf, buf_size);
- free(hsphy_buf);
+hsphy_exit:
+ if (!CONFIG(ENABLE_EARLY_DMA_PROTECTION))
+ free(hsphy_buf);
}