MdeModulePkg/NvmExpressPei: Avoid updating the module-level variable

This commit is out of the scope for BZ-1409. The commit will remove the
call of RegisterForShadow() at the entry point of the driver. By doing so,
the driver is now possible to be executed without being re-loaded into
permanent memory.

Thus, this commit will update the NvmExpressPei driver to avoid updating
the content of a global variable.

Cc: Jian J Wang <jian.j.wang@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Hao Wu <hao.a.wu@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
This commit is contained in:
Hao Wu 2018-08-27 16:51:45 +08:00
parent 112dcbd9c2
commit 4104423ac0
3 changed files with 91 additions and 83 deletions

View File

@ -1,7 +1,7 @@
/** @file
The DMA memory help function.
Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2018 - 2019, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions
@ -16,7 +16,33 @@
#include "NvmExpressPei.h"
EDKII_IOMMU_PPI *mIoMmu;
/**
Get IOMMU PPI.
@return Pointer to IOMMU PPI.
**/
EDKII_IOMMU_PPI *
GetIoMmu (
VOID
)
{
EFI_STATUS Status;
EDKII_IOMMU_PPI *IoMmu;
IoMmu = NULL;
Status = PeiServicesLocatePpi (
&gEdkiiIoMmuPpiGuid,
0,
NULL,
(VOID **) &IoMmu
);
if (!EFI_ERROR (Status) && (IoMmu != NULL)) {
return IoMmu;
}
return NULL;
}
/**
Provides the controller-specific addresses required to access system memory from a
@ -46,18 +72,21 @@ IoMmuMap (
OUT VOID **Mapping
)
{
EFI_STATUS Status;
UINT64 Attribute;
EFI_STATUS Status;
UINT64 Attribute;
EDKII_IOMMU_PPI *IoMmu;
if (mIoMmu != NULL) {
Status = mIoMmu->Map (
mIoMmu,
Operation,
HostAddress,
NumberOfBytes,
DeviceAddress,
Mapping
);
IoMmu = GetIoMmu ();
if (IoMmu != NULL) {
Status = IoMmu->Map (
IoMmu,
Operation,
HostAddress,
NumberOfBytes,
DeviceAddress,
Mapping
);
if (EFI_ERROR (Status)) {
return EFI_OUT_OF_RESOURCES;
}
@ -78,11 +107,11 @@ IoMmuMap (
ASSERT(FALSE);
return EFI_INVALID_PARAMETER;
}
Status = mIoMmu->SetAttribute (
mIoMmu,
*Mapping,
Attribute
);
Status = IoMmu->SetAttribute (
IoMmu,
*Mapping,
Attribute
);
if (EFI_ERROR (Status)) {
return Status;
}
@ -108,11 +137,14 @@ IoMmuUnmap (
IN VOID *Mapping
)
{
EFI_STATUS Status;
EFI_STATUS Status;
EDKII_IOMMU_PPI *IoMmu;
if (mIoMmu != NULL) {
Status = mIoMmu->SetAttribute (mIoMmu, Mapping, 0);
Status = mIoMmu->Unmap (mIoMmu, Mapping);
IoMmu = GetIoMmu ();
if (IoMmu != NULL) {
Status = IoMmu->SetAttribute (IoMmu, Mapping, 0);
Status = IoMmu->Unmap (IoMmu, Mapping);
} else {
Status = EFI_SUCCESS;
}
@ -148,39 +180,42 @@ IoMmuAllocateBuffer (
EFI_STATUS Status;
UINTN NumberOfBytes;
EFI_PHYSICAL_ADDRESS HostPhyAddress;
EDKII_IOMMU_PPI *IoMmu;
*HostAddress = NULL;
*DeviceAddress = 0;
if (mIoMmu != NULL) {
Status = mIoMmu->AllocateBuffer (
mIoMmu,
EfiBootServicesData,
Pages,
HostAddress,
0
);
IoMmu = GetIoMmu ();
if (IoMmu != NULL) {
Status = IoMmu->AllocateBuffer (
IoMmu,
EfiBootServicesData,
Pages,
HostAddress,
0
);
if (EFI_ERROR (Status)) {
return EFI_OUT_OF_RESOURCES;
}
NumberOfBytes = EFI_PAGES_TO_SIZE(Pages);
Status = mIoMmu->Map (
mIoMmu,
EdkiiIoMmuOperationBusMasterCommonBuffer,
*HostAddress,
&NumberOfBytes,
DeviceAddress,
Mapping
);
Status = IoMmu->Map (
IoMmu,
EdkiiIoMmuOperationBusMasterCommonBuffer,
*HostAddress,
&NumberOfBytes,
DeviceAddress,
Mapping
);
if (EFI_ERROR (Status)) {
return EFI_OUT_OF_RESOURCES;
}
Status = mIoMmu->SetAttribute (
mIoMmu,
*Mapping,
EDKII_IOMMU_ACCESS_READ | EDKII_IOMMU_ACCESS_WRITE
);
Status = IoMmu->SetAttribute (
IoMmu,
*Mapping,
EDKII_IOMMU_ACCESS_READ | EDKII_IOMMU_ACCESS_WRITE
);
if (EFI_ERROR (Status)) {
return Status;
}
@ -219,31 +254,17 @@ IoMmuFreeBuffer (
IN VOID *Mapping
)
{
EFI_STATUS Status;
EFI_STATUS Status;
EDKII_IOMMU_PPI *IoMmu;
if (mIoMmu != NULL) {
Status = mIoMmu->SetAttribute (mIoMmu, Mapping, 0);
Status = mIoMmu->Unmap (mIoMmu, Mapping);
Status = mIoMmu->FreeBuffer (mIoMmu, Pages, HostAddress);
IoMmu = GetIoMmu ();
if (IoMmu != NULL) {
Status = IoMmu->SetAttribute (IoMmu, Mapping, 0);
Status = IoMmu->Unmap (IoMmu, Mapping);
Status = IoMmu->FreeBuffer (IoMmu, Pages, HostAddress);
} else {
Status = EFI_SUCCESS;
}
return Status;
}
/**
Initialize IOMMU.
**/
VOID
IoMmuInit (
VOID
)
{
PeiServicesLocatePpi (
&gEdkiiIoMmuPpiGuid,
0,
NULL,
(VOID **)&mIoMmu
);
}

