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