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