]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - 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
1/** @file\r
2 PCI Segment Library implementation using PCI Root Bridge I/O Protocol.\r
3\r
4 Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>\r
5 This program and the accompanying materials are\r
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
9 http://opensource.org/licenses/bsd-license.php.\r
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
19// Global variable to record data of PCI Root Bridge I/O Protocol instances\r
20//\r
21PCI_ROOT_BRIDGE_DATA *mPciRootBridgeData = NULL;\r
22UINTN mNumberOfPciRootBridges = 0;\r
23\r
24/**\r
25 The constructor function caches data of PCI Root Bridge I/O Protocol instances.\r
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
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
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
138 @param Address The address that encodes the Segment, PCI Bus, Device, Function and\r
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
178 @param Address The address that encodes the PCI Bus, Device, Function and\r
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
200 PCI_TO_PCI_ROOT_BRIDGE_IO_ADDRESS (Address),\r
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
216 @param Address The address that encodes the PCI Bus, Device, Function and\r
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
239 PCI_TO_PCI_ROOT_BRIDGE_IO_ADDRESS (Address),\r
240 1,\r
241 &Data\r
242 );\r
243\r
244 return Data;\r
245}\r
246\r
247/**\r
248 Register a PCI device so PCI configuration registers may be accessed after \r
249 SetVirtualAddressMap().\r
250 \r
251 If any reserved bits in Address are set, then ASSERT().\r
252\r
253 @param Address The address that encodes the PCI Bus, Device, Function and\r
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
271 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 0);\r
272 return RETURN_UNSUPPORTED;\r
273}\r
274\r
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
279 This function must guarantee that all PCI read and write operations are serialized.\r
280 \r
281 If any reserved bits in Address are set, then ASSERT().\r
282 \r
283 @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register.\r
284\r
285 @return The 8-bit PCI configuration register specified by Address.\r
286\r
287**/\r
288UINT8\r
289EFIAPI\r
290PciSegmentRead8 (\r
291 IN UINT64 Address\r
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
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
305 If any reserved bits in Address are set, then ASSERT().\r
306\r
307 @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register.\r
308 @param Value The value to write.\r
309\r
310 @return The value written to the PCI configuration register.\r
311\r
312**/\r
313UINT8\r
314EFIAPI\r
315PciSegmentWrite8 (\r
316 IN UINT64 Address,\r
317 IN UINT8 Value\r
318 )\r
319{\r
320 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 0);\r
321\r
322 return (UINT8) DxePciSegmentLibPciRootBridgeIoWriteWorker (Address, EfiPciWidthUint8, Value);\r
323}\r
324\r
325/**\r
326 Performs a bitwise OR of an 8-bit PCI configuration register with an 8-bit value.\r
327\r
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
334 If any reserved bits in Address are set, then ASSERT().\r
335\r
336 @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register.\r
337 @param OrData The value to OR with the PCI configuration register.\r
338\r
339 @return The value written to the PCI configuration register.\r
340\r
341**/\r
342UINT8\r
343EFIAPI\r
344PciSegmentOr8 (\r
345 IN UINT64 Address,\r
346 IN UINT8 OrData\r
347 )\r
348{\r
349 return PciSegmentWrite8 (Address, (UINT8) (PciSegmentRead8 (Address) | OrData));\r
350}\r
351\r
352/**\r
353 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit value.\r
354\r
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
360 If any reserved bits in Address are set, then ASSERT().\r
361\r
362 @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register.\r
363 @param AndData The value to AND with the PCI configuration register.\r
364\r
365 @return The value written to the PCI configuration register.\r
366\r
367**/\r
368UINT8\r
369EFIAPI\r
370PciSegmentAnd8 (\r
371 IN UINT64 Address,\r
372 IN UINT8 AndData\r
373 )\r
374{\r
375 return PciSegmentWrite8 (Address, (UINT8) (PciSegmentRead8 (Address) & AndData));\r
376}\r
377\r
378/**\r
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
389 If any reserved bits in Address are set, then ASSERT().\r
390\r
391 @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register.\r
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
394\r
395 @return The value written to the PCI configuration register.\r
396\r
397**/\r
398UINT8\r
399EFIAPI\r
400PciSegmentAndThenOr8 (\r
401 IN UINT64 Address,\r
402 IN UINT8 AndData,\r
403 IN UINT8 OrData\r
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
421 @param Address The PCI configuration register to read.\r
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
433 IN UINT64 Address,\r
434 IN UINTN StartBit,\r
435 IN UINTN EndBit\r
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
454 @param Address The PCI configuration register to write.\r
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
459 @param Value The new value of the bit field.\r
460\r
461 @return The value written back to the PCI configuration register.\r
462\r
463**/\r
464UINT8\r
465EFIAPI\r
466PciSegmentBitFieldWrite8 (\r
467 IN UINT64 Address,\r
468 IN UINTN StartBit,\r
469 IN UINTN EndBit,\r
470 IN UINT8 Value\r
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
484 bitwise OR between the read result and the value specified by\r
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
495 @param Address The PCI configuration register to write.\r
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
508 IN UINT64 Address,\r
509 IN UINTN StartBit,\r
510 IN UINTN EndBit,\r
511 IN UINT8 OrData\r
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
536 @param Address The PCI configuration register to write.\r
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
549 IN UINT64 Address,\r
550 IN UINTN StartBit,\r
551 IN UINTN EndBit,\r
552 IN UINT8 AndData\r
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
563 bitwise OR, and writes the result back to the bit field in the\r
564 8-bit port.\r
565\r
566 Reads the 8-bit PCI configuration register specified by Address, performs a\r
567 bitwise AND followed by a bitwise OR between the read result and\r
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
579 @param Address The PCI configuration register to write.\r
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
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
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
610 This function must guarantee that all PCI read and write operations are serialized.\r
611 \r
612 If any reserved bits in Address are set, then ASSERT().\r
613 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
614 \r
615 @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register.\r
616\r
617 @return The 16-bit PCI configuration register specified by Address.\r
618\r
619**/\r
620UINT16\r
621EFIAPI\r
622PciSegmentRead16 (\r
623 IN UINT64 Address\r
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
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
637 If any reserved bits in Address are set, then ASSERT().\r
638 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
639\r
640 @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register.\r
641 @param Value The value to write.\r
642\r
643 @return The parameter of Value.\r
644\r
645**/\r
646UINT16\r
647EFIAPI\r
648PciSegmentWrite16 (\r
649 IN UINT64 Address,\r
650 IN UINT16 Value\r
651 )\r
652{\r
653 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 1);\r
654\r
655 return (UINT16) DxePciSegmentLibPciRootBridgeIoWriteWorker (Address, EfiPciWidthUint16, Value);\r
656}\r
657\r
658/**\r
659 Performs a bitwise OR of a 16-bit PCI configuration register with\r
660 a 16-bit value.\r
661\r
662 Reads the 16-bit PCI configuration register specified by Address, performs a\r
663 bitwise OR between the read result and the value specified by\r
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
670 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
671\r
672 @param Address The address that encodes the PCI Segment, Bus, Device, Function and\r
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
682 IN UINT64 Address,\r
683 IN UINT16 OrData\r
684 )\r
685{\r
686 return PciSegmentWrite16 (Address, (UINT16) (PciSegmentRead16 (Address) | OrData));\r
687}\r
688\r
689/**\r
690 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit value.\r
691\r
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
698 If any reserved bits in Address are set, then ASSERT().\r
699 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
700 \r
701 @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register.\r
702 @param AndData The value to AND with the PCI configuration register.\r
703\r
704 @return The value written to the PCI configuration register.\r
705\r
706**/\r
707UINT16\r
708EFIAPI\r
709PciSegmentAnd16 (\r
710 IN UINT64 Address,\r
711 IN UINT16 AndData\r
712 )\r
713{\r
714 return PciSegmentWrite16 (Address, (UINT16) (PciSegmentRead16 (Address) & AndData));\r
715}\r
716\r
717/**\r
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
728 If any reserved bits in Address are set, then ASSERT().\r
729 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
730\r
731 @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register.\r
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
734\r
735 @return The value written to the PCI configuration register.\r
736\r
737**/\r
738UINT16\r
739EFIAPI\r
740PciSegmentAndThenOr16 (\r
741 IN UINT64 Address,\r
742 IN UINT16 AndData,\r
743 IN UINT16 OrData\r
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
757 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
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
762 @param Address The PCI configuration register to read.\r
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
774 IN UINT64 Address,\r
775 IN UINTN StartBit,\r
776 IN UINTN EndBit\r
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
791 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
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
796 @param Address The PCI configuration register to write.\r
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
801 @param Value The new value of the bit field.\r
802\r
803 @return The value written back to the PCI configuration register.\r
804\r
805**/\r
806UINT16\r
807EFIAPI\r
808PciSegmentBitFieldWrite16 (\r
809 IN UINT64 Address,\r
810 IN UINTN StartBit,\r
811 IN UINTN EndBit,\r
812 IN UINT16 Value\r
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
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
825\r
826 If any reserved bits in Address are set, then ASSERT().\r
827 If Address is not aligned on a 16-bit boundary, then ASSERT().\r
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
832 @param Address The PCI configuration register to write.\r
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
845 IN UINT64 Address,\r
846 IN UINTN StartBit,\r
847 IN UINTN EndBit,\r
848 IN UINT16 OrData\r
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
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
868 If any reserved bits in Address are set, then ASSERT().\r
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
872 If EndBit is less than StartBit, then ASSERT().\r
873\r
874 @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register.\r
875 @param StartBit The ordinal of the least significant bit in the bit field.\r
876 The ordinal of the least significant bit in a byte is bit 0.\r
877 @param EndBit The ordinal of the most significant bit in the bit field.\r
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
880\r
881 @return The value written to the PCI configuration register.\r
882\r
883**/\r
884UINT16\r
885EFIAPI\r
886PciSegmentBitFieldAnd16 (\r
887 IN UINT64 Address,\r
888 IN UINTN StartBit,\r
889 IN UINTN EndBit,\r
890 IN UINT16 AndData\r
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
901 bitwise OR, and writes the result back to the bit field in the\r
902 16-bit port.\r
903\r
904 Reads the 16-bit PCI configuration register specified by Address, performs a\r
905 bitwise AND followed by a bitwise OR between the read result and\r
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
917 @param Address The PCI configuration register to write.\r
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
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
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
948 This function must guarantee that all PCI read and write operations are serialized.\r
949 \r
950 If any reserved bits in Address are set, then ASSERT().\r
951 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
952\r
953 @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register.\r
954\r
955 @return The 32-bit PCI configuration register specified by Address.\r
956\r
957**/\r
958UINT32\r
959EFIAPI\r
960PciSegmentRead32 (\r
961 IN UINT64 Address\r
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
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
975 If any reserved bits in Address are set, then ASSERT().\r
976 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
977\r
978 @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register.\r
979 @param Value The value to write.\r
980\r
981 @return The parameter of Value.\r
982\r
983**/\r
984UINT32\r
985EFIAPI\r
986PciSegmentWrite32 (\r
987 IN UINT64 Address,\r
988 IN UINT32 Value\r
989 )\r
990{\r
991 ASSERT_INVALID_PCI_SEGMENT_ADDRESS (Address, 3);\r
992\r
993 return DxePciSegmentLibPciRootBridgeIoWriteWorker (Address, EfiPciWidthUint32, Value);\r
994}\r
995\r
996/**\r
997 Performs a bitwise OR of a 32-bit PCI configuration register with a 32-bit value.\r
998\r
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
1005 If any reserved bits in Address are set, then ASSERT().\r
1006 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
1007\r
1008 @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register.\r
1009 @param OrData The value to OR with the PCI configuration register.\r
1010\r
1011 @return The value written to the PCI configuration register.\r
1012\r
1013**/\r
1014UINT32\r
1015EFIAPI\r
1016PciSegmentOr32 (\r
1017 IN UINT64 Address,\r
1018 IN UINT32 OrData\r
1019 )\r
1020{\r
1021 return PciSegmentWrite32 (Address, PciSegmentRead32 (Address) | OrData);\r
1022}\r
1023\r
1024/**\r
1025 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit value.\r
1026\r
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
1033 If any reserved bits in Address are set, then ASSERT().\r
1034 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
1035\r
1036 @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register.\r
1037 @param AndData The value to AND with the PCI configuration register.\r
1038\r
1039 @return The value written to the PCI configuration register.\r
1040\r
1041**/\r
1042UINT32\r
1043EFIAPI\r
1044PciSegmentAnd32 (\r
1045 IN UINT64 Address,\r
1046 IN UINT32 AndData\r
1047 )\r
1048{\r
1049 return PciSegmentWrite32 (Address, PciSegmentRead32 (Address) & AndData);\r
1050}\r
1051\r
1052/**\r
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
1063 If any reserved bits in Address are set, then ASSERT().\r
1064 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
1065\r
1066 @param Address The address that encodes the PCI Segment, Bus, Device, Function, and Register.\r
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
1069\r
1070 @return The value written to the PCI configuration register.\r
1071\r
1072**/\r
1073UINT32\r
1074EFIAPI\r
1075PciSegmentAndThenOr32 (\r
1076 IN UINT64 Address,\r
1077 IN UINT32 AndData,\r
1078 IN UINT32 OrData\r
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
1092 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
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
1097 @param Address The PCI configuration register to read.\r
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
1109 IN UINT64 Address,\r
1110 IN UINTN StartBit,\r
1111 IN UINTN EndBit\r
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
1126 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
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
1131 @param Address The PCI configuration register to write.\r
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
1136 @param Value The new value of the bit field.\r
1137\r
1138 @return The value written back to the PCI configuration register.\r
1139\r
1140**/\r
1141UINT32\r
1142EFIAPI\r
1143PciSegmentBitFieldWrite32 (\r
1144 IN UINT64 Address,\r
1145 IN UINTN StartBit,\r
1146 IN UINTN EndBit,\r
1147 IN UINT32 Value\r
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
1161 bitwise OR between the read result and the value specified by\r
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
1172 @param Address The PCI configuration register to write.\r
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
1185 IN UINT64 Address,\r
1186 IN UINTN StartBit,\r
1187 IN UINTN EndBit,\r
1188 IN UINT32 OrData\r
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
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
1207 If any reserved bits in Address are set, then ASSERT().\r
1208 If Address is not aligned on a 32-bit boundary, then ASSERT().\r
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
1212 \r
1213\r
1214 @param Address The PCI configuration register to write.\r
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
1227 IN UINT64 Address,\r
1228 IN UINTN StartBit,\r
1229 IN UINTN EndBit,\r
1230 IN UINT32 AndData\r
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
1241 bitwise OR, and writes the result back to the bit field in the\r
1242 32-bit port.\r
1243\r
1244 Reads the 32-bit PCI configuration register specified by Address, performs a\r
1245 bitwise AND followed by a bitwise OR between the read result and\r
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
1257 @param Address The PCI configuration register to write.\r
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
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
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
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
1295 If any reserved bits in StartAddress are set, then ASSERT().\r
1296 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().\r
1297 If Size > 0 and Buffer is NULL, then ASSERT().\r
1298\r
1299 @param StartAddress The starting address that encodes the PCI Segment, Bus, Device,\r
1300 Function and Register.\r
1301 @param Size The size in bytes of the transfer.\r
1302 @param Buffer The pointer to a buffer receiving the data read.\r
1303\r
1304 @return Size\r
1305\r
1306**/\r
1307UINTN\r
1308EFIAPI\r
1309PciSegmentReadBuffer (\r
1310 IN UINT64 StartAddress,\r
1311 IN UINTN Size,\r
1312 OUT VOID *Buffer\r
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
1331 if ((StartAddress & BIT0) != 0) {\r
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
1341 if (Size >= sizeof (UINT16) && (StartAddress & BIT1) != 0) {\r
1342 //\r
1343 // Read a word if StartAddress is word aligned\r
1344 //\r
1345 WriteUnaligned16 (Buffer, PciSegmentRead16 (StartAddress));\r
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
1355 WriteUnaligned32 (Buffer, PciSegmentRead32 (StartAddress));\r
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
1365 WriteUnaligned16 (Buffer, PciSegmentRead16 (StartAddress));\r
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
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
1393 If any reserved bits in StartAddress are set, then ASSERT().\r
1394 If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().\r
1395 If Size > 0 and Buffer is NULL, then ASSERT().\r
1396\r
1397 @param StartAddress The starting address that encodes the PCI Segment, Bus, Device,\r
1398 Function and Register.\r
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
1401\r
1402 @return The parameter of Size.\r
1403\r
1404**/\r
1405UINTN\r
1406EFIAPI\r
1407PciSegmentWriteBuffer (\r
1408 IN UINT64 StartAddress,\r
1409 IN UINTN Size,\r
1410 IN VOID *Buffer\r
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
1429 if ((StartAddress & BIT0) != 0) {\r
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
1439 if (Size >= sizeof (UINT16) && (StartAddress & BIT1) != 0) {\r
1440 //\r
1441 // Write a word if StartAddress is word aligned\r
1442 //\r
1443 PciSegmentWrite16 (StartAddress, ReadUnaligned16 (Buffer));\r
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
1453 PciSegmentWrite32 (StartAddress, ReadUnaligned32 (Buffer));\r
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
1463 PciSegmentWrite16 (StartAddress, ReadUnaligned16 (Buffer));\r
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