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:
@@ -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) &&
|
||||
|
Reference in New Issue
Block a user