]> git.proxmox.com Git - mirror_edk2.git/blob - MdePkg/Library/BasePciCf8Lib/PciCf8Lib.c
Update BASE PCI Library that uses CF8/CFC access mechanism for PCI configuration...
[mirror_edk2.git] / MdePkg / Library / BasePciCf8Lib / PciCf8Lib.c
1 /** @file
2 PCI CF8 Library functions that use I/O ports 0xCF8 and 0xCFC to perform PCI Configuration cycles.
3 Layers on top of an I/O Library instance.
4
5 Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php.
10
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13
14 **/
15
16
17 #include <Base.h>
18
19 #include <Library/BaseLib.h>
20 #include <Library/PciCf8Lib.h>
21 #include <Library/IoLib.h>
22 #include <Library/DebugLib.h>
23
24 //
25 // Declare I/O Ports used to perform PCI Confguration Cycles
26 //
27 #define PCI_CONFIGURATION_ADDRESS_PORT 0xCF8
28 #define PCI_CONFIGURATION_DATA_PORT 0xCFC
29
30 /**
31 Convert a PCI Library address to PCI CF8 formatted address.
32
33 Declare macro to convert PCI Library address to PCI CF8 formatted address.
34 Bit fields of PCI Library and CF8 formatted address is as follows:
35 PCI Library formatted address CF8 Formatted Address
36 ============================= ======================
37 Bits 00..11 Register Bits 00..07 Register
38 Bits 12..14 Function Bits 08..10 Function
39 Bits 15..19 Device Bits 11..15 Device
40 Bits 20..27 Bus Bits 16..23 Bus
41 Bits 28..31 Reserved(MBZ) Bits 24..30 Reserved(MBZ)
42 Bits 31..31 Must be 1
43
44 @param A The address to convert.
45
46 @retval The coverted address.
47
48 **/
49 #define PCI_TO_CF8_ADDRESS(A) \
50 ((UINT32) ((((A) >> 4) & 0x00ffff00) | ((A) & 0xfc) | 0x80000000))
51
52 /**
53 Assert the validity of a PCI CF8 address. A valid PCI CF8 address should contain 1's
54 only in the low 28 bits, excluding bits 08..11.
55
56 @param A The address to validate.
57 @param M Additional bits to assert to be zero.
58
59 **/
60 #define ASSERT_INVALID_PCI_ADDRESS(A,M) \
61 ASSERT (((A) & (~0xffff0ff | (M))) == 0)
62
63 /**
64 Registers a PCI device so PCI configuration registers may be accessed after
65 SetVirtualAddressMap().
66
67 Registers the PCI device specified by Address so all the PCI configuration registers
68 associated with that PCI device may be accessed after SetVirtualAddressMap() is called.
69
70 If Address > 0x0FFFFFFF, then ASSERT().
71 If the register specified by Address >= 0x100, then ASSERT().
72
73 @param Address The address that encodes the PCI Bus, Device, Function and
74 Register.
75
76 @retval RETURN_SUCCESS The PCI device was registered for runtime access.
77 @retval RETURN_UNSUPPORTED An attempt was made to call this function
78 after ExitBootServices().
79 @retval RETURN_UNSUPPORTED The resources required to access the PCI device
80 at runtime could not be mapped.
81 @retval RETURN_OUT_OF_RESOURCES There are not enough resources available to
82 complete the registration.
83
84 **/
85 RETURN_STATUS
86 EFIAPI
87 PciCf8RegisterForRuntimeAccess (
88 IN UINTN Address
89 )
90 {
91 ASSERT_INVALID_PCI_ADDRESS (Address, 0);
92 return RETURN_SUCCESS;
93 }
94
95 /**
96 Reads an 8-bit PCI configuration register.
97
98 Reads and returns the 8-bit PCI configuration register specified by Address.
99 This function must guarantee that all PCI read and write operations are
100 serialized.
101
102 If Address > 0x0FFFFFFF, then ASSERT().
103 If the register specified by Address >= 0x100, then ASSERT().
104
105 @param Address The address that encodes the PCI Bus, Device, Function and
106 Register.
107
108 @return The read value from the PCI configuration register.
109
110 **/
111 UINT8
112 EFIAPI
113 PciCf8Read8 (
114 IN UINTN Address
115 )
116 {
117 BOOLEAN InterruptState;
118 UINT32 AddressPort;
119 UINT8 Result;
120
121 ASSERT_INVALID_PCI_ADDRESS (Address, 0);
122 InterruptState = SaveAndDisableInterrupts ();
123 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);
124 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));
125 Result = IoRead8 (PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3));
126 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);
127 SetInterruptState (InterruptState);
128 return Result;
129 }
130
131 /**
132 Writes an 8-bit PCI configuration register.
133
134 Writes the 8-bit PCI configuration register specified by Address with the
135 value specified by Value. Value is returned. This function must guarantee
136 that all PCI read and write operations are serialized.
137
138 If Address > 0x0FFFFFFF, then ASSERT().
139 If the register specified by Address >= 0x100, then ASSERT().
140
141 @param Address The address that encodes the PCI Bus, Device, Function and
142 Register.
143 @param Value The value to write.
144
145 @return The value written to the PCI configuration register.
146
147 **/
148 UINT8
149 EFIAPI
150 PciCf8Write8 (
151 IN UINTN Address,
152 IN UINT8 Value
153 )
154 {
155 BOOLEAN InterruptState;
156 UINT32 AddressPort;
157 UINT8 Result;
158
159 ASSERT_INVALID_PCI_ADDRESS (Address, 0);
160 InterruptState = SaveAndDisableInterrupts ();
161 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);
162 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));
163 Result = IoWrite8 (
164 PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3),
165 Value
166 );
167 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);
168 SetInterruptState (InterruptState);
169 return Result;
170 }
171
172 /**
173 Performs a bitwise OR of an 8-bit PCI configuration register with
174 an 8-bit value.
175
176 Reads the 8-bit PCI configuration register specified by Address, performs a
177 bitwise OR between the read result and the value specified by
178 OrData, and writes the result to the 8-bit PCI configuration register
179 specified by Address. The value written to the PCI configuration register is
180 returned. This function must guarantee that all PCI read and write operations
181 are serialized.
182
183 If Address > 0x0FFFFFFF, then ASSERT().
184 If the register specified by Address >= 0x100, then ASSERT().
185
186 @param Address The address that encodes the PCI Bus, Device, Function and
187 Register.
188 @param OrData The value to OR with the PCI configuration register.
189
190 @return The value written back to the PCI configuration register.
191
192 **/
193 UINT8
194 EFIAPI
195 PciCf8Or8 (
196 IN UINTN Address,
197 IN UINT8 OrData
198 )
199 {
200 BOOLEAN InterruptState;
201 UINT32 AddressPort;
202 UINT8 Result;
203
204 ASSERT_INVALID_PCI_ADDRESS (Address, 0);
205 InterruptState = SaveAndDisableInterrupts ();
206 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);
207 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));
208 Result = IoOr8 (
209 PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3),
210 OrData
211 );
212 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);
213 SetInterruptState (InterruptState);
214 return Result;
215 }
216
217 /**
218 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
219 value.
220
221 Reads the 8-bit PCI configuration register specified by Address, performs a
222 bitwise AND between the read result and the value specified by AndData, and
223 writes the result to the 8-bit PCI configuration register specified by
224 Address. The value written to the PCI configuration register is returned.
225 This function must guarantee that all PCI read and write operations are
226 serialized.
227
228 If Address > 0x0FFFFFFF, then ASSERT().
229 If the register specified by Address >= 0x100, then ASSERT().
230
231 @param Address The address that encodes the PCI Bus, Device, Function and
232 Register.
233 @param AndData The value to AND with the PCI configuration register.
234
235 @return The value written back to the PCI configuration register.
236
237 **/
238 UINT8
239 EFIAPI
240 PciCf8And8 (
241 IN UINTN Address,
242 IN UINT8 AndData
243 )
244 {
245 BOOLEAN InterruptState;
246 UINT32 AddressPort;
247 UINT8 Result;
248
249 ASSERT_INVALID_PCI_ADDRESS (Address, 0);
250 InterruptState = SaveAndDisableInterrupts ();
251 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);
252 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));
253 Result = IoAnd8 (
254 PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3),
255 AndData
256 );
257 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);
258 SetInterruptState (InterruptState);
259 return Result;
260 }
261
262 /**
263 Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
264 value, followed a bitwise OR with another 8-bit value.
265
266 Reads the 8-bit PCI configuration register specified by Address, performs a
267 bitwise AND between the read result and the value specified by AndData,
268 performs a bitwise OR between the result of the AND operation and
269 the value specified by OrData, and writes the result to the 8-bit PCI
270 configuration register specified by Address. The value written to the PCI
271 configuration register is returned. This function must guarantee that all PCI
272 read and write operations are serialized.
273
274 If Address > 0x0FFFFFFF, then ASSERT().
275 If the register specified by Address >= 0x100, then ASSERT().
276
277 @param Address The address that encodes the PCI Bus, Device, Function and
278 Register.
279 @param AndData The value to AND with the PCI configuration register.
280 @param OrData The value to OR with the result of the AND operation.
281
282 @return The value written back to the PCI configuration register.
283
284 **/
285 UINT8
286 EFIAPI
287 PciCf8AndThenOr8 (
288 IN UINTN Address,
289 IN UINT8 AndData,
290 IN UINT8 OrData
291 )
292 {
293 BOOLEAN InterruptState;
294 UINT32 AddressPort;
295 UINT8 Result;
296
297 ASSERT_INVALID_PCI_ADDRESS (Address, 0);
298 InterruptState = SaveAndDisableInterrupts ();
299 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);
300 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));
301 Result = IoAndThenOr8 (
302 PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3),
303 AndData,
304 OrData
305 );
306 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);
307 SetInterruptState (InterruptState);
308 return Result;
309 }
310
311 /**
312 Reads a bit field of a PCI configuration register.
313
314 Reads the bit field in an 8-bit PCI configuration register. The bit field is
315 specified by the StartBit and the EndBit. The value of the bit field is
316 returned.
317
318 If Address > 0x0FFFFFFF, then ASSERT().
319 If the register specified by Address >= 0x100, then ASSERT().
320 If StartBit is greater than 7, then ASSERT().
321 If EndBit is greater than 7, then ASSERT().
322 If EndBit is less than StartBit, then ASSERT().
323
324 @param Address The PCI configuration register to read.
325 @param StartBit The ordinal of the least significant bit in the bit field.
326 Range 0..7.
327 @param EndBit The ordinal of the most significant bit in the bit field.
328 Range 0..7.
329
330 @return The value of the bit field read from the PCI configuration register.
331
332 **/
333 UINT8
334 EFIAPI
335 PciCf8BitFieldRead8 (
336 IN UINTN Address,
337 IN UINTN StartBit,
338 IN UINTN EndBit
339 )
340 {
341 BOOLEAN InterruptState;
342 UINT32 AddressPort;
343 UINT8 Result;
344
345 ASSERT_INVALID_PCI_ADDRESS (Address, 0);
346 InterruptState = SaveAndDisableInterrupts ();
347 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);
348 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));
349 Result = IoBitFieldRead8 (
350 PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3),
351 StartBit,
352 EndBit
353 );
354 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);
355 SetInterruptState (InterruptState);
356 return Result;
357 }
358
359 /**
360 Writes a bit field to a PCI configuration register.
361
362 Writes Value to the bit field of the PCI configuration register. The bit
363 field is specified by the StartBit and the EndBit. All other bits in the
364 destination PCI configuration register are preserved. The new value of the
365 8-bit register is returned.
366
367 If Address > 0x0FFFFFFF, then ASSERT().
368 If the register specified by Address >= 0x100, then ASSERT().
369 If StartBit is greater than 7, then ASSERT().
370 If EndBit is greater than 7, then ASSERT().
371 If EndBit is less than StartBit, then ASSERT().
372
373 @param Address The PCI configuration register to write.
374 @param StartBit The ordinal of the least significant bit in the bit field.
375 Range 0..7.
376 @param EndBit The ordinal of the most significant bit in the bit field.
377 Range 0..7.
378 @param Value The new value of the bit field.
379
380 @return The value written back to the PCI configuration register.
381
382 **/
383 UINT8
384 EFIAPI
385 PciCf8BitFieldWrite8 (
386 IN UINTN Address,
387 IN UINTN StartBit,
388 IN UINTN EndBit,
389 IN UINT8 Value
390 )
391 {
392 BOOLEAN InterruptState;
393 UINT32 AddressPort;
394 UINT8 Result;
395
396 ASSERT_INVALID_PCI_ADDRESS (Address, 0);
397 InterruptState = SaveAndDisableInterrupts ();
398 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);
399 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));
400 Result = IoBitFieldWrite8 (
401 PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3),
402 StartBit,
403 EndBit,
404 Value
405 );
406 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);
407 SetInterruptState (InterruptState);
408 return Result;
409 }
410
411 /**
412 Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and
413 writes the result back to the bit field in the 8-bit port.
414
415 Reads the 8-bit PCI configuration register specified by Address, performs a
416 bitwise OR between the read result and the value specified by
417 OrData, and writes the result to the 8-bit PCI configuration register
418 specified by Address. The value written to the PCI configuration register is
419 returned. This function must guarantee that all PCI read and write operations
420 are serialized. Extra left bits in OrData are stripped.
421
422 If Address > 0x0FFFFFFF, then ASSERT().
423 If the register specified by Address >= 0x100, then ASSERT().
424 If StartBit is greater than 7, then ASSERT().
425 If EndBit is greater than 7, then ASSERT().
426 If EndBit is less than StartBit, then ASSERT().
427
428 @param Address The PCI configuration register to write.
429 @param StartBit The ordinal of the least significant bit in the bit field.
430 Range 0..7.
431 @param EndBit The ordinal of the most significant bit in the bit field.
432 Range 0..7.
433 @param OrData The value to OR with the PCI configuration register.
434
435 @return The value written back to the PCI configuration register.
436
437 **/
438 UINT8
439 EFIAPI
440 PciCf8BitFieldOr8 (
441 IN UINTN Address,
442 IN UINTN StartBit,
443 IN UINTN EndBit,
444 IN UINT8 OrData
445 )
446 {
447 BOOLEAN InterruptState;
448 UINT32 AddressPort;
449 UINT8 Result;
450
451 ASSERT_INVALID_PCI_ADDRESS (Address, 0);
452 InterruptState = SaveAndDisableInterrupts ();
453 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);
454 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));
455 Result = IoBitFieldOr8 (
456 PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3),
457 StartBit,
458 EndBit,
459 OrData
460 );
461 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);
462 SetInterruptState (InterruptState);
463 return Result;
464 }
465
466 /**
467 Reads a bit field in an 8-bit PCI configuration register, performs a bitwise
468 AND, and writes the result back to the bit field in the 8-bit register.
469
470 Reads the 8-bit PCI configuration register specified by Address, performs a
471 bitwise AND between the read result and the value specified by AndData, and
472 writes the result to the 8-bit PCI configuration register specified by
473 Address. The value written to the PCI configuration register is returned.
474 This function must guarantee that all PCI read and write operations are
475 serialized. Extra left bits in AndData are stripped.
476
477 If Address > 0x0FFFFFFF, then ASSERT().
478 If the register specified by Address >= 0x100, then ASSERT().
479 If StartBit is greater than 7, then ASSERT().
480 If EndBit is greater than 7, then ASSERT().
481 If EndBit is less than StartBit, then ASSERT().
482
483 @param Address The PCI configuration register to write.
484 @param StartBit The ordinal of the least significant bit in the bit field.
485 Range 0..7.
486 @param EndBit The ordinal of the most significant bit in the bit field.
487 Range 0..7.
488 @param AndData The value to AND with the PCI configuration register.
489
490 @return The value written back to the PCI configuration register.
491
492 **/
493 UINT8
494 EFIAPI
495 PciCf8BitFieldAnd8 (
496 IN UINTN Address,
497 IN UINTN StartBit,
498 IN UINTN EndBit,
499 IN UINT8 AndData
500 )
501 {
502 BOOLEAN InterruptState;
503 UINT32 AddressPort;
504 UINT8 Result;
505
506 ASSERT_INVALID_PCI_ADDRESS (Address, 0);
507 InterruptState = SaveAndDisableInterrupts ();
508 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);
509 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));
510 Result = IoBitFieldAnd8 (
511 PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3),
512 StartBit,
513 EndBit,
514 AndData
515 );
516 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);
517 SetInterruptState (InterruptState);
518 return Result;
519 }
520
521 /**
522 Reads a bit field in an 8-bit port, performs a bitwise AND followed by a
523 bitwise OR, and writes the result back to the bit field in the
524 8-bit port.
525
526 Reads the 8-bit PCI configuration register specified by Address, performs a
527 bitwise AND followed by a bitwise OR between the read result and
528 the value specified by AndData, and writes the result to the 8-bit PCI
529 configuration register specified by Address. The value written to the PCI
530 configuration register is returned. This function must guarantee that all PCI
531 read and write operations are serialized. Extra left bits in both AndData and
532 OrData are stripped.
533
534 If Address > 0x0FFFFFFF, then ASSERT().
535 If the register specified by Address >= 0x100, then ASSERT().
536 If StartBit is greater than 7, then ASSERT().
537 If EndBit is greater than 7, then ASSERT().
538 If EndBit is less than StartBit, then ASSERT().
539
540 @param Address The PCI configuration register to write.
541 @param StartBit The ordinal of the least significant bit in the bit field.
542 Range 0..7.
543 @param EndBit The ordinal of the most significant bit in the bit field.
544 Range 0..7.
545 @param AndData The value to AND with the PCI configuration register.
546 @param OrData The value to OR with the result of the AND operation.
547
548 @return The value written back to the PCI configuration register.
549
550 **/
551 UINT8
552 EFIAPI
553 PciCf8BitFieldAndThenOr8(
554 IN UINTN Address,
555 IN UINTN StartBit,
556 IN UINTN EndBit,
557 IN UINT8 AndData,
558 IN UINT8 OrData
559 )
560 {
561 BOOLEAN InterruptState;
562 UINT32 AddressPort;
563 UINT8 Result;
564
565 ASSERT_INVALID_PCI_ADDRESS (Address, 0);
566 InterruptState = SaveAndDisableInterrupts ();
567 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);
568 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));
569 Result = IoBitFieldAndThenOr8 (
570 PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3),
571 StartBit,
572 EndBit,
573 AndData,
574 OrData
575 );
576 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);
577 SetInterruptState (InterruptState);
578 return Result;
579 }
580
581 /**
582 Reads a 16-bit PCI configuration register.
583
584 Reads and returns the 16-bit PCI configuration register specified by Address.
585 This function must guarantee that all PCI read and write operations are
586 serialized.
587
588 If Address > 0x0FFFFFFF, then ASSERT().
589 If Address is not aligned on a 16-bit boundary, then ASSERT().
590 If the register specified by Address >= 0x100, then ASSERT().
591
592 @param Address The address that encodes the PCI Bus, Device, Function and
593 Register.
594
595 @return The read value from the PCI configuration register.
596
597 **/
598 UINT16
599 EFIAPI
600 PciCf8Read16 (
601 IN UINTN Address
602 )
603 {
604 BOOLEAN InterruptState;
605 UINT32 AddressPort;
606 UINT16 Result;
607
608 ASSERT_INVALID_PCI_ADDRESS (Address, 1);
609 InterruptState = SaveAndDisableInterrupts ();
610 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);
611 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));
612 Result = IoRead16 (PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2));
613 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);
614 SetInterruptState (InterruptState);
615 return Result;
616 }
617
618 /**
619 Writes a 16-bit PCI configuration register.
620
621 Writes the 16-bit PCI configuration register specified by Address with the
622 value specified by Value. Value is returned. This function must guarantee
623 that all PCI read and write operations are serialized.
624
625 If Address > 0x0FFFFFFF, then ASSERT().
626 If Address is not aligned on a 16-bit boundary, then ASSERT().
627 If the register specified by Address >= 0x100, then ASSERT().
628
629 @param Address The address that encodes the PCI Bus, Device, Function and
630 Register.
631 @param Value The value to write.
632
633 @return The value written to the PCI configuration register.
634
635 **/
636 UINT16
637 EFIAPI
638 PciCf8Write16 (
639 IN UINTN Address,
640 IN UINT16 Value
641 )
642 {
643 BOOLEAN InterruptState;
644 UINT32 AddressPort;
645 UINT16 Result;
646
647 ASSERT_INVALID_PCI_ADDRESS (Address, 1);
648 InterruptState = SaveAndDisableInterrupts ();
649 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);
650 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));
651 Result = IoWrite16 (
652 PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),
653 Value
654 );
655 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);
656 SetInterruptState (InterruptState);
657 return Result;
658 }
659
660 /**
661 Performs a bitwise OR of a 16-bit PCI configuration register with
662 a 16-bit value.
663
664 Reads the 16-bit PCI configuration register specified by Address, performs a
665 bitwise OR between the read result and the value specified by
666 OrData, and writes the result to the 16-bit PCI configuration register
667 specified by Address. The value written to the PCI configuration register is
668 returned. This function must guarantee that all PCI read and write operations
669 are serialized.
670
671 If Address > 0x0FFFFFFF, then ASSERT().
672 If Address is not aligned on a 16-bit boundary, then ASSERT().
673 If the register specified by Address >= 0x100, then ASSERT().
674
675 @param Address The address that encodes the PCI Bus, Device, Function and
676 Register.
677 @param OrData The value to OR with the PCI configuration register.
678
679 @return The value written back to the PCI configuration register.
680
681 **/
682 UINT16
683 EFIAPI
684 PciCf8Or16 (
685 IN UINTN Address,
686 IN UINT16 OrData
687 )
688 {
689 BOOLEAN InterruptState;
690 UINT32 AddressPort;
691 UINT16 Result;
692
693 ASSERT_INVALID_PCI_ADDRESS (Address, 1);
694 InterruptState = SaveAndDisableInterrupts ();
695 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);
696 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));
697 Result = IoOr16 (
698 PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),
699 OrData
700 );
701 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);
702 SetInterruptState (InterruptState);
703 return Result;
704 }
705
706 /**
707 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
708 value.
709
710 Reads the 16-bit PCI configuration register specified by Address, performs a
711 bitwise AND between the read result and the value specified by AndData, and
712 writes the result to the 16-bit PCI configuration register specified by
713 Address. The value written to the PCI configuration register is returned.
714 This function must guarantee that all PCI read and write operations are
715 serialized.
716
717 If Address > 0x0FFFFFFF, then ASSERT().
718 If Address is not aligned on a 16-bit boundary, then ASSERT().
719 If the register specified by Address >= 0x100, then ASSERT().
720
721 @param Address The address that encodes the PCI Bus, Device, Function and
722 Register.
723 @param AndData The value to AND with the PCI configuration register.
724
725 @return The value written back to the PCI configuration register.
726
727 **/
728 UINT16
729 EFIAPI
730 PciCf8And16 (
731 IN UINTN Address,
732 IN UINT16 AndData
733 )
734 {
735 BOOLEAN InterruptState;
736 UINT32 AddressPort;
737 UINT16 Result;
738
739 ASSERT_INVALID_PCI_ADDRESS (Address, 1);
740 InterruptState = SaveAndDisableInterrupts ();
741 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);
742 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));
743 Result = IoAnd16 (
744 PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),
745 AndData
746 );
747 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);
748 SetInterruptState (InterruptState);
749 return Result;
750 }
751
752 /**
753 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
754 value, followed a bitwise OR with another 16-bit value.
755
756 Reads the 16-bit PCI configuration register specified by Address, performs a
757 bitwise AND between the read result and the value specified by AndData,
758 performs a bitwise OR between the result of the AND operation and
759 the value specified by OrData, and writes the result to the 16-bit PCI
760 configuration register specified by Address. The value written to the PCI
761 configuration register is returned. This function must guarantee that all PCI
762 read and write operations are serialized.
763
764 If Address > 0x0FFFFFFF, then ASSERT().
765 If Address is not aligned on a 16-bit boundary, then ASSERT().
766 If the register specified by Address >= 0x100, then ASSERT().
767
768 @param Address The address that encodes the PCI Bus, Device, Function and
769 Register.
770 @param AndData The value to AND with the PCI configuration register.
771 @param OrData The value to OR with the result of the AND operation.
772
773 @return The value written back to the PCI configuration register.
774
775 **/
776 UINT16
777 EFIAPI
778 PciCf8AndThenOr16 (
779 IN UINTN Address,
780 IN UINT16 AndData,
781 IN UINT16 OrData
782 )
783 {
784 BOOLEAN InterruptState;
785 UINT32 AddressPort;
786 UINT16 Result;
787
788 ASSERT_INVALID_PCI_ADDRESS (Address, 1);
789 InterruptState = SaveAndDisableInterrupts ();
790 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);
791 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));
792 Result = IoAndThenOr16 (
793 PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),
794 AndData,
795 OrData
796 );
797 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);
798 SetInterruptState (InterruptState);
799 return Result;
800 }
801
802 /**
803 Reads a bit field of a PCI configuration register.
804
805 Reads the bit field in a 16-bit PCI configuration register. The bit field is
806 specified by the StartBit and the EndBit. The value of the bit field is
807 returned.
808
809 If Address > 0x0FFFFFFF, then ASSERT().
810 If Address is not aligned on a 16-bit boundary, then ASSERT().
811 If the register specified by Address >= 0x100, then ASSERT().
812 If StartBit is greater than 15, then ASSERT().
813 If EndBit is greater than 15, then ASSERT().
814 If EndBit is less than StartBit, then ASSERT().
815
816 @param Address The PCI configuration register to read.
817 @param StartBit The ordinal of the least significant bit in the bit field.
818 Range 0..15.
819 @param EndBit The ordinal of the most significant bit in the bit field.
820 Range 0..15.
821
822 @return The value of the bit field read from the PCI configuration register.
823
824 **/
825 UINT16
826 EFIAPI
827 PciCf8BitFieldRead16 (
828 IN UINTN Address,
829 IN UINTN StartBit,
830 IN UINTN EndBit
831 )
832 {
833 BOOLEAN InterruptState;
834 UINT32 AddressPort;
835 UINT16 Result;
836
837 ASSERT_INVALID_PCI_ADDRESS (Address, 1);
838 InterruptState = SaveAndDisableInterrupts ();
839 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);
840 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));
841 Result = IoBitFieldRead16 (
842 PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),
843 StartBit,
844 EndBit
845 );
846 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);
847 SetInterruptState (InterruptState);
848 return Result;
849 }
850
851 /**
852 Writes a bit field to a PCI configuration register.
853
854 Writes Value to the bit field of the PCI configuration register. The bit
855 field is specified by the StartBit and the EndBit. All other bits in the
856 destination PCI configuration register are preserved. The new value of the
857 16-bit register is returned.
858
859 If Address > 0x0FFFFFFF, then ASSERT().
860 If Address is not aligned on a 16-bit boundary, then ASSERT().
861 If the register specified by Address >= 0x100, then ASSERT().
862 If StartBit is greater than 15, then ASSERT().
863 If EndBit is greater than 15, then ASSERT().
864 If EndBit is less than StartBit, then ASSERT().
865
866 @param Address The PCI configuration register to write.
867 @param StartBit The ordinal of the least significant bit in the bit field.
868 Range 0..15.
869 @param EndBit The ordinal of the most significant bit in the bit field.
870 Range 0..15.
871 @param Value The new value of the bit field.
872
873 @return The value written back to the PCI configuration register.
874
875 **/
876 UINT16
877 EFIAPI
878 PciCf8BitFieldWrite16 (
879 IN UINTN Address,
880 IN UINTN StartBit,
881 IN UINTN EndBit,
882 IN UINT16 Value
883 )
884 {
885 BOOLEAN InterruptState;
886 UINT32 AddressPort;
887 UINT16 Result;
888
889 ASSERT_INVALID_PCI_ADDRESS (Address, 1);
890 InterruptState = SaveAndDisableInterrupts ();
891 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);
892 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));
893 Result = IoBitFieldWrite16 (
894 PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),
895 StartBit,
896 EndBit,
897 Value
898 );
899 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);
900 SetInterruptState (InterruptState);
901 return Result;
902 }
903
904 /**
905 Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, and
906 writes the result back to the bit field in the 16-bit port.
907
908 Reads the 16-bit PCI configuration register specified by Address, performs a
909 bitwise OR between the read result and the value specified by
910 OrData, and writes the result to the 16-bit PCI configuration register
911 specified by Address. The value written to the PCI configuration register is
912 returned. This function must guarantee that all PCI read and write operations
913 are serialized. Extra left bits in OrData are stripped.
914
915 If Address > 0x0FFFFFFF, then ASSERT().
916 If Address is not aligned on a 16-bit boundary, then ASSERT().
917 If the register specified by Address >= 0x100, then ASSERT().
918 If StartBit is greater than 15, then ASSERT().
919 If EndBit is greater than 15, then ASSERT().
920 If EndBit is less than StartBit, then ASSERT().
921
922 @param Address The PCI configuration register to write.
923 @param StartBit The ordinal of the least significant bit in the bit field.
924 Range 0..15.
925 @param EndBit The ordinal of the most significant bit in the bit field.
926 Range 0..15.
927 @param OrData The value to OR with the PCI configuration register.
928
929 @return The value written back to the PCI configuration register.
930
931 **/
932 UINT16
933 EFIAPI
934 PciCf8BitFieldOr16 (
935 IN UINTN Address,
936 IN UINTN StartBit,
937 IN UINTN EndBit,
938 IN UINT16 OrData
939 )
940 {
941 BOOLEAN InterruptState;
942 UINT32 AddressPort;
943 UINT16 Result;
944
945 ASSERT_INVALID_PCI_ADDRESS (Address, 1);
946 InterruptState = SaveAndDisableInterrupts ();
947 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);
948 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));
949 Result = IoBitFieldOr16 (
950 PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),
951 StartBit,
952 EndBit,
953 OrData
954 );
955 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);
956 SetInterruptState (InterruptState);
957 return Result;
958 }
959
960 /**
961 Reads a bit field in a 16-bit PCI configuration register, performs a bitwise
962 AND, and writes the result back to the bit field in the 16-bit register.
963
964 Reads the 16-bit PCI configuration register specified by Address, performs a
965 bitwise AND between the read result and the value specified by AndData, and
966 writes the result to the 16-bit PCI configuration register specified by
967 Address. The value written to the PCI configuration register is returned.
968 This function must guarantee that all PCI read and write operations are
969 serialized. Extra left bits in AndData are stripped.
970
971 If Address > 0x0FFFFFFF, then ASSERT().
972 If Address is not aligned on a 16-bit boundary, then ASSERT().
973 If the register specified by Address >= 0x100, then ASSERT().
974 If StartBit is greater than 15, then ASSERT().
975 If EndBit is greater than 15, then ASSERT().
976 If EndBit is less than StartBit, then ASSERT().
977
978 @param Address The PCI configuration register to write.
979 @param StartBit The ordinal of the least significant bit in the bit field.
980 Range 0..15.
981 @param EndBit The ordinal of the most significant bit in the bit field.
982 Range 0..15.
983 @param AndData The value to AND with the PCI configuration register.
984
985 @return The value written back to the PCI configuration register.
986
987 **/
988 UINT16
989 EFIAPI
990 PciCf8BitFieldAnd16 (
991 IN UINTN Address,
992 IN UINTN StartBit,
993 IN UINTN EndBit,
994 IN UINT16 AndData
995 )
996 {
997 BOOLEAN InterruptState;
998 UINT32 AddressPort;
999 UINT16 Result;
1000
1001 ASSERT_INVALID_PCI_ADDRESS (Address, 1);
1002 InterruptState = SaveAndDisableInterrupts ();
1003 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);
1004 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));
1005 Result = IoBitFieldAnd16 (
1006 PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),
1007 StartBit,
1008 EndBit,
1009 AndData
1010 );
1011 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);
1012 SetInterruptState (InterruptState);
1013 return Result;
1014 }
1015
1016 /**
1017 Reads a bit field in a 16-bit port, performs a bitwise AND followed by a
1018 bitwise OR, and writes the result back to the bit field in the
1019 16-bit port.
1020
1021 Reads the 16-bit PCI configuration register specified by Address, performs a
1022 bitwise AND followed by a bitwise OR between the read result and
1023 the value specified by AndData, and writes the result to the 16-bit PCI
1024 configuration register specified by Address. The value written to the PCI
1025 configuration register is returned. This function must guarantee that all PCI
1026 read and write operations are serialized. Extra left bits in both AndData and
1027 OrData are stripped.
1028
1029 If Address > 0x0FFFFFFF, then ASSERT().
1030 If Address is not aligned on a 16-bit boundary, then ASSERT().
1031 If the register specified by Address >= 0x100, then ASSERT().
1032 If StartBit is greater than 15, then ASSERT().
1033 If EndBit is greater than 15, then ASSERT().
1034 If EndBit is less than StartBit, then ASSERT().
1035
1036 @param Address The PCI configuration register to write.
1037 @param StartBit The ordinal of the least significant bit in the bit field.
1038 Range 0..15.
1039 @param EndBit The ordinal of the most significant bit in the bit field.
1040 Range 0..15.
1041 @param AndData The value to AND with the PCI configuration register.
1042 @param OrData The value to OR with the result of the AND operation.
1043
1044 @return The value written back to the PCI configuration register.
1045
1046 **/
1047 UINT16
1048 EFIAPI
1049 PciCf8BitFieldAndThenOr16(
1050 IN UINTN Address,
1051 IN UINTN StartBit,
1052 IN UINTN EndBit,
1053 IN UINT16 AndData,
1054 IN UINT16 OrData
1055 )
1056 {
1057 BOOLEAN InterruptState;
1058 UINT32 AddressPort;
1059 UINT16 Result;
1060
1061 ASSERT_INVALID_PCI_ADDRESS (Address, 1);
1062 InterruptState = SaveAndDisableInterrupts ();
1063 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);
1064 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));
1065 Result = IoBitFieldAndThenOr16 (
1066 PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),
1067 StartBit,
1068 EndBit,
1069 AndData,
1070 OrData
1071 );
1072 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);
1073 SetInterruptState (InterruptState);
1074 return Result;
1075 }
1076
1077 /**
1078 Reads a 32-bit PCI configuration register.
1079
1080 Reads and returns the 32-bit PCI configuration register specified by Address.
1081 This function must guarantee that all PCI read and write operations are
1082 serialized.
1083
1084 If Address > 0x0FFFFFFF, then ASSERT().
1085 If Address is not aligned on a 32-bit boundary, then ASSERT().
1086 If the register specified by Address >= 0x100, then ASSERT().
1087
1088 @param Address The address that encodes the PCI Bus, Device, Function and
1089 Register.
1090
1091 @return The read value from the PCI configuration register.
1092
1093 **/
1094 UINT32
1095 EFIAPI
1096 PciCf8Read32 (
1097 IN UINTN Address
1098 )
1099 {
1100 BOOLEAN InterruptState;
1101 UINT32 AddressPort;
1102 UINT32 Result;
1103
1104 ASSERT_INVALID_PCI_ADDRESS (Address, 3);
1105 InterruptState = SaveAndDisableInterrupts ();
1106 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);
1107 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));
1108 Result = IoRead32 (PCI_CONFIGURATION_DATA_PORT);
1109 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);
1110 SetInterruptState (InterruptState);
1111 return Result;
1112 }
1113
1114 /**
1115 Writes a 32-bit PCI configuration register.
1116
1117 Writes the 32-bit PCI configuration register specified by Address with the
1118 value specified by Value. Value is returned. This function must guarantee
1119 that all PCI read and write operations are serialized.
1120
1121 If Address > 0x0FFFFFFF, then ASSERT().
1122 If Address is not aligned on a 32-bit boundary, then ASSERT().
1123 If the register specified by Address >= 0x100, then ASSERT().
1124
1125 @param Address The address that encodes the PCI Bus, Device, Function and
1126 Register.
1127 @param Value The value to write.
1128
1129 @return The value written to the PCI configuration register.
1130
1131 **/
1132 UINT32
1133 EFIAPI
1134 PciCf8Write32 (
1135 IN UINTN Address,
1136 IN UINT32 Value
1137 )
1138 {
1139 BOOLEAN InterruptState;
1140 UINT32 AddressPort;
1141 UINT32 Result;
1142
1143 ASSERT_INVALID_PCI_ADDRESS (Address, 3);
1144 InterruptState = SaveAndDisableInterrupts ();
1145 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);
1146 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));
1147 Result = IoWrite32 (
1148 PCI_CONFIGURATION_DATA_PORT,
1149 Value
1150 );
1151 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);
1152 SetInterruptState (InterruptState);
1153 return Result;
1154 }
1155
1156 /**
1157 Performs a bitwise OR of a 32-bit PCI configuration register with
1158 a 32-bit value.
1159
1160 Reads the 32-bit PCI configuration register specified by Address, performs a
1161 bitwise OR between the read result and the value specified by
1162 OrData, and writes the result to the 32-bit PCI configuration register
1163 specified by Address. The value written to the PCI configuration register is
1164 returned. This function must guarantee that all PCI read and write operations
1165 are serialized.
1166
1167 If Address > 0x0FFFFFFF, then ASSERT().
1168 If Address is not aligned on a 32-bit boundary, then ASSERT().
1169 If the register specified by Address >= 0x100, then ASSERT().
1170
1171 @param Address The address that encodes the PCI Bus, Device, Function and
1172 Register.
1173 @param OrData The value to OR with the PCI configuration register.
1174
1175 @return The value written back to the PCI configuration register.
1176
1177 **/
1178 UINT32
1179 EFIAPI
1180 PciCf8Or32 (
1181 IN UINTN Address,
1182 IN UINT32 OrData
1183 )
1184 {
1185 BOOLEAN InterruptState;
1186 UINT32 AddressPort;
1187 UINT32 Result;
1188
1189 ASSERT_INVALID_PCI_ADDRESS (Address, 3);
1190 InterruptState = SaveAndDisableInterrupts ();
1191 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);
1192 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));
1193 Result = IoOr32 (
1194 PCI_CONFIGURATION_DATA_PORT,
1195 OrData
1196 );
1197 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);
1198 SetInterruptState (InterruptState);
1199 return Result;
1200 }
1201
1202 /**
1203 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
1204 value.
1205
1206 Reads the 32-bit PCI configuration register specified by Address, performs a
1207 bitwise AND between the read result and the value specified by AndData, and
1208 writes the result to the 32-bit PCI configuration register specified by
1209 Address. The value written to the PCI configuration register is returned.
1210 This function must guarantee that all PCI read and write operations are
1211 serialized.
1212
1213 If Address > 0x0FFFFFFF, then ASSERT().
1214 If Address is not aligned on a 32-bit boundary, then ASSERT().
1215 If the register specified by Address >= 0x100, then ASSERT().
1216
1217 @param Address The address that encodes the PCI Bus, Device, Function and
1218 Register.
1219 @param AndData The value to AND with the PCI configuration register.
1220
1221 @return The value written back to the PCI configuration register.
1222
1223 **/
1224 UINT32
1225 EFIAPI
1226 PciCf8And32 (
1227 IN UINTN Address,
1228 IN UINT32 AndData
1229 )
1230 {
1231 BOOLEAN InterruptState;
1232 UINT32 AddressPort;
1233 UINT32 Result;
1234
1235 ASSERT_INVALID_PCI_ADDRESS (Address, 3);
1236 InterruptState = SaveAndDisableInterrupts ();
1237 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);
1238 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));
1239 Result = IoAnd32 (
1240 PCI_CONFIGURATION_DATA_PORT,
1241 AndData
1242 );
1243 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);
1244 SetInterruptState (InterruptState);
1245 return Result;
1246 }
1247
1248 /**
1249 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
1250 value, followed a bitwise OR with another 32-bit value.
1251
1252 Reads the 32-bit PCI configuration register specified by Address, performs a
1253 bitwise AND between the read result and the value specified by AndData,
1254 performs a bitwise OR between the result of the AND operation and
1255 the value specified by OrData, and writes the result to the 32-bit PCI
1256 configuration register specified by Address. The value written to the PCI
1257 configuration register is returned. This function must guarantee that all PCI
1258 read and write operations are serialized.
1259
1260 If Address > 0x0FFFFFFF, then ASSERT().
1261 If Address is not aligned on a 32-bit boundary, then ASSERT().
1262 If the register specified by Address >= 0x100, then ASSERT().
1263
1264 @param Address The address that encodes the PCI Bus, Device, Function and
1265 Register.
1266 @param AndData The value to AND with the PCI configuration register.
1267 @param OrData The value to OR with the result of the AND operation.
1268
1269 @return The value written back to the PCI configuration register.
1270
1271 **/
1272 UINT32
1273 EFIAPI
1274 PciCf8AndThenOr32 (
1275 IN UINTN Address,
1276 IN UINT32 AndData,
1277 IN UINT32 OrData
1278 )
1279 {
1280 BOOLEAN InterruptState;
1281 UINT32 AddressPort;
1282 UINT32 Result;
1283
1284 ASSERT_INVALID_PCI_ADDRESS (Address, 3);
1285 InterruptState = SaveAndDisableInterrupts ();
1286 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);
1287 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));
1288 Result = IoAndThenOr32 (
1289 PCI_CONFIGURATION_DATA_PORT,
1290 AndData,
1291 OrData
1292 );
1293 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);
1294 SetInterruptState (InterruptState);
1295 return Result;
1296 }
1297
1298 /**
1299 Reads a bit field of a PCI configuration register.
1300
1301 Reads the bit field in a 32-bit PCI configuration register. The bit field is
1302 specified by the StartBit and the EndBit. The value of the bit field is
1303 returned.
1304
1305 If Address > 0x0FFFFFFF, then ASSERT().
1306 If Address is not aligned on a 32-bit boundary, then ASSERT().
1307 If the register specified by Address >= 0x100, then ASSERT().
1308 If StartBit is greater than 31, then ASSERT().
1309 If EndBit is greater than 31, then ASSERT().
1310 If EndBit is less than StartBit, then ASSERT().
1311
1312 @param Address The PCI configuration register to read.
1313 @param StartBit The ordinal of the least significant bit in the bit field.
1314 Range 0..31.
1315 @param EndBit The ordinal of the most significant bit in the bit field.
1316 Range 0..31.
1317
1318 @return The value of the bit field read from the PCI configuration register.
1319
1320 **/
1321 UINT32
1322 EFIAPI
1323 PciCf8BitFieldRead32 (
1324 IN UINTN Address,
1325 IN UINTN StartBit,
1326 IN UINTN EndBit
1327 )
1328 {
1329 BOOLEAN InterruptState;
1330 UINT32 AddressPort;
1331 UINT32 Result;
1332
1333 ASSERT_INVALID_PCI_ADDRESS (Address, 3);
1334 InterruptState = SaveAndDisableInterrupts ();
1335 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);
1336 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));
1337 Result = IoBitFieldRead32 (
1338 PCI_CONFIGURATION_DATA_PORT,
1339 StartBit,
1340 EndBit
1341 );
1342 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);
1343 SetInterruptState (InterruptState);
1344 return Result;
1345 }
1346
1347 /**
1348 Writes a bit field to a PCI configuration register.
1349
1350 Writes Value to the bit field of the PCI configuration register. The bit
1351 field is specified by the StartBit and the EndBit. All other bits in the
1352 destination PCI configuration register are preserved. The new value of the
1353 32-bit register is returned.
1354
1355 If Address > 0x0FFFFFFF, then ASSERT().
1356 If Address is not aligned on a 32-bit boundary, then ASSERT().
1357 If the register specified by Address >= 0x100, then ASSERT().
1358 If StartBit is greater than 31, then ASSERT().
1359 If EndBit is greater than 31, then ASSERT().
1360 If EndBit is less than StartBit, then ASSERT().
1361
1362 @param Address The PCI configuration register to write.
1363 @param StartBit The ordinal of the least significant bit in the bit field.
1364 Range 0..31.
1365 @param EndBit The ordinal of the most significant bit in the bit field.
1366 Range 0..31.
1367 @param Value The new value of the bit field.
1368
1369 @return The value written back to the PCI configuration register.
1370
1371 **/
1372 UINT32
1373 EFIAPI
1374 PciCf8BitFieldWrite32 (
1375 IN UINTN Address,
1376 IN UINTN StartBit,
1377 IN UINTN EndBit,
1378 IN UINT32 Value
1379 )
1380 {
1381 BOOLEAN InterruptState;
1382 UINT32 AddressPort;
1383 UINT32 Result;
1384
1385 ASSERT_INVALID_PCI_ADDRESS (Address, 3);
1386 InterruptState = SaveAndDisableInterrupts ();
1387 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);
1388 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));
1389 Result = IoBitFieldWrite32 (
1390 PCI_CONFIGURATION_DATA_PORT,
1391 StartBit,
1392 EndBit,
1393 Value
1394 );
1395 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);
1396 SetInterruptState (InterruptState);
1397 return Result;
1398 }
1399
1400 /**
1401 Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and
1402 writes the result back to the bit field in the 32-bit port.
1403
1404 Reads the 32-bit PCI configuration register specified by Address, performs a
1405 bitwise OR between the read result and the value specified by
1406 OrData, and writes the result to the 32-bit PCI configuration register
1407 specified by Address. The value written to the PCI configuration register is
1408 returned. This function must guarantee that all PCI read and write operations
1409 are serialized. Extra left bits in OrData are stripped.
1410
1411 If Address > 0x0FFFFFFF, then ASSERT().
1412 If Address is not aligned on a 32-bit boundary, then ASSERT().
1413 If the register specified by Address >= 0x100, then ASSERT().
1414 If StartBit is greater than 31, then ASSERT().
1415 If EndBit is greater than 31, then ASSERT().
1416 If EndBit is less than StartBit, then ASSERT().
1417
1418 @param Address The PCI configuration register to write.
1419 @param StartBit The ordinal of the least significant bit in the bit field.
1420 Range 0..31.
1421 @param EndBit The ordinal of the most significant bit in the bit field.
1422 Range 0..31.
1423 @param OrData The value to OR with the PCI configuration register.
1424
1425 @return The value written back to the PCI configuration register.
1426
1427 **/
1428 UINT32
1429 EFIAPI
1430 PciCf8BitFieldOr32 (
1431 IN UINTN Address,
1432 IN UINTN StartBit,
1433 IN UINTN EndBit,
1434 IN UINT32 OrData
1435 )
1436 {
1437 BOOLEAN InterruptState;
1438 UINT32 AddressPort;
1439 UINT32 Result;
1440
1441 ASSERT_INVALID_PCI_ADDRESS (Address, 3);
1442 InterruptState = SaveAndDisableInterrupts ();
1443 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);
1444 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));
1445 Result = IoBitFieldOr32 (
1446 PCI_CONFIGURATION_DATA_PORT,
1447 StartBit,
1448 EndBit,
1449 OrData
1450 );
1451 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);
1452 SetInterruptState (InterruptState);
1453 return Result;
1454 }
1455
1456 /**
1457 Reads a bit field in a 32-bit PCI configuration register, performs a bitwise
1458 AND, and writes the result back to the bit field in the 32-bit register.
1459
1460 Reads the 32-bit PCI configuration register specified by Address, performs a
1461 bitwise AND between the read result and the value specified by AndData, and
1462 writes the result to the 32-bit PCI configuration register specified by
1463 Address. The value written to the PCI configuration register is returned.
1464 This function must guarantee that all PCI read and write operations are
1465 serialized. Extra left bits in AndData are stripped.
1466
1467 If Address > 0x0FFFFFFF, then ASSERT().
1468 If Address is not aligned on a 32-bit boundary, then ASSERT().
1469 If the register specified by Address >= 0x100, then ASSERT().
1470 If StartBit is greater than 31, then ASSERT().
1471 If EndBit is greater than 31, then ASSERT().
1472 If EndBit is less than StartBit, then ASSERT().
1473
1474 @param Address The PCI configuration register to write.
1475 @param StartBit The ordinal of the least significant bit in the bit field.
1476 Range 0..31.
1477 @param EndBit The ordinal of the most significant bit in the bit field.
1478 Range 0..31.
1479 @param AndData The value to AND with the PCI configuration register.
1480
1481 @return The value written back to the PCI configuration register.
1482
1483 **/
1484 UINT32
1485 EFIAPI
1486 PciCf8BitFieldAnd32 (
1487 IN UINTN Address,
1488 IN UINTN StartBit,
1489 IN UINTN EndBit,
1490 IN UINT32 AndData
1491 )
1492 {
1493 BOOLEAN InterruptState;
1494 UINT32 AddressPort;
1495 UINT32 Result;
1496
1497 ASSERT_INVALID_PCI_ADDRESS (Address, 3);
1498 InterruptState = SaveAndDisableInterrupts ();
1499 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);
1500 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));
1501 Result = IoBitFieldAnd32 (
1502 PCI_CONFIGURATION_DATA_PORT,
1503 StartBit,
1504 EndBit,
1505 AndData
1506 );
1507 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);
1508 SetInterruptState (InterruptState);
1509 return Result;
1510 }
1511
1512 /**
1513 Reads a bit field in a 32-bit port, performs a bitwise AND followed by a
1514 bitwise OR, and writes the result back to the bit field in the
1515 32-bit port.
1516
1517 Reads the 32-bit PCI configuration register specified by Address, performs a
1518 bitwise AND followed by a bitwise OR between the read result and
1519 the value specified by AndData, and writes the result to the 32-bit PCI
1520 configuration register specified by Address. The value written to the PCI
1521 configuration register is returned. This function must guarantee that all PCI
1522 read and write operations are serialized. Extra left bits in both AndData and
1523 OrData are stripped.
1524
1525 If Address > 0x0FFFFFFF, then ASSERT().
1526 If Address is not aligned on a 32-bit boundary, then ASSERT().
1527 If the register specified by Address >= 0x100, then ASSERT().
1528 If StartBit is greater than 31, then ASSERT().
1529 If EndBit is greater than 31, then ASSERT().
1530 If EndBit is less than StartBit, then ASSERT().
1531
1532 @param Address The PCI configuration register to write.
1533 @param StartBit The ordinal of the least significant bit in the bit field.
1534 Range 0..31.
1535 @param EndBit The ordinal of the most significant bit in the bit field.
1536 Range 0..31.
1537 @param AndData The value to AND with the PCI configuration register.
1538 @param OrData The value to OR with the result of the AND operation.
1539
1540 @return The value written back to the PCI configuration register.
1541
1542 **/
1543 UINT32
1544 EFIAPI
1545 PciCf8BitFieldAndThenOr32(
1546 IN UINTN Address,
1547 IN UINTN StartBit,
1548 IN UINTN EndBit,
1549 IN UINT32 AndData,
1550 IN UINT32 OrData
1551 )
1552 {
1553 BOOLEAN InterruptState;
1554 UINT32 AddressPort;
1555 UINT32 Result;
1556
1557 ASSERT_INVALID_PCI_ADDRESS (Address, 3);
1558 InterruptState = SaveAndDisableInterrupts ();
1559 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);
1560 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));
1561 Result = IoBitFieldAndThenOr32 (
1562 PCI_CONFIGURATION_DATA_PORT,
1563 StartBit,
1564 EndBit,
1565 AndData,
1566 OrData
1567 );
1568 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);
1569 SetInterruptState (InterruptState);
1570 return Result;
1571 }
1572
1573 /**
1574 Reads a range of PCI configuration registers into a caller supplied buffer.
1575
1576 Reads the range of PCI configuration registers specified by StartAddress and
1577 Size into the buffer specified by Buffer. This function only allows the PCI
1578 configuration registers from a single PCI function to be read. Size is
1579 returned. When possible 32-bit PCI configuration read cycles are used to read
1580 from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit
1581 and 16-bit PCI configuration read cycles may be used at the beginning and the
1582 end of the range.
1583
1584 If StartAddress > 0x0FFFFFFF, then ASSERT().
1585 If the register specified by StartAddress >= 0x100, then ASSERT().
1586 If ((StartAddress & 0xFFF) + Size) > 0x100, then ASSERT().
1587 If Size > 0 and Buffer is NULL, then ASSERT().
1588
1589 @param StartAddress The starting address that encodes the PCI Bus, Device,
1590 Function and Register.
1591 @param Size The size in bytes of the transfer.
1592 @param Buffer The pointer to a buffer receiving the data read.
1593
1594 @return Size read from StartAddress.
1595
1596 **/
1597 UINTN
1598 EFIAPI
1599 PciCf8ReadBuffer (
1600 IN UINTN StartAddress,
1601 IN UINTN Size,
1602 OUT VOID *Buffer
1603 )
1604 {
1605 UINTN ReturnValue;
1606
1607 ASSERT_INVALID_PCI_ADDRESS (StartAddress, 0);
1608 ASSERT (((StartAddress & 0xFFF) + Size) <= 0x100);
1609
1610 if (Size == 0) {
1611 return Size;
1612 }
1613
1614 ASSERT (Buffer != NULL);
1615
1616 //
1617 // Save Size for return
1618 //
1619 ReturnValue = Size;
1620
1621 if ((StartAddress & 1) != 0) {
1622 //
1623 // Read a byte if StartAddress is byte aligned
1624 //
1625 *(volatile UINT8 *)Buffer = PciCf8Read8 (StartAddress);
1626 StartAddress += sizeof (UINT8);
1627 Size -= sizeof (UINT8);
1628 Buffer = (UINT8*)Buffer + 1;
1629 }
1630
1631 if (Size >= sizeof (UINT16) && (StartAddress & 2) != 0) {
1632 //
1633 // Read a word if StartAddress is word aligned
1634 //
1635 WriteUnaligned16 ((UINT16 *)Buffer, (UINT16) PciCf8Read16 (StartAddress));
1636
1637 StartAddress += sizeof (UINT16);
1638 Size -= sizeof (UINT16);
1639 Buffer = (UINT16*)Buffer + 1;
1640 }
1641
1642 while (Size >= sizeof (UINT32)) {
1643 //
1644 // Read as many double words as possible
1645 //
1646 WriteUnaligned32 ((UINT32 *)Buffer, (UINT32) PciCf8Read32 (StartAddress));
1647 StartAddress += sizeof (UINT32);
1648 Size -= sizeof (UINT32);
1649 Buffer = (UINT32*)Buffer + 1;
1650 }
1651
1652 if (Size >= sizeof (UINT16)) {
1653 //
1654 // Read the last remaining word if exist
1655 //
1656 WriteUnaligned16 ((UINT16 *)Buffer, (UINT16) PciCf8Read16 (StartAddress));
1657 StartAddress += sizeof (UINT16);
1658 Size -= sizeof (UINT16);
1659 Buffer = (UINT16*)Buffer + 1;
1660 }
1661
1662 if (Size >= sizeof (UINT8)) {
1663 //
1664 // Read the last remaining byte if exist
1665 //
1666 *(volatile UINT8 *)Buffer = PciCf8Read8 (StartAddress);
1667 }
1668
1669 return ReturnValue;
1670 }
1671
1672 /**
1673 Copies the data in a caller supplied buffer to a specified range of PCI
1674 configuration space.
1675
1676 Writes the range of PCI configuration registers specified by StartAddress and
1677 Size from the buffer specified by Buffer. This function only allows the PCI
1678 configuration registers from a single PCI function to be written. Size is
1679 returned. When possible 32-bit PCI configuration write cycles are used to
1680 write from StartAdress to StartAddress + Size. Due to alignment restrictions,
1681 8-bit and 16-bit PCI configuration write cycles may be used at the beginning
1682 and the end of the range.
1683
1684 If StartAddress > 0x0FFFFFFF, then ASSERT().
1685 If the register specified by StartAddress >= 0x100, then ASSERT().
1686 If ((StartAddress & 0xFFF) + Size) > 0x100, then ASSERT().
1687 If Size > 0 and Buffer is NULL, then ASSERT().
1688
1689 @param StartAddress The starting address that encodes the PCI Bus, Device,
1690 Function and Register.
1691 @param Size The size in bytes of the transfer.
1692 @param Buffer The pointer to a buffer containing the data to write.
1693
1694 @return Size written to StartAddress.
1695
1696 **/
1697 UINTN
1698 EFIAPI
1699 PciCf8WriteBuffer (
1700 IN UINTN StartAddress,
1701 IN UINTN Size,
1702 IN VOID *Buffer
1703 )
1704 {
1705 UINTN ReturnValue;
1706
1707 ASSERT_INVALID_PCI_ADDRESS (StartAddress, 0);
1708 ASSERT (((StartAddress & 0xFFF) + Size) <= 0x100);
1709
1710 if (Size == 0) {
1711 return 0;
1712 }
1713
1714 ASSERT (Buffer != NULL);
1715
1716 //
1717 // Save Size for return
1718 //
1719 ReturnValue = Size;
1720
1721 if ((StartAddress & 1) != 0) {
1722 //
1723 // Write a byte if StartAddress is byte aligned
1724 //
1725 PciCf8Write8 (StartAddress, *(UINT8*)Buffer);
1726 StartAddress += sizeof (UINT8);
1727 Size -= sizeof (UINT8);
1728 Buffer = (UINT8*)Buffer + 1;
1729 }
1730
1731 if (Size >= sizeof (UINT16) && (StartAddress & 2) != 0) {
1732 //
1733 // Write a word if StartAddress is word aligned
1734 //
1735 PciCf8Write16 (StartAddress, ReadUnaligned16 ((UINT16*)Buffer));
1736 StartAddress += sizeof (UINT16);
1737 Size -= sizeof (UINT16);
1738 Buffer = (UINT16*)Buffer + 1;
1739 }
1740
1741 while (Size >= sizeof (UINT32)) {
1742 //
1743 // Write as many double words as possible
1744 //
1745 PciCf8Write32 (StartAddress, ReadUnaligned32 ((UINT32*)Buffer));
1746 StartAddress += sizeof (UINT32);
1747 Size -= sizeof (UINT32);
1748 Buffer = (UINT32*)Buffer + 1;
1749 }
1750
1751 if (Size >= sizeof (UINT16)) {
1752 //
1753 // Write the last remaining word if exist
1754 //
1755 PciCf8Write16 (StartAddress, ReadUnaligned16 ((UINT16*)Buffer));
1756 StartAddress += sizeof (UINT16);
1757 Size -= sizeof (UINT16);
1758 Buffer = (UINT16*)Buffer + 1;
1759 }
1760
1761 if (Size >= sizeof (UINT8)) {
1762 //
1763 // Write the last remaining byte if exist
1764 //
1765 PciCf8Write8 (StartAddress, *(UINT8*)Buffer);
1766 }
1767
1768 return ReturnValue;
1769 }