Add generic HPET Timer DXE Driver and support libraries
[mirror_edk2.git] / PcAtChipsetPkg / PciHostBridgeDxe / PciRootBridgeIo.c
CommitLineData
21b404d1 1/** @file\r
2 PCI Root Bridge Io Protocol implementation\r
3\r
95d48e82 4Copyright (c) 2008 - 2010, Intel Corporation. All rights reserved.<BR>\r
18c97f53 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
21b404d1 12\r
13**/ \r
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
24 {0x8A, 0x2B, 0, 0, 0, 32, 0, 0, 0, 0}, \r
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
18c97f53 36/**\r
37 Polls an address in memory mapped I/O space until an exit condition is met, or \r
38 a timeout occurs. \r
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
57 \r
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
21b404d1 65EFI_STATUS\r
66EFIAPI\r
67RootBridgeIoPollMem ( \r
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
76 \r
18c97f53 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
98 \r
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
21b404d1 106EFI_STATUS\r
107EFIAPI\r
108RootBridgeIoPollIo ( \r
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
117 \r
18c97f53 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
134 \r
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
21b404d1 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
24115e44 148 OUT VOID *Buffer\r
21b404d1 149 );\r
150\r
18c97f53 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
24115e44 165 @param[in] Buffer For read operations, the destination buffer to store the results. For\r
18c97f53 166 write operations, the source buffer to write data from.\r
167 \r
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
21b404d1 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
24115e44 180 IN VOID *Buffer\r
21b404d1 181 );\r
182\r
18c97f53 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
24115e44 188 @param[in] UserAddress The base address of the I/O operation. The caller is responsible for\r
18c97f53 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
24115e44 192 @param[out] UserBuffer For read operations, the destination buffer to store the results. For\r
18c97f53 193 write operations, the source buffer to write data from.\r
194 \r
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
21b404d1 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
24115e44 208 OUT VOID *UserBuffer\r
21b404d1 209 );\r
210\r
18c97f53 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
24115e44 216 @param[in] UserAddress The base address of the I/O operation. The caller is responsible for\r
18c97f53 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
24115e44 220 @param[in] UserBuffer For read operations, the destination buffer to store the results. For\r
18c97f53 221 write operations, the source buffer to write data from.\r
222 \r
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
21b404d1 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
24115e44 236 IN VOID *UserBuffer\r
21b404d1 237 );\r
238\r
18c97f53 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
257 \r
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
21b404d1 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
18c97f53 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
289 \r
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
21b404d1 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
24115e44 303 OUT VOID *Buffer\r
21b404d1 304 );\r
305\r
18c97f53 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
24115e44 320 @param[in] Buffer For read operations, the destination buffer to store the results. For\r
18c97f53 321 write operations, the source buffer to write data from.\r
322 \r
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
21b404d1 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
24115e44 336 IN VOID *Buffer\r
21b404d1 337 );\r
338\r
18c97f53 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
24115e44 349 @param[in, out] NumberOfBytes On input the number of bytes to map. On output the number of bytes that were mapped.\r
18c97f53 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
353 \r
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
21b404d1 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
18c97f53 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
382 Any resources used for the mapping are freed. \r
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
386 \r
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
21b404d1 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
18c97f53 399/**\r
400 Allocates pages that are suitable for an EfiPciOperationBusMasterCommonBuffer or\r
401 EfiPciOperationBusMasterCommonBuffer64 mapping.\r
402 \r
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
409 the attributes EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE, EFI_PCI_ATTRIBUTE_MEMORY_CACHED, \r
410 and EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE may be used with this function.\r
411 \r
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
21b404d1 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
18c97f53 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
439 \r
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
21b404d1 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
18c97f53 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
465 \r
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
21b404d1 472EFI_STATUS\r
473EFIAPI\r
474RootBridgeIoFlush (\r
475 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This\r
476 );\r
477\r
18c97f53 478/**\r
479 Gets the attributes that a PCI root bridge supports setting with SetAttributes(), and the\r
480 attributes that a PCI root bridge is currently using. \r
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
490 \r
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
21b404d1 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
18c97f53 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
24115e44 526 @param[in, out] ResourceBase A pointer to the base address of the resource range to be modified\r
18c97f53 527 by the attributes specified by Attributes.\r
24115e44 528 @param[in, out] ResourceLength A pointer to the length of the resource range to be modified by the\r
18c97f53 529 attributes specified by Attributes.\r
530 \r
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
21b404d1 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
542 IN OUT UINT64 *ResourceLength \r
543 ); \r
544\r
18c97f53 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
562 \r
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
21b404d1 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
cac2ab95 576// Memory Controller Pci Root Bridge Io Module Variables\r
21b404d1 577//\r
cac2ab95 578EFI_METRONOME_ARCH_PROTOCOL *mMetronome;\r
18c97f53 579\r
cac2ab95 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
21b404d1 597\r
598//\r
cac2ab95 599// Lookup table for increment values based on transfer widths\r
21b404d1 600//\r
cac2ab95 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
21b404d1 615\r
18c97f53 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 ResAppeture ResourceAppeture for host bridge\r
624\r
625 @retval EFI_SUCCESS Success to initialize the Pci Root Bridge.\r
626\r
627**/\r
21b404d1 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_APPETURE *ResAppeture\r
634 )\r
21b404d1 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
643 // The host to pci bridge, the host memory and io addresses are\r
644 // direct mapped to pci addresses, so no need translate, set bases to 0.\r
645 //\r
646 PrivateData->MemBase = ResAppeture->MemBase;\r
647 PrivateData->IoBase = ResAppeture->IoBase;\r
648\r
649 //\r
650 // The host bridge only supports 32bit addressing for memory\r
651 // and standard IA32 16bit io\r
652 //\r
653 PrivateData->MemLimit = ResAppeture->MemLimit;\r
654 PrivateData->IoLimit = ResAppeture->IoLimit;\r
655\r
656 //\r
657 // Bus Appeture for this Root Bridge (Possible Range)\r
658 //\r
659 PrivateData->BusBase = ResAppeture->BusBase;\r
660 PrivateData->BusLimit = ResAppeture->BusLimit;\r
661 \r
662 //\r
663 // Specific for this chipset\r
664 //\r
665 for (Index = TypeIo; Index < TypeMax; Index++) {\r
666 PrivateData->ResAllocNode[Index].Type = Index;\r
667 PrivateData->ResAllocNode[Index].Base = 0;\r
668 PrivateData->ResAllocNode[Index].Length = 0;\r
669 PrivateData->ResAllocNode[Index].Status = ResNone;\r
670 }\r
671 \r
21b404d1 672 PrivateData->PciAddress = 0xCF8;\r
673 PrivateData->PciData = 0xCFC;\r
674\r
675 PrivateData->RootBridgeAttrib = Attri;\r
676 \r
e0ee9d93 677 PrivateData->Supports = EFI_PCI_ATTRIBUTE_IDE_PRIMARY_IO | EFI_PCI_ATTRIBUTE_IDE_SECONDARY_IO | \\r
678 EFI_PCI_ATTRIBUTE_ISA_IO_16 | EFI_PCI_ATTRIBUTE_ISA_MOTHERBOARD_IO | \\r
679 EFI_PCI_ATTRIBUTE_VGA_MEMORY | \\r
680 EFI_PCI_ATTRIBUTE_VGA_IO_16 | EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO_16;\r
681 PrivateData->Attributes = PrivateData->Supports;\r
21b404d1 682\r
683 Protocol->ParentHandle = HostBridgeHandle;\r
684 \r
685 Protocol->PollMem = RootBridgeIoPollMem;\r
686 Protocol->PollIo = RootBridgeIoPollIo;\r
687\r
688 Protocol->Mem.Read = RootBridgeIoMemRead;\r
689 Protocol->Mem.Write = RootBridgeIoMemWrite;\r
690\r
691 Protocol->Io.Read = RootBridgeIoIoRead;\r
692 Protocol->Io.Write = RootBridgeIoIoWrite;\r
693\r
694 Protocol->CopyMem = RootBridgeIoCopyMem;\r
695\r
696 Protocol->Pci.Read = RootBridgeIoPciRead;\r
697 Protocol->Pci.Write = RootBridgeIoPciWrite;\r
698\r
699 Protocol->Map = RootBridgeIoMap;\r
700 Protocol->Unmap = RootBridgeIoUnmap;\r
701\r
702 Protocol->AllocateBuffer = RootBridgeIoAllocateBuffer;\r
703 Protocol->FreeBuffer = RootBridgeIoFreeBuffer;\r
704\r
705 Protocol->Flush = RootBridgeIoFlush;\r
706\r
707 Protocol->GetAttributes = RootBridgeIoGetAttributes;\r
708 Protocol->SetAttributes = RootBridgeIoSetAttributes;\r
709\r
710 Protocol->Configuration = RootBridgeIoConfiguration;\r
711\r
712 Protocol->SegmentNumber = 0;\r
713\r
21b404d1 714 Status = gBS->LocateProtocol (&gEfiMetronomeArchProtocolGuid, NULL, (VOID **)&mMetronome);\r
715 ASSERT_EFI_ERROR (Status);\r
716\r
717 return EFI_SUCCESS;\r
718}\r
719\r
cac2ab95 720/**\r
721 Check parameters for IO,MMIO,PCI read/write services of PCI Root Bridge IO.\r
722\r
723 The I/O operations are carried out exactly as requested. The caller is responsible \r
724 for satisfying any alignment and I/O width restrictions that a PI System on a \r
725 platform might require. For example on some platforms, width requests of \r
726 EfiCpuIoWidthUint64 do not work. Misaligned buffers, on the other hand, will \r
727 be handled by the driver.\r
728 \r
729 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
730 @param[in] OperationType I/O operation type: IO/MMIO/PCI.\r
731 @param[in] Width Signifies the width of the I/O or Memory operation.\r
732 @param[in] Address The base address of the I/O operation. \r
733 @param[in] Count The number of I/O operations to perform. The number of \r
734 bytes moved is Width size * Count, starting at Address.\r
735 @param[in] Buffer For read operations, the destination buffer to store the results.\r
736 For write operations, the source buffer from which to write data.\r
737\r
738 @retval EFI_SUCCESS The parameters for this request pass the checks.\r
739 @retval EFI_INVALID_PARAMETER Width is invalid for this PI system.\r
740 @retval EFI_INVALID_PARAMETER Buffer is NULL.\r
741 @retval EFI_UNSUPPORTED The Buffer is not aligned for the given Width.\r
742 @retval EFI_UNSUPPORTED The address range specified by Address, Width, \r
743 and Count is not valid for this PI system.\r
744\r
745**/\r
746EFI_STATUS\r
747RootBridgeIoCheckParameter (\r
748 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
749 IN OPERATION_TYPE OperationType,\r
750 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
751 IN UINT64 Address,\r
752 IN UINTN Count,\r
753 IN VOID *Buffer\r
754 )\r
755{\r
756 PCI_ROOT_BRIDGE_INSTANCE *PrivateData;\r
757 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *PciRbAddr;\r
758 UINT64 MaxCount;\r
759 UINT64 Base;\r
760 UINT64 Limit;\r
761\r
762 //\r
763 // Check to see if Buffer is NULL\r
764 //\r
765 if (Buffer == NULL) {\r
766 return EFI_INVALID_PARAMETER;\r
767 }\r
768\r
769 //\r
770 // Check to see if Width is in the valid range\r
771 //\r
772 if (Width < EfiPciWidthUint8 || Width >= EfiPciWidthMaximum) {\r
773 return EFI_INVALID_PARAMETER;\r
774 }\r
775\r
776 //\r
777 // For FIFO type, the target address won't increase during the access,\r
778 // so treat Count as 1\r
779 //\r
780 if (Width >= EfiPciWidthFifoUint8 && Width <= EfiPciWidthFifoUint64) {\r
781 Count = 1;\r
782 }\r
783\r
784 //\r
785 // Check to see if Width is in the valid range for I/O Port operations\r
786 //\r
787 Width = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (Width & 0x03);\r
788 if ((OperationType != MemOperation) && (Width == EfiPciWidthUint64)) {\r
789 ASSERT (FALSE);\r
790 return EFI_INVALID_PARAMETER;\r
791 }\r
792\r
793 //\r
794 // Check to see if Address is aligned\r
795 //\r
796 if ((Address & (UINT64)(mInStride[Width] - 1)) != 0) {\r
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
803 // Check to see if any address associated with this transfer exceeds the maximum \r
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
810 // Since Limit can be the maximum integer value supported by the CPU and Count \r
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
813 // \r
814 // The following form of the range check is equivalent but assumes that \r
815 // Limit is of the form (2^n - 1).\r
816 //\r
817 if (OperationType == IoOperation) {\r
818 Base = PrivateData->IoBase;\r
819 Limit = PrivateData->IoLimit;\r
820 } else if (OperationType == MemOperation) {\r
821 Base = PrivateData->MemBase;\r
822 Limit = PrivateData->MemLimit;\r
823 } else {\r
824 PciRbAddr = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS*) &Address;\r
825 if (PciRbAddr->Bus < PrivateData->BusBase || PciRbAddr->Bus > PrivateData->BusLimit) {\r
826 return EFI_INVALID_PARAMETER;\r
827 }\r
828\r
829 if (PciRbAddr->Device > MAX_PCI_DEVICE_NUMBER || PciRbAddr->Function > MAX_PCI_FUNCTION_NUMBER) {\r
830 return EFI_INVALID_PARAMETER;\r
831 }\r
832\r
833 if (PciRbAddr->ExtendedRegister != 0) {\r
834 Address = PciRbAddr->ExtendedRegister;\r
835 } else {\r
836 Address = PciRbAddr->Register;\r
837 }\r
838 Base = 0;\r
839 Limit = MAX_PCI_REG_ADDRESS;\r
840 }\r
841\r
842 if (Address < Base) {\r
843 return EFI_INVALID_PARAMETER;\r
844 }\r
845\r
846 if (Count == 0) {\r
847 if (Address > Limit) {\r
848 return EFI_UNSUPPORTED;\r
849 }\r
850 } else { \r
851 MaxCount = RShiftU64 (Limit, Width);\r
852 if (MaxCount < (Count - 1)) {\r
853 return EFI_UNSUPPORTED;\r
854 }\r
855 if (Address > LShiftU64 (MaxCount - Count + 1, Width)) {\r
856 return EFI_UNSUPPORTED;\r
857 }\r
858 }\r
859\r
860 return EFI_SUCCESS;\r
861}\r
862\r
863/**\r
864 Internal help function for read and write memory space.\r
865\r
866 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
867 @param[in] Write Switch value for Read or Write.\r
868 @param[in] Width Signifies the width of the memory operations.\r
869 @param[in] UserAddress The address within the PCI configuration space for the PCI controller.\r
870 @param[in] Count The number of PCI configuration operations to perform. Bytes\r
871 moved is Width size * Count, starting at Address.\r
24115e44 872 @param[in, out] UserBuffer For read operations, the destination buffer to store the results. For\r
cac2ab95 873 write operations, the source buffer to write data from.\r
874 \r
875 @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.\r
876 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.\r
877 @retval EFI_INVALID_PARAMETER Buffer is NULL.\r
878 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
879\r
880**/\r
881EFI_STATUS\r
882RootBridgeIoMemRW (\r
883 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
884 IN BOOLEAN Write,\r
885 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
886 IN UINT64 Address,\r
887 IN UINTN Count,\r
888 IN OUT VOID *Buffer\r
889 )\r
890{\r
891 EFI_STATUS Status;\r
892 UINT8 InStride;\r
893 UINT8 OutStride;\r
894 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH OperationWidth;\r
895 UINT8 *Uint8Buffer;\r
896\r
897 Status = RootBridgeIoCheckParameter (This, MemOperation, Width, Address, Count, Buffer);\r
898 if (EFI_ERROR (Status)) {\r
899 return Status;\r
900 }\r
901\r
902 InStride = mInStride[Width];\r
903 OutStride = mOutStride[Width];\r
904 OperationWidth = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (Width & 0x03);\r
905 for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {\r
906 if (Write) {\r
907 switch (OperationWidth) {\r
908 case EfiPciWidthUint8:\r
909 MmioWrite8 ((UINTN)Address, *Uint8Buffer);\r
910 break;\r
911 case EfiPciWidthUint16:\r
912 MmioWrite16 ((UINTN)Address, *((UINT16 *)Uint8Buffer));\r
913 break;\r
914 case EfiPciWidthUint32:\r
915 MmioWrite32 ((UINTN)Address, *((UINT32 *)Uint8Buffer));\r
916 break;\r
917 case EfiPciWidthUint64:\r
918 MmioWrite64 ((UINTN)Address, *((UINT64 *)Uint8Buffer));\r
919 break;\r
daaad270 920 default:\r
921 //\r
922 // The RootBridgeIoCheckParameter call above will ensure that this\r
923 // path is not taken.\r
924 //\r
925 ASSERT (FALSE);\r
926 break;\r
cac2ab95 927 }\r
928 } else {\r
929 switch (OperationWidth) {\r
930 case EfiPciWidthUint8:\r
931 *Uint8Buffer = MmioRead8 ((UINTN)Address);\r
932 break;\r
933 case EfiPciWidthUint16:\r
934 *((UINT16 *)Uint8Buffer) = MmioRead16 ((UINTN)Address);\r
935 break;\r
936 case EfiPciWidthUint32:\r
937 *((UINT32 *)Uint8Buffer) = MmioRead32 ((UINTN)Address);\r
938 break;\r
939 case EfiPciWidthUint64:\r
940 *((UINT64 *)Uint8Buffer) = MmioRead64 ((UINTN)Address);\r
941 break;\r
daaad270 942 default:\r
943 //\r
944 // The RootBridgeIoCheckParameter call above will ensure that this\r
945 // path is not taken.\r
946 //\r
947 ASSERT (FALSE);\r
948 break;\r
cac2ab95 949 }\r
950 }\r
951 }\r
952 return EFI_SUCCESS; \r
953}\r
954\r
955/**\r
956 Internal help function for read and write IO space.\r
957\r
958 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
959 @param[in] Write Switch value for Read or Write.\r
960 @param[in] Width Signifies the width of the memory operations.\r
961 @param[in] UserAddress The address within the PCI configuration space for the PCI controller.\r
962 @param[in] Count The number of PCI configuration operations to perform. Bytes\r
963 moved is Width size * Count, starting at Address.\r
24115e44 964 @param[in, out] UserBuffer For read operations, the destination buffer to store the results. For\r
cac2ab95 965 write operations, the source buffer to write data from.\r
966 \r
967 @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.\r
968 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.\r
969 @retval EFI_INVALID_PARAMETER Buffer is NULL.\r
970 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
971\r
972**/\r
973EFI_STATUS\r
974RootBridgeIoIoRW (\r
975 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
976 IN BOOLEAN Write,\r
977 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
978 IN UINT64 Address,\r
979 IN UINTN Count,\r
980 IN OUT VOID *Buffer\r
981 )\r
982{\r
983 EFI_STATUS Status;\r
984 UINT8 InStride;\r
985 UINT8 OutStride;\r
986 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH OperationWidth;\r
987 UINT8 *Uint8Buffer;\r
988\r
989 Status = RootBridgeIoCheckParameter (This, IoOperation, Width, Address, Count, Buffer);\r
990 if (EFI_ERROR (Status)) {\r
991 return Status;\r
992 }\r
993\r
994 InStride = mInStride[Width];\r
995 OutStride = mOutStride[Width];\r
996 OperationWidth = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (Width & 0x03);\r
997 for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {\r
998 if (Write) {\r
999 switch (OperationWidth) {\r
1000 case EfiPciWidthUint8:\r
1001 IoWrite8 ((UINTN)Address, *Uint8Buffer);\r
1002 break;\r
1003 case EfiPciWidthUint16:\r
1004 IoWrite16 ((UINTN)Address, *((UINT16 *)Uint8Buffer));\r
1005 break;\r
1006 case EfiPciWidthUint32:\r
1007 IoWrite32 ((UINTN)Address, *((UINT32 *)Uint8Buffer));\r
1008 break;\r
daaad270 1009 default:\r
1010 //\r
1011 // The RootBridgeIoCheckParameter call above will ensure that this\r
1012 // path is not taken.\r
1013 //\r
1014 ASSERT (FALSE);\r
1015 break;\r
cac2ab95 1016 }\r
1017 } else {\r
1018 switch (OperationWidth) {\r
1019 case EfiPciWidthUint8:\r
1020 *Uint8Buffer = IoRead8 ((UINTN)Address);\r
1021 break;\r
1022 case EfiPciWidthUint16:\r
1023 *((UINT16 *)Uint8Buffer) = IoRead16 ((UINTN)Address);\r
1024 break;\r
1025 case EfiPciWidthUint32:\r
1026 *((UINT32 *)Uint8Buffer) = IoRead32 ((UINTN)Address);\r
1027 break;\r
daaad270 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
cac2ab95 1035 }\r
1036 }\r
1037 }\r
1038 return EFI_SUCCESS;\r
1039}\r
1040\r
1041/**\r
1042 Internal help function for read and write PCI configuration space.\r
1043\r
1044 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
1045 @param[in] Write Switch value for Read or Write.\r
1046 @param[in] Width Signifies the width of the memory operations.\r
1047 @param[in] UserAddress The address within the PCI configuration space for the PCI controller.\r
1048 @param[in] Count The number of PCI configuration operations to perform. Bytes\r
1049 moved is Width size * Count, starting at Address.\r
24115e44 1050 @param[in, out] UserBuffer For read operations, the destination buffer to store the results. For\r
cac2ab95 1051 write operations, the source buffer to write data from.\r
1052 \r
1053 @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.\r
1054 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.\r
1055 @retval EFI_INVALID_PARAMETER Buffer is NULL.\r
1056 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
1057\r
1058**/\r
1059EFI_STATUS\r
1060RootBridgeIoPciRW (\r
1061 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
1062 IN BOOLEAN Write,\r
1063 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
1064 IN UINT64 Address,\r
1065 IN UINTN Count,\r
1066 IN OUT VOID *Buffer\r
1067 )\r
1068{\r
1069 EFI_STATUS Status;\r
1070 UINT8 InStride;\r
1071 UINT8 OutStride;\r
1072 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH OperationWidth;\r
1073 UINT8 *Uint8Buffer;\r
1074 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *PciRbAddr;\r
1075 UINTN PcieRegAddr;\r
1076\r
1077 Status = RootBridgeIoCheckParameter (This, PciOperation, Width, Address, Count, Buffer);\r
1078 if (EFI_ERROR (Status)) {\r
1079 return Status;\r
1080 }\r
1081\r
1082 PciRbAddr = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS*) &Address;\r
1083\r
1084 PcieRegAddr = (UINTN) PCI_LIB_ADDRESS (\r
1085 PciRbAddr->Bus,\r
1086 PciRbAddr->Device,\r
1087 PciRbAddr->Function,\r
1088 (PciRbAddr->ExtendedRegister != 0) ? \\r
1089 PciRbAddr->ExtendedRegister :\r
1090 PciRbAddr->Register\r
1091 );\r
1092\r
1093 InStride = mInStride[Width];\r
1094 OutStride = mOutStride[Width];\r
1095 OperationWidth = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (Width & 0x03);\r
1096 for (Uint8Buffer = Buffer; Count > 0; PcieRegAddr += InStride, Uint8Buffer += OutStride, Count--) {\r
1097 if (Write) {\r
1098 switch (OperationWidth) {\r
1099 case EfiPciWidthUint8:\r
1100 PciWrite8 (PcieRegAddr, *Uint8Buffer);\r
1101 break;\r
1102 case EfiPciWidthUint16:\r
1103 PciWrite16 (PcieRegAddr, *((UINT16 *)Uint8Buffer));\r
1104 break;\r
1105 case EfiPciWidthUint32:\r
1106 PciWrite32 (PcieRegAddr, *((UINT32 *)Uint8Buffer));\r
1107 break;\r
daaad270 1108 default:\r
1109 //\r
1110 // The RootBridgeIoCheckParameter call above will ensure that this\r
1111 // path is not taken.\r
1112 //\r
1113 ASSERT (FALSE);\r
1114 break;\r
cac2ab95 1115 }\r
1116 } else {\r
1117 switch (OperationWidth) {\r
1118 case EfiPciWidthUint8:\r
1119 *Uint8Buffer = PciRead8 (PcieRegAddr);\r
1120 break;\r
1121 case EfiPciWidthUint16:\r
1122 *((UINT16 *)Uint8Buffer) = PciRead16 (PcieRegAddr);\r
1123 break;\r
1124 case EfiPciWidthUint32:\r
1125 *((UINT32 *)Uint8Buffer) = PciRead32 (PcieRegAddr);\r
1126 break;\r
daaad270 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
cac2ab95 1134 }\r
1135 }\r
1136 }\r
1137\r
1138 return EFI_SUCCESS;\r
1139}\r
1140\r
18c97f53 1141/**\r
1142 Polls an address in memory mapped I/O space until an exit condition is met, or \r
1143 a timeout occurs. \r
1144\r
1145 This function provides a standard way to poll a PCI memory location. A PCI memory read\r
1146 operation is performed at the PCI memory address specified by Address for the width specified\r
1147 by Width. The result of this PCI memory read operation is stored in Result. This PCI memory\r
1148 read operation is repeated until either a timeout of Delay 100 ns units has expired, or (Result &\r
1149 Mask) is equal to Value.\r
1150\r
1151 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
1152 @param[in] Width Signifies the width of the memory operations.\r
1153 @param[in] Address The base address of the memory operations. The caller is\r
1154 responsible for aligning Address if required.\r
1155 @param[in] Mask Mask used for the polling criteria. Bytes above Width in Mask\r
1156 are ignored. The bits in the bytes below Width which are zero in\r
1157 Mask are ignored when polling the memory address.\r
1158 @param[in] Value The comparison value used for the polling exit criteria.\r
1159 @param[in] Delay The number of 100 ns units to poll. Note that timer available may\r
1160 be of poorer granularity.\r
1161 @param[out] Result Pointer to the last value read from the memory location.\r
1162 \r
1163 @retval EFI_SUCCESS The last data returned from the access matched the poll exit criteria.\r
1164 @retval EFI_INVALID_PARAMETER Width is invalid.\r
1165 @retval EFI_INVALID_PARAMETER Result is NULL.\r
1166 @retval EFI_TIMEOUT Delay expired before a match occurred.\r
1167 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
1168\r
1169**/\r
21b404d1 1170EFI_STATUS\r
1171EFIAPI\r
1172RootBridgeIoPollMem ( \r
1173 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
1174 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
1175 IN UINT64 Address,\r
1176 IN UINT64 Mask,\r
1177 IN UINT64 Value,\r
1178 IN UINT64 Delay,\r
1179 OUT UINT64 *Result\r
1180 )\r
21b404d1 1181{\r
1182 EFI_STATUS Status;\r
1183 UINT64 NumberOfTicks;\r
1184 UINT32 Remainder;\r
1185\r
1186 if (Result == NULL) {\r
1187 return EFI_INVALID_PARAMETER;\r
1188 }\r
1189\r
1190 if (Width < 0 || Width > EfiPciWidthUint64) {\r
1191 return EFI_INVALID_PARAMETER;\r
1192 }\r
1193\r
1194 //\r
1195 // No matter what, always do a single poll.\r
1196 //\r
1197 Status = This->Mem.Read (This, Width, Address, 1, Result);\r
1198 if (EFI_ERROR (Status)) {\r
1199 return Status;\r
1200 } \r
1201 if ((*Result & Mask) == Value) {\r
1202 return EFI_SUCCESS;\r
1203 }\r
1204\r
1205 if (Delay == 0) {\r
1206 return EFI_SUCCESS;\r
1207 \r
1208 } else {\r
1209\r
1210 //\r
1211 // Determine the proper # of metronome ticks to wait for polling the\r
1212 // location. The nuber of ticks is Roundup (Delay / mMetronome->TickPeriod)+1\r
1213 // The "+1" to account for the possibility of the first tick being short\r
1214 // because we started in the middle of a tick.\r
1215 //\r
1216 // BugBug: overriding mMetronome->TickPeriod with UINT32 until Metronome\r
1217 // protocol definition is updated.\r
1218 //\r
1219 NumberOfTicks = DivU64x32Remainder (Delay, (UINT32) mMetronome->TickPeriod, &Remainder);\r
1220 if (Remainder != 0) {\r
1221 NumberOfTicks += 1;\r
1222 }\r
1223 NumberOfTicks += 1;\r
1224 \r
24115e44 1225 while (NumberOfTicks != 0) {\r
21b404d1 1226\r
1227 mMetronome->WaitForTick (mMetronome, 1);\r
1228 \r
1229 Status = This->Mem.Read (This, Width, Address, 1, Result);\r
1230 if (EFI_ERROR (Status)) {\r
1231 return Status;\r
1232 }\r
1233 \r
1234 if ((*Result & Mask) == Value) {\r
1235 return EFI_SUCCESS;\r
1236 }\r
1237\r
1238 NumberOfTicks -= 1;\r
1239 }\r
1240 }\r
1241 return EFI_TIMEOUT;\r
1242}\r
1243 \r
18c97f53 1244/**\r
1245 Reads from the I/O space of a PCI Root Bridge. Returns when either the polling exit criteria is\r
1246 satisfied or after a defined duration.\r
1247\r
1248 This function provides a standard way to poll a PCI I/O location. A PCI I/O read operation is\r
1249 performed at the PCI I/O address specified by Address for the width specified by Width.\r
1250 The result of this PCI I/O read operation is stored in Result. This PCI I/O read operation is\r
1251 repeated until either a timeout of Delay 100 ns units has expired, or (Result & Mask) is equal\r
1252 to Value.\r
1253\r
1254 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
1255 @param[in] Width Signifies the width of the I/O operations.\r
1256 @param[in] Address The base address of the I/O operations. The caller is responsible\r
1257 for aligning Address if required.\r
1258 @param[in] Mask Mask used for the polling criteria. Bytes above Width in Mask\r
1259 are ignored. The bits in the bytes below Width which are zero in\r
1260 Mask are ignored when polling the I/O address.\r
1261 @param[in] Value The comparison value used for the polling exit criteria.\r
1262 @param[in] Delay The number of 100 ns units to poll. Note that timer available may\r
1263 be of poorer granularity.\r
1264 @param[out] Result Pointer to the last value read from the memory location.\r
1265 \r
1266 @retval EFI_SUCCESS The last data returned from the access matched the poll exit criteria.\r
1267 @retval EFI_INVALID_PARAMETER Width is invalid.\r
1268 @retval EFI_INVALID_PARAMETER Result is NULL.\r
1269 @retval EFI_TIMEOUT Delay expired before a match occurred.\r
1270 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
1271\r
1272**/\r
21b404d1 1273EFI_STATUS\r
1274EFIAPI\r
1275RootBridgeIoPollIo ( \r
1276 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
1277 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
1278 IN UINT64 Address,\r
1279 IN UINT64 Mask,\r
1280 IN UINT64 Value,\r
1281 IN UINT64 Delay,\r
1282 OUT UINT64 *Result\r
1283 )\r
21b404d1 1284{\r
1285 EFI_STATUS Status;\r
1286 UINT64 NumberOfTicks;\r
1287 UINT32 Remainder;\r
1288\r
1289 //\r
1290 // No matter what, always do a single poll.\r
1291 //\r
1292\r
1293 if (Result == NULL) {\r
1294 return EFI_INVALID_PARAMETER;\r
1295 }\r
1296\r
1297 if (Width < 0 || Width > EfiPciWidthUint64) {\r
1298 return EFI_INVALID_PARAMETER;\r
1299 }\r
1300 \r
1301 Status = This->Io.Read (This, Width, Address, 1, Result);\r
1302 if (EFI_ERROR (Status)) {\r
1303 return Status;\r
1304 } \r
1305 if ((*Result & Mask) == Value) {\r
1306 return EFI_SUCCESS;\r
1307 }\r
1308\r
1309 if (Delay == 0) {\r
1310 return EFI_SUCCESS;\r
1311 \r
1312 } else {\r
1313\r
1314 //\r
1315 // Determine the proper # of metronome ticks to wait for polling the\r
1316 // location. The number of ticks is Roundup (Delay / mMetronome->TickPeriod)+1\r
1317 // The "+1" to account for the possibility of the first tick being short\r
1318 // because we started in the middle of a tick.\r
1319 //\r
1320 NumberOfTicks = DivU64x32Remainder (Delay, (UINT32)mMetronome->TickPeriod, &Remainder);\r
1321 if (Remainder != 0) {\r
1322 NumberOfTicks += 1;\r
1323 }\r
1324 NumberOfTicks += 1;\r
1325 \r
24115e44 1326 while (NumberOfTicks != 0) {\r
21b404d1 1327\r
1328 mMetronome->WaitForTick (mMetronome, 1);\r
1329 \r
1330 Status = This->Io.Read (This, Width, Address, 1, Result);\r
1331 if (EFI_ERROR (Status)) {\r
1332 return Status;\r
1333 }\r
1334 \r
1335 if ((*Result & Mask) == Value) {\r
1336 return EFI_SUCCESS;\r
1337 }\r
1338\r
1339 NumberOfTicks -= 1;\r
1340 }\r
1341 }\r
1342 return EFI_TIMEOUT;\r
1343}\r
1344\r
18c97f53 1345/**\r
1346 Enables a PCI driver to access PCI controller registers in the PCI root bridge memory space.\r
1347\r
1348 The Mem.Read(), and Mem.Write() functions enable a driver to access PCI controller\r
1349 registers in the PCI root bridge memory space.\r
1350 The memory operations are carried out exactly as requested. The caller is responsible for satisfying\r
1351 any alignment and memory width restrictions that a PCI Root Bridge on a platform might require.\r
1352\r
1353 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
1354 @param[in] Width Signifies the width of the memory operation.\r
1355 @param[in] Address The base address of the memory operation. The caller is\r
1356 responsible for aligning the Address if required.\r
1357 @param[in] Count The number of memory operations to perform. Bytes moved is\r
1358 Width size * Count, starting at Address.\r
1359 @param[out] Buffer For read operations, the destination buffer to store the results. For\r
1360 write operations, the source buffer to write data from.\r
1361 \r
1362 @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.\r
1363 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.\r
1364 @retval EFI_INVALID_PARAMETER Buffer is NULL.\r
1365 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
1366\r
1367**/\r
21b404d1 1368EFI_STATUS\r
1369EFIAPI\r
1370RootBridgeIoMemRead (\r
1371 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
1372 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
1373 IN UINT64 Address,\r
1374 IN UINTN Count,\r
24115e44 1375 OUT VOID *Buffer\r
21b404d1 1376 )\r
21b404d1 1377{\r
cac2ab95 1378 return RootBridgeIoMemRW (This, FALSE, Width, Address, Count, Buffer);\r
21b404d1 1379}\r
1380\r
18c97f53 1381/**\r
1382 Enables a PCI driver to access PCI controller registers in the PCI root bridge memory space.\r
1383\r
1384 The Mem.Read(), and Mem.Write() functions enable a driver to access PCI controller\r
1385 registers in the PCI root bridge memory space.\r
1386 The memory operations are carried out exactly as requested. The caller is responsible for satisfying\r
1387 any alignment and memory width restrictions that a PCI Root Bridge on a platform might require.\r
1388\r
1389 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
1390 @param[in] Width Signifies the width of the memory operation.\r
1391 @param[in] Address The base address of the memory operation. The caller is\r
1392 responsible for aligning the Address if required.\r
1393 @param[in] Count The number of memory operations to perform. Bytes moved is\r
1394 Width size * Count, starting at Address.\r
24115e44 1395 @param[in] Buffer For read operations, the destination buffer to store the results. For\r
18c97f53 1396 write operations, the source buffer to write data from.\r
1397 \r
1398 @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.\r
1399 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.\r
1400 @retval EFI_INVALID_PARAMETER Buffer is NULL.\r
1401 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
1402**/\r
21b404d1 1403EFI_STATUS\r
1404EFIAPI\r
1405RootBridgeIoMemWrite (\r
1406 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
1407 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
1408 IN UINT64 Address,\r
1409 IN UINTN Count,\r
24115e44 1410 IN VOID *Buffer\r
21b404d1 1411 )\r
21b404d1 1412{\r
cac2ab95 1413 return RootBridgeIoMemRW (This, TRUE, Width, Address, Count, Buffer); \r
21b404d1 1414}\r
1415\r
18c97f53 1416/**\r
1417 Enables a PCI driver to access PCI controller registers in the PCI root bridge I/O space.\r
1418\r
1419 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
1420 @param[in] Width Signifies the width of the memory operations.\r
1421 @param[in] Address The base address of the I/O operation. The caller is responsible for\r
1422 aligning the Address if required.\r
1423 @param[in] Count The number of I/O operations to perform. Bytes moved is Width\r
1424 size * Count, starting at Address.\r
1425 @param[out] Buffer For read operations, the destination buffer to store the results. For\r
1426 write operations, the source buffer to write data from.\r
1427 \r
1428 @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.\r
1429 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.\r
1430 @retval EFI_INVALID_PARAMETER Buffer is NULL.\r
1431 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
1432\r
1433**/\r
21b404d1 1434EFI_STATUS\r
1435EFIAPI\r
1436RootBridgeIoIoRead (\r
1437 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
1438 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
1439 IN UINT64 Address,\r
1440 IN UINTN Count,\r
24115e44 1441 OUT VOID *Buffer\r
21b404d1 1442 )\r
21b404d1 1443{\r
cac2ab95 1444 return RootBridgeIoIoRW (This, FALSE, Width, Address, Count, Buffer); \r
21b404d1 1445}\r
1446\r
18c97f53 1447/**\r
1448 Enables a PCI driver to access PCI controller registers in the PCI root bridge I/O space.\r
1449\r
1450 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
1451 @param[in] Width Signifies the width of the memory operations.\r
1452 @param[in] Address The base address of the I/O operation. The caller is responsible for\r
1453 aligning the Address if required.\r
1454 @param[in] Count The number of I/O operations to perform. Bytes moved is Width\r
1455 size * Count, starting at Address.\r
24115e44 1456 @param[in] Buffer For read operations, the destination buffer to store the results. For\r
18c97f53 1457 write operations, the source buffer to write data from.\r
1458 \r
1459 @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.\r
1460 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.\r
1461 @retval EFI_INVALID_PARAMETER Buffer is NULL.\r
1462 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
1463\r
1464**/\r
21b404d1 1465EFI_STATUS\r
1466EFIAPI\r
1467RootBridgeIoIoWrite (\r
1468 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
1469 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
1470 IN UINT64 Address,\r
1471 IN UINTN Count,\r
24115e44 1472 IN VOID *Buffer\r
21b404d1 1473 )\r
21b404d1 1474{\r
cac2ab95 1475 return RootBridgeIoIoRW (This, TRUE, Width, Address, Count, Buffer); \r
21b404d1 1476}\r
1477\r
18c97f53 1478/**\r
1479 Enables a PCI driver to copy one region of PCI root bridge memory space to another region of PCI\r
1480 root bridge memory space.\r
1481\r
1482 The CopyMem() function enables a PCI driver to copy one region of PCI root bridge memory\r
1483 space to another region of PCI root bridge memory space. This is especially useful for video scroll\r
1484 operation on a memory mapped video buffer.\r
1485 The memory operations are carried out exactly as requested. The caller is responsible for satisfying\r
1486 any alignment and memory width restrictions that a PCI root bridge on a platform might require.\r
1487\r
1488 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance.\r
1489 @param[in] Width Signifies the width of the memory operations.\r
1490 @param[in] DestAddress The destination address of the memory operation. The caller is\r
1491 responsible for aligning the DestAddress if required.\r
1492 @param[in] SrcAddress The source address of the memory operation. The caller is\r
1493 responsible for aligning the SrcAddress if required.\r
1494 @param[in] Count The number of memory operations to perform. Bytes moved is\r
1495 Width size * Count, starting at DestAddress and SrcAddress.\r
1496 \r
1497 @retval EFI_SUCCESS The data was copied from one memory region to another memory region.\r
1498 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.\r
1499 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
1500\r
1501**/\r
21b404d1 1502EFI_STATUS\r
1503EFIAPI\r
1504RootBridgeIoCopyMem (\r
24115e44 1505 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
21b404d1 1506 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
1507 IN UINT64 DestAddress,\r
1508 IN UINT64 SrcAddress,\r
1509 IN UINTN Count\r
1510 )\r
21b404d1 1511{\r
1512 EFI_STATUS Status;\r
1513 BOOLEAN Direction;\r
1514 UINTN Stride;\r
1515 UINTN Index;\r
1516 UINT64 Result;\r
1517\r
1518 if (Width < 0 || Width > EfiPciWidthUint64) {\r
1519 return EFI_INVALID_PARAMETER;\r
1520 } \r
1521\r
1522 if (DestAddress == SrcAddress) {\r
1523 return EFI_SUCCESS;\r
1524 }\r
1525\r
1526 Stride = (UINTN)(1 << Width);\r
1527\r
1528 Direction = TRUE;\r
1529 if ((DestAddress > SrcAddress) && (DestAddress < (SrcAddress + Count * Stride))) {\r
1530 Direction = FALSE;\r
1531 SrcAddress = SrcAddress + (Count-1) * Stride;\r
1532 DestAddress = DestAddress + (Count-1) * Stride;\r
1533 }\r
1534\r
1535 for (Index = 0;Index < Count;Index++) {\r
1536 Status = RootBridgeIoMemRead (\r
1537 This,\r
1538 Width,\r
1539 SrcAddress,\r
1540 1,\r
1541 &Result\r
1542 );\r
1543 if (EFI_ERROR (Status)) {\r
1544 return Status;\r
1545 }\r
1546 Status = RootBridgeIoMemWrite (\r
1547 This,\r
1548 Width,\r
1549 DestAddress,\r
1550 1,\r
1551 &Result\r
1552 );\r
1553 if (EFI_ERROR (Status)) {\r
1554 return Status;\r
1555 }\r
1556 if (Direction) {\r
1557 SrcAddress += Stride;\r
1558 DestAddress += Stride;\r
1559 } else {\r
1560 SrcAddress -= Stride;\r
1561 DestAddress -= Stride;\r
1562 }\r
1563 }\r
1564 return EFI_SUCCESS;\r
1565}\r
1566\r
18c97f53 1567/**\r
1568 Enables a PCI driver to access PCI controller registers in a PCI root bridge's configuration space.\r
1569\r
1570 The Pci.Read() and Pci.Write() functions enable a driver to access PCI configuration\r
1571 registers for a PCI controller.\r
1572 The PCI Configuration operations are carried out exactly as requested. The caller is responsible for\r
1573 any alignment and PCI configuration width issues that a PCI Root Bridge on a platform might\r
1574 require.\r
1575\r
1576 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
1577 @param[in] Width Signifies the width of the memory operations.\r
1578 @param[in] Address The address within the PCI configuration space for the PCI controller.\r
1579 @param[in] Count The number of PCI configuration operations to perform. Bytes\r
1580 moved is Width size * Count, starting at Address.\r
1581 @param[out] Buffer For read operations, the destination buffer to store the results. For\r
1582 write operations, the source buffer to write data from.\r
1583 \r
1584 @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.\r
1585 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.\r
1586 @retval EFI_INVALID_PARAMETER Buffer is NULL.\r
1587 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
1588\r
1589**/\r
21b404d1 1590EFI_STATUS\r
1591EFIAPI\r
1592RootBridgeIoPciRead (\r
1593 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
1594 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
1595 IN UINT64 Address,\r
1596 IN UINTN Count,\r
24115e44 1597 OUT VOID *Buffer\r
21b404d1 1598 )\r
21b404d1 1599{\r
21b404d1 1600 return RootBridgeIoPciRW (This, FALSE, Width, Address, Count, Buffer);\r
1601}\r
1602\r
18c97f53 1603/**\r
1604 Enables a PCI driver to access PCI controller registers in a PCI root bridge's configuration space.\r
1605\r
1606 The Pci.Read() and Pci.Write() functions enable a driver to access PCI configuration\r
1607 registers for a PCI controller.\r
1608 The PCI Configuration operations are carried out exactly as requested. The caller is responsible for\r
1609 any alignment and PCI configuration width issues that a PCI Root Bridge on a platform might\r
1610 require.\r
1611\r
1612 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
1613 @param[in] Width Signifies the width of the memory operations.\r
1614 @param[in] Address The address within the PCI configuration space for the PCI controller.\r
1615 @param[in] Count The number of PCI configuration operations to perform. Bytes\r
1616 moved is Width size * Count, starting at Address.\r
24115e44 1617 @param[in] Buffer For read operations, the destination buffer to store the results. For\r
18c97f53 1618 write operations, the source buffer to write data from.\r
1619 \r
1620 @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.\r
1621 @retval EFI_INVALID_PARAMETER Width is invalid for this PCI root bridge.\r
1622 @retval EFI_INVALID_PARAMETER Buffer is NULL.\r
1623 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
1624\r
1625**/\r
21b404d1 1626EFI_STATUS\r
1627EFIAPI\r
1628RootBridgeIoPciWrite (\r
1629 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
1630 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
1631 IN UINT64 Address,\r
1632 IN UINTN Count,\r
24115e44 1633 IN VOID *Buffer\r
21b404d1 1634 )\r
21b404d1 1635{\r
21b404d1 1636 return RootBridgeIoPciRW (This, TRUE, Width, Address, Count, Buffer);\r
1637}\r
1638\r
18c97f53 1639/**\r
1640 Provides the PCI controller-specific addresses required to access system memory from a\r
1641 DMA bus master.\r
1642\r
1643 The Map() function provides the PCI controller specific addresses needed to access system\r
1644 memory. This function is used to map system memory for PCI bus master DMA accesses.\r
1645\r
1646 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
1647 @param[in] Operation Indicates if the bus master is going to read or write to system memory.\r
1648 @param[in] HostAddress The system memory address to map to the PCI controller.\r
24115e44 1649 @param[in, out] NumberOfBytes On input the number of bytes to map. On output the number of bytes that were mapped.\r
18c97f53 1650 @param[out] DeviceAddress The resulting map address for the bus master PCI controller to use\r
1651 to access the system memory's HostAddress.\r
1652 @param[out] Mapping The value to pass to Unmap() when the bus master DMA operation is complete.\r
1653 \r
1654 @retval EFI_SUCCESS The range was mapped for the returned NumberOfBytes.\r
1655 @retval EFI_INVALID_PARAMETER Operation is invalid.\r
1656 @retval EFI_INVALID_PARAMETER HostAddress is NULL.\r
1657 @retval EFI_INVALID_PARAMETER NumberOfBytes is NULL.\r
1658 @retval EFI_INVALID_PARAMETER DeviceAddress is NULL.\r
1659 @retval EFI_INVALID_PARAMETER Mapping is NULL.\r
1660 @retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a common buffer.\r
1661 @retval EFI_DEVICE_ERROR The system hardware could not map the requested address.\r
1662 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
1663\r
1664**/\r
21b404d1 1665EFI_STATUS\r
1666EFIAPI\r
1667RootBridgeIoMap (\r
1668 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
1669 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION Operation,\r
1670 IN VOID *HostAddress,\r
1671 IN OUT UINTN *NumberOfBytes,\r
1672 OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,\r
1673 OUT VOID **Mapping\r
1674 )\r
21b404d1 1675{\r
1676 EFI_STATUS Status;\r
1677 EFI_PHYSICAL_ADDRESS PhysicalAddress;\r
1678 MAP_INFO *MapInfo;\r
1679\r
1680 if (HostAddress == NULL || NumberOfBytes == NULL || DeviceAddress == NULL || Mapping == NULL) {\r
1681 return EFI_INVALID_PARAMETER;\r
1682 }\r
1683 \r
1684 //\r
1685 // Initialize the return values to their defaults\r
1686 //\r
1687 *Mapping = NULL;\r
1688\r
1689 //\r
1690 // Make sure that Operation is valid\r
1691 //\r
1692 if (Operation < 0 || Operation >= EfiPciOperationMaximum) {\r
1693 return EFI_INVALID_PARAMETER;\r
1694 }\r
1695\r
1696 //\r
1697 // Most PCAT like chipsets can not handle performing DMA above 4GB.\r
1698 // If any part of the DMA transfer being mapped is above 4GB, then\r
1699 // map the DMA transfer to a buffer below 4GB.\r
1700 //\r
1701 PhysicalAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress;\r
1702 if ((PhysicalAddress + *NumberOfBytes) > 0x100000000ULL) {\r
1703\r
1704 //\r
1705 // Common Buffer operations can not be remapped. If the common buffer\r
1706 // if above 4GB, then it is not possible to generate a mapping, so return \r
1707 // an error.\r
1708 //\r
1709 if (Operation == EfiPciOperationBusMasterCommonBuffer || Operation == EfiPciOperationBusMasterCommonBuffer64) {\r
1710 return EFI_UNSUPPORTED;\r
1711 }\r
1712\r
1713 //\r
1714 // Allocate a MAP_INFO structure to remember the mapping when Unmap() is\r
1715 // called later.\r
1716 //\r
1717 Status = gBS->AllocatePool (\r
1718 EfiBootServicesData, \r
1719 sizeof(MAP_INFO), \r
1720 (VOID **)&MapInfo\r
1721 );\r
1722 if (EFI_ERROR (Status)) {\r
1723 *NumberOfBytes = 0;\r
1724 return Status;\r
1725 }\r
1726\r
1727 //\r
1728 // Return a pointer to the MAP_INFO structure in Mapping\r
1729 //\r
1730 *Mapping = MapInfo;\r
1731\r
1732 //\r
1733 // Initialize the MAP_INFO structure\r
1734 //\r
1735 MapInfo->Operation = Operation;\r
1736 MapInfo->NumberOfBytes = *NumberOfBytes;\r
1737 MapInfo->NumberOfPages = EFI_SIZE_TO_PAGES(*NumberOfBytes);\r
1738 MapInfo->HostAddress = PhysicalAddress;\r
1739 MapInfo->MappedHostAddress = 0x00000000ffffffff;\r
1740\r
1741 //\r
1742 // Allocate a buffer below 4GB to map the transfer to.\r
1743 //\r
1744 Status = gBS->AllocatePages (\r
1745 AllocateMaxAddress, \r
1746 EfiBootServicesData, \r
1747 MapInfo->NumberOfPages,\r
1748 &MapInfo->MappedHostAddress\r
1749 );\r
1750 if (EFI_ERROR (Status)) {\r
1751 gBS->FreePool (MapInfo);\r
1752 *NumberOfBytes = 0;\r
1753 return Status;\r
1754 }\r
1755\r
1756 //\r
1757 // If this is a read operation from the Bus Master's point of view,\r
1758 // then copy the contents of the real buffer into the mapped buffer\r
1759 // so the Bus Master can read the contents of the real buffer.\r
1760 //\r
1761 if (Operation == EfiPciOperationBusMasterRead || Operation == EfiPciOperationBusMasterRead64) {\r
1762 CopyMem (\r
1763 (VOID *)(UINTN)MapInfo->MappedHostAddress, \r
1764 (VOID *)(UINTN)MapInfo->HostAddress,\r
1765 MapInfo->NumberOfBytes\r
1766 );\r
1767 }\r
1768\r
1769 //\r
1770 // The DeviceAddress is the address of the maped buffer below 4GB\r
1771 //\r
1772 *DeviceAddress = MapInfo->MappedHostAddress;\r
1773 } else {\r
1774 //\r
1775 // The transfer is below 4GB, so the DeviceAddress is simply the HostAddress\r
1776 //\r
1777 *DeviceAddress = PhysicalAddress;\r
1778 }\r
1779\r
1780 return EFI_SUCCESS;\r
1781}\r
1782\r
18c97f53 1783/**\r
1784 Completes the Map() operation and releases any corresponding resources.\r
1785\r
1786 The Unmap() function completes the Map() operation and releases any corresponding resources.\r
1787 If the operation was an EfiPciOperationBusMasterWrite or\r
1788 EfiPciOperationBusMasterWrite64, the data is committed to the target system memory.\r
1789 Any resources used for the mapping are freed. \r
1790\r
1791 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
1792 @param[in] Mapping The mapping value returned from Map().\r
1793 \r
1794 @retval EFI_SUCCESS The range was unmapped.\r
1795 @retval EFI_INVALID_PARAMETER Mapping is not a value that was returned by Map().\r
1796 @retval EFI_DEVICE_ERROR The data was not committed to the target system memory.\r
1797\r
1798**/\r
21b404d1 1799EFI_STATUS\r
1800EFIAPI\r
1801RootBridgeIoUnmap (\r
1802 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
1803 IN VOID *Mapping\r
1804 )\r
21b404d1 1805{\r
1806 MAP_INFO *MapInfo;\r
1807\r
1808 //\r
1809 // See if the Map() operation associated with this Unmap() required a mapping buffer.\r
1810 // If a mapping buffer was not required, then this function simply returns EFI_SUCCESS.\r
1811 //\r
1812 if (Mapping != NULL) {\r
1813 //\r
1814 // Get the MAP_INFO structure from Mapping\r
1815 //\r
1816 MapInfo = (MAP_INFO *)Mapping;\r
1817\r
1818 //\r
1819 // If this is a write operation from the Bus Master's point of view,\r
1820 // then copy the contents of the mapped buffer into the real buffer\r
1821 // so the processor can read the contents of the real buffer.\r
1822 //\r
1823 if (MapInfo->Operation == EfiPciOperationBusMasterWrite || MapInfo->Operation == EfiPciOperationBusMasterWrite64) {\r
1824 CopyMem (\r
1825 (VOID *)(UINTN)MapInfo->HostAddress, \r
1826 (VOID *)(UINTN)MapInfo->MappedHostAddress,\r
1827 MapInfo->NumberOfBytes\r
1828 );\r
1829 }\r
1830\r
1831 //\r
1832 // Free the mapped buffer and the MAP_INFO structure.\r
1833 //\r
1834 gBS->FreePages (MapInfo->MappedHostAddress, MapInfo->NumberOfPages);\r
1835 gBS->FreePool (Mapping);\r
1836 }\r
1837 return EFI_SUCCESS;\r
1838}\r
1839\r
18c97f53 1840/**\r
1841 Allocates pages that are suitable for an EfiPciOperationBusMasterCommonBuffer or\r
1842 EfiPciOperationBusMasterCommonBuffer64 mapping.\r
1843 \r
1844 @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
1845 @param Type This parameter is not used and must be ignored.\r
1846 @param MemoryType The type of memory to allocate, EfiBootServicesData or EfiRuntimeServicesData.\r
1847 @param Pages The number of pages to allocate.\r
1848 @param HostAddress A pointer to store the base system memory address of the allocated range.\r
1849 @param Attributes The requested bit mask of attributes for the allocated range. Only\r
1850 the attributes EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE, EFI_PCI_ATTRIBUTE_MEMORY_CACHED, \r
1851 and EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE may be used with this function.\r
1852 \r
1853 @retval EFI_SUCCESS The requested memory pages were allocated.\r
1854 @retval EFI_INVALID_PARAMETER MemoryType is invalid.\r
1855 @retval EFI_INVALID_PARAMETER HostAddress is NULL.\r
1856 @retval EFI_UNSUPPORTED Attributes is unsupported. The only legal attribute bits are\r
1857 MEMORY_WRITE_COMBINE, MEMORY_CACHED, and DUAL_ADDRESS_CYCLE.\r
1858 @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated.\r
1859\r
1860**/\r
21b404d1 1861EFI_STATUS\r
1862EFIAPI\r
1863RootBridgeIoAllocateBuffer (\r
1864 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
1865 IN EFI_ALLOCATE_TYPE Type,\r
1866 IN EFI_MEMORY_TYPE MemoryType,\r
1867 IN UINTN Pages,\r
1868 OUT VOID **HostAddress,\r
1869 IN UINT64 Attributes\r
1870 )\r
21b404d1 1871{\r
1872 EFI_STATUS Status;\r
1873 EFI_PHYSICAL_ADDRESS PhysicalAddress;\r
1874\r
1875 //\r
1876 // Validate Attributes\r
1877 //\r
24115e44 1878 if ((Attributes & EFI_PCI_ATTRIBUTE_INVALID_FOR_ALLOCATE_BUFFER) != 0) {\r
21b404d1 1879 return EFI_UNSUPPORTED;\r
1880 }\r
1881\r
1882 //\r
1883 // Check for invalid inputs\r
1884 //\r
1885 if (HostAddress == NULL) {\r
1886 return EFI_INVALID_PARAMETER;\r
1887 }\r
1888 \r
1889 //\r
1890 // The only valid memory types are EfiBootServicesData and EfiRuntimeServicesData\r
1891 //\r
1892 if (MemoryType != EfiBootServicesData && MemoryType != EfiRuntimeServicesData) {\r
1893 return EFI_INVALID_PARAMETER;\r
1894 }\r
1895\r
1896 //\r
1897 // Limit allocations to memory below 4GB\r
1898 //\r
1899 PhysicalAddress = (EFI_PHYSICAL_ADDRESS)(0xffffffff);\r
1900\r
1901 Status = gBS->AllocatePages (AllocateMaxAddress, MemoryType, Pages, &PhysicalAddress);\r
1902 if (EFI_ERROR (Status)) {\r
1903 return Status;\r
1904 }\r
1905\r
1906 *HostAddress = (VOID *)(UINTN)PhysicalAddress;\r
1907\r
1908 return EFI_SUCCESS;\r
1909}\r
1910\r
18c97f53 1911/**\r
1912 Frees memory that was allocated with AllocateBuffer().\r
1913\r
1914 The FreeBuffer() function frees memory that was allocated with AllocateBuffer().\r
1915\r
1916 @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
1917 @param Pages The number of pages to free.\r
1918 @param HostAddress The base system memory address of the allocated range.\r
1919 \r
1920 @retval EFI_SUCCESS The requested memory pages were freed.\r
1921 @retval EFI_INVALID_PARAMETER The memory range specified by HostAddress and Pages\r
1922 was not allocated with AllocateBuffer().\r
1923\r
1924**/\r
21b404d1 1925EFI_STATUS\r
1926EFIAPI\r
1927RootBridgeIoFreeBuffer (\r
1928 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
1929 IN UINTN Pages,\r
1930 OUT VOID *HostAddress\r
1931 )\r
21b404d1 1932{\r
1933 return gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress, Pages);\r
1934}\r
1935\r
18c97f53 1936/**\r
1937 Flushes all PCI posted write transactions from a PCI host bridge to system memory.\r
1938\r
1939 The Flush() function flushes any PCI posted write transactions from a PCI host bridge to system\r
1940 memory. Posted write transactions are generated by PCI bus masters when they perform write\r
1941 transactions to target addresses in system memory.\r
1942 This function does not flush posted write transactions from any PCI bridges. A PCI controller\r
1943 specific action must be taken to guarantee that the posted write transactions have been flushed from\r
1944 the PCI controller and from all the PCI bridges into the PCI host bridge. This is typically done with\r
1945 a PCI read transaction from the PCI controller prior to calling Flush().\r
1946\r
1947 @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
1948 \r
1949 @retval EFI_SUCCESS The PCI posted write transactions were flushed from the PCI host\r
1950 bridge to system memory.\r
1951 @retval EFI_DEVICE_ERROR The PCI posted write transactions were not flushed from the PCI\r
1952 host bridge due to a hardware error.\r
1953\r
1954**/\r
21b404d1 1955EFI_STATUS\r
1956EFIAPI\r
1957RootBridgeIoFlush (\r
1958 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This\r
1959 )\r
21b404d1 1960{\r
1961 //\r
1962 // not supported yet\r
1963 //\r
1964 return EFI_SUCCESS;\r
1965}\r
1966\r
18c97f53 1967/**\r
1968 Gets the attributes that a PCI root bridge supports setting with SetAttributes(), and the\r
1969 attributes that a PCI root bridge is currently using. \r
1970\r
1971 The GetAttributes() function returns the mask of attributes that this PCI root bridge supports\r
1972 and the mask of attributes that the PCI root bridge is currently using.\r
1973\r
1974 @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
1975 @param Supported A pointer to the mask of attributes that this PCI root bridge\r
1976 supports setting with SetAttributes().\r
1977 @param Attributes A pointer to the mask of attributes that this PCI root bridge is\r
1978 currently using.\r
1979 \r
1980 @retval EFI_SUCCESS If Supports is not NULL, then the attributes that the PCI root\r
1981 bridge supports is returned in Supports. If Attributes is\r
1982 not NULL, then the attributes that the PCI root bridge is currently\r
1983 using is returned in Attributes.\r
1984 @retval EFI_INVALID_PARAMETER Both Supports and Attributes are NULL.\r
1985\r
1986**/\r
21b404d1 1987EFI_STATUS\r
1988EFIAPI\r
1989RootBridgeIoGetAttributes (\r
1990 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
1991 OUT UINT64 *Supported,\r
1992 OUT UINT64 *Attributes\r
1993 )\r
21b404d1 1994{\r
1995 PCI_ROOT_BRIDGE_INSTANCE *PrivateData;\r
1996\r
1997 PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(This);\r
1998\r
1999 if (Attributes == NULL && Supported == NULL) {\r
2000 return EFI_INVALID_PARAMETER;\r
2001 }\r
2002\r
2003 //\r
2004 // Set the return value for Supported and Attributes\r
2005 //\r
24115e44 2006 if (Supported != NULL) {\r
21b404d1 2007 *Supported = PrivateData->Supports; \r
2008 }\r
2009\r
24115e44 2010 if (Attributes != NULL) {\r
21b404d1 2011 *Attributes = PrivateData->Attributes;\r
2012 }\r
2013 \r
2014 return EFI_SUCCESS;\r
2015}\r
2016\r
18c97f53 2017/**\r
2018 Sets attributes for a resource range on a PCI root bridge.\r
2019\r
2020 The SetAttributes() function sets the attributes specified in Attributes for the PCI root\r
2021 bridge on the resource range specified by ResourceBase and ResourceLength. Since the\r
2022 granularity of setting these attributes may vary from resource type to resource type, and from\r
2023 platform to platform, the actual resource range and the one passed in by the caller may differ. As a\r
2024 result, this function may set the attributes specified by Attributes on a larger resource range\r
2025 than the caller requested. The actual range is returned in ResourceBase and\r
2026 ResourceLength. The caller is responsible for verifying that the actual range for which the\r
2027 attributes were set is acceptable.\r
2028\r
2029 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
2030 @param[in] Attributes The mask of attributes to set. If the attribute bit\r
2031 MEMORY_WRITE_COMBINE, MEMORY_CACHED, or\r
2032 MEMORY_DISABLE is set, then the resource range is specified by\r
2033 ResourceBase and ResourceLength. If\r
2034 MEMORY_WRITE_COMBINE, MEMORY_CACHED, and\r
2035 MEMORY_DISABLE are not set, then ResourceBase and\r
2036 ResourceLength are ignored, and may be NULL.\r
24115e44 2037 @param[in, out] ResourceBase A pointer to the base address of the resource range to be modified\r
18c97f53 2038 by the attributes specified by Attributes.\r
24115e44 2039 @param[in, out] ResourceLength A pointer to the length of the resource range to be modified by the\r
18c97f53 2040 attributes specified by Attributes.\r
2041 \r
2042 @retval EFI_SUCCESS The current configuration of this PCI root bridge was returned in Resources.\r
2043 @retval EFI_UNSUPPORTED The current configuration of this PCI root bridge could not be retrieved.\r
2044 @retval EFI_INVALID_PARAMETER Invalid pointer of EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL\r
2045\r
2046**/\r
21b404d1 2047EFI_STATUS\r
2048EFIAPI\r
2049RootBridgeIoSetAttributes (\r
2050 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
2051 IN UINT64 Attributes,\r
2052 IN OUT UINT64 *ResourceBase,\r
2053 IN OUT UINT64 *ResourceLength \r
2054 )\r
21b404d1 2055{\r
2056 PCI_ROOT_BRIDGE_INSTANCE *PrivateData;\r
2057 \r
2058 PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(This);\r
2059 \r
24115e44 2060 if (Attributes != 0) {\r
21b404d1 2061 if ((Attributes & (~(PrivateData->Supports))) != 0) {\r
2062 return EFI_UNSUPPORTED;\r
2063 }\r
2064 }\r
2065 \r
2066 //\r
2067 // This is a generic driver for a PC-AT class system. It does not have any\r
2068 // chipset specific knowlegde, so none of the attributes can be set or \r
2069 // cleared. Any attempt to set attribute that are already set will succeed, \r
2070 // and any attempt to set an attribute that is not supported will fail.\r
2071 //\r
2072 if (Attributes & (~PrivateData->Attributes)) {\r
2073 return EFI_UNSUPPORTED;\r
2074 }\r
2075\r
2076 return EFI_SUCCESS;\r
2077}\r
2078\r
18c97f53 2079/**\r
2080 Retrieves the current resource settings of this PCI root bridge in the form of a set of ACPI 2.0\r
2081 resource descriptors.\r
2082\r
2083 There are only two resource descriptor types from the ACPI Specification that may be used to\r
2084 describe the current resources allocated to a PCI root bridge. These are the QWORD Address\r
2085 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
2086 QWORD Address Space Descriptor can describe memory, I/O, and bus number ranges for dynamic\r
2087 or fixed resources. The configuration of a PCI root bridge is described with one or more QWORD\r
2088 Address Space Descriptors followed by an End Tag.\r
2089\r
2090 @param[in] This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
2091 @param[out] Resources A pointer to the ACPI 2.0 resource descriptors that describe the\r
2092 current configuration of this PCI root bridge. The storage for the\r
2093 ACPI 2.0 resource descriptors is allocated by this function. The\r
2094 caller must treat the return buffer as read-only data, and the buffer\r
2095 must not be freed by the caller.\r
2096 \r
2097 @retval EFI_SUCCESS The current configuration of this PCI root bridge was returned in Resources.\r
2098 @retval EFI_UNSUPPORTED The current configuration of this PCI root bridge could not be retrieved.\r
2099 @retval EFI_INVALID_PARAMETER Invalid pointer of EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL\r
2100\r
2101**/\r
21b404d1 2102EFI_STATUS\r
2103EFIAPI\r
2104RootBridgeIoConfiguration (\r
2105 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
2106 OUT VOID **Resources\r
2107 )\r
21b404d1 2108{\r
2109 PCI_ROOT_BRIDGE_INSTANCE *PrivateData;\r
2110 UINTN Index;\r
2111\r
2112 PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);\r
2113 \r
2114 for (Index = 0; Index < TypeMax; Index++) {\r
2115 if (PrivateData->ResAllocNode[Index].Status == ResAllocated) {\r
2116 Configuration.SpaceDesp[Index].AddrRangeMin = PrivateData->ResAllocNode[Index].Base;\r
2117 Configuration.SpaceDesp[Index].AddrRangeMax = PrivateData->ResAllocNode[Index].Base + PrivateData->ResAllocNode[Index].Length - 1;\r
2118 Configuration.SpaceDesp[Index].AddrLen = PrivateData->ResAllocNode[Index].Length;\r
2119 } \r
2120 } \r
2121 \r
2122 *Resources = &Configuration; \r
2123 return EFI_SUCCESS;\r
2124}\r
2125\r