From 41aa8d60355c16959e63ae9f0bad65efd4cc64f5 Mon Sep 17 00:00:00 2001 From: John Zhao Date: Thu, 20 Jan 2022 11:29:18 -0800 Subject: [PATCH] soc/intel/common: Add the Primary to Sideband bridge library New platforms have additional Primary to Sideband bridge besides the PCH P2SB. This change puts the common functions into the P2SB library. BUG=b:213574324 TEST=Build platforms coreboot images successfully. Signed-off-by: John Zhao Change-Id: I63f58584e8c3bfe42cdd81912e1e5140337c2d55 Reviewed-on: https://review.coreboot.org/c/coreboot/+/61283 Tested-by: build bot (Jenkins) Reviewed-by: EricR Lai Reviewed-by: Wonkyu Kim Reviewed-by: Subrata Banik Reviewed-by: Angel Pons --- .../common/block/include/intelblocks/p2sb.h | 1 - .../block/include/intelblocks/p2sblib.h | 19 ++++ src/soc/intel/common/block/p2sb/Makefile.inc | 12 ++- src/soc/intel/common/block/p2sb/p2sb.c | 46 ++-------- src/soc/intel/common/block/p2sb/p2sblib.c | 92 +++++++++++++++++++ 5 files changed, 126 insertions(+), 44 deletions(-) create mode 100644 src/soc/intel/common/block/include/intelblocks/p2sblib.h create mode 100644 src/soc/intel/common/block/p2sb/p2sblib.c diff --git a/src/soc/intel/common/block/include/intelblocks/p2sb.h b/src/soc/intel/common/block/include/intelblocks/p2sb.h index 436861c924..b330ccdc54 100644 --- a/src/soc/intel/common/block/include/intelblocks/p2sb.h +++ b/src/soc/intel/common/block/include/intelblocks/p2sb.h @@ -43,7 +43,6 @@ void p2sb_set_hpet_bdf(union p2sb_bdf bdf); union p2sb_bdf p2sb_get_ioapic_bdf(void); void p2sb_set_ioapic_bdf(union p2sb_bdf bdf); - /* SOC overrides */ /* * Each SoC should implement EP Mask register to disable SB access diff --git a/src/soc/intel/common/block/include/intelblocks/p2sblib.h b/src/soc/intel/common/block/include/intelblocks/p2sblib.h new file mode 100644 index 0000000000..7df528d20d --- /dev/null +++ b/src/soc/intel/common/block/include/intelblocks/p2sblib.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef SOC_INTEL_COMMON_BLOCK_P2SBLIB_H +#define SOC_INTEL_COMMON_BLOCK_P2SBLIB_H + +#include +#include + +/* P2SB generic configuration register */ +#define P2SBC 0xe0 +#define P2SBC_HIDE_BIT (1 << 0) + +bool p2sb_dev_is_hidden(pci_devfn_t dev); +void p2sb_dev_unhide(pci_devfn_t dev); +void p2sb_dev_hide(pci_devfn_t dev); +uint32_t p2sb_dev_sbi_read(pci_devfn_t dev, uint8_t pid, uint16_t reg); +void p2sb_dev_sbi_write(pci_devfn_t dev, uint8_t pid, uint16_t reg, uint32_t val); + +#endif /* SOC_INTEL_COMMON_BLOCK_P2SBLIB_H */ diff --git a/src/soc/intel/common/block/p2sb/Makefile.inc b/src/soc/intel/common/block/p2sb/Makefile.inc index d557e36833..5c6378e2a4 100644 --- a/src/soc/intel/common/block/p2sb/Makefile.inc +++ b/src/soc/intel/common/block/p2sb/Makefile.inc @@ -1,4 +1,8 @@ -bootblock-$(CONFIG_SOC_INTEL_COMMON_BLOCK_P2SB) += p2sb.c -romstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_P2SB) += p2sb.c -ramstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_P2SB) += p2sb.c -smm-$(CONFIG_SOC_INTEL_COMMON_BLOCK_P2SB) += p2sb.c +ifeq ($(CONFIG_SOC_INTEL_COMMON_BLOCK_P2SB),y) +bootblock-y += p2sb.c +romstage-y += p2sb.c +ramstage-y += p2sb.c +ramstage-y += p2sblib.c +smm-y += p2sb.c +smm-y += p2sblib.c +endif diff --git a/src/soc/intel/common/block/p2sb/p2sb.c b/src/soc/intel/common/block/p2sb/p2sb.c index a9384aeb64..16da6911c9 100644 --- a/src/soc/intel/common/block/p2sb/p2sb.c +++ b/src/soc/intel/common/block/p2sb/p2sb.c @@ -1,11 +1,14 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#define __SIMPLE_DEVICE__ + #include #include #include #include #include #include +#include #include #include #include @@ -13,20 +16,6 @@ #define PCH_P2SB_EPMASK(mask_number) (PCH_P2SB_EPMASK0 + ((mask_number) * 4)) -#define HIDE_BIT (1 << 0) - -static bool p2sb_is_hidden(void) -{ - const uint16_t pci_vid = pci_read_config16(PCH_DEV_P2SB, PCI_VENDOR_ID); - - if (pci_vid == 0xffff) - return true; - if (pci_vid == PCI_VENDOR_ID_INTEL) - return false; - printk(BIOS_ERR, "P2SB PCI_VENDOR_ID is invalid, unknown if hidden\n"); - return true; -} - void p2sb_enable_bar(void) { /* Enable PCR Base address in PCH */ @@ -56,7 +45,7 @@ void p2sb_configure_hpet(void) union p2sb_bdf p2sb_get_hpet_bdf(void) { - const bool was_hidden = p2sb_is_hidden(); + const bool was_hidden = p2sb_dev_is_hidden(PCH_DEV_P2SB); if (was_hidden) p2sb_unhide(); @@ -75,7 +64,7 @@ void p2sb_set_hpet_bdf(union p2sb_bdf bdf) union p2sb_bdf p2sb_get_ioapic_bdf(void) { - const bool was_hidden = p2sb_is_hidden(); + const bool was_hidden = p2sb_dev_is_hidden(PCH_DEV_P2SB); if (was_hidden) p2sb_unhide(); @@ -92,35 +81,14 @@ void p2sb_set_ioapic_bdf(union p2sb_bdf bdf) pci_write_config16(PCH_DEV_P2SB, PCH_P2SB_IBDF, bdf.raw); } -static void p2sb_set_hide_bit(int hide) -{ - const uint16_t reg = PCH_P2SB_E0 + 1; - const uint8_t mask = HIDE_BIT; - uint8_t val; - - val = pci_read_config8(PCH_DEV_P2SB, reg); - val &= ~mask; - if (hide) - val |= mask; - pci_write_config8(PCH_DEV_P2SB, reg, val); -} - void p2sb_unhide(void) { - p2sb_set_hide_bit(0); - - if (p2sb_is_hidden()) - die_with_post_code(POST_HW_INIT_FAILURE, - "Unable to unhide PCH_DEV_P2SB device !\n"); + p2sb_dev_unhide(PCH_DEV_P2SB); } void p2sb_hide(void) { - p2sb_set_hide_bit(1); - - if (!p2sb_is_hidden()) - die_with_post_code(POST_HW_INIT_FAILURE, - "Unable to hide PCH_DEV_P2SB device !\n"); + p2sb_dev_hide(PCH_DEV_P2SB); } static void p2sb_configure_endpoints(int epmask_id, uint32_t mask) diff --git a/src/soc/intel/common/block/p2sb/p2sblib.c b/src/soc/intel/common/block/p2sb/p2sblib.c new file mode 100644 index 0000000000..d00606dd89 --- /dev/null +++ b/src/soc/intel/common/block/p2sb/p2sblib.c @@ -0,0 +1,92 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#define __SIMPLE_DEVICE__ + +#include +#include +#include +#include +#include +#include +#include + +bool p2sb_dev_is_hidden(pci_devfn_t dev) +{ + const uint16_t pci_vid = pci_read_config16(dev, PCI_VENDOR_ID); + + if (pci_vid == 0xffff) + return true; + if (pci_vid == PCI_VENDOR_ID_INTEL) + return false; + printk(BIOS_ERR, "P2SB PCI_VENDOR_ID is invalid, unknown if hidden\n"); + return true; +} + +static void p2sb_dev_set_hide_bit(pci_devfn_t dev, int hide) +{ + const uint16_t reg = P2SBC + 1; + const uint8_t mask = P2SBC_HIDE_BIT; + uint8_t val; + + val = pci_read_config8(dev, reg); + val &= ~mask; + if (hide) + val |= mask; + pci_write_config8(dev, reg, val); +} + +void p2sb_dev_unhide(pci_devfn_t dev) +{ + p2sb_dev_set_hide_bit(dev, 0); + + if (p2sb_dev_is_hidden(dev)) + die_with_post_code(POST_HW_INIT_FAILURE, + "Unable to unhide the P2SB device!\n"); +} + +void p2sb_dev_hide(pci_devfn_t dev) +{ + p2sb_dev_set_hide_bit(dev, 1); + + if (!p2sb_dev_is_hidden(dev)) + die_with_post_code(POST_HW_INIT_FAILURE, + "Unable to hide the P2SB device!\n"); +} + +static void p2sb_execute_sideband_access(pci_devfn_t dev, uint8_t cmd, uint8_t pid, + uint16_t reg, uint32_t *data) +{ + struct pcr_sbi_msg msg = { + .pid = pid, + .offset = reg, + .opcode = cmd, + .is_posted = false, + .fast_byte_enable = 0xF, + .bar = 0, + .fid = 0 + }; + uint8_t response; + int status; + + /* Unhide the P2SB device */ + p2sb_dev_unhide(dev); + + status = pcr_execute_sideband_msg(dev, &msg, data, &response); + if (status || response) + printk(BIOS_ERR, "Fail to execute p2sb sideband access\n"); + + /* Hide the P2SB device */ + p2sb_dev_hide(dev); +} + +uint32_t p2sb_dev_sbi_read(pci_devfn_t dev, uint8_t pid, uint16_t reg) +{ + uint32_t val = 0; + p2sb_execute_sideband_access(dev, PCR_READ, pid, reg, &val); + return val; +} + +void p2sb_dev_sbi_write(pci_devfn_t dev, uint8_t pid, uint16_t reg, uint32_t val) +{ + p2sb_execute_sideband_access(dev, PCR_WRITE, pid, reg, &val); +}