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