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