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>
When enabling MSI & MSI-X, the code seemed to handle fallback to MSI
when MSI-X is not available, but the logic uses MSI-X even if not
available and the MSI path never gets used.
Fixes: a2491b321e ("drivers/pcie: Add support for MSI-X")
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
When building on non-X86 platforms K_MEM_PERM_RW gets undefined.
Fixes: a2491b321e ("drivers/pcie: Add support for MSI-X")
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
In some cases we cannot know the BDF up-front, so provide a way to
look it up based on the vendor and device ID.
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
These have been redefined in various places - better to have them in a
single place that different users can use.
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Now that we generate a header that extern's all possible devicetree
based device struct we can remove DEVICE_DT_DECLARE and
DEVICE_DT_INST_DECLARE as they aren't needed anymore.
Signed-off-by: Kumar Gala <kumar.gala@linaro.org>
Renamed to make its semantics clearer; this function maps
*physical* memory addresses and is not equivalent to
posix mmap(), which might confuse people.
mem_map test case remains the same name as other memory
mapping scenarios will be added in the fullness of time.
Parameter names to z_phys_map adjusted slightly to be more
consistent with names used in other memory mapping functions.
Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
It's disabled by default. When enabled, and if the device exposes both
MSI and MSI-X capabilities: MSI-X will be selected and MSI disabled on
the device.
Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
This enables software MSI "multi-vector" feature, letting the user to
register an isr handler per-MSI message.
Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
Though it was noted that pcie_get_cap() is only used by MSI code so far,
there is no need to put it in msi code. If unused, linker will nuke it.
So let's move things to where it belongs to.
Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
Originally, sys_read8 to the mapped address was added part of
the unmap API to protect OMAP mapping, i.e. in case of PCIe writes,
OMAP should not be overwritten before writes are completed.
Now that we have added dummy PCIe read in the common APIs, namely
pcie_ep_xfer_data_memcpy and pcie_ep_xfer_data_dma, for the purpose
of flushing PCIe writes; the purpose of protecting OMAP *also*
gets satisfied, randering PCIe read in the unmap useless,
so remove the same.
Signed-off-by: Abhishek Shah <abhishek.shah@broadcom.com>
Introduce common API to achieve data transfer using system DMA.
"System DMA" uses the outbound memory mapped Host address,
it cannot understand Host/PCIe address.
This API will take of mapping the Host address, completing
the data transfer to/from Host memory and unmapping the window;
thus providing abstraction to the user.
Since v1:
- refactored code for the cases where we have valid mapped_addr
to improve error management logic
Signed-off-by: Abhishek Shah <abhishek.shah@broadcom.com>
Once host memory is mapped to outbound memory, PL330 can be used to
transfer data between outbound memory and local memory.
Add API for the same, we get pl330 device as well as channels to be
used for tx/rx from DT and use DMA public APIs for data transfer.
Signed-off-by: Abhishek Shah <abhishek.shah@broadcom.com>
An address might be made for 64bit though it's lower 32 bits are made of
0. Also Simplifying the overall by removing a useless variable.
Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
currently pcie_get_mbar only returns the physical address.
This changes the function to return the size of the mbar and
the flags (IO Bar vs MEM BAR).
Signed-off-by: Maximilian Bachmann <m.bachmann@acontis.com>
There are x86 platforms where the IRQ configuration register for PCIe
is not pre-populated and the OS needs to assign a number dynamically
by writing to the register.
In order to allocate interrupts we have to know which ones have been
hard-coded in device tree. We accomplish this by collecting these
values through the IRQ_CONNECT() macro and placing them in a dedicated
linker section (in ROM).
The full set of allocated interrupts are managed through a bitmap, and
the pre-allocated values (from the linker section) are inserted into
this upon initial runtime access.
This patch introduces a new pcie_alloc_irq() API that drivers can use
to allocate interrupt line numbers. The two in-tree drivers that were
using this API (I2C and UART) are converted to use the new API.
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
We should clear the pvm interrupts (snoop and pcie pmon lite interrupt)
at source before handling them.
This will make sure that we do not lose any interrupts that may have
been asserted to interrupt controller during the handling routine.
Signed-off-by: Abhishek Shah <abhishek.shah@broadcom.com>
Add support for interrupt driven MSI-X PVM feature for Viper.
Function mask bit update is tracked with snoop interrupt
and vector mask bit update is tracked with pcie pmon lite
address range access detection interrupt.
Both the interrupts are required to enable this feature.
Signed-off-by: Abhishek Shah <abhishek.shah@broadcom.com>
drivers: pcie_ep: iproc: move msi/msix functions to a separate
file. This increases readability and modularity.
Signed-off-by: Abhishek Shah <abhishek.shah@broadcom.com>
File names such as pcie_ep_bcm_iproc.c / pcie_ep_bcm_iproc_regs.h
seem unnecessarily long, same with CONFIG symbols' names.
Let's shorten them by replacing 'bcm_iproc' with simply 'iproc'.
Signed-off-by: Abhishek Shah <abhishek.shah@broadcom.com>