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