You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by bt...@apache.org on 2020/07/30 02:26:48 UTC

[incubator-nuttx] 11/11: pcie: create MSI/MSIX related marcos and simplify the msi/msix routines

This is an automated email from the ASF dual-hosted git repository.

btashton pushed a commit to branch pci
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit bf7ed8f9f760a0bccf6b70834ebeac76cef5b39a
Author: Yang Chung-Fan <so...@gmail.com>
AuthorDate: Wed May 6 21:35:42 2020 +0900

    pcie: create MSI/MSIX related marcos and simplify the msi/msix routines
---
 boards/x86_64/intel64/qemu-intel64/src/qemu_pcie.c | 79 +++++++++++++---------
 include/nuttx/pcie/pcie.h                          | 33 ++++++++-
 2 files changed, 77 insertions(+), 35 deletions(-)

diff --git a/boards/x86_64/intel64/qemu-intel64/src/qemu_pcie.c b/boards/x86_64/intel64/qemu-intel64/src/qemu_pcie.c
index 439532c..0580593 100644
--- a/boards/x86_64/intel64/qemu-intel64/src/qemu_pcie.c
+++ b/boards/x86_64/intel64/qemu-intel64/src/qemu_pcie.c
@@ -266,53 +266,62 @@ static int qemu_pci_msix_register(FAR struct pcie_dev_s *dev,
   unsigned int bar;
   uint16_t message_control;
   uint32_t table_bar_ind;
-  uint32_t lo_table_addr;
-  uint32_t hi_table_addr;
+  uint32_t table_addr_32;
   uint64_t msix_table_addr = 0;
 
   int cap = pci_find_cap(dev, PCI_CAP_MSIX);
   if (cap < 0)
       return -EINVAL;
 
-  __qemu_pci_cfg_read(dev->bdf, cap + 2, &message_control, 2);
+  __qemu_pci_cfg_read(dev->bdf, cap + PCI_MSIX_MCR,
+                      &message_control, PCI_MSIX_MCR_SIZE);
 
   /* bounds check */
 
-  if (index > (message_control & 0x3ff))
+  if (index > (message_control & PCI_MSIX_MCR_TBL_MASK))
       return -EINVAL;
 
-  __qemu_pci_cfg_read(dev->bdf, cap + 4, &table_bar_ind, 4);
+  __qemu_pci_cfg_read(dev->bdf, cap + PCI_MSIX_TBL,
+                      &table_bar_ind, PCI_MSIX_TBL_SIZE);
 
-  bar = (table_bar_ind & 7) * 4 + PCI_CFG_BAR;
+  bar = (table_bar_ind & PCI_MSIX_BIR_MASK);
 
-  __qemu_pci_cfg_read(dev->bdf, bar, &lo_table_addr, 4);
+  if (!pci_get_bar(dev, bar, &table_addr_32))
+    {
+      /* 32 bit bar */
 
-  if ((lo_table_addr & 6) == PCI_BAR_64BIT)
+      msix_table_addr = table_addr_32;
+    }
+  else
     {
-      __qemu_pci_cfg_read(dev->bdf, bar + 4, &hi_table_addr, 4);
-      msix_table_addr = (uint64_t)hi_table_addr << 32;
+      pci_get_bar64(dev, bar, &msix_table_addr);
     }
 
-  msix_table_addr |= lo_table_addr & ~0xf;
-  msix_table_addr += table_bar_ind & ~0x7;
+  msix_table_addr &= ~0xf;
+  msix_table_addr += table_bar_ind & ~PCI_MSIX_BIR_MASK;
 
   /* enable and mask */
 
-  message_control |= (MSIX_CTRL_ENABLE | MSIX_CTRL_FMASK);
-  __qemu_pci_cfg_write(dev->bdf, cap + 2, &message_control, 2);
+  message_control |= (PCI_MSIX_MCR_EN | PCI_MSIX_MCR_FMASK);
+  __qemu_pci_cfg_write(dev->bdf, cap + PCI_MSIX_MCR,
+                       &message_control, PCI_MSIX_MCR_SIZE);
 
-  msix_table_addr += 16 * index;
-  mmio_write32((uint32_t *)(msix_table_addr),
-               0xfee00000 | up_apic_cpu_id() << 12);
-  mmio_write32((uint32_t *)(msix_table_addr + 4), 0);
-  mmio_write32((uint32_t *)(msix_table_addr + 8), vector);
-  mmio_write32((uint32_t *)(msix_table_addr + 12), 0);
+  msix_table_addr += PCI_MSIX_TBL_ENTRY_SIZE * index;
+  mmio_write32((uint32_t *)(msix_table_addr + PCI_MSIX_TBL_LO_ADDR),
+               0xfee00000 | up_apic_cpu_id() << PCI_MSIX_APIC_ID_OFFSET);
+  mmio_write32((uint32_t *)(msix_table_addr + PCI_MSIX_TBL_HI_ADDR),
+               0);
+  mmio_write32((uint32_t *)(msix_table_addr + PCI_MSIX_TBL_MSG_DATA),
+               vector);
+  mmio_write32((uint32_t *)(msix_table_addr + PCI_MSIX_TBL_VEC_CTL),
+               0);
 
   /* enable and unmask */
 
-  message_control &= ~MSIX_CTRL_FMASK;
+  message_control &= ~PCI_MSIX_MCR_FMASK;
 
-  __qemu_pci_cfg_write(dev->bdf, cap + 2, &message_control, 2);
+  __qemu_pci_cfg_write(dev->bdf, cap + PCI_MSIX_MCR,
+                       &message_control, PCI_MSIX_MCR_SIZE);
 
   return 0;
 }
