diff options
author | Subrata Banik <subrata.banik@intel.com> | 2018-05-07 17:13:40 +0530 |
---|---|---|
committer | Subrata Banik <subrata.banik@intel.com> | 2018-06-28 08:35:29 +0000 |
commit | 7837c203d615fce03c6d89d99ba9a746619e49d4 (patch) | |
tree | ba3626a10a35bd99108228611b18e7f76b7abd02 /src/soc/intel/common/block | |
parent | 210b351df3cc070f103feb01a40be9811af87906 (diff) |
soc/intel/common/block: Move p2sb common functions into block/p2sb
This patch cleans soc/intel/{apollolake/cannonlake/skylake} by moving
common soc code into common/block/p2sb.
BUG=b:78109109
BRANCH=none
TEST=Build and boot KBL/CNL/APL platform.
Change-Id: Ie9fd933d155b3fcd0d616b41cdf042cefe2c649a
Signed-off-by: Subrata Banik <subrata.banik@intel.com>
Reviewed-on: https://review.coreboot.org/26132
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Furquan Shaikh <furquan@google.com>
Diffstat (limited to 'src/soc/intel/common/block')
-rw-r--r-- | src/soc/intel/common/block/include/intelblocks/p2sb.h | 32 | ||||
-rw-r--r-- | src/soc/intel/common/block/p2sb/Makefile.inc | 2 | ||||
-rw-r--r-- | src/soc/intel/common/block/p2sb/p2sb.c | 113 |
3 files changed, 137 insertions, 10 deletions
diff --git a/src/soc/intel/common/block/include/intelblocks/p2sb.h b/src/soc/intel/common/block/include/intelblocks/p2sb.h index 8139a69b62..e5c1f3ef6a 100644 --- a/src/soc/intel/common/block/include/intelblocks/p2sb.h +++ b/src/soc/intel/common/block/include/intelblocks/p2sb.h @@ -1,7 +1,7 @@ /* * This file is part of the coreboot project. * - * Copyright 2017 Intel Corporation. + * Copyright (C) 2017-2018 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,37 @@ #ifndef SOC_INTEL_COMMON_BLOCK_P2SB_H #define SOC_INTEL_COMMON_BLOCK_P2SB_H +#include <stddef.h> +#include <stdint.h> + +#define PCH_P2SB_E0 0xe0 +#define P2SB_E0_MASKLOCK (1 << 1) + +enum { + P2SB_EP_MASK_0_REG, + P2SB_EP_MASK_1_REG, + P2SB_EP_MASK_2_REG, + P2SB_EP_MASK_3_REG, + P2SB_EP_MASK_4_REG, + P2SB_EP_MASK_5_REG, + P2SB_EP_MASK_6_REG, + P2SB_EP_MASK_7_REG, + P2SB_EP_MASK_MAX_REG, +}; + void p2sb_unhide(void); void p2sb_hide(void); +void p2sb_disable_sideband_access(void); +void p2sb_enable_bar(void); +void p2sb_configure_hpet(void); + +/* SOC overrides */ +/* + * Each SoC should implement EP Mask register to disable SB access + * Input: + * ep_mask: An array to be filled by SoC code with EP mask register. + * count: number of element in EP mask array. + */ +void p2sb_soc_get_sb_mask(uint32_t *ep_mask, size_t count); #endif /* SOC_INTEL_COMMON_BLOCK_P2SB_H */ diff --git a/src/soc/intel/common/block/p2sb/Makefile.inc b/src/soc/intel/common/block/p2sb/Makefile.inc index d78714b03e..a1330abdd9 100644 --- a/src/soc/intel/common/block/p2sb/Makefile.inc +++ b/src/soc/intel/common/block/p2sb/Makefile.inc @@ -1 +1,3 @@ +bootblock-$(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 diff --git a/src/soc/intel/common/block/p2sb/p2sb.c b/src/soc/intel/common/block/p2sb/p2sb.c index 6a9bd34668..c09c6aa7ef 100644 --- a/src/soc/intel/common/block/p2sb/p2sb.c +++ b/src/soc/intel/common/block/p2sb/p2sb.c @@ -1,7 +1,8 @@ /* * This file is part of the coreboot project. * - * Copyright 2016 Google Inc. + * Copyright (C) 2016 Google Inc. + * Copyright (C) 2018 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,38 +19,132 @@ #include <device/device.h> #include <device/pci.h> #include <device/pci_ids.h> +#include <intelblocks/p2sb.h> #include <rules.h> #include <soc/iomap.h> +#include <soc/p2sb.h> #include <soc/pci_devs.h> -#include <intelblocks/p2sb.h> +#include <string.h> + +#define PCH_P2SB_EPMASK(mask_number) (PCH_P2SB_EPMASK0 + ((mask_number) * 4)) -#define P2SB_E0 0xe0 #define HIDE_BIT (1 << 0) +#if defined(__SIMPLE_DEVICE__) +static pci_devfn_t p2sb_get_device(void) +{ + int devfn = PCH_DEVFN_P2SB; + pci_devfn_t dev = PCI_DEV(0, PCI_SLOT(devfn), PCI_FUNC(devfn)); + + if (dev == PCI_DEV_INVALID) + die("PCH_DEV_P2SB not found!\n"); + + return dev; +} +#else +static struct device *p2sb_get_device(void) +{ + struct device *dev = PCH_DEV_P2SB; + if (!dev) + die("PCH_DEV_P2SB not found!\n"); + + return dev; +} +#endif + +#define P2SB_GET_DEV p2sb_get_device() + +void p2sb_enable_bar(void) +{ + /* Enable PCR Base address in PCH */ + pci_write_config32(P2SB_GET_DEV, PCI_BASE_ADDRESS_0, P2SB_BAR); + pci_write_config32(P2SB_GET_DEV, PCI_BASE_ADDRESS_1, 0); + + /* Enable P2SB MSE */ + pci_write_config8(P2SB_GET_DEV, PCI_COMMAND, + PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY); +} + +/* + * Enable decoding for HPET range. + * This is needed for FspMemoryInit to store and retrieve a global data + * pointer. + */ +void p2sb_configure_hpet(void) +{ + /* + * Enable decoding for HPET memory address range. + * HPTC_OFFSET(0x60) bit 7, when set the P2SB will decode + * the High Performance Timer memory address range + * selected by bits 1:0 + */ + pci_write_config8(P2SB_GET_DEV, HPTC_OFFSET, HPTC_ADDR_ENABLE_BIT); +} + static void p2sb_set_hide_bit(int hide) { - struct device *dev; - const uint16_t reg = P2SB_E0 + 1; + const uint16_t reg = PCH_P2SB_E0 + 1; const uint8_t mask = HIDE_BIT; uint8_t val; - dev = PCH_DEV_P2SB; - - val = pci_read_config8(dev, reg); + val = pci_read_config8(P2SB_GET_DEV, reg); val &= ~mask; if (hide) val |= mask; - pci_write_config8(dev, reg, val); + pci_write_config8(P2SB_GET_DEV, reg, val); } void p2sb_unhide(void) { p2sb_set_hide_bit(0); + + if (pci_read_config16(P2SB_GET_DEV, PCI_VENDOR_ID) != + PCI_VENDOR_ID_INTEL) + die("Unable to unhide PCH_DEV_P2SB device !\n"); } void p2sb_hide(void) { p2sb_set_hide_bit(1); + + if (pci_read_config16(P2SB_GET_DEV, PCI_VENDOR_ID) != + 0xFFFF) + die("Unable to hide PCH_DEV_P2SB device !\n"); +} + +static void p2sb_configure_endpoints(int epmask_id, uint32_t mask) +{ + uint32_t reg32; + + reg32 = pci_read_config32(P2SB_GET_DEV, PCH_P2SB_EPMASK(epmask_id)); + pci_write_config32(P2SB_GET_DEV, PCH_P2SB_EPMASK(epmask_id), + reg32 | mask); +} + +static void p2sb_lock_endpoints(void) +{ + uint8_t reg8; + + /* Set the "Endpoint Mask Lock!", P2SB PCI offset E2h bit[1] to 1. */ + reg8 = pci_read_config8(P2SB_GET_DEV, PCH_P2SB_E0 + 2); + pci_write_config8(P2SB_GET_DEV, PCH_P2SB_E0 + 2, + reg8 | P2SB_E0_MASKLOCK); +} + +void p2sb_disable_sideband_access(void) +{ + uint32_t ep_mask[P2SB_EP_MASK_MAX_REG]; + int i; + + memset(ep_mask, 0, sizeof(ep_mask)); + + p2sb_soc_get_sb_mask(ep_mask, ARRAY_SIZE(ep_mask)); + + /* Remove the host accessing right to PSF register range. */ + for (i = 0; i < P2SB_EP_MASK_MAX_REG; i++) + p2sb_configure_endpoints(i, ep_mask[i]); + + p2sb_lock_endpoints(); } static void read_resources(struct device *dev) |