[coreboot-gerrit] Change in coreboot[master]: soc/intel/common/block/pcr: Function for executing PCH SBI message

Subrata Banik (Code Review) gerrit at coreboot.org
Mon Feb 19 11:27:06 CET 2018


Subrata Banik has uploaded this change for review. ( https://review.coreboot.org/23809


Change subject: soc/intel/common/block/pcr: Function for executing PCH SBI message
......................................................................

soc/intel/common/block/pcr: Function for executing PCH SBI message

This function to perform SBI communication

Input:
 * PID: Port ID of the SBI message
 * Offset: Register offset of the SBI message
 * Opcode: Opcode
 * Posted: Posted message
 * Fast_Byte_Enable: First Byte Enable
 * BAR: base address
 * FID: Function ID
 * Data: Read/Write Data
 * Response: Response

Output:
 * 0: SBI message is Successfully completed
 * -1: SBI message failure

Change-Id: I4e49311564e20cedbfabaaceaf5f72c480e5ea26
Signed-off-by: Subrata Banik <subrata.banik at intel.com>
---
M src/soc/intel/common/block/include/intelblocks/pcr.h
M src/soc/intel/common/block/pcr/pcr.c
2 files changed, 233 insertions(+), 0 deletions(-)



  git pull ssh://review.coreboot.org:29418/coreboot refs/changes/09/23809/1

diff --git a/src/soc/intel/common/block/include/intelblocks/pcr.h b/src/soc/intel/common/block/include/intelblocks/pcr.h
index cfe0015..0127f17 100644
--- a/src/soc/intel/common/block/include/intelblocks/pcr.h
+++ b/src/soc/intel/common/block/include/intelblocks/pcr.h
@@ -38,6 +38,39 @@
 void pcr_or16(uint8_t pid, uint16_t offset, uint16_t ordata);
 void pcr_or8(uint8_t pid, uint16_t offset, uint8_t ordata);
 
+/* SBI command */
+enum {
+	MEM_READ = 0,
+	MEM_WRITE = 1,
+	PCI_CONFIG_READ = 4,
+	PCI_CONFIG_WRITE = 5,
+	PCR_READ = 6,
+	PCR_WRITE = 7,
+	GPIO_LOCK_UNLOCK = 13,
+};
+
+/*
+ * API to perform sideband communication
+ *
+ * Input:
+ * PID: Port ID of the SBI message
+ * Offset: Register offset of the SBI message
+ * Opcode: Opcode
+ * Posted: Posted message
+ * Fast_Byte_Enable: First Byte Enable
+ * BAR: base address
+ * FID: Function ID
+ * Data: Read/Write Data
+ * Response: Response
+ *
+ * Output:
+ * 0: SBI message is Successfully completed
+ * -1: SBI message failure
+ */
+int pcr_execute_sideband_msg(uint8_t pid, uint32_t offset, uint8_t opcode,
+		bool is_posted, uint16_t fast_byte_enable, uint16_t bar,
+		uint16_t fid, uint32_t *data, uint8_t *response);
+
 /* Get the starting address of the port's registers. */
 void *pcr_reg_address(uint8_t pid, uint16_t offset);
 #endif /* if !defined(__ACPI__) */
diff --git a/src/soc/intel/common/block/pcr/pcr.c b/src/soc/intel/common/block/pcr/pcr.c
index 4264cdf..28c93c2 100644
--- a/src/soc/intel/common/block/pcr/pcr.c
+++ b/src/soc/intel/common/block/pcr/pcr.c
@@ -15,13 +15,41 @@
 
 #include <arch/io.h>
 #include <assert.h>
+#include <console/console.h>
 #include <intelblocks/pcr.h>
+#include <soc/pci_devs.h>
 #include <soc/pcr_ids.h>
 
 #if !defined(CONFIG_PCR_BASE_ADDRESS) || (CONFIG_PCR_BASE_ADDRESS == 0)
 #error "PCR_BASE_ADDRESS need to be non-zero!"
 #endif
 
+/* P2SB PCI configuration register */
+#define P2SB_CR_SBI_ADDR	0xd0
+#define  P2SB_CR_SBI_DESTID	24
+#define P2SB_CR_SBI_DATA	0xd4
+#define P2SB_CR_SBI_STATUS	0xd8
+/* Bit 15:8 */
+#define  P2SB_CR_SBI_OPCODE	8
+/* Bit 7 */
+#define  P2SB_CR_SBI_POSTED	7
+/* Bit 2-1 */
+#define  P2SB_CR_SBI_STATUS_SUCCESS	0
+#define  P2SB_CR_SBI_STATUS_NOT_SUPPORTED	1
+#define  P2SB_CR_SBI_STATUS_POWERED_DOWN	2
+#define  P2SB_CR_SBI_STATUS_MULTI_CAST_MIXED	3
+/* Bit 0 */
+#define  P2SB_CR_SBI_STATUS_READY	0
+#define  P2SB_CR_SBI_STATUS_BUSY	1
+#define P2SB_CR_SBI_ROUTE_IDEN	0xda
+/* Bit 15-12 */
+#define  P2SB_CR_SBI_FBE	12
+/* Bit 10-8 */
+#define  P2SB_CR_SBI_BAR	8
+/* Bit 7-0 */
+#define  P2SB_CR_SBI_FID	0
+#define P2SB_CR_SBI_EXT_ADDR	0xdc
+
 static void *__pcr_reg_address(uint8_t pid, uint16_t offset)
 {
 	uintptr_t reg_addr;
@@ -178,3 +206,175 @@
 	data8 |= ordata;
 	pcr_write8(pid, offset, data8);
 }
+
+static int pcr_check_for_timeout(device_t dev)
+{
+	uint32_t	timeout;
+
+	timeout = 0xFFFFFFF;
+	while (timeout > 0) {
+		if ((pci_read_config16 (dev, P2SB_CR_SBI_STATUS) &
+				P2SB_CR_SBI_STATUS_BUSY) == 0)
+			break;
+		timeout--;
+	}
+
+	/* Timed out */
+	if (timeout == 0)
+		return -1;
+
+	return 0;
+}
+
+/*
+ * API to perform sideband communication
+ *
+ * Input:
+ * PID: Port ID of the SBI message
+ * Offset: Register offset of the SBI message
+ * Opcode: Opcode
+ * Posted: Posted message
+ * Fast_Byte_Enable: First Byte Enable
+ * BAR: base address
+ * FID: Function ID
+ * Data: Read/Write Data
+ * Response: Response
+ *
+ * Output:
+ * 0: SBI message is Successfully completed
+ * -1: SBI message failure
+ */
+int pcr_execute_sideband_msg(uint8_t pid, uint32_t offset, uint8_t opcode,
+		bool is_posted, uint16_t fast_byte_enable, uint16_t bar,
+		uint16_t fid, uint32_t *data, uint8_t *response)
+{
+	device_t dev = PCH_DEV_P2SB;
+	uint32_t sbi_data;
+	uint16_t sbi_status;
+
+	switch(opcode) {
+		case MEM_READ:
+		case MEM_WRITE:
+		case PCI_CONFIG_READ:
+		case PCI_CONFIG_WRITE:
+		case PCR_READ:
+		case PCR_WRITE:
+		case GPIO_LOCK_UNLOCK:
+			break;
+		default:
+			printk(BIOS_DEBUG, "SBI Failure: Wrong Input!\n");
+			return -1;
+			break;
+	}
+
+	if (pci_read_config16(dev, PCI_VENDOR_ID) == 0xffff) {
+		printk(BIOS_DEBUG, "SBI Failure: P2SB device Hidden!\n");
+		return -1;
+	}
+
+	/*
+	 * BWG Section 2.2.1
+	 * 1. Poll P2SB PCI offset D8h[0] = 0b
+	 * Make sure the previous opeartion is completed.
+	 */
+	if (pcr_check_for_timeout(dev)) {
+		printk(BIOS_DEBUG, "SBI Failure: Time Out!\n");
+		return -1;
+	}
+
+	/* Initial Response status */
+	*response = 0xFF;
+	sbi_status = 0;
+
+	/*
+	 * 2. Write P2SB PCI offset D0h[31:0] with Address
+	 * and Destination Port ID
+	 */
+	pci_write_config32 (dev, P2SB_CR_SBI_ADDR,
+		(uint32_t) ((pid << P2SB_CR_SBI_DESTID) | (uint16_t) offset));
+
+	/*
+	 * 3. Write P2SB PCI offset DCh[31:0] with extended address,
+	 * which is expected to be 0 in CNL PCH
+	 */
+	pci_write_config32 (dev, P2SB_CR_SBI_EXT_ADDR,
+		(uint32_t) (offset >> 16));
+
+	/*
+	 * 4. Set P2SB PCI offset D8h[15:8] = 00000110b for read
+	 *    Set P2SB PCI offset D8h[15:8] = 00000111b for write
+	 *
+	 * Set SBISTAT[15:8] to the opcode passed in
+	 * Set SBISTAT[7] to the posted passed in
+	 */
+	sbi_status = pci_read_config16 (dev, P2SB_CR_SBI_STATUS);
+	sbi_status &= ~(0xFF00 | (1 << P2SB_CR_SBI_POSTED));
+	sbi_status |= ((opcode << P2SB_CR_SBI_OPCODE) |
+				(is_posted << P2SB_CR_SBI_POSTED));
+	pci_write_config16 (dev, P2SB_CR_SBI_STATUS, sbi_status);
+
+	/*
+	 * 5. Write P2SB PCI offset DAh[15:0] = F000h
+	 *
+	 * Set RID[15:0] = Fbe << 12 | Bar << 8 | Fid
+	 */
+	pci_write_config16 (dev, P2SB_CR_SBI_ROUTE_IDEN, (uint16_t) (
+			((fast_byte_enable & 0x000F) << P2SB_CR_SBI_FBE) |
+			((bar & 0x0007) << P2SB_CR_SBI_BAR) |
+			(fid & 0x00FF)));
+
+	switch(opcode) {
+		case MEM_WRITE:
+		case PCI_CONFIG_WRITE:
+		case PCR_WRITE:
+			/*
+			 * 6. Write P2SB PCI offset D4h[31:0] with the
+			 * intended data accordingly
+			 */
+			sbi_data = *data;
+			pci_write_config32 (dev, P2SB_CR_SBI_DATA, sbi_data);
+			break;
+		default:
+			/* 6. Write P2SB PCI offset D4h[31:0] with dummy data */
+			sbi_data = 0;
+			pci_write_config32 (dev, P2SB_CR_SBI_DATA, sbi_data);
+			break;
+	}
+
+	/*
+	 * 7. Set P2SB PCI offset D8h[0] = 1b, Poll P2SB PCI offset D8h[0] = 0b
+	 *
+	 * Set SBISTAT[0] = 1b, trigger the SBI operation
+	 */
+	sbi_status = pci_read_config16 (dev, P2SB_CR_SBI_STATUS);
+	sbi_status |= P2SB_CR_SBI_STATUS_BUSY;
+	pci_write_config16 (dev, P2SB_CR_SBI_STATUS, sbi_status);
+
+	/* Poll SBISTAT[0] = 0b, Polling for Busy bit */
+	if (pcr_check_for_timeout(dev)) {
+		printk(BIOS_DEBUG, "SBI Failure: Time Out!\n");
+		return -1;
+	}
+
+	/*
+	 * 8. Check if P2SB PCI offset D8h[2:1] = 00b for
+	 * successful transaction
+	 */
+	*response = (uint8_t) ((sbi_status & 0x0006) >> 1);
+	if (*response == P2SB_CR_SBI_STATUS_SUCCESS) {
+		switch(opcode) {
+		case MEM_READ:
+		case PCI_CONFIG_READ:
+		case PCR_READ:
+			sbi_data = pci_read_config32 (dev, P2SB_CR_SBI_DATA);
+			*data = sbi_data;
+			break;
+		default:
+			break;
+		}
+		return 0;
+	} else {
+		printk(BIOS_DEBUG, "SBI Failure: Transaction Failure!\n");
+		return -1;
+	}
+}

-- 
To view, visit https://review.coreboot.org/23809
To unsubscribe, or for help writing mail filters, visit https://review.coreboot.org/settings

Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: I4e49311564e20cedbfabaaceaf5f72c480e5ea26
Gerrit-Change-Number: 23809
Gerrit-PatchSet: 1
Gerrit-Owner: Subrata Banik <subrata.banik at intel.com>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.coreboot.org/pipermail/coreboot-gerrit/attachments/20180219/9e15fd74/attachment-0001.html>


More information about the coreboot-gerrit mailing list