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