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