From ec2b9d42afbffa27076bf42b4953eacfb8a3c709 Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Wed, 11 Aug 2021 11:16:11 -0700 Subject: [PATCH] pcie: msi: pci_msi_enable() to take IRQ as parameter 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 --- drivers/pcie/host/msi.c | 19 ++++++++----------- drivers/pcie/host/pcie.c | 2 +- include/drivers/pcie/msi.h | 4 +++- 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/drivers/pcie/host/msi.c b/drivers/pcie/host/msi.c index a19d7a364b6..187c9ceff4a 100644 --- a/drivers/pcie/host/msi.c +++ b/drivers/pcie/host/msi.c @@ -188,14 +188,12 @@ bool pcie_msi_vector_connect(pcie_bdf_t bdf, static void enable_msix(pcie_bdf_t bdf, msi_vector_t *vectors, uint8_t n_vector, - uint32_t base) + uint32_t base, + unsigned int irq) { - unsigned int irq; uint32_t mcr; int i; - irq = pcie_get_irq(bdf); - for (i = 0; i < n_vector; i++) { uint32_t map = pcie_msi_map(irq, &vectors[i]); uint32_t mdr = pcie_msi_mdr(irq, &vectors[i]); @@ -228,16 +226,14 @@ static void disable_msi(pcie_bdf_t bdf, static void enable_msi(pcie_bdf_t bdf, msi_vector_t *vectors, uint8_t n_vector, - uint32_t base) + uint32_t base, + unsigned int irq) { - unsigned int irq; uint32_t mcr; uint32_t map; uint32_t mdr; uint32_t mme; - irq = pcie_get_irq(bdf); - map = pcie_msi_map(irq, vectors); pcie_conf_write(bdf, base + PCIE_MSI_MAP0, map); @@ -263,7 +259,8 @@ static void enable_msi(pcie_bdf_t bdf, bool pcie_msi_enable(pcie_bdf_t bdf, msi_vector_t *vectors, - uint8_t n_vector) + uint8_t n_vector, + unsigned int irq) { bool msi = true; uint32_t base; @@ -288,9 +285,9 @@ bool pcie_msi_enable(pcie_bdf_t bdf, } if (!msi && IS_ENABLED(CONFIG_PCIE_MSI_X)) { - enable_msix(bdf, vectors, n_vector, base); + enable_msix(bdf, vectors, n_vector, base, irq); } else { - enable_msi(bdf, vectors, n_vector, base); + enable_msi(bdf, vectors, n_vector, base, irq); } pcie_set_cmd(bdf, PCIE_CONF_CMDSTAT_MASTER, true); diff --git a/drivers/pcie/host/pcie.c b/drivers/pcie/host/pcie.c index c115b477569..acb73288759 100644 --- a/drivers/pcie/host/pcie.c +++ b/drivers/pcie/host/pcie.c @@ -238,7 +238,7 @@ unsigned int pcie_get_irq(pcie_bdf_t bdf) void pcie_irq_enable(pcie_bdf_t bdf, unsigned int irq) { #if CONFIG_PCIE_MSI - if (pcie_msi_enable(bdf, NULL, 1)) { + if (pcie_msi_enable(bdf, NULL, 1, irq)) { return; } #endif diff --git a/include/drivers/pcie/msi.h b/include/drivers/pcie/msi.h index 31d6ff12311..d13cca81891 100644 --- a/include/drivers/pcie/msi.h +++ b/include/drivers/pcie/msi.h @@ -101,11 +101,13 @@ extern uint16_t pcie_msi_mdr(unsigned int irq, * @param bdf the target PCI endpoint * @param vectors an array of allocated vector(s) * @param n_vector the size of the vector array + * @param irq The IRQ we wish to trigger via MSI. * @return true if the endpoint supports MSI, false otherwise. */ extern bool pcie_msi_enable(pcie_bdf_t bdf, msi_vector_t *vectors, - uint8_t n_vector); + uint8_t n_vector, + unsigned int irq); /* * MSI capability IDs in the PCI configuration capability list.