1
0
Fork 0
mirror of https://git.rwth-aachen.de/acs/public/villas/node/ synced 2025-03-09 00:00:00 +01:00

kernel/pci: parse BAR regions

This commit is contained in:
Daniel Krebs 2018-05-15 15:11:47 +02:00
parent 2bfb9e2450
commit ad820a3618
2 changed files with 77 additions and 0 deletions

View file

@ -9,6 +9,7 @@
#pragma once
#include <stdint.h>
#include "list.h"
#define PCI_SLOT(devfn) (((devfn) >> 3) & 0x1f)
@ -33,6 +34,13 @@ struct pci_device {
} slot; /**< Bus, Device, Function (BDF) */
};
struct pci_region {
int num;
uintptr_t start;
uintptr_t end;
unsigned long long flags;
};
struct pci {
struct list devices; /**< List of available PCI devices in the system (struct pci_device) */
};
@ -66,6 +74,8 @@ int pci_attach_driver(const struct pci_device *d, const char *driver);
/** Return the IOMMU group of this PCI device or -1 if the device is not in a group. */
int pci_get_iommu_group(const struct pci_device *d);
size_t pci_get_regions(const struct pci_device *d, struct pci_region** regions);
#ifdef __cplusplus
}
#endif

View file

@ -254,6 +254,73 @@ struct pci_device * pci_lookup_device(struct pci *p, struct pci_device *f)
return list_search(&p->devices, (cmp_cb_t) pci_device_compare, (void *) f);
}
size_t pci_get_regions(const struct pci_device *d, struct pci_region** regions)
{
FILE* f;
char sysfs[1024];
assert(regions != NULL);
snprintf(sysfs, sizeof(sysfs), "%s/bus/pci/devices/%04x:%02x:%02x.%x/resource",
SYSFS_PATH, d->slot.domain, d->slot.bus, d->slot.device, d->slot.function);
f = fopen(sysfs, "r");
if (!f)
serror("Failed to open resource mapping %s", sysfs);
struct pci_region _regions[8];
struct pci_region* cur_region = _regions;
size_t valid_regions = 0;
ssize_t bytesRead;
char* line = NULL;
size_t len = 0;
int region = 0;
// cap to 8 regions, just because we don't know how many may exist
while(region < 8 && (bytesRead = getline(&line, &len, f)) != -1) {
unsigned long long tokens[3];
char* s = line;
for(int i = 0; i < 3; i++) {
char* end;
tokens[i] = strtoull(s, &end, 16);
if(s == end) {
printf("Error parsing line %d of %s\n", region + 1, sysfs);
tokens[0] = tokens[1] = 0; // mark invalid
break;
}
s = end;
}
free(line);
// required for getline() to allocate a new buffer on the next iteration
line = NULL;
len = 0;
if(tokens[0] != tokens[1]) {
// this is a valid region
cur_region->num = region;
cur_region->start = tokens[0];
cur_region->end = tokens[1];
cur_region->flags = tokens[2];
cur_region++;
valid_regions++;
}
region++;
}
if(valid_regions > 0) {
const size_t len = valid_regions * sizeof (struct pci_region);
*regions = malloc(len);
memcpy(*regions, _regions, len);
}
return valid_regions;
}
int pci_get_driver(const struct pci_device *d, char *buf, size_t buflen)
{
int ret;