summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mainboard/protectli/vault_cml/mainboard.c93
1 files changed, 93 insertions, 0 deletions
diff --git a/src/mainboard/protectli/vault_cml/mainboard.c b/src/mainboard/protectli/vault_cml/mainboard.c
index 24f46c9013..1e06fc5fee 100644
--- a/src/mainboard/protectli/vault_cml/mainboard.c
+++ b/src/mainboard/protectli/vault_cml/mainboard.c
@@ -1,12 +1,30 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
+#include <console/console.h>
#include <cpu/x86/name.h>
#include <device/device.h>
+#include <device/mmio.h>
+#include <intelblocks/cse.h>
#include <pc80/i8254.h>
+#include <soc/intel/common/reset.h>
+#include <soc/ramstage.h>
+#include <fmap.h>
#include <smbios.h>
#include <string.h>
+static bool need_global_reset = false;
+
+/* Flash Master 1 : HOST/BIOS */
+#define FLMSTR1 0x80
+
+#define FLASH_SIGNATURE_OFFSET 0x10
+#define FLMSTR_WR_SHIFT_V2 20
+#define FLASH_SIGNATURE_VAL 0x0FF0A55A
+
+#define SI_DESC_SIZE (4 * KiB)
+#define SI_DESC_REGION "SI_DESC"
+
const char *smbios_mainboard_product_name(void)
{
char processor_name[49];
@@ -29,6 +47,81 @@ static void mainboard_final(void *unused)
beep(1500, 100);
}
+/* It checks whether host (Flash Master 1) has write access to the Descriptor Region or not */
+static bool is_descriptor_writeable(uint8_t *desc)
+{
+ /* Check flash has valid signature */
+ if (read32((void *)(desc + FLASH_SIGNATURE_OFFSET)) != FLASH_SIGNATURE_VAL) {
+ printk(BIOS_ERR, "Flash Descriptor is not valid\n");
+ printk(BIOS_ERR, "Descriptor needs to be fixed to ensure proper operation\n");
+ return false;
+ }
+
+ /* Check host has write access to the Descriptor Region */
+ if (!((read32((void *)(desc + FLMSTR1)) >> FLMSTR_WR_SHIFT_V2) & BIT(0))) {
+ printk(BIOS_ERR, "Host doesn't have write access to Descriptor Region\n");
+ return false;
+ }
+
+ return true;
+}
+
+static void configure_descriptor_for_lpc_tpm(void)
+{
+ uint8_t si_desc_buf[SI_DESC_SIZE];
+ struct region_device desc_rdev;
+
+ if (fmap_locate_area_as_rdev_rw(SI_DESC_REGION, &desc_rdev) < 0) {
+ printk(BIOS_ERR, "Failed to locate %s in the FMAP\n", SI_DESC_REGION);
+ return;
+ }
+
+ if (rdev_readat(&desc_rdev, si_desc_buf, 0, SI_DESC_SIZE) != SI_DESC_SIZE) {
+ printk(BIOS_ERR, "Failed to read Descriptor Region from SPI Flash\n");
+ return;
+ }
+
+ if (!is_descriptor_writeable(si_desc_buf))
+ return;
+
+ /* Disable SPI TPM if necessary */
+ if ((si_desc_buf[0x1f0] & 0xfe) == si_desc_buf[0x1f0]) {
+ printk(BIOS_DEBUG, "Update of Descriptor is not required!\n");
+ return;
+ }
+
+ si_desc_buf[0x1f0] &= 0xfe;
+
+ if (rdev_eraseat(&desc_rdev, 0, SI_DESC_SIZE) != SI_DESC_SIZE) {
+ printk(BIOS_ERR, "Failed to erase Descriptor Region area\n");
+ return;
+ }
+
+ if (rdev_writeat(&desc_rdev, si_desc_buf, 0, SI_DESC_SIZE) != SI_DESC_SIZE) {
+ printk(BIOS_ERR, "Failed to update Descriptor Region\n");
+ return;
+ }
+
+ printk(BIOS_DEBUG, "Update of Descriptor successful\n");
+ need_global_reset = true;
+}
+
+void mainboard_silicon_init_params(FSPS_UPD *supd)
+{
+ /* Call it right before Silicon Init, so that we avoid EOP */
+ configure_descriptor_for_lpc_tpm();
+ cse_enable_ptt(false);
+ /*
+ * We wait with global reset after descriptor update until PTT state change to avoid
+ * double global reset. In case PTT was already disabled or cse_enable_ptt will fail
+ * for some reason, but descriptor has been updated we need to do global reset here,
+ * otherwise cse_enable_ptt will do the global reset and the branch below won't be
+ * reached.
+ */
+ if (need_global_reset)
+ do_global_reset();
+}
+
struct chip_operations mainboard_ops = {
.final = mainboard_final,
};