]> git.ipfire.org Git - thirdparty/pciutils.git/commitdiff
Port to RT-Thread Smart DM PCI
authorGuEe-GUI <2991707448@qq.com>
Thu, 28 Nov 2024 06:37:12 +0000 (14:37 +0800)
committerMartin Mareš <mj@ucw.cz>
Wed, 11 Jun 2025 08:37:52 +0000 (10:37 +0200)
Signed-off-by: GuEe-GUI <2991707448@qq.com>
README
lib/Makefile
lib/configure
lib/init.c
lib/internal.h
lib/pci.h
lib/rt-thread-smart-dm.c [new file with mode: 0644]
pcilib.man

diff --git a/README b/README
index 549d9cd3390e26bb3f884295e50878f42b794199..c4ab99487d68382dc6749ee967cec0e513918049 100644 (file)
--- a/README
+++ b/README
@@ -33,6 +33,7 @@ In runs on the following systems:
        DOS/DJGPP       (via i386 ports)
        SylixOS         (via /proc/pci)
        AmigaOS on PPC  (via Expansion library)
+       RT-Thread Smart (via /proc/pci)
 
 It should be very easy to add support for other systems as well (volunteers
 wanted; if you want to try that, I'll be very glad to see the patches and
index 8dba53e13ee497def3c38a4ab10ab31ef3dc5d24..3ed5e45e16f8f842143b1752f18605ef500020e6 100644 (file)
@@ -95,6 +95,10 @@ ifdef PCI_HAVE_PM_AOS_EXPANSION
 OBJS += aos-expansion
 endif
 
+ifdef PCI_HAVE_PM_RT_THREAD_SMART_DM
+OBJS += rt-thread-smart-dm
+endif
+
 all: $(PCILIB) $(PCILIBPC)
 
 ifeq ($(SHARED),no)
index a4909e1281e1ac7f64d52da9feba559f1ff571c5..4aad9252d93754d4fce48a7e2a2d2d532d3cfc13 100755 (executable)
@@ -235,6 +235,13 @@ case $sys in
                IDSDIR="DEVS:"
                echo >>$m 'CC=gcc'
                ;;
+       rt_thread_smart)
+               echo >>$c '#define PCI_PATH_RT_THREAD_SMART_DM "/proc/pci"'
+               echo >>$c '#define PCI_HAVE_64BIT_ADDRESS'
+               echo >>$c '#define PCI_HAVE_PM_RT_THREAD_SMART_DM'
+               IDSDIR="/etc/pci"
+               LIBRESOLV=
+               ;;
        *)
                echo " Unfortunately, your OS is not supported by the PCI Library"
                exit 1
index c26720a124ef652c96816b21c2e45a92dbd85a6e..b0e50186d6332665a2fe52329259762a28f68e21 100644 (file)
@@ -163,6 +163,11 @@ static struct pci_methods *pci_methods[PCI_ACCESS_MAX] = {
 #else
   NULL,
 #endif
+#ifdef PCI_HAVE_PM_RT_THREAD_SMART_DM
+  &pm_rt_thread_smart_dm,
+#else
+  NULL,
+#endif
 };
 
 // If PCI_ACCESS_AUTO is selected, we probe the access methods in this order
