4
0
mirror of https://github.com/RT-Thread/rt-thread.git synced 2025-01-19 08:53:32 +08:00
GuEe-GUI 2168ed8e7d [DM/Feature] Basic PCI/PCIe (Peripheral Component Interconnect Express) bus
PCI/PCIe have better performance and more devices support, such as
NVMe, GPU, Powerful NIC (Like RDMA). PCI/PCIe can access control by
IOMMU that the virtualiztion and userspace driver will more safety.
PCI/PCIe device could hot plugging, no design modifications SoC required,
PCI/PCIe on Embedded SoC is popular now.
We make a simple framework to support them.

Feature Lists:
1.PCI INTx: the INT[A-D] pin IRQ for legacy PCI, work with platform PIC.
2.MSI/MSI-X: the message write IRQ for PCIe, work with platform's PIC.
3.PME: we only support the D0, D1, D2, D3HOT, D3COLD init by framework.
4.Endpoint: a simple EP framework for PCI FPGA or NTB function.
5.OFW: we only support work on OFW SoC, ACPI support in the future maybe.

Host controller:
1. Common PCI host controller on ECAM.
2. Generic PCI host controller on ECAM.

Signed-off-by: GuEe-GUI <2991707448@qq.com>
2024-09-06 17:45:03 -04:00

61 lines
1.3 KiB
C

/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-11-07 GuEe-GUI first version
*/
#include <rtthread.h>
#define DBG_TAG "pci.irq"
#define DBG_LVL DBG_INFO
#include <rtdbg.h>
#include <drivers/pci.h>
void rt_pci_assign_irq(struct rt_pci_device *pdev)
{
int irq = 0;
rt_uint8_t pin, slot = -1;
struct rt_pci_host_bridge *host_bridge = rt_pci_find_host_bridge(pdev->bus);
if (!host_bridge->irq_map)
{
LOG_D("PCI-Device<%s> runtime IRQ mapping not provided by platform",
rt_dm_dev_get_name(&pdev->parent));
return;
}
/* Must try the swizzle when interrupt line passes through a P2P bridge */
rt_pci_read_config_u8(pdev, PCIR_INTPIN, &pin);
if (pin > RT_PCI_INTX_PIN_MAX)
{
pin = 1;
}
if (pin)
{
if (host_bridge->irq_slot)
{
slot = host_bridge->irq_slot(pdev, &pin);
}
/* Map IRQ */
if ((irq = host_bridge->irq_map(pdev, slot, pin)) == -1)
{
irq = 0;
}
}
pdev->irq = irq;
LOG_D("PCI-Device<%s> assign IRQ: got %d", rt_dm_dev_get_name(&pdev->parent), pdev->irq);
/* Save IRQ */
rt_pci_write_config_u8(pdev, PCIR_INTLINE, irq);
}