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