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