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