From: Daniel Mrzyglod <daniel.t.mrzyglod@intel.com>
To: igt-dev@lists.freedesktop.org
Cc: Mrzyglod@freedesktop.org
Subject: [igt-dev] [PATCH i-g-t] lib: add pci helper functions to intel_chipset
Date: Mon, 11 Mar 2019 14:23:09 +0100 [thread overview]
Message-ID: <20190311132309.11061-1-daniel.t.mrzyglod@intel.com> (raw)
From: "Mrzyglod, Daniel T" <daniel.t.mrzyglod@intel.com>
This patch add two helper functions:
* reading register from PCI based on open fd
* getting PCI domain/bus/dev/func based on fd
The reason why we need this function is up to scenario when we have
multiple PCI devices.
Signed-off-by: Mrzyglod, Daniel T <daniel.t.mrzyglod@intel.com>
---
lib/intel_chipset.c | 176 ++++++++++++++++++++++++++++++++++++++++++++
lib/intel_chipset.h | 13 ++++
2 files changed, 189 insertions(+)
diff --git a/lib/intel_chipset.c b/lib/intel_chipset.c
index 4748a3fb..3dd722d6 100644
--- a/lib/intel_chipset.c
+++ b/lib/intel_chipset.c
@@ -36,6 +36,7 @@
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/mman.h>
+#include <linux/limits.h>
#include "i915_drm.h"
#include "drmtest.h"
@@ -178,3 +179,178 @@ intel_check_pch(void)
return;
}
}
+
+/**
+ * parse_pci_address_string:
+ * @pci_address: PCI string in form 0000:00:00.0
+ * @dev_addr: structure to be filled by this parsing function
+ *
+ * This function fill fd_pci_address structure with data about pci: domain, bus
+ * device, function
+ * Return:
+ * O or -EINVAL
+ */
+static int parse_pci_address_string(char *pci_address,
+ struct fd_pci_address *dev_addr)
+{
+ unsigned long val;
+ char *pch;
+ int i = 0;
+
+ if (strlen(pci_address) != 12)
+ return -EINVAL;
+
+ /* parse PCI address string for domain */
+ pch = strtok(pci_address, ":.");
+ errno = 0;
+ val = strtoul(pch, NULL, 16);
+ if (errno != 0 || val > UINT16_MAX)
+ return -EINVAL;
+ dev_addr->domain = val;
+
+ /* parse PCI address for: BUS DEVICE FUNCTION */
+ for (i = 0; i < 3; i++) {
+ pch = strtok(NULL, ":.");
+ errno = 0;
+ val = strtoul(pch, NULL, 16);
+ if (errno != 0 || val > UINT8_MAX)
+ return -EINVAL;
+
+ switch (i) {
+ case 0:
+ dev_addr->bus = val;
+ break;
+ case 1:
+ dev_addr->dev = val;
+ break;
+ case 2:
+ dev_addr->func = val;
+ break;
+ default:
+ return -EINVAL;
+ break;
+ }
+ }
+
+ pch = strtok(NULL, ":.");
+ if (pch)
+ return -EINVAL;
+
+ return 0;
+}
+
+/**
+ * parse_pci_filepath_string:
+ * @filepath: string in form ../../devices/pci0000:00/0000:00:00.0/drm/card0
+ * @dev_addr: structure to be filled by this parsing function
+ *
+ * This function parse filepath string to PCI address string 0000:00:00.0 form.
+ * and fill dev_addr.
+ * Return:
+ * O or -EINVAL
+ */
+static int
+parse_pci_filepath_string(char *filepath, struct fd_pci_address *dev_addr)
+{
+ char *pch = strstr(filepath, "pci");
+ char *begin = NULL;
+ char *end = NULL;
+
+ if (pch) {
+ pch = strstr(pch, "/");
+ pch++;
+ begin = pch;
+ end = strstr(pch, "/");
+ *end = '\0';
+ } else {
+ return -EINVAL;
+ }
+ if (strlen(begin) != 12)
+ return -EINVAL;
+ if (parse_pci_address_string(begin, dev_addr) < 0)
+ return -EINVAL;
+ return 0;
+}
+
+/**
+ * get_pci_address_space:
+ * @fd: file descriptor of opened device
+ * @dev_addr: structure with pci_address to be filled by this parsing function
+ *
+ * This function fill dev_addr from reading fstats from opened device.
+ * from it.
+ * Return:
+ * O or -EINVAL
+ */
+int intel_get_pci_address_space(int fd, struct fd_pci_address *dev_addr)
+{
+ struct stat sb;
+ char filepath[PATH_MAX];
+ char fdp[PATH_MAX];
+ int ret = -1;
+
+ if (fstat(fd, &sb) == -1) {
+ perror("stat");
+ return -EINVAL;
+ }
+
+ sprintf(fdp, "/sys/dev/char/%d:%d", major(sb.st_rdev),
+ minor(sb.st_rdev));
+ readlink(fdp, filepath, PATH_MAX);
+
+ ret = parse_pci_filepath_string(filepath, dev_addr);
+ if (ret < 0)
+ return -EINVAL;
+
+ return 0;
+}
+
+/**
+ * pci_read_register_u32:
+ * @fd: file descriptor of opened device
+ * @reg_name: offset in mmio space
+ *
+ * This function read UINT32 from pci.
+ * Return:
+ * Register value or igt_fail
+ */
+uint32_t intel_pci_read_register_u32(int fd, uint32_t reg_name)
+{
+ uint32_t reg_val = 0;
+ int error = -1;
+ int mmio_bar, mmio_size;
+ struct pci_device *dev;
+ struct fd_pci_address dev_addr;
+ void *igt_mmio;
+
+ intel_get_pci_address_space(fd, &dev_addr);
+ pci_system_init();
+ dev = pci_device_find_by_slot((uint32_t)dev_addr.domain,
+ (uint32_t)dev_addr.bus,
+ (uint32_t)dev_addr.dev,
+ (uint32_t)dev_addr.func);
+
+ error = pci_device_probe(dev);
+ igt_fail_on_f(error != 0,
+ "Couldn't probe graphics card\n");
+
+ mmio_bar = 0;
+ mmio_size = 2 * 1024 * 1024;
+
+ error = pci_device_map_range(dev,
+ dev->regions[mmio_bar].base_addr,
+ mmio_size,
+ PCI_DEV_MAP_FLAG_WRITABLE,
+ &igt_mmio);
+ igt_fail_on_f(error != 0,
+ "Couldn't map MMIO region\n");
+
+ reg_val = *(volatile uint32_t *)((volatile char *)igt_mmio + reg_name);
+
+ error = pci_device_unmap_range(dev, igt_mmio,
+ mmio_size);
+ igt_fail_on_f(error != 0,
+ "Couldn't unmap MMIO region\n");
+
+ return reg_val;
+}
diff --git a/lib/intel_chipset.h b/lib/intel_chipset.h
index 40170b7b..96a618eb 100644
--- a/lib/intel_chipset.h
+++ b/lib/intel_chipset.h
@@ -73,6 +73,19 @@ struct intel_device_info {
const struct intel_device_info *intel_get_device_info(uint16_t devid) __attribute__((pure));
+struct fd_pci_address {
+ /**
+ * PCI Address
+ */
+ uint16_t domain;
+ uint8_t bus;
+ uint8_t dev;
+ uint8_t func;
+};
+
+uint32_t intel_pci_read_register_u32(int fd, uint32_t reg_name);
+int intel_get_pci_address_space(int fd, struct fd_pci_address *dev_addr);
+
unsigned intel_gen(uint16_t devid) __attribute__((pure));
unsigned intel_gt(uint16_t devid) __attribute__((pure));
--
2.20.1
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev
next reply other threads:[~2019-03-11 13:23 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-03-11 13:23 Daniel Mrzyglod [this message]
2019-03-11 13:44 ` [igt-dev] ✓ Fi.CI.BAT: success for lib: add pci helper functions to intel_chipset Patchwork
2019-03-11 13:52 ` [igt-dev] [PATCH i-g-t] " Chris Wilson
2019-03-11 14:24 ` Mrzyglod, Daniel T
2019-03-11 15:47 ` [igt-dev] ✗ Fi.CI.IGT: failure for " Patchwork
2019-03-12 13:43 ` [igt-dev] [PATCH i-g-t] " Jani Nikula
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190311132309.11061-1-daniel.t.mrzyglod@intel.com \
--to=daniel.t.mrzyglod@intel.com \
--cc=Mrzyglod@freedesktop.org \
--cc=igt-dev@lists.freedesktop.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox