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