]> git.proxmox.com Git - mirror_edk2.git/blob - ArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/PciRootBridgeIo.c
ArmPlatformPkg/ArmJunoPkg: Added Juno development board support
[mirror_edk2.git] / ArmPlatformPkg / ArmJunoPkg / Drivers / ArmJunoDxe / PciRootBridgeIo.c
1 /** @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
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 Width = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (Width & 0x03);
46 Stride = (UINTN)1 << Width;
47 InStride = InStrideFlag ? Stride : 0;
48 OutStride = OutStrideFlag ? Stride : 0;
49
50 //
51 // Loop for each iteration and move the data
52 //
53 switch (Width) {
54 case EfiPciWidthUint8:
55 for (;Count > 0; Count--, In.Buffer += InStride, Out.Buffer += OutStride) {
56 *In.Ui8 = *Out.Ui8;
57 }
58 break;
59 case EfiPciWidthUint16:
60 for (;Count > 0; Count--, In.Buffer += InStride, Out.Buffer += OutStride) {
61 *In.Ui16 = *Out.Ui16;
62 }
63 break;
64 case EfiPciWidthUint32:
65 for (;Count > 0; Count--, In.Buffer += InStride, Out.Buffer += OutStride) {
66 *In.Ui32 = *Out.Ui32;
67 }
68 break;
69 default:
70 return EFI_INVALID_PARAMETER;
71 }
72
73 return EFI_SUCCESS;
74 }
75
76 EFI_STATUS
77 PciRootBridgeIoPciRW (
78 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
79 IN BOOLEAN Write,
80 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
81 IN UINT64 UserAddress,
82 IN UINTN Count,
83 IN OUT VOID *UserBuffer
84 )
85 {
86 return EFI_SUCCESS;
87 }
88
89 /**
90 Enables a PCI driver to access PCI controller registers in the PCI root bridge memory space.
91
92 @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
93 @param Width Signifies the width of the memory operations.
94 @param Address The base address of the memory operations.
95 @param Count The number of memory operations to perform.
96 @param Buffer For read operations, the destination buffer to store the results. For write
97 operations, the source buffer to write data from.
98
99 @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.
100 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
101 @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
102
103 **/
104 EFI_STATUS
105 EFIAPI
106 PciRootBridgeIoMemRead (
107 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
108 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
109 IN UINT64 Address,
110 IN UINTN Count,
111 IN OUT VOID *Buffer
112 )
113 {
114 PCI_ROOT_BRIDGE *Private;
115 UINTN AlignMask;
116 PTR In;
117 PTR Out;
118
119 if ( Buffer == NULL ) {
120 return EFI_INVALID_PARAMETER;
121 }
122
123 Private = INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);
124
125 if (!PciRootBridgeMemAddressValid (Private, Address)) {
126 return EFI_INVALID_PARAMETER;
127 }
128
129 AlignMask = (1 << (Width & 0x03)) - 1;
130 if (Address & AlignMask) {
131 return EFI_INVALID_PARAMETER;
132 }
133
134 In.Buffer = Buffer;
135 Out.Buffer = (VOID *)(UINTN) Address;
136
137 switch (Width) {
138 case EfiPciWidthUint8:
139 case EfiPciWidthUint16:
140 case EfiPciWidthUint32:
141 case EfiPciWidthUint64:
142 return PciRootBridgeIoMemRW (Width, Count, TRUE, In, TRUE, Out);
143
144 case EfiPciWidthFifoUint8:
145 case EfiPciWidthFifoUint16:
146 case EfiPciWidthFifoUint32:
147 case EfiPciWidthFifoUint64:
148 return PciRootBridgeIoMemRW (Width, Count, TRUE, In, FALSE, Out);
149
150 case EfiPciWidthFillUint8:
151 case EfiPciWidthFillUint16:
152 case EfiPciWidthFillUint32:
153 case EfiPciWidthFillUint64:
154 return PciRootBridgeIoMemRW (Width, Count, FALSE, In, TRUE, Out);
155
156 default:
157 break;
158 }
159
160 return EFI_INVALID_PARAMETER;
161 }
162
163 /**
164 Enables a PCI driver to access PCI controller registers in the PCI root bridge memory space.
165
166 @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
167 @param Width Signifies the width of the memory operations.
168 @param Address The base address of the memory operations.
169 @param Count The number of memory operations to perform.
170 @param Buffer For read operations, the destination buffer to store the results. For write
171 operations, the source buffer to write data from.
172
173 @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.
174 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
175 @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
176
177 **/
178 EFI_STATUS
179 EFIAPI
180 PciRootBridgeIoMemWrite (
181 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
182 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
183 IN UINT64 Address,
184 IN UINTN Count,
185 IN OUT VOID *Buffer
186 )
187 {
188 PCI_ROOT_BRIDGE *Private;
189 UINTN AlignMask;
190 PTR In;
191 PTR Out;
192
193 if ( Buffer == NULL ) {
194 return EFI_INVALID_PARAMETER;
195 }
196
197 Private = INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);
198
199 if (!PciRootBridgeMemAddressValid (Private, Address)) {
200 return EFI_INVALID_PARAMETER;
201 }
202
203 AlignMask = (1 << (Width & 0x03)) - 1;
204 if (Address & AlignMask) {
205 return EFI_INVALID_PARAMETER;
206 }
207
208 In.Buffer = (VOID *)(UINTN) Address;
209 Out.Buffer = Buffer;
210
211 switch (Width) {
212 case EfiPciWidthUint8:
213 case EfiPciWidthUint16:
214 case EfiPciWidthUint32:
215 case EfiPciWidthUint64:
216 return PciRootBridgeIoMemRW (Width, Count, TRUE, In, TRUE, Out);
217
218 case EfiPciWidthFifoUint8:
219 case EfiPciWidthFifoUint16:
220 case EfiPciWidthFifoUint32:
221 case EfiPciWidthFifoUint64:
222 return PciRootBridgeIoMemRW (Width, Count, FALSE, In, TRUE, Out);
223
224 case EfiPciWidthFillUint8:
225 case EfiPciWidthFillUint16:
226 case EfiPciWidthFillUint32:
227 case EfiPciWidthFillUint64:
228 return PciRootBridgeIoMemRW (Width, Count, TRUE, In, FALSE, Out);
229
230 default:
231 break;
232 }
233
234 return EFI_INVALID_PARAMETER;
235 }
236
237 /**
238 Enables a PCI driver to access PCI controller registers in the PCI root bridge memory space.
239
240 @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
241 @param Width Signifies the width of the memory operations.
242 @param Address The base address of the memory operations.
243 @param Count The number of memory operations to perform.
244 @param Buffer For read operations, the destination buffer to store the results. For write
245 operations, the source buffer to write data from.
246
247 @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.
248 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
249 @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
250
251 **/
252 EFI_STATUS
253 EFIAPI
254 PciRootBridgeIoPciRead (
255 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
256 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
257 IN UINT64 Address,
258 IN UINTN Count,
259 IN OUT VOID *Buffer
260 )
261 {
262 if (Buffer == NULL) {
263 return EFI_INVALID_PARAMETER;
264 }
265
266 return PciRootBridgeIoPciRW (This, FALSE, Width, Address, Count, Buffer);
267 }
268
269 /**
270 Enables a PCI driver to access PCI controller registers in the PCI root bridge memory space.
271
272 @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
273 @param Width Signifies the width of the memory operations.
274 @param Address The base address of the memory operations.
275 @param Count The number of memory operations to perform.
276 @param Buffer For read operations, the destination buffer to store the results. For write
277 operations, the source buffer to write data from.
278
279 @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.
280 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
281 @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
282
283 **/
284 EFI_STATUS
285 EFIAPI
286 PciRootBridgeIoPciWrite (
287 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
288 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
289 IN UINT64 Address,
290 IN UINTN Count,
291 IN OUT VOID *Buffer
292 )
293 {
294 if (Buffer == NULL) {
295 return EFI_INVALID_PARAMETER;
296 }
297
298 return PciRootBridgeIoPciRW (This, TRUE, Width, Address, Count, Buffer);
299 }