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