[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