“Steve Reid” <stever@qnx.com> wrote:
Chris McKillop <> cdm@qnx.com> > wrote:
: You have to manually loop over and call mem_offset().
Is there a workaround?
Here is the workaround I use:
/***********************************************************************
*
- void *osMemVirt2Phys(void *vAddr, size_t size);
-
- Returns the physical address corresponding to the virtual
- address ‘vAddr’.
-
- The argument ‘size’ is used to verify if the block of virtual memory
- occupies a contiguous block of physical memory.
-
*/
void * osMemVirt2Phys
(
void vAddr, / Virtual address to convert /
size_t size / Length of the block pointed to by vAddr. */
)
{
off_t offset;
size_t contigLen = 0;
size_t remainLen;
off_t dummyOffset1;
off_t dummyOffset2;
size_t contigLen2 = 0;
void *dummyAddr;
/* Validate parameter */
if ((size == 0) || (vAddr == NULL)) return (NULL);
/* Obtain the physical address (offset) of the first segment. */
if (mem_offset(vAddr, NOFD, size, &offset, &contigLen) == -1)
{
return (NULL);
}
/* Make sure memory is contiguous */
dummyAddr = (void *)((int)vAddr + contigLen);
if (contigLen > size)
{
remainLen = 0;
}
else
{
remainLen = size - contigLen;
}
/* Loop thru all segments of physical memory /
/ to ensure they’re contiguous. /
dummyOffset1 = offset;
while(remainLen > 0)
{
/ Obtain the physical address of the next segment. */
if (mem_offset(dummyAddr, NOFD, remainLen,
&dummyOffset2, &contigLen2) == -1)
{
return NULL;
}
/* Make sure this segment is located /
/ immediately after the previous one. */
if (dummyOffset2 - dummyOffset1 != contigLen)
{
return NULL;
}
dummyAddr = (void *)((int)dummyAddr + contigLen2);
if (contigLen2 > remainLen)
{
remainLen = 0;
}
else
{
remainLen -= contigLen2;
}
dummyOffset1 = dummyOffset2;
contigLen = contigLen2;
}
/* Fine… the memory block is contiguous. */
return ((void *)offset);
} /* end of osMemVirt2Phys */