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