View File

@ -2,7 +2,7 @@
The NvmExpressPei driver is used to manage non-volatile memory subsystem
which follows NVM Express specification at PEI phase.
Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2018 - 2019, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions
@ -214,13 +214,6 @@ NvmExpressPeimEntry (
PEI_NVME_CONTROLLER_PRIVATE_DATA *Private;
EFI_PHYSICAL_ADDRESS DeviceAddress;
//
// Shadow this PEIM to run from memory
//
if (!EFI_ERROR (PeiServicesRegisterForShadow (FileHandle))) {
return EFI_SUCCESS;
}
//
// Locate the NVME host controller PPI
//
@ -235,8 +228,6 @@ NvmExpressPeimEntry (
return EFI_UNSUPPORTED;
}
IoMmuInit ();
Controller = 0;
MmioBase = 0;
while (TRUE) {

View File

@ -2,7 +2,7 @@
The NvmExpressPei driver is used to manage non-volatile memory subsystem
which follows NVM Express specification at PEI phase.
Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2018 - 2019, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions
@ -147,13 +147,9 @@ struct _PEI_NVME_CONTROLLER_PRIVATE_DATA {
CR (a, PEI_NVME_CONTROLLER_PRIVATE_DATA, EndOfPeiNotifyList, NVME_PEI_CONTROLLER_PRIVATE_DATA_SIGNATURE)
/**
Initialize IOMMU.
**/
VOID
IoMmuInit (
VOID
);
//
// Internal functions
//
/**
Allocates pages that are suitable for an OperationBusMasterCommonBuffer or