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