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