For architectures that rely on a PCIe controller (for example, ARM64),
scanning the PCI space will only succeed after the controller has
initialized. Therefore, in the presence of PCIe controller, the PCIe
initialization is bumped to the next system init level.
In the past, drivers like ivshmem would do a late scan of the PCI space
in case the early scan failed; however, the cited commit removed this
feature and ivshmem fails for ARM64. This commit fix this by making the
early scan succeed.
Fixes: a96016d747 ("drivers: ivshmem: Remove unnecessary BDF lookup ...")
Signed-off-by: Rodrigo Cataldo <rodrigo.cataldo@huawei.com>
Co-authored-by: Henri Xavier <datacomos@huawei.com>
Take advantage of the new PCIe scanning API for doing the initial lookup
of PCIe devices specified for a given board.
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
This adds a generic API to be used for scanning for available PCI
endpoints. It takes a more detailed approach than the "brute force"
based scanning that's so far been used in Zephyr, buy inspecting the
host controller node and bridge nodes, and only scanning for busses and
devices that are actually expected to exist.
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
PCI(e) host controllers behave in different ways (some more buggy than
others) in what value they use to indicate that an endpoint is not
present. In most cases the VID/DID is all ones (PCIE_ID_NONE) but in
others it's all zeroes, and some may even have the VID all zeroes and
the DID all ones, or vice-versa.
Add a macro to easily test for all these possibilities. The "all ones"
and "all zeroes" cases have been verified to exist on actual HW
supported by Zephyr, however the test for the mixed cases is simply
based on what Linux considers valid values (drivers/pci/probe.c in the
Linux kernel tree).
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Use the new PCIe core infrastructure for looking up the BDF at runtime
based on the VID/DID values.
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
The ptm.c driver never defined DT_DRV_COMPAT, so the various DT macros
never expanded to anything useful.
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
The BDF values can differ on the same platform, based on e.g. BIOS
configuration, and in the case of qemu the command line parameters. It's
therefore more reliable to always look up the BDF value based on the
known Vendor and Device IDs.
This patch introduces such a framework, and allows the incremental
update of PCIe drivers to start taking advantage of it.
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
It was previously written as regular members of a struct, which
allows the C compiler to do things the way it wants. On ARM64, gcc
would typically write field by pairs (`STP`), which
would generate aborts.
By using `sys_write32`, we force it the right way.
Signed-off-by: Henri Xavier <datacomos@huawei.com>
Change automated searching for files using "IRQ_CONNECT()" API not
including <zephyr/irq.h>.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
Use SHELL_CMD_ARG() for argument check and add help, looking like:
...
$ pcie -h
pcie - PCI(e) device information
Subcommands:
ls :List PCIE devices
Usage: ls [bus:device:function] [dump]
Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Add argument dump for dumping first 16 PCI configuration space
registers same way lspci -x is doing. Also parse bdf string as
argument. pcie can be called following way:
uart:~$ pcie 0:1f.4
...
uart:~$ pcie 0:1f.4 dump
...
Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
MISRA C:2012 Rule 14.4 (The controlling expression of an if statement
and the controlling expression of an iteration-statement shall have
essentially Boolean type.)
Use `do { ... } while (false)' instead of `do { ... } while (0)'.
Use comparisons with zero instead of implicitly testing integers.
The commit is a subset of the original auditable-branch commit:
5d02614e34
Signed-off-by: Simon Hein <SHein@baumer.com>
Following zephyr's style guideline, all if statements, including single
line statements shall have braces.
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
Invert the physical address given to pcie_ctrl_region_translate() to
match the PCI BAR layout. Previously, physical addresses for memory
space BAR were exposed to bit 3 (prefetchable bit) and 2 (1 type bit) of
the header.
Signed-off-by: Rodrigo Cataldo <rodrigo.cataldo@huawei.com>
MISRA C:2012 Rule 7.2 (A `u' or `U' suffix shall be applied to all
integer constants that are represented in an unsigned type)
Added missing `U' suffixes in constants that are involved in the
analyzed build, plus a few more not to introduce inconsistencies
with respect to nearby constants that are either unused in the
build (but implicitly unsigned) or are used and are immediately
converted to unsigned.
Signed-off-by: Abramo Bagnara <abramo.bagnara@bugseng.com>
In order to bring consistency in-tree, migrate all drivers to the new
prefix <zephyr/...>. Note that the conversion has been scripted, refer
to #45388 for more details.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
This implements the msi_device_setup() callback for ECAM controllers
used with an ARM GIC ITS MSI message translater.
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Define the MSI/MSI-X APIs to be used with the Generic PCIe Controller API.
It notably adds the msi_device_setup() callback to the PCI Express
Controller API used to allocate and setup the MSI/MSI-C vectors on the
MSI message translater HW.
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
According to Kconfig guidelines, boolean prompts must not start with
"Enable...". The following command has been used to automate the changes
in this patch:
sed -i "s/bool \"[Ee]nables\? \(\w\)/bool \"\U\1/g" **/Kconfig*
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
In order to preserve stack, this replaces the single-bus enumeration
loop by a stack based non-recursive pcie hierarchy iteration.
Each stack entry contains a bridge bus enumeration state.
When a bridge endpoint is detected on the current bus, it is
configured and this new bus is pushed on top of the stack in
order to be enumerated at next loop.
When enumeration ends on the bus, the current bus state is
removed from the stack to continue enumeration on the previous
bus.
This enumeration affects a sequential bus number to each new
bus detected in the same order as Linux & U-Boot does.
In this hierarchy:
[0 1 2 ... 31]
| | |
EP | |
| |
[0 1 ... 31] [0 ... 31]
| | |
| EP |
| [0 ... 31]
[0 ... 31] |
| EP
EP
We will get the following BDFs enumeration order:
00:00.0 Endpoint
00:01.0 Bridge => Bus primary 0 secondary 1
01:00.0 Bridge => Bus primary 1 secondary 2
02:00.0 Endpoint
... Bus secondary 2 => subordinate 2
01:01.0 Endpoint
... Bus secondary 1 => subordinate 2
00:02.0 Bridge => Bus primary 0 secondary 3
03:00.0 Bridge => Bus primary 3 secondary 4
04:00.0 Endpoint
... Bus secondary 4 => subordinate 4
... Bus secondary 3 => subordinate 4
The gives the following primary/secondary/subordinate map:
Bus 0 [0 1 2 ... 31]
| | |
| [0:1->2] [0:3->4]
EP 00:00.0 | |
| |
Bus 1 [0 1 ... 31] Bus 3 [0 ... 31]
| | |
| EP 01:01.0 |
[1:2->2] [3:4->4]
| |
| Bus 4 [0 ... 31]
Bus 2 [0 ... 31] |
| EP 04:00.0
EP 02:00.0
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
This adds setup of Type 1 bridge endpoints in two steps, first when
endpoint is detected and secondly when enumerating the next endpoint.
First, the code configures the bus primary & secondary number and 0xff
as subordinate to redirect all PCIe messages to this bus.
Then memory & I/O base are programmed by getting the current allocation
bases.
Finally, now right away, we program the subordinate to the max bus
number under the bridge, here the same, and the memory & I/O limit,
here lower than the base.
This doesn't make the bridge totally usable, enumeration would work
bus not for nested bridges and BARs wouldn't be accessible.
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
In order to prepare support for bridges enumeration, split out the
actual endpoint enumeration code out of the enumeration loop.
Pass a skip_next_func boolean to indicate if the current endpoint
is multifunction of not, to continue to next dev or next function.
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
The Type 1 endpoints has 2 BARs are the same position as the Type 0
BARS 0 & 1, so reuse the generic_pcie_ctrl_type0_enumerate_bars()
for both types by passing the number of possible BARs on the endpoint.
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Some drivers explicitely casted data/config from void * to the
corresponding type. However, this is unnecessary and, in many drivers it
has been misused to drop const qualifier (refer to previous commits).
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
As suggested by Tomasz Bursztyka, it's clearer to move generic after the
domain prefix, here pcie.
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
As suggested by Tomasz Bursztyka, translate is clearer than xlate in
the PCIe controller functions and callbacks names.
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Refactor to handle this case. This is valid only when MSI multi-vector
feature is enabled.
Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
The is meant to fix a chicken & egg issue with MSI interrupt remapping.
Currently, drivers first connect the irq (by-passing any possible MSI
remapping), so the IRQ ends-up being remapped at the IOAPIC level which
is not what we want.
So adding a dedicated function to properly handle this case. This is
valid only for runtime dynamic IRQ connection obviously.
Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
And since it does yet another round of pcie_get_cap() on PCIE_MSI_CAP_ID
and PCIE_MSIX_CAP_ID, let's factorize that into a utility function and
change the relevant places to use that function instead.
Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
PCIE now uses the new interface. And pcie_alloc_irq() is only made
available when CONFIG_PCIE_CONTROLLER is unset. So only for x86 atm.
Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
This adds :
- Generic PCIe Controller layer implementing the current PCIe API
- Generic PCIe Controller in ECAM mode driver
The Generic PCIe Controller layer provides:
- Configuration space read/write
- single bus endpoint enumerations
- Endpoint I/O, MEM & MEM64 BARs allocation
- Endpoint I/O, MEM & MEM64 BARs get & translation for drivers
The Generic PCIe Controller in ECAM mode driver provides:
- Raw DT RANGES properties into usable PCIe regions
- Configuration space read/write into ECAM config space
- PCIe regions allocation & translation
The limitations are:
- No support for PCIe prefetchable regions
- No support for PCIe bus configuration (only bus0 is supported)
- No support for multiple controllers (no domain-id in BDF)
Support has been designed to initially support Root Complexes with
Root Complex Integrated Endpoint, which was designed for Embedded
Systems with internal-only PCIe Endpoints on bus 0.
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Any exposed PTM root device will by default see their root capability
enabled so they will become PTM responder.
Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
Such module is missing and will prove to be useful for future features
and/or printing out debug messages on existing ones.
Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
Add __printf_like modifier to validate strings used by shell.
Fixing warnings triggered by this change.
Signed-off-by: Krzysztof Chruscinski <krzysztof.chruscinski@nordicsemi.no>
Remove the locally MSI/MSI-X capabilities ID define and use the
newly introduced one from the PCI Code and ID Assignment
Specification Revision 1.11 document header.
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Extend the PCIe API to find Extended Capabilities in the PCI Express
Extended Capabilities located in Configuration Space at offsets 256
or greater.
Note: the Root Complex Register Block is not supported
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
This changes pci_msi_enable() to take IRQ number as a function
parameter. The old behavior relies on putting the IRQ number
into the interrupt line register in the PCI config space
during IRQ allocation, and reading it back when enabling IRQ.
However, the interrupt line register is only required to be
read-/writable when legacy interrupt is supported on the device.
Otherwise it has undefined behavior. On ACRN, they don't even
care about this register and always wires it to 0x00.
So this commit changes the behavior in pci_msi_enable() to not
require reading back the interrupt line register and instead
takes the IRQ number via function parameter.
Fixes#36765
Signed-off-by: Daniel Leung <daniel.leung@intel.com>
So far pcie_get_mbar() has been the only way to retrieve a MBAR. But
it's logic does not fit all uses cases as we will see further.
The meaning of its parameter "index" is not about BAR index but about
a valid Base Address count instead. It's an arbitrary way to index
MBARs unrelated to the actual BAR index.
While this has proven to be just the function we needed so far, this has
not been the case for MSI-X, which one (through BIR info) needs to
access the BAR by their actual index. Same as ivshmem in fact, though
that one did not generate any bug since it never has IO BARs nor 64bits
BARs (so far?).
So:
- renaming existing pcie_get_mbar() to pcie_probe_mbar(), which is a
more relevant name as it indeed probes the BARs to find the nth valid
one.
- Introducing a new pcie_get_mbar() which this time really asks for the
BAR index.
- Applying the change where relevant. So all use pcie_probe_mbar() now
but MSI-X and ivshmem.
Fixes#37444
Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
Instead of putting the object files inside libzephyr.a,
simply build a separate static library as most other
driver types are doing this already.
Signed-off-by: Daniel Leung <daniel.leung@intel.com>