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

Other Resources

OEMSetMemoryAttributes