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