[coreboot-gerrit] Change in coreboot[master]: soc/cavium: Add PCI support

Philipp Deppenwiese (Code Review) gerrit at coreboot.org
Thu Jul 19 15:57:28 CEST 2018


Philipp Deppenwiese has submitted this change and it was merged. ( https://review.coreboot.org/25750 )

Change subject: soc/cavium: Add PCI support
......................................................................

soc/cavium: Add PCI support

* Add support for secure/unsecure split
* Use MMCONF to access devices in domain0
* Program MSIX vectors to fix a crash in GNU/Linux

Tested on Cavium CN81XX_EVB.

All PCI devices are visible.

Change-Id: I881f38a26a165e6bd965fcd73547473b5e32d4b0
Signed-off-by: Patrick Rudolph <patrick.rudolph at 9elements.com>
Reviewed-on: https://review.coreboot.org/25750
Reviewed-by: Philipp Deppenwiese <zaolin.daisuki at gmail.com>
Tested-by: build bot (Jenkins) <no-reply at coreboot.org>
---
M src/mainboard/cavium/cn8100_sff_evb/devicetree.cb
M src/soc/cavium/cn81xx/Kconfig
M src/soc/cavium/cn81xx/Makefile.inc
A src/soc/cavium/cn81xx/ecam0.c
M src/soc/cavium/cn81xx/include/soc/addressmap.h
A src/soc/cavium/cn81xx/include/soc/ecam0.h
M src/soc/cavium/cn81xx/soc.c
A src/soc/cavium/common/pci/chip.h
8 files changed, 633 insertions(+), 1 deletion(-)

Approvals:
  build bot (Jenkins): Verified
  Philipp Deppenwiese: Looks good to me, approved



diff --git a/src/mainboard/cavium/cn8100_sff_evb/devicetree.cb b/src/mainboard/cavium/cn8100_sff_evb/devicetree.cb
index cd495e1..3398e9a 100644
--- a/src/mainboard/cavium/cn8100_sff_evb/devicetree.cb
+++ b/src/mainboard/cavium/cn8100_sff_evb/devicetree.cb
@@ -15,4 +15,196 @@
 
 chip soc/cavium/cn81xx
 	device cpu_cluster 0 on end
+
+	device domain 0 on
+		chip soc/cavium/common/pci
+			register "secure" = "0"
+			device pci 01.0 on # PCI bridge
+				chip soc/cavium/common/pci
+					register "secure" = "0"
+					device pci 00.0 on end # MRML
+				end
+				chip soc/cavium/common/pci
+					register "secure" = "0"
+					device pci 00.1 on end # RESET
+				end
+				chip soc/cavium/common/pci
+					register "secure" = "1"
+					device pci 00.2 on end # DAP
+				end
+				chip soc/cavium/common/pci
+					register "secure" = "1"
+					device pci 00.3 on end # MDIO
+				end
+				chip soc/cavium/common/pci
+					register "secure" = "1"
+					device pci 00.4 on end # FUSE
+				end
+				chip soc/cavium/common/pci
+					register "secure" = "0"
+					device pci 01.2 on end # SGPIO
+				end
+				chip soc/cavium/common/pci
+					register "secure" = "0"
+					device pci 01.3 on end # SMI
+				end
+				chip soc/cavium/common/pci
+					register "secure" = "0"
+					device pci 01.4 on end # MMC
+				end
+				chip soc/cavium/common/pci
+					register "secure" = "1"
+					device pci 01.5 on end # KEY
+				end
+				chip soc/cavium/common/pci
+					register "secure" = "1"
+					device pci 01.6 on end # BOOT BUS
+				end
+				chip soc/cavium/common/pci
+					register "secure" = "0"
+					device pci 01.7 on end # PBUS
+				end
+				chip soc/cavium/common/pci
+					register "secure" = "0"
+					device pci 02.0 on end # XCV
+				end
+				device pci 04.0 on end
+
+				chip soc/cavium/common/pci
+					register "secure" = "0"
+					device pci 06.0 on end # L2C-TAD
+				end
+				chip soc/cavium/common/pci
+					register "secure" = "0"
+					device pci 07.0 on end # L2C-CBC
+				end
+				chip soc/cavium/common/pci
+					register "secure" = "0"
+					device pci 07.4 on end # L2C-MCI
+				end
+
+				chip soc/cavium/common/pci
+					register "secure" = "1"
+					device pci 08.0 on end # UUA0
+				end
+				chip soc/cavium/common/pci
+					register "secure" = "1"
+					device pci 08.1 on end # UUA1
+				end
+				chip soc/cavium/common/pci
+					register "secure" = "1"
+					device pci 08.2 on end # UUA2
+				end
+				chip soc/cavium/common/pci
+					register "secure" = "1"
+					device pci 08.3 on end # UUA3
+				end
+				chip soc/cavium/common/pci
+					register "secure" = "1"
+					device pci 08.4 on end # VRM
+				end
+				chip soc/cavium/common/pci
+					register "secure" = "0"
+					device pci 09.0 on end # I2C0
+				end
+				chip soc/cavium/common/pci
+					register "secure" = "0"
+					device pci 09.1 on end # I2C1
+				end
+				chip soc/cavium/common/pci
+					register "secure" = "0"
+					device pci 0a.0 on end # PCC Bridge
+				end
+				chip soc/cavium/common/pci
+					register "secure" = "1"
+					device pci 0b.0 on end # IOBN
+				end
+				chip soc/cavium/common/pci
+					register "secure" = "0"
+					device pci 0c.0 on end # OCLA0
+				end
+				chip soc/cavium/common/pci
+					register "secure" = "0"
+					device pci 0c.1 on end # OCLA1
+				end
+				chip soc/cavium/common/pci
+					register "secure" = "1"
+					device pci 0d.0 on end
+				end
+				chip soc/cavium/common/pci
+					register "secure" = "1"
+					device pci 0e.0 on end # PCIe0
+				end
+				chip soc/cavium/common/pci
+					register "secure" = "1"
+					device pci 0e.1 on end # PCIe1
+				end
+				chip soc/cavium/common/pci
+					register "secure" = "1"
+					device pci 0e.2 on end # PCIe2
+				end
+				chip soc/cavium/common/pci
+					register "secure" = "0"
+					device pci 10.0 on end # bgx0
+				end
+				chip soc/cavium/common/pci
+					register "secure" = "0"
+					device pci 10.1 on end # bgx1
+				end
+				chip soc/cavium/common/pci
+					register "secure" = "0"
+					device pci 11.0 on end # rgx0
+				end
+				chip soc/cavium/common/pci
+					register "secure" = "0"
+					device pci 12.0 on end # MAC
+				end
+				chip soc/cavium/common/pci
+					register "secure" = "1"
+					device pci 1c.0 on end # GSER0
+				end
+				chip soc/cavium/common/pci
+					register "secure" = "1"
+					device pci 1c.1 on end # GSER1
+				end
+				chip soc/cavium/common/pci
+					register "secure" = "1"
+					device pci 1c.2 on end # GSER2
+				end
+				chip soc/cavium/common/pci
+					register "secure" = "1"
+					device pci 1c.3 on end # GSER3
+				end
+			end
+			chip soc/cavium/common/pci
+				register "secure" = "1"
+				device pci 02.0 on end #SMMU
+			end
+			chip soc/cavium/common/pci
+				register "secure" = "1"
+				device pci 03.0 on end #GIC
+			end
+			chip soc/cavium/common/pci
+				register "secure" = "1"
+				device pci 04.0 on end #GTI
+			end
+
+			device pci 05.0 on end # NIC
+			device pci 06.0 on end # GPIO
+			device pci 07.0 on end # SPI
+			device pci 08.0 on end # MIO
+			device pci 09.0 on end # PCI bridge
+			device pci 0a.0 on end # PCI bridge
+			device pci 0b.0 on end # NFC
+			device pci 0c.0 on end # PCI bridge
+			device pci 0d.0 on end # PCM
+			device pci 0e.0 on end # VRM
+			device pci 0f.0 on end # PCI bridge
+
+			device pci 10.0 on end # USB0
+			device pci 11.0 on end # USB1
+			device pci 16.0 on end # SATA0
+			device pci 17.0 on end # SATA1
+		end
+	end
 end
diff --git a/src/soc/cavium/cn81xx/Kconfig b/src/soc/cavium/cn81xx/Kconfig
index 9cc7b48..3191ef3 100644
--- a/src/soc/cavium/cn81xx/Kconfig
+++ b/src/soc/cavium/cn81xx/Kconfig
@@ -12,6 +12,8 @@
 	select UART_OVERRIDE_REFCLK
 	select SOC_CAVIUM_COMMON
 	select CAVIUM_BDK_DDR_TUNE_HW_OFFSETS
+	select MMCONF_SUPPORT
+	select PCI
 
 if SOC_CAVIUM_CN81XX
 
@@ -25,4 +27,7 @@
 config STACK_SIZE
 	default 0x2000
 
+config MMCONF_BASE_ADDRESS
+	default 0x848000000000
+
 endif
diff --git a/src/soc/cavium/cn81xx/Makefile.inc b/src/soc/cavium/cn81xx/Makefile.inc
index 16aa4ff..b2de484 100644
--- a/src/soc/cavium/cn81xx/Makefile.inc
+++ b/src/soc/cavium/cn81xx/Makefile.inc
@@ -63,6 +63,7 @@
 ramstage-y += soc.c
 ramstage-y += cpu.c
 ramstage-y += cpu_secondary.S
+ramstage-y += ecam0.c
 
 # BDK coreboot interface
 ramstage-y += ../common/bdk-coreboot.c
diff --git a/src/soc/cavium/cn81xx/ecam0.c b/src/soc/cavium/cn81xx/ecam0.c
new file mode 100644
index 0000000..cff2507
--- /dev/null
+++ b/src/soc/cavium/cn81xx/ecam0.c
@@ -0,0 +1,374 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2018       Facebook, Inc.
+ * Copyright 2003-2017  Cavium Inc.  <support at cavium.com>
+ *
+ * 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
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Derived from Cavium's BSD-3 Clause OCTEONTX-SDK-6.2.0.
+ */
+
+#include <console/console.h>
+#include <arch/io.h>
+#include <device/pci.h>
+#include <device/pci_ops.h>
+#include <soc/addressmap.h>
+#include <soc/cavium/common/pci/chip.h>
+#include <assert.h>
+
+#define CAVM_PCCPF_XXX_VSEC_CTL 0x108
+#define CAVM_PCCPF_XXX_VSEC_SCTL 0x10c
+
+/*
+ * Hide PCI device function on BUS 1 in non secure world.
+ */
+static void disable_func(unsigned int devfn)
+{
+	u64 *addr;
+	printk(BIOS_DEBUG, "PCI: 01:%02x.%x is secure\n", devfn >> 3,
+	       devfn & 7);
+
+	/* disable function */
+	addr = (void *)ECAM0_RSLX_SDIS;
+	u64 reg = read64(&addr[devfn]);
+	reg &= ~3;
+	reg |= 2;
+	write64(&addr[devfn], reg);
+}
+
+/*
+ * Show PCI device function on BUS 1 in non secure world.
+ */
+static void enable_func(unsigned int devfn)
+{
+	u64 *addr;
+
+	printk(BIOS_DEBUG, "PCI: 01:%02x.%x is insecure\n", devfn >> 3,
+	       devfn & 7);
+
+	/* enable function */
+	addr = (void *)ECAM0_RSLX_SDIS;
+	u64 reg = read64(&addr[devfn]);
+	reg &= ~3;
+	write64(&addr[devfn], reg);
+
+	addr = (void *)ECAM0_RSLX_NSDIS;
+	reg = read64(&addr[devfn]);
+	reg &= ~1;
+	write64(&addr[devfn], reg);
+}
+
+/*
+ * Hide PCI device on BUS 0 in non secure world.
+ */
+static void disable_device(unsigned int dev)
+{
+	u64 *addr;
+
+	printk(BIOS_DEBUG, "PCI: 00:%02x.0 is secure\n", dev);
+
+	/* disable function */
+	addr = (void *)ECAM0_DEVX_SDIS;
+	u64 reg = read64(&addr[dev]);
+	reg &= ~3;
+	write64(&addr[dev], reg);
+
+	addr = (void *)ECAM0_DEVX_NSDIS;
+	reg = read64(&addr[dev]);
+	reg |= 1;
+	write64(&addr[dev], reg);
+}
+
+/*
+ * Show PCI device on BUS 0 in non secure world.
+ */
+static void enable_device(unsigned int dev)
+{
+	u64 *addr;
+
+	printk(BIOS_DEBUG, "PCI: 00:%02x.0 is insecure\n", dev);
+
+	/* enable function */
+	addr = (void *)ECAM0_DEVX_SDIS;
+	u64 reg = read64(&addr[dev]);
+	reg &= ~3;
+	write64(&addr[dev], reg);
+
+	addr = (void *)ECAM0_DEVX_NSDIS;
+	reg = read64(&addr[dev]);
+	reg &= ~1;
+	write64(&addr[dev], reg);
+}
+
+static void ecam0_read_resources(struct device *dev)
+{
+	/* There are no dynamic PCI resources on Cavium SoC */
+}
+
+static void ecam0_fix_missing_devices(struct bus *link)
+{
+	size_t i;
+
+	/**
+	 * Cavium thinks it's a good idea to violate the PCI spec.
+	 * Disabled multi-function PCI devices might have active functions.
+	 * Add devices here manually, as coreboot's PCI allocator won't find
+	 * them otherwise...
+	 */
+	for (i = 0; i <= PCI_DEVFN(0x1f, 7); i++) {
+		struct device_path pci_path;
+		struct device *child;
+
+		pci_path.type = DEVICE_PATH_PCI;
+		pci_path.pci.devfn = i;
+
+		child = find_dev_path(link, &pci_path);
+		if (!child)
+			pci_probe_dev(NULL, link, i);
+	}
+}
+
+/**
+ * Get PCI BAR address from cavium specific extended capability.
+ * Use regular BAR if not found in extended capability space.
+ *
+ * @return The pyhsical address of the BAR, zero on error
+ */
+static uint64_t get_bar_val(struct device *dev, u8 bar)
+{
+	size_t cap_offset = pci_find_capability(dev, 0x14);
+	uint64_t h, l, ret = 0;
+	if (cap_offset) {
+		/* Found EA */
+		u8 es, bei;
+		u8 ne = pci_read_config8(dev, cap_offset + 2) & 0x3f;
+
+		cap_offset += 4;
+		while (ne) {
+			uint32_t dw0 = pci_read_config32(dev, cap_offset);
+
+			es = dw0 & 7;
+			bei = (dw0 >> 4) & 0xf;
+			if (bei == bar) {
+				h = 0;
+				l = pci_read_config32(dev, cap_offset + 4);
+				if (l & 2)
+					h = pci_read_config32(dev,
+							      cap_offset + 12);
+				ret = (h << 32) | (l & ~0xfull);
+				break;
+			}
+			cap_offset += (es + 1) * 4;
+			ne--;
+		}
+	} else {
+		h = 0;
+		l = pci_read_config32(dev, bar * 4 + PCI_BASE_ADDRESS_0);
+		if (l & 4)
+			h = pci_read_config32(dev, bar * 4 + PCI_BASE_ADDRESS_0
+					      + 4);
+		ret = (h << 32) | (l & ~0xfull);
+	}
+	return ret;
+}
+
+/**
+ * pci_enable_msix - configure device's MSI-X capability structure
+ * @dev: pointer to the pci_dev data structure of MSI-X device function
+ * @entries: pointer to an array of MSI-X entries
+ * @nvec: number of MSI-X irqs requested for allocation by device driver
+ *
+ * Setup the MSI-X capability structure of device function with the number
+ * of requested irqs upon its software driver call to request for
+ * MSI-X mode enabled on its hardware device function. A return of zero
+ * indicates the successful configuration of MSI-X capability structure.
+ * A return of < 0 indicates a failure.
+ * Or a return of > 0 indicates that driver request is exceeding the number
+ * of irqs or MSI-X vectors available. Driver should use the returned value to
+ * re-send its request.
+ **/
+static size_t ecam0_pci_enable_msix(struct device *dev,
+				    struct msix_entry *entries, size_t nvec)
+{
+	struct msix_entry *msixtable;
+	u32 offset;
+	u8 bar_idx;
+	u64 bar;
+	size_t nr_entries;
+	size_t i;
+	u16 control;
+
+	if (!entries) {
+		printk(BIOS_ERR, "%s: No entries specified\n", __func__);
+		return -1;
+	}
+
+	const size_t pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
+	if (!pos) {
+		printk(BIOS_ERR, "%s: Device not MSI-X capable\n",
+		       dev_path(dev));
+		return -1;
+	}
+	nr_entries = pci_msix_table_size(dev);
+	if (nvec > nr_entries) {
+		printk(BIOS_ERR, "ERROR: %s: Specified to many table entries\n",
+		       dev_path(dev));
+		return nr_entries;
+	}
+
+	/* Ensure MSI-X is disabled while it is set up */
+	control = pci_read_config16(dev, pos + PCI_MSIX_FLAGS);
+	control &= ~PCI_MSIX_FLAGS_ENABLE;
+	pci_write_config16(dev, pos + PCI_MSIX_FLAGS, control);
+
+	/* Find MSI-X table region */
+	offset = 0;
+	bar_idx = 0;
+	if (pci_msix_table_bar(dev, &offset, &bar_idx)) {
+		printk(BIOS_ERR, "ERROR: %s: Failed to find MSI-X entry\n",
+		       dev_path(dev));
+		return -1;
+	}
+	bar = get_bar_val(dev, bar_idx);
+	if (!bar) {
+		printk(BIOS_ERR, "ERROR: %s: Failed to find MSI-X bar\n",
+		       dev_path(dev));
+		return -1;
+	}
+	msixtable = (struct msix_entry *)((void *)bar + offset);
+
+	/*
+	 * Some devices require MSI-X to be enabled before we can touch the
+	 * MSI-X registers.  We need to mask all the vectors to prevent
+	 * interrupts coming in before they're fully set up.
+	 */
+	control |= PCI_MSIX_FLAGS_MASKALL | PCI_MSIX_FLAGS_ENABLE;
+	pci_write_config16(dev, pos + PCI_MSIX_FLAGS, control);
+
+	for (i = 0; i < nvec; i++) {
+		write64(&msixtable[i].addr, entries[i].addr);
+		write32(&msixtable[i].data, entries[i].data);
+		write32(&msixtable[i].vec_control, entries[i].vec_control);
+	}
+
+	control &= ~PCI_MSIX_FLAGS_MASKALL;
+	pci_write_config16(dev, pos + PCI_MSIX_FLAGS, control);
+
+	return 0;
+}
+
+static void ecam0_init(struct device *dev)
+{
+	struct soc_cavium_common_pci_config *config;
+	struct device *child, *child_last;
+	size_t i;
+	u32 reg32;
+
+	printk(BIOS_INFO, "ECAM0: init\n");
+	const struct device *bridge = dev_find_slot(0, PCI_DEVFN(1, 0));
+	if (!bridge) {
+		printk(BIOS_INFO, "ECAM0: ERROR: PCI 00:01.0 not found.\n");
+		return;
+	}
+	/**
+	 * Search for missing devices on BUS 1.
+	 * Only required for ARI capability programming.
+	 */
+	ecam0_fix_missing_devices(bridge->link_list);
+
+	/* Program secure ARI capability on bus 1 */
+	child_last = NULL;
+	for (i = 0; i <= PCI_DEVFN(0x1f, 7); i++) {
+		child = dev_find_slot(bridge->link_list->secondary, i);
+		if (!child || !child->enabled)
+			continue;
+
+		if (child_last) {
+			/* Program ARI capability of the previous device */
+			reg32 = pci_read_config32(child_last,
+						  CAVM_PCCPF_XXX_VSEC_SCTL);
+			reg32 &= ~(0xffU << 24);
+			reg32 |= child->path.pci.devfn << 24;
+			pci_write_config32(child_last, CAVM_PCCPF_XXX_VSEC_SCTL,
+					   reg32);
+		}
+		child_last = child;
+	}
+
+	/* Program insecure ARI capability on bus 1 */
+	child_last = NULL;
+	for (i = 0; i <= PCI_DEVFN(0x1f, 7); i++) {
+		child = dev_find_slot(bridge->link_list->secondary, i);
+		if (!child)
+			continue;
+		config = child->chip_info;
+		if (!child->enabled || (config && config->secure))
+			continue;
+
+		if (child_last) {
+			/* Program ARI capability of the previous device */
+			reg32 = pci_read_config32(child_last,
+						  CAVM_PCCPF_XXX_VSEC_CTL);
+			reg32 &= ~(0xffU << 24);
+			reg32 |= child->path.pci.devfn << 24;
+			pci_write_config32(child_last, CAVM_PCCPF_XXX_VSEC_CTL,
+					   reg32);
+		}
+		child_last = child;
+	}
+
+	/* Enable / disable devices on bus 0 */
+	for (i = 0; i <= 0x1f; i++) {
+		child = dev_find_slot(0, PCI_DEVFN(i, 0));
+		config = child ? child->chip_info : NULL;
+		if (child && child->enabled && config && !config->secure)
+			enable_device(i);
+		else
+			disable_device(i);
+	}
+
+	/* Enable / disable devices and functions on bus 1 */
+	for (i = 0; i <= PCI_DEVFN(0x1f, 7); i++) {
+		child = dev_find_slot(bridge->link_list->secondary, i);
+		config = child ? child->chip_info : NULL;
+		if (child && child->enabled &&
+		    ((config && !config->secure) || !config))
+			enable_func(i);
+		else
+			disable_func(i);
+	}
+
+	/* Apply IRQ on PCI devices */
+	/* UUA */
+	for (i = 0; i < 4; i++) {
+		child = dev_find_slot(bridge->link_list->secondary,
+				      PCI_DEVFN(8, i));
+		if (!child)
+			continue;
+
+		struct msix_entry entry[2] = {
+			{.addr = CAVM_GICD_SETSPI_NSR, .data = 37 + i},
+			{.addr = CAVM_GICD_CLRSPI_NSR, .data = 37 + i},
+		};
+
+		ecam0_pci_enable_msix(child, entry, 2);
+	}
+
+	printk(BIOS_INFO, "ECAM0: done\n");
+}
+
+struct device_operations pci_domain_ops_ecam0 = {
+	.set_resources    = NULL,
+	.enable_resources = NULL,
+	.read_resources   = ecam0_read_resources,
+	.init             = ecam0_init,
+	.scan_bus         = pci_domain_scan_bus,
+};
diff --git a/src/soc/cavium/cn81xx/include/soc/addressmap.h b/src/soc/cavium/cn81xx/include/soc/addressmap.h
index 938dd32..392c93f 100644
--- a/src/soc/cavium/cn81xx/include/soc/addressmap.h
+++ b/src/soc/cavium/cn81xx/include/soc/addressmap.h
@@ -52,6 +52,10 @@
 
 /* PCC */
 #define ECAM_PF_BAR2		0x848000000000ULL
+#define ECAM0_DEVX_NSDIS	0x87e048070000ULL
+#define ECAM0_DEVX_SDIS		0x87e048060000ULL
+#define ECAM0_RSLX_NSDIS	0x87e048050000ULL
+#define ECAM0_RSLX_SDIS		0x87e048040000ULL
 
 /* CPT */
 /* SLI */
@@ -102,6 +106,8 @@
 	((((x) == 0) || ((x) == 1) || ((x) == 2) || ((x) == 3)) ? \
 	 (0x87E028000000ULL + ((x) << 24)) : 0)
 
+#define CAVM_GICD_SETSPI_NSR	0x801000000040ULL
+#define CAVM_GICD_CLRSPI_NSR	0x801000000048ULL
 
 /* TWSI */
 #define MIO_TWS0_PF_BAR0	(0x87E0D0000000ULL + (0 << 24))
diff --git a/src/soc/cavium/cn81xx/include/soc/ecam0.h b/src/soc/cavium/cn81xx/include/soc/ecam0.h
new file mode 100644
index 0000000..1cc249d
--- /dev/null
+++ b/src/soc/cavium/cn81xx/include/soc/ecam0.h
@@ -0,0 +1,21 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2018-present Facebook, Inc.
+ *
+ * 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
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __COREBOOT_SRC_SOC_CAVIUM_COMMON_INCLUDE_SOC_ECAM0_H
+#define __COREBOOT_SRC_SOC_CAVIUM_COMMON_INCLUDE_SOC_ECAM0_H
+
+extern struct device_operations pci_domain_ops_ecam0;
+
+#endif
diff --git a/src/soc/cavium/cn81xx/soc.c b/src/soc/cavium/cn81xx/soc.c
index 6c68bb2..5e540a6 100644
--- a/src/soc/cavium/cn81xx/soc.c
+++ b/src/soc/cavium/cn81xx/soc.c
@@ -29,6 +29,7 @@
 #include <string.h>
 #include <symbols.h>
 #include <libbdk-boot/bdk-boot.h>
+#include <soc/ecam0.h>
 
 static void soc_read_resources(device_t dev)
 {
@@ -59,7 +60,12 @@
 
 static void enable_soc_dev(device_t dev)
 {
-	dev->ops = &soc_ops;
+	if (dev->path.type == DEVICE_PATH_DOMAIN &&
+		dev->path.domain.domain == 0) {
+		dev->ops = &pci_domain_ops_ecam0;
+	} else if (dev->path.type == DEVICE_PATH_CPU_CLUSTER) {
+		dev->ops = &soc_ops;
+	}
 }
 
 struct chip_operations soc_cavium_cn81xx_ops = {
diff --git a/src/soc/cavium/common/pci/chip.h b/src/soc/cavium/common/pci/chip.h
new file mode 100644
index 0000000..0d0d33f
--- /dev/null
+++ b/src/soc/cavium/common/pci/chip.h
@@ -0,0 +1,27 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2018-present Facebook, Inc.
+ *
+ * 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
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __SOC_CAVIUM_COMMON_PCI_CHIP_H
+#define __SOC_CAVIUM_COMMON_PCI_CHIP_H
+
+struct soc_cavium_common_pci_config {
+	/**
+	 * Mark the PCI device as secure.
+	 * It will be visible from EL3, but hidden in EL2-0.
+	 */
+	u8 secure;
+};
+
+#endif /* __SOC_CAVIUM_COMMON_PCI_CHIP_H */

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

Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-MessageType: merged
Gerrit-Change-Id: I881f38a26a165e6bd965fcd73547473b5e32d4b0
Gerrit-Change-Number: 25750
Gerrit-PatchSet: 29
Gerrit-Owner: Patrick Rudolph <patrick.rudolph at 9elements.com>
Gerrit-Reviewer: Paul Menzel <paulepanter at users.sourceforge.net>
Gerrit-Reviewer: Philipp Deppenwiese <zaolin.daisuki at gmail.com>
Gerrit-Reviewer: build bot (Jenkins) <no-reply at coreboot.org>
Gerrit-CC: Aaron Durbin <adurbin at chromium.org>
Gerrit-CC: Nico Huber <nico.h at gmx.de>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.coreboot.org/pipermail/coreboot-gerrit/attachments/20180719/b3831525/attachment.html>


More information about the coreboot-gerrit mailing list