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