espi: Add support for debug helper to print slave capabilities

This change adds a Kconfig option to enable eSPI debugging that pulls
in a helper function to print slave capabilities.

BUG=b:153675913

Signed-off-by: Furquan Shaikh <furquan@google.com>
Change-Id: I8ff250fe85dfa9370bf93ce3c7e2de5c069bf9e9
Reviewed-on: https://review.coreboot.org/c/coreboot/+/41254
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Raul Rangel <rrangel@chromium.org>
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
diff --git a/src/include/espi.h b/src/include/espi.h
index f0ae373..7503af7 100644
--- a/src/include/espi.h
+++ b/src/include/espi.h
@@ -229,6 +229,12 @@
 #define  ESPI_VW_SIGNAL_HIGH(x)			(ESPI_VW_VALID(x) | ESPI_VW_VALUE(1, x))
 #define  ESPI_VW_SIGNAL_LOW(x)			(ESPI_VW_VALID(x) | ESPI_VW_VALUE(0, x))
 
+#if CONFIG(ESPI_DEBUG)
+void espi_show_slave_general_configuration(uint32_t config);
+#else
+static void espi_show_slave_general_configuration(uint32_t config) {}
+#endif
+
 static inline bool espi_slave_supports_quad_io(uint32_t gen_caps)
 {
 	uint32_t mode = gen_caps & ESPI_SLAVE_IO_MODE_SUPP_MASK;
diff --git a/src/lib/Kconfig b/src/lib/Kconfig
index dd9974a..a6fb1f1 100644
--- a/src/lib/Kconfig
+++ b/src/lib/Kconfig
@@ -75,3 +75,9 @@
 	  If your platform really doesn't want to use an FMAP cache (e.g. due to
 	  space constraints), you can select this to disable warnings and save
 	  a bit more code.
+
+config ESPI_DEBUG
+	bool
+	help
+	  This option enables eSPI library helper functions for displaying debug
+	  information.
diff --git a/src/lib/Makefile.inc b/src/lib/Makefile.inc
index f9bbebb..1fed543 100644
--- a/src/lib/Makefile.inc
+++ b/src/lib/Makefile.inc
@@ -162,6 +162,11 @@
 verstage-y += hexdump.c
 smm-y += hexdump.c
 
+bootblock-$(CONFIG_ESPI_DEBUG) += espi_debug.c
+verstage-$(CONFIG_ESPI_DEBUG) += espi_debug.c
+romstage-$(CONFIG_ESPI_DEBUG) += espi_debug.c
+ramstage-$(CONFIG_ESPI_DEBUG) += espi_debug.c
+
 bootblock-$(CONFIG_REG_SCRIPT) += reg_script.c
 verstage-$(CONFIG_REG_SCRIPT) += reg_script.c
 romstage-$(CONFIG_REG_SCRIPT) += reg_script.c
