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