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