]> git.proxmox.com Git - mirror_edk2.git/blob - MdePkg/Library/BasePciCf8Lib/PciCf8Lib.c
MdePkg: Clean up source files
[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 - 2018, 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 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
373
374 @param Address The PCI configuration register to write.
375 @param StartBit The ordinal of the least significant bit in the bit field.
376 Range 0..7.
377 @param EndBit The ordinal of the most significant bit in the bit field.
378 Range 0..7.
379 @param Value The new value of the bit field.
380
381 @return The value written back to the PCI configuration register.
382
383 **/
384 UINT8
385 EFIAPI
386 PciCf8BitFieldWrite8 (
387 IN UINTN Address,
388 IN UINTN StartBit,
389 IN UINTN EndBit,
390 IN UINT8 Value
391 )
392 {
393 BOOLEAN InterruptState;
394 UINT32 AddressPort;
395 UINT8 Result;
396
397 ASSERT_INVALID_PCI_ADDRESS (Address, 0);
398 InterruptState = SaveAndDisableInterrupts ();
399 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);
400 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));
401 Result = IoBitFieldWrite8 (
402 PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3),
403 StartBit,
404 EndBit,
405 Value
406 );
407 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);
408 SetInterruptState (InterruptState);
409 return Result;
410 }
411
412 /**
413 Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and
414 writes the result back to the bit field in the 8-bit port.
415
416 Reads the 8-bit PCI configuration register specified by Address, performs a
417 bitwise OR between the read result and the value specified by
418 OrData, and writes the result to the 8-bit PCI configuration register
419 specified by Address. The value written to the PCI configuration register is
420 returned. This function must guarantee that all PCI read and write operations
421 are serialized. Extra left bits in OrData are stripped.
422
423 If Address > 0x0FFFFFFF, then ASSERT().
424 If the register specified by Address >= 0x100, then ASSERT().
425 If StartBit is greater than 7, then ASSERT().
426 If EndBit is greater than 7, then ASSERT().
427 If EndBit is less than StartBit, then ASSERT().
428 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
429
430 @param Address The PCI configuration register to write.
431 @param StartBit The ordinal of the least significant bit in the bit field.
432 Range 0..7.
433 @param EndBit The ordinal of the most significant bit in the bit field.
434 Range 0..7.
435 @param OrData The value to OR with the PCI configuration register.
436
437 @return The value written back to the PCI configuration register.
438
439 **/
440 UINT8
441 EFIAPI
442 PciCf8BitFieldOr8 (
443 IN UINTN Address,
444 IN UINTN StartBit,
445 IN UINTN EndBit,
446 IN UINT8 OrData
447 )
448 {
449 BOOLEAN InterruptState;
450 UINT32 AddressPort;
451 UINT8 Result;
452
453 ASSERT_INVALID_PCI_ADDRESS (Address, 0);
454 InterruptState = SaveAndDisableInterrupts ();
455 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);
456 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));
457 Result = IoBitFieldOr8 (
458 PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3),
459 StartBit,
460 EndBit,
461 OrData
462 );
463 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);
464 SetInterruptState (InterruptState);
465 return Result;
466 }
467
468 /**
469 Reads a bit field in an 8-bit PCI configuration register, performs a bitwise
470 AND, and writes the result back to the bit field in the 8-bit register.
471
472 Reads the 8-bit PCI configuration register specified by Address, performs a
473 bitwise AND between the read result and the value specified by AndData, and
474 writes the result to the 8-bit PCI configuration register specified by
475 Address. The value written to the PCI configuration register is returned.
476 This function must guarantee that all PCI read and write operations are
477 serialized. Extra left bits in AndData are stripped.
478
479 If Address > 0x0FFFFFFF, then ASSERT().
480 If the register specified by Address >= 0x100, then ASSERT().
481 If StartBit is greater than 7, then ASSERT().
482 If EndBit is greater than 7, then ASSERT().
483 If EndBit is less than StartBit, then ASSERT().
484 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
485
486 @param Address The PCI configuration register to write.
487 @param StartBit The ordinal of the least significant bit in the bit field.
488 Range 0..7.
489 @param EndBit The ordinal of the most significant bit in the bit field.
490 Range 0..7.
491 @param AndData The value to AND with the PCI configuration register.
492
493 @return The value written back to the PCI configuration register.
494
495 **/
496 UINT8
497 EFIAPI
498 PciCf8BitFieldAnd8 (
499 IN UINTN Address,
500 IN UINTN StartBit,
501 IN UINTN EndBit,
502 IN UINT8 AndData
503 )
504 {
505 BOOLEAN InterruptState;
506 UINT32 AddressPort;
507 UINT8 Result;
508
509 ASSERT_INVALID_PCI_ADDRESS (Address, 0);
510 InterruptState = SaveAndDisableInterrupts ();
511 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);
512 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));
513 Result = IoBitFieldAnd8 (
514 PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3),
515 StartBit,
516 EndBit,
517 AndData
518 );
519 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);
520 SetInterruptState (InterruptState);
521 return Result;
522 }
523
524 /**
525 Reads a bit field in an 8-bit port, performs a bitwise AND followed by a
526 bitwise OR, and writes the result back to the bit field in the
527 8-bit port.
528
529 Reads the 8-bit PCI configuration register specified by Address, performs a
530 bitwise AND followed by a bitwise OR between the read result and
531 the value specified by AndData, and writes the result to the 8-bit PCI
532 configuration register specified by Address. The value written to the PCI
533 configuration register is returned. This function must guarantee that all PCI
534 read and write operations are serialized. Extra left bits in both AndData and
535 OrData are stripped.
536
537 If Address > 0x0FFFFFFF, then ASSERT().
538 If the register specified by Address >= 0x100, then ASSERT().
539 If StartBit is greater than 7, then ASSERT().
540 If EndBit is greater than 7, then ASSERT().
541 If EndBit is less than StartBit, then ASSERT().
542 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
543 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
544
545 @param Address The PCI configuration register to write.
546 @param StartBit The ordinal of the least significant bit in the bit field.
547 Range 0..7.
548 @param EndBit The ordinal of the most significant bit in the bit field.
549 Range 0..7.
550 @param AndData The value to AND with the PCI configuration register.
551 @param OrData The value to OR with the result of the AND operation.
552
553 @return The value written back to the PCI configuration register.
554
555 **/
556 UINT8
557 EFIAPI
558 PciCf8BitFieldAndThenOr8(
559 IN UINTN Address,
560 IN UINTN StartBit,
561 IN UINTN EndBit,
562 IN UINT8 AndData,
563 IN UINT8 OrData
564 )
565 {
566 BOOLEAN InterruptState;
567 UINT32 AddressPort;
568 UINT8 Result;
569
570 ASSERT_INVALID_PCI_ADDRESS (Address, 0);
571 InterruptState = SaveAndDisableInterrupts ();
572 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);
573 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));
574 Result = IoBitFieldAndThenOr8 (
575 PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 3),
576 StartBit,
577 EndBit,
578 AndData,
579 OrData
580 );
581 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);
582 SetInterruptState (InterruptState);
583 return Result;
584 }
585
586 /**
587 Reads a 16-bit PCI configuration register.
588
589 Reads and returns the 16-bit PCI configuration register specified by Address.
590 This function must guarantee that all PCI read and write operations are
591 serialized.
592
593 If Address > 0x0FFFFFFF, then ASSERT().
594 If Address is not aligned on a 16-bit boundary, then ASSERT().
595 If the register specified by Address >= 0x100, then ASSERT().
596
597 @param Address The address that encodes the PCI Bus, Device, Function and
598 Register.
599
600 @return The read value from the PCI configuration register.
601
602 **/
603 UINT16
604 EFIAPI
605 PciCf8Read16 (
606 IN UINTN Address
607 )
608 {
609 BOOLEAN InterruptState;
610 UINT32 AddressPort;
611 UINT16 Result;
612
613 ASSERT_INVALID_PCI_ADDRESS (Address, 1);
614 InterruptState = SaveAndDisableInterrupts ();
615 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);
616 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));
617 Result = IoRead16 (PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2));
618 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);
619 SetInterruptState (InterruptState);
620 return Result;
621 }
622
623 /**
624 Writes a 16-bit PCI configuration register.
625
626 Writes the 16-bit PCI configuration register specified by Address with the
627 value specified by Value. Value is returned. This function must guarantee
628 that all PCI read and write operations are serialized.
629
630 If Address > 0x0FFFFFFF, then ASSERT().
631 If Address is not aligned on a 16-bit boundary, then ASSERT().
632 If the register specified by Address >= 0x100, then ASSERT().
633
634 @param Address The address that encodes the PCI Bus, Device, Function and
635 Register.
636 @param Value The value to write.
637
638 @return The value written to the PCI configuration register.
639
640 **/
641 UINT16
642 EFIAPI
643 PciCf8Write16 (
644 IN UINTN Address,
645 IN UINT16 Value
646 )
647 {
648 BOOLEAN InterruptState;
649 UINT32 AddressPort;
650 UINT16 Result;
651
652 ASSERT_INVALID_PCI_ADDRESS (Address, 1);
653 InterruptState = SaveAndDisableInterrupts ();
654 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);
655 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));
656 Result = IoWrite16 (
657 PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),
658 Value
659 );
660 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);
661 SetInterruptState (InterruptState);
662 return Result;
663 }
664
665 /**
666 Performs a bitwise OR of a 16-bit PCI configuration register with
667 a 16-bit value.
668
669 Reads the 16-bit PCI configuration register specified by Address, performs a
670 bitwise OR between the read result and the value specified by
671 OrData, and writes the result to the 16-bit PCI configuration register
672 specified by Address. The value written to the PCI configuration register is
673 returned. This function must guarantee that all PCI read and write operations
674 are serialized.
675
676 If Address > 0x0FFFFFFF, then ASSERT().
677 If Address is not aligned on a 16-bit boundary, then ASSERT().
678 If the register specified by Address >= 0x100, then ASSERT().
679
680 @param Address The address that encodes the PCI Bus, Device, Function and
681 Register.
682 @param OrData The value to OR with the PCI configuration register.
683
684 @return The value written back to the PCI configuration register.
685
686 **/
687 UINT16
688 EFIAPI
689 PciCf8Or16 (
690 IN UINTN Address,
691 IN UINT16 OrData
692 )
693 {
694 BOOLEAN InterruptState;
695 UINT32 AddressPort;
696 UINT16 Result;
697
698 ASSERT_INVALID_PCI_ADDRESS (Address, 1);
699 InterruptState = SaveAndDisableInterrupts ();
700 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);
701 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));
702 Result = IoOr16 (
703 PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),
704 OrData
705 );
706 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);
707 SetInterruptState (InterruptState);
708 return Result;
709 }
710
711 /**
712 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
713 value.
714
715 Reads the 16-bit PCI configuration register specified by Address, performs a
716 bitwise AND between the read result and the value specified by AndData, and
717 writes the result to the 16-bit PCI configuration register specified by
718 Address. The value written to the PCI configuration register is returned.
719 This function must guarantee that all PCI read and write operations are
720 serialized.
721
722 If Address > 0x0FFFFFFF, then ASSERT().
723 If Address is not aligned on a 16-bit boundary, then ASSERT().
724 If the register specified by Address >= 0x100, then ASSERT().
725
726 @param Address The address that encodes the PCI Bus, Device, Function and
727 Register.
728 @param AndData The value to AND with the PCI configuration register.
729
730 @return The value written back to the PCI configuration register.
731
732 **/
733 UINT16
734 EFIAPI
735 PciCf8And16 (
736 IN UINTN Address,
737 IN UINT16 AndData
738 )
739 {
740 BOOLEAN InterruptState;
741 UINT32 AddressPort;
742 UINT16 Result;
743
744 ASSERT_INVALID_PCI_ADDRESS (Address, 1);
745 InterruptState = SaveAndDisableInterrupts ();
746 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);
747 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));
748 Result = IoAnd16 (
749 PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),
750 AndData
751 );
752 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);
753 SetInterruptState (InterruptState);
754 return Result;
755 }
756
757 /**
758 Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
759 value, followed a bitwise OR with another 16-bit value.
760
761 Reads the 16-bit PCI configuration register specified by Address, performs a
762 bitwise AND between the read result and the value specified by AndData,
763 performs a bitwise OR between the result of the AND operation and
764 the value specified by OrData, and writes the result to the 16-bit PCI
765 configuration register specified by Address. The value written to the PCI
766 configuration register is returned. This function must guarantee that all PCI
767 read and write operations are serialized.
768
769 If Address > 0x0FFFFFFF, then ASSERT().
770 If Address is not aligned on a 16-bit boundary, then ASSERT().
771 If the register specified by Address >= 0x100, then ASSERT().
772
773 @param Address The address that encodes the PCI Bus, Device, Function and
774 Register.
775 @param AndData The value to AND with the PCI configuration register.
776 @param OrData The value to OR with the result of the AND operation.
777
778 @return The value written back to the PCI configuration register.
779
780 **/
781 UINT16
782 EFIAPI
783 PciCf8AndThenOr16 (
784 IN UINTN Address,
785 IN UINT16 AndData,
786 IN UINT16 OrData
787 )
788 {
789 BOOLEAN InterruptState;
790 UINT32 AddressPort;
791 UINT16 Result;
792
793 ASSERT_INVALID_PCI_ADDRESS (Address, 1);
794 InterruptState = SaveAndDisableInterrupts ();
795 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);
796 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));
797 Result = IoAndThenOr16 (
798 PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),
799 AndData,
800 OrData
801 );
802 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);
803 SetInterruptState (InterruptState);
804 return Result;
805 }
806
807 /**
808 Reads a bit field of a PCI configuration register.
809
810 Reads the bit field in a 16-bit PCI configuration register. The bit field is
811 specified by the StartBit and the EndBit. The value of the bit field is
812 returned.
813
814 If Address > 0x0FFFFFFF, then ASSERT().
815 If Address is not aligned on a 16-bit boundary, then ASSERT().
816 If the register specified by Address >= 0x100, then ASSERT().
817 If StartBit is greater than 15, then ASSERT().
818 If EndBit is greater than 15, then ASSERT().
819 If EndBit is less than StartBit, then ASSERT().
820
821 @param Address The PCI configuration register to read.
822 @param StartBit The ordinal of the least significant bit in the bit field.
823 Range 0..15.
824 @param EndBit The ordinal of the most significant bit in the bit field.
825 Range 0..15.
826
827 @return The value of the bit field read from the PCI configuration register.
828
829 **/
830 UINT16
831 EFIAPI
832 PciCf8BitFieldRead16 (
833 IN UINTN Address,
834 IN UINTN StartBit,
835 IN UINTN EndBit
836 )
837 {
838 BOOLEAN InterruptState;
839 UINT32 AddressPort;
840 UINT16 Result;
841
842 ASSERT_INVALID_PCI_ADDRESS (Address, 1);
843 InterruptState = SaveAndDisableInterrupts ();
844 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);
845 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));
846 Result = IoBitFieldRead16 (
847 PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),
848 StartBit,
849 EndBit
850 );
851 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);
852 SetInterruptState (InterruptState);
853 return Result;
854 }
855
856 /**
857 Writes a bit field to a PCI configuration register.
858
859 Writes Value to the bit field of the PCI configuration register. The bit
860 field is specified by the StartBit and the EndBit. All other bits in the
861 destination PCI configuration register are preserved. The new value of the
862 16-bit register is returned.
863
864 If Address > 0x0FFFFFFF, then ASSERT().
865 If Address is not aligned on a 16-bit boundary, then ASSERT().
866 If the register specified by Address >= 0x100, then ASSERT().
867 If StartBit is greater than 15, then ASSERT().
868 If EndBit is greater than 15, then ASSERT().
869 If EndBit is less than StartBit, then ASSERT().
870 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
871
872 @param Address The PCI configuration register to write.
873 @param StartBit The ordinal of the least significant bit in the bit field.
874 Range 0..15.
875 @param EndBit The ordinal of the most significant bit in the bit field.
876 Range 0..15.
877 @param Value The new value of the bit field.
878
879 @return The value written back to the PCI configuration register.
880
881 **/
882 UINT16
883 EFIAPI
884 PciCf8BitFieldWrite16 (
885 IN UINTN Address,
886 IN UINTN StartBit,
887 IN UINTN EndBit,
888 IN UINT16 Value
889 )
890 {
891 BOOLEAN InterruptState;
892 UINT32 AddressPort;
893 UINT16 Result;
894
895 ASSERT_INVALID_PCI_ADDRESS (Address, 1);
896 InterruptState = SaveAndDisableInterrupts ();
897 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);
898 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));
899 Result = IoBitFieldWrite16 (
900 PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),
901 StartBit,
902 EndBit,
903 Value
904 );
905 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);
906 SetInterruptState (InterruptState);
907 return Result;
908 }
909
910 /**
911 Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, and
912 writes the result back to the bit field in the 16-bit port.
913
914 Reads the 16-bit PCI configuration register specified by Address, performs a
915 bitwise OR between the read result and the value specified by
916 OrData, and writes the result to the 16-bit PCI configuration register
917 specified by Address. The value written to the PCI configuration register is
918 returned. This function must guarantee that all PCI read and write operations
919 are serialized. Extra left bits in OrData are stripped.
920
921 If Address > 0x0FFFFFFF, then ASSERT().
922 If Address is not aligned on a 16-bit boundary, then ASSERT().
923 If the register specified by Address >= 0x100, then ASSERT().
924 If StartBit is greater than 15, then ASSERT().
925 If EndBit is greater than 15, then ASSERT().
926 If EndBit is less than StartBit, then ASSERT().
927 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
928
929 @param Address The PCI configuration register to write.
930 @param StartBit The ordinal of the least significant bit in the bit field.
931 Range 0..15.
932 @param EndBit The ordinal of the most significant bit in the bit field.
933 Range 0..15.
934 @param OrData The value to OR with the PCI configuration register.
935
936 @return The value written back to the PCI configuration register.
937
938 **/
939 UINT16
940 EFIAPI
941 PciCf8BitFieldOr16 (
942 IN UINTN Address,
943 IN UINTN StartBit,
944 IN UINTN EndBit,
945 IN UINT16 OrData
946 )
947 {
948 BOOLEAN InterruptState;
949 UINT32 AddressPort;
950 UINT16 Result;
951
952 ASSERT_INVALID_PCI_ADDRESS (Address, 1);
953 InterruptState = SaveAndDisableInterrupts ();
954 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);
955 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));
956 Result = IoBitFieldOr16 (
957 PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),
958 StartBit,
959 EndBit,
960 OrData
961 );
962 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);
963 SetInterruptState (InterruptState);
964 return Result;
965 }
966
967 /**
968 Reads a bit field in a 16-bit PCI configuration register, performs a bitwise
969 AND, and writes the result back to the bit field in the 16-bit register.
970
971 Reads the 16-bit PCI configuration register specified by Address, performs a
972 bitwise AND between the read result and the value specified by AndData, and
973 writes the result to the 16-bit PCI configuration register specified by
974 Address. The value written to the PCI configuration register is returned.
975 This function must guarantee that all PCI read and write operations are
976 serialized. Extra left bits in AndData are stripped.
977
978 If Address > 0x0FFFFFFF, then ASSERT().
979 If Address is not aligned on a 16-bit boundary, then ASSERT().
980 If the register specified by Address >= 0x100, then ASSERT().
981 If StartBit is greater than 15, then ASSERT().
982 If EndBit is greater than 15, then ASSERT().
983 If EndBit is less than StartBit, then ASSERT().
984 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
985
986 @param Address The PCI configuration register to write.
987 @param StartBit The ordinal of the least significant bit in the bit field.
988 Range 0..15.
989 @param EndBit The ordinal of the most significant bit in the bit field.
990 Range 0..15.
991 @param AndData The value to AND with the PCI configuration register.
992
993 @return The value written back to the PCI configuration register.
994
995 **/
996 UINT16
997 EFIAPI
998 PciCf8BitFieldAnd16 (
999 IN UINTN Address,
1000 IN UINTN StartBit,
1001 IN UINTN EndBit,
1002 IN UINT16 AndData
1003 )
1004 {
1005 BOOLEAN InterruptState;
1006 UINT32 AddressPort;
1007 UINT16 Result;
1008
1009 ASSERT_INVALID_PCI_ADDRESS (Address, 1);
1010 InterruptState = SaveAndDisableInterrupts ();
1011 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);
1012 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));
1013 Result = IoBitFieldAnd16 (
1014 PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),
1015 StartBit,
1016 EndBit,
1017 AndData
1018 );
1019 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);
1020 SetInterruptState (InterruptState);
1021 return Result;
1022 }
1023
1024 /**
1025 Reads a bit field in a 16-bit port, performs a bitwise AND followed by a
1026 bitwise OR, and writes the result back to the bit field in the
1027 16-bit port.
1028
1029 Reads the 16-bit PCI configuration register specified by Address, performs a
1030 bitwise AND followed by a bitwise OR between the read result and
1031 the value specified by AndData, and writes the result to the 16-bit PCI
1032 configuration register specified by Address. The value written to the PCI
1033 configuration register is returned. This function must guarantee that all PCI
1034 read and write operations are serialized. Extra left bits in both AndData and
1035 OrData are stripped.
1036
1037 If Address > 0x0FFFFFFF, then ASSERT().
1038 If Address is not aligned on a 16-bit boundary, then ASSERT().
1039 If the register specified by Address >= 0x100, then ASSERT().
1040 If StartBit is greater than 15, then ASSERT().
1041 If EndBit is greater than 15, then ASSERT().
1042 If EndBit is less than StartBit, then ASSERT().
1043 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1044 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1045
1046 @param Address The PCI configuration register to write.
1047 @param StartBit The ordinal of the least significant bit in the bit field.
1048 Range 0..15.
1049 @param EndBit The ordinal of the most significant bit in the bit field.
1050 Range 0..15.
1051 @param AndData The value to AND with the PCI configuration register.
1052 @param OrData The value to OR with the result of the AND operation.
1053
1054 @return The value written back to the PCI configuration register.
1055
1056 **/
1057 UINT16
1058 EFIAPI
1059 PciCf8BitFieldAndThenOr16(
1060 IN UINTN Address,
1061 IN UINTN StartBit,
1062 IN UINTN EndBit,
1063 IN UINT16 AndData,
1064 IN UINT16 OrData
1065 )
1066 {
1067 BOOLEAN InterruptState;
1068 UINT32 AddressPort;
1069 UINT16 Result;
1070
1071 ASSERT_INVALID_PCI_ADDRESS (Address, 1);
1072 InterruptState = SaveAndDisableInterrupts ();
1073 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);
1074 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));
1075 Result = IoBitFieldAndThenOr16 (
1076 PCI_CONFIGURATION_DATA_PORT + (UINT16)(Address & 2),
1077 StartBit,
1078 EndBit,
1079 AndData,
1080 OrData
1081 );
1082 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);
1083 SetInterruptState (InterruptState);
1084 return Result;
1085 }
1086
1087 /**
1088 Reads a 32-bit PCI configuration register.
1089
1090 Reads and returns the 32-bit PCI configuration register specified by Address.
1091 This function must guarantee that all PCI read and write operations are
1092 serialized.
1093
1094 If Address > 0x0FFFFFFF, then ASSERT().
1095 If Address is not aligned on a 32-bit boundary, then ASSERT().
1096 If the register specified by Address >= 0x100, then ASSERT().
1097
1098 @param Address The address that encodes the PCI Bus, Device, Function and
1099 Register.
1100
1101 @return The read value from the PCI configuration register.
1102
1103 **/
1104 UINT32
1105 EFIAPI
1106 PciCf8Read32 (
1107 IN UINTN Address
1108 )
1109 {
1110 BOOLEAN InterruptState;
1111 UINT32 AddressPort;
1112 UINT32 Result;
1113
1114 ASSERT_INVALID_PCI_ADDRESS (Address, 3);
1115 InterruptState = SaveAndDisableInterrupts ();
1116 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);
1117 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));
1118 Result = IoRead32 (PCI_CONFIGURATION_DATA_PORT);
1119 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);
1120 SetInterruptState (InterruptState);
1121 return Result;
1122 }
1123
1124 /**
1125 Writes a 32-bit PCI configuration register.
1126
1127 Writes the 32-bit PCI configuration register specified by Address with the
1128 value specified by Value. Value is returned. This function must guarantee
1129 that all PCI read and write operations are serialized.
1130
1131 If Address > 0x0FFFFFFF, then ASSERT().
1132 If Address is not aligned on a 32-bit boundary, then ASSERT().
1133 If the register specified by Address >= 0x100, then ASSERT().
1134
1135 @param Address The address that encodes the PCI Bus, Device, Function and
1136 Register.
1137 @param Value The value to write.
1138
1139 @return The value written to the PCI configuration register.
1140
1141 **/
1142 UINT32
1143 EFIAPI
1144 PciCf8Write32 (
1145 IN UINTN Address,
1146 IN UINT32 Value
1147 )
1148 {
1149 BOOLEAN InterruptState;
1150 UINT32 AddressPort;
1151 UINT32 Result;
1152
1153 ASSERT_INVALID_PCI_ADDRESS (Address, 3);
1154 InterruptState = SaveAndDisableInterrupts ();
1155 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);
1156 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));
1157 Result = IoWrite32 (
1158 PCI_CONFIGURATION_DATA_PORT,
1159 Value
1160 );
1161 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);
1162 SetInterruptState (InterruptState);
1163 return Result;
1164 }
1165
1166 /**
1167 Performs a bitwise OR of a 32-bit PCI configuration register with
1168 a 32-bit value.
1169
1170 Reads the 32-bit PCI configuration register specified by Address, performs a
1171 bitwise OR between the read result and the value specified by
1172 OrData, and writes the result to the 32-bit PCI configuration register
1173 specified by Address. The value written to the PCI configuration register is
1174 returned. This function must guarantee that all PCI read and write operations
1175 are serialized.
1176
1177 If Address > 0x0FFFFFFF, then ASSERT().
1178 If Address is not aligned on a 32-bit boundary, then ASSERT().
1179 If the register specified by Address >= 0x100, then ASSERT().
1180
1181 @param Address The address that encodes the PCI Bus, Device, Function and
1182 Register.
1183 @param OrData The value to OR with the PCI configuration register.
1184
1185 @return The value written back to the PCI configuration register.
1186
1187 **/
1188 UINT32
1189 EFIAPI
1190 PciCf8Or32 (
1191 IN UINTN Address,
1192 IN UINT32 OrData
1193 )
1194 {
1195 BOOLEAN InterruptState;
1196 UINT32 AddressPort;
1197 UINT32 Result;
1198
1199 ASSERT_INVALID_PCI_ADDRESS (Address, 3);
1200 InterruptState = SaveAndDisableInterrupts ();
1201 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);
1202 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));
1203 Result = IoOr32 (
1204 PCI_CONFIGURATION_DATA_PORT,
1205 OrData
1206 );
1207 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);
1208 SetInterruptState (InterruptState);
1209 return Result;
1210 }
1211
1212 /**
1213 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
1214 value.
1215
1216 Reads the 32-bit PCI configuration register specified by Address, performs a
1217 bitwise AND between the read result and the value specified by AndData, and
1218 writes the result to the 32-bit PCI configuration register specified by
1219 Address. The value written to the PCI configuration register is returned.
1220 This function must guarantee that all PCI read and write operations are
1221 serialized.
1222
1223 If Address > 0x0FFFFFFF, then ASSERT().
1224 If Address is not aligned on a 32-bit boundary, then ASSERT().
1225 If the register specified by Address >= 0x100, then ASSERT().
1226
1227 @param Address The address that encodes the PCI Bus, Device, Function and
1228 Register.
1229 @param AndData The value to AND with the PCI configuration register.
1230
1231 @return The value written back to the PCI configuration register.
1232
1233 **/
1234 UINT32
1235 EFIAPI
1236 PciCf8And32 (
1237 IN UINTN Address,
1238 IN UINT32 AndData
1239 )
1240 {
1241 BOOLEAN InterruptState;
1242 UINT32 AddressPort;
1243 UINT32 Result;
1244
1245 ASSERT_INVALID_PCI_ADDRESS (Address, 3);
1246 InterruptState = SaveAndDisableInterrupts ();
1247 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);
1248 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));
1249 Result = IoAnd32 (
1250 PCI_CONFIGURATION_DATA_PORT,
1251 AndData
1252 );
1253 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);
1254 SetInterruptState (InterruptState);
1255 return Result;
1256 }
1257
1258 /**
1259 Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
1260 value, followed a bitwise OR with another 32-bit value.
1261
1262 Reads the 32-bit PCI configuration register specified by Address, performs a
1263 bitwise AND between the read result and the value specified by AndData,
1264 performs a bitwise OR between the result of the AND operation and
1265 the value specified by OrData, and writes the result to the 32-bit PCI
1266 configuration register specified by Address. The value written to the PCI
1267 configuration register is returned. This function must guarantee that all PCI
1268 read and write operations are serialized.
1269
1270 If Address > 0x0FFFFFFF, then ASSERT().
1271 If Address is not aligned on a 32-bit boundary, then ASSERT().
1272 If the register specified by Address >= 0x100, then ASSERT().
1273
1274 @param Address The address that encodes the PCI Bus, Device, Function and
1275 Register.
1276 @param AndData The value to AND with the PCI configuration register.
1277 @param OrData The value to OR with the result of the AND operation.
1278
1279 @return The value written back to the PCI configuration register.
1280
1281 **/
1282 UINT32
1283 EFIAPI
1284 PciCf8AndThenOr32 (
1285 IN UINTN Address,
1286 IN UINT32 AndData,
1287 IN UINT32 OrData
1288 )
1289 {
1290 BOOLEAN InterruptState;
1291 UINT32 AddressPort;
1292 UINT32 Result;
1293
1294 ASSERT_INVALID_PCI_ADDRESS (Address, 3);
1295 InterruptState = SaveAndDisableInterrupts ();
1296 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);
1297 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));
1298 Result = IoAndThenOr32 (
1299 PCI_CONFIGURATION_DATA_PORT,
1300 AndData,
1301 OrData
1302 );
1303 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);
1304 SetInterruptState (InterruptState);
1305 return Result;
1306 }
1307
1308 /**
1309 Reads a bit field of a PCI configuration register.
1310
1311 Reads the bit field in a 32-bit PCI configuration register. The bit field is
1312 specified by the StartBit and the EndBit. The value of the bit field is
1313 returned.
1314
1315 If Address > 0x0FFFFFFF, then ASSERT().
1316 If Address is not aligned on a 32-bit boundary, then ASSERT().
1317 If the register specified by Address >= 0x100, then ASSERT().
1318 If StartBit is greater than 31, then ASSERT().
1319 If EndBit is greater than 31, then ASSERT().
1320 If EndBit is less than StartBit, then ASSERT().
1321
1322 @param Address The PCI configuration register to read.
1323 @param StartBit The ordinal of the least significant bit in the bit field.
1324 Range 0..31.
1325 @param EndBit The ordinal of the most significant bit in the bit field.
1326 Range 0..31.
1327
1328 @return The value of the bit field read from the PCI configuration register.
1329
1330 **/
1331 UINT32
1332 EFIAPI
1333 PciCf8BitFieldRead32 (
1334 IN UINTN Address,
1335 IN UINTN StartBit,
1336 IN UINTN EndBit
1337 )
1338 {
1339 BOOLEAN InterruptState;
1340 UINT32 AddressPort;
1341 UINT32 Result;
1342
1343 ASSERT_INVALID_PCI_ADDRESS (Address, 3);
1344 InterruptState = SaveAndDisableInterrupts ();
1345 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);
1346 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));
1347 Result = IoBitFieldRead32 (
1348 PCI_CONFIGURATION_DATA_PORT,
1349 StartBit,
1350 EndBit
1351 );
1352 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);
1353 SetInterruptState (InterruptState);
1354 return Result;
1355 }
1356
1357 /**
1358 Writes a bit field to a PCI configuration register.
1359
1360 Writes Value to the bit field of the PCI configuration register. The bit
1361 field is specified by the StartBit and the EndBit. All other bits in the
1362 destination PCI configuration register are preserved. The new value of the
1363 32-bit register is returned.
1364
1365 If Address > 0x0FFFFFFF, then ASSERT().
1366 If Address is not aligned on a 32-bit boundary, then ASSERT().
1367 If the register specified by Address >= 0x100, then ASSERT().
1368 If StartBit is greater than 31, then ASSERT().
1369 If EndBit is greater than 31, then ASSERT().
1370 If EndBit is less than StartBit, then ASSERT().
1371 If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1372
1373 @param Address The PCI configuration register to write.
1374 @param StartBit The ordinal of the least significant bit in the bit field.
1375 Range 0..31.
1376 @param EndBit The ordinal of the most significant bit in the bit field.
1377 Range 0..31.
1378 @param Value The new value of the bit field.
1379
1380 @return The value written back to the PCI configuration register.
1381
1382 **/
1383 UINT32
1384 EFIAPI
1385 PciCf8BitFieldWrite32 (
1386 IN UINTN Address,
1387 IN UINTN StartBit,
1388 IN UINTN EndBit,
1389 IN UINT32 Value
1390 )
1391 {
1392 BOOLEAN InterruptState;
1393 UINT32 AddressPort;
1394 UINT32 Result;
1395
1396 ASSERT_INVALID_PCI_ADDRESS (Address, 3);
1397 InterruptState = SaveAndDisableInterrupts ();
1398 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);
1399 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));
1400 Result = IoBitFieldWrite32 (
1401 PCI_CONFIGURATION_DATA_PORT,
1402 StartBit,
1403 EndBit,
1404 Value
1405 );
1406 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);
1407 SetInterruptState (InterruptState);
1408 return Result;
1409 }
1410
1411 /**
1412 Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and
1413 writes the result back to the bit field in the 32-bit port.
1414
1415 Reads the 32-bit PCI configuration register specified by Address, performs a
1416 bitwise OR between the read result and the value specified by
1417 OrData, and writes the result to the 32-bit PCI configuration register
1418 specified by Address. The value written to the PCI configuration register is
1419 returned. This function must guarantee that all PCI read and write operations
1420 are serialized. Extra left bits in OrData are stripped.
1421
1422 If Address > 0x0FFFFFFF, then ASSERT().
1423 If Address is not aligned on a 32-bit boundary, then ASSERT().
1424 If the register specified by Address >= 0x100, then ASSERT().
1425 If StartBit is greater than 31, then ASSERT().
1426 If EndBit is greater than 31, then ASSERT().
1427 If EndBit is less than StartBit, then ASSERT().
1428 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1429
1430 @param Address The PCI configuration register to write.
1431 @param StartBit The ordinal of the least significant bit in the bit field.
1432 Range 0..31.
1433 @param EndBit The ordinal of the most significant bit in the bit field.
1434 Range 0..31.
1435 @param OrData The value to OR with the PCI configuration register.
1436
1437 @return The value written back to the PCI configuration register.
1438
1439 **/
1440 UINT32
1441 EFIAPI
1442 PciCf8BitFieldOr32 (
1443 IN UINTN Address,
1444 IN UINTN StartBit,
1445 IN UINTN EndBit,
1446 IN UINT32 OrData
1447 )
1448 {
1449 BOOLEAN InterruptState;
1450 UINT32 AddressPort;
1451 UINT32 Result;
1452
1453 ASSERT_INVALID_PCI_ADDRESS (Address, 3);
1454 InterruptState = SaveAndDisableInterrupts ();
1455 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);
1456 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));
1457 Result = IoBitFieldOr32 (
1458 PCI_CONFIGURATION_DATA_PORT,
1459 StartBit,
1460 EndBit,
1461 OrData
1462 );
1463 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);
1464 SetInterruptState (InterruptState);
1465 return Result;
1466 }
1467
1468 /**
1469 Reads a bit field in a 32-bit PCI configuration register, performs a bitwise
1470 AND, and writes the result back to the bit field in the 32-bit register.
1471
1472 Reads the 32-bit PCI configuration register specified by Address, performs a
1473 bitwise AND between the read result and the value specified by AndData, and
1474 writes the result to the 32-bit PCI configuration register specified by
1475 Address. The value written to the PCI configuration register is returned.
1476 This function must guarantee that all PCI read and write operations are
1477 serialized. Extra left bits in AndData are stripped.
1478
1479 If Address > 0x0FFFFFFF, then ASSERT().
1480 If Address is not aligned on a 32-bit boundary, then ASSERT().
1481 If the register specified by Address >= 0x100, then ASSERT().
1482 If StartBit is greater than 31, then ASSERT().
1483 If EndBit is greater than 31, then ASSERT().
1484 If EndBit is less than StartBit, then ASSERT().
1485 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1486
1487 @param Address The PCI configuration register to write.
1488 @param StartBit The ordinal of the least significant bit in the bit field.
1489 Range 0..31.
1490 @param EndBit The ordinal of the most significant bit in the bit field.
1491 Range 0..31.
1492 @param AndData The value to AND with the PCI configuration register.
1493
1494 @return The value written back to the PCI configuration register.
1495
1496 **/
1497 UINT32
1498 EFIAPI
1499 PciCf8BitFieldAnd32 (
1500 IN UINTN Address,
1501 IN UINTN StartBit,
1502 IN UINTN EndBit,
1503 IN UINT32 AndData
1504 )
1505 {
1506 BOOLEAN InterruptState;
1507 UINT32 AddressPort;
1508 UINT32 Result;
1509
1510 ASSERT_INVALID_PCI_ADDRESS (Address, 3);
1511 InterruptState = SaveAndDisableInterrupts ();
1512 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);
1513 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));
1514 Result = IoBitFieldAnd32 (
1515 PCI_CONFIGURATION_DATA_PORT,
1516 StartBit,
1517 EndBit,
1518 AndData
1519 );
1520 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);
1521 SetInterruptState (InterruptState);
1522 return Result;
1523 }
1524
1525 /**
1526 Reads a bit field in a 32-bit port, performs a bitwise AND followed by a
1527 bitwise OR, and writes the result back to the bit field in the
1528 32-bit port.
1529
1530 Reads the 32-bit PCI configuration register specified by Address, performs a
1531 bitwise AND followed by a bitwise OR between the read result and
1532 the value specified by AndData, and writes the result to the 32-bit PCI
1533 configuration register specified by Address. The value written to the PCI
1534 configuration register is returned. This function must guarantee that all PCI
1535 read and write operations are serialized. Extra left bits in both AndData and
1536 OrData are stripped.
1537
1538 If Address > 0x0FFFFFFF, then ASSERT().
1539 If Address is not aligned on a 32-bit boundary, then ASSERT().
1540 If the register specified by Address >= 0x100, then ASSERT().
1541 If StartBit is greater than 31, then ASSERT().
1542 If EndBit is greater than 31, then ASSERT().
1543 If EndBit is less than StartBit, then ASSERT().
1544 If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1545 If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
1546
1547 @param Address The PCI configuration register to write.
1548 @param StartBit The ordinal of the least significant bit in the bit field.
1549 Range 0..31.
1550 @param EndBit The ordinal of the most significant bit in the bit field.
1551 Range 0..31.
1552 @param AndData The value to AND with the PCI configuration register.
1553 @param OrData The value to OR with the result of the AND operation.
1554
1555 @return The value written back to the PCI configuration register.
1556
1557 **/
1558 UINT32
1559 EFIAPI
1560 PciCf8BitFieldAndThenOr32(
1561 IN UINTN Address,
1562 IN UINTN StartBit,
1563 IN UINTN EndBit,
1564 IN UINT32 AndData,
1565 IN UINT32 OrData
1566 )
1567 {
1568 BOOLEAN InterruptState;
1569 UINT32 AddressPort;
1570 UINT32 Result;
1571
1572 ASSERT_INVALID_PCI_ADDRESS (Address, 3);
1573 InterruptState = SaveAndDisableInterrupts ();
1574 AddressPort = IoRead32 (PCI_CONFIGURATION_ADDRESS_PORT);
1575 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, PCI_TO_CF8_ADDRESS (Address));
1576 Result = IoBitFieldAndThenOr32 (
1577 PCI_CONFIGURATION_DATA_PORT,
1578 StartBit,
1579 EndBit,
1580 AndData,
1581 OrData
1582 );
1583 IoWrite32 (PCI_CONFIGURATION_ADDRESS_PORT, AddressPort);
1584 SetInterruptState (InterruptState);
1585 return Result;
1586 }
1587
1588 /**
1589 Reads a range of PCI configuration registers into a caller supplied buffer.
1590
1591 Reads the range of PCI configuration registers specified by StartAddress and
1592 Size into the buffer specified by Buffer. This function only allows the PCI
1593 configuration registers from a single PCI function to be read. Size is
1594 returned. When possible 32-bit PCI configuration read cycles are used to read
1595 from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit
1596 and 16-bit PCI configuration read cycles may be used at the beginning and the
1597 end of the range.
1598
1599 If StartAddress > 0x0FFFFFFF, then ASSERT().
1600 If the register specified by StartAddress >= 0x100, then ASSERT().
1601 If ((StartAddress & 0xFFF) + Size) > 0x100, then ASSERT().
1602 If Size > 0 and Buffer is NULL, then ASSERT().
1603
1604 @param StartAddress The starting address that encodes the PCI Bus, Device,
1605 Function and Register.
1606 @param Size The size in bytes of the transfer.
1607 @param Buffer The pointer to a buffer receiving the data read.
1608
1609 @return Size read from StartAddress.
1610
1611 **/
1612 UINTN
1613 EFIAPI
1614 PciCf8ReadBuffer (
1615 IN UINTN StartAddress,
1616 IN UINTN Size,
1617 OUT VOID *Buffer
1618 )
1619 {
1620 UINTN ReturnValue;
1621
1622 ASSERT_INVALID_PCI_ADDRESS (StartAddress, 0);
1623 ASSERT (((StartAddress & 0xFFF) + Size) <= 0x100);
1624
1625 if (Size == 0) {
1626 return Size;
1627 }
1628
1629 ASSERT (Buffer != NULL);
1630
1631 //
1632 // Save Size for return
1633 //
1634 ReturnValue = Size;
1635
1636 if ((StartAddress & 1) != 0) {
1637 //
1638 // Read a byte if StartAddress is byte aligned
1639 //
1640 *(volatile UINT8 *)Buffer = PciCf8Read8 (StartAddress);
1641 StartAddress += sizeof (UINT8);
1642 Size -= sizeof (UINT8);
1643 Buffer = (UINT8*)Buffer + 1;
1644 }
1645
1646 if (Size >= sizeof (UINT16) && (StartAddress & 2) != 0) {
1647 //
1648 // Read a word if StartAddress is word aligned
1649 //
1650 WriteUnaligned16 ((UINT16 *)Buffer, (UINT16) PciCf8Read16 (StartAddress));
1651
1652 StartAddress += sizeof (UINT16);
1653 Size -= sizeof (UINT16);
1654 Buffer = (UINT16*)Buffer + 1;
1655 }
1656
1657 while (Size >= sizeof (UINT32)) {
1658 //
1659 // Read as many double words as possible
1660 //
1661 WriteUnaligned32 ((UINT32 *)Buffer, (UINT32) PciCf8Read32 (StartAddress));
1662 StartAddress += sizeof (UINT32);
1663 Size -= sizeof (UINT32);
1664 Buffer = (UINT32*)Buffer + 1;
1665 }
1666
1667 if (Size >= sizeof (UINT16)) {
1668 //
1669 // Read the last remaining word if exist
1670 //
1671 WriteUnaligned16 ((UINT16 *)Buffer, (UINT16) PciCf8Read16 (StartAddress));
1672 StartAddress += sizeof (UINT16);
1673 Size -= sizeof (UINT16);
1674 Buffer = (UINT16*)Buffer + 1;
1675 }
1676
1677 if (Size >= sizeof (UINT8)) {
1678 //
1679 // Read the last remaining byte if exist
1680 //
1681 *(volatile UINT8 *)Buffer = PciCf8Read8 (StartAddress);
1682 }
1683
1684 return ReturnValue;
1685 }
1686
1687 /**
1688 Copies the data in a caller supplied buffer to a specified range of PCI
1689 configuration space.
1690
1691 Writes the range of PCI configuration registers specified by StartAddress and
1692 Size from the buffer specified by Buffer. This function only allows the PCI
1693 configuration registers from a single PCI function to be written. Size is
1694 returned. When possible 32-bit PCI configuration write cycles are used to
1695 write from StartAdress to StartAddress + Size. Due to alignment restrictions,
1696 8-bit and 16-bit PCI configuration write cycles may be used at the beginning
1697 and the end of the range.
1698
1699 If StartAddress > 0x0FFFFFFF, then ASSERT().
1700 If the register specified by StartAddress >= 0x100, then ASSERT().
1701 If ((StartAddress & 0xFFF) + Size) > 0x100, then ASSERT().
1702 If Size > 0 and Buffer is NULL, then ASSERT().
1703
1704 @param StartAddress The starting address that encodes the PCI Bus, Device,
1705 Function and Register.
1706 @param Size The size in bytes of the transfer.
1707 @param Buffer The pointer to a buffer containing the data to write.
1708
1709 @return Size written to StartAddress.
1710
1711 **/
1712 UINTN
1713 EFIAPI
1714 PciCf8WriteBuffer (
1715 IN UINTN StartAddress,
1716 IN UINTN Size,
1717 IN VOID *Buffer
1718 )
1719 {
1720 UINTN ReturnValue;
1721
1722 ASSERT_INVALID_PCI_ADDRESS (StartAddress, 0);
1723 ASSERT (((StartAddress & 0xFFF) + Size) <= 0x100);
1724
1725 if (Size == 0) {
1726 return 0;
1727 }
1728
1729 ASSERT (Buffer != NULL);
1730
1731 //
1732 // Save Size for return
1733 //
1734 ReturnValue = Size;
1735
1736 if ((StartAddress & 1) != 0) {
1737 //
1738 // Write a byte if StartAddress is byte aligned
1739 //
1740 PciCf8Write8 (StartAddress, *(UINT8*)Buffer);
1741 StartAddress += sizeof (UINT8);
1742 Size -= sizeof (UINT8);
1743 Buffer = (UINT8*)Buffer + 1;
1744 }
1745
1746 if (Size >= sizeof (UINT16) && (StartAddress & 2) != 0) {
1747 //
1748 // Write a word if StartAddress is word aligned
1749 //
1750 PciCf8Write16 (StartAddress, ReadUnaligned16 ((UINT16*)Buffer));
1751 StartAddress += sizeof (UINT16);
1752 Size -= sizeof (UINT16);
1753 Buffer = (UINT16*)Buffer + 1;
1754 }
1755
1756 while (Size >= sizeof (UINT32)) {
1757 //
1758 // Write as many double words as possible
1759 //
1760 PciCf8Write32 (StartAddress, ReadUnaligned32 ((UINT32*)Buffer));
1761 StartAddress += sizeof (UINT32);
1762 Size -= sizeof (UINT32);
1763 Buffer = (UINT32*)Buffer + 1;
1764 }
1765
1766 if (Size >= sizeof (UINT16)) {
1767 //
1768 // Write the last remaining word if exist
1769 //
1770 PciCf8Write16 (StartAddress, ReadUnaligned16 ((UINT16*)Buffer));
1771 StartAddress += sizeof (UINT16);
1772 Size -= sizeof (UINT16);
1773 Buffer = (UINT16*)Buffer + 1;
1774 }
1775
1776 if (Size >= sizeof (UINT8)) {
1777 //
1778 // Write the last remaining byte if exist
1779 //
1780 PciCf8Write8 (StartAddress, *(UINT8*)Buffer);
1781 }
1782
1783 return ReturnValue;
1784 }