This is an automated email from the ASF dual-hosted git repository. raiden00 pushed a commit to branch releases/12.7 in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 519c5c86aa781dc37783ad775f27e0d43af42502 Author: lipengfei28 <[email protected]> AuthorDate: Thu Jul 11 10:38:53 2024 +0800 add pci irq interface Signed-off-by: lipengfei28 <[email protected]> --- arch/x86_64/include/irq.h | 12 ------ arch/x86_64/src/common/x86_64_pci.c | 35 ++++++----------- arch/x86_64/src/intel64/intel64_irq.c | 48 ++++++++++++++++++++++- drivers/pci/pci.c | 10 ++++- include/nuttx/arch.h | 72 +++++++++++++++++++++++++++++++++++ include/nuttx/pci/pci.h | 3 +- 6 files changed, 142 insertions(+), 38 deletions(-) diff --git a/arch/x86_64/include/irq.h b/arch/x86_64/include/irq.h index 76de330d94..e45b25ea9e 100644 --- a/arch/x86_64/include/irq.h +++ b/arch/x86_64/include/irq.h @@ -147,18 +147,6 @@ static inline_function bool up_interrupt_context(void) return up_current_regs() != NULL; } -/**************************************************************************** - * Name: up_alloc_irq_msi - * Name: up_release_irq_msi - * - * Description: - * Reserve/release vector for MSI - * - ****************************************************************************/ - -int up_alloc_irq_msi(int *num); -void up_release_irq_msi(int *irq, int num); - #undef EXTERN #ifdef __cplusplus } diff --git a/arch/x86_64/src/common/x86_64_pci.c b/arch/x86_64/src/common/x86_64_pci.c index 9502c97360..a7ecd3c92f 100644 --- a/arch/x86_64/src/common/x86_64_pci.c +++ b/arch/x86_64/src/common/x86_64_pci.c @@ -27,8 +27,7 @@ #include <assert.h> #include <debug.h> -#include <arch/irq.h> - +#include <nuttx/arch.h> #include <nuttx/pci/pci.h> #include "x86_64_internal.h" @@ -41,9 +40,6 @@ #define PCI_DATA_ADDR 0xcfc #define PCI_CFG_EN (1 << 31) -#define X86_64_MAR_DEST 0xfee00000 -#define X86_64_MDR_TYPE 0x4000 - #define X86_64_IO_ADDR_LIMIT 0xffff #define readb(addr) ((addr) > X86_64_IO_ADDR_LIMIT ? \ @@ -75,7 +71,8 @@ static int x86_64_pci_read_io(struct pci_bus_s *bus, uintptr_t addr, static int x86_64_pci_write_io(struct pci_bus_s *bus, uintptr_t addr, int size, uint32_t val); -static int x86_64_pci_get_irq(struct pci_bus_s *bus, uint8_t line); +static int x86_64_pci_get_irq(struct pci_bus_s *bus, uint32_t devfn, + uint8_t line, uint8_t pin); static int x86_64_pci_alloc_irq(struct pci_bus_s *bus, int *irq, int num); @@ -319,19 +316,22 @@ static uintptr_t x86_64_pci_map(struct pci_bus_s *bus, uintptr_t start, * Get interrupt number associated with a given INTx line. * * Input Parameters: - * bus - Bus that PCI device resides - * line - activated PCI legacy interrupt line + * bus - Bus that PCI device resides + * devfn - The pci device and function number + * line - Activated PCI legacy interrupt line + * pin - Intx pin number * * Returned Value: * Return interrupt number associated with a given INTx * ****************************************************************************/ -static int x86_64_pci_get_irq(struct pci_bus_s *bus, uint8_t line) +static int x86_64_pci_get_irq(struct pci_bus_s *bus, uint32_t devfn, + uint8_t line, uint8_t pin) { UNUSED(bus); - return IRQ0 + line; + return up_get_legacy_irq(devfn, line, pin); } /**************************************************************************** @@ -416,20 +416,9 @@ static void x86_64_pci_release_irq(struct pci_bus_s *bus, int *irq, int num) static int x86_64_pci_connect_irq(struct pci_bus_s *bus, int *irq, int num, uintptr_t *mar, uint32_t *mdr) { - UNUSED(num); - - if (mar != NULL) - { - *mar = X86_64_MAR_DEST | - (up_apic_cpu_id() << PCI_MSI_DATA_CPUID_SHIFT); - } - - if (mdr != NULL) - { - *mdr = X86_64_MDR_TYPE | irq[0]; - } + UNUSED(bus); - return OK; + return up_connect_irq(irq, num, mar, mdr); } /**************************************************************************** diff --git a/arch/x86_64/src/intel64/intel64_irq.c b/arch/x86_64/src/intel64/intel64_irq.c index f617d98f42..374a240c68 100644 --- a/arch/x86_64/src/intel64/intel64_irq.c +++ b/arch/x86_64/src/intel64/intel64_irq.c @@ -32,6 +32,7 @@ #include <nuttx/irq.h> #include <nuttx/arch.h> +#include <nuttx/pci/pci.h> #include <arch/arch.h> #include <arch/irq.h> #include <arch/io.h> @@ -47,7 +48,9 @@ * Pre-processor Definitions ****************************************************************************/ -#define IRQ_MSI_START IRQ32 +#define IRQ_MSI_START IRQ32 +#define X86_64_MAR_DEST 0xfee00000 +#define X86_64_MDR_TYPE 0x4000 /**************************************************************************** * Private Types @@ -622,6 +625,21 @@ void up_trigger_irq(int irq, cpu_set_t cpuset) } } +/**************************************************************************** + * Name: up_get_legacy_irq + * + * Description: + * Reserve vector for legacy + * + ****************************************************************************/ + +int up_get_legacy_irq(uint32_t devfn, uint8_t line, uint8_t pin) +{ + UNUSED(devfn); + UNUSED(pin); + return IRQ0 + line; +} + /**************************************************************************** * Name: up_alloc_irq_msi * @@ -690,3 +708,31 @@ void up_release_irq_msi(int *irq, int num) spin_unlock_irqrestore(&g_irq_spin, flags); } + +/**************************************************************************** + * Name: up_connect_irq + * + * Description: + * Connect MSI/MSI-X vector to irq + * + ****************************************************************************/ + +int up_connect_irq(FAR int *irq, int num, + FAR uintptr_t *mar, FAR uint32_t *mdr) +{ + UNUSED(num); + + if (mar != NULL) + { + *mar = X86_64_MAR_DEST | + (up_apic_cpu_id() << PCI_MSI_DATA_CPUID_SHIFT); + } + + if (mdr != NULL) + { + *mdr = X86_64_MDR_TYPE | irq[0]; + } + + return OK; +} + diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 11f4717edf..7c08feb04e 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -1695,9 +1695,17 @@ bool pci_stat_line(FAR struct pci_device_s *dev) int pci_get_irq(FAR struct pci_device_s *dev) { uint8_t line = 0; + uint8_t pin = 0; pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &line); - return dev->bus->ctrl->ops->get_irq(dev->bus, line); + pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); + + if (dev->bus->ctrl->ops->get_irq) + { + return dev->bus->ctrl->ops->get_irq(dev->bus, dev->devfn, line, pin); + } + + return -ENOTSUP; } /**************************************************************************** diff --git a/include/nuttx/arch.h b/include/nuttx/arch.h index 64d68203be..77b4e39226 100644 --- a/include/nuttx/arch.h +++ b/include/nuttx/arch.h @@ -3073,6 +3073,78 @@ int up_debugpoint_remove(int type, FAR void *addr, size_t size); #endif +#ifdef CONFIG_PCI + +/**************************************************************************** + * Name: up_alloc_irq_msi + * + * Description: + * Allocate interrupts for MSI/MSI-X vector. + * + * Input Parameters: + * bus - Bus that PCI device resides + * irq - allocated vectors array + * num - number of vectors to allocate + * + * Returned Value: + * >0: success, return number of allocated vectors, + * <0: A negative value errno + * + ****************************************************************************/ + +int up_alloc_irq_msi(FAR int *num); + +/**************************************************************************** + * Name: up_release_irq_msi + * + * Description: + * Allocate interrupts for MSI/MSI-X vector. + * + * Input Parameters: + * bus - Bus that PCI device resides + * irq - vectors array to release + * num - number of vectors in array + * + * Returned Value: + * None + * + ****************************************************************************/ + +void up_release_irq_msi(FAR int *irq, int num); + +/**************************************************************************** + * Name: up_connect_irq + * + * Description: + * Connect interrupt for MSI/MSI-X. + * + * Input Parameters: + * bus - Bus that PCI device resides + * irq - vectors array + * num - number of vectors in array + * mar - returned value for Message Address Register + * mdr - returned value for Message Data Register + * + * Returned Value: + * >0: success, 0: A positive value errno + * + ****************************************************************************/ + +int up_connect_irq(FAR int *irq, int num, + FAR uintptr_t *mar, FAR uint32_t *mdr); + +/**************************************************************************** + * Name: up_get_legacy_irq + * + * Description: + * Reserve vector for legacy + * + ****************************************************************************/ + +int up_get_legacy_irq(uint32_t devfn, uint8_t line, uint8_t pin); + +#endif + #undef EXTERN #if defined(__cplusplus) } diff --git a/include/nuttx/pci/pci.h b/include/nuttx/pci/pci.h index 80660c3bdf..f3ee1cd420 100644 --- a/include/nuttx/pci/pci.h +++ b/include/nuttx/pci/pci.h @@ -306,7 +306,8 @@ struct pci_ops_s /* Get interrupt number associated with a given INTx line */ - CODE int (*get_irq)(FAR struct pci_bus_s *bus, uint8_t line); + CODE int (*get_irq)(FAR struct pci_bus_s *bus, uint32_t devfn, + uint8_t line, uint8_t pin); /* Allocate interrupt for MSI/MSI-X */
