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