Skip to content

Commit

Permalink
UefiCpuPkg/CpuDxe: Add memory attribute setting.
Browse files Browse the repository at this point in the history
Add memory attribute setting in CpuArch protocol.
Previous SetMemoryAttributes() API only supports cache attribute setting.

This patch updated SetMemoryAttributes() API to support memory attribute
setting by updating CPU page table.

Cc: Jeff Fan <jeff.fan@intel.com>
Cc: Michael Kinney <michael.d.kinney@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
Reviewed-by: Jeff Fan <jeff.fan@intel.com>
  • Loading branch information
jyao1 committed Feb 22, 2017
1 parent d37fa01 commit 22292ed
Show file tree
Hide file tree
Showing 4 changed files with 977 additions and 61 deletions.
141 changes: 82 additions & 59 deletions UefiCpuPkg/CpuDxe/CpuDxe.c
@@ -1,7 +1,7 @@
/** @file
CPU DXE Module to produce CPU ARCH Protocol.
Copyright (c) 2008 - 2016, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2008 - 2017, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
Expand All @@ -14,6 +14,10 @@

#include "CpuDxe.h"
#include "CpuMp.h"
#include "CpuPageTable.h"

#define CACHE_ATTRIBUTE_MASK (EFI_MEMORY_UC | EFI_MEMORY_WC | EFI_MEMORY_WT | EFI_MEMORY_WB | EFI_MEMORY_UCE | EFI_MEMORY_WP)
#define MEMORY_ATTRIBUTE_MASK (EFI_MEMORY_RP | EFI_MEMORY_XP | EFI_MEMORY_RO)

//
// Global Variables
Expand Down Expand Up @@ -368,10 +372,9 @@ CpuSetMemoryAttributes (
EFI_STATUS MpStatus;
EFI_MP_SERVICES_PROTOCOL *MpService;
MTRR_SETTINGS MtrrSettings;

if (!IsMtrrSupported ()) {
return EFI_UNSUPPORTED;
}
UINT64 CacheAttributes;
UINT64 MemoryAttributes;
MTRR_MEMORY_CACHE_TYPE CurrentCacheType;

//
// If this function is called because GCD SetMemorySpaceAttributes () is called
Expand All @@ -384,69 +387,87 @@ CpuSetMemoryAttributes (
return EFI_SUCCESS;
}

switch (Attributes) {
case EFI_MEMORY_UC:
CacheType = CacheUncacheable;
break;

case EFI_MEMORY_WC:
CacheType = CacheWriteCombining;
break;
CacheAttributes = Attributes & CACHE_ATTRIBUTE_MASK;
MemoryAttributes = Attributes & MEMORY_ATTRIBUTE_MASK;

case EFI_MEMORY_WT:
CacheType = CacheWriteThrough;
break;
if (Attributes != (CacheAttributes | MemoryAttributes)) {
return EFI_INVALID_PARAMETER;
}

case EFI_MEMORY_WP:
CacheType = CacheWriteProtected;
break;
if (CacheAttributes != 0) {
if (!IsMtrrSupported ()) {
return EFI_UNSUPPORTED;
}

case EFI_MEMORY_WB:
CacheType = CacheWriteBack;
break;
switch (CacheAttributes) {
case EFI_MEMORY_UC:
CacheType = CacheUncacheable;
break;

case EFI_MEMORY_UCE:
case EFI_MEMORY_RP:
case EFI_MEMORY_XP:
case EFI_MEMORY_RUNTIME:
return EFI_UNSUPPORTED;
case EFI_MEMORY_WC:
CacheType = CacheWriteCombining;
break;

default:
return EFI_INVALID_PARAMETER;
}
//
// call MTRR libary function
//
Status = MtrrSetMemoryAttribute (
BaseAddress,
Length,
CacheType
);
case EFI_MEMORY_WT:
CacheType = CacheWriteThrough;
break;

if (!RETURN_ERROR (Status)) {
MpStatus = gBS->LocateProtocol (
&gEfiMpServiceProtocolGuid,
NULL,
(VOID **)&MpService
);
//
// Synchronize the update with all APs
//
if (!EFI_ERROR (MpStatus)) {
MtrrGetAllMtrrs (&MtrrSettings);
MpStatus = MpService->StartupAllAPs (
MpService, // This
SetMtrrsFromBuffer, // Procedure
FALSE, // SingleThread
NULL, // WaitEvent
0, // TimeoutInMicrosecsond
&MtrrSettings, // ProcedureArgument
NULL // FailedCpuList
);
ASSERT (MpStatus == EFI_SUCCESS || MpStatus == EFI_NOT_STARTED);
case EFI_MEMORY_WP:
CacheType = CacheWriteProtected;
break;

case EFI_MEMORY_WB:
CacheType = CacheWriteBack;
break;

default:
return EFI_INVALID_PARAMETER;
}
CurrentCacheType = MtrrGetMemoryAttribute(BaseAddress);
if (CurrentCacheType != CacheType) {
//
// call MTRR libary function
//
Status = MtrrSetMemoryAttribute (
BaseAddress,
Length,
CacheType
);

if (!RETURN_ERROR (Status)) {
MpStatus = gBS->LocateProtocol (
&gEfiMpServiceProtocolGuid,
NULL,
(VOID **)&MpService
);
//
// Synchronize the update with all APs
//
if (!EFI_ERROR (MpStatus)) {
MtrrGetAllMtrrs (&MtrrSettings);
MpStatus = MpService->StartupAllAPs (
MpService, // This
SetMtrrsFromBuffer, // Procedure
FALSE, // SingleThread
NULL, // WaitEvent
0, // TimeoutInMicrosecsond
&MtrrSettings, // ProcedureArgument
NULL // FailedCpuList
);
ASSERT (MpStatus == EFI_SUCCESS || MpStatus == EFI_NOT_STARTED);
}
}
if (EFI_ERROR(Status)) {
return Status;
}
}
}
return (EFI_STATUS) Status;

//
// Set memory attribute by page table
//
return AssignMemoryPageAttributes (NULL, BaseAddress, Length, MemoryAttributes, AllocatePages);
}

/**
Expand Down Expand Up @@ -888,6 +909,8 @@ InitializeCpu (
{
EFI_STATUS Status;
EFI_EVENT IdleLoopEvent;

InitializePageTableLib();

InitializeFloatingPointUnits ();

Expand Down
5 changes: 3 additions & 2 deletions UefiCpuPkg/CpuDxe/CpuDxe.inf
@@ -1,7 +1,7 @@
## @file
# CPU driver installs CPU Architecture Protocol and CPU MP protocol.
#
# Copyright (c) 2008 - 2016, Intel Corporation. All rights reserved.<BR>
# Copyright (c) 2008 - 2017, Intel Corporation. All rights reserved.<BR>
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
Expand All @@ -19,7 +19,6 @@
FILE_GUID = 1A1E4886-9517-440e-9FDE-3BE44CEE2136
MODULE_TYPE = DXE_DRIVER
VERSION_STRING = 1.0

ENTRY_POINT = InitializeCpu

[Packages]
Expand Down Expand Up @@ -52,6 +51,8 @@
CpuGdt.h
CpuMp.c
CpuMp.h
CpuPageTable.h
CpuPageTable.c

[Sources.IA32]
Ia32/CpuAsm.asm
Expand Down

0 comments on commit 22292ed

Please sign in to comment.