]> git.proxmox.com Git - mirror_edk2.git/blame - MdePkg/Library/UefiPciSegmentLibPciRootBridgeIo/PciSegmentLib.c
Update the copyright notice format
[mirror_edk2.git] / MdePkg / Library / UefiPciSegmentLibPciRootBridgeIo / PciSegmentLib.c
CommitLineData
1a3eaf06 1/** @file\r
e43e4b3e 2 PCI Segment Library implementation using PCI Root Bridge I/O Protocol.\r
1a3eaf06 3\r
a0720bb8 4 Copyright (c) 2007 - 2010, Intel Corporation All rights\r
1a3eaf06 5 reserved. This program and the accompanying materials are\r
6 licensed and made available under the terms and conditions of\r
7 the BSD License which accompanies this distribution. The full\r
8 text of the license may be found at\r
9 http://opensource.org/licenses/bsd-license.php\r
10 \r
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13\r
14**/\r
15\r
16#include "PciSegmentLib.h"\r
17\r
18//\r
a0720bb8 19// Global variable to record data of PCI Root Bridge I/O Protocol instances\r
1a3eaf06 20//\r
21PCI_ROOT_BRIDGE_DATA *mPciRootBridgeData = NULL;\r
22UINTN mNumberOfPciRootBridges = 0;\r
23\r
24/**\r
a0720bb8 25 The constructor function caches data of PCI Root Bridge I/O Protocol instances.\r
1a3eaf06 26 \r
27 The constructor function locates PCI Root Bridge I/O protocol instances,\r
28 and caches the protocol instances, together with their segment numbers and bus ranges.\r
29 It will ASSERT() if that related operation fails and it will always return EFI_SUCCESS. \r
30\r
31 @param ImageHandle The firmware allocated handle for the EFI image.\r
32 @param SystemTable A pointer to the EFI System Table.\r
33 \r
34 @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.\r
35\r
36**/\r
37EFI_STATUS\r
38EFIAPI\r
39PciSegmentLibConstructor (\r
40 IN EFI_HANDLE ImageHandle,\r
41 IN EFI_SYSTEM_TABLE *SystemTable\r
42 )\r
43{\r
44 EFI_STATUS Status;\r
45 UINTN Index;\r
46 UINTN HandleCount;\r
47 EFI_HANDLE *HandleBuffer;\r
48 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo; \r
49 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors;\r
50\r
51 HandleCount = 0;\r
52 HandleBuffer = NULL;\r
53 PciRootBridgeIo = NULL;\r
54 Descriptors = NULL;\r
55\r
56 Status = gBS->LocateHandleBuffer (\r
57 ByProtocol,\r
58 &gEfiPciRootBridgeIoProtocolGuid,\r
59 NULL,\r
60 &HandleCount,\r
61 &HandleBuffer\r
62 );\r
63 ASSERT_EFI_ERROR (Status);\r
64\r
65 mNumberOfPciRootBridges = HandleCount;\r
66\r
67 mPciRootBridgeData = AllocatePool (HandleCount * sizeof (PCI_ROOT_BRIDGE_DATA));\r
68 ASSERT (mPciRootBridgeData != NULL);\r
69\r
70 //\r
71 // Traverse all PCI Root Bridge I/O Protocol instances, and record the protocol\r
72 // instances, together with their segment numbers and bus ranges.\r
73 //\r
74 for (Index = 0; Index < HandleCount; Index++) {\r
75 Status = gBS->HandleProtocol (\r
76 HandleBuffer[Index],\r
77 &gEfiPciRootBridgeIoProtocolGuid,\r
78 (VOID **) &PciRootBridgeIo\r
79 );\r
80 ASSERT_EFI_ERROR (Status);\r
81\r
82 mPciRootBridgeData[Index].PciRootBridgeIo = PciRootBridgeIo;\r
83 mPciRootBridgeData[Index].SegmentNumber = PciRootBridgeIo->SegmentNumber;\r
84\r
85 Status = PciRootBridgeIo->Configuration (PciRootBridgeIo, (VOID **) &Descriptors);\r
86 ASSERT_EFI_ERROR (Status);\r
87\r
88 while (Descriptors->Desc != ACPI_END_TAG_DESCRIPTOR) {\r
89 if (Descriptors->ResType == ACPI_ADDRESS_SPACE_TYPE_BUS) {\r
90 mPciRootBridgeData[Index].MinBusNumber = Descriptors->AddrRangeMin;\r
91 mPciRootBridgeData[Index].MaxBusNumber = Descriptors->AddrRangeMax;\r
92 break;\r
93 }\r
94 Descriptors++;\r
95 }\r
96 ASSERT (Descriptors->Desc != ACPI_END_TAG_DESCRIPTOR);\r
97 }\r
98\r
e43e4b3e 99 FreePool(HandleBuffer);\r
1a3eaf06 100\r
101 return EFI_SUCCESS;\r
102}\r
103\r
104/**\r
105 The destructor function frees memory allocated by constructor.\r
106 \r
107 The destructor function frees memory for data of protocol instances allocated by constructor.\r
108 It will ASSERT() if that related operation fails and it will always return EFI_SUCCESS. \r
109\r
110 @param ImageHandle The firmware allocated handle for the EFI image.\r
111 @param SystemTable A pointer to the EFI System Table.\r
112 \r
113 @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.\r
114\r
115**/\r
116EFI_STATUS\r
117EFIAPI\r
118PciSegmentLibDestructor (\r
119 IN EFI_HANDLE ImageHandle,\r
120 IN EFI_SYSTEM_TABLE *SystemTable\r
121 )\r
122{\r
123 FreePool (mPciRootBridgeData);\r
124\r
125 return EFI_SUCCESS;\r
126}\r
127\r
128/**\r
129 According to address, search for the corresponding PCI Root Bridge I/O Protocol instance.\r
130\r
131 This internal function extracts segment number and bus number data from address, and\r
132 retrieves the corresponding PCI Root Bridge I/O Protocol instance.\r
133\r
134 @param Address Address that encodes the Segment, PCI Bus, Device, Function and\r
135 Register.\r
136\r
137 @return The address for PCI Root Bridge I/O Protocol.\r
138\r
139**/\r
140EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *\r
141PciSegmentLibSearchForRootBridge (\r
142 IN UINT64 Address\r
143 )\r
144{\r
145 UINTN Index;\r
146 UINT64 SegmentNumber;\r
147 UINT64 BusNumber;\r
148\r
149 for (Index = 0; Index < mNumberOfPciRootBridges; Index++) {\r
150 //\r
151 // Matches segment number of address with the segment number of protocol instance.\r
152 //\r
153 SegmentNumber = BitFieldRead64 (Address, 32, 63);\r
154 if (SegmentNumber == mPciRootBridgeData[Index].SegmentNumber) {\r
155 //\r
156 // Matches the bus number of address with bus number range of protocol instance.\r
157 //\r
158 BusNumber = BitFieldRead64 (Address, 20, 27);\r
159 if (BusNumber >= mPciRootBridgeData[Index].MinBusNumber && BusNumber <= mPciRootBridgeData[Index].MaxBusNumber) {\r
160 return mPciRootBridgeData[Index].PciRootBridgeIo;\r
161 }\r
162 } \r
163 }\r
164 return NULL;\r
165}\r
166\r
167/**\r
168 Internal worker function to read a PCI configuration register.\r
169\r
170 This function wraps EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.Pci.Read() service.\r
171 It reads and returns the PCI configuration register specified by Address,\r
172 the width of data is specified by Width.\r
173\r
174 @param Address Address that encodes the PCI Bus, Device, Function and\r
175 Register.\r
176 @param Width Width of data to read\r
177\r
178 @return The value read from the PCI configuration register.\r
179\r
180**/\r
181UINT32\r
182DxePciSegmentLibPciRootBridgeIoReadWorker (\r
183 IN UINT64 Address,\r
184 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width\r
185 )\r
186{\r
187 UINT32 Data;\r
188 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo; \r
189\r
190 PciRootBridgeIo = PciSegmentLibSearchForRootBridge (Address);\r
191 ASSERT (PciRootBridgeIo != NULL);\r
192\r
193 PciRootBridgeIo->Pci.Read (\r
194 PciRootBridgeIo,\r
195 Width,\r
e43e4b3e 196 PCI_TO_PCI_ROOT_BRIDGE_IO_ADDRESS (Address),\r
1a3eaf06 197 1,\r
198 &Data\r
199 );\r
200\r
201 return Data;\r
202}\r
203\r
204/**\r
205 Internal worker function to writes a PCI configuration register.\r
206\r
207 This function wraps EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.Pci.Write() service.\r
208 It writes the PCI configuration register specified by Address with the\r
209 value specified by Data. The width of data is specifed by Width.\r
210 Data is returned.\r
211\r
212 @param Address Address that encodes the PCI Bus, Device, Function and\r
213 Register.\r
214 @param Width Width of data to write\r
215 @param Data The value to write.\r
216\r
217 @return The value written to the PCI configuration register.\r
218\r
219**/\r
220UINT32\r
221DxePciSegmentLibPciRootBridgeIoWriteWorker (\r
222 IN UINT64 Address,\r
223 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
224 IN UINT32 Data\r
225 )\r
226{\r
227 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo; \r
228\r
229 PciRootBridgeIo = PciSegmentLibSearchForRootBridge (Address);\r
230 ASSERT (PciRootBridgeIo != NULL);\r
231\r
232 PciRootBridgeIo->Pci.Write (\r
233 PciRootBridgeIo,\r
234 Width,\r
e43e4b3e 235 PCI_TO_PCI_ROOT_BRIDGE_IO_ADDRESS (Address),\r
1a3eaf06 236 1,\r
237 &Data\r
238 );\r
239\r
240 return Data;\r
241}\r
242\r
3e3ae634 243/**\r
244 Register a PCI device so PCI configuration registers may be accessed after \r
245 SetVirtualAddressMap().\r
246 \r
59ceeabe 247 If any reserved bits in Address are set, then ASSERT().\r
3e3ae634 248\r
249 @param Address Address that encodes the PCI Bus, Device, Function and\r
250 Register.\r
251 \r
252 @retval RETURN_SUCCESS The PCI device was registered for runtime access.\r
253 @retval RETURN_UNSUPPORTED An attempt was made to call this function \r
254 after ExitBootServices().\r
255 @retval RETURN_UNSUPPORTED The resources required to access the PCI device\r
256 at runtime could not be mapped.\r
257 @retval RETURN_OUT_OF_RESOURCES There are not enough resources available to\r
258 complete the registration.\r
259\r
260**/\r
261RETURN_STATUS\r
262EFIAPI\r
263PciSegmentRegisterForRuntimeAccess (\r
264 IN UINTN Address\r
265 )\r
266{\r
59ceeabe 267 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 0);\r
3e3ae634 268 return RETURN_UNSUPPORTED;\r
269}\r
270\r
1a3eaf06 271/**\r
272 Reads an 8-bit PCI configuration register.\r
273\r
274 Reads and returns the 8-bit PCI configuration register specified by Address.\r
070a76b1 275 This function must guarantee that all PCI read and write operations are serialized.\r
276 \r
1a3eaf06 277 If any reserved bits in Address are set, then ASSERT().\r
070a76b1 278 \r
279 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.\r
1a3eaf06 280\r
070a76b1 281 @return The 8-bit PCI configuration register specified by Address.\r
1a3eaf06 282\r
283**/\r
284UINT8\r
285EFIAPI\r
286PciSegmentRead8 (\r
070a76b1 287 IN UINT64 Address\r
1a3eaf06 288 )\r
289{\r
290 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 0);\r
291\r
292 return (UINT8) DxePciSegmentLibPciRootBridgeIoReadWorker (Address, EfiPciWidthUint8);\r
293}\r
294\r
295/**\r
296 Writes an 8-bit PCI configuration register.\r
297\r
070a76b1 298 Writes the 8-bit PCI configuration register specified by Address with the value specified by Value.\r
299 Value is returned. This function must guarantee that all PCI read and write operations are serialized.\r
300 \r
59ceeabe 301 If any reserved bits in Address are set, then ASSERT().\r
1a3eaf06 302\r
070a76b1 303 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.\r
304 @param Value The value to write.\r
1a3eaf06 305\r
306 @return The value written to the PCI configuration register.\r
307\r
308**/\r
309UINT8\r
310EFIAPI\r
311PciSegmentWrite8 (\r
070a76b1 312 IN UINT64 Address,\r
313 IN UINT8 Value\r
1a3eaf06 314 )\r
315{\r
316 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 0);\r
317\r
070a76b1 318 return (UINT8) DxePciSegmentLibPciRootBridgeIoWriteWorker (Address, EfiPciWidthUint8, Value);\r
1a3eaf06 319}\r
320\r
321/**\r
070a76b1 322 Performs a bitwise OR of an 8-bit PCI configuration register with an 8-bit value.\r
1a3eaf06 323\r
070a76b1 324 Reads the 8-bit PCI configuration register specified by Address,\r
325 performs a bitwise OR between the read result and the value specified by OrData,\r
326 and writes the result to the 8-bit PCI configuration register specified by Address.\r
327 The value written to the PCI configuration register is returned.\r
328 This function must guarantee that all PCI read and write operations are serialized.\r
329 \r
1a3eaf06 330 If any reserved bits in Address are set, then ASSERT().\r
331\r
070a76b1 332 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.\r
333 @param OrData The value to OR with the PCI configuration register.\r
1a3eaf06 334\r
070a76b1 335 @return The value written to the PCI configuration register.\r
1a3eaf06 336\r
337**/\r
338UINT8\r
339EFIAPI\r
340PciSegmentOr8 (\r
070a76b1 341 IN UINT64 Address,\r
342 IN UINT8 OrData\r
1a3eaf06 343 )\r
344{\r
345 return PciSegmentWrite8 (Address, (UINT8) (PciSegmentRead8 (Address) | OrData));\r
346}\r
347\r
348/**\r
070a76b1 349 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit value.\r
1a3eaf06 350\r
070a76b1 351 Reads the 8-bit PCI configuration register specified by Address,\r
352 performs a bitwise AND between the read result and the value specified by AndData,\r
353 and writes the result to the 8-bit PCI configuration register specified by Address.\r
354 The value written to the PCI configuration register is returned.\r
355 This function must guarantee that all PCI read and write operations are serialized.\r
1a3eaf06 356 If any reserved bits in Address are set, then ASSERT().\r
357\r
070a76b1 358 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.\r
359 @param AndData The value to AND with the PCI configuration register.\r
1a3eaf06 360\r
070a76b1 361 @return The value written to the PCI configuration register.\r
1a3eaf06 362\r
363**/\r
364UINT8\r
365EFIAPI\r
366PciSegmentAnd8 (\r
070a76b1 367 IN UINT64 Address,\r
368 IN UINT8 AndData\r
1a3eaf06 369 )\r
370{\r
371 return PciSegmentWrite8 (Address, (UINT8) (PciSegmentRead8 (Address) & AndData));\r
372}\r
373\r
374/**\r
070a76b1 375 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit value,\r
376 followed a bitwise OR with another 8-bit value.\r
377 \r
378 Reads the 8-bit PCI configuration register specified by Address,\r
379 performs a bitwise AND between the read result and the value specified by AndData,\r
380 performs a bitwise OR between the result of the AND operation and the value specified by OrData,\r
381 and writes the result to the 8-bit PCI configuration register specified by Address.\r
382 The value written to the PCI configuration register is returned.\r
383 This function must guarantee that all PCI read and write operations are serialized.\r
384 \r
1a3eaf06 385 If any reserved bits in Address are set, then ASSERT().\r
386\r
070a76b1 387 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.\r
388 @param AndData The value to AND with the PCI configuration register.\r
389 @param OrData The value to OR with the PCI configuration register.\r
1a3eaf06 390\r
070a76b1 391 @return The value written to the PCI configuration register.\r
1a3eaf06 392\r
393**/\r
394UINT8\r
395EFIAPI\r
396PciSegmentAndThenOr8 (\r
070a76b1 397 IN UINT64 Address,\r
398 IN UINT8 AndData,\r
399 IN UINT8 OrData\r
1a3eaf06 400 )\r
401{\r
402 return PciSegmentWrite8 (Address, (UINT8) ((PciSegmentRead8 (Address) & AndData) | OrData));\r
403}\r
404\r
405/**\r
406 Reads a bit field of a PCI configuration register.\r
407\r
408 Reads the bit field in an 8-bit PCI configuration register. The bit field is\r
409 specified by the StartBit and the EndBit. The value of the bit field is\r
410 returned.\r
411\r
412 If any reserved bits in Address are set, then ASSERT().\r
413 If StartBit is greater than 7, then ASSERT().\r
414 If EndBit is greater than 7, then ASSERT().\r
415 If EndBit is less than StartBit, then ASSERT().\r
416\r
417 @param Address PCI configuration register to read.\r
418 @param StartBit The ordinal of the least significant bit in the bit field.\r
419 Range 0..7.\r
420 @param EndBit The ordinal of the most significant bit in the bit field.\r
421 Range 0..7.\r
422\r
423 @return The value of the bit field read from the PCI configuration register.\r
424\r
425**/\r
426UINT8\r
427EFIAPI\r
428PciSegmentBitFieldRead8 (\r
070a76b1 429 IN UINT64 Address,\r
430 IN UINTN StartBit,\r
431 IN UINTN EndBit\r
1a3eaf06 432 )\r
433{\r
434 return BitFieldRead8 (PciSegmentRead8 (Address), StartBit, EndBit);\r
435}\r
436\r
437/**\r
438 Writes a bit field to a PCI configuration register.\r
439\r
440 Writes Value to the bit field of the PCI configuration register. The bit\r
441 field is specified by the StartBit and the EndBit. All other bits in the\r
442 destination PCI configuration register are preserved. The new value of the\r
443 8-bit register is returned.\r
444\r
445 If any reserved bits in Address are set, then ASSERT().\r
446 If StartBit is greater than 7, then ASSERT().\r
447 If EndBit is greater than 7, then ASSERT().\r
448 If EndBit is less than StartBit, then ASSERT().\r
449\r
450 @param Address PCI configuration register to write.\r
451 @param StartBit The ordinal of the least significant bit in the bit field.\r
452 Range 0..7.\r
453 @param EndBit The ordinal of the most significant bit in the bit field.\r
454 Range 0..7.\r
455 @param Value New value of the bit field.\r
456\r
457 @return The value written back to the PCI configuration register.\r
458\r
459**/\r
460UINT8\r
461EFIAPI\r
462PciSegmentBitFieldWrite8 (\r
070a76b1 463 IN UINT64 Address,\r
464 IN UINTN StartBit,\r
465 IN UINTN EndBit,\r
466 IN UINT8 Value\r
1a3eaf06 467 )\r
468{\r
469 return PciSegmentWrite8 (\r
470 Address,\r
471 BitFieldWrite8 (PciSegmentRead8 (Address), StartBit, EndBit, Value)\r
472 );\r
473}\r
474\r
475/**\r
476 Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and\r
477 writes the result back to the bit field in the 8-bit port.\r
478\r
479 Reads the 8-bit PCI configuration register specified by Address, performs a\r
62991af2 480 bitwise OR between the read result and the value specified by\r
1a3eaf06 481 OrData, and writes the result to the 8-bit PCI configuration register\r
482 specified by Address. The value written to the PCI configuration register is\r
483 returned. This function must guarantee that all PCI read and write operations\r
484 are serialized. Extra left bits in OrData are stripped.\r
485\r
486 If any reserved bits in Address are set, then ASSERT().\r
487 If StartBit is greater than 7, then ASSERT().\r
488 If EndBit is greater than 7, then ASSERT().\r
489 If EndBit is less than StartBit, then ASSERT().\r
490\r
491 @param Address PCI configuration register to write.\r
492 @param StartBit The ordinal of the least significant bit in the bit field.\r
493 Range 0..7.\r
494 @param EndBit The ordinal of the most significant bit in the bit field.\r
495 Range 0..7.\r
496 @param OrData The value to OR with the PCI configuration register.\r
497\r
498 @return The value written back to the PCI configuration register.\r
499\r
500**/\r
501UINT8\r
502EFIAPI\r
503PciSegmentBitFieldOr8 (\r
070a76b1 504 IN UINT64 Address,\r
505 IN UINTN StartBit,\r
506 IN UINTN EndBit,\r
507 IN UINT8 OrData\r
1a3eaf06 508 )\r
509{\r
510 return PciSegmentWrite8 (\r
511 Address,\r
512 BitFieldOr8 (PciSegmentRead8 (Address), StartBit, EndBit, OrData)\r
513 );\r
514}\r
515\r
516/**\r
517 Reads a bit field in an 8-bit PCI configuration register, performs a bitwise\r
518 AND, and writes the result back to the bit field in the 8-bit register.\r
519\r
520 Reads the 8-bit PCI configuration register specified by Address, performs a\r
521 bitwise AND between the read result and the value specified by AndData, and\r
522 writes the result to the 8-bit PCI configuration register specified by\r
523 Address. The value written to the PCI configuration register is returned.\r
524 This function must guarantee that all PCI read and write operations are\r
525 serialized. Extra left bits in AndData are stripped.\r
526\r
527 If any reserved bits in Address are set, then ASSERT().\r
528 If StartBit is greater than 7, then ASSERT().\r
529 If EndBit is greater than 7, then ASSERT().\r
530 If EndBit is less than StartBit, then ASSERT().\r
531\r
532 @param Address PCI configuration register to write.\r
533 @param StartBit The ordinal of the least significant bit in the bit field.\r
534 Range 0..7.\r
535 @param EndBit The ordinal of the most significant bit in the bit field.\r
536 Range 0..7.\r
537 @param AndData The value to AND with the PCI configuration register.\r
538\r
539 @return The value written back to the PCI configuration register.\r
540\r
541**/\r
542UINT8\r
543EFIAPI\r
544PciSegmentBitFieldAnd8 (\r
070a76b1 545 IN UINT64 Address,\r
546 IN UINTN StartBit,\r
547 IN UINTN EndBit,\r
548 IN UINT8 AndData\r
1a3eaf06 549 )\r
550{\r
551 return PciSegmentWrite8 (\r
552 Address,\r
553 BitFieldAnd8 (PciSegmentRead8 (Address), StartBit, EndBit, AndData)\r
554 );\r
555}\r
556\r
557/**\r
558 Reads a bit field in an 8-bit port, performs a bitwise AND followed by a\r
62991af2 559 bitwise OR, and writes the result back to the bit field in the\r
1a3eaf06 560 8-bit port.\r
561\r
562 Reads the 8-bit PCI configuration register specified by Address, performs a\r
62991af2 563 bitwise AND followed by a bitwise OR between the read result and\r
1a3eaf06 564 the value specified by AndData, and writes the result to the 8-bit PCI\r
565 configuration register specified by Address. The value written to the PCI\r
566 configuration register is returned. This function must guarantee that all PCI\r
567 read and write operations are serialized. Extra left bits in both AndData and\r
568 OrData are stripped.\r
569\r
570 If any reserved bits in Address are set, then ASSERT().\r
571 If StartBit is greater than 7, then ASSERT().\r
572 If EndBit is greater than 7, then ASSERT().\r
573 If EndBit is less than StartBit, then ASSERT().\r
574\r
575 @param Address PCI configuration register to write.\r
576 @param StartBit The ordinal of the least significant bit in the bit field.\r
577 Range 0..7.\r
578 @param EndBit The ordinal of the most significant bit in the bit field.\r
579 Range 0..7.\r
580 @param AndData The value to AND with the PCI configuration register.\r
581 @param OrData The value to OR with the result of the AND operation.\r
582\r
583 @return The value written back to the PCI configuration register.\r
584\r
585**/\r
586UINT8\r
587EFIAPI\r
588PciSegmentBitFieldAndThenOr8 (\r
070a76b1 589 IN UINT64 Address,\r
590 IN UINTN StartBit,\r
591 IN UINTN EndBit,\r
592 IN UINT8 AndData,\r
593 IN UINT8 OrData\r
1a3eaf06 594 )\r
595{\r
596 return PciSegmentWrite8 (\r
597 Address,\r
598 BitFieldAndThenOr8 (PciSegmentRead8 (Address), StartBit, EndBit, AndData, OrData)\r
599 );\r
600}\r
601\r
602/**\r
603 Reads a 16-bit PCI configuration register.\r
604\r
605 Reads and returns the 16-bit PCI configuration register specified by Address.\r
070a76b1 606 This function must guarantee that all PCI read and write operations are serialized.\r
607 \r
1a3eaf06 608 If any reserved bits in Address are set, then ASSERT().\r
070a76b1 609 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
610 \r
611 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.\r
1a3eaf06 612\r
070a76b1 613 @return The 16-bit PCI configuration register specified by Address.\r
1a3eaf06 614\r
615**/\r
616UINT16\r
617EFIAPI\r
618PciSegmentRead16 (\r
070a76b1 619 IN UINT64 Address\r
1a3eaf06 620 )\r
621{\r
622 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 1);\r
623\r
624 return (UINT16) DxePciSegmentLibPciRootBridgeIoReadWorker (Address, EfiPciWidthUint16);\r
625}\r
626\r
627/**\r
628 Writes a 16-bit PCI configuration register.\r
629\r
070a76b1 630 Writes the 16-bit PCI configuration register specified by Address with the value specified by Value.\r
631 Value is returned. This function must guarantee that all PCI read and write operations are serialized.\r
632 \r
1a3eaf06 633 If any reserved bits in Address are set, then ASSERT().\r
070a76b1 634 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
1a3eaf06 635\r
070a76b1 636 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.\r
637 @param Value The value to write.\r
1a3eaf06 638\r
070a76b1 639 @return The parameter of Value.\r
1a3eaf06 640\r
641**/\r
642UINT16\r
643EFIAPI\r
644PciSegmentWrite16 (\r
070a76b1 645 IN UINT64 Address,\r
646 IN UINT16 Value\r
1a3eaf06 647 )\r
648{\r
649 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 1);\r
650\r
070a76b1 651 return (UINT16) DxePciSegmentLibPciRootBridgeIoWriteWorker (Address, EfiPciWidthUint16, Value);\r
1a3eaf06 652}\r
653\r
654/**\r
62991af2 655 Performs a bitwise OR of a 16-bit PCI configuration register with\r
1a3eaf06 656 a 16-bit value.\r
657\r
658 Reads the 16-bit PCI configuration register specified by Address, performs a\r
62991af2 659 bitwise OR between the read result and the value specified by\r
1a3eaf06 660 OrData, and writes the result to the 16-bit PCI configuration register\r
661 specified by Address. The value written to the PCI configuration register is\r
662 returned. This function must guarantee that all PCI read and write operations\r
663 are serialized.\r
664\r
665 If any reserved bits in Address are set, then ASSERT().\r
070a76b1 666 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
1a3eaf06 667\r
668 @param Address Address that encodes the PCI Segment, Bus, Device, Function and\r
669 Register.\r
670 @param OrData The value to OR with the PCI configuration register.\r
671\r
672 @return The value written back to the PCI configuration register.\r
673\r
674**/\r
675UINT16\r
676EFIAPI\r
677PciSegmentOr16 (\r
070a76b1 678 IN UINT64 Address,\r
679 IN UINT16 OrData\r
1a3eaf06 680 )\r
681{\r
682 return PciSegmentWrite16 (Address, (UINT16) (PciSegmentRead16 (Address) | OrData));\r
683}\r
684\r
685/**\r
070a76b1 686 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit value.\r
1a3eaf06 687\r
070a76b1 688 Reads the 16-bit PCI configuration register specified by Address,\r
689 performs a bitwise AND between the read result and the value specified by AndData,\r
690 and writes the result to the 16-bit PCI configuration register specified by Address.\r
691 The value written to the PCI configuration register is returned.\r
692 This function must guarantee that all PCI read and write operations are serialized.\r
693 \r
1a3eaf06 694 If any reserved bits in Address are set, then ASSERT().\r
070a76b1 695 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
696 \r
697 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.\r
698 @param AndData The value to AND with the PCI configuration register.\r
1a3eaf06 699\r
070a76b1 700 @return The value written to the PCI configuration register.\r
1a3eaf06 701\r
702**/\r
703UINT16\r
704EFIAPI\r
705PciSegmentAnd16 (\r
070a76b1 706 IN UINT64 Address,\r
707 IN UINT16 AndData\r
1a3eaf06 708 )\r
709{\r
710 return PciSegmentWrite16 (Address, (UINT16) (PciSegmentRead16 (Address) & AndData));\r
711}\r
712\r
713/**\r
070a76b1 714 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit value,\r
715 followed a bitwise OR with another 16-bit value.\r
716 \r
717 Reads the 16-bit PCI configuration register specified by Address,\r
718 performs a bitwise AND between the read result and the value specified by AndData,\r
719 performs a bitwise OR between the result of the AND operation and the value specified by OrData,\r
720 and writes the result to the 16-bit PCI configuration register specified by Address.\r
721 The value written to the PCI configuration register is returned.\r
722 This function must guarantee that all PCI read and write operations are serialized.\r
723 \r
1a3eaf06 724 If any reserved bits in Address are set, then ASSERT().\r
070a76b1 725 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
1a3eaf06 726\r
070a76b1 727 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.\r
728 @param AndData The value to AND with the PCI configuration register.\r
729 @param OrData The value to OR with the PCI configuration register.\r
1a3eaf06 730\r
070a76b1 731 @return The value written to the PCI configuration register.\r
1a3eaf06 732\r
733**/\r
734UINT16\r
735EFIAPI\r
736PciSegmentAndThenOr16 (\r
070a76b1 737 IN UINT64 Address,\r
738 IN UINT16 AndData,\r
739 IN UINT16 OrData\r
1a3eaf06 740 )\r
741{\r
742 return PciSegmentWrite16 (Address, (UINT16) ((PciSegmentRead16 (Address) & AndData) | OrData));\r
743}\r
744\r
745/**\r
746 Reads a bit field of a PCI configuration register.\r
747\r
748 Reads the bit field in a 16-bit PCI configuration register. The bit field is\r
749 specified by the StartBit and the EndBit. The value of the bit field is\r
750 returned.\r
751\r
752 If any reserved bits in Address are set, then ASSERT().\r
070a76b1 753 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
1a3eaf06 754 If StartBit is greater than 15, then ASSERT().\r
755 If EndBit is greater than 15, then ASSERT().\r
756 If EndBit is less than StartBit, then ASSERT().\r
757\r
758 @param Address PCI configuration register to read.\r
759 @param StartBit The ordinal of the least significant bit in the bit field.\r
760 Range 0..15.\r
761 @param EndBit The ordinal of the most significant bit in the bit field.\r
762 Range 0..15.\r
763\r
764 @return The value of the bit field read from the PCI configuration register.\r
765\r
766**/\r
767UINT16\r
768EFIAPI\r
769PciSegmentBitFieldRead16 (\r
070a76b1 770 IN UINT64 Address,\r
771 IN UINTN StartBit,\r
772 IN UINTN EndBit\r
1a3eaf06 773 )\r
774{\r
775 return BitFieldRead16 (PciSegmentRead16 (Address), StartBit, EndBit);\r
776}\r
777\r
778/**\r
779 Writes a bit field to a PCI configuration register.\r
780\r
781 Writes Value to the bit field of the PCI configuration register. The bit\r
782 field is specified by the StartBit and the EndBit. All other bits in the\r
783 destination PCI configuration register are preserved. The new value of the\r
784 16-bit register is returned.\r
785\r
786 If any reserved bits in Address are set, then ASSERT().\r
070a76b1 787 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
1a3eaf06 788 If StartBit is greater than 15, then ASSERT().\r
789 If EndBit is greater than 15, then ASSERT().\r
790 If EndBit is less than StartBit, then ASSERT().\r
791\r
792 @param Address PCI configuration register to write.\r
793 @param StartBit The ordinal of the least significant bit in the bit field.\r
794 Range 0..15.\r
795 @param EndBit The ordinal of the most significant bit in the bit field.\r
796 Range 0..15.\r
797 @param Value New value of the bit field.\r
798\r
799 @return The value written back to the PCI configuration register.\r
800\r
801**/\r
802UINT16\r
803EFIAPI\r
804PciSegmentBitFieldWrite16 (\r
070a76b1 805 IN UINT64 Address,\r
806 IN UINTN StartBit,\r
807 IN UINTN EndBit,\r
808 IN UINT16 Value\r
1a3eaf06 809 )\r
810{\r
811 return PciSegmentWrite16 (\r
812 Address,\r
813 BitFieldWrite16 (PciSegmentRead16 (Address), StartBit, EndBit, Value)\r
814 );\r
815}\r
816\r
817/**\r
070a76b1 818 Reads the 16-bit PCI configuration register specified by Address,\r
819 performs a bitwise OR between the read result and the value specified by OrData,\r
820 and writes the result to the 16-bit PCI configuration register specified by Address. \r
1a3eaf06 821\r
822 If any reserved bits in Address are set, then ASSERT().\r
070a76b1 823 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
1a3eaf06 824 If StartBit is greater than 15, then ASSERT().\r
825 If EndBit is greater than 15, then ASSERT().\r
826 If EndBit is less than StartBit, then ASSERT().\r
827\r
828 @param Address PCI configuration register to write.\r
829 @param StartBit The ordinal of the least significant bit in the bit field.\r
830 Range 0..15.\r
831 @param EndBit The ordinal of the most significant bit in the bit field.\r
832 Range 0..15.\r
833 @param OrData The value to OR with the PCI configuration register.\r
834\r
835 @return The value written back to the PCI configuration register.\r
836\r
837**/\r
838UINT16\r
839EFIAPI\r
840PciSegmentBitFieldOr16 (\r
070a76b1 841 IN UINT64 Address,\r
842 IN UINTN StartBit,\r
843 IN UINTN EndBit,\r
844 IN UINT16 OrData\r
1a3eaf06 845 )\r
846{\r
847 return PciSegmentWrite16 (\r
848 Address,\r
849 BitFieldOr16 (PciSegmentRead16 (Address), StartBit, EndBit, OrData)\r
850 );\r
851}\r
852\r
853/**\r
070a76b1 854 Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR,\r
855 and writes the result back to the bit field in the 16-bit port.\r
856\r
857 Reads the 16-bit PCI configuration register specified by Address,\r
858 performs a bitwise OR between the read result and the value specified by OrData,\r
859 and writes the result to the 16-bit PCI configuration register specified by Address.\r
860 The value written to the PCI configuration register is returned.\r
861 This function must guarantee that all PCI read and write operations are serialized.\r
862 Extra left bits in OrData are stripped.\r
863 \r
1a3eaf06 864 If any reserved bits in Address are set, then ASSERT().\r
070a76b1 865 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
866 If StartBit is greater than 7, then ASSERT().\r
867 If EndBit is greater than 7, then ASSERT().\r
1a3eaf06 868 If EndBit is less than StartBit, then ASSERT().\r
869\r
070a76b1 870 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.\r
1a3eaf06 871 @param StartBit The ordinal of the least significant bit in the bit field.\r
070a76b1 872 The ordinal of the least significant bit in a byte is bit 0.\r
1a3eaf06 873 @param EndBit The ordinal of the most significant bit in the bit field.\r
070a76b1 874 The ordinal of the most significant bit in a byte is bit 7.\r
875 @param AndData The value to AND with the read value from the PCI configuration register.\r
1a3eaf06 876\r
070a76b1 877 @return The value written to the PCI configuration register.\r
1a3eaf06 878\r
879**/\r
880UINT16\r
881EFIAPI\r
882PciSegmentBitFieldAnd16 (\r
070a76b1 883 IN UINT64 Address,\r
884 IN UINTN StartBit,\r
885 IN UINTN EndBit,\r
886 IN UINT16 AndData\r
1a3eaf06 887 )\r
888{\r
889 return PciSegmentWrite16 (\r
890 Address,\r
891 BitFieldAnd16 (PciSegmentRead16 (Address), StartBit, EndBit, AndData)\r
892 );\r
893}\r
894\r
895/**\r
896 Reads a bit field in a 16-bit port, performs a bitwise AND followed by a\r
62991af2 897 bitwise OR, and writes the result back to the bit field in the\r
1a3eaf06 898 16-bit port.\r
899\r
900 Reads the 16-bit PCI configuration register specified by Address, performs a\r
62991af2 901 bitwise AND followed by a bitwise OR between the read result and\r
1a3eaf06 902 the value specified by AndData, and writes the result to the 16-bit PCI\r
903 configuration register specified by Address. The value written to the PCI\r
904 configuration register is returned. This function must guarantee that all PCI\r
905 read and write operations are serialized. Extra left bits in both AndData and\r
906 OrData are stripped.\r
907\r
908 If any reserved bits in Address are set, then ASSERT().\r
909 If StartBit is greater than 15, then ASSERT().\r
910 If EndBit is greater than 15, then ASSERT().\r
911 If EndBit is less than StartBit, then ASSERT().\r
912\r
913 @param Address PCI configuration register to write.\r
914 @param StartBit The ordinal of the least significant bit in the bit field.\r
915 Range 0..15.\r
916 @param EndBit The ordinal of the most significant bit in the bit field.\r
917 Range 0..15.\r
918 @param AndData The value to AND with the PCI configuration register.\r
919 @param OrData The value to OR with the result of the AND operation.\r
920\r
921 @return The value written back to the PCI configuration register.\r
922\r
923**/\r
924UINT16\r
925EFIAPI\r
926PciSegmentBitFieldAndThenOr16 (\r
070a76b1 927 IN UINT64 Address,\r
928 IN UINTN StartBit,\r
929 IN UINTN EndBit,\r
930 IN UINT16 AndData,\r
931 IN UINT16 OrData\r
1a3eaf06 932 )\r
933{\r
934 return PciSegmentWrite16 (\r
935 Address,\r
936 BitFieldAndThenOr16 (PciSegmentRead16 (Address), StartBit, EndBit, AndData, OrData)\r
937 );\r
938}\r
939\r
940/**\r
941 Reads a 32-bit PCI configuration register.\r
942\r
943 Reads and returns the 32-bit PCI configuration register specified by Address.\r
070a76b1 944 This function must guarantee that all PCI read and write operations are serialized.\r
945 \r
1a3eaf06 946 If any reserved bits in Address are set, then ASSERT().\r
070a76b1 947 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
1a3eaf06 948\r
070a76b1 949 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.\r
1a3eaf06 950\r
070a76b1 951 @return The 32-bit PCI configuration register specified by Address.\r
1a3eaf06 952\r
953**/\r
954UINT32\r
955EFIAPI\r
956PciSegmentRead32 (\r
070a76b1 957 IN UINT64 Address\r
1a3eaf06 958 )\r
959{\r
960 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 3);\r
961\r
962 return DxePciSegmentLibPciRootBridgeIoReadWorker (Address, EfiPciWidthUint32);\r
963}\r
964\r
965/**\r
966 Writes a 32-bit PCI configuration register.\r
967\r
070a76b1 968 Writes the 32-bit PCI configuration register specified by Address with the value specified by Value.\r
969 Value is returned. This function must guarantee that all PCI read and write operations are serialized.\r
970 \r
1a3eaf06 971 If any reserved bits in Address are set, then ASSERT().\r
070a76b1 972 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
1a3eaf06 973\r
070a76b1 974 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.\r
975 @param Value The value to write.\r
1a3eaf06 976\r
070a76b1 977 @return The parameter of Value.\r
1a3eaf06 978\r
979**/\r
980UINT32\r
981EFIAPI\r
982PciSegmentWrite32 (\r
070a76b1 983 IN UINT64 Address,\r
984 IN UINT32 Value\r
1a3eaf06 985 )\r
986{\r
987 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 3);\r
988\r
070a76b1 989 return DxePciSegmentLibPciRootBridgeIoWriteWorker (Address, EfiPciWidthUint32, Value);\r
1a3eaf06 990}\r
991\r
992/**\r
070a76b1 993 Performs a bitwise OR of a 32-bit PCI configuration register with a 32-bit value.\r
1a3eaf06 994\r
070a76b1 995 Reads the 32-bit PCI configuration register specified by Address,\r
996 performs a bitwise OR between the read result and the value specified by OrData,\r
997 and writes the result to the 32-bit PCI configuration register specified by Address.\r
998 The value written to the PCI configuration register is returned.\r
999 This function must guarantee that all PCI read and write operations are serialized.\r
1000 \r
1a3eaf06 1001 If any reserved bits in Address are set, then ASSERT().\r
070a76b1 1002 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
1a3eaf06 1003\r
070a76b1 1004 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.\r
1005 @param OrData The value to OR with the PCI configuration register.\r
1a3eaf06 1006\r
070a76b1 1007 @return The value written to the PCI configuration register.\r
1a3eaf06 1008\r
1009**/\r
1010UINT32\r
1011EFIAPI\r
1012PciSegmentOr32 (\r
070a76b1 1013 IN UINT64 Address,\r
1014 IN UINT32 OrData\r
1a3eaf06 1015 )\r
1016{\r
1017 return PciSegmentWrite32 (Address, PciSegmentRead32 (Address) | OrData);\r
1018}\r
1019\r
1020/**\r
070a76b1 1021 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit value.\r
1a3eaf06 1022\r
070a76b1 1023 Reads the 32-bit PCI configuration register specified by Address,\r
1024 performs a bitwise AND between the read result and the value specified by AndData,\r
1025 and writes the result to the 32-bit PCI configuration register specified by Address.\r
1026 The value written to the PCI configuration register is returned.\r
1027 This function must guarantee that all PCI read and write operations are serialized.\r
1028 \r
1a3eaf06 1029 If any reserved bits in Address are set, then ASSERT().\r
070a76b1 1030 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
1a3eaf06 1031\r
070a76b1 1032 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.\r
1033 @param AndData The value to AND with the PCI configuration register.\r
1a3eaf06 1034\r
070a76b1 1035 @return The value written to the PCI configuration register.\r
1a3eaf06 1036\r
1037**/\r
1038UINT32\r
1039EFIAPI\r
1040PciSegmentAnd32 (\r
070a76b1 1041 IN UINT64 Address,\r
1042 IN UINT32 AndData\r
1a3eaf06 1043 )\r
1044{\r
1045 return PciSegmentWrite32 (Address, PciSegmentRead32 (Address) & AndData);\r
1046}\r
1047\r
1048/**\r
070a76b1 1049 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit value,\r
1050 followed a bitwise OR with another 32-bit value.\r
1051 \r
1052 Reads the 32-bit PCI configuration register specified by Address,\r
1053 performs a bitwise AND between the read result and the value specified by AndData,\r
1054 performs a bitwise OR between the result of the AND operation and the value specified by OrData,\r
1055 and writes the result to the 32-bit PCI configuration register specified by Address.\r
1056 The value written to the PCI configuration register is returned.\r
1057 This function must guarantee that all PCI read and write operations are serialized.\r
1058 \r
1a3eaf06 1059 If any reserved bits in Address are set, then ASSERT().\r
070a76b1 1060 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
1a3eaf06 1061\r
070a76b1 1062 @param Address Address that encodes the PCI Segment, Bus, Device, Function, and Register.\r
1063 @param AndData The value to AND with the PCI configuration register.\r
1064 @param OrData The value to OR with the PCI configuration register.\r
1a3eaf06 1065\r
070a76b1 1066 @return The value written to the PCI configuration register.\r
1a3eaf06 1067\r
1068**/\r
1069UINT32\r
1070EFIAPI\r
1071PciSegmentAndThenOr32 (\r
070a76b1 1072 IN UINT64 Address,\r
1073 IN UINT32 AndData,\r
1074 IN UINT32 OrData\r
1a3eaf06 1075 )\r
1076{\r
1077 return PciSegmentWrite32 (Address, (PciSegmentRead32 (Address) & AndData) | OrData);\r
1078}\r
1079\r
1080/**\r
1081 Reads a bit field of a PCI configuration register.\r
1082\r
1083 Reads the bit field in a 32-bit PCI configuration register. The bit field is\r
1084 specified by the StartBit and the EndBit. The value of the bit field is\r
1085 returned.\r
1086\r
1087 If any reserved bits in Address are set, then ASSERT().\r
070a76b1 1088 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
1a3eaf06 1089 If StartBit is greater than 31, then ASSERT().\r
1090 If EndBit is greater than 31, then ASSERT().\r
1091 If EndBit is less than StartBit, then ASSERT().\r
1092\r
1093 @param Address PCI configuration register to read.\r
1094 @param StartBit The ordinal of the least significant bit in the bit field.\r
1095 Range 0..31.\r
1096 @param EndBit The ordinal of the most significant bit in the bit field.\r
1097 Range 0..31.\r
1098\r
1099 @return The value of the bit field read from the PCI configuration register.\r
1100\r
1101**/\r
1102UINT32\r
1103EFIAPI\r
1104PciSegmentBitFieldRead32 (\r
070a76b1 1105 IN UINT64 Address,\r
1106 IN UINTN StartBit,\r
1107 IN UINTN EndBit\r
1a3eaf06 1108 )\r
1109{\r
1110 return BitFieldRead32 (PciSegmentRead32 (Address), StartBit, EndBit);\r
1111}\r
1112\r
1113/**\r
1114 Writes a bit field to a PCI configuration register.\r
1115\r
1116 Writes Value to the bit field of the PCI configuration register. The bit\r
1117 field is specified by the StartBit and the EndBit. All other bits in the\r
1118 destination PCI configuration register are preserved. The new value of the\r
1119 32-bit register is returned.\r
1120\r
1121 If any reserved bits in Address are set, then ASSERT().\r
070a76b1 1122 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
1a3eaf06 1123 If StartBit is greater than 31, then ASSERT().\r
1124 If EndBit is greater than 31, then ASSERT().\r
1125 If EndBit is less than StartBit, then ASSERT().\r
1126\r
1127 @param Address PCI configuration register to write.\r
1128 @param StartBit The ordinal of the least significant bit in the bit field.\r
1129 Range 0..31.\r
1130 @param EndBit The ordinal of the most significant bit in the bit field.\r
1131 Range 0..31.\r
1132 @param Value New value of the bit field.\r
1133\r
1134 @return The value written back to the PCI configuration register.\r
1135\r
1136**/\r
1137UINT32\r
1138EFIAPI\r
1139PciSegmentBitFieldWrite32 (\r
070a76b1 1140 IN UINT64 Address,\r
1141 IN UINTN StartBit,\r
1142 IN UINTN EndBit,\r
1143 IN UINT32 Value\r
1a3eaf06 1144 )\r
1145{\r
1146 return PciSegmentWrite32 (\r
1147 Address,\r
1148 BitFieldWrite32 (PciSegmentRead32 (Address), StartBit, EndBit, Value)\r
1149 );\r
1150}\r
1151\r
1152/**\r
1153 Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and\r
1154 writes the result back to the bit field in the 32-bit port.\r
1155\r
1156 Reads the 32-bit PCI configuration register specified by Address, performs a\r
62991af2 1157 bitwise OR between the read result and the value specified by\r
1a3eaf06 1158 OrData, and writes the result to the 32-bit PCI configuration register\r
1159 specified by Address. The value written to the PCI configuration register is\r
1160 returned. This function must guarantee that all PCI read and write operations\r
1161 are serialized. Extra left bits in OrData are stripped.\r
1162\r
1163 If any reserved bits in Address are set, then ASSERT().\r
1164 If StartBit is greater than 31, then ASSERT().\r
1165 If EndBit is greater than 31, then ASSERT().\r
1166 If EndBit is less than StartBit, then ASSERT().\r
1167\r
1168 @param Address PCI configuration register to write.\r
1169 @param StartBit The ordinal of the least significant bit in the bit field.\r
1170 Range 0..31.\r
1171 @param EndBit The ordinal of the most significant bit in the bit field.\r
1172 Range 0..31.\r
1173 @param OrData The value to OR with the PCI configuration register.\r
1174\r
1175 @return The value written back to the PCI configuration register.\r
1176\r
1177**/\r
1178UINT32\r
1179EFIAPI\r
1180PciSegmentBitFieldOr32 (\r
070a76b1 1181 IN UINT64 Address,\r
1182 IN UINTN StartBit,\r
1183 IN UINTN EndBit,\r
1184 IN UINT32 OrData\r
1a3eaf06 1185 )\r
1186{\r
1187 return PciSegmentWrite32 (\r
1188 Address,\r
1189 BitFieldOr32 (PciSegmentRead32 (Address), StartBit, EndBit, OrData)\r
1190 );\r
1191}\r
1192\r
1193/**\r
1194 Reads a bit field in a 32-bit PCI configuration register, performs a bitwise\r
1195 AND, and writes the result back to the bit field in the 32-bit register.\r
1196\r
070a76b1 1197 \r
1198 Reads the 32-bit PCI configuration register specified by Address, performs a bitwise\r
1199 AND between the read result and the value specified by AndData, and writes the result\r
1200 to the 32-bit PCI configuration register specified by Address. The value written to\r
1201 the PCI configuration register is returned. This function must guarantee that all PCI\r
1202 read and write operations are serialized. Extra left bits in AndData are stripped.\r
1a3eaf06 1203 If any reserved bits in Address are set, then ASSERT().\r
070a76b1 1204 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
1a3eaf06 1205 If StartBit is greater than 31, then ASSERT().\r
1206 If EndBit is greater than 31, then ASSERT().\r
1207 If EndBit is less than StartBit, then ASSERT().\r
070a76b1 1208 \r
1a3eaf06 1209\r
1210 @param Address PCI configuration register to write.\r
1211 @param StartBit The ordinal of the least significant bit in the bit field.\r
1212 Range 0..31.\r
1213 @param EndBit The ordinal of the most significant bit in the bit field.\r
1214 Range 0..31.\r
1215 @param AndData The value to AND with the PCI configuration register.\r
1216\r
1217 @return The value written back to the PCI configuration register.\r
1218\r
1219**/\r
1220UINT32\r
1221EFIAPI\r
1222PciSegmentBitFieldAnd32 (\r
070a76b1 1223 IN UINT64 Address,\r
1224 IN UINTN StartBit,\r
1225 IN UINTN EndBit,\r
1226 IN UINT32 AndData\r
1a3eaf06 1227 )\r
1228{\r
1229 return PciSegmentWrite32 (\r
1230 Address,\r
1231 BitFieldAnd32 (PciSegmentRead32 (Address), StartBit, EndBit, AndData)\r
1232 );\r
1233}\r
1234\r
1235/**\r
1236 Reads a bit field in a 32-bit port, performs a bitwise AND followed by a\r
62991af2 1237 bitwise OR, and writes the result back to the bit field in the\r
1a3eaf06 1238 32-bit port.\r
1239\r
1240 Reads the 32-bit PCI configuration register specified by Address, performs a\r
62991af2 1241 bitwise AND followed by a bitwise OR between the read result and\r
1a3eaf06 1242 the value specified by AndData, and writes the result to the 32-bit PCI\r
1243 configuration register specified by Address. The value written to the PCI\r
1244 configuration register is returned. This function must guarantee that all PCI\r
1245 read and write operations are serialized. Extra left bits in both AndData and\r
1246 OrData are stripped.\r
1247\r
1248 If any reserved bits in Address are set, then ASSERT().\r
1249 If StartBit is greater than 31, then ASSERT().\r
1250 If EndBit is greater than 31, then ASSERT().\r
1251 If EndBit is less than StartBit, then ASSERT().\r
1252\r
1253 @param Address PCI configuration register to write.\r
1254 @param StartBit The ordinal of the least significant bit in the bit field.\r
1255 Range 0..31.\r
1256 @param EndBit The ordinal of the most significant bit in the bit field.\r
1257 Range 0..31.\r
1258 @param AndData The value to AND with the PCI configuration register.\r
1259 @param OrData The value to OR with the result of the AND operation.\r
1260\r
1261 @return The value written back to the PCI configuration register.\r
1262\r
1263**/\r
1264UINT32\r
1265EFIAPI\r
1266PciSegmentBitFieldAndThenOr32 (\r
070a76b1 1267 IN UINT64 Address,\r
1268 IN UINTN StartBit,\r
1269 IN UINTN EndBit,\r
1270 IN UINT32 AndData,\r
1271 IN UINT32 OrData\r
1a3eaf06 1272 )\r
1273{\r
1274 return PciSegmentWrite32 (\r
1275 Address,\r
1276 BitFieldAndThenOr32 (PciSegmentRead32 (Address), StartBit, EndBit, AndData, OrData)\r
1277 );\r
1278}\r
1279\r
1280/**\r
1281 Reads a range of PCI configuration registers into a caller supplied buffer.\r
1282\r
070a76b1 1283 Reads the range of PCI configuration registers specified by StartAddress and\r
1284 Size into the buffer specified by Buffer. This function only allows the PCI\r
1285 configuration registers from a single PCI function to be read. Size is\r
1286 returned. When possible 32-bit PCI configuration read cycles are used to read\r
1287 from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit\r
1288 and 16-bit PCI configuration read cycles may be used at the beginning and the\r
1289 end of the range.\r
1290\r
59ceeabe 1291 If any reserved bits in StartAddress are set, then ASSERT().\r
1a3eaf06 1292 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().\r
1293 If Size > 0 and Buffer is NULL, then ASSERT().\r
1294\r
070a76b1 1295 @param StartAddress Starting address that encodes the PCI Segment, Bus, Device,\r
1296 Function and Register.\r
1a3eaf06 1297 @param Size Size in bytes of the transfer.\r
1298 @param Buffer Pointer to a buffer receiving the data read.\r
1299\r
070a76b1 1300 @return Size\r
1a3eaf06 1301\r
1302**/\r
1303UINTN\r
1304EFIAPI\r
1305PciSegmentReadBuffer (\r
070a76b1 1306 IN UINT64 StartAddress,\r
1307 IN UINTN Size,\r
1308 OUT VOID *Buffer\r
1a3eaf06 1309 )\r
1310{\r
1311 UINTN ReturnValue;\r
1312\r
1313 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress, 0);\r
1314 ASSERT (((StartAddress & 0xFFF) + Size) <= 0x1000);\r
1315\r
1316 if (Size == 0) {\r
1317 return Size;\r
1318 }\r
1319\r
1320 ASSERT (Buffer != NULL);\r
1321\r
1322 //\r
1323 // Save Size for return\r
1324 //\r
1325 ReturnValue = Size;\r
1326\r
e43e4b3e 1327 if ((StartAddress & BIT0) != 0) {\r
1a3eaf06 1328 //\r
1329 // Read a byte if StartAddress is byte aligned\r
1330 //\r
1331 *(volatile UINT8 *)Buffer = PciSegmentRead8 (StartAddress);\r
1332 StartAddress += sizeof (UINT8);\r
1333 Size -= sizeof (UINT8);\r
1334 Buffer = (UINT8*)Buffer + 1;\r
1335 }\r
1336\r
e43e4b3e 1337 if (Size >= sizeof (UINT16) && (StartAddress & BIT1) != 0) {\r
1a3eaf06 1338 //\r
1339 // Read a word if StartAddress is word aligned\r
1340 //\r
5dc4fd78 1341 WriteUnaligned16 (Buffer, PciSegmentRead16 (StartAddress));\r
1a3eaf06 1342 StartAddress += sizeof (UINT16);\r
1343 Size -= sizeof (UINT16);\r
1344 Buffer = (UINT16*)Buffer + 1;\r
1345 }\r
1346\r
1347 while (Size >= sizeof (UINT32)) {\r
1348 //\r
1349 // Read as many double words as possible\r
1350 //\r
5dc4fd78 1351 WriteUnaligned32 (Buffer, PciSegmentRead32 (StartAddress));\r
1a3eaf06 1352 StartAddress += sizeof (UINT32);\r
1353 Size -= sizeof (UINT32);\r
1354 Buffer = (UINT32*)Buffer + 1;\r
1355 }\r
1356\r
1357 if (Size >= sizeof (UINT16)) {\r
1358 //\r
1359 // Read the last remaining word if exist\r
1360 //\r
5dc4fd78 1361 WriteUnaligned16 (Buffer, PciSegmentRead16 (StartAddress));\r
1a3eaf06 1362 StartAddress += sizeof (UINT16);\r
1363 Size -= sizeof (UINT16);\r
1364 Buffer = (UINT16*)Buffer + 1;\r
1365 }\r
1366\r
1367 if (Size >= sizeof (UINT8)) {\r
1368 //\r
1369 // Read the last remaining byte if exist\r
1370 //\r
1371 *(volatile UINT8 *)Buffer = PciSegmentRead8 (StartAddress);\r
1372 }\r
1373\r
1374 return ReturnValue;\r
1375}\r
1376\r
1377/**\r
070a76b1 1378 Copies the data in a caller supplied buffer to a specified range of PCI\r
1379 configuration space.\r
1380\r
1381 Writes the range of PCI configuration registers specified by StartAddress and\r
1382 Size from the buffer specified by Buffer. This function only allows the PCI\r
1383 configuration registers from a single PCI function to be written. Size is\r
1384 returned. When possible 32-bit PCI configuration write cycles are used to\r
1385 write from StartAdress to StartAddress + Size. Due to alignment restrictions,\r
1386 8-bit and 16-bit PCI configuration write cycles may be used at the beginning\r
1387 and the end of the range.\r
1388\r
59ceeabe 1389 If any reserved bits in StartAddress are set, then ASSERT().\r
1a3eaf06 1390 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().\r
1391 If Size > 0 and Buffer is NULL, then ASSERT().\r
1392\r
070a76b1 1393 @param StartAddress Starting address that encodes the PCI Segment, Bus, Device,\r
1394 Function and Register.\r
1a3eaf06 1395 @param Size Size in bytes of the transfer.\r
1396 @param Buffer Pointer to a buffer containing the data to write.\r
1397\r
34ffd1bb 1398 @return The parameter of Size.\r
1a3eaf06 1399\r
1400**/\r
1401UINTN\r
1402EFIAPI\r
1403PciSegmentWriteBuffer (\r
070a76b1 1404 IN UINT64 StartAddress,\r
1405 IN UINTN Size,\r
1406 IN VOID *Buffer\r
1a3eaf06 1407 )\r
1408{\r
1409 UINTN ReturnValue;\r
1410\r
1411 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress, 0);\r
1412 ASSERT (((StartAddress & 0xFFF) + Size) <= 0x1000);\r
1413\r
1414 if (Size == 0) {\r
1415 return 0;\r
1416 }\r
1417\r
1418 ASSERT (Buffer != NULL);\r
1419\r
1420 //\r
1421 // Save Size for return\r
1422 //\r
1423 ReturnValue = Size;\r
1424\r
e43e4b3e 1425 if ((StartAddress & BIT0) != 0) {\r
1a3eaf06 1426 //\r
1427 // Write a byte if StartAddress is byte aligned\r
1428 //\r
1429 PciSegmentWrite8 (StartAddress, *(UINT8*)Buffer);\r
1430 StartAddress += sizeof (UINT8);\r
1431 Size -= sizeof (UINT8);\r
1432 Buffer = (UINT8*)Buffer + 1;\r
1433 }\r
1434\r
e43e4b3e 1435 if (Size >= sizeof (UINT16) && (StartAddress & BIT1) != 0) {\r
1a3eaf06 1436 //\r
1437 // Write a word if StartAddress is word aligned\r
1438 //\r
5dc4fd78 1439 PciSegmentWrite16 (StartAddress, ReadUnaligned16 (Buffer));\r
1a3eaf06 1440 StartAddress += sizeof (UINT16);\r
1441 Size -= sizeof (UINT16);\r
1442 Buffer = (UINT16*)Buffer + 1;\r
1443 }\r
1444\r
1445 while (Size >= sizeof (UINT32)) {\r
1446 //\r
1447 // Write as many double words as possible\r
1448 //\r
5dc4fd78 1449 PciSegmentWrite32 (StartAddress, ReadUnaligned32 (Buffer));\r
1a3eaf06 1450 StartAddress += sizeof (UINT32);\r
1451 Size -= sizeof (UINT32);\r
1452 Buffer = (UINT32*)Buffer + 1;\r
1453 }\r
1454\r
1455 if (Size >= sizeof (UINT16)) {\r
1456 //\r
1457 // Write the last remaining word if exist\r
1458 //\r
5dc4fd78 1459 PciSegmentWrite16 (StartAddress, ReadUnaligned16 (Buffer));\r
1a3eaf06 1460 StartAddress += sizeof (UINT16);\r
1461 Size -= sizeof (UINT16);\r
1462 Buffer = (UINT16*)Buffer + 1;\r
1463 }\r
1464\r
1465 if (Size >= sizeof (UINT8)) {\r
1466 //\r
1467 // Write the last remaining byte if exist\r
1468 //\r
1469 PciSegmentWrite8 (StartAddress, *(UINT8*)Buffer);\r
1470 }\r
1471\r
1472 return ReturnValue;\r
1473}\r