#pragma once #include #include //-------------- 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 ); }