You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2024/09/06 02:01:19 UTC
(nuttx) 02/13: Changed the x86 64 pci driver
This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 7cbb7d36d8a7ecc61e9a7afe4d393da22237189a
Author: yangshuyong <ya...@xiaomi.com>
AuthorDate: Tue Mar 5 14:25:08 2024 +0800
Changed the x86 64 pci driver
Signed-off-by: yangshuyong <ya...@xiaomi.com>
Signed-off-by: lipengfei28 <li...@xiaomi.com>
---
arch/x86_64/src/common/x86_64_pci.c | 228 ++++++++++++++++++++++++------------
drivers/pci/pci.c | 36 ++++++
include/nuttx/pci/pci.h | 22 ++++
3 files changed, 209 insertions(+), 77 deletions(-)
diff --git a/arch/x86_64/src/common/x86_64_pci.c b/arch/x86_64/src/common/x86_64_pci.c
index d603d8999b..a84bc73898 100644
--- a/arch/x86_64/src/common/x86_64_pci.c
+++ b/arch/x86_64/src/common/x86_64_pci.c
@@ -35,39 +35,41 @@
* Pre-processor Definitions
****************************************************************************/
-#define PCI_CFG_ADDR 0xcf8
-#define PCI_DATA_ADDR 0xcfc
-#define PCI_CFG_EN (1 << 31)
+#define PCI_CFG_ADDR 0xcf8
+#define PCI_DATA_ADDR 0xcfc
+#define PCI_CFG_EN (1 << 31)
/****************************************************************************
* Private Functions Definitions
****************************************************************************/
-static void x86_64_pci_cfg_write(struct pci_dev_s *dev, int reg,
- uint32_t val, int width);
-static uint32_t x86_64_pci_cfg_read(struct pci_dev_s *dev, int reg,
- int width);
-static int x86_64_pci_map_bar(uint64_t addr, uint64_t len);
-static uint32_t x86_64_pci_io_read(const volatile void *addr, int width);
-static void x86_64_pci_io_write(const volatile void *addr, uint32_t val,
- int width);
+static int x86_64_pci_write(struct pci_bus_s *bus, unsigned int devfn,
+ int where, int size, uint32_t val);
+static int x86_64_pci_read(struct pci_bus_s *bus, unsigned int devfn,
+ int where, int size, uint32_t *val);
+static uintptr_t x86_64_pci_map(struct pci_bus_s *bus, uintptr_t start,
+ uintptr_t end);
+static int x86_64_pci_read_io(struct pci_bus_s *bus, uintptr_t addr,
+ int size, uint32_t *val);
+static int x86_64_pci_write_io(struct pci_bus_s *bus, uintptr_t addr,
+ int size, uint32_t val);
/****************************************************************************
* Private Data
****************************************************************************/
-static const struct pci_bus_ops_s g_x86_64_pci_bus_ops =
+static const struct pci_ops_s g_x86_64_pci_ops =
{
- .pci_cfg_write = x86_64_pci_cfg_write,
- .pci_cfg_read = x86_64_pci_cfg_read,
- .pci_map_bar = x86_64_pci_map_bar,
- .pci_io_read = x86_64_pci_io_read,
- .pci_io_write = x86_64_pci_io_write,
+ .write = x86_64_pci_write,
+ .read = x86_64_pci_read,
+ .map = x86_64_pci_map,
+ .read_io = x86_64_pci_read_io,
+ .write_io = x86_64_pci_write_io,
};
-static struct pci_bus_s g_x86_64_pci_bus =
+static struct pci_controller_s g_x86_64_pci =
{
- .ops = &g_x86_64_pci_bus_ops,
+ .ops = &g_x86_64_pci_ops
};
/****************************************************************************
@@ -75,135 +77,208 @@ static struct pci_bus_s g_x86_64_pci_bus =
****************************************************************************/
/****************************************************************************
- * Name: x86_64_pci_cfg_write
+ * Name: x86_64_pci_write
*
* Description:
- * Write 8, 16, 32, 64 bits data to PCI-E configuration space of device
+ * Write 8, 16, 32, 64 bits data to PCI configuration space of device
* specified by dev
*
* Input Parameters:
- * bdf - Device private data
- * reg - A pointer to the read-only buffer of data to be written
- * size - The number of bytes to send from the buffer
+ * bus - Bus that PCI device resides
+ * devfn - The device and function bit field of bdf
+ * where - Offset in the specify PCI device cfg address space
+ * size - The number of bytes to send from the buffer
+ * val - The value to write
*
* Returned Value:
* 0: success, <0: A negated errno
*
****************************************************************************/
-static void x86_64_pci_cfg_write(struct pci_dev_s *dev, int reg,
- uint32_t val, int width)
+static int x86_64_pci_write(struct pci_bus_s *bus, unsigned int devfn,
+ int where, int size, uint32_t val)
{
- uint8_t offset_mask = (4 - width);
+ uint8_t offset_mask = (4 - size);
- outl(PCI_CFG_EN | (dev->bdf << 8) | reg, PCI_CFG_ADDR);
- switch (width)
+ outl(PCI_CFG_EN | (bus->number << 16) | (devfn << 8) | where,
+ PCI_CFG_ADDR);
+
+ switch (size)
{
case 1:
- outb(val, PCI_DATA_ADDR + (reg & offset_mask));
- return;
+ outb(val, PCI_DATA_ADDR + (where & offset_mask));
+ break;
case 2:
- outw(val, PCI_DATA_ADDR + (reg & offset_mask));
- return;
+ outw(val, PCI_DATA_ADDR + (where & offset_mask));
+ break;
case 4:
outl(val, PCI_DATA_ADDR);
- return;
+ break;
default:
- pcierr("Invalid cfg write width %d\n", width);
+ pcierr("Invalid cfg write size %d\n", size);
+ return -EINVAL;
}
+
+ return 0;
}
/****************************************************************************
- * Name: x86_64_pci_cfg_read
+ * Name: x86_64_pci_read
*
* Description:
- * Read 8, 16, 32, 64 bits data from PCI-E configuration space of device
+ * Read 8, 16, 32, 64 bits data from PCI configuration space of device
* specified by dev
*
* Input Parameters:
- * dev - Device private data
- * buffer - A pointer to a buffer to receive the data from the device
+ * bus - Bus that PCI device resides
+ * devfn - The device and function bit field of bdf
+ * where - Offset in the specify PCI device cfg address space
* size - The requested number of bytes to be read
+ * val - A pointer to a buffer to receive the data from the device
*
* Returned Value:
* 0: success, <0: A negated errno
*
****************************************************************************/
-static uint32_t x86_64_pci_cfg_read(struct pci_dev_s *dev, int reg,
- int width)
+static int x86_64_pci_read(struct pci_bus_s *bus, unsigned int devfn,
+ int where, int size, uint32_t *val)
{
- uint32_t ret;
- uint8_t offset_mask = 4 - width;
+ uint8_t offset_mask = 4 - size;
- outl(PCI_CFG_EN | (dev->bdf << 8) | reg, PCI_CFG_ADDR);
+ outl(PCI_CFG_EN | (bus->number << 16) | (devfn << 8) | where,
+ PCI_CFG_ADDR);
- switch (width)
+ switch (size)
{
case 1:
- ret = inb(PCI_DATA_ADDR + (reg & offset_mask));
- return ret;
-
+ *val = inb(PCI_DATA_ADDR + (where & offset_mask));
+ break;
case 2:
- ret = inw(PCI_DATA_ADDR + (reg & offset_mask));
- return ret;
+ *val = inw(PCI_DATA_ADDR + (where & offset_mask));
+ break;
case 4:
- ret = inl(PCI_DATA_ADDR);
- return ret;
+ *val = inl(PCI_DATA_ADDR);
+ break;
default:
- pcierr("Invalid cfg read width %d\n", width);
+ *val = 0;
+ pcierr("Invalid cfg read size %d\n", size);
+ return -EINVAL;
}
- return 0;
+ return OK;
}
-static uint32_t x86_64_pci_io_read(const volatile void *addr, int width)
+/****************************************************************************
+ * Name: x86_64_pci_read_io
+ *
+ * Description:
+ * Read 8, 16, 32, 64 bits data from PCI io address space of x86 64 device
+ *
+ * Input Parameters:
+ * bus - Bus that PCI device resides
+ * addr - The address to received data
+ * size - The requested number of bytes to be read
+ * val - A pointer to a buffer to receive the data from the device
+ *
+ * Returned Value:
+ * 0: success, <0: A negated errno
+ *
+ ****************************************************************************/
+
+static int x86_64_pci_read_io(struct pci_bus_s *bus, uintptr_t addr,
+ int size, uint32_t *val)
{
- uint16_t portaddr = (uint16_t)(intptr_t)addr;
+ uint16_t portaddr = (uint16_t)addr;
- switch (width)
+ switch (size)
{
case 1:
- return (uint32_t)inb(portaddr);
+ *val = (uint32_t)inb(portaddr);
+ break;
case 2:
- return (uint32_t)inw(portaddr);
+ *val = (uint32_t)inw(portaddr);
+ break;
case 4:
- return (uint32_t)inl(portaddr);
+ *val = (uint32_t)inl(portaddr);
+ break;
default:
- pcierr("Invalid read width %d\n", width);
+ *val = 0;
+ pcierr("Invalid read size %d\n", size);
DEBUGPANIC();
+ return -EINVAL;
}
- return 0;
+ return OK;
}
-static void x86_64_pci_io_write(const volatile void *addr, uint32_t val,
- int width)
+/****************************************************************************
+ * Name: x86_64_pci_write_io
+ *
+ * Description:
+ * Write 8, 16, 32, 64 bits data to PCI io address space of x86 64 device
+ *
+ * Input Parameters:
+ * bus - Bus that PCI device resides
+ * addr - The address to write data
+ * size - The requested number of bytes to be write
+ * val - The value to write
+ *
+ * Returned Value:
+ * 0: success, <0: A negated errno
+ *
+ ****************************************************************************/
+
+static int x86_64_pci_write_io(struct pci_bus_s *bus, uintptr_t addr,
+ int size, uint32_t val)
{
- uint16_t portaddr = (uint16_t)(intptr_t)addr;
+ uint16_t portaddr = (uint16_t)addr;
- switch (width)
+ switch (size)
{
case 1:
outb((uint8_t)val, portaddr);
- return;
+ break;
case 2:
outw((uint16_t)val, portaddr);
- return;
+ break;
case 4:
outl((uint32_t)val, portaddr);
- return;
+ break;
default:
- pcierr("Invalid write width %d\n", width);
+ pcierr("Invalid write size %d\n", size);
DEBUGPANIC();
+ return -EINVAL;
}
+
+ return OK;
}
-static int x86_64_pci_map_bar(uint64_t addr, uint64_t len)
+/****************************************************************************
+ * Name: x86_64_pci_map
+ *
+ * Description:
+ * Map a memory region
+ *
+ * Input Parameters:
+ * bus - Bus that PCI device resides
+ * start - The start address to map
+ * end - The end address to map
+ *
+ * Returned Value:
+ * >0: success, 0: A positive value errno
+ *
+ ****************************************************************************/
+
+static uintptr_t x86_64_pci_map(struct pci_bus_s *bus, uintptr_t start,
+ uintptr_t end)
{
- up_map_region((void *)(uintptr_t)addr, len,
- X86_PAGE_WR | X86_PAGE_PRESENT | X86_PAGE_NOCACHE | X86_PAGE_GLOBAL);
- return OK;
+ int ret;
+
+ ret = up_map_region((void *)start, end - start + 1, X86_PAGE_WR |
+ X86_PAGE_PRESENT | X86_PAGE_NOCACHE | X86_PAGE_GLOBAL);
+
+ return ret < 0 ? 0 : start;
}
/****************************************************************************
@@ -214,12 +289,11 @@ static int x86_64_pci_map_bar(uint64_t addr, uint64_t len)
* Name: x86_64_pci_init
*
* Description:
- * Initialize the PCI-E bus
+ * Initialize the PCI bus
*
****************************************************************************/
void x86_64_pci_init(void)
{
- pciinfo("Initializing PCI Bus\n");
- pci_initialize(&g_x86_64_pci_bus);
+ pci_register_controller(&g_x86_64_pci);
}
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index adcb05da3c..35b4ac0056 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -74,6 +74,36 @@
return ret; \
}
+#define PCI_BUS_READ_IO(len, type, size) \
+ int pci_bus_read_io_##len(FAR struct pci_bus_s *bus, uintptr_t where, \
+ FAR type *value) \
+ { \
+ int ret = -EINVAL; \
+ uint32_t data = 0; \
+ \
+ if (!PCI_##len##_BAD) \
+ { \
+ ret = bus->ctrl->ops->read_io(bus, where, size, &data); \
+ } \
+ \
+ *value = (type)data; \
+ return ret; \
+ }
+
+#define PCI_BUS_WRITE_IO(len, type, size) \
+ int pci_bus_write_io_##len(FAR struct pci_bus_s *bus, uintptr_t where, \
+ type value) \
+ { \
+ int ret = -EINVAL; \
+ \
+ if (!PCI_##len##_BAD) \
+ { \
+ ret = bus->ctrl->ops->write_io(bus, where, size, value); \
+ } \
+ \
+ return ret; \
+ }
+
#define pci_match_one_device(id, dev) \
(((id)->vendor == PCI_ANY_ID || (id)->vendor == (dev)->vendor) && \
((id)->device == PCI_ANY_ID || (id)->device == (dev)->device) && \
@@ -1171,3 +1201,9 @@ PCI_BUS_READ_CONFIG(dword, uint32_t, 4)
PCI_BUS_WRITE_CONFIG(byte, uint8_t, 1)
PCI_BUS_WRITE_CONFIG(word, uint16_t, 2)
PCI_BUS_WRITE_CONFIG(dword, uint32_t, 4)
+PCI_BUS_READ_IO(byte, uint8_t, 1)
+PCI_BUS_READ_IO(word, uint16_t, 2)
+PCI_BUS_READ_IO(dword, uint32_t, 4)
+PCI_BUS_WRITE_IO(byte, uint8_t, 1)
+PCI_BUS_WRITE_IO(word, uint16_t, 2)
+PCI_BUS_WRITE_IO(dword, uint32_t, 4)
\ No newline at end of file
diff --git a/include/nuttx/pci/pci.h b/include/nuttx/pci/pci.h
index 917ea81d92..f6835e8c81 100644
--- a/include/nuttx/pci/pci.h
+++ b/include/nuttx/pci/pci.h
@@ -152,6 +152,24 @@
#define pci_write_config_dword(dev, where, val) \
pci_bus_write_config_dword((dev)->bus, (dev)->devfn, where, val)
+#define pci_read_io_byte(dev, addr, val) \
+ pci_bus_read_io_byte((dev)->bus, addr, val)
+
+#define pci_read_io_word(dev, addr, val) \
+ pci_bus_read_io_word((dev)->bus, addr, val)
+
+#define pci_read_io_dword(dev, addr, val) \
+ pci_bus_read_io_dword((dev)->bus, addr, val)
+
+#define pci_write_io_byte(dev, addr, val) \
+ pci_bus_write_io_byte((dev)->bus, addr, val)
+
+#define pci_write_io_word(dev, addr, val) \
+ pci_bus_write_io_word((dev)->bus, addr, val)
+
+#define pci_write_io_dword(dev, addr, val) \
+ pci_bus_write_io_dword((dev)->bus, addr, val)
+
/****************************************************************************
* Public Types
****************************************************************************/
@@ -232,6 +250,10 @@ struct pci_ops_s
CODE uintptr_t (*map)(FAR struct pci_bus_s *bus, uintptr_t start,
uintptr_t end);
+ CODE int (*read_io)(FAR struct pci_bus_s *bus, uintptr_t addr,
+ int size, FAR uint32_t *val);
+ CODE int (*write_io)(FAR struct pci_bus_s *bus, uintptr_t addr,
+ int size, uint32_t val);
};
/* Each pci channel is a top-level PCI bus seem by CPU. A machine with