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