MdeModulePkg/SdBlockIoPei: Support IoMmu

Update the SdBlockIoPei driver to consume IOMMU_PPI to allocate DMA
buffer.

If no IOMMU_PPI exists, this driver still calls PEI service
to allocate DMA buffer, with assumption that DRAM==DMA.

This is a compatible change.

Cc: Jiewen Yao <jiewen.yao@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Hao Wu <hao.a.wu@intel.com>
Reviewed-by: Star Zeng <star.zeng@intel.com>
(cherry picked from commit 77af86688c)
This commit is contained in:
Hao Wu
2017-10-30 13:49:31 +08:00
committed by Star Zeng
parent b16a16d30c
commit e4961ec4a2
7 changed files with 483 additions and 19 deletions

View File

@@ -929,7 +929,7 @@ BuildAdmaDescTable (
UINT64 Remaining;
UINT32 Address;
Data = (EFI_PHYSICAL_ADDRESS)(UINTN)Trb->Data;
Data = Trb->DataPhy;
DataLen = Trb->DataLen;
//
// Only support 32bit ADMA Descriptor Table
@@ -998,6 +998,8 @@ SdPeimCreateTrb (
SD_TRB *Trb;
EFI_STATUS Status;
SD_HC_SLOT_CAP Capability;
EDKII_IOMMU_OPERATION MapOp;
UINTN MapLength;
//
// Calculate a divisor for SD clock frequency
@@ -1007,7 +1009,7 @@ SdPeimCreateTrb (
return NULL;
}
Trb = SdPeimAllocateMem (Slot->Private->Pool, sizeof (SD_TRB));
Trb = AllocateZeroPool (sizeof (SD_TRB));
if (Trb == NULL) {
return NULL;
}
@@ -1039,6 +1041,22 @@ SdPeimCreateTrb (
if (Packet->SdCmdBlk->CommandIndex == SD_SEND_TUNING_BLOCK) {
Trb->Mode = SdPioMode;
} else {
if (Trb->Read) {
MapOp = EdkiiIoMmuOperationBusMasterWrite;
} else {
MapOp = EdkiiIoMmuOperationBusMasterRead;
}
if (Trb->DataLen != 0) {
MapLength = Trb->DataLen;
Status = IoMmuMap (MapOp, Trb->Data, &MapLength, &Trb->DataPhy, &Trb->DataMap);
if (EFI_ERROR (Status) || (MapLength != Trb->DataLen)) {
DEBUG ((DEBUG_ERROR, "SdPeimCreateTrb: Fail to map data buffer.\n"));
goto Error;
}
}
if (Trb->DataLen == 0) {
Trb->Mode = SdNoData;
} else if (Capability.Adma2 != 0) {
@@ -1071,12 +1089,16 @@ SdPeimFreeTrb (
IN SD_TRB *Trb
)
{
if ((Trb != NULL) && (Trb->DataMap != NULL)) {
IoMmuUnmap (Trb->DataMap);
}
if ((Trb != NULL) && (Trb->AdmaDesc != NULL)) {
SdPeimFreeMem (Trb->Slot->Private->Pool, Trb->AdmaDesc, Trb->AdmaDescSize);
}
if (Trb != NULL) {
SdPeimFreeMem (Trb->Slot->Private->Pool, Trb, sizeof (SD_TRB));
FreePool (Trb);
}
return;
}
@@ -1241,11 +1263,11 @@ SdPeimExecTrb (
SdPeimHcLedOnOff (Bar, TRUE);
if (Trb->Mode == SdSdmaMode) {
if ((UINT64)(UINTN)Trb->Data >= 0x100000000ul) {
if ((UINT64)(UINTN)Trb->DataPhy >= 0x100000000ul) {
return EFI_INVALID_PARAMETER;
}
SdmaAddr = (UINT32)(UINTN)Trb->Data;
SdmaAddr = (UINT32)(UINTN)Trb->DataPhy;
Status = SdPeimHcRwMmio (Bar + SD_HC_SDMA_ADDR, FALSE, sizeof (SdmaAddr), &SdmaAddr);
if (EFI_ERROR (Status)) {
return Status;
@@ -1485,7 +1507,7 @@ SdPeimCheckTrbResult (
//
// Update SDMA Address register.
//
SdmaAddr = SD_SDMA_ROUND_UP ((UINT32)(UINTN)Trb->Data, SD_SDMA_BOUNDARY);
SdmaAddr = SD_SDMA_ROUND_UP ((UINT32)(UINTN)Trb->DataPhy, SD_SDMA_BOUNDARY);
Status = SdPeimHcRwMmio (
Bar + SD_HC_SDMA_ADDR,
FALSE,
@@ -1495,7 +1517,7 @@ SdPeimCheckTrbResult (
if (EFI_ERROR (Status)) {
goto Done;
}
Trb->Data = (VOID*)(UINTN)SdmaAddr;
Trb->DataPhy = (UINT32)(UINTN)SdmaAddr;
}
if ((Packet->SdCmdBlk->CommandType != SdCommandTypeAdtc) &&