]> git.proxmox.com Git - mirror_edk2.git/blame - MdePkg/Library/UefiPciSegmentLibPciRootBridgeIo/PciSegmentLib.c
Add ASSERT() for BitField operations to make sure the input value is valid.
[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
94952554 4 Copyright (c) 2007 - 2012, 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
2fc59a00 249 @param Address The 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
276 \r
1a3eaf06 277 If any reserved bits in Address are set, then ASSERT().\r
070a76b1 278 \r
2fc59a00 279 @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register.\r
1a3eaf06 280\r
070a76b1 281 @return The 8-bit PCI configuration register specified by Address.\r
1a3eaf06 282\r
283**/\r
284UINT8\r
285EFIAPI\r
286PciSegmentRead8 (\r
070a76b1 287 IN UINT64 Address\r
1a3eaf06 288 )\r
289{\r
290 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 0);\r
291\r
292 return (UINT8) DxePciSegmentLibPciRootBridgeIoReadWorker (Address, EfiPciWidthUint8);\r
293}\r
294\r
295/**\r
296 Writes an 8-bit PCI configuration register.\r
297\r
070a76b1 298 Writes the 8-bit PCI configuration register specified by Address with the value specified by Value.\r
299 Value is returned. This function must guarantee that all PCI read and write operations are serialized.\r
300 \r
59ceeabe 301 If any reserved bits in Address are set, then ASSERT().\r
1a3eaf06 302\r
2fc59a00 303 @param Address The 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
329 \r
1a3eaf06 330 If any reserved bits in Address are set, then ASSERT().\r
331\r
2fc59a00 332 @param Address The 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
2fc59a00 358 @param Address The 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
377 \r
378 Reads the 8-bit PCI configuration register specified by Address,\r
379 performs a bitwise AND between the read result and the value specified by AndData,\r
380 performs a bitwise OR between the result of the AND operation and the value specified by OrData,\r
381 and writes the result to the 8-bit PCI configuration register specified by Address.\r
382 The value written to the PCI configuration register is returned.\r
383 This function must guarantee that all PCI read and write operations are serialized.\r
384 \r
1a3eaf06 385 If any reserved bits in Address are set, then ASSERT().\r
386\r
2fc59a00 387 @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register.\r
070a76b1 388 @param AndData The value to AND with the PCI configuration register.\r
389 @param OrData The value to OR with the PCI configuration register.\r
1a3eaf06 390\r
070a76b1 391 @return The value written to the PCI configuration register.\r
1a3eaf06 392\r
393**/\r
394UINT8\r
395EFIAPI\r
396PciSegmentAndThenOr8 (\r
070a76b1 397 IN UINT64 Address,\r
398 IN UINT8 AndData,\r
399 IN UINT8 OrData\r
1a3eaf06 400 )\r
401{\r
402 return PciSegmentWrite8 (Address, (UINT8) ((PciSegmentRead8 (Address) & AndData) | OrData));\r
403}\r
404\r
405/**\r
406 Reads a bit field of a PCI configuration register.\r
407\r
408 Reads the bit field in an 8-bit PCI configuration register. The bit field is\r
409 specified by the StartBit and the EndBit. The value of the bit field is\r
410 returned.\r
411\r
412 If any reserved bits in Address are set, then ASSERT().\r
413 If StartBit is greater than 7, then ASSERT().\r
414 If EndBit is greater than 7, then ASSERT().\r
415 If EndBit is less than StartBit, then ASSERT().\r
416\r
2fc59a00 417 @param Address The 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
2fc59a00 451 @param Address The 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
2fc59a00 456 @param Value The 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
2fc59a00 493 @param Address The 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
2fc59a00 535 @param Address The 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
62991af2 562 bitwise OR, and writes the result back to the bit field in the\r
1a3eaf06 563 8-bit port.\r
564\r
565 Reads the 8-bit PCI configuration register specified by Address, performs a\r
62991af2 566 bitwise AND followed by a bitwise OR between the read result and\r
1a3eaf06 567 the value specified by AndData, and writes the result to the 8-bit PCI\r
568 configuration register specified by Address. The value written to the PCI\r
569 configuration register is returned. This function must guarantee that all PCI\r
570 read and write operations are serialized. Extra left bits in both AndData and\r
571 OrData are stripped.\r
572\r
573 If any reserved bits in Address are set, then ASSERT().\r
574 If StartBit is greater than 7, then ASSERT().\r
575 If EndBit is greater than 7, then ASSERT().\r
576 If EndBit is less than StartBit, then ASSERT().\r
94952554
LG
577 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
578 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
1a3eaf06 579\r
2fc59a00 580 @param Address The PCI configuration register to write.\r
1a3eaf06 581 @param StartBit The ordinal of the least significant bit in the bit field.\r
582 Range 0..7.\r
583 @param EndBit The ordinal of the most significant bit in the bit field.\r
584 Range 0..7.\r
585 @param AndData The value to AND with the PCI configuration register.\r
586 @param OrData The value to OR with the result of the AND operation.\r
587\r
588 @return The value written back to the PCI configuration register.\r
589\r
590**/\r
591UINT8\r
592EFIAPI\r
593PciSegmentBitFieldAndThenOr8 (\r
070a76b1 594 IN UINT64 Address,\r
595 IN UINTN StartBit,\r
596 IN UINTN EndBit,\r
597 IN UINT8 AndData,\r
598 IN UINT8 OrData\r
1a3eaf06 599 )\r
600{\r
601 return PciSegmentWrite8 (\r
602 Address,\r
603 BitFieldAndThenOr8 (PciSegmentRead8 (Address), StartBit, EndBit, AndData, OrData)\r
604 );\r
605}\r
606\r
607/**\r
608 Reads a 16-bit PCI configuration register.\r
609\r
610 Reads and returns the 16-bit PCI configuration register specified by Address.\r
070a76b1 611 This function must guarantee that all PCI read and write operations are serialized.\r
612 \r
1a3eaf06 613 If any reserved bits in Address are set, then ASSERT().\r
070a76b1 614 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
615 \r
2fc59a00 616 @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register.\r
1a3eaf06 617\r
070a76b1 618 @return The 16-bit PCI configuration register specified by Address.\r
1a3eaf06 619\r
620**/\r
621UINT16\r
622EFIAPI\r
623PciSegmentRead16 (\r
070a76b1 624 IN UINT64 Address\r
1a3eaf06 625 )\r
626{\r
627 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 1);\r
628\r
629 return (UINT16) DxePciSegmentLibPciRootBridgeIoReadWorker (Address, EfiPciWidthUint16);\r
630}\r
631\r
632/**\r
633 Writes a 16-bit PCI configuration register.\r
634\r
070a76b1 635 Writes the 16-bit PCI configuration register specified by Address with the value specified by Value.\r
636 Value is returned. This function must guarantee that all PCI read and write operations are serialized.\r
637 \r
1a3eaf06 638 If any reserved bits in Address are set, then ASSERT().\r
070a76b1 639 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
1a3eaf06 640\r
2fc59a00 641 @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register.\r
070a76b1 642 @param Value The value to write.\r
1a3eaf06 643\r
070a76b1 644 @return The parameter of Value.\r
1a3eaf06 645\r
646**/\r
647UINT16\r
648EFIAPI\r
649PciSegmentWrite16 (\r
070a76b1 650 IN UINT64 Address,\r
651 IN UINT16 Value\r
1a3eaf06 652 )\r
653{\r
654 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 1);\r
655\r
070a76b1 656 return (UINT16) DxePciSegmentLibPciRootBridgeIoWriteWorker (Address, EfiPciWidthUint16, Value);\r
1a3eaf06 657}\r
658\r
659/**\r
62991af2 660 Performs a bitwise OR of a 16-bit PCI configuration register with\r
1a3eaf06 661 a 16-bit value.\r
662\r
663 Reads the 16-bit PCI configuration register specified by Address, performs a\r
62991af2 664 bitwise OR between the read result and the value specified by\r
1a3eaf06 665 OrData, and writes the result to the 16-bit PCI configuration register\r
666 specified by Address. The value written to the PCI configuration register is\r
667 returned. This function must guarantee that all PCI read and write operations\r
668 are serialized.\r
669\r
670 If any reserved bits in Address are set, then ASSERT().\r
070a76b1 671 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
1a3eaf06 672\r
2fc59a00 673 @param Address The address that encodes the PCI Segment, Bus, Device, Function and\r
1a3eaf06 674 Register.\r
675 @param OrData The value to OR with the PCI configuration register.\r
676\r
677 @return The value written back to the PCI configuration register.\r
678\r
679**/\r
680UINT16\r
681EFIAPI\r
682PciSegmentOr16 (\r
070a76b1 683 IN UINT64 Address,\r
684 IN UINT16 OrData\r
1a3eaf06 685 )\r
686{\r
687 return PciSegmentWrite16 (Address, (UINT16) (PciSegmentRead16 (Address) | OrData));\r
688}\r
689\r
690/**\r
070a76b1 691 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit value.\r
1a3eaf06 692\r
070a76b1 693 Reads the 16-bit PCI configuration register specified by Address,\r
694 performs a bitwise AND between the read result and the value specified by AndData,\r
695 and writes the result to the 16-bit PCI configuration register specified by Address.\r
696 The value written to the PCI configuration register is returned.\r
697 This function must guarantee that all PCI read and write operations are serialized.\r
698 \r
1a3eaf06 699 If any reserved bits in Address are set, then ASSERT().\r
070a76b1 700 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
701 \r
2fc59a00 702 @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register.\r
070a76b1 703 @param AndData The value to AND with the PCI configuration register.\r
1a3eaf06 704\r
070a76b1 705 @return The value written to the PCI configuration register.\r
1a3eaf06 706\r
707**/\r
708UINT16\r
709EFIAPI\r
710PciSegmentAnd16 (\r
070a76b1 711 IN UINT64 Address,\r
712 IN UINT16 AndData\r
1a3eaf06 713 )\r
714{\r
715 return PciSegmentWrite16 (Address, (UINT16) (PciSegmentRead16 (Address) & AndData));\r
716}\r
717\r
718/**\r
070a76b1 719 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit value,\r
720 followed a bitwise OR with another 16-bit value.\r
721 \r
722 Reads the 16-bit PCI configuration register specified by Address,\r
723 performs a bitwise AND between the read result and the value specified by AndData,\r
724 performs a bitwise OR between the result of the AND operation and the value specified by OrData,\r
725 and writes the result to the 16-bit PCI configuration register specified by Address.\r
726 The value written to the PCI configuration register is returned.\r
727 This function must guarantee that all PCI read and write operations are serialized.\r
728 \r
1a3eaf06 729 If any reserved bits in Address are set, then ASSERT().\r
070a76b1 730 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
1a3eaf06 731\r
2fc59a00 732 @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register.\r
070a76b1 733 @param AndData The value to AND with the PCI configuration register.\r
734 @param OrData The value to OR with the PCI configuration register.\r
1a3eaf06 735\r
070a76b1 736 @return The value written to the PCI configuration register.\r
1a3eaf06 737\r
738**/\r
739UINT16\r
740EFIAPI\r
741PciSegmentAndThenOr16 (\r
070a76b1 742 IN UINT64 Address,\r
743 IN UINT16 AndData,\r
744 IN UINT16 OrData\r
1a3eaf06 745 )\r
746{\r
747 return PciSegmentWrite16 (Address, (UINT16) ((PciSegmentRead16 (Address) & AndData) | OrData));\r
748}\r
749\r
750/**\r
751 Reads a bit field of a PCI configuration register.\r
752\r
753 Reads the bit field in a 16-bit PCI configuration register. The bit field is\r
754 specified by the StartBit and the EndBit. The value of the bit field is\r
755 returned.\r
756\r
757 If any reserved bits in Address are set, then ASSERT().\r
070a76b1 758 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
1a3eaf06 759 If StartBit is greater than 15, then ASSERT().\r
760 If EndBit is greater than 15, then ASSERT().\r
761 If EndBit is less than StartBit, then ASSERT().\r
762\r
2fc59a00 763 @param Address The PCI configuration register to read.\r
1a3eaf06 764 @param StartBit The ordinal of the least significant bit in the bit field.\r
765 Range 0..15.\r
766 @param EndBit The ordinal of the most significant bit in the bit field.\r
767 Range 0..15.\r
768\r
769 @return The value of the bit field read from the PCI configuration register.\r
770\r
771**/\r
772UINT16\r
773EFIAPI\r
774PciSegmentBitFieldRead16 (\r
070a76b1 775 IN UINT64 Address,\r
776 IN UINTN StartBit,\r
777 IN UINTN EndBit\r
1a3eaf06 778 )\r
779{\r
780 return BitFieldRead16 (PciSegmentRead16 (Address), StartBit, EndBit);\r
781}\r
782\r
783/**\r
784 Writes a bit field to a PCI configuration register.\r
785\r
786 Writes Value to the bit field of the PCI configuration register. The bit\r
787 field is specified by the StartBit and the EndBit. All other bits in the\r
788 destination PCI configuration register are preserved. The new value of the\r
789 16-bit register is returned.\r
790\r
791 If any reserved bits in Address are set, then ASSERT().\r
070a76b1 792 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
1a3eaf06 793 If StartBit is greater than 15, then ASSERT().\r
794 If EndBit is greater than 15, then ASSERT().\r
795 If EndBit is less than StartBit, then ASSERT().\r
94952554 796 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
1a3eaf06 797\r
2fc59a00 798 @param Address The PCI configuration register to write.\r
1a3eaf06 799 @param StartBit The ordinal of the least significant bit in the bit field.\r
800 Range 0..15.\r
801 @param EndBit The ordinal of the most significant bit in the bit field.\r
802 Range 0..15.\r
2fc59a00 803 @param Value The new value of the bit field.\r
1a3eaf06 804\r
805 @return The value written back to the PCI configuration register.\r
806\r
807**/\r
808UINT16\r
809EFIAPI\r
810PciSegmentBitFieldWrite16 (\r
070a76b1 811 IN UINT64 Address,\r
812 IN UINTN StartBit,\r
813 IN UINTN EndBit,\r
814 IN UINT16 Value\r
1a3eaf06 815 )\r
816{\r
817 return PciSegmentWrite16 (\r
818 Address,\r
819 BitFieldWrite16 (PciSegmentRead16 (Address), StartBit, EndBit, Value)\r
820 );\r
821}\r
822\r
823/**\r
070a76b1 824 Reads the 16-bit PCI configuration register specified by Address,\r
825 performs a bitwise OR between the read result and the value specified by OrData,\r
826 and writes the result to the 16-bit PCI configuration register specified by Address. \r
1a3eaf06 827\r
828 If any reserved bits in Address are set, then ASSERT().\r
070a76b1 829 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
1a3eaf06 830 If StartBit is greater than 15, then ASSERT().\r
831 If EndBit is greater than 15, then ASSERT().\r
832 If EndBit is less than StartBit, then ASSERT().\r
94952554 833 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
1a3eaf06 834\r
2fc59a00 835 @param Address The PCI configuration register to write.\r
1a3eaf06 836 @param StartBit The ordinal of the least significant bit in the bit field.\r
837 Range 0..15.\r
838 @param EndBit The ordinal of the most significant bit in the bit field.\r
839 Range 0..15.\r
840 @param OrData The value to OR with the PCI configuration register.\r
841\r
842 @return The value written back to the PCI configuration register.\r
843\r
844**/\r
845UINT16\r
846EFIAPI\r
847PciSegmentBitFieldOr16 (\r
070a76b1 848 IN UINT64 Address,\r
849 IN UINTN StartBit,\r
850 IN UINTN EndBit,\r
851 IN UINT16 OrData\r
1a3eaf06 852 )\r
853{\r
854 return PciSegmentWrite16 (\r
855 Address,\r
856 BitFieldOr16 (PciSegmentRead16 (Address), StartBit, EndBit, OrData)\r
857 );\r
858}\r
859\r
860/**\r
070a76b1 861 Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR,\r
862 and writes the result back to the bit field in the 16-bit port.\r
863\r
864 Reads the 16-bit PCI configuration register specified by Address,\r
865 performs a bitwise OR between the read result and the value specified by OrData,\r
866 and writes the result to the 16-bit PCI configuration register specified by Address.\r
867 The value written to the PCI configuration register is returned.\r
868 This function must guarantee that all PCI read and write operations are serialized.\r
869 Extra left bits in OrData are stripped.\r
870 \r
1a3eaf06 871 If any reserved bits in Address are set, then ASSERT().\r
070a76b1 872 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
873 If StartBit is greater than 7, then ASSERT().\r
874 If EndBit is greater than 7, then ASSERT().\r
1a3eaf06 875 If EndBit is less than StartBit, then ASSERT().\r
94952554 876 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
1a3eaf06 877\r
2fc59a00 878 @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register.\r
1a3eaf06 879 @param StartBit The ordinal of the least significant bit in the bit field.\r
070a76b1 880 The ordinal of the least significant bit in a byte is bit 0.\r
1a3eaf06 881 @param EndBit The ordinal of the most significant bit in the bit field.\r
070a76b1 882 The ordinal of the most significant bit in a byte is bit 7.\r
883 @param AndData The value to AND with the read value from the PCI configuration register.\r
1a3eaf06 884\r
070a76b1 885 @return The value written to the PCI configuration register.\r
1a3eaf06 886\r
887**/\r
888UINT16\r
889EFIAPI\r
890PciSegmentBitFieldAnd16 (\r
070a76b1 891 IN UINT64 Address,\r
892 IN UINTN StartBit,\r
893 IN UINTN EndBit,\r
894 IN UINT16 AndData\r
1a3eaf06 895 )\r
896{\r
897 return PciSegmentWrite16 (\r
898 Address,\r
899 BitFieldAnd16 (PciSegmentRead16 (Address), StartBit, EndBit, AndData)\r
900 );\r
901}\r
902\r
903/**\r
904 Reads a bit field in a 16-bit port, performs a bitwise AND followed by a\r
62991af2 905 bitwise OR, and writes the result back to the bit field in the\r
1a3eaf06 906 16-bit port.\r
907\r
908 Reads the 16-bit PCI configuration register specified by Address, performs a\r
62991af2 909 bitwise AND followed by a bitwise OR between the read result and\r
1a3eaf06 910 the value specified by AndData, and writes the result to the 16-bit PCI\r
911 configuration register specified by Address. The value written to the PCI\r
912 configuration register is returned. This function must guarantee that all PCI\r
913 read and write operations are serialized. Extra left bits in both AndData and\r
914 OrData are stripped.\r
915\r
916 If any reserved bits in Address are set, then ASSERT().\r
917 If StartBit is greater than 15, then ASSERT().\r
918 If EndBit is greater than 15, then ASSERT().\r
919 If EndBit is less than StartBit, then ASSERT().\r
94952554
LG
920 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
921 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
1a3eaf06 922\r
2fc59a00 923 @param Address The PCI configuration register to write.\r
1a3eaf06 924 @param StartBit The ordinal of the least significant bit in the bit field.\r
925 Range 0..15.\r
926 @param EndBit The ordinal of the most significant bit in the bit field.\r
927 Range 0..15.\r
928 @param AndData The value to AND with the PCI configuration register.\r
929 @param OrData The value to OR with the result of the AND operation.\r
930\r
931 @return The value written back to the PCI configuration register.\r
932\r
933**/\r
934UINT16\r
935EFIAPI\r
936PciSegmentBitFieldAndThenOr16 (\r
070a76b1 937 IN UINT64 Address,\r
938 IN UINTN StartBit,\r
939 IN UINTN EndBit,\r
940 IN UINT16 AndData,\r
941 IN UINT16 OrData\r
1a3eaf06 942 )\r
943{\r
944 return PciSegmentWrite16 (\r
945 Address,\r
946 BitFieldAndThenOr16 (PciSegmentRead16 (Address), StartBit, EndBit, AndData, OrData)\r
947 );\r
948}\r
949\r
950/**\r
951 Reads a 32-bit PCI configuration register.\r
952\r
953 Reads and returns the 32-bit PCI configuration register specified by Address.\r
070a76b1 954 This function must guarantee that all PCI read and write operations are serialized.\r
955 \r
1a3eaf06 956 If any reserved bits in Address are set, then ASSERT().\r
070a76b1 957 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
1a3eaf06 958\r
2fc59a00 959 @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register.\r
1a3eaf06 960\r
070a76b1 961 @return The 32-bit PCI configuration register specified by Address.\r
1a3eaf06 962\r
963**/\r
964UINT32\r
965EFIAPI\r
966PciSegmentRead32 (\r
070a76b1 967 IN UINT64 Address\r
1a3eaf06 968 )\r
969{\r
970 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 3);\r
971\r
972 return DxePciSegmentLibPciRootBridgeIoReadWorker (Address, EfiPciWidthUint32);\r
973}\r
974\r
975/**\r
976 Writes a 32-bit PCI configuration register.\r
977\r
070a76b1 978 Writes the 32-bit PCI configuration register specified by Address with the value specified by Value.\r
979 Value is returned. This function must guarantee that all PCI read and write operations are serialized.\r
980 \r
1a3eaf06 981 If any reserved bits in Address are set, then ASSERT().\r
070a76b1 982 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
1a3eaf06 983\r
2fc59a00 984 @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register.\r
070a76b1 985 @param Value The value to write.\r
1a3eaf06 986\r
070a76b1 987 @return The parameter of Value.\r
1a3eaf06 988\r
989**/\r
990UINT32\r
991EFIAPI\r
992PciSegmentWrite32 (\r
070a76b1 993 IN UINT64 Address,\r
994 IN UINT32 Value\r
1a3eaf06 995 )\r
996{\r
997 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 3);\r
998\r
070a76b1 999 return DxePciSegmentLibPciRootBridgeIoWriteWorker (Address, EfiPciWidthUint32, Value);\r
1a3eaf06 1000}\r
1001\r
1002/**\r
070a76b1 1003 Performs a bitwise OR of a 32-bit PCI configuration register with a 32-bit value.\r
1a3eaf06 1004\r
070a76b1 1005 Reads the 32-bit PCI configuration register specified by Address,\r
1006 performs a bitwise OR between the read result and the value specified by OrData,\r
1007 and writes the result to the 32-bit PCI configuration register specified by Address.\r
1008 The value written to the PCI configuration register is returned.\r
1009 This function must guarantee that all PCI read and write operations are serialized.\r
1010 \r
1a3eaf06 1011 If any reserved bits in Address are set, then ASSERT().\r
070a76b1 1012 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
1a3eaf06 1013\r
2fc59a00 1014 @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register.\r
070a76b1 1015 @param OrData The value to OR with the PCI configuration register.\r
1a3eaf06 1016\r
070a76b1 1017 @return The value written to the PCI configuration register.\r
1a3eaf06 1018\r
1019**/\r
1020UINT32\r
1021EFIAPI\r
1022PciSegmentOr32 (\r
070a76b1 1023 IN UINT64 Address,\r
1024 IN UINT32 OrData\r
1a3eaf06 1025 )\r
1026{\r
1027 return PciSegmentWrite32 (Address, PciSegmentRead32 (Address) | OrData);\r
1028}\r
1029\r
1030/**\r
070a76b1 1031 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit value.\r
1a3eaf06 1032\r
070a76b1 1033 Reads the 32-bit PCI configuration register specified by Address,\r
1034 performs a bitwise AND between the read result and the value specified by AndData,\r
1035 and writes the result to the 32-bit PCI configuration register specified by Address.\r
1036 The value written to the PCI configuration register is returned.\r
1037 This function must guarantee that all PCI read and write operations are serialized.\r
1038 \r
1a3eaf06 1039 If any reserved bits in Address are set, then ASSERT().\r
070a76b1 1040 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
1a3eaf06 1041\r
2fc59a00 1042 @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register.\r
070a76b1 1043 @param AndData The value to AND with the PCI configuration register.\r
1a3eaf06 1044\r
070a76b1 1045 @return The value written to the PCI configuration register.\r
1a3eaf06 1046\r
1047**/\r
1048UINT32\r
1049EFIAPI\r
1050PciSegmentAnd32 (\r
070a76b1 1051 IN UINT64 Address,\r
1052 IN UINT32 AndData\r
1a3eaf06 1053 )\r
1054{\r
1055 return PciSegmentWrite32 (Address, PciSegmentRead32 (Address) & AndData);\r
1056}\r
1057\r
1058/**\r
070a76b1 1059 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit value,\r
1060 followed a bitwise OR with another 32-bit value.\r
1061 \r
1062 Reads the 32-bit PCI configuration register specified by Address,\r
1063 performs a bitwise AND between the read result and the value specified by AndData,\r
1064 performs a bitwise OR between the result of the AND operation and the value specified by OrData,\r
1065 and writes the result to the 32-bit PCI configuration register specified by Address.\r
1066 The value written to the PCI configuration register is returned.\r
1067 This function must guarantee that all PCI read and write operations are serialized.\r
1068 \r
1a3eaf06 1069 If any reserved bits in Address are set, then ASSERT().\r
070a76b1 1070 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
1a3eaf06 1071\r
2fc59a00 1072 @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register.\r
070a76b1 1073 @param AndData The value to AND with the PCI configuration register.\r
1074 @param OrData The value to OR with the PCI configuration register.\r
1a3eaf06 1075\r
070a76b1 1076 @return The value written to the PCI configuration register.\r
1a3eaf06 1077\r
1078**/\r
1079UINT32\r
1080EFIAPI\r
1081PciSegmentAndThenOr32 (\r
070a76b1 1082 IN UINT64 Address,\r
1083 IN UINT32 AndData,\r
1084 IN UINT32 OrData\r
1a3eaf06 1085 )\r
1086{\r
1087 return PciSegmentWrite32 (Address, (PciSegmentRead32 (Address) & AndData) | OrData);\r
1088}\r
1089\r
1090/**\r
1091 Reads a bit field of a PCI configuration register.\r
1092\r
1093 Reads the bit field in a 32-bit PCI configuration register. The bit field is\r
1094 specified by the StartBit and the EndBit. The value of the bit field is\r
1095 returned.\r
1096\r
1097 If any reserved bits in Address are set, then ASSERT().\r
070a76b1 1098 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
1a3eaf06 1099 If StartBit is greater than 31, then ASSERT().\r
1100 If EndBit is greater than 31, then ASSERT().\r
1101 If EndBit is less than StartBit, then ASSERT().\r
1102\r
2fc59a00 1103 @param Address The PCI configuration register to read.\r
1a3eaf06 1104 @param StartBit The ordinal of the least significant bit in the bit field.\r
1105 Range 0..31.\r
1106 @param EndBit The ordinal of the most significant bit in the bit field.\r
1107 Range 0..31.\r
1108\r
1109 @return The value of the bit field read from the PCI configuration register.\r
1110\r
1111**/\r
1112UINT32\r
1113EFIAPI\r
1114PciSegmentBitFieldRead32 (\r
070a76b1 1115 IN UINT64 Address,\r
1116 IN UINTN StartBit,\r
1117 IN UINTN EndBit\r
1a3eaf06 1118 )\r
1119{\r
1120 return BitFieldRead32 (PciSegmentRead32 (Address), StartBit, EndBit);\r
1121}\r
1122\r
1123/**\r
1124 Writes a bit field to a PCI configuration register.\r
1125\r
1126 Writes Value to the bit field of the PCI configuration register. The bit\r
1127 field is specified by the StartBit and the EndBit. All other bits in the\r
1128 destination PCI configuration register are preserved. The new value of the\r
1129 32-bit register is returned.\r
1130\r
1131 If any reserved bits in Address are set, then ASSERT().\r
070a76b1 1132 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
1a3eaf06 1133 If StartBit is greater than 31, then ASSERT().\r
1134 If EndBit is greater than 31, then ASSERT().\r
1135 If EndBit is less than StartBit, then ASSERT().\r
94952554 1136 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
1a3eaf06 1137\r
2fc59a00 1138 @param Address The PCI configuration register to write.\r
1a3eaf06 1139 @param StartBit The ordinal of the least significant bit in the bit field.\r
1140 Range 0..31.\r
1141 @param EndBit The ordinal of the most significant bit in the bit field.\r
1142 Range 0..31.\r
2fc59a00 1143 @param Value The new value of the bit field.\r
1a3eaf06 1144\r
1145 @return The value written back to the PCI configuration register.\r
1146\r
1147**/\r
1148UINT32\r
1149EFIAPI\r
1150PciSegmentBitFieldWrite32 (\r
070a76b1 1151 IN UINT64 Address,\r
1152 IN UINTN StartBit,\r
1153 IN UINTN EndBit,\r
1154 IN UINT32 Value\r
1a3eaf06 1155 )\r
1156{\r
1157 return PciSegmentWrite32 (\r
1158 Address,\r
1159 BitFieldWrite32 (PciSegmentRead32 (Address), StartBit, EndBit, Value)\r
1160 );\r
1161}\r
1162\r
1163/**\r
1164 Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and\r
1165 writes the result back to the bit field in the 32-bit port.\r
1166\r
1167 Reads the 32-bit PCI configuration register specified by Address, performs a\r
62991af2 1168 bitwise OR between the read result and the value specified by\r
1a3eaf06 1169 OrData, and writes the result to the 32-bit PCI configuration register\r
1170 specified by Address. The value written to the PCI configuration register is\r
1171 returned. This function must guarantee that all PCI read and write operations\r
1172 are serialized. Extra left bits in OrData are stripped.\r
1173\r
1174 If any reserved bits in Address are set, then ASSERT().\r
1175 If StartBit is greater than 31, then ASSERT().\r
1176 If EndBit is greater than 31, then ASSERT().\r
1177 If EndBit is less than StartBit, then ASSERT().\r
94952554 1178 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
1a3eaf06 1179\r
2fc59a00 1180 @param Address The PCI configuration register to write.\r
1a3eaf06 1181 @param StartBit The ordinal of the least significant bit in the bit field.\r
1182 Range 0..31.\r
1183 @param EndBit The ordinal of the most significant bit in the bit field.\r
1184 Range 0..31.\r
1185 @param OrData The value to OR with the PCI configuration register.\r
1186\r
1187 @return The value written back to the PCI configuration register.\r
1188\r
1189**/\r
1190UINT32\r
1191EFIAPI\r
1192PciSegmentBitFieldOr32 (\r
070a76b1 1193 IN UINT64 Address,\r
1194 IN UINTN StartBit,\r
1195 IN UINTN EndBit,\r
1196 IN UINT32 OrData\r
1a3eaf06 1197 )\r
1198{\r
1199 return PciSegmentWrite32 (\r
1200 Address,\r
1201 BitFieldOr32 (PciSegmentRead32 (Address), StartBit, EndBit, OrData)\r
1202 );\r
1203}\r
1204\r
1205/**\r
1206 Reads a bit field in a 32-bit PCI configuration register, performs a bitwise\r
1207 AND, and writes the result back to the bit field in the 32-bit register.\r
1208\r
070a76b1 1209 \r
1210 Reads the 32-bit PCI configuration register specified by Address, performs a bitwise\r
1211 AND between the read result and the value specified by AndData, and writes the result\r
1212 to the 32-bit PCI configuration register specified by Address. The value written to\r
1213 the PCI configuration register is returned. This function must guarantee that all PCI\r
1214 read and write operations are serialized. Extra left bits in AndData are stripped.\r
1a3eaf06 1215 If any reserved bits in Address are set, then ASSERT().\r
070a76b1 1216 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
1a3eaf06 1217 If StartBit is greater than 31, then ASSERT().\r
1218 If EndBit is greater than 31, then ASSERT().\r
1219 If EndBit is less than StartBit, then ASSERT().\r
94952554 1220 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
1a3eaf06 1221\r
2fc59a00 1222 @param Address The PCI configuration register to write.\r
1a3eaf06 1223 @param StartBit The ordinal of the least significant bit in the bit field.\r
1224 Range 0..31.\r
1225 @param EndBit The ordinal of the most significant bit in the bit field.\r
1226 Range 0..31.\r
1227 @param AndData The value to AND with the PCI configuration register.\r
1228\r
1229 @return The value written back to the PCI configuration register.\r
1230\r
1231**/\r
1232UINT32\r
1233EFIAPI\r
1234PciSegmentBitFieldAnd32 (\r
070a76b1 1235 IN UINT64 Address,\r
1236 IN UINTN StartBit,\r
1237 IN UINTN EndBit,\r
1238 IN UINT32 AndData\r
1a3eaf06 1239 )\r
1240{\r
1241 return PciSegmentWrite32 (\r
1242 Address,\r
1243 BitFieldAnd32 (PciSegmentRead32 (Address), StartBit, EndBit, AndData)\r
1244 );\r
1245}\r
1246\r
1247/**\r
1248 Reads a bit field in a 32-bit port, performs a bitwise AND followed by a\r
62991af2 1249 bitwise OR, and writes the result back to the bit field in the\r
1a3eaf06 1250 32-bit port.\r
1251\r
1252 Reads the 32-bit PCI configuration register specified by Address, performs a\r
62991af2 1253 bitwise AND followed by a bitwise OR between the read result and\r
1a3eaf06 1254 the value specified by AndData, and writes the result to the 32-bit PCI\r
1255 configuration register specified by Address. The value written to the PCI\r
1256 configuration register is returned. This function must guarantee that all PCI\r
1257 read and write operations are serialized. Extra left bits in both AndData and\r
1258 OrData are stripped.\r
1259\r
1260 If any reserved bits in Address are set, then ASSERT().\r
1261 If StartBit is greater than 31, then ASSERT().\r
1262 If EndBit is greater than 31, then ASSERT().\r
1263 If EndBit is less than StartBit, then ASSERT().\r
94952554
LG
1264 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
1265 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().\r
1a3eaf06 1266\r
2fc59a00 1267 @param Address The PCI configuration register to write.\r
1a3eaf06 1268 @param StartBit The ordinal of the least significant bit in the bit field.\r
1269 Range 0..31.\r
1270 @param EndBit The ordinal of the most significant bit in the bit field.\r
1271 Range 0..31.\r
1272 @param AndData The value to AND with the PCI configuration register.\r
1273 @param OrData The value to OR with the result of the AND operation.\r
1274\r
1275 @return The value written back to the PCI configuration register.\r
1276\r
1277**/\r
1278UINT32\r
1279EFIAPI\r
1280PciSegmentBitFieldAndThenOr32 (\r
070a76b1 1281 IN UINT64 Address,\r
1282 IN UINTN StartBit,\r
1283 IN UINTN EndBit,\r
1284 IN UINT32 AndData,\r
1285 IN UINT32 OrData\r
1a3eaf06 1286 )\r
1287{\r
1288 return PciSegmentWrite32 (\r
1289 Address,\r
1290 BitFieldAndThenOr32 (PciSegmentRead32 (Address), StartBit, EndBit, AndData, OrData)\r
1291 );\r
1292}\r
1293\r
1294/**\r
1295 Reads a range of PCI configuration registers into a caller supplied buffer.\r
1296\r
070a76b1 1297 Reads the range of PCI configuration registers specified by StartAddress and\r
1298 Size into the buffer specified by Buffer. This function only allows the PCI\r
1299 configuration registers from a single PCI function to be read. Size is\r
1300 returned. When possible 32-bit PCI configuration read cycles are used to read\r
1301 from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit\r
1302 and 16-bit PCI configuration read cycles may be used at the beginning and the\r
1303 end of the range.\r
1304\r
59ceeabe 1305 If any reserved bits in StartAddress are set, then ASSERT().\r
1a3eaf06 1306 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().\r
1307 If Size > 0 and Buffer is NULL, then ASSERT().\r
1308\r
2fc59a00 1309 @param StartAddress The starting address that encodes the PCI Segment, Bus, Device,\r
070a76b1 1310 Function and Register.\r
2fc59a00 1311 @param Size The size in bytes of the transfer.\r
1312 @param Buffer The pointer to a buffer receiving the data read.\r
1a3eaf06 1313\r
070a76b1 1314 @return Size\r
1a3eaf06 1315\r
1316**/\r
1317UINTN\r
1318EFIAPI\r
1319PciSegmentReadBuffer (\r
070a76b1 1320 IN UINT64 StartAddress,\r
1321 IN UINTN Size,\r
1322 OUT VOID *Buffer\r
1a3eaf06 1323 )\r
1324{\r
1325 UINTN ReturnValue;\r
1326\r
1327 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress, 0);\r
1328 ASSERT (((StartAddress & 0xFFF) + Size) <= 0x1000);\r
1329\r
1330 if (Size == 0) {\r
1331 return Size;\r
1332 }\r
1333\r
1334 ASSERT (Buffer != NULL);\r
1335\r
1336 //\r
1337 // Save Size for return\r
1338 //\r
1339 ReturnValue = Size;\r
1340\r
e43e4b3e 1341 if ((StartAddress & BIT0) != 0) {\r
1a3eaf06 1342 //\r
1343 // Read a byte if StartAddress is byte aligned\r
1344 //\r
1345 *(volatile UINT8 *)Buffer = PciSegmentRead8 (StartAddress);\r
1346 StartAddress += sizeof (UINT8);\r
1347 Size -= sizeof (UINT8);\r
1348 Buffer = (UINT8*)Buffer + 1;\r
1349 }\r
1350\r
e43e4b3e 1351 if (Size >= sizeof (UINT16) && (StartAddress & BIT1) != 0) {\r
1a3eaf06 1352 //\r
1353 // Read a word if StartAddress is word aligned\r
1354 //\r
5dc4fd78 1355 WriteUnaligned16 (Buffer, PciSegmentRead16 (StartAddress));\r
1a3eaf06 1356 StartAddress += sizeof (UINT16);\r
1357 Size -= sizeof (UINT16);\r
1358 Buffer = (UINT16*)Buffer + 1;\r
1359 }\r
1360\r
1361 while (Size >= sizeof (UINT32)) {\r
1362 //\r
1363 // Read as many double words as possible\r
1364 //\r
5dc4fd78 1365 WriteUnaligned32 (Buffer, PciSegmentRead32 (StartAddress));\r
1a3eaf06 1366 StartAddress += sizeof (UINT32);\r
1367 Size -= sizeof (UINT32);\r
1368 Buffer = (UINT32*)Buffer + 1;\r
1369 }\r
1370\r
1371 if (Size >= sizeof (UINT16)) {\r
1372 //\r
1373 // Read the last remaining word if exist\r
1374 //\r
5dc4fd78 1375 WriteUnaligned16 (Buffer, PciSegmentRead16 (StartAddress));\r
1a3eaf06 1376 StartAddress += sizeof (UINT16);\r
1377 Size -= sizeof (UINT16);\r
1378 Buffer = (UINT16*)Buffer + 1;\r
1379 }\r
1380\r
1381 if (Size >= sizeof (UINT8)) {\r
1382 //\r
1383 // Read the last remaining byte if exist\r
1384 //\r
1385 *(volatile UINT8 *)Buffer = PciSegmentRead8 (StartAddress);\r
1386 }\r
1387\r
1388 return ReturnValue;\r
1389}\r
1390\r
1391/**\r
070a76b1 1392 Copies the data in a caller supplied buffer to a specified range of PCI\r
1393 configuration space.\r
1394\r
1395 Writes the range of PCI configuration registers specified by StartAddress and\r
1396 Size from the buffer specified by Buffer. This function only allows the PCI\r
1397 configuration registers from a single PCI function to be written. Size is\r
1398 returned. When possible 32-bit PCI configuration write cycles are used to\r
1399 write from StartAdress to StartAddress + Size. Due to alignment restrictions,\r
1400 8-bit and 16-bit PCI configuration write cycles may be used at the beginning\r
1401 and the end of the range.\r
1402\r
59ceeabe 1403 If any reserved bits in StartAddress are set, then ASSERT().\r
1a3eaf06 1404 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().\r
1405 If Size > 0 and Buffer is NULL, then ASSERT().\r
1406\r
2fc59a00 1407 @param StartAddress The starting address that encodes the PCI Segment, Bus, Device,\r
070a76b1 1408 Function and Register.\r
2fc59a00 1409 @param Size The size in bytes of the transfer.\r
1410 @param Buffer The pointer to a buffer containing the data to write.\r
1a3eaf06 1411\r
34ffd1bb 1412 @return The parameter of Size.\r
1a3eaf06 1413\r
1414**/\r
1415UINTN\r
1416EFIAPI\r
1417PciSegmentWriteBuffer (\r
070a76b1 1418 IN UINT64 StartAddress,\r
1419 IN UINTN Size,\r
1420 IN VOID *Buffer\r
1a3eaf06 1421 )\r
1422{\r
1423 UINTN ReturnValue;\r
1424\r
1425 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (StartAddress, 0);\r
1426 ASSERT (((StartAddress & 0xFFF) + Size) <= 0x1000);\r
1427\r
1428 if (Size == 0) {\r
1429 return 0;\r
1430 }\r
1431\r
1432 ASSERT (Buffer != NULL);\r
1433\r
1434 //\r
1435 // Save Size for return\r
1436 //\r
1437 ReturnValue = Size;\r
1438\r
e43e4b3e 1439 if ((StartAddress & BIT0) != 0) {\r
1a3eaf06 1440 //\r
1441 // Write a byte if StartAddress is byte aligned\r
1442 //\r
1443 PciSegmentWrite8 (StartAddress, *(UINT8*)Buffer);\r
1444 StartAddress += sizeof (UINT8);\r
1445 Size -= sizeof (UINT8);\r
1446 Buffer = (UINT8*)Buffer + 1;\r
1447 }\r
1448\r
e43e4b3e 1449 if (Size >= sizeof (UINT16) && (StartAddress & BIT1) != 0) {\r
1a3eaf06 1450 //\r
1451 // Write a word if StartAddress is word aligned\r
1452 //\r
5dc4fd78 1453 PciSegmentWrite16 (StartAddress, ReadUnaligned16 (Buffer));\r
1a3eaf06 1454 StartAddress += sizeof (UINT16);\r
1455 Size -= sizeof (UINT16);\r
1456 Buffer = (UINT16*)Buffer + 1;\r
1457 }\r
1458\r
1459 while (Size >= sizeof (UINT32)) {\r
1460 //\r
1461 // Write as many double words as possible\r
1462 //\r
5dc4fd78 1463 PciSegmentWrite32 (StartAddress, ReadUnaligned32 (Buffer));\r
1a3eaf06 1464 StartAddress += sizeof (UINT32);\r
1465 Size -= sizeof (UINT32);\r
1466 Buffer = (UINT32*)Buffer + 1;\r
1467 }\r
1468\r
1469 if (Size >= sizeof (UINT16)) {\r
1470 //\r
1471 // Write the last remaining word if exist\r
1472 //\r
5dc4fd78 1473 PciSegmentWrite16 (StartAddress, ReadUnaligned16 (Buffer));\r
1a3eaf06 1474 StartAddress += sizeof (UINT16);\r
1475 Size -= sizeof (UINT16);\r
1476 Buffer = (UINT16*)Buffer + 1;\r
1477 }\r
1478\r
1479 if (Size >= sizeof (UINT8)) {\r
1480 //\r
1481 // Write the last remaining byte if exist\r
1482 //\r
1483 PciSegmentWrite8 (StartAddress, *(UINT8*)Buffer);\r
1484 }\r
1485\r
1486 return ReturnValue;\r
1487}\r