[coreboot-gerrit] Change in coreboot[master]: (WIP) soc/amd/common: Add PSP-to-BIOS mailbox
frank vibrans (Code Review)
gerrit at coreboot.org
Thu Oct 12 18:36:42 CEST 2017
frank vibrans has uploaded this change for review. ( https://review.coreboot.org/21993
Change subject: (WIP) soc/amd/common: Add PSP-to-BIOS mailbox
......................................................................
(WIP) soc/amd/common: Add PSP-to-BIOS mailbox
Add PSP-to-BIOS mailbox communications path. It is characterized and
enabled by the config value "HAVE_PSP2C_MBOX". It is initialized
via the SMI command port with the value APM_CNT_PSP_SMM_INIT. This
communications path allows the PSP to request services from the BIOS.
The request comes to the BIOS via an SMI and a data block located in
SMM space that the PSP can access.
TODO: Change the initialization mechanism to use the command
APM_CNT_GNVS_UPDATE that is not currently in place, and implement the
services available to the PSP.
Change-Id: I8e174b277cab45bf5e386425042e542cfef817e9
Signed-off-by: Frank Vibrans <frank.vibrans at scarletltd.com>
---
M src/soc/amd/common/block/include/amdblocks/psp.h
M src/soc/amd/common/block/psp/Kconfig
M src/soc/amd/common/block/psp/Makefile.inc
A src/soc/amd/common/block/psp/p2cmbox.c
M src/soc/amd/common/block/psp/psp.c
5 files changed, 215 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/93/21993/1
diff --git a/src/soc/amd/common/block/include/amdblocks/psp.h b/src/soc/amd/common/block/include/amdblocks/psp.h
index 7915b1f..8d731d6 100644
--- a/src/soc/amd/common/block/include/amdblocks/psp.h
+++ b/src/soc/amd/common/block/include/amdblocks/psp.h
@@ -31,6 +31,16 @@
#define MBOX_BIOS_CMD_NOP 0x09
#define MBOX_BIOS_CMD_ABORT 0xfe
+/* Definitions for MboxBiosCmdSmmInfo buffer - command 0x2 */
+#define PSP_SMMINFO_TYPE_IO 0
+#define PSP_SMMINFO_TYPE_MMIO 1
+#define PSP_SMMINFO_TYPE_PCI 2
+
+#define PSP_SMMINFO_WIDTH_BYTE 0
+#define PSP_SMMINFO_WIDTH_WORD 1
+#define PSP_SMMINFO_WIDTH_DWORD 2
+#define PSP_SMMINFO_WIDTH_QWORD 3
+
/* generic PSP interface status */
#define STATUS_INITIALIZED 0x1
#define STATUS_ERROR 0x2
@@ -91,6 +101,21 @@
struct smm_req_buffer req;
} __attribute__((packed));
+/* PSP-to-BIOS form of the mailbox. This differs from the BIOS-to-PSP form
+ * because the command/response buffer occurs at a fixed location in the
+ * mailbox data space (offset 8) rather than somewhere in the stack.
+ */
+struct p2c_cmd_resp {
+ struct mbox_buffer_header hdr;
+ u64 cmd_buf[1]; /* Placeholder for rest of P2C data space */
+} __packed;
+
+struct p2c_mbox {
+ u32 p2c_command;
+ u32 p2c_status;
+ struct p2c_cmd_resp response;
+} __packed;
+
/* send_psp_command() error codes */
#define PSPSTS_SUCCESS 0
#define PSPSTS_NOBASE 1
@@ -99,6 +124,21 @@
#define PSPSTS_SEND_ERROR 4
#define PSPSTS_INIT_TIMEOUT 5
#define PSPSTS_CMD_TIMEOUT 6
+
+/* Size of PSP data space located in SMM space */
+#define PSP_SMM_DATA_BLK_SIZE (4 * 1024)
+
+/* PSP to BIOS commands */
+#define PSP_GET_ATTRIBUTE 0x81
+#define PSP_SET_ATTRIBUTE 0x82 /* Not currently supported */
+#define PSP_GET_BLOCKSIZE 0x83
+#define PSP_READ_FW_VOLUME 0x84
+#define PSP_WRITE_FW_VOLUME 0x85
+#define PSP_ERASE_FW_VOLUME 0x86
+
+/* PSP to BIOS status bits */
+#define PSP_CMD_STATUS_CMD_READY (1 << 31)
+#define PSP_CMD_STATUS_CHKSUM_ENABLE (1 << 8)
#if !defined(__SIMPLE_DEVICE__)
#include <device/device.h>
@@ -138,4 +178,11 @@
int psp_notify_smm_info(uintptr_t base, size_t length, uintptr_t psp_data_base,
size_t psp_data_length, struct smm_trigger_info *smm_trig_info);
+/* TODO: Replace this with APM_CNT_GNVS_UPDATE */
+#define APM_CNT_PSP_SMM_INIT 0xd8
+
+/* PSP-to-BIOS related functions that run in SMM */
+void psp_smm_init(void);
+void psp_p2cmbox_event(void);
+
#endif /* __AMD_PSP_H__ */
diff --git a/src/soc/amd/common/block/psp/Kconfig b/src/soc/amd/common/block/psp/Kconfig
index 69958f2..db58683 100644
--- a/src/soc/amd/common/block/psp/Kconfig
+++ b/src/soc/amd/common/block/psp/Kconfig
@@ -4,3 +4,10 @@
help
This option builds in the Platform Security Processor initialization
functions.
+
+config HAVE_PSP2C_MBOX
+ bool
+ default n
+ help
+ This option builds in the PSP to BIOS mailbox functions needed for
+ PSP fTPM support.
diff --git a/src/soc/amd/common/block/psp/Makefile.inc b/src/soc/amd/common/block/psp/Makefile.inc
index b4f3b8d..1683e58 100644
--- a/src/soc/amd/common/block/psp/Makefile.inc
+++ b/src/soc/amd/common/block/psp/Makefile.inc
@@ -1,3 +1,4 @@
romstage-$(CONFIG_SOC_AMD_COMMON_BLOCK_PSP) += psp.c
ramstage-$(CONFIG_SOC_AMD_COMMON_BLOCK_PSP) += psp.c
smm-$(CONFIG_SOC_AMD_COMMON_BLOCK_PSP) += psp.c
+smm-$(CONFIG_HAVE_PSP2C_MBOX) += p2cmbox.c
diff --git a/src/soc/amd/common/block/psp/p2cmbox.c b/src/soc/amd/common/block/psp/p2cmbox.c
new file mode 100644
index 0000000..d9e49c9
--- /dev/null
+++ b/src/soc/amd/common/block/psp/p2cmbox.c
@@ -0,0 +1,147 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2017 Advanced Micro Devices, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <stddef.h>
+#include <arch/io.h>
+#include <console/console.h>
+#include <cpu/x86/msr.h>
+#include <cpu/amd/amdfam15.h>
+#include <amdblocks/psp.h>
+#include <soc/southbridge.h>
+#include <soc/smi.h>
+
+/* PSP uses psp_p2c_data as the PSP mailbox and command/response buffer
+ * for PSP-to-BIOS communications.
+ */
+uint8_t __attribute__ ((aligned (32))) psp_p2c_data[PSP_SMM_DATA_BLK_SIZE];
+
+static uint32_t get_p2c_command(struct p2c_mbox *mbox)
+{
+ return read32((uint32_t *)mbox->p2c_command);
+}
+
+static uint32_t get_p2c_cmdlen(struct p2c_mbox *mbox)
+{
+ return read32((uint32_t *)mbox->response.hdr.size);
+}
+
+static uint32_t get_p2c_status(struct p2c_mbox *mbox)
+{
+ return read32((uint32_t *)mbox->p2c_status);
+}
+
+static void set_p2c_status(struct p2c_mbox *mbox, uint32_t new_status)
+{
+ uint32_t status = read32((uint32_t *)mbox->p2c_status);
+ status |= new_status;
+ write32((uint32_t *)mbox->p2c_status,status);
+}
+
+static bool test_checksum(void *start, size_t len)
+{
+ uint8_t test_sum = 0;
+ uint8_t *tptr = start;
+ int i;
+
+ for (i = 0; i < len; i++) {
+ test_sum += read8(tptr + i);
+ };
+
+ return test_sum != 0;
+}
+
+void psp_p2cmbox_event(void)
+{
+ struct p2c_mbox *psp_p2c_mbox = (struct p2c_mbox *)&psp_p2c_data;
+
+ /* Check if a command is ready */
+ uint32_t cmd_status = get_p2c_status(psp_p2c_mbox);
+ if (!(cmd_status & PSP_CMD_STATUS_CMD_READY)) {
+ printk(BIOS_ERR, "PSP: Command not ready in SMI. ");
+ return;
+ }
+
+ /* Test checksum if necessary */
+ if (cmd_status & PSP_CMD_STATUS_CHKSUM_ENABLE) {
+ uint32_t length = get_p2c_cmdlen(psp_p2c_mbox);
+ if (test_checksum(psp_p2c_mbox, length)) {
+ printk(BIOS_ERR, "PSP: Checksum failure. ");
+ return;
+ }
+ };
+
+ uint32_t psp_cmd = get_p2c_command(psp_p2c_mbox);
+ /* TODO: Fill out this skeleton to provide the functionality suggested
+ * here.
+ */
+ switch (psp_cmd) {
+ case PSP_GET_ATTRIBUTE:
+ break;
+ case PSP_GET_BLOCKSIZE:
+ break;
+ case PSP_READ_FW_VOLUME:
+ break;
+ case PSP_WRITE_FW_VOLUME:
+ break;
+ case PSP_ERASE_FW_VOLUME:
+ break;
+ case PSP_SET_ATTRIBUTE: /* Not currently supported by PSP */
+ default:
+ break;
+ }
+}
+
+static void psp_p2cmbox_init(void)
+{
+ struct smm_trigger_info trig_info;
+
+ /* Have FakeSMI0 generate an SMI with status routed to SmiStatus4 */
+ configure_smi(SMITYPE_FAKE0, SMI_MODE_SMI);
+
+ /* Determine MBoxBiosCmdSmmInfo message parameters */
+ /* SMI trigger information */
+ trig_info.address = (uintptr_t)(APU_SMI_BASE + SMI_REG_SMITRIG0);
+ trig_info.address_type = PSP_SMMINFO_TYPE_MMIO;
+ trig_info.value_width = PSP_SMMINFO_WIDTH_DWORD;
+ trig_info.value_and_mask = ~SMITRG0_FAKE0;
+ trig_info.value_or_mask = SMITRG0_FAKE0;
+
+ /* TSEG information */
+ msr_t msr = rdmsr(MSR_TSEG_BASE);
+ uintptr_t tseg_base = ((uint64_t)msr.hi << 32) | (uint64_t)msr.lo;
+ msr = rdmsr(MSR_SMM_MASK);
+ /* Ignore mask bits 32-47 because a TSEG > 4GB is not likely. */
+ size_t tseg_length = ~msr.lo + 1;
+
+ /* PSP SMM data buffer information */
+ uintptr_t psp_data_base = (uintptr_t)&psp_p2c_data;
+ size_t psp_data_length = PSP_SMM_DATA_BLK_SIZE;
+
+ /* Send the MBoxBiosCmdSmmInfo command to the PSP. Failure is
+ * announced by printk in psp_notify_smm_info function.
+ */
+ if (psp_notify_smm_info(tseg_base, tseg_length, psp_data_base,
+ psp_data_length, (struct smm_trigger_info *)&trig_info))
+ return;
+
+ /* Tell the PSP the mailbox is initialized */
+ struct p2c_mbox *psp_p2c_mbox = (struct p2c_mbox *)&psp_p2c_data;
+ set_p2c_status(psp_p2c_mbox, STATUS_INITIALIZED);
+}
+
+void psp_smm_init(void)
+{
+ psp_p2cmbox_init();
+}
diff --git a/src/soc/amd/common/block/psp/psp.c b/src/soc/amd/common/block/psp/psp.c
index 5bbdf41..aa58030 100644
--- a/src/soc/amd/common/block/psp/psp.c
+++ b/src/soc/amd/common/block/psp/psp.c
@@ -16,10 +16,12 @@
#include <stddef.h>
#include <types.h>
#include <arch/io.h>
+#include <bootstate.h>
#include <timer.h>
#include <cpu/x86/msr.h>
#include <device/pci_def.h>
#include <console/console.h>
+#include <soc/smi.h>
#include <amdblocks/psp.h>
#if !ENV_SMM
# include <Porting.h>
@@ -259,3 +261,14 @@
return cmd_status;
}
+
+#if IS_ENABLED(CONFIG_HAVE_PSP2C_MBOX)
+static void psp_smm_initialize(void *unused)
+{
+ /* TODO: Replace APM_CNT_PSP_SMM_INIT with APM_CNT_GNVS_UPDATE */
+ /* Trigger SMI that starts PSP SMM initialization */
+ outb(APM_CNT_PSP_SMM_INIT, pm_acpi_smi_cmd_port());
+}
+
+BOOT_STATE_INIT_ENTRY(BS_DEV_INIT_CHIPS, BS_ON_EXIT, psp_smm_initialize, NULL);
+#endif
--
To view, visit https://review.coreboot.org/21993
To unsubscribe, visit https://review.coreboot.org/settings
Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: I8e174b277cab45bf5e386425042e542cfef817e9
Gerrit-Change-Number: 21993
Gerrit-PatchSet: 1
Gerrit-Owner: frank vibrans <frank.vibrans at scarletltd.com>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.coreboot.org/pipermail/coreboot-gerrit/attachments/20171012/2e9bdfc2/attachment-0001.html>
More information about the coreboot-gerrit
mailing list