summaryrefslogtreecommitdiff
path: root/src/soc/intel/common
diff options
context:
space:
mode:
authorSubrata Banik <subrata.banik@intel.com>2018-05-07 17:13:40 +0530
committerSubrata Banik <subrata.banik@intel.com>2018-06-28 08:35:29 +0000
commit7837c203d615fce03c6d89d99ba9a746619e49d4 (patch)
treeba3626a10a35bd99108228611b18e7f76b7abd02 /src/soc/intel/common
parent210b351df3cc070f103feb01a40be9811af87906 (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')
-rw-r--r--src/soc/intel/common/block/include/intelblocks/p2sb.h32
-rw-r--r--src/soc/intel/common/block/p2sb/Makefile.inc2
-rw-r--r--src/soc/intel/common/block/p2sb/p2sb.c113
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)