@@ -181,6 +186,7 @@ static int probe_sequence[] = {
   PCI_ACCESS_WIN32_KLDBG,
   PCI_ACCESS_WIN32_SYSDBG,
   PCI_ACCESS_AOS_EXPANSION,
+  PCI_ACCESS_RT_THREAD_SMART_DM,
   // Low-level methods poking the hardware directly
   PCI_ACCESS_ECAM,
   PCI_ACCESS_I386_TYPE1,
index 996b80dd0c33654f695a9d169b6587f5be1f5760..43be8d1a5dac4e81d3d5978d9c85b05acccf5fe2 100644 (file)
@@ -144,6 +144,7 @@ extern struct pci_methods pm_intel_conf1, pm_intel_conf2, pm_linux_proc,
        pm_fbsd_device, pm_aix_device, pm_nbsd_libpci, pm_obsd_device,
        pm_dump, pm_linux_sysfs, pm_darwin, pm_sylixos_device, pm_hurd,
        pm_mmio_conf1, pm_mmio_conf1_ext, pm_ecam,
-       pm_win32_cfgmgr32, pm_win32_kldbg, pm_win32_sysdbg, pm_aos_expansion;
+       pm_win32_cfgmgr32, pm_win32_kldbg, pm_win32_sysdbg, pm_aos_expansion,
+       pm_rt_thread_smart_dm;
 
 #endif
index 58fd5b43717021a5410c9b42376a365ece85acb2..f41bc3c12864b902f07d3281ec4f2cbe0aa7c09d 100644 (file)
--- a/lib/pci.h
+++ b/lib/pci.h
@@ -56,6 +56,7 @@ enum pci_access_type {
   PCI_ACCESS_MMIO_TYPE1_EXT,           /* MMIO ports, type 1 extended */
   PCI_ACCESS_ECAM,                     /* PCIe ECAM via /dev/mem */
   PCI_ACCESS_AOS_EXPANSION,            /* AmigaOS Expansion library */
+  PCI_ACCESS_RT_THREAD_SMART_DM,       /* RT-Thread Smart pci */
   PCI_ACCESS_MAX
 };
 
diff --git a/lib/rt-thread-smart-dm.c b/lib/rt-thread-smart-dm.c
new file mode 100644 (file)
index 0000000..71c5e0c
--- /dev/null
@@ -0,0 +1,222 @@
+/*
+ *  The PCI Library -- Direct Configuration access via RT-Thread Smart DM Ports
+ *
+ *  Copyright (c) 2024 RT-Thread Development Team
+ *
+ *  Can be freely distributed and used under the terms of the GNU GPL v2+.
+ *
+ *  SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdint.h>
+
+#include "internal.h"
+
+static void
+rt_thread_smart_dm_config(struct pci_access *a)
+{
+  pci_define_param(a, "rt-thread-smart-dm.path", PCI_PATH_RT_THREAD_SMART_DM,
+    "Path to the RT-Thread Smart PCI device");
+}
+
+static int
+rt_thread_smart_dm_detect(struct pci_access *a)
+{
+  char *name = pci_get_param(a, "rt-thread-smart-dm.path");
+
+  if (access(name, R_OK))
+    {
+      a->warning("Cannot open %s", name);
+      return 0;
+    }
+
+  a->debug("...using %s", name);
+  return 1;
+}
+
+static void
+rt_thread_smart_dm_init(struct pci_access *a)
+{
+  a->fd = -1;
+}
+
+static void
+rt_thread_smart_dm_cleanup(struct pci_access *a UNUSED)
+{
+  if (a->fd >= 0)
+    {
+      close(a->fd);
+      a->fd = -1;
+    }
+}
+
+static void
+rt_thread_smart_dm_scan(struct pci_access *a)
+{
+  FILE *f;
+  char buf[512];
+
+  if (snprintf(buf, sizeof(buf), "%s/devices", pci_get_param(a, "rt-thread-smart-dm.path")) == sizeof(buf))
+    a->error("File name too long");
+
+  f = fopen(buf, "r");
+  if (!f)
+    a->error("Cannot open %s", buf);
+
+  while (fgets(buf, sizeof(buf)-1, f))
+    {
+      struct pci_dev *d = pci_alloc_dev(a);
+      unsigned int dfn, vend, cnt, known;
+      char *driver;
+      int offset;
+
+#define F " %016" PCI_U64_FMT_X
+      cnt = sscanf(buf, "%x %x %x" F F F F F F F F F F F F F F "%n",
+             &dfn,
+             &vend,
+             &d->irq,
+             &d->base_addr[0],
+             &d->base_addr[1],
+             &d->base_addr[2],
+             &d->base_addr[3],
+             &d->base_addr[4],
+             &d->base_addr[5],
+             &d->rom_base_addr,
+             &d->size[0],
+             &d->size[1],
+             &d->size[2],
+             &d->size[3],
+             &d->size[4],
+             &d->size[5],
+             &d->rom_size,
+             &offset);
+#undef F
+      if (cnt != 9 && cnt != 10 && cnt != 17)
+        a->error("proc: parse error (read only %d items)", cnt);
+      d->bus = dfn >> 8U;
+      d->dev = PCI_SLOT(dfn & 0xff);
+      d->func = PCI_FUNC(dfn & 0xff);
+      d->vendor_id = vend >> 16U;
+      d->device_id = vend & 0xffff;
+      known = 0;
+      if (!a->buscentric)
+        {
+          known |= PCI_FILL_IDENT | PCI_FILL_IRQ | PCI_FILL_BASES;
+          if (cnt >= 10)
+            known |= PCI_FILL_ROM_BASE;
+          if (cnt >= 17)
+            known |= PCI_FILL_SIZES;
+        }
+      if (cnt >= 17)
+        {
+          while (buf[offset] && isspace(buf[offset]))
+            ++offset;
+          driver = &buf[offset];
+          while (buf[offset] && !isspace(buf[offset]))
+            ++offset;
+          buf[offset] = '\0';
+          if (driver[0])
+            {
+              pci_set_property(d, PCI_FILL_DRIVER, driver);
+              known |= PCI_FILL_DRIVER;
+            }
+        }
+      d->known_fields = known;
+      pci_link_dev(a, d);
+    }
+
+  fclose(f);
+}
+
+static int
+rt_thread_smart_dm_setup(struct pci_dev *d, int rw)
+{
+  struct pci_access *a = d->access;
+
+  if (a->cached_dev != d || a->fd_rw < rw)
+    {
+      char buf[1024];
+      int e;
+      if (a->fd >= 0)
+        close(a->fd);
+      e = snprintf(buf, sizeof(buf), "%s/%04x:%02x:%02x.%u",
+                   pci_get_param(a, "rt-thread-smart-dm.path"),
+                   d->domain, d->bus, d->dev, d->func);
+      if (e < 0 || e >= (int) sizeof(buf))
+        a->error("File name too long");
+      a->fd_rw = a->writeable || rw;
+      a->fd = open(buf, a->fd_rw ? O_RDWR : O_RDONLY);
+      if (a->fd < 0)
+        a->warning("Cannot open %s", buf);
+      a->cached_dev = d;
+    }
+  return a->fd;
+}
+
+static int
+rt_thread_smart_dm_read(struct pci_dev *d, int pos, byte *buf, int len)
+{
+  int fd = rt_thread_smart_dm_setup(d, 0);
+  int res;
+
+  if (fd < 0)
+    return 0;
+  res = pread(fd, buf, len, pos);
+  if (res < 0)
+    {
+      d->access->warning("%s: read failed: %s", __func__, strerror(errno));
+      return 0;
+    }
+  else if (res != len)
+    return 0;
+  return 1;
+}
+
+static int
+rt_thread_smart_dm_write(struct pci_dev *d, int pos, byte *buf, int len)
+{
+  int fd = rt_thread_smart_dm_setup(d, 1);
+  int res;
+
+  if (fd < 0)
+    return 0;
+  res = pwrite(fd, buf, len, pos);
+  if (res < 0)
+    {
+      d->access->warning("%s: write failed: %s", __func__, strerror(errno));
+      return 0;
+    }
+  else if (res != len)
+    {
+      d->access->warning("%s: tried to write %d bytes at %d, but only %d succeeded", __func__, len, pos, res);
+      return 0;
+    }
+  return 1;
+}
+
+static void
+rt_thread_smart_dm_cleanup_dev(struct pci_dev *d)
+{
+  if (d->access->cached_dev == d)
+    d->access->cached_dev = NULL;
+}
+
+struct pci_methods pm_rt_thread_smart_dm = {
+  .name = "rt-thread-smart-dm",
+  .help = "RT-Thrad Smart /proc/pci device",
+  .config = rt_thread_smart_dm_config,
+  .detect = rt_thread_smart_dm_detect,
+  .init = rt_thread_smart_dm_init,
+  .cleanup = rt_thread_smart_dm_cleanup,
+  .scan = rt_thread_smart_dm_scan,
+  .fill_info = pci_generic_fill_info,
+  .read = rt_thread_smart_dm_read,
+  .write = rt_thread_smart_dm_write,
+  .cleanup_dev = rt_thread_smart_dm_cleanup_dev,
+};
index 3b7bff438fc75d9a3f6d4873aeeec061181bd2fb..71e10505cfad8896001e1bcd2020c985d02fe3fa 100644 (file)
@@ -159,6 +159,15 @@ https://web.archive.org/web/20110214012715/https://www.microsoft.com/whdc/devtoo
 .TP
 .B aos-expansion
 Access method used on PowerPC Amiga running OS4+. Access is made through Expansion.library. It offers read and write access to configuration space.
+.TP
+.B rt-thread-smart
+The
+.B /proc/pci
+filesystem provided by RT-Thread Smart OS. This method requires PCI support
+(with the procfs feature enabled) to be available in the driver subsystem,
+and the DFS v2-based procfs must be mounted in a rootfs-enabled environment.
+It provides access to the standard PCI configuration space, with limited
+information available.
 
 .SH PARAMETERS
 
@@ -188,6 +197,9 @@ Path to the procfs bus tree.
 .B sysfs.path
 Path to the sysfs device tree.
 .TP
+.B rt-thread-smart-dm.path
+Path to the rt-thread smart DM procfs device tree.
+.TP
 .B devmem.path
 Path to the /dev/mem device or path to the \\Device\\PhysicalMemory NT section
 or name of the platform specific physical address access method. Generally on