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