blob: e8635ed88d91d49307a380f023d0788b964759d1 [file] [log] [blame]
Vishal Bhoj82c80712015-12-15 21:13:33 +05301/** @file
2
3 Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
4
5 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
17BOOLEAN
18PciRootBridgeMemAddressValid (
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
31EFI_STATUS
32PciRootBridgeIoMemRW (
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
77EFI_STATUS
78PciRootBridgeIoPciRW (
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**/
105EFI_STATUS
106EFIAPI
107PciRootBridgeIoMemRead (
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**/
181EFI_STATUS
182EFIAPI
183PciRootBridgeIoMemWrite (
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**/
255EFI_STATUS
256EFIAPI
257PciRootBridgeIoPciRead (
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**/
289EFI_STATUS
290EFIAPI
291PciRootBridgeIoPciWrite (
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