1 /*++
2 
3 Copyright (c) 2004 - 2006, Intel Corporation. All rights reserved.<BR>
4 This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution.  The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8 
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11 
12 
13 Module Name:
14 
15   BitField.c
16 
17 Abstract:
18 
19   Bit field functions of BaseLib.
20 
21 --*/
22 
23 #include "BaseLibInternals.h"
24 
25 /**
26   Worker function that returns a bit field from Operand
27 
28   Returns the bitfield specified by the StartBit and the EndBit from Operand.
29 
30   @param  Operand   Operand on which to perform the bitfield operation.
31   @param  StartBit  The ordinal of the least significant bit in the bit field.
32   @param  EndBit    The ordinal of the most significant bit in the bit field.
33 
34   @return The bit field read.
35 
36 **/
37 unsigned int
BitFieldReadUint(IN unsigned int Operand,IN UINTN StartBit,IN UINTN EndBit)38 BitFieldReadUint (
39   IN      unsigned int              Operand,
40   IN      UINTN                     StartBit,
41   IN      UINTN                     EndBit
42   )
43 {
44   //
45   // ~((unsigned int)-2 << EndBit) is a mask in which bit[0] thru bit[EndBit]
46   // are 1's while bit[EndBit + 1] thru the most significant bit are 0's.
47   //
48   return (Operand & ~((unsigned int)-2 << EndBit)) >> StartBit;
49 }
50 
51 /**
52   Worker function that reads a bit field from Operand, performs a bitwise OR,
53   and returns the result.
54 
55   Performs a bitwise OR between the bit field specified by StartBit and EndBit
56   in Operand and the value specified by AndData. All other bits in Operand are
57   preserved. The new value is returned.
58 
59   @param  Operand   Operand on which to perform the bitfield operation.
60   @param  StartBit  The ordinal of the least significant bit in the bit field.
61   @param  EndBit    The ordinal of the most significant bit in the bit field.
62   @param  OrData    The value to OR with the read value from the value
63 
64   @return The new value.
65 
66 **/
67 unsigned int
BitFieldOrUint(IN unsigned int Operand,IN UINTN StartBit,IN UINTN EndBit,IN unsigned int OrData)68 BitFieldOrUint (
69   IN      unsigned int              Operand,
70   IN      UINTN                     StartBit,
71   IN      UINTN                     EndBit,
72   IN      unsigned int              OrData
73   )
74 {
75   //
76   // ~((unsigned int)-2 << EndBit) is a mask in which bit[0] thru bit[EndBit]
77   // are 1's while bit[EndBit + 1] thru the most significant bit are 0's.
78   //
79   return Operand | ((OrData << StartBit) & ~((unsigned int) -2 << EndBit));
80 }
81 
82 /**
83   Worker function that reads a bit field from Operand, performs a bitwise AND,
84   and returns the result.
85 
86   Performs a bitwise AND between the bit field specified by StartBit and EndBit
87   in Operand and the value specified by AndData. All other bits in Operand are
88   preserved. The new value is returned.
89 
90   @param  Operand   Operand on which to perform the bitfield operation.
91   @param  StartBit  The ordinal of the least significant bit in the bit field.
92   @param  EndBit    The ordinal of the most significant bit in the bit field.
93   @param  AndData    The value to And with the read value from the value
94 
95   @return The new value.
96 
97 **/
98 unsigned int
BitFieldAndUint(IN unsigned int Operand,IN UINTN StartBit,IN UINTN EndBit,IN unsigned int AndData)99 BitFieldAndUint (
100   IN      unsigned int              Operand,
101   IN      UINTN                     StartBit,
102   IN      UINTN                     EndBit,
103   IN      unsigned int              AndData
104   )
105 {
106   //
107   // ~((unsigned int)-2 << EndBit) is a mask in which bit[0] thru bit[EndBit]
108   // are 1's while bit[EndBit + 1] thru the most significant bit are 0's.
109   //
110   return Operand & ~((~AndData << StartBit) & ~((unsigned int) -2 << EndBit));
111 }
112 
113 /**
114   Returns a bit field from an 8-bit value.
115 
116   Returns the bitfield specified by the StartBit and the EndBit from Operand.
117 
118   If 8-bit operations are not supported, then ASSERT().
119   If StartBit is greater than 7, then ASSERT().
120   If EndBit is greater than 7, then ASSERT().
121   If EndBit is less than StartBit, then ASSERT().
122 
123   @param  Operand   Operand on which to perform the bitfield operation.
124   @param  StartBit  The ordinal of the least significant bit in the bit field.
125                     Range 0..7.
126   @param  EndBit    The ordinal of the most significant bit in the bit field.
127                     Range 0..7.
128 
129   @return The bit field read.
130 
131 **/
132 UINT8
133 EFIAPI
BitFieldRead8(IN UINT8 Operand,IN UINTN StartBit,IN UINTN EndBit)134 BitFieldRead8 (
135   IN      UINT8                     Operand,
136   IN      UINTN                     StartBit,
137   IN      UINTN                     EndBit
138   )
139 {
140   ASSERT (EndBit < sizeof (Operand) * 8);
141   ASSERT (StartBit <= EndBit);
142   return (UINT8)BitFieldReadUint (Operand, StartBit, EndBit);
143 }
144 
145 /**
146   Writes a bit field to an 8-bit value, and returns the result.
147 
148   Writes Value to the bit field specified by the StartBit and the EndBit in
149   Operand. All other bits in Operand are preserved. The new 8-bit value is
150   returned.
151 
152   If 8-bit operations are not supported, then ASSERT().
153   If StartBit is greater than 7, then ASSERT().
154   If EndBit is greater than 7, then ASSERT().
155   If EndBit is less than StartBit, then ASSERT().
156 
157   @param  Operand   Operand on which to perform the bitfield operation.
158   @param  StartBit  The ordinal of the least significant bit in the bit field.
159                     Range 0..7.
160   @param  EndBit    The ordinal of the most significant bit in the bit field.
161                     Range 0..7.
162   @param  Value     New value of the bit field.
163 
164   @return The new 8-bit value.
165 
166 **/
167 UINT8
168 EFIAPI
BitFieldWrite8(IN UINT8 Operand,IN UINTN StartBit,IN UINTN EndBit,IN UINT8 Value)169 BitFieldWrite8 (
170   IN      UINT8                     Operand,
171   IN      UINTN                     StartBit,
172   IN      UINTN                     EndBit,
173   IN      UINT8                     Value
174   )
175 {
176   ASSERT (EndBit < sizeof (Operand) * 8);
177   ASSERT (StartBit <= EndBit);
178   return BitFieldAndThenOr8 (Operand, StartBit, EndBit, 0, Value);
179 }
180 
181 /**
182   Reads a bit field from an 8-bit value, performs a bitwise OR, and returns the
183   result.
184 
185   Performs a bitwise inclusive OR between the bit field specified by StartBit
186   and EndBit in Operand and the value specified by OrData. All other bits in
187   Operand are preserved. The new 8-bit value is returned.
188 
189   If 8-bit operations are not supported, then ASSERT().
190   If StartBit is greater than 7, then ASSERT().
191   If EndBit is greater than 7, then ASSERT().
192   If EndBit is less than StartBit, then ASSERT().
193 
194   @param  Operand   Operand on which to perform the bitfield operation.
195   @param  StartBit  The ordinal of the least significant bit in the bit field.
196                     Range 0..7.
197   @param  EndBit    The ordinal of the most significant bit in the bit field.
198                     Range 0..7.
199   @param  OrData    The value to OR with the read value from the value
200 
201   @return The new 8-bit value.
202 
203 **/
204 UINT8
205 EFIAPI
BitFieldOr8(IN UINT8 Operand,IN UINTN StartBit,IN UINTN EndBit,IN UINT8 OrData)206 BitFieldOr8 (
207   IN      UINT8                     Operand,
208   IN      UINTN                     StartBit,
209   IN      UINTN                     EndBit,
210   IN      UINT8                     OrData
211   )
212 {
213   ASSERT (EndBit < sizeof (Operand) * 8);
214   ASSERT (StartBit <= EndBit);
215   return (UINT8)BitFieldOrUint (Operand, StartBit, EndBit, OrData);
216 }
217 
218 /**
219   Reads a bit field from an 8-bit value, performs a bitwise AND, and returns
220   the result.
221 
222   Performs a bitwise AND between the bit field specified by StartBit and EndBit
223   in Operand and the value specified by AndData. All other bits in Operand are
224   preserved. The new 8-bit value is returned.
225 
226   If 8-bit operations are not supported, then ASSERT().
227   If StartBit is greater than 7, then ASSERT().
228   If EndBit is greater than 7, then ASSERT().
229   If EndBit is less than StartBit, then ASSERT().
230 
231   @param  Operand   Operand on which to perform the bitfield operation.
232   @param  StartBit  The ordinal of the least significant bit in the bit field.
233                     Range 0..7.
234   @param  EndBit    The ordinal of the most significant bit in the bit field.
235                     Range 0..7.
236   @param  AndData   The value to AND with the read value from the value.
237 
238   @return The new 8-bit value.
239 
240 **/
241 UINT8
242 EFIAPI
BitFieldAnd8(IN UINT8 Operand,IN UINTN StartBit,IN UINTN EndBit,IN UINT8 AndData)243 BitFieldAnd8 (
244   IN      UINT8                     Operand,
245   IN      UINTN                     StartBit,
246   IN      UINTN                     EndBit,
247   IN      UINT8                     AndData
248   )
249 {
250   ASSERT (EndBit < sizeof (Operand) * 8);
251   ASSERT (StartBit <= EndBit);
252   return (UINT8)BitFieldAndUint (Operand, StartBit, EndBit, AndData);
253 }
254 
255 /**
256   Reads a bit field from an 8-bit value, performs a bitwise AND followed by a
257   bitwise OR, and returns the result.
258 
259   Performs a bitwise AND between the bit field specified by StartBit and EndBit
260   in Operand and the value specified by AndData, followed by a bitwise
261   inclusive OR with value specified by OrData. All other bits in Operand are
262   preserved. The new 8-bit value is returned.
263 
264   If 8-bit operations are not supported, then ASSERT().
265   If StartBit is greater than 7, then ASSERT().
266   If EndBit is greater than 7, then ASSERT().
267   If EndBit is less than StartBit, then ASSERT().
268 
269   @param  Operand   Operand on which to perform the bitfield operation.
270   @param  StartBit  The ordinal of the least significant bit in the bit field.
271                     Range 0..7.
272   @param  EndBit    The ordinal of the most significant bit in the bit field.
273                     Range 0..7.
274   @param  AndData   The value to AND with the read value from the value.
275   @param  OrData    The value to OR with the result of the AND operation.
276 
277   @return The new 8-bit value.
278 
279 **/
280 UINT8
281 EFIAPI
BitFieldAndThenOr8(IN UINT8 Operand,IN UINTN StartBit,IN UINTN EndBit,IN UINT8 AndData,IN UINT8 OrData)282 BitFieldAndThenOr8 (
283   IN      UINT8                     Operand,
284   IN      UINTN                     StartBit,
285   IN      UINTN                     EndBit,
286   IN      UINT8                     AndData,
287   IN      UINT8                     OrData
288   )
289 {
290   ASSERT (EndBit < sizeof (Operand) * 8);
291   ASSERT (StartBit <= EndBit);
292   return BitFieldOr8 (
293            BitFieldAnd8 (Operand, StartBit, EndBit, AndData),
294            StartBit,
295            EndBit,
296            OrData
297            );
298 }
299 
300 /**
301   Returns a bit field from a 16-bit value.
302 
303   Returns the bitfield specified by the StartBit and the EndBit from Operand.
304 
305   If 16-bit operations are not supported, then ASSERT().
306   If StartBit is greater than 15, then ASSERT().
307   If EndBit is greater than 15, then ASSERT().
308   If EndBit is less than StartBit, then ASSERT().
309 
310   @param  Operand   Operand on which to perform the bitfield operation.
311   @param  StartBit  The ordinal of the least significant bit in the bit field.
312                     Range 0..15.
313   @param  EndBit    The ordinal of the most significant bit in the bit field.
314                     Range 0..15.
315 
316   @return The bit field read.
317 
318 **/
319 UINT16
320 EFIAPI
BitFieldRead16(IN UINT16 Operand,IN UINTN StartBit,IN UINTN EndBit)321 BitFieldRead16 (
322   IN      UINT16                    Operand,
323   IN      UINTN                     StartBit,
324   IN      UINTN                     EndBit
325   )
326 {
327   ASSERT (EndBit < sizeof (Operand) * 8);
328   ASSERT (StartBit <= EndBit);
329   return (UINT16)BitFieldReadUint (Operand, StartBit, EndBit);
330 }
331 
332 /**
333   Writes a bit field to a 16-bit value, and returns the result.
334 
335   Writes Value to the bit field specified by the StartBit and the EndBit in
336   Operand. All other bits in Operand are preserved. The new 16-bit value is
337   returned.
338 
339   If 16-bit operations are not supported, then ASSERT().
340   If StartBit is greater than 15, then ASSERT().
341   If EndBit is greater than 15, then ASSERT().
342   If EndBit is less than StartBit, then ASSERT().
343 
344   @param  Operand   Operand on which to perform the bitfield operation.
345   @param  StartBit  The ordinal of the least significant bit in the bit field.
346                     Range 0..15.
347   @param  EndBit    The ordinal of the most significant bit in the bit field.
348                     Range 0..15.
349   @param  Value     New value of the bit field.
350 
351   @return The new 16-bit value.
352 
353 **/
354 UINT16
355 EFIAPI
BitFieldWrite16(IN UINT16 Operand,IN UINTN StartBit,IN UINTN EndBit,IN UINT16 Value)356 BitFieldWrite16 (
357   IN      UINT16                    Operand,
358   IN      UINTN                     StartBit,
359   IN      UINTN                     EndBit,
360   IN      UINT16                    Value
361   )
362 {
363   ASSERT (EndBit < sizeof (Operand) * 8);
364   ASSERT (StartBit <= EndBit);
365   return BitFieldAndThenOr16 (Operand, StartBit, EndBit, 0, Value);
366 }
367 
368 /**
369   Reads a bit field from a 16-bit value, performs a bitwise OR, and returns the
370   result.
371 
372   Performs a bitwise inclusive OR between the bit field specified by StartBit
373   and EndBit in Operand and the value specified by OrData. All other bits in
374   Operand are preserved. The new 16-bit value is returned.
375 
376   If 16-bit operations are not supported, then ASSERT().
377   If StartBit is greater than 15, then ASSERT().
378   If EndBit is greater than 15, then ASSERT().
379   If EndBit is less than StartBit, then ASSERT().
380 
381   @param  Operand   Operand on which to perform the bitfield operation.
382   @param  StartBit  The ordinal of the least significant bit in the bit field.
383                     Range 0..15.
384   @param  EndBit    The ordinal of the most significant bit in the bit field.
385                     Range 0..15.
386   @param  OrData    The value to OR with the read value from the value
387 
388   @return The new 16-bit value.
389 
390 **/
391 UINT16
392 EFIAPI
BitFieldOr16(IN UINT16 Operand,IN UINTN StartBit,IN UINTN EndBit,IN UINT16 OrData)393 BitFieldOr16 (
394   IN      UINT16                    Operand,
395   IN      UINTN                     StartBit,
396   IN      UINTN                     EndBit,
397   IN      UINT16                    OrData
398   )
399 {
400   ASSERT (EndBit < sizeof (Operand) * 8);
401   ASSERT (StartBit <= EndBit);
402   return (UINT16)BitFieldOrUint (Operand, StartBit, EndBit, OrData);
403 }
404 
405 /**
406   Reads a bit field from a 16-bit value, performs a bitwise AND, and returns
407   the result.
408 
409   Performs a bitwise AND between the bit field specified by StartBit and EndBit
410   in Operand and the value specified by AndData. All other bits in Operand are
411   preserved. The new 16-bit value is returned.
412 
413   If 16-bit operations are not supported, then ASSERT().
414   If StartBit is greater than 15, then ASSERT().
415   If EndBit is greater than 15, then ASSERT().
416   If EndBit is less than StartBit, then ASSERT().
417 
418   @param  Operand   Operand on which to perform the bitfield operation.
419   @param  StartBit  The ordinal of the least significant bit in the bit field.
420                     Range 0..15.
421   @param  EndBit    The ordinal of the most significant bit in the bit field.
422                     Range 0..15.
423   @param  AndData   The value to AND with the read value from the value
424 
425   @return The new 16-bit value.
426 
427 **/
428 UINT16
429 EFIAPI
BitFieldAnd16(IN UINT16 Operand,IN UINTN StartBit,IN UINTN EndBit,IN UINT16 AndData)430 BitFieldAnd16 (
431   IN      UINT16                    Operand,
432   IN      UINTN                     StartBit,
433   IN      UINTN                     EndBit,
434   IN      UINT16                    AndData
435   )
436 {
437   ASSERT (EndBit < sizeof (Operand) * 8);
438   ASSERT (StartBit <= EndBit);
439   return (UINT16)BitFieldAndUint (Operand, StartBit, EndBit, AndData);
440 }
441 
442 /**
443   Reads a bit field from a 16-bit value, performs a bitwise AND followed by a
444   bitwise OR, and returns the result.
445 
446   Performs a bitwise AND between the bit field specified by StartBit and EndBit
447   in Operand and the value specified by AndData, followed by a bitwise
448   inclusive OR with value specified by OrData. All other bits in Operand are
449   preserved. The new 16-bit value is returned.
450 
451   If 16-bit operations are not supported, then ASSERT().
452   If StartBit is greater than 15, then ASSERT().
453   If EndBit is greater than 15, then ASSERT().
454   If EndBit is less than StartBit, then ASSERT().
455 
456   @param  Operand   Operand on which to perform the bitfield operation.
457   @param  StartBit  The ordinal of the least significant bit in the bit field.
458                     Range 0..15.
459   @param  EndBit    The ordinal of the most significant bit in the bit field.
460                     Range 0..15.
461   @param  AndData   The value to AND with the read value from the value.
462   @param  OrData    The value to OR with the result of the AND operation.
463 
464   @return The new 16-bit value.
465 
466 **/
467 UINT16
468 EFIAPI
BitFieldAndThenOr16(IN UINT16 Operand,IN UINTN StartBit,IN UINTN EndBit,IN UINT16 AndData,IN UINT16 OrData)469 BitFieldAndThenOr16 (
470   IN      UINT16                    Operand,
471   IN      UINTN                     StartBit,
472   IN      UINTN                     EndBit,
473   IN      UINT16                    AndData,
474   IN      UINT16                    OrData
475   )
476 {
477   ASSERT (EndBit < sizeof (Operand) * 8);
478   ASSERT (StartBit <= EndBit);
479   return BitFieldOr16 (
480            BitFieldAnd16 (Operand, StartBit, EndBit, AndData),
481            StartBit,
482            EndBit,
483            OrData
484            );
485 }
486 
487 /**
488   Returns a bit field from a 32-bit value.
489 
490   Returns the bitfield specified by the StartBit and the EndBit from Operand.
491 
492   If 32-bit operations are not supported, then ASSERT().
493   If StartBit is greater than 31, then ASSERT().
494   If EndBit is greater than 31, then ASSERT().
495   If EndBit is less than StartBit, then ASSERT().
496 
497   @param  Operand   Operand on which to perform the bitfield operation.
498   @param  StartBit  The ordinal of the least significant bit in the bit field.
499                     Range 0..31.
500   @param  EndBit    The ordinal of the most significant bit in the bit field.
501                     Range 0..31.
502 
503   @return The bit field read.
504 
505 **/
506 UINT32
507 EFIAPI
BitFieldRead32(IN UINT32 Operand,IN UINTN StartBit,IN UINTN EndBit)508 BitFieldRead32 (
509   IN      UINT32                    Operand,
510   IN      UINTN                     StartBit,
511   IN      UINTN                     EndBit
512   )
513 {
514   ASSERT (EndBit < sizeof (Operand) * 8);
515   ASSERT (StartBit <= EndBit);
516   return (UINT32)BitFieldReadUint (Operand, StartBit, EndBit);
517 }
518 
519 /**
520   Writes a bit field to a 32-bit value, and returns the result.
521 
522   Writes Value to the bit field specified by the StartBit and the EndBit in
523   Operand. All other bits in Operand are preserved. The new 32-bit value is
524   returned.
525 
526   If 32-bit operations are not supported, then ASSERT().
527   If StartBit is greater than 31, then ASSERT().
528   If EndBit is greater than 31, then ASSERT().
529   If EndBit is less than StartBit, then ASSERT().
530 
531   @param  Operand   Operand on which to perform the bitfield operation.
532   @param  StartBit  The ordinal of the least significant bit in the bit field.
533                     Range 0..31.
534   @param  EndBit    The ordinal of the most significant bit in the bit field.
535                     Range 0..31.
536   @param  Value     New value of the bit field.
537 
538   @return The new 32-bit value.
539 
540 **/
541 UINT32
542 EFIAPI
BitFieldWrite32(IN UINT32 Operand,IN UINTN StartBit,IN UINTN EndBit,IN UINT32 Value)543 BitFieldWrite32 (
544   IN      UINT32                    Operand,
545   IN      UINTN                     StartBit,
546   IN      UINTN                     EndBit,
547   IN      UINT32                    Value
548   )
549 {
550   ASSERT (EndBit < sizeof (Operand) * 8);
551   ASSERT (StartBit <= EndBit);
552   return BitFieldAndThenOr32 (Operand, StartBit, EndBit, 0, Value);
553 }
554 
555 /**
556   Reads a bit field from a 32-bit value, performs a bitwise OR, and returns the
557   result.
558 
559   Performs a bitwise inclusive OR between the bit field specified by StartBit
560   and EndBit in Operand and the value specified by OrData. All other bits in
561   Operand are preserved. The new 32-bit value is returned.
562 
563   If 32-bit operations are not supported, then ASSERT().
564   If StartBit is greater than 31, then ASSERT().
565   If EndBit is greater than 31, then ASSERT().
566   If EndBit is less than StartBit, then ASSERT().
567 
568   @param  Operand   Operand on which to perform the bitfield operation.
569   @param  StartBit  The ordinal of the least significant bit in the bit field.
570                     Range 0..31.
571   @param  EndBit    The ordinal of the most significant bit in the bit field.
572                     Range 0..31.
573   @param  OrData    The value to OR with the read value from the value
574 
575   @return The new 32-bit value.
576 
577 **/
578 UINT32
579 EFIAPI
BitFieldOr32(IN UINT32 Operand,IN UINTN StartBit,IN UINTN EndBit,IN UINT32 OrData)580 BitFieldOr32 (
581   IN      UINT32                    Operand,
582   IN      UINTN                     StartBit,
583   IN      UINTN                     EndBit,
584   IN      UINT32                    OrData
585   )
586 {
587   ASSERT (EndBit < sizeof (Operand) * 8);
588   ASSERT (StartBit <= EndBit);
589   return (UINT32)BitFieldOrUint (Operand, StartBit, EndBit, OrData);
590 }
591 
592 /**
593   Reads a bit field from a 32-bit value, performs a bitwise AND, and returns
594   the result.
595 
596   Performs a bitwise AND between the bit field specified by StartBit and EndBit
597   in Operand and the value specified by AndData. All other bits in Operand are
598   preserved. The new 32-bit value is returned.
599 
600   If 32-bit operations are not supported, then ASSERT().
601   If StartBit is greater than 31, then ASSERT().
602   If EndBit is greater than 31, then ASSERT().
603   If EndBit is less than StartBit, then ASSERT().
604 
605   @param  Operand   Operand on which to perform the bitfield operation.
606   @param  StartBit  The ordinal of the least significant bit in the bit field.
607                     Range 0..31.
608   @param  EndBit    The ordinal of the most significant bit in the bit field.
609                     Range 0..31.
610   @param  AndData   The value to AND with the read value from the value
611 
612   @return The new 32-bit value.
613 
614 **/
615 UINT32
616 EFIAPI
BitFieldAnd32(IN UINT32 Operand,IN UINTN StartBit,IN UINTN EndBit,IN UINT32 AndData)617 BitFieldAnd32 (
618   IN      UINT32                    Operand,
619   IN      UINTN                     StartBit,
620   IN      UINTN                     EndBit,
621   IN      UINT32                    AndData
622   )
623 {
624   ASSERT (EndBit < sizeof (Operand) * 8);
625   ASSERT (StartBit <= EndBit);
626   return (UINT32)BitFieldAndUint (Operand, StartBit, EndBit, AndData);
627 }
628 
629 /**
630   Reads a bit field from a 32-bit value, performs a bitwise AND followed by a
631   bitwise OR, and returns the result.
632 
633   Performs a bitwise AND between the bit field specified by StartBit and EndBit
634   in Operand and the value specified by AndData, followed by a bitwise
635   inclusive OR with value specified by OrData. All other bits in Operand are
636   preserved. The new 32-bit value is returned.
637 
638   If 32-bit operations are not supported, then ASSERT().
639   If StartBit is greater than 31, then ASSERT().
640   If EndBit is greater than 31, then ASSERT().
641   If EndBit is less than StartBit, then ASSERT().
642 
643   @param  Operand   Operand on which to perform the bitfield operation.
644   @param  StartBit  The ordinal of the least significant bit in the bit field.
645                     Range 0..31.
646   @param  EndBit    The ordinal of the most significant bit in the bit field.
647                     Range 0..31.
648   @param  AndData   The value to AND with the read value from the value.
649   @param  OrData    The value to OR with the result of the AND operation.
650 
651   @return The new 32-bit value.
652 
653 **/
654 UINT32
655 EFIAPI
BitFieldAndThenOr32(IN UINT32 Operand,IN UINTN StartBit,IN UINTN EndBit,IN UINT32 AndData,IN UINT32 OrData)656 BitFieldAndThenOr32 (
657   IN      UINT32                    Operand,
658   IN      UINTN                     StartBit,
659   IN      UINTN                     EndBit,
660   IN      UINT32                    AndData,
661   IN      UINT32                    OrData
662   )
663 {
664   ASSERT (EndBit < sizeof (Operand) * 8);
665   ASSERT (StartBit <= EndBit);
666   return BitFieldOr32 (
667            BitFieldAnd32 (Operand, StartBit, EndBit, AndData),
668            StartBit,
669            EndBit,
670            OrData
671            );
672 }
673 
674 /**
675   Returns a bit field from a 64-bit value.
676 
677   Returns the bitfield specified by the StartBit and the EndBit from Operand.
678 
679   If 64-bit operations are not supported, then ASSERT().
680   If StartBit is greater than 63, then ASSERT().
681   If EndBit is greater than 63, then ASSERT().
682   If EndBit is less than StartBit, then ASSERT().
683 
684   @param  Operand   Operand on which to perform the bitfield operation.
685   @param  StartBit  The ordinal of the least significant bit in the bit field.
686                     Range 0..63.
687   @param  EndBit    The ordinal of the most significant bit in the bit field.
688                     Range 0..63.
689 
690   @return The bit field read.
691 
692 **/
693 UINT64
694 EFIAPI
BitFieldRead64(IN UINT64 Operand,IN UINTN StartBit,IN UINTN EndBit)695 BitFieldRead64 (
696   IN      UINT64                    Operand,
697   IN      UINTN                     StartBit,
698   IN      UINTN                     EndBit
699   )
700 {
701   ASSERT (EndBit < sizeof (Operand) * 8);
702   ASSERT (StartBit <= EndBit);
703   return RShiftU64 (Operand & ~LShiftU64 ((UINT64)-2, EndBit), StartBit);
704 }
705 
706 /**
707   Writes a bit field to a 64-bit value, and returns the result.
708 
709   Writes Value to the bit field specified by the StartBit and the EndBit in
710   Operand. All other bits in Operand are preserved. The new 64-bit value is
711   returned.
712 
713   If 64-bit operations are not supported, then ASSERT().
714   If StartBit is greater than 63, then ASSERT().
715   If EndBit is greater than 63, then ASSERT().
716   If EndBit is less than StartBit, then ASSERT().
717 
718   @param  Operand   Operand on which to perform the bitfield operation.
719   @param  StartBit  The ordinal of the least significant bit in the bit field.
720                     Range 0..63.
721   @param  EndBit    The ordinal of the most significant bit in the bit field.
722                     Range 0..63.
723   @param  Value     New value of the bit field.
724 
725   @return The new 64-bit value.
726 
727 **/
728 UINT64
729 EFIAPI
BitFieldWrite64(IN UINT64 Operand,IN UINTN StartBit,IN UINTN EndBit,IN UINT64 Value)730 BitFieldWrite64 (
731   IN      UINT64                    Operand,
732   IN      UINTN                     StartBit,
733   IN      UINTN                     EndBit,
734   IN      UINT64                    Value
735   )
736 {
737   ASSERT (EndBit < sizeof (Operand) * 8);
738   ASSERT (StartBit <= EndBit);
739   return BitFieldAndThenOr64 (Operand, StartBit, EndBit, 0, Value);
740 }
741 
742 /**
743   Reads a bit field from a 64-bit value, performs a bitwise OR, and returns the
744   result.
745 
746   Performs a bitwise inclusive OR between the bit field specified by StartBit
747   and EndBit in Operand and the value specified by OrData. All other bits in
748   Operand are preserved. The new 64-bit value is returned.
749 
750   If 64-bit operations are not supported, then ASSERT().
751   If StartBit is greater than 63, then ASSERT().
752   If EndBit is greater than 63, then ASSERT().
753   If EndBit is less than StartBit, then ASSERT().
754 
755   @param  Operand   Operand on which to perform the bitfield operation.
756   @param  StartBit  The ordinal of the least significant bit in the bit field.
757                     Range 0..63.
758   @param  EndBit    The ordinal of the most significant bit in the bit field.
759                     Range 0..63.
760   @param  OrData    The value to OR with the read value from the value
761 
762   @return The new 64-bit value.
763 
764 **/
765 UINT64
766 EFIAPI
BitFieldOr64(IN UINT64 Operand,IN UINTN StartBit,IN UINTN EndBit,IN UINT64 OrData)767 BitFieldOr64 (
768   IN      UINT64                    Operand,
769   IN      UINTN                     StartBit,
770   IN      UINTN                     EndBit,
771   IN      UINT64                    OrData
772   )
773 {
774   UINT64  Value1;
775   UINT64  Value2;
776 
777   ASSERT (EndBit < sizeof (Operand) * 8);
778   ASSERT (StartBit <= EndBit);
779 
780   Value1 = LShiftU64 (OrData, StartBit);
781   Value2 = LShiftU64 ((UINT64) - 2, EndBit);
782 
783   return Operand | (Value1 & ~Value2);
784 }
785 
786 /**
787   Reads a bit field from a 64-bit value, performs a bitwise AND, and returns
788   the result.
789 
790   Performs a bitwise AND between the bit field specified by StartBit and EndBit
791   in Operand and the value specified by AndData. All other bits in Operand are
792   preserved. The new 64-bit value is returned.
793 
794   If 64-bit operations are not supported, then ASSERT().
795   If StartBit is greater than 63, then ASSERT().
796   If EndBit is greater than 63, then ASSERT().
797   If EndBit is less than StartBit, then ASSERT().
798 
799   @param  Operand   Operand on which to perform the bitfield operation.
800   @param  StartBit  The ordinal of the least significant bit in the bit field.
801                     Range 0..63.
802   @param  EndBit    The ordinal of the most significant bit in the bit field.
803                     Range 0..63.
804   @param  AndData   The value to AND with the read value from the value
805 
806   @return The new 64-bit value.
807 
808 **/
809 UINT64
810 EFIAPI
BitFieldAnd64(IN UINT64 Operand,IN UINTN StartBit,IN UINTN EndBit,IN UINT64 AndData)811 BitFieldAnd64 (
812   IN      UINT64                    Operand,
813   IN      UINTN                     StartBit,
814   IN      UINTN                     EndBit,
815   IN      UINT64                    AndData
816   )
817 {
818   UINT64  Value1;
819   UINT64  Value2;
820 
821   ASSERT (EndBit < sizeof (Operand) * 8);
822   ASSERT (StartBit <= EndBit);
823 
824   Value1 = LShiftU64 (~AndData, StartBit);
825   Value2 = LShiftU64 ((UINT64)-2, EndBit);
826 
827   return Operand & ~(Value1 & ~Value2);
828 }
829 
830 /**
831   Reads a bit field from a 64-bit value, performs a bitwise AND followed by a
832   bitwise OR, and returns the result.
833 
834   Performs a bitwise AND between the bit field specified by StartBit and EndBit
835   in Operand and the value specified by AndData, followed by a bitwise
836   inclusive OR with value specified by OrData. All other bits in Operand are
837   preserved. The new 64-bit value is returned.
838 
839   If 64-bit operations are not supported, then ASSERT().
840   If StartBit is greater than 63, then ASSERT().
841   If EndBit is greater than 63, then ASSERT().
842   If EndBit is less than StartBit, then ASSERT().
843 
844   @param  Operand   Operand on which to perform the bitfield operation.
845   @param  StartBit  The ordinal of the least significant bit in the bit field.
846                     Range 0..63.
847   @param  EndBit    The ordinal of the most significant bit in the bit field.
848                     Range 0..63.
849   @param  AndData   The value to AND with the read value from the value.
850   @param  OrData    The value to OR with the result of the AND operation.
851 
852   @return The new 64-bit value.
853 
854 **/
855 UINT64
856 EFIAPI
BitFieldAndThenOr64(IN UINT64 Operand,IN UINTN StartBit,IN UINTN EndBit,IN UINT64 AndData,IN UINT64 OrData)857 BitFieldAndThenOr64 (
858   IN      UINT64                    Operand,
859   IN      UINTN                     StartBit,
860   IN      UINTN                     EndBit,
861   IN      UINT64                    AndData,
862   IN      UINT64                    OrData
863   )
864 {
865   ASSERT (EndBit < sizeof (Operand) * 8);
866   ASSERT (StartBit <= EndBit);
867   return BitFieldOr64 (
868            BitFieldAnd64 (Operand, StartBit, EndBit, AndData),
869            StartBit,
870            EndBit,
871            OrData
872            );
873 }
874