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