[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