42STATIC PHYSICAL_ADDRESS mDmaHostAddressLimit;
50 return (PHYSICAL_ADDRESS)(
UINTN)Address +
PcdGet64 (PcdDmaDeviceOffset);
92 ASSERT ((Alignment & (Alignment - 1)) == 0);
98 if (Alignment > EFI_PAGE_SIZE) {
103 AlignmentMask = Alignment - 1;
109 ASSERT (RealPages > Pages);
111 Memory = mDmaHostAddressLimit;
112 Status =
gBS->AllocatePages (
118 if (EFI_ERROR (Status)) {
122 AlignedMemory = ((
UINTN)Memory + AlignmentMask) & ~AlignmentMask;
124 if (UnalignedPages > 0) {
128 Status =
gBS->FreePages (Memory, UnalignedPages);
133 UnalignedPages = RealPages - Pages - UnalignedPages;
134 if (UnalignedPages > 0) {
138 Status =
gBS->FreePages (Memory, UnalignedPages);
145 Memory = mDmaHostAddressLimit;
146 Status =
gBS->AllocatePages (
152 if (EFI_ERROR (Status)) {
156 AlignedMemory = (
UINTN)Memory;
159 return (VOID *)AlignedMemory;
193 IN VOID *HostAddress,
195 OUT PHYSICAL_ADDRESS *DeviceAddress,
205 if ((HostAddress ==
NULL) ||
206 (NumberOfBytes ==
NULL) ||
207 (DeviceAddress ==
NULL) ||
210 return EFI_INVALID_PARAMETER;
213 if (Operation >= MapOperationMaximum) {
214 return EFI_INVALID_PARAMETER;
217 *DeviceAddress = HostToDeviceAddress (HostAddress);
222 return EFI_OUT_OF_RESOURCES;
225 if (((
UINTN)HostAddress + *NumberOfBytes) > mDmaHostAddressLimit) {
227 goto CommonBufferError;
236 if (Map->BufferAddress ==
NULL) {
237 Status = EFI_OUT_OF_RESOURCES;
242 CopyMem (Map->BufferAddress, (VOID *)(
UINTN)HostAddress, *NumberOfBytes);
245 mCpu->FlushDataCache (
247 (
UINTN)Map->BufferAddress,
249 EfiCpuFlushTypeWriteBack
252 *DeviceAddress = HostToDeviceAddress (Map->BufferAddress);
258 Status =
gDS->GetMemorySpaceDescriptor ((
UINTN)HostAddress, &GcdDescriptor);
259 if (EFI_ERROR (Status)) {
264 if ((GcdDescriptor.
Attributes & (EFI_MEMORY_WB | EFI_MEMORY_WT)) != 0) {
270 goto CommonBufferError;
280 Map->DoubleBuffer =
TRUE;
284 if (Map->BufferAddress ==
NULL) {
285 Status = EFI_OUT_OF_RESOURCES;
290 *DeviceAddress = HostToDeviceAddress (Buffer);
297 mCpu->FlushDataCache (
301 EfiCpuFlushTypeWriteBack
304 Map->DoubleBuffer =
FALSE;
307 Map->DoubleBuffer =
FALSE;
318 Status =
gDS->GetMemorySpaceDescriptor ((
UINTN)HostAddress, &GcdDescriptor);
323 (GcdDescriptor.
Attributes & (EFI_MEMORY_WB | EFI_MEMORY_WT)) == 0
330 mCpu->FlushDataCache (
334 EfiCpuFlushTypeWriteBackInvalidate
338 Map->HostAddress = (
UINTN)HostAddress;
339 Map->NumberOfBytes = *NumberOfBytes;
340 Map->Operation = Operation;
349 "%a: Operation type 'MapOperationBusMasterCommonBuffer' is only "
350 "supported\non memory regions that were allocated using "
351 "DmaAllocateBuffer ()\n",
354 Status = EFI_UNSUPPORTED;
386 if (Mapping ==
NULL) {
388 return EFI_INVALID_PARAMETER;
394 if (((
UINTN)Map->HostAddress + Map->NumberOfBytes) > mDmaHostAddressLimit) {
397 mCpu->FlushDataCache (
399 (
UINTN)Map->BufferAddress,
401 EfiCpuFlushTypeInvalidate
404 (VOID *)(
UINTN)Map->HostAddress,
411 }
else if (Map->DoubleBuffer) {
415 Status = EFI_INVALID_PARAMETER;
419 mCpu->FlushDataCache (
423 EfiCpuFlushTypeInvalidate
426 CopyMem ((VOID *)(
UINTN)Map->HostAddress, Buffer, Map->NumberOfBytes);
435 mCpu->FlushDataCache (
439 EfiCpuFlushTypeInvalidate
469 OUT VOID **HostAddress
498 OUT VOID **HostAddress
507 Attributes = EFI_MEMORY_XP;
509 if (Alignment == 0) {
510 Alignment = EFI_PAGE_SIZE;
513 if ((HostAddress ==
NULL) ||
514 ((Alignment & (Alignment - 1)) != 0))
516 return EFI_INVALID_PARAMETER;
524 return EFI_INVALID_PARAMETER;
527 if (Allocation ==
NULL) {
528 return EFI_OUT_OF_RESOURCES;
532 Status =
gDS->GetMemorySpaceDescriptor ((
UINTN)Allocation, &GcdDescriptor);
533 if (EFI_ERROR (Status)) {
539 Attributes |= EFI_MEMORY_WC;
540 }
else if (GcdDescriptor.
Capabilities & EFI_MEMORY_UC) {
541 Attributes |= EFI_MEMORY_UC;
543 Status = EFI_UNSUPPORTED;
552 Alloc->HostAddress = Allocation;
553 Alloc->NumPages = Pages;
559 if ((GcdDescriptor.
Capabilities & EFI_MEMORY_XP) != EFI_MEMORY_XP) {
560 Status =
gDS->SetMemorySpaceCapabilities (
561 (PHYSICAL_ADDRESS)(
UINTN)Allocation,
569 if (EFI_ERROR (Status)) {
572 "%a failed to set EFI_MEMORY_XP capability on 0x%llx for length 0x%llx. Attempting to allocate without XP set.\n",
580 Attributes &= ~EFI_MEMORY_XP;
585 Status =
gDS->SetMemorySpaceAttributes (
586 (PHYSICAL_ADDRESS)(
UINTN)Allocation,
590 if (EFI_ERROR (Status)) {
594 Status = mCpu->FlushDataCache (
596 (PHYSICAL_ADDRESS)(
UINTN)Allocation,
598 EfiCpuFlushTypeInvalidate
600 if (EFI_ERROR (Status)) {
604 *HostAddress = Allocation;
642 if (HostAddress ==
NULL) {
643 return EFI_INVALID_PARAMETER;
647 !
IsNull (&UncachedAllocationList, Link);
648 Link =
GetNextNode (&UncachedAllocationList, Link))
651 if ((Alloc->HostAddress == HostAddress) && (Alloc->NumPages == Pages)) {
659 return EFI_INVALID_PARAMETER;
664 Status =
gDS->SetMemorySpaceAttributes (
665 (PHYSICAL_ADDRESS)(
UINTN)HostAddress,
669 if (EFI_ERROR (Status)) {
686NonCoherentDmaLibConstructor (
699 mDmaHostAddressLimit =
PcdGet64 (PcdDmaDeviceLimit) -
703 return gBS->LocateProtocol (&gEfiCpuArchProtocolGuid,
NULL, (VOID **)&mCpu);
BOOLEAN EFIAPI IsNull(IN CONST LIST_ENTRY *List, IN CONST LIST_ENTRY *Node)
LIST_ENTRY *EFIAPI GetNextNode(IN CONST LIST_ENTRY *List, IN CONST LIST_ENTRY *Node)
LIST_ENTRY *EFIAPI InsertHeadList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
LIST_ENTRY *EFIAPI GetFirstNode(IN CONST LIST_ENTRY *List)
LIST_ENTRY *EFIAPI RemoveEntryList(IN CONST LIST_ENTRY *Entry)
LIST_ENTRY *EFIAPI InitializeListHead(IN OUT LIST_ENTRY *ListHead)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
@ MapOperationBusMasterWrite
@ MapOperationBusMasterRead
@ MapOperationBusMasterCommonBuffer
VOID EFIAPI FreePages(IN VOID *Buffer, IN UINTN Pages)
VOID EFIAPI FreePool(IN VOID *Buffer)
#define ALIGN_POINTER(Pointer, Alignment)
#define ALIGN_VALUE(Value, Alignment)
#define BASE_CR(Record, TYPE, Field)
#define ASSERT_EFI_ERROR(StatusParameter)
#define DEBUG_CODE_BEGIN()
#define DEBUG(Expression)
EFI_STATUS EFIAPI DmaAllocateAlignedBuffer(IN EFI_MEMORY_TYPE MemoryType, IN UINTN Pages, IN UINTN Alignment, OUT VOID **HostAddress)
EFI_STATUS EFIAPI DmaUnmap(IN VOID *Mapping)
EFI_STATUS EFIAPI DmaMap(IN DMA_MAP_OPERATION Operation, IN VOID *HostAddress, IN OUT UINTN *NumberOfBytes, OUT PHYSICAL_ADDRESS *DeviceAddress, OUT VOID **Mapping)
EFI_STATUS EFIAPI DmaAllocateBuffer(IN EFI_MEMORY_TYPE MemoryType, IN UINTN Pages, OUT VOID **HostAddress)
STATIC VOID * InternalAllocateAlignedPages(IN EFI_MEMORY_TYPE MemoryType, IN UINTN Pages, IN UINTN Alignment)
EFI_STATUS EFIAPI DmaFreeBuffer(IN UINTN Pages, IN VOID *HostAddress)
#define PcdGet64(TokenName)
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
UINT64 EFI_PHYSICAL_ADDRESS
#define EFI_PAGES_TO_SIZE(Pages)
#define EFI_SIZE_TO_PAGES(Size)
UINT32 DmaBufferAlignment