typedef struct bar_mapping_t {
uintptr_t virt_addr;
void * mmap_addr;
+ off_t mmap_offset;
uintptr_t phys_addr;
uint32_t size;
uint32_t offset;
FILE *file;
void *s;
int ssiz;
+ static size_t page_size;
+
+ page_size = sysconf(_SC_PAGESIZE);
+
ssiz = snprintf(NULL, 0, "/sys/class/uio/%s/maps/map%i/", uio_dev, map_nr);
if (ssiz < 0)
return -1;
snprintf(s, ssiz, "/sys/class/uio/%s/maps/map%i/addr", uio_dev, map_nr);
file = fopen(s, "rb");
+ if (file == NULL)
+ return -1;
fscanf(file, "%"SCNiPTR, &barmap->phys_addr);
fclose(file);
snprintf(s, ssiz, "/sys/class/uio/%s/maps/map%i/offset", uio_dev, map_nr);
file = fopen(s, "rb");
- fscanf(file, "%"SCNi32, &barmap->offset);
- fclose(file);
+ if (file == NULL) {
+ barmap->offset = barmap->phys_addr & (page_size - 1);
+ } else {
+ fscanf(file, "%"SCNi32, &barmap->offset);
+ fclose(file);
+ }
snprintf(s, ssiz, "/sys/class/uio/%s/maps/map%i/size", uio_dev, map_nr);
file = fopen(s, "rb");
+ if (file == NULL)
+ return -1;
fscanf(file, "%"SCNi32, &barmap->size);
fclose(file);
+ barmap->mmap_offset = page_size * map_nr + barmap->offset;
+
return 0;
}
int bar_mapping_setup(bar_mapping_t *barmap, int device_fd)
{
static size_t page_mask = 0;
- off_t mmap_offset;
+ off_t mmap_start;
size_t mmap_size;
if (!page_mask)
page_mask = sysconf(_SC_PAGESIZE) - 1;
- mmap_offset = barmap->offset & ~page_mask;
- mmap_size = barmap->offset + barmap->size + page_mask - mmap_offset;
+ mmap_start = barmap->mmap_offset & ~page_mask;
+ mmap_size = barmap->mmap_offset + barmap->size + page_mask - mmap_start;
mmap_size &= ~page_mask;
- barmap->mmap_addr = mmap(0, mmap_size, PROT_READ | PROT_WRITE, MAP_SHARED, device_fd, mmap_offset);
+ barmap->mmap_addr = mmap(0, mmap_size, PROT_READ | PROT_WRITE, MAP_SHARED, device_fd, mmap_start);
if (barmap->mmap_addr == MAP_FAILED) {
return -1;
}
barmap->virt_addr = (uintptr_t)barmap->mmap_addr;
- barmap->virt_addr += barmap->offset & page_mask;
+ barmap->virt_addr += barmap->mmap_offset & page_mask;
return 0;
}