Srinidhi N Kaushik has uploaded this change for review.

View Change

soc/intel/common/dmi: Add DMI driver support

This is change allows configuring the General Purpose
Memory Range(GPMR) register in BIOS to set up the decoding of extended
BIOS region in DMI.
This driver provides the following functionality:
1. Add a helper function dmi_enable_gpmr which takes as input base, limit
and destination ID to configure in general purpose memory range
registers. It can ensure that the PCR base address is configured and
then set the GPMR registers in the next available free GMPR and enable
the decoding.
2. Add helper function get_available_gpmr which returns available free
GPMR.
2. This helper function can be utilized by the fast SPI driver to
configure the window for the extended BIOS region.

BUG=b:171534504

Signed-off-by: Srinidhi N Kaushik <srinidhi.n.kaushik@intel.com>
Change-Id: I34a894e295ecb98fbc4a81282361e851c436a403
---
A src/soc/intel/common/block/dmi/Kconfig
A src/soc/intel/common/block/dmi/Makefile.inc
A src/soc/intel/common/block/dmi/dmi.c
A src/soc/intel/common/block/include/intelblocks/dmi.h
M src/soc/intel/common/pch/Kconfig
5 files changed, 88 insertions(+), 0 deletions(-)

git pull ssh://review.coreboot.org:29418/coreboot refs/changes/88/47988/1
diff --git a/src/soc/intel/common/block/dmi/Kconfig b/src/soc/intel/common/block/dmi/Kconfig
new file mode 100644
index 0000000..2cc4646
--- /dev/null
+++ b/src/soc/intel/common/block/dmi/Kconfig
@@ -0,0 +1,5 @@
+config SOC_INTEL_COMMON_BLOCK_DMI
+ bool
+ select SOC_INTEL_COMMON_BLOCK_PCR
+ help
+ Intel Processor common DMI support
diff --git a/src/soc/intel/common/block/dmi/Makefile.inc b/src/soc/intel/common/block/dmi/Makefile.inc
new file mode 100644
index 0000000..99a1c18
--- /dev/null
+++ b/src/soc/intel/common/block/dmi/Makefile.inc
@@ -0,0 +1,10 @@
+ifeq ($(CONFIG_SOC_INTEL_COMMON_BLOCK_DMI), y)
+
+bootblock-$(CONFIG_SOC_INTEL_COMMON_BLOCK_DMI) += dmi.c
+romstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_DMI) += dmi.c
+ramstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_DMI) += dmi.c
+smm-$(CONFIG_SOC_INTEL_COMMON_BLOCK_DMI) += dmi.c
+postcar-$(CONFIG_SOC_INTEL_COMMON_BLOCK_DMI) += dmi.c
+verstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_DMI) += dmi.c
+
+endif
diff --git a/src/soc/intel/common/block/dmi/dmi.c b/src/soc/intel/common/block/dmi/dmi.c
new file mode 100644
index 0000000..eac86e8
--- /dev/null
+++ b/src/soc/intel/common/block/dmi/dmi.c
@@ -0,0 +1,58 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <console/console.h>
+#include <intelblocks/dmi.h>
+#include <intelblocks/pcr.h>
+#include <soc/pcr_ids.h>
+
+#define MAX_GPMR_REGS 2 /* 3 GPMR registers */
+#define GPMR_OFFSET(x) (0x277c + (x)*8)
+#define GPMR_DID_OFFSET(x) (0x2780 + (x)*8)
+#define DMI_PCR_GPMR_BASE_SHIFT 16
+#define DMI_PCR_GPMR_LIMIT_MASK 0xffff0000
+#define DMI_PCR_GPMR_BASE_MASK 0xffff
+#define DMI_PCR_GPMR_EN BIT(31)
+
+/* GPMR Register read given offset */
+static uint32_t gpmr_read32(uint16_t offset)
+{
+ return pcr_read32(PID_DMI, offset);
+}
+
+/* GPMR Register write given offset and val */
+static void gpmr_write32(uint16_t offset, uint32_t val)
+{
+ return pcr_write32(PID_DMI, offset, val);
+}
+
+/* Check for available free gpmr */
+static uint32_t get_available_gpmr(void)
+{
+ int i;
+ uint32_t val;
+
+ for (i = 0; i <= MAX_GPMR_REGS; i++) {
+ val = gpmr_read32(GPMR_DID_OFFSET(i));
+ if (!(val & DMI_PCR_GPMR_EN))
+ return i;
+ }
+ printk(BIOS_ERR, "get_available_gpmr: No available free gpmr found \n");
+ return -1;
+}
+
+/* Configure GPMR for the given base and size of extended BIOS Region */
+void dmi_enable_gpmr(uint32_t base, uint32_t size, uint32_t dest_id)
+{
+ uint32_t gpmr_num;
+
+ /* Get available free GPMR */
+ gpmr_num = get_available_gpmr();
+
+ /* Program Range for the given decode window */
+ gpmr_write32(GPMR_OFFSET(gpmr_num),
+ (size & DMI_PCR_GPMR_LIMIT_MASK) |
+ ((base >> DMI_PCR_GPMR_BASE_SHIFT) & DMI_PCR_GPMR_BASE_MASK));
+
+ /* Program source decode enable bit and the Destination ID */
+ gpmr_write32(GPMR_DID_OFFSET(gpmr_num), dest_id | DMI_PCR_GPMR_EN);
+}
diff --git a/src/soc/intel/common/block/include/intelblocks/dmi.h b/src/soc/intel/common/block/include/intelblocks/dmi.h
new file mode 100644
index 0000000..629d1a6
--- /dev/null
+++ b/src/soc/intel/common/block/include/intelblocks/dmi.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef SOC_INTEL_COMMON_BLOCK_DMI_H
+#define SOC_INTEL_COMMON_BLOCK_DMI_H
+
+#include <types.h>
+
+/*
+ * Takes base, size and destination ID and configures the GPMR
+ * for accessing the region.
+ */
+void dmi_enable_gpmr(uint32_t base, uint32_t size, uint32_t dest_id);
+
+#endif /* SOC_INTEL_COMMON_BLOCK_DMI_H */
diff --git a/src/soc/intel/common/pch/Kconfig b/src/soc/intel/common/pch/Kconfig
index cca65d6..b00fc8b 100644
--- a/src/soc/intel/common/pch/Kconfig
+++ b/src/soc/intel/common/pch/Kconfig
@@ -19,6 +19,7 @@
select SOC_INTEL_COMMON_BLOCK_CHIP_CONFIG
select SOC_INTEL_COMMON_BLOCK_CSE
select SOC_INTEL_COMMON_BLOCK_DSP
+ select SOC_INTEL_COMMON_BLOCK_DMI
select SOC_INTEL_COMMON_BLOCK_FAST_SPI
select SOC_INTEL_COMMON_BLOCK_GPIO
select SOC_INTEL_COMMON_BLOCK_GPIO_ITSS_POL_CFG

To view, visit change 47988. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Change-Id: I34a894e295ecb98fbc4a81282361e851c436a403
Gerrit-Change-Number: 47988
Gerrit-PatchSet: 1
Gerrit-Owner: Srinidhi N Kaushik <srinidhi.n.kaushik@intel.com>
Gerrit-MessageType: newchange