1 /** @file
2   Generic ARM implementation of DmaLib.h
3 
4   Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
5 
6   This program and the accompanying materials
7   are licensed and made available under the terms and conditions of the BSD License
8   which accompanies this distribution.  The full text of the license may be found at
9   http://opensource.org/licenses/bsd-license.php
10 
11   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13 
14 **/
15 
16 #include <Uefi.h>
17 #include <Library/DebugLib.h>
18 #include <Library/DmaLib.h>
19 #include <Library/MemoryAllocationLib.h>
20 
21 
22 
23 /**
24   Provides the DMA controller-specific addresses needed to access system memory.
25 
26   Operation is relative to the DMA bus master.
27 
28   @param  Operation             Indicates if the bus master is going to read or write to system memory.
29   @param  HostAddress           The system memory address to map to the DMA controller.
30   @param  NumberOfBytes         On input the number of bytes to map. On output the number of bytes
31                                 that were mapped.
32   @param  DeviceAddress         The resulting map address for the bus master controller to use to
33                                 access the hosts HostAddress.
34   @param  Mapping               A resulting value to pass to Unmap().
35 
36   @retval EFI_SUCCESS           The range was mapped for the returned NumberOfBytes.
37   @retval EFI_UNSUPPORTED       The HostAddress cannot be mapped as a common buffer.
38   @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
39   @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a lack of resources.
40   @retval EFI_DEVICE_ERROR      The system hardware could not map the requested address.
41 
42 **/
43 EFI_STATUS
44 EFIAPI
DmaMap(IN DMA_MAP_OPERATION Operation,IN VOID * HostAddress,IN OUT UINTN * NumberOfBytes,OUT PHYSICAL_ADDRESS * DeviceAddress,OUT VOID ** Mapping)45 DmaMap (
46   IN     DMA_MAP_OPERATION              Operation,
47   IN     VOID                           *HostAddress,
48   IN OUT UINTN                          *NumberOfBytes,
49   OUT    PHYSICAL_ADDRESS               *DeviceAddress,
50   OUT    VOID                           **Mapping
51   )
52 {
53   *DeviceAddress = (PHYSICAL_ADDRESS)(UINTN)HostAddress;
54   *Mapping = NULL;
55   return EFI_SUCCESS;
56 }
57 
58 
59 /**
60   Completes the DmaMapBusMasterRead(), DmaMapBusMasterWrite(), or DmaMapBusMasterCommonBuffer()
61   operation and releases any corresponding resources.
62 
63   @param  Mapping               The mapping value returned from DmaMap*().
64 
65   @retval EFI_SUCCESS           The range was unmapped.
66   @retval EFI_DEVICE_ERROR      The data was not committed to the target system memory.
67 
68 **/
69 EFI_STATUS
70 EFIAPI
DmaUnmap(IN VOID * Mapping)71 DmaUnmap (
72   IN  VOID                         *Mapping
73   )
74 {
75   return EFI_SUCCESS;
76 }
77 
78 /**
79   Allocates pages that are suitable for an DmaMap() of type MapOperationBusMasterCommonBuffer.
80   mapping.
81 
82   @param  MemoryType            The type of memory to allocate, EfiBootServicesData or
83                                 EfiRuntimeServicesData.
84   @param  Pages                 The number of pages to allocate.
85   @param  HostAddress           A pointer to store the base system memory address of the
86                                 allocated range.
87 
88                                 @retval EFI_SUCCESS           The requested memory pages were allocated.
89   @retval EFI_UNSUPPORTED       Attributes is unsupported. The only legal attribute bits are
90                                 MEMORY_WRITE_COMBINE and MEMORY_CACHED.
91   @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
92   @retval EFI_OUT_OF_RESOURCES  The memory pages could not be allocated.
93 
94 **/
95 EFI_STATUS
96 EFIAPI
DmaAllocateBuffer(IN EFI_MEMORY_TYPE MemoryType,IN UINTN Pages,OUT VOID ** HostAddress)97 DmaAllocateBuffer (
98   IN  EFI_MEMORY_TYPE              MemoryType,
99   IN  UINTN                        Pages,
100   OUT VOID                         **HostAddress
101   )
102 {
103   if (HostAddress == NULL) {
104     return EFI_INVALID_PARAMETER;
105   }
106 
107   //
108   // The only valid memory types are EfiBootServicesData and EfiRuntimeServicesData
109   //
110   // We used uncached memory to keep coherency
111   //
112   if (MemoryType == EfiBootServicesData) {
113     *HostAddress = AllocatePages (Pages);
114   } else if (MemoryType != EfiRuntimeServicesData) {
115     *HostAddress = AllocateRuntimePages (Pages);
116   } else {
117     return EFI_INVALID_PARAMETER;
118   }
119 
120   return EFI_SUCCESS;
121 }
122 
123 
124 /**
125   Frees memory that was allocated with DmaAllocateBuffer().
126 
127   @param  Pages                 The number of pages to free.
128   @param  HostAddress           The base system memory address of the allocated range.
129 
130   @retval EFI_SUCCESS           The requested memory pages were freed.
131   @retval EFI_INVALID_PARAMETER The memory range specified by HostAddress and Pages
132                                 was not allocated with DmaAllocateBuffer().
133 
134 **/
135 EFI_STATUS
136 EFIAPI
DmaFreeBuffer(IN UINTN Pages,IN VOID * HostAddress)137 DmaFreeBuffer (
138   IN  UINTN                        Pages,
139   IN  VOID                         *HostAddress
140   )
141 {
142   if (HostAddress == NULL) {
143      return EFI_INVALID_PARAMETER;
144   }
145 
146   FreePages (HostAddress, Pages);
147   return EFI_SUCCESS;
148 }
149 
150