]> git.proxmox.com Git - mirror_edk2.git/blame - ArmVirtPkg/PciHostBridgeDxe/PciRootBridgeIo.c
SecurityPkg: Add TPM PTP support in TCG2 SMM.
[mirror_edk2.git] / ArmVirtPkg / PciHostBridgeDxe / PciRootBridgeIo.c
CommitLineData
9595e3cd
LE
1/** @file\r
2 PCI Root Bridge Io Protocol implementation\r
3\r
4Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.<BR>\r
5This program and the accompanying materials are\r
6licensed and made available under the terms and conditions of the BSD License\r
7which accompanies this distribution. The full text of the license may be found at\r
8http://opensource.org/licenses/bsd-license.php\r
9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
d1c561f9 13**/\r
9595e3cd
LE
14\r
15#include "PciHostBridge.h"\r
16\r
17typedef struct {\r
18 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR SpaceDesp[TypeMax];\r
19 EFI_ACPI_END_TAG_DESCRIPTOR EndDesp;\r
20} RESOURCE_CONFIGURATION;\r
21\r
22RESOURCE_CONFIGURATION Configuration = {\r
23 {{0x8A, 0x2B, 1, 0, 0, 0, 0, 0, 0, 0},\r
d1c561f9 24 {0x8A, 0x2B, 0, 0, 0, 32, 0, 0, 0, 0},\r
9595e3cd
LE
25 {0x8A, 0x2B, 0, 0, 6, 32, 0, 0, 0, 0},\r
26 {0x8A, 0x2B, 0, 0, 0, 64, 0, 0, 0, 0},\r
27 {0x8A, 0x2B, 0, 0, 6, 64, 0, 0, 0, 0},\r
28 {0x8A, 0x2B, 2, 0, 0, 0, 0, 0, 0, 0}},\r
29 {0x79, 0}\r
30};\r
31\r
32//\r
33// Protocol Member Function Prototypes\r
34//\r
35\r
36/**\r
d1c561f9
OM
37 Polls an address in memory mapped I/O space until an exit condition is met, or\r
38 a timeout occurs.\r
9595e3cd
LE
39\r
40 This function provides a standard way to poll a PCI memory location. A PCI memory read\r
41 operation is performed at the PCI memory address specified by Address for the width specified\r
42 by Width. The result of this PCI memory read operation is stored in Result. This PCI memory\r
43 read operation is repeated until either a timeout of Delay 100 ns units has expired, or (Result &\r
44 Mask) is equal to Value.\r
45\r
46 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
47 @param[in] Width Signifies the width of the memory operations.\r
48 @param[in] Address The base address of the memory operations. The caller is\r
49 responsible for aligning Address if required.\r
50 @param[in] Mask Mask used for the polling criteria. Bytes above Width in Mask\r
51 are ignored. The bits in the bytes below Width which are zero in\r
52 Mask are ignored when polling the memory address.\r
53 @param[in] Value The comparison value used for the polling exit criteria.\r
54 @param[in] Delay The number of 100 ns units to poll. Note that timer available may\r
55 be of poorer granularity.\r
56 @param[out] Result Pointer to the last value read from the memory location.\r
d1c561f9 57\r
9595e3cd
LE
58 @retval EFI_SUCCESS The last data returned from the access matched the poll exit criteria.\r
59 @retval EFI_INVALID_PARAMETER Width is invalid.\r
60 @retval EFI_INVALID_PARAMETER Result is NULL.\r
61 @retval EFI_TIMEOUT Delay expired before a match occurred.\r
62 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
63\r
64**/\r
65EFI_STATUS\r
66EFIAPI\r
d1c561f9 67RootBridgeIoPollMem (\r
9595e3cd
LE
68 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
69 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
70 IN UINT64 Address,\r
71 IN UINT64 Mask,\r
72 IN UINT64 Value,\r
73 IN UINT64 Delay,\r
74 OUT UINT64 *Result\r
75 );\r
d1c561f9 76\r
9595e3cd
LE
77/**\r
78 Reads from the I/O space of a PCI Root Bridge. Returns when either the polling exit criteria is\r
79 satisfied or after a defined duration.\r
80\r
81 This function provides a standard way to poll a PCI I/O location. A PCI I/O read operation is\r
82 performed at the PCI I/O address specified by Address for the width specified by Width.\r
83 The result of this PCI I/O read operation is stored in Result. This PCI I/O read operation is\r
84 repeated until either a timeout of Delay 100 ns units has expired, or (Result & Mask) is equal\r
85 to Value.\r
86\r
87 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
88 @param[in] Width Signifies the width of the I/O operations.\r
89 @param[in] Address The base address of the I/O operations. The caller is responsible\r
90 for aligning Address if required.\r
91 @param[in] Mask Mask used for the polling criteria. Bytes above Width in Mask\r
92 are ignored. The bits in the bytes below Width which are zero in\r
93 Mask are ignored when polling the I/O address.\r
94 @param[in] Value The comparison value used for the polling exit criteria.\r
95 @param[in] Delay The number of 100 ns units to poll. Note that timer available may\r
96 be of poorer granularity.\r
97 @param[out] Result Pointer to the last value read from the memory location.\r
d1c561f9 98\r
9595e3cd
LE
99 @retval EFI_SUCCESS The last data returned from the access matched the poll exit criteria.\r
100 @retval EFI_INVALID_PARAMETER Width is invalid.\r
101 @retval EFI_INVALID_PARAMETER Result is NULL.\r
102 @retval EFI_TIMEOUT Delay expired before a match occurred.\r
103 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
104\r
105**/\r
106EFI_STATUS\r
107EFIAPI\r
d1c561f9 108RootBridgeIoPollIo (\r
9595e3cd
LE
109 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
110 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
111 IN UINT64 Address,\r
112 IN UINT64 Mask,\r
113 IN UINT64 Value,\r
114 IN UINT64 Delay,\r
115 OUT UINT64 *Result\r
116 );\r
d1c561f9 117\r
9595e3cd
LE
118/**\r
119 Enables a PCI driver to access PCI controller registers in the PCI root bridge memory space.\r
120\r
121 The Mem.Read(), and Mem.Write() functions enable a driver to access PCI controller\r
122 registers in the PCI root bridge memory space.\r
123 The memory operations are carried out exactly as requested. The caller is responsible for satisfying\r
124 any alignment and memory width restrictions that a PCI Root Bridge on a platform might require.\r
125\r
126 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
127 @param[in] Width Signifies the width of the memory operation.\r
128 @param[in] Address The base address of the memory operation. The caller is\r
129 responsible for aligning the Address if required.\r
130 @param[in] Count The number of memory operations to perform. Bytes moved is\r
131 Width size * Count, starting at Address.\r
132 @param[out] Buffer For read operations, the destination buffer to store the results. For\r
133 write operations, the source buffer to write data from.\r
d1c561f9 134\r
9595e3cd
LE
135 @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.\r
136 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.\r
137 @retval EFI_INVALID_PARAMETER Buffer is NULL.\r
138 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
139\r
140**/\r
141EFI_STATUS\r
142EFIAPI\r
143RootBridgeIoMemRead (\r
144 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
145 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
146 IN UINT64 Address,\r
147 IN UINTN Count,\r
148 OUT VOID *Buffer\r
149 );\r
150\r
151/**\r
152 Enables a PCI driver to access PCI controller registers in the PCI root bridge memory space.\r
153\r
154 The Mem.Read(), and Mem.Write() functions enable a driver to access PCI controller\r
155 registers in the PCI root bridge memory space.\r
156 The memory operations are carried out exactly as requested. The caller is responsible for satisfying\r
157 any alignment and memory width restrictions that a PCI Root Bridge on a platform might require.\r
158\r
159 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
160 @param[in] Width Signifies the width of the memory operation.\r
161 @param[in] Address The base address of the memory operation. The caller is\r
162 responsible for aligning the Address if required.\r
163 @param[in] Count The number of memory operations to perform. Bytes moved is\r
164 Width size * Count, starting at Address.\r
165 @param[in] Buffer For read operations, the destination buffer to store the results. For\r
166 write operations, the source buffer to write data from.\r
d1c561f9 167\r
9595e3cd
LE
168 @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.\r
169 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.\r
170 @retval EFI_INVALID_PARAMETER Buffer is NULL.\r
171 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
172**/\r
173EFI_STATUS\r
174EFIAPI\r
175RootBridgeIoMemWrite (\r
176 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
177 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
178 IN UINT64 Address,\r
179 IN UINTN Count,\r
180 IN VOID *Buffer\r
181 );\r
182\r
183/**\r
184 Enables a PCI driver to access PCI controller registers in the PCI root bridge I/O space.\r
185\r
186 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
187 @param[in] Width Signifies the width of the memory operations.\r
188 @param[in] UserAddress The base address of the I/O operation. The caller is responsible for\r
189 aligning the Address if required.\r
190 @param[in] Count The number of I/O operations to perform. Bytes moved is Width\r
191 size * Count, starting at Address.\r
192 @param[out] UserBuffer For read operations, the destination buffer to store the results. For\r
193 write operations, the source buffer to write data from.\r
d1c561f9 194\r
9595e3cd
LE
195 @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.\r
196 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.\r
197 @retval EFI_INVALID_PARAMETER Buffer is NULL.\r
198 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
199\r
200**/\r
201EFI_STATUS\r
202EFIAPI\r
203RootBridgeIoIoRead (\r
204 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
205 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
206 IN UINT64 UserAddress,\r
207 IN UINTN Count,\r
208 OUT VOID *UserBuffer\r
209 );\r
210\r
211/**\r
212 Enables a PCI driver to access PCI controller registers in the PCI root bridge I/O space.\r
213\r
214 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
215 @param[in] Width Signifies the width of the memory operations.\r
216 @param[in] UserAddress The base address of the I/O operation. The caller is responsible for\r
217 aligning the Address if required.\r
218 @param[in] Count The number of I/O operations to perform. Bytes moved is Width\r
219 size * Count, starting at Address.\r
220 @param[in] UserBuffer For read operations, the destination buffer to store the results. For\r
221 write operations, the source buffer to write data from.\r
d1c561f9 222\r
9595e3cd
LE
223 @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.\r
224 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.\r
225 @retval EFI_INVALID_PARAMETER Buffer is NULL.\r
226 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
227\r
228**/\r
229EFI_STATUS\r
230EFIAPI\r
231RootBridgeIoIoWrite (\r
232 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
233 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
234 IN UINT64 UserAddress,\r
235 IN UINTN Count,\r
236 IN VOID *UserBuffer\r
237 );\r
238\r
239/**\r
240 Enables a PCI driver to copy one region of PCI root bridge memory space to another region of PCI\r
241 root bridge memory space.\r
242\r
243 The CopyMem() function enables a PCI driver to copy one region of PCI root bridge memory\r
244 space to another region of PCI root bridge memory space. This is especially useful for video scroll\r
245 operation on a memory mapped video buffer.\r
246 The memory operations are carried out exactly as requested. The caller is responsible for satisfying\r
247 any alignment and memory width restrictions that a PCI root bridge on a platform might require.\r
248\r
249 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance.\r
250 @param[in] Width Signifies the width of the memory operations.\r
251 @param[in] DestAddress The destination address of the memory operation. The caller is\r
252 responsible for aligning the DestAddress if required.\r
253 @param[in] SrcAddress The source address of the memory operation. The caller is\r
254 responsible for aligning the SrcAddress if required.\r
255 @param[in] Count The number of memory operations to perform. Bytes moved is\r
256 Width size * Count, starting at DestAddress and SrcAddress.\r
d1c561f9 257\r
9595e3cd
LE
258 @retval EFI_SUCCESS The data was copied from one memory region to another memory region.\r
259 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.\r
260 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
261\r
262**/\r
263EFI_STATUS\r
264EFIAPI\r
265RootBridgeIoCopyMem (\r
266 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
267 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
268 IN UINT64 DestAddress,\r
269 IN UINT64 SrcAddress,\r
270 IN UINTN Count\r
271 );\r
272\r
273/**\r
274 Enables a PCI driver to access PCI controller registers in a PCI root bridge's configuration space.\r
275\r
276 The Pci.Read() and Pci.Write() functions enable a driver to access PCI configuration\r
277 registers for a PCI controller.\r
278 The PCI Configuration operations are carried out exactly as requested. The caller is responsible for\r
279 any alignment and PCI configuration width issues that a PCI Root Bridge on a platform might\r
280 require.\r
281\r
282 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
283 @param[in] Width Signifies the width of the memory operations.\r
284 @param[in] Address The address within the PCI configuration space for the PCI controller.\r
285 @param[in] Count The number of PCI configuration operations to perform. Bytes\r
286 moved is Width size * Count, starting at Address.\r
287 @param[out] Buffer For read operations, the destination buffer to store the results. For\r
288 write operations, the source buffer to write data from.\r
d1c561f9 289\r
9595e3cd
LE
290 @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.\r
291 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.\r
292 @retval EFI_INVALID_PARAMETER Buffer is NULL.\r
293 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
294\r
295**/\r
296EFI_STATUS\r
297EFIAPI\r
298RootBridgeIoPciRead (\r
299 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
300 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
301 IN UINT64 Address,\r
302 IN UINTN Count,\r
303 OUT VOID *Buffer\r
304 );\r
305\r
306/**\r
307 Enables a PCI driver to access PCI controller registers in a PCI root bridge's configuration space.\r
308\r
309 The Pci.Read() and Pci.Write() functions enable a driver to access PCI configuration\r
310 registers for a PCI controller.\r
311 The PCI Configuration operations are carried out exactly as requested. The caller is responsible for\r
312 any alignment and PCI configuration width issues that a PCI Root Bridge on a platform might\r
313 require.\r
314\r
315 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
316 @param[in] Width Signifies the width of the memory operations.\r
317 @param[in] Address The address within the PCI configuration space for the PCI controller.\r
318 @param[in] Count The number of PCI configuration operations to perform. Bytes\r
319 moved is Width size * Count, starting at Address.\r
320 @param[in] Buffer For read operations, the destination buffer to store the results. For\r
321 write operations, the source buffer to write data from.\r
d1c561f9 322\r
9595e3cd
LE
323 @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.\r
324 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.\r
325 @retval EFI_INVALID_PARAMETER Buffer is NULL.\r
326 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
327\r
328**/\r
329EFI_STATUS\r
330EFIAPI\r
331RootBridgeIoPciWrite (\r
332 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
333 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
334 IN UINT64 Address,\r
335 IN UINTN Count,\r
336 IN VOID *Buffer\r
337 );\r
338\r
339/**\r
340 Provides the PCI controller-specific addresses required to access system memory from a\r
341 DMA bus master.\r
342\r
343 The Map() function provides the PCI controller specific addresses needed to access system\r
344 memory. This function is used to map system memory for PCI bus master DMA accesses.\r
345\r
346 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
347 @param[in] Operation Indicates if the bus master is going to read or write to system memory.\r
348 @param[in] HostAddress The system memory address to map to the PCI controller.\r
349 @param[in, out] NumberOfBytes On input the number of bytes to map. On output the number of bytes that were mapped.\r
350 @param[out] DeviceAddress The resulting map address for the bus master PCI controller to use\r
351 to access the system memory's HostAddress.\r
352 @param[out] Mapping The value to pass to Unmap() when the bus master DMA operation is complete.\r
d1c561f9 353\r
9595e3cd
LE
354 @retval EFI_SUCCESS The range was mapped for the returned NumberOfBytes.\r
355 @retval EFI_INVALID_PARAMETER Operation is invalid.\r
356 @retval EFI_INVALID_PARAMETER HostAddress is NULL.\r
357 @retval EFI_INVALID_PARAMETER NumberOfBytes is NULL.\r
358 @retval EFI_INVALID_PARAMETER DeviceAddress is NULL.\r
359 @retval EFI_INVALID_PARAMETER Mapping is NULL.\r
360 @retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a common buffer.\r
361 @retval EFI_DEVICE_ERROR The system hardware could not map the requested address.\r
362 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
363\r
364**/\r
365EFI_STATUS\r
366EFIAPI\r
367RootBridgeIoMap (\r
368 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
369 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION Operation,\r
370 IN VOID *HostAddress,\r
371 IN OUT UINTN *NumberOfBytes,\r
372 OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,\r
373 OUT VOID **Mapping\r
374 );\r
375\r
376/**\r
377 Completes the Map() operation and releases any corresponding resources.\r
378\r
379 The Unmap() function completes the Map() operation and releases any corresponding resources.\r
380 If the operation was an EfiPciOperationBusMasterWrite or\r
381 EfiPciOperationBusMasterWrite64, the data is committed to the target system memory.\r
d1c561f9 382 Any resources used for the mapping are freed.\r
9595e3cd
LE
383\r
384 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
385 @param[in] Mapping The mapping value returned from Map().\r
d1c561f9 386\r
9595e3cd
LE
387 @retval EFI_SUCCESS The range was unmapped.\r
388 @retval EFI_INVALID_PARAMETER Mapping is not a value that was returned by Map().\r
389 @retval EFI_DEVICE_ERROR The data was not committed to the target system memory.\r
390\r
391**/\r
392EFI_STATUS\r
393EFIAPI\r
394RootBridgeIoUnmap (\r
395 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
396 IN VOID *Mapping\r
397 );\r
398\r
399/**\r
400 Allocates pages that are suitable for an EfiPciOperationBusMasterCommonBuffer or\r
401 EfiPciOperationBusMasterCommonBuffer64 mapping.\r
d1c561f9 402\r
9595e3cd
LE
403 @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
404 @param Type This parameter is not used and must be ignored.\r
405 @param MemoryType The type of memory to allocate, EfiBootServicesData or EfiRuntimeServicesData.\r
406 @param Pages The number of pages to allocate.\r
407 @param HostAddress A pointer to store the base system memory address of the allocated range.\r
408 @param Attributes The requested bit mask of attributes for the allocated range. Only\r
d1c561f9 409 the attributes EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE, EFI_PCI_ATTRIBUTE_MEMORY_CACHED,\r
9595e3cd 410 and EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE may be used with this function.\r
d1c561f9 411\r
9595e3cd
LE
412 @retval EFI_SUCCESS The requested memory pages were allocated.\r
413 @retval EFI_INVALID_PARAMETER MemoryType is invalid.\r
414 @retval EFI_INVALID_PARAMETER HostAddress is NULL.\r
415 @retval EFI_UNSUPPORTED Attributes is unsupported. The only legal attribute bits are\r
416 MEMORY_WRITE_COMBINE, MEMORY_CACHED, and DUAL_ADDRESS_CYCLE.\r
417 @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated.\r
418\r
419**/\r
420EFI_STATUS\r
421EFIAPI\r
422RootBridgeIoAllocateBuffer (\r
423 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
424 IN EFI_ALLOCATE_TYPE Type,\r
425 IN EFI_MEMORY_TYPE MemoryType,\r
426 IN UINTN Pages,\r
427 OUT VOID **HostAddress,\r
428 IN UINT64 Attributes\r
429 );\r
430\r
431/**\r
432 Frees memory that was allocated with AllocateBuffer().\r
433\r
434 The FreeBuffer() function frees memory that was allocated with AllocateBuffer().\r
435\r
436 @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
437 @param Pages The number of pages to free.\r
438 @param HostAddress The base system memory address of the allocated range.\r
d1c561f9 439\r
9595e3cd
LE
440 @retval EFI_SUCCESS The requested memory pages were freed.\r
441 @retval EFI_INVALID_PARAMETER The memory range specified by HostAddress and Pages\r
442 was not allocated with AllocateBuffer().\r
443\r
444**/\r
445EFI_STATUS\r
446EFIAPI\r
447RootBridgeIoFreeBuffer (\r
448 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
449 IN UINTN Pages,\r
450 OUT VOID *HostAddress\r
451 );\r
452\r
453/**\r
454 Flushes all PCI posted write transactions from a PCI host bridge to system memory.\r
455\r
456 The Flush() function flushes any PCI posted write transactions from a PCI host bridge to system\r
457 memory. Posted write transactions are generated by PCI bus masters when they perform write\r
458 transactions to target addresses in system memory.\r
459 This function does not flush posted write transactions from any PCI bridges. A PCI controller\r
460 specific action must be taken to guarantee that the posted write transactions have been flushed from\r
461 the PCI controller and from all the PCI bridges into the PCI host bridge. This is typically done with\r
462 a PCI read transaction from the PCI controller prior to calling Flush().\r
463\r
464 @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
d1c561f9 465\r
9595e3cd
LE
466 @retval EFI_SUCCESS The PCI posted write transactions were flushed from the PCI host\r
467 bridge to system memory.\r
468 @retval EFI_DEVICE_ERROR The PCI posted write transactions were not flushed from the PCI\r
469 host bridge due to a hardware error.\r
470\r
471**/\r
472EFI_STATUS\r
473EFIAPI\r
474RootBridgeIoFlush (\r
475 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This\r
476 );\r
477\r
478/**\r
479 Gets the attributes that a PCI root bridge supports setting with SetAttributes(), and the\r
d1c561f9 480 attributes that a PCI root bridge is currently using.\r
9595e3cd
LE
481\r
482 The GetAttributes() function returns the mask of attributes that this PCI root bridge supports\r
483 and the mask of attributes that the PCI root bridge is currently using.\r
484\r
485 @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
486 @param Supported A pointer to the mask of attributes that this PCI root bridge\r
487 supports setting with SetAttributes().\r
488 @param Attributes A pointer to the mask of attributes that this PCI root bridge is\r
489 currently using.\r
d1c561f9 490\r
9595e3cd
LE
491 @retval EFI_SUCCESS If Supports is not NULL, then the attributes that the PCI root\r
492 bridge supports is returned in Supports. If Attributes is\r
493 not NULL, then the attributes that the PCI root bridge is currently\r
494 using is returned in Attributes.\r
495 @retval EFI_INVALID_PARAMETER Both Supports and Attributes are NULL.\r
496\r
497**/\r
498EFI_STATUS\r
499EFIAPI\r
500RootBridgeIoGetAttributes (\r
501 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
502 OUT UINT64 *Supported,\r
503 OUT UINT64 *Attributes\r
504 );\r
505\r
506/**\r
507 Sets attributes for a resource range on a PCI root bridge.\r
508\r
509 The SetAttributes() function sets the attributes specified in Attributes for the PCI root\r
510 bridge on the resource range specified by ResourceBase and ResourceLength. Since the\r
511 granularity of setting these attributes may vary from resource type to resource type, and from\r
512 platform to platform, the actual resource range and the one passed in by the caller may differ. As a\r
513 result, this function may set the attributes specified by Attributes on a larger resource range\r
514 than the caller requested. The actual range is returned in ResourceBase and\r
515 ResourceLength. The caller is responsible for verifying that the actual range for which the\r
516 attributes were set is acceptable.\r
517\r
518 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
519 @param[in] Attributes The mask of attributes to set. If the attribute bit\r
520 MEMORY_WRITE_COMBINE, MEMORY_CACHED, or\r
521 MEMORY_DISABLE is set, then the resource range is specified by\r
522 ResourceBase and ResourceLength. If\r
523 MEMORY_WRITE_COMBINE, MEMORY_CACHED, and\r
524 MEMORY_DISABLE are not set, then ResourceBase and\r
525 ResourceLength are ignored, and may be NULL.\r
526 @param[in, out] ResourceBase A pointer to the base address of the resource range to be modified\r
527 by the attributes specified by Attributes.\r
528 @param[in, out] ResourceLength A pointer to the length of the resource range to be modified by the\r
529 attributes specified by Attributes.\r
d1c561f9 530\r
9595e3cd
LE
531 @retval EFI_SUCCESS The current configuration of this PCI root bridge was returned in Resources.\r
532 @retval EFI_UNSUPPORTED The current configuration of this PCI root bridge could not be retrieved.\r
533 @retval EFI_INVALID_PARAMETER Invalid pointer of EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL\r
534\r
535**/\r
536EFI_STATUS\r
537EFIAPI\r
538RootBridgeIoSetAttributes (\r
539 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
540 IN UINT64 Attributes,\r
541 IN OUT UINT64 *ResourceBase,\r
d1c561f9
OM
542 IN OUT UINT64 *ResourceLength\r
543 );\r
9595e3cd
LE
544\r
545/**\r
546 Retrieves the current resource settings of this PCI root bridge in the form of a set of ACPI 2.0\r
547 resource descriptors.\r
548\r
549 There are only two resource descriptor types from the ACPI Specification that may be used to\r
550 describe the current resources allocated to a PCI root bridge. These are the QWORD Address\r
551 Space Descriptor (ACPI 2.0 Section 6.4.3.5.1), and the End Tag (ACPI 2.0 Section 6.4.2.8). The\r
552 QWORD Address Space Descriptor can describe memory, I/O, and bus number ranges for dynamic\r
553 or fixed resources. The configuration of a PCI root bridge is described with one or more QWORD\r
554 Address Space Descriptors followed by an End Tag.\r
555\r
556 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
557 @param[out] Resources A pointer to the ACPI 2.0 resource descriptors that describe the\r
558 current configuration of this PCI root bridge. The storage for the\r
559 ACPI 2.0 resource descriptors is allocated by this function. The\r
560 caller must treat the return buffer as read-only data, and the buffer\r
561 must not be freed by the caller.\r
d1c561f9 562\r
9595e3cd
LE
563 @retval EFI_SUCCESS The current configuration of this PCI root bridge was returned in Resources.\r
564 @retval EFI_UNSUPPORTED The current configuration of this PCI root bridge could not be retrieved.\r
565 @retval EFI_INVALID_PARAMETER Invalid pointer of EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL\r
566\r
567**/\r
568EFI_STATUS\r
569EFIAPI\r
570RootBridgeIoConfiguration (\r
571 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
572 OUT VOID **Resources\r
573 );\r
574\r
575//\r
576// Memory Controller Pci Root Bridge Io Module Variables\r
577//\r
578EFI_METRONOME_ARCH_PROTOCOL *mMetronome;\r
579\r
580//\r
581// Lookup table for increment values based on transfer widths\r
582//\r
583UINT8 mInStride[] = {\r
584 1, // EfiPciWidthUint8\r
585 2, // EfiPciWidthUint16\r
586 4, // EfiPciWidthUint32\r
587 8, // EfiPciWidthUint64\r
588 0, // EfiPciWidthFifoUint8\r
589 0, // EfiPciWidthFifoUint16\r
590 0, // EfiPciWidthFifoUint32\r
591 0, // EfiPciWidthFifoUint64\r
592 1, // EfiPciWidthFillUint8\r
593 2, // EfiPciWidthFillUint16\r
594 4, // EfiPciWidthFillUint32\r
595 8 // EfiPciWidthFillUint64\r
596};\r
597\r
598//\r
599// Lookup table for increment values based on transfer widths\r
600//\r
601UINT8 mOutStride[] = {\r
602 1, // EfiPciWidthUint8\r
603 2, // EfiPciWidthUint16\r
604 4, // EfiPciWidthUint32\r
605 8, // EfiPciWidthUint64\r
606 1, // EfiPciWidthFifoUint8\r
607 2, // EfiPciWidthFifoUint16\r
608 4, // EfiPciWidthFifoUint32\r
609 8, // EfiPciWidthFifoUint64\r
610 0, // EfiPciWidthFillUint8\r
611 0, // EfiPciWidthFillUint16\r
612 0, // EfiPciWidthFillUint32\r
613 0 // EfiPciWidthFillUint64\r
614};\r
615\r
616/**\r
617\r
618 Construct the Pci Root Bridge Io protocol\r
619\r
620 @param Protocol Point to protocol instance\r
621 @param HostBridgeHandle Handle of host bridge\r
622 @param Attri Attribute of host bridge\r
623 @param ResAperture ResourceAperture for host bridge\r
624\r
625 @retval EFI_SUCCESS Success to initialize the Pci Root Bridge.\r
626\r
627**/\r
628EFI_STATUS\r
629RootBridgeConstructor (\r
630 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *Protocol,\r
631 IN EFI_HANDLE HostBridgeHandle,\r
632 IN UINT64 Attri,\r
633 IN PCI_ROOT_BRIDGE_RESOURCE_APERTURE *ResAperture\r
634 )\r
635{\r
636 EFI_STATUS Status;\r
637 PCI_ROOT_BRIDGE_INSTANCE *PrivateData;\r
638 PCI_RESOURCE_TYPE Index;\r
639\r
640 PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (Protocol);\r
641\r
642 //\r
1275aaf4
LE
643 // The host to PCI bridge. The host memory addresses are direct mapped to PCI\r
644 // addresses, so there's no need to translate them. IO addresses need\r
645 // translation however.\r
9595e3cd 646 //\r
1275aaf4
LE
647 PrivateData->MemBase = ResAperture->MemBase;\r
648 PrivateData->IoBase = ResAperture->IoBase;\r
649 PrivateData->IoTranslation = ResAperture->IoTranslation;\r
9595e3cd
LE
650\r
651 //\r
652 // The host bridge only supports 32bit addressing for memory\r
653 // and standard IA32 16bit io\r
654 //\r
655 PrivateData->MemLimit = ResAperture->MemLimit;\r
656 PrivateData->IoLimit = ResAperture->IoLimit;\r
657\r
658 //\r
659 // Bus Aperture for this Root Bridge (Possible Range)\r
660 //\r
661 PrivateData->BusBase = ResAperture->BusBase;\r
662 PrivateData->BusLimit = ResAperture->BusLimit;\r
d1c561f9 663\r
9595e3cd
LE
664 //\r
665 // Specific for this chipset\r
666 //\r
667 for (Index = TypeIo; Index < TypeMax; Index++) {\r
668 PrivateData->ResAllocNode[Index].Type = Index;\r
669 PrivateData->ResAllocNode[Index].Base = 0;\r
670 PrivateData->ResAllocNode[Index].Length = 0;\r
671 PrivateData->ResAllocNode[Index].Status = ResNone;\r
672 }\r
d1c561f9 673\r
9595e3cd 674 PrivateData->RootBridgeAttrib = Attri;\r
d1c561f9 675\r
9595e3cd
LE
676 PrivateData->Supports = EFI_PCI_ATTRIBUTE_IDE_PRIMARY_IO | EFI_PCI_ATTRIBUTE_IDE_SECONDARY_IO | \\r
677 EFI_PCI_ATTRIBUTE_ISA_IO_16 | EFI_PCI_ATTRIBUTE_ISA_MOTHERBOARD_IO | \\r
678 EFI_PCI_ATTRIBUTE_VGA_MEMORY | \\r
679 EFI_PCI_ATTRIBUTE_VGA_IO_16 | EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO_16;\r
680 PrivateData->Attributes = PrivateData->Supports;\r
681\r
682 Protocol->ParentHandle = HostBridgeHandle;\r
d1c561f9 683\r
9595e3cd
LE
684 Protocol->PollMem = RootBridgeIoPollMem;\r
685 Protocol->PollIo = RootBridgeIoPollIo;\r
686\r
687 Protocol->Mem.Read = RootBridgeIoMemRead;\r
688 Protocol->Mem.Write = RootBridgeIoMemWrite;\r
689\r
690 Protocol->Io.Read = RootBridgeIoIoRead;\r
691 Protocol->Io.Write = RootBridgeIoIoWrite;\r
692\r
693 Protocol->CopyMem = RootBridgeIoCopyMem;\r
694\r
695 Protocol->Pci.Read = RootBridgeIoPciRead;\r
696 Protocol->Pci.Write = RootBridgeIoPciWrite;\r
697\r
698 Protocol->Map = RootBridgeIoMap;\r
699 Protocol->Unmap = RootBridgeIoUnmap;\r
700\r
701 Protocol->AllocateBuffer = RootBridgeIoAllocateBuffer;\r
702 Protocol->FreeBuffer = RootBridgeIoFreeBuffer;\r
703\r
704 Protocol->Flush = RootBridgeIoFlush;\r
705\r
706 Protocol->GetAttributes = RootBridgeIoGetAttributes;\r
707 Protocol->SetAttributes = RootBridgeIoSetAttributes;\r
708\r
709 Protocol->Configuration = RootBridgeIoConfiguration;\r
710\r
711 Protocol->SegmentNumber = 0;\r
712\r
713 Status = gBS->LocateProtocol (&gEfiMetronomeArchProtocolGuid, NULL, (VOID **)&mMetronome);\r
714 ASSERT_EFI_ERROR (Status);\r
715\r
716 return EFI_SUCCESS;\r
717}\r
718\r
719/**\r
720 Check parameters for IO,MMIO,PCI read/write services of PCI Root Bridge IO.\r
721\r
d1c561f9
OM
722 The I/O operations are carried out exactly as requested. The caller is responsible\r
723 for satisfying any alignment and I/O width restrictions that a PI System on a\r
724 platform might require. For example on some platforms, width requests of\r
725 EfiCpuIoWidthUint64 do not work. Misaligned buffers, on the other hand, will\r
9595e3cd 726 be handled by the driver.\r
d1c561f9 727\r
9595e3cd
LE
728 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
729 @param[in] OperationType I/O operation type: IO/MMIO/PCI.\r
730 @param[in] Width Signifies the width of the I/O or Memory operation.\r
d1c561f9
OM
731 @param[in] Address The base address of the I/O operation.\r
732 @param[in] Count The number of I/O operations to perform. The number of\r
9595e3cd
LE
733 bytes moved is Width size * Count, starting at Address.\r
734 @param[in] Buffer For read operations, the destination buffer to store the results.\r
735 For write operations, the source buffer from which to write data.\r
736\r
737 @retval EFI_SUCCESS The parameters for this request pass the checks.\r
738 @retval EFI_INVALID_PARAMETER Width is invalid for this PI system.\r
739 @retval EFI_INVALID_PARAMETER Buffer is NULL.\r
740 @retval EFI_UNSUPPORTED The Buffer is not aligned for the given Width.\r
d1c561f9 741 @retval EFI_UNSUPPORTED The address range specified by Address, Width,\r
9595e3cd
LE
742 and Count is not valid for this PI system.\r
743\r
744**/\r
745EFI_STATUS\r
746RootBridgeIoCheckParameter (\r
747 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
748 IN OPERATION_TYPE OperationType,\r
749 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
750 IN UINT64 Address,\r
751 IN UINTN Count,\r
752 IN VOID *Buffer\r
753 )\r
754{\r
755 PCI_ROOT_BRIDGE_INSTANCE *PrivateData;\r
756 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *PciRbAddr;\r
286c88bc 757 UINT32 Stride;\r
9595e3cd
LE
758 UINT64 Base;\r
759 UINT64 Limit;\r
760\r
761 //\r
762 // Check to see if Buffer is NULL\r
763 //\r
764 if (Buffer == NULL) {\r
765 return EFI_INVALID_PARAMETER;\r
766 }\r
767\r
768 //\r
769 // Check to see if Width is in the valid range\r
770 //\r
771 if ((UINT32)Width >= EfiPciWidthMaximum) {\r
772 return EFI_INVALID_PARAMETER;\r
773 }\r
774\r
775 //\r
776 // For FIFO type, the target address won't increase during the access,\r
777 // so treat Count as 1\r
778 //\r
779 if (Width >= EfiPciWidthFifoUint8 && Width <= EfiPciWidthFifoUint64) {\r
780 Count = 1;\r
781 }\r
782\r
783 //\r
784 // Check to see if Width is in the valid range for I/O Port operations\r
785 //\r
786 Width = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (Width & 0x03);\r
787 if ((OperationType != MemOperation) && (Width == EfiPciWidthUint64)) {\r
788 ASSERT (FALSE);\r
789 return EFI_INVALID_PARAMETER;\r
790 }\r
791\r
792 //\r
793 // Check to see if Address is aligned\r
794 //\r
286c88bc
LE
795 Stride = mInStride[Width];\r
796 if ((Address & (UINT64)(Stride - 1)) != 0) {\r
9595e3cd
LE
797 return EFI_UNSUPPORTED;\r
798 }\r
799\r
800 PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);\r
801\r
802 //\r
d1c561f9 803 // Check to see if any address associated with this transfer exceeds the maximum\r
9595e3cd
LE
804 // allowed address. The maximum address implied by the parameters passed in is\r
805 // Address + Size * Count. If the following condition is met, then the transfer\r
806 // is not supported.\r
807 //\r
808 // Address + Size * Count > Limit + 1\r
809 //\r
d1c561f9 810 // Since Limit can be the maximum integer value supported by the CPU and Count\r
9595e3cd
LE
811 // can also be the maximum integer value supported by the CPU, this range\r
812 // check must be adjusted to avoid all oveflow conditions.\r
9595e3cd
LE
813 //\r
814 if (OperationType == IoOperation) {\r
815 Base = PrivateData->IoBase;\r
816 Limit = PrivateData->IoLimit;\r
817 } else if (OperationType == MemOperation) {\r
818 Base = PrivateData->MemBase;\r
819 Limit = PrivateData->MemLimit;\r
820 } else {\r
821 PciRbAddr = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS*) &Address;\r
822 if (PciRbAddr->Bus < PrivateData->BusBase || PciRbAddr->Bus > PrivateData->BusLimit) {\r
823 return EFI_INVALID_PARAMETER;\r
824 }\r
825\r
826 if (PciRbAddr->Device > MAX_PCI_DEVICE_NUMBER || PciRbAddr->Function > MAX_PCI_FUNCTION_NUMBER) {\r
827 return EFI_INVALID_PARAMETER;\r
828 }\r
829\r
830 if (PciRbAddr->ExtendedRegister != 0) {\r
831 Address = PciRbAddr->ExtendedRegister;\r
832 } else {\r
833 Address = PciRbAddr->Register;\r
834 }\r
835 Base = 0;\r
836 Limit = MAX_PCI_REG_ADDRESS;\r
837 }\r
838\r
286c88bc
LE
839 if (Limit < Address) {\r
840 return EFI_INVALID_PARAMETER;\r
841 }\r
842\r
9595e3cd
LE
843 if (Address < Base) {\r
844 return EFI_INVALID_PARAMETER;\r
845 }\r
846\r
286c88bc
LE
847 //\r
848 // Base <= Address <= Limit\r
849 //\r
850 if (Address == 0 && Limit == MAX_UINT64) {\r
851 //\r
852 // 2^64 bytes are valid to transfer. With Stride == 1, that's simply\r
853 // impossible to reach in Count; with Stride in {2, 4, 8}, we can divide\r
854 // both 2^64 and Stride with 2.\r
855 //\r
856 if (Stride > 1 && Count > DivU64x32 (BIT63, Stride / 2)) {\r
9595e3cd
LE
857 return EFI_UNSUPPORTED;\r
858 }\r
286c88bc
LE
859 } else {\r
860 //\r
861 // (Limit - Address) does not wrap, and it is smaller than MAX_UINT64.\r
862 //\r
863 if (Count > DivU64x32 (Limit - Address + 1, Stride)) {\r
9595e3cd
LE
864 return EFI_UNSUPPORTED;\r
865 }\r
866 }\r
867\r
868 return EFI_SUCCESS;\r
869}\r
870\r
871/**\r
872 Internal help function for read and write memory space.\r
873\r
874 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
875 @param[in] Write Switch value for Read or Write.\r
876 @param[in] Width Signifies the width of the memory operations.\r
877 @param[in] UserAddress The address within the PCI configuration space for the PCI controller.\r
878 @param[in] Count The number of PCI configuration operations to perform. Bytes\r
879 moved is Width size * Count, starting at Address.\r
880 @param[in, out] UserBuffer For read operations, the destination buffer to store the results. For\r
881 write operations, the source buffer to write data from.\r
d1c561f9 882\r
9595e3cd
LE
883 @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.\r
884 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.\r
885 @retval EFI_INVALID_PARAMETER Buffer is NULL.\r
886 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
887\r
888**/\r
889EFI_STATUS\r
890RootBridgeIoMemRW (\r
891 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
892 IN BOOLEAN Write,\r
893 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
894 IN UINT64 Address,\r
895 IN UINTN Count,\r
896 IN OUT VOID *Buffer\r
897 )\r
898{\r
899 EFI_STATUS Status;\r
900 UINT8 InStride;\r
901 UINT8 OutStride;\r
902 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH OperationWidth;\r
903 UINT8 *Uint8Buffer;\r
904\r
905 Status = RootBridgeIoCheckParameter (This, MemOperation, Width, Address, Count, Buffer);\r
906 if (EFI_ERROR (Status)) {\r
907 return Status;\r
908 }\r
909\r
910 InStride = mInStride[Width];\r
911 OutStride = mOutStride[Width];\r
912 OperationWidth = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (Width & 0x03);\r
913 for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {\r
914 if (Write) {\r
915 switch (OperationWidth) {\r
916 case EfiPciWidthUint8:\r
917 MmioWrite8 ((UINTN)Address, *Uint8Buffer);\r
918 break;\r
919 case EfiPciWidthUint16:\r
920 MmioWrite16 ((UINTN)Address, *((UINT16 *)Uint8Buffer));\r
921 break;\r
922 case EfiPciWidthUint32:\r
923 MmioWrite32 ((UINTN)Address, *((UINT32 *)Uint8Buffer));\r
924 break;\r
925 case EfiPciWidthUint64:\r
926 MmioWrite64 ((UINTN)Address, *((UINT64 *)Uint8Buffer));\r
927 break;\r
928 default:\r
929 //\r
930 // The RootBridgeIoCheckParameter call above will ensure that this\r
931 // path is not taken.\r
932 //\r
933 ASSERT (FALSE);\r
934 break;\r
935 }\r
936 } else {\r
937 switch (OperationWidth) {\r
938 case EfiPciWidthUint8:\r
939 *Uint8Buffer = MmioRead8 ((UINTN)Address);\r
940 break;\r
941 case EfiPciWidthUint16:\r
942 *((UINT16 *)Uint8Buffer) = MmioRead16 ((UINTN)Address);\r
943 break;\r
944 case EfiPciWidthUint32:\r
945 *((UINT32 *)Uint8Buffer) = MmioRead32 ((UINTN)Address);\r
946 break;\r
947 case EfiPciWidthUint64:\r
948 *((UINT64 *)Uint8Buffer) = MmioRead64 ((UINTN)Address);\r
949 break;\r
950 default:\r
951 //\r
952 // The RootBridgeIoCheckParameter call above will ensure that this\r
953 // path is not taken.\r
954 //\r
955 ASSERT (FALSE);\r
956 break;\r
957 }\r
958 }\r
959 }\r
d1c561f9 960 return EFI_SUCCESS;\r
9595e3cd
LE
961}\r
962\r
963/**\r
964 Internal help function for read and write IO space.\r
965\r
966 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
967 @param[in] Write Switch value for Read or Write.\r
968 @param[in] Width Signifies the width of the memory operations.\r
969 @param[in] UserAddress The address within the PCI configuration space for the PCI controller.\r
970 @param[in] Count The number of PCI configuration operations to perform. Bytes\r
971 moved is Width size * Count, starting at Address.\r
972 @param[in, out] UserBuffer For read operations, the destination buffer to store the results. For\r
973 write operations, the source buffer to write data from.\r
d1c561f9 974\r
9595e3cd
LE
975 @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.\r
976 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.\r
977 @retval EFI_INVALID_PARAMETER Buffer is NULL.\r
978 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
979\r
980**/\r
981EFI_STATUS\r
982RootBridgeIoIoRW (\r
983 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
984 IN BOOLEAN Write,\r
985 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
986 IN UINT64 Address,\r
987 IN UINTN Count,\r
988 IN OUT VOID *Buffer\r
989 )\r
990{\r
991 EFI_STATUS Status;\r
1275aaf4 992 PCI_ROOT_BRIDGE_INSTANCE *PrivateData;\r
9595e3cd
LE
993 UINT8 InStride;\r
994 UINT8 OutStride;\r
995 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH OperationWidth;\r
996 UINT8 *Uint8Buffer;\r
997\r
998 Status = RootBridgeIoCheckParameter (This, IoOperation, Width, Address, Count, Buffer);\r
999 if (EFI_ERROR (Status)) {\r
1000 return Status;\r
1001 }\r
1002\r
1275aaf4
LE
1003 PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);\r
1004 //\r
1005 // The addition below is performed in UINT64 modular arithmetic, in\r
1006 // accordance with the definition of PcdPciIoTranslation in\r
1007 // "ArmPlatformPkg.dec". Meaning, the addition below may in fact *decrease*\r
1008 // Address, implementing a negative offset translation.\r
1009 //\r
1010 Address += PrivateData->IoTranslation;\r
1011\r
9595e3cd
LE
1012 InStride = mInStride[Width];\r
1013 OutStride = mOutStride[Width];\r
1014 OperationWidth = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (Width & 0x03);\r
1015\r
1016 for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {\r
1017 if (Write) {\r
1018 switch (OperationWidth) {\r
1019 case EfiPciWidthUint8:\r
1cfa1957 1020 MmioWrite8 ((UINTN)Address, *Uint8Buffer);\r
9595e3cd
LE
1021 break;\r
1022 case EfiPciWidthUint16:\r
1cfa1957 1023 MmioWrite16 ((UINTN)Address, *((UINT16 *)Uint8Buffer));\r
9595e3cd
LE
1024 break;\r
1025 case EfiPciWidthUint32:\r
1cfa1957 1026 MmioWrite32 ((UINTN)Address, *((UINT32 *)Uint8Buffer));\r
9595e3cd
LE
1027 break;\r
1028 default:\r
1029 //\r
1030 // The RootBridgeIoCheckParameter call above will ensure that this\r
1031 // path is not taken.\r
1032 //\r
1033 ASSERT (FALSE);\r
1034 break;\r
1035 }\r
1036 } else {\r
1037 switch (OperationWidth) {\r
1038 case EfiPciWidthUint8:\r
1cfa1957 1039 *Uint8Buffer = MmioRead8 ((UINTN)Address);\r
9595e3cd
LE
1040 break;\r
1041 case EfiPciWidthUint16:\r
1cfa1957 1042 *((UINT16 *)Uint8Buffer) = MmioRead16 ((UINTN)Address);\r
9595e3cd
LE
1043 break;\r
1044 case EfiPciWidthUint32:\r
1cfa1957 1045 *((UINT32 *)Uint8Buffer) = MmioRead32 ((UINTN)Address);\r
9595e3cd
LE
1046 break;\r
1047 default:\r
1048 //\r
1049 // The RootBridgeIoCheckParameter call above will ensure that this\r
1050 // path is not taken.\r
1051 //\r
1052 ASSERT (FALSE);\r
1053 break;\r
1054 }\r
1055 }\r
1056 }\r
1057 return EFI_SUCCESS;\r
1058}\r
1059\r
1060/**\r
1061 Internal help function for read and write PCI configuration space.\r
1062\r
1063 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
1064 @param[in] Write Switch value for Read or Write.\r
1065 @param[in] Width Signifies the width of the memory operations.\r
1066 @param[in] UserAddress The address within the PCI configuration space for the PCI controller.\r
1067 @param[in] Count The number of PCI configuration operations to perform. Bytes\r
1068 moved is Width size * Count, starting at Address.\r
1069 @param[in, out] UserBuffer For read operations, the destination buffer to store the results. For\r
1070 write operations, the source buffer to write data from.\r
d1c561f9 1071\r
9595e3cd
LE
1072 @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.\r
1073 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.\r
1074 @retval EFI_INVALID_PARAMETER Buffer is NULL.\r
1075 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
1076\r
1077**/\r
1078EFI_STATUS\r
1079RootBridgeIoPciRW (\r
1080 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
1081 IN BOOLEAN Write,\r
1082 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
1083 IN UINT64 Address,\r
1084 IN UINTN Count,\r
1085 IN OUT VOID *Buffer\r
1086 )\r
1087{\r
1088 EFI_STATUS Status;\r
1089 UINT8 InStride;\r
1090 UINT8 OutStride;\r
1091 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH OperationWidth;\r
1092 UINT8 *Uint8Buffer;\r
1093 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *PciRbAddr;\r
1094 UINTN PcieRegAddr;\r
1095\r
1096 Status = RootBridgeIoCheckParameter (This, PciOperation, Width, Address, Count, Buffer);\r
1097 if (EFI_ERROR (Status)) {\r
1098 return Status;\r
1099 }\r
1100\r
1101 PciRbAddr = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS*) &Address;\r
1102\r
1103 PcieRegAddr = (UINTN) PCI_LIB_ADDRESS (\r
1104 PciRbAddr->Bus,\r
1105 PciRbAddr->Device,\r
1106 PciRbAddr->Function,\r
1107 (PciRbAddr->ExtendedRegister != 0) ? \\r
1108 PciRbAddr->ExtendedRegister :\r
1109 PciRbAddr->Register\r
1110 );\r
1111\r
1112 InStride = mInStride[Width];\r
1113 OutStride = mOutStride[Width];\r
1114 OperationWidth = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (Width & 0x03);\r
1115 for (Uint8Buffer = Buffer; Count > 0; PcieRegAddr += InStride, Uint8Buffer += OutStride, Count--) {\r
1116 if (Write) {\r
1117 switch (OperationWidth) {\r
1118 case EfiPciWidthUint8:\r
1119 PciWrite8 (PcieRegAddr, *Uint8Buffer);\r
1120 break;\r
1121 case EfiPciWidthUint16:\r
1122 PciWrite16 (PcieRegAddr, *((UINT16 *)Uint8Buffer));\r
1123 break;\r
1124 case EfiPciWidthUint32:\r
1125 PciWrite32 (PcieRegAddr, *((UINT32 *)Uint8Buffer));\r
1126 break;\r
1127 default:\r
1128 //\r
1129 // The RootBridgeIoCheckParameter call above will ensure that this\r
1130 // path is not taken.\r
1131 //\r
1132 ASSERT (FALSE);\r
1133 break;\r
1134 }\r
1135 } else {\r
1136 switch (OperationWidth) {\r
1137 case EfiPciWidthUint8:\r
1138 *Uint8Buffer = PciRead8 (PcieRegAddr);\r
1139 break;\r
1140 case EfiPciWidthUint16:\r
1141 *((UINT16 *)Uint8Buffer) = PciRead16 (PcieRegAddr);\r
1142 break;\r
1143 case EfiPciWidthUint32:\r
1144 *((UINT32 *)Uint8Buffer) = PciRead32 (PcieRegAddr);\r
1145 break;\r
1146 default:\r
1147 //\r
1148 // The RootBridgeIoCheckParameter call above will ensure that this\r
1149 // path is not taken.\r
1150 //\r
1151 ASSERT (FALSE);\r
1152 break;\r
1153 }\r
1154 }\r
1155 }\r
1156\r
1157 return EFI_SUCCESS;\r
1158}\r
1159\r
1160/**\r
d1c561f9
OM
1161 Polls an address in memory mapped I/O space until an exit condition is met, or\r
1162 a timeout occurs.\r
9595e3cd
LE
1163\r
1164 This function provides a standard way to poll a PCI memory location. A PCI memory read\r
1165 operation is performed at the PCI memory address specified by Address for the width specified\r
1166 by Width. The result of this PCI memory read operation is stored in Result. This PCI memory\r
1167 read operation is repeated until either a timeout of Delay 100 ns units has expired, or (Result &\r
1168 Mask) is equal to Value.\r
1169\r
1170 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
1171 @param[in] Width Signifies the width of the memory operations.\r
1172 @param[in] Address The base address of the memory operations. The caller is\r
1173 responsible for aligning Address if required.\r
1174 @param[in] Mask Mask used for the polling criteria. Bytes above Width in Mask\r
1175 are ignored. The bits in the bytes below Width which are zero in\r
1176 Mask are ignored when polling the memory address.\r
1177 @param[in] Value The comparison value used for the polling exit criteria.\r
1178 @param[in] Delay The number of 100 ns units to poll. Note that timer available may\r
1179 be of poorer granularity.\r
1180 @param[out] Result Pointer to the last value read from the memory location.\r
d1c561f9 1181\r
9595e3cd
LE
1182 @retval EFI_SUCCESS The last data returned from the access matched the poll exit criteria.\r
1183 @retval EFI_INVALID_PARAMETER Width is invalid.\r
1184 @retval EFI_INVALID_PARAMETER Result is NULL.\r
1185 @retval EFI_TIMEOUT Delay expired before a match occurred.\r
1186 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
1187\r
1188**/\r
1189EFI_STATUS\r
1190EFIAPI\r
d1c561f9 1191RootBridgeIoPollMem (\r
9595e3cd
LE
1192 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
1193 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
1194 IN UINT64 Address,\r
1195 IN UINT64 Mask,\r
1196 IN UINT64 Value,\r
1197 IN UINT64 Delay,\r
1198 OUT UINT64 *Result\r
1199 )\r
1200{\r
1201 EFI_STATUS Status;\r
1202 UINT64 NumberOfTicks;\r
1203 UINT32 Remainder;\r
1204\r
1205 if (Result == NULL) {\r
1206 return EFI_INVALID_PARAMETER;\r
1207 }\r
1208\r
1209 if ((UINT32)Width > EfiPciWidthUint64) {\r
1210 return EFI_INVALID_PARAMETER;\r
1211 }\r
1212\r
1213 //\r
1214 // No matter what, always do a single poll.\r
1215 //\r
1216 Status = This->Mem.Read (This, Width, Address, 1, Result);\r
1217 if (EFI_ERROR (Status)) {\r
1218 return Status;\r
d1c561f9 1219 }\r
9595e3cd
LE
1220 if ((*Result & Mask) == Value) {\r
1221 return EFI_SUCCESS;\r
1222 }\r
1223\r
1224 if (Delay == 0) {\r
1225 return EFI_SUCCESS;\r
d1c561f9 1226\r
9595e3cd
LE
1227 } else {\r
1228\r
1229 //\r
1230 // Determine the proper # of metronome ticks to wait for polling the\r
1231 // location. The nuber of ticks is Roundup (Delay / mMetronome->TickPeriod)+1\r
1232 // The "+1" to account for the possibility of the first tick being short\r
1233 // because we started in the middle of a tick.\r
1234 //\r
1235 // BugBug: overriding mMetronome->TickPeriod with UINT32 until Metronome\r
1236 // protocol definition is updated.\r
1237 //\r
1238 NumberOfTicks = DivU64x32Remainder (Delay, (UINT32) mMetronome->TickPeriod, &Remainder);\r
1239 if (Remainder != 0) {\r
1240 NumberOfTicks += 1;\r
1241 }\r
1242 NumberOfTicks += 1;\r
d1c561f9 1243\r
9595e3cd
LE
1244 while (NumberOfTicks != 0) {\r
1245\r
1246 mMetronome->WaitForTick (mMetronome, 1);\r
d1c561f9 1247\r
9595e3cd
LE
1248 Status = This->Mem.Read (This, Width, Address, 1, Result);\r
1249 if (EFI_ERROR (Status)) {\r
1250 return Status;\r
1251 }\r
d1c561f9 1252\r
9595e3cd
LE
1253 if ((*Result & Mask) == Value) {\r
1254 return EFI_SUCCESS;\r
1255 }\r
1256\r
1257 NumberOfTicks -= 1;\r
1258 }\r
1259 }\r
1260 return EFI_TIMEOUT;\r
1261}\r
d1c561f9 1262\r
9595e3cd
LE
1263/**\r
1264 Reads from the I/O space of a PCI Root Bridge. Returns when either the polling exit criteria is\r
1265 satisfied or after a defined duration.\r
1266\r
1267 This function provides a standard way to poll a PCI I/O location. A PCI I/O read operation is\r
1268 performed at the PCI I/O address specified by Address for the width specified by Width.\r
1269 The result of this PCI I/O read operation is stored in Result. This PCI I/O read operation is\r
1270 repeated until either a timeout of Delay 100 ns units has expired, or (Result & Mask) is equal\r
1271 to Value.\r
1272\r
1273 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
1274 @param[in] Width Signifies the width of the I/O operations.\r
1275 @param[in] Address The base address of the I/O operations. The caller is responsible\r
1276 for aligning Address if required.\r
1277 @param[in] Mask Mask used for the polling criteria. Bytes above Width in Mask\r
1278 are ignored. The bits in the bytes below Width which are zero in\r
1279 Mask are ignored when polling the I/O address.\r
1280 @param[in] Value The comparison value used for the polling exit criteria.\r
1281 @param[in] Delay The number of 100 ns units to poll. Note that timer available may\r
1282 be of poorer granularity.\r
1283 @param[out] Result Pointer to the last value read from the memory location.\r
d1c561f9 1284\r
9595e3cd
LE
1285 @retval EFI_SUCCESS The last data returned from the access matched the poll exit criteria.\r
1286 @retval EFI_INVALID_PARAMETER Width is invalid.\r
1287 @retval EFI_INVALID_PARAMETER Result is NULL.\r
1288 @retval EFI_TIMEOUT Delay expired before a match occurred.\r
1289 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
1290\r
1291**/\r
1292EFI_STATUS\r
1293EFIAPI\r
d1c561f9 1294RootBridgeIoPollIo (\r
9595e3cd
LE
1295 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
1296 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
1297 IN UINT64 Address,\r
1298 IN UINT64 Mask,\r
1299 IN UINT64 Value,\r
1300 IN UINT64 Delay,\r
1301 OUT UINT64 *Result\r
1302 )\r
1303{\r
1304 EFI_STATUS Status;\r
1305 UINT64 NumberOfTicks;\r
1306 UINT32 Remainder;\r
1307\r
1308 //\r
1309 // No matter what, always do a single poll.\r
1310 //\r
1311\r
1312 if (Result == NULL) {\r
1313 return EFI_INVALID_PARAMETER;\r
1314 }\r
1315\r
1316 if ((UINT32)Width > EfiPciWidthUint64) {\r
1317 return EFI_INVALID_PARAMETER;\r
1318 }\r
d1c561f9 1319\r
9595e3cd
LE
1320 Status = This->Io.Read (This, Width, Address, 1, Result);\r
1321 if (EFI_ERROR (Status)) {\r
1322 return Status;\r
d1c561f9 1323 }\r
9595e3cd
LE
1324 if ((*Result & Mask) == Value) {\r
1325 return EFI_SUCCESS;\r
1326 }\r
1327\r
1328 if (Delay == 0) {\r
1329 return EFI_SUCCESS;\r
d1c561f9 1330\r
9595e3cd
LE
1331 } else {\r
1332\r
1333 //\r
1334 // Determine the proper # of metronome ticks to wait for polling the\r
1335 // location. The number of ticks is Roundup (Delay / mMetronome->TickPeriod)+1\r
1336 // The "+1" to account for the possibility of the first tick being short\r
1337 // because we started in the middle of a tick.\r
1338 //\r
1339 NumberOfTicks = DivU64x32Remainder (Delay, (UINT32)mMetronome->TickPeriod, &Remainder);\r
1340 if (Remainder != 0) {\r
1341 NumberOfTicks += 1;\r
1342 }\r
1343 NumberOfTicks += 1;\r
d1c561f9 1344\r
9595e3cd
LE
1345 while (NumberOfTicks != 0) {\r
1346\r
1347 mMetronome->WaitForTick (mMetronome, 1);\r
d1c561f9 1348\r
9595e3cd
LE
1349 Status = This->Io.Read (This, Width, Address, 1, Result);\r
1350 if (EFI_ERROR (Status)) {\r
1351 return Status;\r
1352 }\r
d1c561f9 1353\r
9595e3cd
LE
1354 if ((*Result & Mask) == Value) {\r
1355 return EFI_SUCCESS;\r
1356 }\r
1357\r
1358 NumberOfTicks -= 1;\r
1359 }\r
1360 }\r
1361 return EFI_TIMEOUT;\r
1362}\r
1363\r
1364/**\r
1365 Enables a PCI driver to access PCI controller registers in the PCI root bridge memory space.\r
1366\r
1367 The Mem.Read(), and Mem.Write() functions enable a driver to access PCI controller\r
1368 registers in the PCI root bridge memory space.\r
1369 The memory operations are carried out exactly as requested. The caller is responsible for satisfying\r
1370 any alignment and memory width restrictions that a PCI Root Bridge on a platform might require.\r
1371\r
1372 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
1373 @param[in] Width Signifies the width of the memory operation.\r
1374 @param[in] Address The base address of the memory operation. The caller is\r
1375 responsible for aligning the Address if required.\r
1376 @param[in] Count The number of memory operations to perform. Bytes moved is\r
1377 Width size * Count, starting at Address.\r
1378 @param[out] Buffer For read operations, the destination buffer to store the results. For\r
1379 write operations, the source buffer to write data from.\r
d1c561f9 1380\r
9595e3cd
LE
1381 @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.\r
1382 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.\r
1383 @retval EFI_INVALID_PARAMETER Buffer is NULL.\r
1384 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
1385\r
1386**/\r
1387EFI_STATUS\r
1388EFIAPI\r
1389RootBridgeIoMemRead (\r
1390 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
1391 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
1392 IN UINT64 Address,\r
1393 IN UINTN Count,\r
1394 OUT VOID *Buffer\r
1395 )\r
1396{\r
1397 return RootBridgeIoMemRW (This, FALSE, Width, Address, Count, Buffer);\r
1398}\r
1399\r
1400/**\r
1401 Enables a PCI driver to access PCI controller registers in the PCI root bridge memory space.\r
1402\r
1403 The Mem.Read(), and Mem.Write() functions enable a driver to access PCI controller\r
1404 registers in the PCI root bridge memory space.\r
1405 The memory operations are carried out exactly as requested. The caller is responsible for satisfying\r
1406 any alignment and memory width restrictions that a PCI Root Bridge on a platform might require.\r
1407\r
1408 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
1409 @param[in] Width Signifies the width of the memory operation.\r
1410 @param[in] Address The base address of the memory operation. The caller is\r
1411 responsible for aligning the Address if required.\r
1412 @param[in] Count The number of memory operations to perform. Bytes moved is\r
1413 Width size * Count, starting at Address.\r
1414 @param[in] Buffer For read operations, the destination buffer to store the results. For\r
1415 write operations, the source buffer to write data from.\r
d1c561f9 1416\r
9595e3cd
LE
1417 @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.\r
1418 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.\r
1419 @retval EFI_INVALID_PARAMETER Buffer is NULL.\r
1420 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
1421**/\r
1422EFI_STATUS\r
1423EFIAPI\r
1424RootBridgeIoMemWrite (\r
1425 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
1426 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
1427 IN UINT64 Address,\r
1428 IN UINTN Count,\r
1429 IN VOID *Buffer\r
1430 )\r
1431{\r
d1c561f9 1432 return RootBridgeIoMemRW (This, TRUE, Width, Address, Count, Buffer);\r
9595e3cd
LE
1433}\r
1434\r
1435/**\r
1436 Enables a PCI driver to access PCI controller registers in the PCI root bridge I/O space.\r
1437\r
1438 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
1439 @param[in] Width Signifies the width of the memory operations.\r
1440 @param[in] Address The base address of the I/O operation. The caller is responsible for\r
1441 aligning the Address if required.\r
1442 @param[in] Count The number of I/O operations to perform. Bytes moved is Width\r
1443 size * Count, starting at Address.\r
1444 @param[out] Buffer For read operations, the destination buffer to store the results. For\r
1445 write operations, the source buffer to write data from.\r
d1c561f9 1446\r
9595e3cd
LE
1447 @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.\r
1448 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.\r
1449 @retval EFI_INVALID_PARAMETER Buffer is NULL.\r
1450 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
1451\r
1452**/\r
1453EFI_STATUS\r
1454EFIAPI\r
1455RootBridgeIoIoRead (\r
1456 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
1457 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
1458 IN UINT64 Address,\r
1459 IN UINTN Count,\r
1460 OUT VOID *Buffer\r
1461 )\r
1462{\r
d1c561f9 1463 return RootBridgeIoIoRW (This, FALSE, Width, Address, Count, Buffer);\r
9595e3cd
LE
1464}\r
1465\r
1466/**\r
1467 Enables a PCI driver to access PCI controller registers in the PCI root bridge I/O space.\r
1468\r
1469 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
1470 @param[in] Width Signifies the width of the memory operations.\r
1471 @param[in] Address The base address of the I/O operation. The caller is responsible for\r
1472 aligning the Address if required.\r
1473 @param[in] Count The number of I/O operations to perform. Bytes moved is Width\r
1474 size * Count, starting at Address.\r
1475 @param[in] Buffer For read operations, the destination buffer to store the results. For\r
1476 write operations, the source buffer to write data from.\r
d1c561f9 1477\r
9595e3cd
LE
1478 @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.\r
1479 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.\r
1480 @retval EFI_INVALID_PARAMETER Buffer is NULL.\r
1481 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
1482\r
1483**/\r
1484EFI_STATUS\r
1485EFIAPI\r
1486RootBridgeIoIoWrite (\r
1487 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
1488 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
1489 IN UINT64 Address,\r
1490 IN UINTN Count,\r
1491 IN VOID *Buffer\r
1492 )\r
1493{\r
d1c561f9 1494 return RootBridgeIoIoRW (This, TRUE, Width, Address, Count, Buffer);\r
9595e3cd
LE
1495}\r
1496\r
1497/**\r
1498 Enables a PCI driver to copy one region of PCI root bridge memory space to another region of PCI\r
1499 root bridge memory space.\r
1500\r
1501 The CopyMem() function enables a PCI driver to copy one region of PCI root bridge memory\r
1502 space to another region of PCI root bridge memory space. This is especially useful for video scroll\r
1503 operation on a memory mapped video buffer.\r
1504 The memory operations are carried out exactly as requested. The caller is responsible for satisfying\r
1505 any alignment and memory width restrictions that a PCI root bridge on a platform might require.\r
1506\r
1507 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance.\r
1508 @param[in] Width Signifies the width of the memory operations.\r
1509 @param[in] DestAddress The destination address of the memory operation. The caller is\r
1510 responsible for aligning the DestAddress if required.\r
1511 @param[in] SrcAddress The source address of the memory operation. The caller is\r
1512 responsible for aligning the SrcAddress if required.\r
1513 @param[in] Count The number of memory operations to perform. Bytes moved is\r
1514 Width size * Count, starting at DestAddress and SrcAddress.\r
d1c561f9 1515\r
9595e3cd
LE
1516 @retval EFI_SUCCESS The data was copied from one memory region to another memory region.\r
1517 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.\r
1518 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
1519\r
1520**/\r
1521EFI_STATUS\r
1522EFIAPI\r
1523RootBridgeIoCopyMem (\r
1524 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
1525 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
1526 IN UINT64 DestAddress,\r
1527 IN UINT64 SrcAddress,\r
1528 IN UINTN Count\r
1529 )\r
1530{\r
1531 EFI_STATUS Status;\r
1532 BOOLEAN Direction;\r
1533 UINTN Stride;\r
1534 UINTN Index;\r
1535 UINT64 Result;\r
1536\r
1537 if ((UINT32)Width > EfiPciWidthUint64) {\r
1538 return EFI_INVALID_PARAMETER;\r
d1c561f9 1539 }\r
9595e3cd
LE
1540\r
1541 if (DestAddress == SrcAddress) {\r
1542 return EFI_SUCCESS;\r
1543 }\r
1544\r
1545 Stride = (UINTN)(1 << Width);\r
1546\r
1547 Direction = TRUE;\r
1548 if ((DestAddress > SrcAddress) && (DestAddress < (SrcAddress + Count * Stride))) {\r
1549 Direction = FALSE;\r
1550 SrcAddress = SrcAddress + (Count-1) * Stride;\r
1551 DestAddress = DestAddress + (Count-1) * Stride;\r
1552 }\r
1553\r
1554 for (Index = 0;Index < Count;Index++) {\r
1555 Status = RootBridgeIoMemRead (\r
1556 This,\r
1557 Width,\r
1558 SrcAddress,\r
1559 1,\r
1560 &Result\r
1561 );\r
1562 if (EFI_ERROR (Status)) {\r
1563 return Status;\r
1564 }\r
1565 Status = RootBridgeIoMemWrite (\r
1566 This,\r
1567 Width,\r
1568 DestAddress,\r
1569 1,\r
1570 &Result\r
1571 );\r
1572 if (EFI_ERROR (Status)) {\r
1573 return Status;\r
1574 }\r
1575 if (Direction) {\r
1576 SrcAddress += Stride;\r
1577 DestAddress += Stride;\r
1578 } else {\r
1579 SrcAddress -= Stride;\r
1580 DestAddress -= Stride;\r
1581 }\r
1582 }\r
1583 return EFI_SUCCESS;\r
1584}\r
1585\r
1586/**\r
1587 Enables a PCI driver to access PCI controller registers in a PCI root bridge's configuration space.\r
1588\r
1589 The Pci.Read() and Pci.Write() functions enable a driver to access PCI configuration\r
1590 registers for a PCI controller.\r
1591 The PCI Configuration operations are carried out exactly as requested. The caller is responsible for\r
1592 any alignment and PCI configuration width issues that a PCI Root Bridge on a platform might\r
1593 require.\r
1594\r
1595 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
1596 @param[in] Width Signifies the width of the memory operations.\r
1597 @param[in] Address The address within the PCI configuration space for the PCI controller.\r
1598 @param[in] Count The number of PCI configuration operations to perform. Bytes\r
1599 moved is Width size * Count, starting at Address.\r
1600 @param[out] Buffer For read operations, the destination buffer to store the results. For\r
1601 write operations, the source buffer to write data from.\r
d1c561f9 1602\r
9595e3cd
LE
1603 @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.\r
1604 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.\r
1605 @retval EFI_INVALID_PARAMETER Buffer is NULL.\r
1606 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
1607\r
1608**/\r
1609EFI_STATUS\r
1610EFIAPI\r
1611RootBridgeIoPciRead (\r
1612 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
1613 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
1614 IN UINT64 Address,\r
1615 IN UINTN Count,\r
1616 OUT VOID *Buffer\r
1617 )\r
1618{\r
1619 return RootBridgeIoPciRW (This, FALSE, Width, Address, Count, Buffer);\r
1620}\r
1621\r
1622/**\r
1623 Enables a PCI driver to access PCI controller registers in a PCI root bridge's configuration space.\r
1624\r
1625 The Pci.Read() and Pci.Write() functions enable a driver to access PCI configuration\r
1626 registers for a PCI controller.\r
1627 The PCI Configuration operations are carried out exactly as requested. The caller is responsible for\r
1628 any alignment and PCI configuration width issues that a PCI Root Bridge on a platform might\r
1629 require.\r
1630\r
1631 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
1632 @param[in] Width Signifies the width of the memory operations.\r
1633 @param[in] Address The address within the PCI configuration space for the PCI controller.\r
1634 @param[in] Count The number of PCI configuration operations to perform. Bytes\r
1635 moved is Width size * Count, starting at Address.\r
1636 @param[in] Buffer For read operations, the destination buffer to store the results. For\r
1637 write operations, the source buffer to write data from.\r
d1c561f9 1638\r
9595e3cd
LE
1639 @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.\r
1640 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.\r
1641 @retval EFI_INVALID_PARAMETER Buffer is NULL.\r
1642 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
1643\r
1644**/\r
1645EFI_STATUS\r
1646EFIAPI\r
1647RootBridgeIoPciWrite (\r
1648 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
1649 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
1650 IN UINT64 Address,\r
1651 IN UINTN Count,\r
1652 IN VOID *Buffer\r
1653 )\r
1654{\r
1655 return RootBridgeIoPciRW (This, TRUE, Width, Address, Count, Buffer);\r
1656}\r
1657\r
1658/**\r
1659 Provides the PCI controller-specific addresses required to access system memory from a\r
1660 DMA bus master.\r
1661\r
1662 The Map() function provides the PCI controller specific addresses needed to access system\r
1663 memory. This function is used to map system memory for PCI bus master DMA accesses.\r
1664\r
1665 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
1666 @param[in] Operation Indicates if the bus master is going to read or write to system memory.\r
1667 @param[in] HostAddress The system memory address to map to the PCI controller.\r
1668 @param[in, out] NumberOfBytes On input the number of bytes to map. On output the number of bytes that were mapped.\r
1669 @param[out] DeviceAddress The resulting map address for the bus master PCI controller to use\r
1670 to access the system memory's HostAddress.\r
1671 @param[out] Mapping The value to pass to Unmap() when the bus master DMA operation is complete.\r
d1c561f9 1672\r
9595e3cd
LE
1673 @retval EFI_SUCCESS The range was mapped for the returned NumberOfBytes.\r
1674 @retval EFI_INVALID_PARAMETER Operation is invalid.\r
1675 @retval EFI_INVALID_PARAMETER HostAddress is NULL.\r
1676 @retval EFI_INVALID_PARAMETER NumberOfBytes is NULL.\r
1677 @retval EFI_INVALID_PARAMETER DeviceAddress is NULL.\r
1678 @retval EFI_INVALID_PARAMETER Mapping is NULL.\r
1679 @retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a common buffer.\r
1680 @retval EFI_DEVICE_ERROR The system hardware could not map the requested address.\r
1681 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
1682\r
1683**/\r
1684EFI_STATUS\r
1685EFIAPI\r
1686RootBridgeIoMap (\r
1687 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
1688 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION Operation,\r
1689 IN VOID *HostAddress,\r
1690 IN OUT UINTN *NumberOfBytes,\r
1691 OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,\r
1692 OUT VOID **Mapping\r
1693 )\r
1694{\r
1695 EFI_STATUS Status;\r
1696 EFI_PHYSICAL_ADDRESS PhysicalAddress;\r
1697 MAP_INFO *MapInfo;\r
1698\r
1699 if (HostAddress == NULL || NumberOfBytes == NULL || DeviceAddress == NULL || Mapping == NULL) {\r
1700 return EFI_INVALID_PARAMETER;\r
1701 }\r
d1c561f9 1702\r
9595e3cd
LE
1703 //\r
1704 // Initialize the return values to their defaults\r
1705 //\r
1706 *Mapping = NULL;\r
1707\r
1708 //\r
1709 // Make sure that Operation is valid\r
1710 //\r
1711 if ((UINT32)Operation >= EfiPciOperationMaximum) {\r
1712 return EFI_INVALID_PARAMETER;\r
1713 }\r
1714\r
1715 //\r
1716 // Most PCAT like chipsets can not handle performing DMA above 4GB.\r
1717 // If any part of the DMA transfer being mapped is above 4GB, then\r
1718 // map the DMA transfer to a buffer below 4GB.\r
1719 //\r
1720 PhysicalAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress;\r
1721 if ((PhysicalAddress + *NumberOfBytes) > 0x100000000ULL) {\r
1722\r
1723 //\r
1724 // Common Buffer operations can not be remapped. If the common buffer\r
d1c561f9 1725 // if above 4GB, then it is not possible to generate a mapping, so return\r
9595e3cd
LE
1726 // an error.\r
1727 //\r
1728 if (Operation == EfiPciOperationBusMasterCommonBuffer || Operation == EfiPciOperationBusMasterCommonBuffer64) {\r
1729 return EFI_UNSUPPORTED;\r
1730 }\r
1731\r
1732 //\r
1733 // Allocate a MAP_INFO structure to remember the mapping when Unmap() is\r
1734 // called later.\r
1735 //\r
1736 Status = gBS->AllocatePool (\r
d1c561f9
OM
1737 EfiBootServicesData,\r
1738 sizeof(MAP_INFO),\r
9595e3cd
LE
1739 (VOID **)&MapInfo\r
1740 );\r
1741 if (EFI_ERROR (Status)) {\r
1742 *NumberOfBytes = 0;\r
1743 return Status;\r
1744 }\r
1745\r
1746 //\r
1747 // Return a pointer to the MAP_INFO structure in Mapping\r
1748 //\r
1749 *Mapping = MapInfo;\r
1750\r
1751 //\r
1752 // Initialize the MAP_INFO structure\r
1753 //\r
1754 MapInfo->Operation = Operation;\r
1755 MapInfo->NumberOfBytes = *NumberOfBytes;\r
1756 MapInfo->NumberOfPages = EFI_SIZE_TO_PAGES(*NumberOfBytes);\r
1757 MapInfo->HostAddress = PhysicalAddress;\r
1758 MapInfo->MappedHostAddress = 0x00000000ffffffff;\r
1759\r
1760 //\r
1761 // Allocate a buffer below 4GB to map the transfer to.\r
1762 //\r
1763 Status = gBS->AllocatePages (\r
d1c561f9
OM
1764 AllocateMaxAddress,\r
1765 EfiBootServicesData,\r
9595e3cd
LE
1766 MapInfo->NumberOfPages,\r
1767 &MapInfo->MappedHostAddress\r
1768 );\r
1769 if (EFI_ERROR (Status)) {\r
1770 gBS->FreePool (MapInfo);\r
1771 *NumberOfBytes = 0;\r
1772 return Status;\r
1773 }\r
1774\r
1775 //\r
1776 // If this is a read operation from the Bus Master's point of view,\r
1777 // then copy the contents of the real buffer into the mapped buffer\r
1778 // so the Bus Master can read the contents of the real buffer.\r
1779 //\r
1780 if (Operation == EfiPciOperationBusMasterRead || Operation == EfiPciOperationBusMasterRead64) {\r
1781 CopyMem (\r
d1c561f9 1782 (VOID *)(UINTN)MapInfo->MappedHostAddress,\r
9595e3cd
LE
1783 (VOID *)(UINTN)MapInfo->HostAddress,\r
1784 MapInfo->NumberOfBytes\r
1785 );\r
1786 }\r
1787\r
1788 //\r
1789 // The DeviceAddress is the address of the maped buffer below 4GB\r
1790 //\r
1791 *DeviceAddress = MapInfo->MappedHostAddress;\r
1792 } else {\r
1793 //\r
1794 // The transfer is below 4GB, so the DeviceAddress is simply the HostAddress\r
1795 //\r
1796 *DeviceAddress = PhysicalAddress;\r
1797 }\r
1798\r
1799 return EFI_SUCCESS;\r
1800}\r
1801\r
1802/**\r
1803 Completes the Map() operation and releases any corresponding resources.\r
1804\r
1805 The Unmap() function completes the Map() operation and releases any corresponding resources.\r
1806 If the operation was an EfiPciOperationBusMasterWrite or\r
1807 EfiPciOperationBusMasterWrite64, the data is committed to the target system memory.\r
d1c561f9 1808 Any resources used for the mapping are freed.\r
9595e3cd
LE
1809\r
1810 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
1811 @param[in] Mapping The mapping value returned from Map().\r
d1c561f9 1812\r
9595e3cd
LE
1813 @retval EFI_SUCCESS The range was unmapped.\r
1814 @retval EFI_INVALID_PARAMETER Mapping is not a value that was returned by Map().\r
1815 @retval EFI_DEVICE_ERROR The data was not committed to the target system memory.\r
1816\r
1817**/\r
1818EFI_STATUS\r
1819EFIAPI\r
1820RootBridgeIoUnmap (\r
1821 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
1822 IN VOID *Mapping\r
1823 )\r
1824{\r
1825 MAP_INFO *MapInfo;\r
1826\r
1827 //\r
1828 // See if the Map() operation associated with this Unmap() required a mapping buffer.\r
1829 // If a mapping buffer was not required, then this function simply returns EFI_SUCCESS.\r
1830 //\r
1831 if (Mapping != NULL) {\r
1832 //\r
1833 // Get the MAP_INFO structure from Mapping\r
1834 //\r
1835 MapInfo = (MAP_INFO *)Mapping;\r
1836\r
1837 //\r
1838 // If this is a write operation from the Bus Master's point of view,\r
1839 // then copy the contents of the mapped buffer into the real buffer\r
1840 // so the processor can read the contents of the real buffer.\r
1841 //\r
1842 if (MapInfo->Operation == EfiPciOperationBusMasterWrite || MapInfo->Operation == EfiPciOperationBusMasterWrite64) {\r
1843 CopyMem (\r
d1c561f9 1844 (VOID *)(UINTN)MapInfo->HostAddress,\r
9595e3cd
LE
1845 (VOID *)(UINTN)MapInfo->MappedHostAddress,\r
1846 MapInfo->NumberOfBytes\r
1847 );\r
1848 }\r
1849\r
1850 //\r
1851 // Free the mapped buffer and the MAP_INFO structure.\r
1852 //\r
1853 gBS->FreePages (MapInfo->MappedHostAddress, MapInfo->NumberOfPages);\r
1854 gBS->FreePool (Mapping);\r
1855 }\r
1856 return EFI_SUCCESS;\r
1857}\r
1858\r
1859/**\r
1860 Allocates pages that are suitable for an EfiPciOperationBusMasterCommonBuffer or\r
1861 EfiPciOperationBusMasterCommonBuffer64 mapping.\r
d1c561f9 1862\r
9595e3cd
LE
1863 @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
1864 @param Type This parameter is not used and must be ignored.\r
1865 @param MemoryType The type of memory to allocate, EfiBootServicesData or EfiRuntimeServicesData.\r
1866 @param Pages The number of pages to allocate.\r
1867 @param HostAddress A pointer to store the base system memory address of the allocated range.\r
1868 @param Attributes The requested bit mask of attributes for the allocated range. Only\r
d1c561f9 1869 the attributes EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE, EFI_PCI_ATTRIBUTE_MEMORY_CACHED,\r
9595e3cd 1870 and EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE may be used with this function.\r
d1c561f9 1871\r
9595e3cd
LE
1872 @retval EFI_SUCCESS The requested memory pages were allocated.\r
1873 @retval EFI_INVALID_PARAMETER MemoryType is invalid.\r
1874 @retval EFI_INVALID_PARAMETER HostAddress is NULL.\r
1875 @retval EFI_UNSUPPORTED Attributes is unsupported. The only legal attribute bits are\r
1876 MEMORY_WRITE_COMBINE, MEMORY_CACHED, and DUAL_ADDRESS_CYCLE.\r
1877 @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated.\r
1878\r
1879**/\r
1880EFI_STATUS\r
1881EFIAPI\r
1882RootBridgeIoAllocateBuffer (\r
1883 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
1884 IN EFI_ALLOCATE_TYPE Type,\r
1885 IN EFI_MEMORY_TYPE MemoryType,\r
1886 IN UINTN Pages,\r
1887 OUT VOID **HostAddress,\r
1888 IN UINT64 Attributes\r
1889 )\r
1890{\r
1891 EFI_STATUS Status;\r
1892 EFI_PHYSICAL_ADDRESS PhysicalAddress;\r
1893\r
1894 //\r
1895 // Validate Attributes\r
1896 //\r
1897 if ((Attributes & EFI_PCI_ATTRIBUTE_INVALID_FOR_ALLOCATE_BUFFER) != 0) {\r
1898 return EFI_UNSUPPORTED;\r
1899 }\r
1900\r
1901 //\r
1902 // Check for invalid inputs\r
1903 //\r
1904 if (HostAddress == NULL) {\r
1905 return EFI_INVALID_PARAMETER;\r
1906 }\r
d1c561f9 1907\r
9595e3cd
LE
1908 //\r
1909 // The only valid memory types are EfiBootServicesData and EfiRuntimeServicesData\r
1910 //\r
1911 if (MemoryType != EfiBootServicesData && MemoryType != EfiRuntimeServicesData) {\r
1912 return EFI_INVALID_PARAMETER;\r
1913 }\r
1914\r
1915 //\r
1916 // Limit allocations to memory below 4GB\r
1917 //\r
1918 PhysicalAddress = (EFI_PHYSICAL_ADDRESS)(0xffffffff);\r
1919\r
1920 Status = gBS->AllocatePages (AllocateMaxAddress, MemoryType, Pages, &PhysicalAddress);\r
1921 if (EFI_ERROR (Status)) {\r
1922 return Status;\r
1923 }\r
1924\r
1925 *HostAddress = (VOID *)(UINTN)PhysicalAddress;\r
1926\r
1927 return EFI_SUCCESS;\r
1928}\r
1929\r
1930/**\r
1931 Frees memory that was allocated with AllocateBuffer().\r
1932\r
1933 The FreeBuffer() function frees memory that was allocated with AllocateBuffer().\r
1934\r
1935 @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
1936 @param Pages The number of pages to free.\r
1937 @param HostAddress The base system memory address of the allocated range.\r
d1c561f9 1938\r
9595e3cd
LE
1939 @retval EFI_SUCCESS The requested memory pages were freed.\r
1940 @retval EFI_INVALID_PARAMETER The memory range specified by HostAddress and Pages\r
1941 was not allocated with AllocateBuffer().\r
1942\r
1943**/\r
1944EFI_STATUS\r
1945EFIAPI\r
1946RootBridgeIoFreeBuffer (\r
1947 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
1948 IN UINTN Pages,\r
1949 OUT VOID *HostAddress\r
1950 )\r
1951{\r
1952 return gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress, Pages);\r
1953}\r
1954\r
1955/**\r
1956 Flushes all PCI posted write transactions from a PCI host bridge to system memory.\r
1957\r
1958 The Flush() function flushes any PCI posted write transactions from a PCI host bridge to system\r
1959 memory. Posted write transactions are generated by PCI bus masters when they perform write\r
1960 transactions to target addresses in system memory.\r
1961 This function does not flush posted write transactions from any PCI bridges. A PCI controller\r
1962 specific action must be taken to guarantee that the posted write transactions have been flushed from\r
1963 the PCI controller and from all the PCI bridges into the PCI host bridge. This is typically done with\r
1964 a PCI read transaction from the PCI controller prior to calling Flush().\r
1965\r
1966 @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
d1c561f9 1967\r
9595e3cd
LE
1968 @retval EFI_SUCCESS The PCI posted write transactions were flushed from the PCI host\r
1969 bridge to system memory.\r
1970 @retval EFI_DEVICE_ERROR The PCI posted write transactions were not flushed from the PCI\r
1971 host bridge due to a hardware error.\r
1972\r
1973**/\r
1974EFI_STATUS\r
1975EFIAPI\r
1976RootBridgeIoFlush (\r
1977 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This\r
1978 )\r
1979{\r
1980 //\r
1981 // not supported yet\r
1982 //\r
1983 return EFI_SUCCESS;\r
1984}\r
1985\r
1986/**\r
1987 Gets the attributes that a PCI root bridge supports setting with SetAttributes(), and the\r
d1c561f9 1988 attributes that a PCI root bridge is currently using.\r
9595e3cd
LE
1989\r
1990 The GetAttributes() function returns the mask of attributes that this PCI root bridge supports\r
1991 and the mask of attributes that the PCI root bridge is currently using.\r
1992\r
1993 @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
1994 @param Supported A pointer to the mask of attributes that this PCI root bridge\r
1995 supports setting with SetAttributes().\r
1996 @param Attributes A pointer to the mask of attributes that this PCI root bridge is\r
1997 currently using.\r
d1c561f9 1998\r
9595e3cd
LE
1999 @retval EFI_SUCCESS If Supports is not NULL, then the attributes that the PCI root\r
2000 bridge supports is returned in Supports. If Attributes is\r
2001 not NULL, then the attributes that the PCI root bridge is currently\r
2002 using is returned in Attributes.\r
2003 @retval EFI_INVALID_PARAMETER Both Supports and Attributes are NULL.\r
2004\r
2005**/\r
2006EFI_STATUS\r
2007EFIAPI\r
2008RootBridgeIoGetAttributes (\r
2009 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
2010 OUT UINT64 *Supported,\r
2011 OUT UINT64 *Attributes\r
2012 )\r
2013{\r
2014 PCI_ROOT_BRIDGE_INSTANCE *PrivateData;\r
2015\r
2016 PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(This);\r
2017\r
2018 if (Attributes == NULL && Supported == NULL) {\r
2019 return EFI_INVALID_PARAMETER;\r
2020 }\r
2021\r
2022 //\r
2023 // Set the return value for Supported and Attributes\r
2024 //\r
2025 if (Supported != NULL) {\r
d1c561f9 2026 *Supported = PrivateData->Supports;\r
9595e3cd
LE
2027 }\r
2028\r
2029 if (Attributes != NULL) {\r
2030 *Attributes = PrivateData->Attributes;\r
2031 }\r
d1c561f9 2032\r
9595e3cd
LE
2033 return EFI_SUCCESS;\r
2034}\r
2035\r
2036/**\r
2037 Sets attributes for a resource range on a PCI root bridge.\r
2038\r
2039 The SetAttributes() function sets the attributes specified in Attributes for the PCI root\r
2040 bridge on the resource range specified by ResourceBase and ResourceLength. Since the\r
2041 granularity of setting these attributes may vary from resource type to resource type, and from\r
2042 platform to platform, the actual resource range and the one passed in by the caller may differ. As a\r
2043 result, this function may set the attributes specified by Attributes on a larger resource range\r
2044 than the caller requested. The actual range is returned in ResourceBase and\r
2045 ResourceLength. The caller is responsible for verifying that the actual range for which the\r
2046 attributes were set is acceptable.\r
2047\r
2048 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
2049 @param[in] Attributes The mask of attributes to set. If the attribute bit\r
2050 MEMORY_WRITE_COMBINE, MEMORY_CACHED, or\r
2051 MEMORY_DISABLE is set, then the resource range is specified by\r
2052 ResourceBase and ResourceLength. If\r
2053 MEMORY_WRITE_COMBINE, MEMORY_CACHED, and\r
2054 MEMORY_DISABLE are not set, then ResourceBase and\r
2055 ResourceLength are ignored, and may be NULL.\r
2056 @param[in, out] ResourceBase A pointer to the base address of the resource range to be modified\r
2057 by the attributes specified by Attributes.\r
2058 @param[in, out] ResourceLength A pointer to the length of the resource range to be modified by the\r
2059 attributes specified by Attributes.\r
d1c561f9 2060\r
9595e3cd
LE
2061 @retval EFI_SUCCESS The current configuration of this PCI root bridge was returned in Resources.\r
2062 @retval EFI_UNSUPPORTED The current configuration of this PCI root bridge could not be retrieved.\r
2063 @retval EFI_INVALID_PARAMETER Invalid pointer of EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL\r
2064\r
2065**/\r
2066EFI_STATUS\r
2067EFIAPI\r
2068RootBridgeIoSetAttributes (\r
2069 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
2070 IN UINT64 Attributes,\r
2071 IN OUT UINT64 *ResourceBase,\r
d1c561f9 2072 IN OUT UINT64 *ResourceLength\r
9595e3cd
LE
2073 )\r
2074{\r
2075 PCI_ROOT_BRIDGE_INSTANCE *PrivateData;\r
d1c561f9 2076\r
9595e3cd 2077 PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(This);\r
d1c561f9 2078\r
9595e3cd
LE
2079 if (Attributes != 0) {\r
2080 if ((Attributes & (~(PrivateData->Supports))) != 0) {\r
2081 return EFI_UNSUPPORTED;\r
2082 }\r
2083 }\r
d1c561f9 2084\r
9595e3cd
LE
2085 //\r
2086 // This is a generic driver for a PC-AT class system. It does not have any\r
d1c561f9
OM
2087 // chipset specific knowlegde, so none of the attributes can be set or\r
2088 // cleared. Any attempt to set attribute that are already set will succeed,\r
9595e3cd
LE
2089 // and any attempt to set an attribute that is not supported will fail.\r
2090 //\r
2091 if (Attributes & (~PrivateData->Attributes)) {\r
2092 return EFI_UNSUPPORTED;\r
2093 }\r
2094\r
2095 return EFI_SUCCESS;\r
2096}\r
2097\r
2098/**\r
2099 Retrieves the current resource settings of this PCI root bridge in the form of a set of ACPI 2.0\r
2100 resource descriptors.\r
2101\r
2102 There are only two resource descriptor types from the ACPI Specification that may be used to\r
2103 describe the current resources allocated to a PCI root bridge. These are the QWORD Address\r
2104 Space Descriptor (ACPI 2.0 Section 6.4.3.5.1), and the End Tag (ACPI 2.0 Section 6.4.2.8). The\r
2105 QWORD Address Space Descriptor can describe memory, I/O, and bus number ranges for dynamic\r
2106 or fixed resources. The configuration of a PCI root bridge is described with one or more QWORD\r
2107 Address Space Descriptors followed by an End Tag.\r
2108\r
2109 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
2110 @param[out] Resources A pointer to the ACPI 2.0 resource descriptors that describe the\r
2111 current configuration of this PCI root bridge. The storage for the\r
2112 ACPI 2.0 resource descriptors is allocated by this function. The\r
2113 caller must treat the return buffer as read-only data, and the buffer\r
2114 must not be freed by the caller.\r
d1c561f9 2115\r
9595e3cd
LE
2116 @retval EFI_SUCCESS The current configuration of this PCI root bridge was returned in Resources.\r
2117 @retval EFI_UNSUPPORTED The current configuration of this PCI root bridge could not be retrieved.\r
2118 @retval EFI_INVALID_PARAMETER Invalid pointer of EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL\r
2119\r
2120**/\r
2121EFI_STATUS\r
2122EFIAPI\r
2123RootBridgeIoConfiguration (\r
2124 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
2125 OUT VOID **Resources\r
2126 )\r
2127{\r
2128 PCI_ROOT_BRIDGE_INSTANCE *PrivateData;\r
2129 UINTN Index;\r
2130\r
2131 PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);\r
d1c561f9 2132\r
9595e3cd
LE
2133 for (Index = 0; Index < TypeMax; Index++) {\r
2134 if (PrivateData->ResAllocNode[Index].Status == ResAllocated) {\r
2135 Configuration.SpaceDesp[Index].AddrRangeMin = PrivateData->ResAllocNode[Index].Base;\r
2136 Configuration.SpaceDesp[Index].AddrRangeMax = PrivateData->ResAllocNode[Index].Base + PrivateData->ResAllocNode[Index].Length - 1;\r
2137 Configuration.SpaceDesp[Index].AddrLen = PrivateData->ResAllocNode[Index].Length;\r
d1c561f9
OM
2138 }\r
2139 }\r
2140\r
2141 *Resources = &Configuration;\r
9595e3cd
LE
2142 return EFI_SUCCESS;\r
2143}\r
2144\r