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