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