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 /** @file
The DMA memory help function. 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 This program and the accompanying materials
are licensed and made available under the terms and conditions are licensed and made available under the terms and conditions
@@ -16,7 +16,33 @@
#include "NvmExpressPei.h" #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 Provides the controller-specific addresses required to access system memory from a
@@ -46,18 +72,21 @@ IoMmuMap (
OUT VOID **Mapping OUT VOID **Mapping
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
UINT64 Attribute; UINT64 Attribute;
EDKII_IOMMU_PPI *IoMmu;
if (mIoMmu != NULL) { IoMmu = GetIoMmu ();
Status = mIoMmu->Map (
mIoMmu, if (IoMmu != NULL) {
Operation, Status = IoMmu->Map (
HostAddress, IoMmu,
NumberOfBytes, Operation,
DeviceAddress, HostAddress,
Mapping NumberOfBytes,
); DeviceAddress,
Mapping
);
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
return EFI_OUT_OF_RESOURCES; return EFI_OUT_OF_RESOURCES;
} }
@@ -78,11 +107,11 @@ IoMmuMap (
ASSERT(FALSE); ASSERT(FALSE);
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
Status = mIoMmu->SetAttribute ( Status = IoMmu->SetAttribute (
mIoMmu, IoMmu,
*Mapping, *Mapping,
Attribute Attribute
); );
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
return Status; return Status;
} }
@@ -108,11 +137,14 @@ IoMmuUnmap (
IN VOID *Mapping IN VOID *Mapping
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
EDKII_IOMMU_PPI *IoMmu;
if (mIoMmu != NULL) { IoMmu = GetIoMmu ();
Status = mIoMmu->SetAttribute (mIoMmu, Mapping, 0);
Status = mIoMmu->Unmap (mIoMmu, Mapping); if (IoMmu != NULL) {
Status = IoMmu->SetAttribute (IoMmu, Mapping, 0);
Status = IoMmu->Unmap (IoMmu, Mapping);
} else { } else {
Status = EFI_SUCCESS; Status = EFI_SUCCESS;
} }
@@ -148,39 +180,42 @@ IoMmuAllocateBuffer (
EFI_STATUS Status; EFI_STATUS Status;
UINTN NumberOfBytes; UINTN NumberOfBytes;
EFI_PHYSICAL_ADDRESS HostPhyAddress; EFI_PHYSICAL_ADDRESS HostPhyAddress;
EDKII_IOMMU_PPI *IoMmu;
*HostAddress = NULL; *HostAddress = NULL;
*DeviceAddress = 0; *DeviceAddress = 0;
if (mIoMmu != NULL) { IoMmu = GetIoMmu ();
Status = mIoMmu->AllocateBuffer (
mIoMmu, if (IoMmu != NULL) {
EfiBootServicesData, Status = IoMmu->AllocateBuffer (
Pages, IoMmu,
HostAddress, EfiBootServicesData,
0 Pages,
); HostAddress,
0
);
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
return EFI_OUT_OF_RESOURCES; return EFI_OUT_OF_RESOURCES;
} }
NumberOfBytes = EFI_PAGES_TO_SIZE(Pages); NumberOfBytes = EFI_PAGES_TO_SIZE(Pages);
Status = mIoMmu->Map ( Status = IoMmu->Map (
mIoMmu, IoMmu,
EdkiiIoMmuOperationBusMasterCommonBuffer, EdkiiIoMmuOperationBusMasterCommonBuffer,
*HostAddress, *HostAddress,
&NumberOfBytes, &NumberOfBytes,
DeviceAddress, DeviceAddress,
Mapping Mapping
); );
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
return EFI_OUT_OF_RESOURCES; return EFI_OUT_OF_RESOURCES;
} }
Status = mIoMmu->SetAttribute ( Status = IoMmu->SetAttribute (
mIoMmu, IoMmu,
*Mapping, *Mapping,
EDKII_IOMMU_ACCESS_READ | EDKII_IOMMU_ACCESS_WRITE EDKII_IOMMU_ACCESS_READ | EDKII_IOMMU_ACCESS_WRITE
); );
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
return Status; return Status;
} }
@@ -219,31 +254,17 @@ IoMmuFreeBuffer (
IN VOID *Mapping IN VOID *Mapping
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
EDKII_IOMMU_PPI *IoMmu;
if (mIoMmu != NULL) { IoMmu = GetIoMmu ();
Status = mIoMmu->SetAttribute (mIoMmu, Mapping, 0);
Status = mIoMmu->Unmap (mIoMmu, Mapping); if (IoMmu != NULL) {
Status = mIoMmu->FreeBuffer (mIoMmu, Pages, HostAddress); Status = IoMmu->SetAttribute (IoMmu, Mapping, 0);
Status = IoMmu->Unmap (IoMmu, Mapping);
Status = IoMmu->FreeBuffer (IoMmu, Pages, HostAddress);
} else { } else {
Status = EFI_SUCCESS; Status = EFI_SUCCESS;
} }
return Status; 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 The NvmExpressPei driver is used to manage non-volatile memory subsystem
which follows NVM Express specification at PEI phase. 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 This program and the accompanying materials
are licensed and made available under the terms and conditions are licensed and made available under the terms and conditions
@@ -214,13 +214,6 @@ NvmExpressPeimEntry (
PEI_NVME_CONTROLLER_PRIVATE_DATA *Private; PEI_NVME_CONTROLLER_PRIVATE_DATA *Private;
EFI_PHYSICAL_ADDRESS DeviceAddress; 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 // Locate the NVME host controller PPI
// //
@@ -235,8 +228,6 @@ NvmExpressPeimEntry (
return EFI_UNSUPPORTED; return EFI_UNSUPPORTED;
} }
IoMmuInit ();
Controller = 0; Controller = 0;
MmioBase = 0; MmioBase = 0;
while (TRUE) { while (TRUE) {

View File

@@ -2,7 +2,7 @@
The NvmExpressPei driver is used to manage non-volatile memory subsystem The NvmExpressPei driver is used to manage non-volatile memory subsystem
which follows NVM Express specification at PEI phase. 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 This program and the accompanying materials
are licensed and made available under the terms and conditions 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) CR (a, PEI_NVME_CONTROLLER_PRIVATE_DATA, EndOfPeiNotifyList, NVME_PEI_CONTROLLER_PRIVATE_DATA_SIGNATURE)
/** //
Initialize IOMMU. // Internal functions
**/ //
VOID
IoMmuInit (
VOID
);
/** /**
Allocates pages that are suitable for an OperationBusMasterCommonBuffer or Allocates pages that are suitable for an OperationBusMasterCommonBuffer or