Moving OMAP 3530 code out of BeagleBoard package into its own package
[mirror_edk2.git] / Omap35xxPkg / PciEmulation / PciRootBridgeIo.c
1 /** @file
2
3 Copyright (c) 2008-2009, Apple Inc. All rights reserved.
4
5 All rights reserved. This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13 **/
14
15 #include "PciEmulation.h"
16
17 BOOLEAN
18 PciRootBridgeMemAddressValid (
19 IN PCI_ROOT_BRIDGE *Private,
20 IN UINT64 Address
21 )
22 {
23 if ((Address >= Private->MemoryStart) && (Address < (Private->MemoryStart + Private->MemorySize))) {
24 return TRUE;
25 }
26
27 return FALSE;
28 }
29
30
31 EFI_STATUS
32 PciRootBridgeIoMemRW (
33 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
34 IN UINTN Count,
35 IN BOOLEAN InStrideFlag,
36 IN PTR In,
37 IN BOOLEAN OutStrideFlag,
38 OUT PTR Out
39 )
40 {
41 UINTN Stride;
42 UINTN InStride;
43 UINTN OutStride;
44
45
46 Width = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (Width & 0x03);
47 Stride = (UINTN)1 << Width;
48 InStride = InStrideFlag ? Stride : 0;
49 OutStride = OutStrideFlag ? Stride : 0;
50
51 //
52 // Loop for each iteration and move the data
53 //
54 switch (Width) {
55 case EfiPciWidthUint8:
56 for (;Count > 0; Count--, In.buf += InStride, Out.buf += OutStride) {
57 *In.ui8 = *Out.ui8;
58 }
59 break;
60 case EfiPciWidthUint16:
61 for (;Count > 0; Count--, In.buf += InStride, Out.buf += OutStride) {
62 *In.ui16 = *Out.ui16;
63 }
64 break;
65 case EfiPciWidthUint32:
66 for (;Count > 0; Count--, In.buf += InStride, Out.buf += OutStride) {
67 *In.ui32 = *Out.ui32;
68 }
69 break;
70 default:
71 return EFI_INVALID_PARAMETER;
72 }
73
74 return EFI_SUCCESS;
75 }
76
77 EFI_STATUS
78 PciRootBridgeIoPciRW (
79 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
80 IN BOOLEAN Write,
81 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
82 IN UINT64 UserAddress,
83 IN UINTN Count,
84 IN OUT VOID *UserBuffer
85 )
86 {
87 return EFI_SUCCESS;
88 }
89
90 /**
91 Enables a PCI driver to access PCI controller registers in the PCI root bridge memory space.
92
93 @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
94 @param Width Signifies the width of the memory operations.
95 @param Address The base address of the memory operations.
96 @param Count The number of memory operations to perform.
97 @param Buffer For read operations, the destination buffer to store the results. For write
98 operations, the source buffer to write data from.
99
100 @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.
101 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
102 @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
103
104 **/
105 EFI_STATUS
106 EFIAPI
107 PciRootBridgeIoMemRead (
108 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
109 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
110 IN UINT64 Address,
111 IN UINTN Count,
112 IN OUT VOID *Buffer
113 )
114 {
115 PCI_ROOT_BRIDGE *Private;
116 UINTN AlignMask;
117 PTR In;
118 PTR Out;
119
120 if ( Buffer == NULL ) {
121 return EFI_INVALID_PARAMETER;
122 }
123
124 Private = INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);
125
126 if (!PciRootBridgeMemAddressValid (Private, Address)) {
127 return EFI_INVALID_PARAMETER;
128 }
129
130 AlignMask = (1 << (Width & 0x03)) - 1;
131 if (Address & AlignMask) {
132 return EFI_INVALID_PARAMETER;
133 }
134
135 In.buf = Buffer;
136 Out.buf = (VOID *)(UINTN) Address;
137
138 switch (Width) {
139 case EfiPciWidthUint8:
140 case EfiPciWidthUint16:
141 case EfiPciWidthUint32:
142 case EfiPciWidthUint64:
143 return PciRootBridgeIoMemRW (Width, Count, TRUE, In, TRUE, Out);
144
145 case EfiPciWidthFifoUint8:
146 case EfiPciWidthFifoUint16:
147 case EfiPciWidthFifoUint32:
148 case EfiPciWidthFifoUint64:
149 return PciRootBridgeIoMemRW (Width, Count, TRUE, In, FALSE, Out);
150
151 case EfiPciWidthFillUint8:
152 case EfiPciWidthFillUint16:
153 case EfiPciWidthFillUint32:
154 case EfiPciWidthFillUint64:
155 return PciRootBridgeIoMemRW (Width, Count, FALSE, In, TRUE, Out);
156
157 default:
158 break;
159 }
160
161 return EFI_INVALID_PARAMETER;
162 }
163
164
165
166 /**
167 Enables a PCI driver to access PCI controller registers in the PCI root bridge memory space.
168
169 @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
170 @param Width Signifies the width of the memory operations.
171 @param Address The base address of the memory operations.
172 @param Count The number of memory operations to perform.
173 @param Buffer For read operations, the destination buffer to store the results. For write
174 operations, the source buffer to write data from.
175
176 @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.
177 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
178 @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
179
180 **/
181 EFI_STATUS
182 EFIAPI
183 PciRootBridgeIoMemWrite (
184 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
185 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
186 IN UINT64 Address,
187 IN UINTN Count,
188 IN OUT VOID *Buffer
189 )
190 {
191 PCI_ROOT_BRIDGE *Private;
192 UINTN AlignMask;
193 PTR In;
194 PTR Out;
195
196 if ( Buffer == NULL ) {
197 return EFI_INVALID_PARAMETER;
198 }
199
200 Private = INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);
201
202 if (!PciRootBridgeMemAddressValid (Private, Address)) {
203 return EFI_INVALID_PARAMETER;
204 }
205
206 AlignMask = (1 << (Width & 0x03)) - 1;
207 if (Address & AlignMask) {
208 return EFI_INVALID_PARAMETER;
209 }
210
211 In.buf = (VOID *)(UINTN) Address;
212 Out.buf = Buffer;
213
214 switch (Width) {
215 case EfiPciWidthUint8:
216 case EfiPciWidthUint16:
217 case EfiPciWidthUint32:
218 case EfiPciWidthUint64:
219 return PciRootBridgeIoMemRW (Width, Count, TRUE, In, TRUE, Out);
220
221 case EfiPciWidthFifoUint8:
222 case EfiPciWidthFifoUint16:
223 case EfiPciWidthFifoUint32:
224 case EfiPciWidthFifoUint64:
225 return PciRootBridgeIoMemRW (Width, Count, FALSE, In, TRUE, Out);
226
227 case EfiPciWidthFillUint8:
228 case EfiPciWidthFillUint16:
229 case EfiPciWidthFillUint32:
230 case EfiPciWidthFillUint64:
231 return PciRootBridgeIoMemRW (Width, Count, TRUE, In, FALSE, Out);
232
233 default:
234 break;
235 }
236
237 return EFI_INVALID_PARAMETER;
238 }
239
240 /**
241 Enables a PCI driver to access PCI controller registers in the PCI root bridge memory space.
242
243 @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
244 @param Width Signifies the width of the memory operations.
245 @param Address The base address of the memory operations.
246 @param Count The number of memory operations to perform.
247 @param Buffer For read operations, the destination buffer to store the results. For write
248 operations, the source buffer to write data from.
249
250 @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.
251 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
252 @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
253
254 **/
255 EFI_STATUS
256 EFIAPI
257 PciRootBridgeIoPciRead (
258 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
259 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
260 IN UINT64 Address,
261 IN UINTN Count,
262 IN OUT VOID *Buffer
263 )
264 {
265 if (Buffer == NULL) {
266 return EFI_INVALID_PARAMETER;
267 }
268
269 return PciRootBridgeIoPciRW (This, FALSE, Width, Address, Count, Buffer);
270 }
271
272
273
274 /**
275 Enables a PCI driver to access PCI controller registers in the PCI root bridge memory space.
276
277 @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
278 @param Width Signifies the width of the memory operations.
279 @param Address The base address of the memory operations.
280 @param Count The number of memory operations to perform.
281 @param Buffer For read operations, the destination buffer to store the results. For write
282 operations, the source buffer to write data from.
283
284 @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.
285 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
286 @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
287
288 **/
289 EFI_STATUS
290 EFIAPI
291 PciRootBridgeIoPciWrite (
292 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
293 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
294 IN UINT64 Address,
295 IN UINTN Count,
296 IN OUT VOID *Buffer
297 )
298 {
299 if (Buffer == NULL) {
300 return EFI_INVALID_PARAMETER;
301 }
302
303 return PciRootBridgeIoPciRW (This, TRUE, Width, Address, Count, Buffer);
304 }
305
306