#define NONEXCLUSIVE_MEMORY_ATTRIBUTES (EFI_MEMORY_XP | EFI_MEMORY_RP | \\r
EFI_MEMORY_RO)\r
\r
-#define INVALID_CPU_ARCH_ATTRIBUTES 0xffffffff\r
-\r
//\r
// Module Variables\r
//\r
// Call CPU Arch Protocol to attempt to set attributes on the range\r
//\r
CpuArchAttributes = ConverToCpuArchAttributes (Attributes);\r
- if (CpuArchAttributes != INVALID_CPU_ARCH_ATTRIBUTES) {\r
+ //\r
+ // CPU arch attributes include page attributes and cache attributes. \r
+ // Only page attributes supports to be cleared, but not cache attributes.\r
+ // Caller is expected to use GetMemorySpaceDescriptor() to get the current\r
+ // attributes, AND/OR attributes, and then calls SetMemorySpaceAttributes()\r
+ // to set the new attributes.\r
+ // So 0 CPU arch attributes should not happen as memory should always have\r
+ // a cache attribute (no matter UC or WB, etc). \r
+ //\r
+ // Here, 0 CPU arch attributes will be filtered to be compatible with the\r
+ // case that caller just calls SetMemorySpaceAttributes() with none CPU\r
+ // arch attributes (for example, RUNTIME) as the purpose of the case is not\r
+ // to clear CPU arch attributes.\r
+ //\r
+ if (CpuArchAttributes != 0) {\r
if (gCpu == NULL) {\r
Status = EFI_NOT_AVAILABLE_YET;\r
} else {\r
// Set attributes operation\r
//\r
case GCD_SET_ATTRIBUTES_MEMORY_OPERATION:\r
+ if (CpuArchAttributes == 0) {\r
+ //\r
+ // Keep original CPU arch attributes when caller just calls\r
+ // SetMemorySpaceAttributes() with none CPU arch attributes (for example, RUNTIME).\r
+ //\r
+ Attributes |= (Entry->Attributes & (EXCLUSIVE_MEMORY_ATTRIBUTES | NONEXCLUSIVE_MEMORY_ATTRIBUTES));\r
+ }\r
Entry->Attributes = Attributes;\r
break;\r
//\r