#pragma once
#include <sys/mman.h>
#include <errno.h>
//-------------- UIO memory mapping ------------------------------------------//
//
// All functions here return NULL (and set errno) on failure.
//
// UIO abuses the offset parameter of mmap() to specify the memory region index.
//
// NOTE: instead of hardcoding memory region indices you really ought to try to
// look them up by name via sysfs, where you can also find the size and physical
// address for each region. This is left as an exercise for the reader.
// Map memory region of given size.
//
inline void *uio_mmap( int fd, int index, size_t size, bool readonly = false )
{
static int const MAX_UIO_MAPS = 5;
static int const page_size = getpagesize();
size += -size & ( page_size - 1 ); // round up to multiple of page size
if( index < 0 || index >= MAX_UIO_MAPS || size == 0 ) {
errno = EINVAL;
return NULL;
}
int prot = PROT_READ | ( readonly ? 0 : PROT_WRITE );
void *ptr = mmap( NULL, size, prot, MAP_SHARED, fd, index * page_size );
if( ptr == MAP_FAILED )
return NULL;
assert( ptr != NULL );
return ptr;
}
// Map memory region of given type T.
//
template< typename T >
T *uio_mmap( int fd, int index, bool readonly = false )
{
return (T *)uio_mmap( fd, index, sizeof(T), readonly );
}
Comments