Index: sys/arm64/cavium/thunder_pcie.h =================================================================== --- /dev/null +++ sys/arm64/cavium/thunder_pcie.h @@ -0,0 +1,36 @@ +/*- + * Copyright (c) 2016 Cavium + * All rights reserved. + * + * This software was developed by Semihalf. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef __THUNDER_PCIE_H_ +#define __THUNDER_PCIE_H_ + + +int thunder_pcie_identify_ecam(device_t, int *); + + +#endif /* __THUNDER_PCIE_H_ */ Index: sys/arm64/cavium/thunder_pcie.c =================================================================== --- sys/arm64/cavium/thunder_pcie.c +++ sys/arm64/cavium/thunder_pcie.c @@ -52,6 +52,7 @@ #include #include +#include "thunder_pcie.h" #include "thunder_pcie_common.h" #include "pcib_if.h" @@ -71,15 +72,6 @@ (((func) & PCIE_FUNC_MASK) << PCIE_FUNC_SHIFT) | \ ((reg) & PCIE_REG_MASK)) -#define THUNDER_ECAM0_CFG_BASE 0x848000000000UL -#define THUNDER_ECAM1_CFG_BASE 0x849000000000UL -#define THUNDER_ECAM2_CFG_BASE 0x84a000000000UL -#define THUNDER_ECAM3_CFG_BASE 0x84b000000000UL -#define THUNDER_ECAM4_CFG_BASE 0x948000000000UL -#define THUNDER_ECAM5_CFG_BASE 0x949000000000UL -#define THUNDER_ECAM6_CFG_BASE 0x94a000000000UL -#define THUNDER_ECAM7_CFG_BASE 0x94b000000000UL - /* * ThunderX supports up to 4 ethernet interfaces, so it's good * value to use as default for numbers of VFs, since each eth @@ -90,7 +82,6 @@ &thunder_pcie_max_vfs, 0, "Max VFs supported by ThunderX internal PCIe"); /* Forward prototypes */ -static int thunder_pcie_identify_pcib(device_t); static int thunder_pcie_maxslots(device_t); static uint32_t thunder_pcie_read_config(device_t, u_int, u_int, u_int, u_int, int); @@ -112,7 +103,7 @@ sc->dev = dev; /* Identify pcib domain */ - if (thunder_pcie_identify_pcib(dev)) + if (thunder_pcie_identify_ecam(dev, &sc->ecam)) return (ENXIO); rid = 0; @@ -357,45 +348,24 @@ return (NULL); } -static int -thunder_pcie_identify_pcib(device_t dev) + +#define THUNDER_CFG_BASE_TO_ECAM(x) ((((x) >> 36UL) & 0x3) | (((x) >> 42UL) & 0x4)) + +int +thunder_pcie_identify_ecam(device_t dev, int *ecam) { - struct thunder_pcie_softc *sc; rman_res_t start; - sc = device_get_softc(dev); + /* Check if we're running on Cavium ThunderX */ + if (!CPU_MATCH(CPU_IMPL_MASK | CPU_PART_MASK, + CPU_IMPL_CAVIUM, CPU_PART_THUNDER, 0, 0)) + return (EINVAL); + start = bus_get_resource_start(dev, SYS_RES_MEMORY, 0); + *ecam = THUNDER_CFG_BASE_TO_ECAM(start); + + device_printf(dev, "ThunderX quirk, setting ECAM to %d\n", *ecam); - switch(start) { - case THUNDER_ECAM0_CFG_BASE: - sc->ecam = 0; - break; - case THUNDER_ECAM1_CFG_BASE: - sc->ecam = 1; - break; - case THUNDER_ECAM2_CFG_BASE: - sc->ecam = 2; - break; - case THUNDER_ECAM3_CFG_BASE: - sc->ecam = 3; - break; - case THUNDER_ECAM4_CFG_BASE: - sc->ecam = 4; - break; - case THUNDER_ECAM5_CFG_BASE: - sc->ecam = 5; - break; - case THUNDER_ECAM6_CFG_BASE: - sc->ecam = 6; - break; - case THUNDER_ECAM7_CFG_BASE: - sc->ecam = 7; - break; - default: - device_printf(dev, - "error: incorrect resource address=%#lx.\n", start); - return (ENXIO); - } return (0); } Index: sys/dev/pci/pci_host_generic.c =================================================================== --- sys/dev/pci/pci_host_generic.c +++ sys/dev/pci/pci_host_generic.c @@ -57,6 +57,10 @@ #include #include +#ifdef __aarch64__ +#include +#include "opt_soc.h" +#endif #include "pcib_if.h" /* Assembling ECAM Configuration Address */ @@ -109,6 +113,11 @@ struct ofw_bus_iinfo pci_iinfo; }; +typedef void (*generic_pcie_quirk)(device_t); +struct generic_pcie_quirks { + generic_pcie_quirk cb; +}; + /* Forward prototypes */ static int generic_pcie_probe(device_t dev); @@ -138,7 +147,7 @@ if (ofw_bus_is_compatible(dev, "pci-host-ecam-generic")) { device_set_desc(dev, "Generic PCI host controller"); - return (BUS_PROBE_DEFAULT); + return (BUS_PROBE_GENERIC); } return (ENXIO); @@ -220,6 +229,10 @@ ofw_bus_setup_iinfo(ofw_bus_get_node(dev), &sc->pci_iinfo, sizeof(cell_t)); + /* Quirks */ +#ifdef SOC_CAVM_THUNDERX + thunder_pcie_identify_ecam(dev, &sc->ecam); +#endif device_add_child(dev, "pci", -1); return (bus_generic_attach(dev)); @@ -314,7 +327,8 @@ uint64_t offset; uint32_t data; - if (bus > 255 || slot > 31 || func > 7 || reg > 4095) + if ((bus > PCI_BUSMAX) || (slot > PCI_SLOTMAX) || + (func > PCI_FUNCMAX) || (reg > PCIE_REGMAX)) return (~0U); sc = device_get_softc(dev); @@ -349,7 +363,8 @@ bus_space_tag_t t; uint64_t offset; - if (bus > 255 || slot > 31 || func > 7 || reg > 4095) + if ((bus > PCI_BUSMAX) || (slot > PCI_SLOTMAX) || + (func > PCI_FUNCMAX) || (reg > PCIE_REGMAX)) return; sc = device_get_softc(dev); @@ -434,7 +449,8 @@ return (0); } - device_printf(dev, "ERROR: Unknown index.\n"); + if (bootverbose) + device_printf(dev, "ERROR: Unknown index %d.\n", index); return (ENOENT); }