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