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@9elements.com> Reviewed-on: https://review.coreboot.org/25750 Reviewed-by: Philipp Deppenwiese <zaolin.daisuki@gmail.com> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
parent
02c0814764
commit
d0c6797e79
|
@ -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
|
||||
|
|
|
@ -12,6 +12,8 @@ config SOC_CAVIUM_CN81XX
|
|||
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 HEAP_SIZE
|
|||
config STACK_SIZE
|
||||
default 0x2000
|
||||
|
||||
config MMCONF_BASE_ADDRESS
|
||||
default 0x848000000000
|
||||
|
||||
endif
|
||||
|
|
|
@ -63,6 +63,7 @@ ramstage-y += sdram.c
|
|||
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
|
||||
|
|
|
@ -0,0 +1,374 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright 2018 Facebook, Inc.
|
||||
* Copyright 2003-2017 Cavium Inc. <support@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,
|
||||
};
|
|
@ -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))
|
||||
|
|
|
@ -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
|
|
@ -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 struct device_operations soc_ops = {
|
|||
|
||||
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 = {
|
||||
|
|
|
@ -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 */
|
Loading…
Reference in New Issue