@@ -342,27 +351,31 @@ static int qemu_pci_msi_register(FAR struct pcie_dev_s *dev, uint16_t vector)
   if (cap < 0)
       return -1;
 
-  uint32_t dest = 0xfee00000 | (up_apic_cpu_id() << 12);
-  __qemu_pci_cfg_write(dev->bdf, cap + 4, &dest, 4);
+  uint32_t dest = 0xfee00000 | (up_apic_cpu_id() << PCI_MSI_APIC_ID_OFFSET);
+  __qemu_pci_cfg_write(dev->bdf, cap + PCI_MSI_MAR, &dest, PCI_MSI_MAR_SIZE);
 
-  __qemu_pci_cfg_read(dev->bdf, cap + 2, &ctl, 2);
-  if (ctl & (1 << 7))
+  __qemu_pci_cfg_read(dev->bdf, cap + PCI_MSI_MCR, &ctl, PCI_MSI_MCR_SIZE);
+  if ((ctl & PCI_MSI_MCR_64) == PCI_MSI_MCR_64)
     {
       uint32_t tmp = 0;
-      __qemu_pci_cfg_write(dev->bdf, cap + 8, &tmp, 4);
-      data = cap + 0x0c;
+      __qemu_pci_cfg_write(dev->bdf,
+                           cap + PCI_MSI_MAR64_HI, &tmp,
+                           PCI_MSI_MAR64_HI_SIZE);
+      data = cap + PCI_MSI_MDR64;
     }
   else
     {
-      data = cap + 0x08;
+      data = cap + PCI_MSI_MDR;
     }
 
-  __qemu_pci_cfg_write(dev->bdf, data, &vector, 2);
+  __qemu_pci_cfg_write(dev->bdf, data, &vector, PCI_MSI_MDR_SIZE);
+
+  __qemu_pci_cfg_write(dev->bdf, cap + PCI_MSI_MCR, &vector,
+                       PCI_MSI_MCR_SIZE);
 
-  __qemu_pci_cfg_write(dev->bdf, cap + 2, &vector, 2);
+  uint16_t tmp = PCI_MSI_MCR_EN;
 
-  uint16_t en = 0x0001;
-  __qemu_pci_cfg_write(dev->bdf, cap + 2, &en, 2);
+  __qemu_pci_cfg_write(dev->bdf, cap + PCI_MSI_MCR, &tmp, PCI_MSI_MCR_SIZE);
 
   return OK;
 }
diff --git a/include/nuttx/pcie/pcie.h b/include/nuttx/pcie/pcie.h
index 8b5b98e..fffc791 100644
--- a/include/nuttx/pcie/pcie.h
+++ b/include/nuttx/pcie/pcie.h
@@ -59,10 +59,39 @@
 #define PCI_DEV_CLASS_OTHER     0xff
 
 #define PCI_CAP_PM              0x01
+
 #define PCI_CAP_MSI             0x05
+# define PCI_MSI_MCR            0x02
+# define PCI_MSI_MCR_SIZE       2
+# define PCI_MSI_MCR_EN         (1 << 0)
+# define PCI_MSI_MCR_64         (1 << 7)
+# define PCI_MSI_MAR            0x04
+# define PCI_MSI_MAR_SIZE       4
+# define PCI_MSI_MDR            0x08
+# define PCI_MSI_MDR_SIZE       2
+# define PCI_MSI_MAR64_HI       0x08
+# define PCI_MSI_MAR64_HI_SIZE  4
+# define PCI_MSI_MDR64          0x0c
+# define PCI_MSI_MDR64_SIZE     2
+# define PCI_MSI_APIC_ID_OFFSET 0xc
+
 #define PCI_CAP_MSIX            0x11
-# define MSIX_CTRL_ENABLE       0x8000
-# define MSIX_CTRL_FMASK        0x4000
+# define PCI_MSIX_MCR           0x02
+# define PCI_MSIX_MCR_SIZE      2
+# define PCI_MSIX_MCR_EN        (1 << 15)
+# define PCI_MSIX_MCR_FMASK     0x4000
+# define PCI_MSIX_MCR_TBL_MASK  0x03ff
+# define PCI_MSIX_TBL           0x04
+# define PCI_MSIX_TBL_SIZE      4
+# define PCI_MSIX_PBA           0x08
+# define PCI_MSIX_PBA_SIZE      4
+# define PCI_MSIX_BIR_MASK      0x07
+# define PCI_MSIX_TBL_ENTRY_SIZE 0x10
+# define PCI_MSIX_TBL_LO_ADDR   0x0
+# define PCI_MSIX_TBL_HI_ADDR   0x4
+# define PCI_MSIX_TBL_MSG_DATA  0x8
+# define PCI_MSIX_TBL_VEC_CTL   0xc
+# define PCI_MSIX_APIC_ID_OFFSET 0xc
 
 /****************************************************************************
  * Public Types