drivers: pcie: reintroduce support for I/O BARs
Reintroduce support for accessing I/O BARs which was removed in
43d84147d9
.
Signed-off-by: Henrik Brix Andersen <henrik@brixandersen.dk>
This commit is contained in:
parent
7756809c97
commit
3c99a1e015
9 changed files with 105 additions and 24 deletions
|
@ -88,7 +88,7 @@ void z_x86_early_serial_init(void)
|
||||||
{
|
{
|
||||||
#if defined(DEVICE_MMIO_IS_IN_RAM) && !defined(CONFIG_UART_NS16550_ACCESS_IOPORT)
|
#if defined(DEVICE_MMIO_IS_IN_RAM) && !defined(CONFIG_UART_NS16550_ACCESS_IOPORT)
|
||||||
#ifdef X86_SOC_EARLY_SERIAL_PCIDEV
|
#ifdef X86_SOC_EARLY_SERIAL_PCIDEV
|
||||||
struct pcie_mbar mbar;
|
struct pcie_bar mbar;
|
||||||
pcie_get_mbar(X86_SOC_EARLY_SERIAL_PCIDEV, 0, &mbar);
|
pcie_get_mbar(X86_SOC_EARLY_SERIAL_PCIDEV, 0, &mbar);
|
||||||
pcie_set_cmd(X86_SOC_EARLY_SERIAL_PCIDEV, PCIE_CONF_CMDSTAT_MEM, true);
|
pcie_set_cmd(X86_SOC_EARLY_SERIAL_PCIDEV, PCIE_CONF_CMDSTAT_MEM, true);
|
||||||
device_map(&mmio, mbar.phys_addr, mbar.size, K_MEM_CACHE_NONE);
|
device_map(&mmio, mbar.phys_addr, mbar.size, K_MEM_CACHE_NONE);
|
||||||
|
|
|
@ -606,7 +606,7 @@ may be used directly:
|
||||||
void some_init_code(...)
|
void some_init_code(...)
|
||||||
{
|
{
|
||||||
...
|
...
|
||||||
struct pcie_mbar mbar;
|
struct pcie_bar mbar;
|
||||||
bool bar_found = pcie_get_mbar(bdf, index, &mbar);
|
bool bar_found = pcie_get_mbar(bdf, index, &mbar);
|
||||||
|
|
||||||
device_map(DEVICE_MMIO_RAM_PTR(dev), mbar.phys_addr, mbar.size, K_MEM_CACHE_NONE);
|
device_map(DEVICE_MMIO_RAM_PTR(dev), mbar.phys_addr, mbar.size, K_MEM_CACHE_NONE);
|
||||||
|
|
|
@ -238,7 +238,7 @@ int e1000_probe(const struct device *ddev)
|
||||||
const pcie_bdf_t bdf = PCIE_BDF(0, 3, 0);
|
const pcie_bdf_t bdf = PCIE_BDF(0, 3, 0);
|
||||||
struct e1000_dev *dev = ddev->data;
|
struct e1000_dev *dev = ddev->data;
|
||||||
uint32_t ral, rah;
|
uint32_t ral, rah;
|
||||||
struct pcie_mbar mbar;
|
struct pcie_bar mbar;
|
||||||
|
|
||||||
if (!pcie_probe(bdf, PCIE_ID(PCI_VENDOR_ID_INTEL,
|
if (!pcie_probe(bdf, PCIE_ID(PCI_VENDOR_ID_INTEL,
|
||||||
PCI_DEVICE_ID_I82540EM))) {
|
PCI_DEVICE_ID_I82540EM))) {
|
||||||
|
|
|
@ -849,7 +849,7 @@ static int i2c_dw_initialize(const struct device *dev)
|
||||||
|
|
||||||
#if DT_ANY_INST_ON_BUS_STATUS_OKAY(pcie)
|
#if DT_ANY_INST_ON_BUS_STATUS_OKAY(pcie)
|
||||||
if (rom->pcie) {
|
if (rom->pcie) {
|
||||||
struct pcie_mbar mbar;
|
struct pcie_bar mbar;
|
||||||
|
|
||||||
if (!pcie_probe(rom->pcie_bdf, rom->pcie_id)) {
|
if (!pcie_probe(rom->pcie_bdf, rom->pcie_id)) {
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
|
@ -84,7 +84,7 @@ static bool map_msix_table_entries(pcie_bdf_t bdf,
|
||||||
{
|
{
|
||||||
uint32_t table_offset;
|
uint32_t table_offset;
|
||||||
uint8_t table_bir;
|
uint8_t table_bir;
|
||||||
struct pcie_mbar bar;
|
struct pcie_bar bar;
|
||||||
uintptr_t mapped_table;
|
uintptr_t mapped_table;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
|
|
@ -103,9 +103,19 @@ uint32_t pcie_get_ext_cap(pcie_bdf_t bdf, uint32_t cap_id)
|
||||||
return reg;
|
return reg;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool pcie_get_mbar(pcie_bdf_t bdf,
|
/**
|
||||||
|
* @brief Get the BAR at a specific BAR index
|
||||||
|
*
|
||||||
|
* @param bdf the PCI(e) endpoint
|
||||||
|
* @param bar_index 0-based BAR index
|
||||||
|
* @param bar Pointer to struct pcie_bar
|
||||||
|
* @param io true for I/O BARs, false otherwise
|
||||||
|
* @return true if the BAR was found and is valid, false otherwise
|
||||||
|
*/
|
||||||
|
static bool pcie_get_bar(pcie_bdf_t bdf,
|
||||||
unsigned int bar_index,
|
unsigned int bar_index,
|
||||||
struct pcie_mbar *mbar)
|
struct pcie_bar *bar,
|
||||||
|
bool io)
|
||||||
{
|
{
|
||||||
uint32_t reg = bar_index + PCIE_CONF_BAR0;
|
uint32_t reg = bar_index + PCIE_CONF_BAR0;
|
||||||
#ifdef CONFIG_PCIE_CONTROLLER
|
#ifdef CONFIG_PCIE_CONTROLLER
|
||||||
|
@ -128,8 +138,7 @@ bool pcie_get_mbar(pcie_bdf_t bdf,
|
||||||
|
|
||||||
phys_addr = pcie_conf_read(bdf, reg);
|
phys_addr = pcie_conf_read(bdf, reg);
|
||||||
#ifndef CONFIG_PCIE_CONTROLLER
|
#ifndef CONFIG_PCIE_CONTROLLER
|
||||||
if (PCIE_CONF_BAR_IO(phys_addr)) {
|
if ((PCIE_CONF_BAR_MEM(phys_addr) && io) || (PCIE_CONF_BAR_IO(phys_addr) && !io)) {
|
||||||
/* Discard I/O bars */
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -183,20 +192,36 @@ bool pcie_get_mbar(pcie_bdf_t bdf,
|
||||||
PCIE_CONF_BAR_MEM(phys_addr) ?
|
PCIE_CONF_BAR_MEM(phys_addr) ?
|
||||||
PCIE_CONF_BAR_ADDR(phys_addr)
|
PCIE_CONF_BAR_ADDR(phys_addr)
|
||||||
: PCIE_CONF_BAR_IO_ADDR(phys_addr),
|
: PCIE_CONF_BAR_IO_ADDR(phys_addr),
|
||||||
&mbar->phys_addr)) {
|
&bar->phys_addr)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
mbar->phys_addr = PCIE_CONF_BAR_ADDR(phys_addr);
|
bar->phys_addr = PCIE_CONF_BAR_ADDR(phys_addr);
|
||||||
#endif /* CONFIG_PCIE_CONTROLLER */
|
#endif /* CONFIG_PCIE_CONTROLLER */
|
||||||
mbar->size = size & ~(size-1);
|
bar->size = size & ~(size-1);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool pcie_probe_mbar(pcie_bdf_t bdf,
|
/**
|
||||||
|
* @brief Probe the nth BAR assigned to an endpoint.
|
||||||
|
*
|
||||||
|
* A PCI(e) endpoint has 0 or more BARs. This function
|
||||||
|
* allows the caller to enumerate them by calling with index=0..n.
|
||||||
|
* Value of n has to be below 6, as there is a maximum of 6 BARs. The indices
|
||||||
|
* are order-preserving with respect to the endpoint BARs: e.g., index 0
|
||||||
|
* will return the lowest-numbered BAR on the endpoint.
|
||||||
|
*
|
||||||
|
* @param bdf the PCI(e) endpoint
|
||||||
|
* @param index (0-based) index
|
||||||
|
* @param bar Pointer to struct pcie_bar
|
||||||
|
* @param io true for I/O BARs, false otherwise
|
||||||
|
* @return true if the BAR was found and is valid, false otherwise
|
||||||
|
*/
|
||||||
|
static bool pcie_probe_bar(pcie_bdf_t bdf,
|
||||||
unsigned int index,
|
unsigned int index,
|
||||||
struct pcie_mbar *mbar)
|
struct pcie_bar *bar,
|
||||||
|
bool io)
|
||||||
{
|
{
|
||||||
uint32_t reg;
|
uint32_t reg;
|
||||||
|
|
||||||
|
@ -213,7 +238,35 @@ bool pcie_probe_mbar(pcie_bdf_t bdf,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return pcie_get_mbar(bdf, reg - PCIE_CONF_BAR0, mbar);
|
return pcie_get_bar(bdf, reg - PCIE_CONF_BAR0, bar, io);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool pcie_get_mbar(pcie_bdf_t bdf,
|
||||||
|
unsigned int bar_index,
|
||||||
|
struct pcie_bar *mbar)
|
||||||
|
{
|
||||||
|
return pcie_get_bar(bdf, bar_index, mbar, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool pcie_probe_mbar(pcie_bdf_t bdf,
|
||||||
|
unsigned int index,
|
||||||
|
struct pcie_bar *mbar)
|
||||||
|
{
|
||||||
|
return pcie_probe_bar(bdf, index, mbar, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool pcie_get_iobar(pcie_bdf_t bdf,
|
||||||
|
unsigned int bar_index,
|
||||||
|
struct pcie_bar *iobar)
|
||||||
|
{
|
||||||
|
return pcie_get_bar(bdf, bar_index, iobar, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool pcie_probe_iobar(pcie_bdf_t bdf,
|
||||||
|
unsigned int index,
|
||||||
|
struct pcie_bar *iobar)
|
||||||
|
{
|
||||||
|
return pcie_probe_bar(bdf, index, iobar, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef CONFIG_PCIE_CONTROLLER
|
#ifndef CONFIG_PCIE_CONTROLLER
|
||||||
|
|
|
@ -333,7 +333,7 @@ static int uart_ns16550_configure(const struct device *dev,
|
||||||
#ifndef CONFIG_UART_NS16550_ACCESS_IOPORT
|
#ifndef CONFIG_UART_NS16550_ACCESS_IOPORT
|
||||||
#if DT_ANY_INST_ON_BUS_STATUS_OKAY(pcie)
|
#if DT_ANY_INST_ON_BUS_STATUS_OKAY(pcie)
|
||||||
if (dev_cfg->pcie) {
|
if (dev_cfg->pcie) {
|
||||||
struct pcie_mbar mbar;
|
struct pcie_bar mbar;
|
||||||
|
|
||||||
if (!pcie_probe(dev_cfg->pcie_bdf, dev_cfg->pcie_id)) {
|
if (!pcie_probe(dev_cfg->pcie_bdf, dev_cfg->pcie_id)) {
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
|
|
|
@ -108,7 +108,7 @@ static const struct ivshmem_reg no_reg;
|
||||||
static bool ivshmem_configure(const struct device *dev)
|
static bool ivshmem_configure(const struct device *dev)
|
||||||
{
|
{
|
||||||
struct ivshmem *data = dev->data;
|
struct ivshmem *data = dev->data;
|
||||||
struct pcie_mbar mbar_regs, mbar_mem;
|
struct pcie_bar mbar_regs, mbar_mem;
|
||||||
|
|
||||||
if (!pcie_get_mbar(data->bdf, IVSHMEM_PCIE_REG_BAR_IDX, &mbar_regs)) {
|
if (!pcie_get_mbar(data->bdf, IVSHMEM_PCIE_REG_BAR_IDX, &mbar_regs)) {
|
||||||
#ifdef CONFIG_IVSHMEM_DOORBELL
|
#ifdef CONFIG_IVSHMEM_DOORBELL
|
||||||
|
|
|
@ -36,7 +36,7 @@ typedef uint32_t pcie_bdf_t;
|
||||||
*/
|
*/
|
||||||
typedef uint32_t pcie_id_t;
|
typedef uint32_t pcie_id_t;
|
||||||
|
|
||||||
struct pcie_mbar {
|
struct pcie_bar {
|
||||||
uintptr_t phys_addr;
|
uintptr_t phys_addr;
|
||||||
size_t size;
|
size_t size;
|
||||||
};
|
};
|
||||||
|
@ -91,18 +91,18 @@ extern bool pcie_probe(pcie_bdf_t bdf, pcie_id_t id);
|
||||||
* @brief Get the MBAR at a specific BAR index
|
* @brief Get the MBAR at a specific BAR index
|
||||||
* @param bdf the PCI(e) endpoint
|
* @param bdf the PCI(e) endpoint
|
||||||
* @param bar_index 0-based BAR index
|
* @param bar_index 0-based BAR index
|
||||||
* @param mbar Pointer to struct pcie_mbar
|
* @param mbar Pointer to struct pcie_bar
|
||||||
* @return true if the mbar was found and is valid, false otherwise
|
* @return true if the mbar was found and is valid, false otherwise
|
||||||
*/
|
*/
|
||||||
extern bool pcie_get_mbar(pcie_bdf_t bdf,
|
extern bool pcie_get_mbar(pcie_bdf_t bdf,
|
||||||
unsigned int bar_index,
|
unsigned int bar_index,
|
||||||
struct pcie_mbar *mbar);
|
struct pcie_bar *mbar);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Probe the nth MMIO address assigned to an endpoint.
|
* @brief Probe the nth MMIO address assigned to an endpoint.
|
||||||
* @param bdf the PCI(e) endpoint
|
* @param bdf the PCI(e) endpoint
|
||||||
* @param index (0-based) index
|
* @param index (0-based) index
|
||||||
* @param mbar Pointer to struct pcie_mbar
|
* @param mbar Pointer to struct pcie_bar
|
||||||
* @return true if the mbar was found and is valid, false otherwise
|
* @return true if the mbar was found and is valid, false otherwise
|
||||||
*
|
*
|
||||||
* A PCI(e) endpoint has 0 or more memory-mapped regions. This function
|
* A PCI(e) endpoint has 0 or more memory-mapped regions. This function
|
||||||
|
@ -113,7 +113,35 @@ extern bool pcie_get_mbar(pcie_bdf_t bdf,
|
||||||
*/
|
*/
|
||||||
extern bool pcie_probe_mbar(pcie_bdf_t bdf,
|
extern bool pcie_probe_mbar(pcie_bdf_t bdf,
|
||||||
unsigned int index,
|
unsigned int index,
|
||||||
struct pcie_mbar *mbar);
|
struct pcie_bar *mbar);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the I/O BAR at a specific BAR index
|
||||||
|
* @param bdf the PCI(e) endpoint
|
||||||
|
* @param bar_index 0-based BAR index
|
||||||
|
* @param iobar Pointer to struct pcie_bar
|
||||||
|
* @return true if the I/O BAR was found and is valid, false otherwise
|
||||||
|
*/
|
||||||
|
extern bool pcie_get_iobar(pcie_bdf_t bdf,
|
||||||
|
unsigned int bar_index,
|
||||||
|
struct pcie_bar *iobar);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Probe the nth I/O BAR address assigned to an endpoint.
|
||||||
|
* @param bdf the PCI(e) endpoint
|
||||||
|
* @param index (0-based) index
|
||||||
|
* @param iobar Pointer to struct pcie_bar
|
||||||
|
* @return true if the I/O BAR was found and is valid, false otherwise
|
||||||
|
*
|
||||||
|
* A PCI(e) endpoint has 0 or more I/O regions. This function
|
||||||
|
* allows the caller to enumerate them by calling with index=0..n.
|
||||||
|
* Value of n has to be below 6, as there is a maximum of 6 BARs. The indices
|
||||||
|
* are order-preserving with respect to the endpoint BARs: e.g., index 0
|
||||||
|
* will return the lowest-numbered I/O BAR on the endpoint.
|
||||||
|
*/
|
||||||
|
extern bool pcie_probe_iobar(pcie_bdf_t bdf,
|
||||||
|
unsigned int index,
|
||||||
|
struct pcie_bar *iobar);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set or reset bits in the endpoint command/status register.
|
* @brief Set or reset bits in the endpoint command/status register.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue