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