From: Jani Nikula <jani.nikula@linux.intel.com>
To: Daniel Mrzyglod <daniel.t.mrzyglod@intel.com>,
igt-dev@lists.freedesktop.org
Cc: Mrzyglod@freedesktop.org
Subject: Re: [igt-dev] [PATCH i-g-t] lib: add pci helper functions to intel_chipset
Date: Tue, 12 Mar 2019 15:43:57 +0200 [thread overview]
Message-ID: <87imwojjhe.fsf@intel.com> (raw)
In-Reply-To: <20190311132309.11061-1-daniel.t.mrzyglod@intel.com>
On Mon, 11 Mar 2019, Daniel Mrzyglod <daniel.t.mrzyglod@intel.com> wrote:
> 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;
> +}
static int parse_pci_address_string(const char *pci_address,
struct fd_pci_address *dev_addr)
{
int ret;
unsigned int domain, bus, dev, func;
ret = sscanf(pci_address, "%4x:%2x:%2x.%1x", &domain, &bus, &dev, &func);
if (ret != 4)
return -EINVAL;
dev_addr->domain = domain;
dev_addr->bus = bus;
dev_addr->dev = dev;
dev_addr->func = func;
return 0;
}
BR,
Jani.
> +
> +/**
> + * 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));
--
Jani Nikula, Intel Open Source Graphics Center
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev
prev parent reply other threads:[~2019-03-12 13:42 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-03-11 13:23 [igt-dev] [PATCH i-g-t] lib: add pci helper functions to intel_chipset Daniel Mrzyglod
2019-03-11 13:44 ` [igt-dev] ✓ Fi.CI.BAT: success for " 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 ` Jani Nikula [this message]
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=87imwojjhe.fsf@intel.com \
--to=jani.nikula@linux.intel.com \
--cc=Mrzyglod@freedesktop.org \
--cc=daniel.t.mrzyglod@intel.com \
--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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.