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