add pci irq interface

Signed-off-by: lipengfei28 <lipengfei28@xiaomi.com>
This commit is contained in:
lipengfei28 2024-07-11 10:38:53 +08:00 committed by Mateusz Szafoni
parent 1e091fb2e0
commit 519c5c86aa
6 changed files with 142 additions and 38 deletions

View File

@ -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
}

View File

@ -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);
UNUSED(bus);
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;
return up_connect_irq(irq, num, mar, mdr);
}
/****************************************************************************

View File

@ -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;
}

View File

@ -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;
}
/****************************************************************************

View File

@ -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)
}

View File

@ -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 */