CeSetMemoryAttributes (Compact 2013)
3/28/2014
This function provides device drivers and applications with a way to use memory attributes supported on some hardware platforms that the kernel does not support by default.
Syntax
BOOL CeSetMemoryAttributes(
LPVOID pVirtualAddr,
LPVOID pShiftedPhysAddr,
DWORD cbSize,
DWORD dwAttributes
);
Parameters
pVirtualAddr
[in] Beginning virtual memory address.The memory address must be page-aligned.
pShiftedPhysAddr
[in] Corresponding physical memory address shifted by 8 bits, or PHYSICAL_ADDRESS_UNKNOWN.If the value of this parameter is not set to PHYSICAL_ADDRESS_UNKNOWN, a physical address that has this parameter set to less than 8 must be page-aligned.
The range specified must be physically contiguous, which means that the range (pVirtualAddr to pVirtualAddr plus cbSize) must be mapped to (pPhysAddr to pPhysAddr plus cbSize).
cbSize
[in] Size, in bytes, of the memory to be changed.This parameter must be a multiple of pages.
dwAttributes
[in] Memory attribute to be set.Only PAGE_WRITECOMBINE is supported. Write-combining allows bus write transfers to be combined into a larger transfer before being written.
Return Value
Nonzero indicates success. Zero indicates failure. To get extended error information, call GetLastError.
Remarks
The current support for memory attributes in the VirtualSetAttributes function does not require #ifdef
tags and queries to the OAL for drivers or applications to use these attributes.
CeSetMemoryAttributes is platform-independent.
This function is one-way, which means that after the attribute is set, it cannot be unset.
Some x86 CPUs, such as x86 with PAT support, do not require the physical address to support write-combine. Other CPUs require contiguous physical address, such as x86 with Memory Type Range Registers (MTRR) support. Call CeSetMemoryAttributes with a valid pShiftedPhysAddr if the range of physical address is known so that it works on either x86 CPUs.
The following code example shows an implementation of CeSetMemoryAttributes in typical display driver code.
Important
For readability, the following code example does not contain security checking or error handling. Do not use the following code in a production environment.
#define FRAMEBUFFER_PHYSADDR 0xdc000000 // Physical address of the frame buffer
#define FRAMEBUFFER_SIZE 0x00400000 // 4M of frame buffer
LPVOID InitFrameBuffer ()
{
// Allocate and set up the frame buffer.
LPVOID pVirtualAddr = VirtualAlloc (NULL, FRAMEBUFFER_SIZE, MEM_RESERVE, PAGE_NOACCESS);
if (!pVirtualAddr)
{
return NULL;
}
if (!VirtualCopy (pVirtualAddr, (LPVOID) (FRAMEBUFFER_PHYSADDR >> 8), FRAMEBUFFER_SIZE, PAGE_NOCACHE|PAGE_READWRITE))
{
// Error
VirtualFree (pVirtualAddr, 0, MEM_RELEASE);
return NULL;
}
// Try to set 'Write-Combine' attribute on the frame buffer.
// It does not matter if it succeeds or not.
CeSetMemoryAttributes (pVirtualAddr, (LPVOID) (FRAMEBUFFER_PHYSADDR >> 8), FRAMEBUFFER_SIZE, PAGE_WRITECOMBINE);
return pVirtualAddr;
}
Requirements
Header |
pkfuncs.h |
Library |
coredll.lib |
See Also
Reference
Kernel Functions
VirtualSetAttributes