diff --git a/src/lib/espi_debug.c b/src/lib/espi_debug.c
new file mode 100644
index 0000000..63e16f4
--- /dev/null
+++ b/src/lib/espi_debug.c
@@ -0,0 +1,94 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/* This file is part of the coreboot project. */
+
+#include <console/console.h>
+#include <espi.h>
+#include <stdint.h>
+
+void espi_show_slave_general_configuration(uint32_t config)
+{
+	uint32_t io_mode;
+	uint32_t op_freq;
+
+	printk(BIOS_DEBUG, "eSPI Slave configuration:\n");
+
+	if (config & ESPI_SLAVE_CRC_ENABLE)
+		printk(BIOS_DEBUG, "    CRC checking enabled\n");
+
+	if (config & ESPI_SLAVE_RESP_MOD_ENABLE)
+		printk(BIOS_DEBUG, "    Response modifier enabled\n");
+
+	if (config & ESPI_SLAVE_ALERT_MODE_PIN)
+		printk(BIOS_DEBUG, "    Dedicated Alert# used to signal alert event\n");
+	else
+		printk(BIOS_DEBUG, "    IO bit1 pin used to signal alert event\n");
+
+	io_mode = config & ESPI_SLAVE_IO_MODE_SEL_MASK;
+	if (io_mode == ESPI_SLAVE_IO_MODE_SEL_SINGLE)
+		printk(BIOS_DEBUG, "    eSPI single IO mode selected\n");
+	else if (io_mode == ESPI_SLAVE_IO_MODE_SEL_DUAL)
+		printk(BIOS_DEBUG, "    eSPI dual IO mode selected\n");
+	else if (io_mode == ESPI_SLAVE_IO_MODE_SEL_QUAD)
+		printk(BIOS_DEBUG, "    eSPI quad IO mode selected\n");
+	else
+		printk(BIOS_DEBUG, "    Error: Invalid eSPI IO mode selected\n");
+
+	io_mode = config & ESPI_SLAVE_IO_MODE_SUPP_MASK;
+	if (io_mode == ESPI_SLAVE_IO_MODE_SUPP_SINGLE_QUAD)
+		printk(BIOS_DEBUG, "    eSPI quad and single IO modes supported\n");
+	else if (io_mode == ESPI_SLAVE_IO_MODE_SUPP_SINGLE_DUAL)
+		printk(BIOS_DEBUG, "    eSPI dual and single IO mode supported\n");
+	else if (io_mode == ESPI_SLAVE_IO_MODE_SUPP_SINGLE_DUAL_QUAD)
+		printk(BIOS_DEBUG, "    eSPI quad, dual, and single IO modes supported\n");
+	else
+		printk(BIOS_DEBUG, "    Only eSPI single IO mode supported\n");
+
+	if (config & ESPI_SLAVE_OPEN_DRAIN_ALERT_SEL)
+		printk(BIOS_DEBUG, "    Alert# pin is open-drain\n");
+	else
+		printk(BIOS_DEBUG, "    Alert# pin is driven\n");
+
+	op_freq = config & ESPI_SLAVE_OP_FREQ_SEL_MASK;
+	if (op_freq == ESPI_SLAVE_OP_FREQ_SEL_20_MHZ)
+		printk(BIOS_DEBUG, "    eSPI 20MHz selected\n");
+	else if (op_freq == ESPI_SLAVE_OP_FREQ_SEL_25_MHZ)
+		printk(BIOS_DEBUG, "    eSPI 25MHz selected\n");
+	else if (op_freq == ESPI_SLAVE_OP_FREQ_SEL_33_MHZ)
+		printk(BIOS_DEBUG, "    eSPI 33MHz selected\n");
+	else if (op_freq == ESPI_SLAVE_OP_FREQ_SEL_50_MHZ)
+		printk(BIOS_DEBUG, "    eSPI 50MHz selected\n");
+	else if (op_freq == ESPI_SLAVE_OP_FREQ_SEL_66_MHZ)
+		printk(BIOS_DEBUG, "    eSPI 66MHz selected\n");
+	else
+		printk(BIOS_DEBUG, "    Error: Invalid eSPI frequency\n");
+
+	if (config & ESPI_SLAVE_OPEN_DRAIN_ALERT_SUPP)
+		printk(BIOS_DEBUG, "    Open-drain Alert# pin supported\n");
+
+	op_freq = config & ESPI_SLAVE_OP_FREQ_SUPP_MASK;
+	if (op_freq == ESPI_SLAVE_OP_FREQ_SUPP_20_MHZ)
+		printk(BIOS_DEBUG, "    eSPI 20MHz supported\n");
+	else if (op_freq == ESPI_SLAVE_OP_FREQ_SUPP_25_MHZ)
+		printk(BIOS_DEBUG, "    eSPI 25MHz supported\n");
+	else if (op_freq == ESPI_SLAVE_OP_FREQ_SUPP_33_MHZ)
+		printk(BIOS_DEBUG, "    eSPI 33MHz supported\n");
+	else if (op_freq == ESPI_SLAVE_OP_FREQ_SUPP_50_MHZ)
+		printk(BIOS_DEBUG, "    eSPI 50MHz supported\n");
+	else if (op_freq == ESPI_SLAVE_OP_FREQ_SUPP_66_MHZ)
+		printk(BIOS_DEBUG, "    eSPI 66MHz supported\n");
+	else
+		printk(BIOS_DEBUG, "    Error: Invalid eSPI frequency\n");
+
+	printk(BIOS_DEBUG, "    Maximum Wait state: %d\n",
+	       (config & ESPI_SLAVE_MAX_WAIT_MASK) >> ESPI_SLAVE_MAX_WAIT_SHIFT);
+
+	if (config & ESPI_SLAVE_PERIPH_CH_SUPP)
+		printk(BIOS_DEBUG, "    Peripheral Channel supported\n");
+	if (config & ESPI_SLAVE_VW_CH_SUPP)
+		printk(BIOS_DEBUG, "    Virtual Wire Channel supported\n");
+	if (config & ESPI_SLAVE_OOB_CH_SUPP)
+		printk(BIOS_DEBUG, "    OOB Channel supported\n");
+	if (config & ESPI_SLAVE_FLASH_CH_SUPP)
+		printk(BIOS_DEBUG, "    Flash Access Channel supported\n");
+	printk(BIOS_DEBUG, "\n");
+}