Map a device's physical memory into a process's address space
#include <sys/mman.h> void * mmap_device_memory( void * addr, size_t len, int prot, int flags, uint64_t physical );
Read the architecture guide for your processor; you may need to add special instructions. For example, if you specify PROT_NOCACHE on a PPC device, you may need to issue special eieio (Enforce In-Order Execution of I/O) instructions to ensure that writes occur in a desired order. You'll find an eieio() macro in <ppc/inout.h>. |
Use MAP_FIXED with caution. Not all memory models support it. In general, you should assume that you can MAP_FIXED only at an address (and size) that a call to mmap() without MAP_FIXED returned. |
A memory area being mapped with MAP_FIXED is first unmapped by the system using the same memory area. See munmap() for details.
This function already uses MAP_SHARED ORed with MAP_PHYS (see mmap() for a description of these flags).
libc
Use the -l c option to qcc to link against this library. This library is usually included automatically.
The mmap_device_memory() function maps len bytes of a device's physical memory address into the caller's address space at the location returned by mmap_device_memory().
You should use this function instead of using mmap() with the MAP_PHYS flag.
Typically, you don't need to use addr; you can just pass NULL instead. If you set addr to a non-NULL value, whether the object is mapped depends on whether or not you set MAP_FIXED in flags:
The address of the mapped-in object, or MAP_FAILED if an error occurs (errno is set).
/* Map in the physical memory; 0xb8000 is text mode VGA video memory */ ptr = mmap_device_memory( 0, len, PROT_READ|PROT_WRITE|PROT_NOCACHE, 0, 0xb8000 ); if ( ptr == MAP_FAILED ) { perror( "mmap_device_memory for physical address 0xb8000 failed" ); exit( EXIT_FAILURE ); }
Safety: | |
---|---|
Cancellation point | No |
Interrupt handler | No |
Signal handler | Yes |
Thread | Yes |
mmap(), mmap_device_io(), munmap_device_memory()