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