Coverage Report

Created: 2024-10-17 06:29

/src/hbfa-fl/HBFA/UefiHostTestPkg/Library/BaseLibHost/BitField.c
Line
Count
Source (jump to first uncovered line)
1
/** @file
2
  Bit field functions of BaseLib.
3
4
  Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
5
  SPDX-License-Identifier: BSD-2-Clause-Patent
6
7
**/
8
9
#include <Base.h>
10
#include <Library/BaseLib.h>
11
#include <Library/DebugLib.h>
12
13
/**
14
  Worker function that returns a bit field from Operand.
15
16
  Returns the bitfield specified by the StartBit and the EndBit from Operand.
17
18
  @param  Operand   Operand on which to perform the bitfield operation.
19
  @param  StartBit  The ordinal of the least significant bit in the bit field.
20
  @param  EndBit    The ordinal of the most significant bit in the bit field.
21
22
  @return The bit field read.
23
24
**/
25
UINTN
26
EFIAPI
27
InternalBaseLibBitFieldReadUint (
28
  IN      UINTN                     Operand,
29
  IN      UINTN                     StartBit,
30
  IN      UINTN                     EndBit
31
  )
32
0
{
33
  //
34
  // ~((UINTN)-2 << EndBit) is a mask in which bit[0] thru bit[EndBit]
35
  // are 1's while bit[EndBit + 1] thru the most significant bit are 0's.
36
  //
37
0
  return (Operand & ~((UINTN)-2 << EndBit)) >> StartBit;
38
0
}
39
40
/**
41
  Worker function that reads a bit field from Operand, performs a bitwise OR,
42
  and returns the result.
43
44
  Performs a bitwise OR between the bit field specified by StartBit and EndBit
45
  in Operand and the value specified by AndData. All other bits in Operand are
46
  preserved. The new value is returned.
47
48
  If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
49
50
  @param  Operand   Operand on which to perform the bitfield operation.
51
  @param  StartBit  The ordinal of the least significant bit in the bit field.
52
  @param  EndBit    The ordinal of the most significant bit in the bit field.
53
  @param  OrData    The value to OR with the read value from the value.
54
55
  @return The new value.
56
57
**/
58
UINTN
59
EFIAPI
60
InternalBaseLibBitFieldOrUint (
61
  IN      UINTN                     Operand,
62
  IN      UINTN                     StartBit,
63
  IN      UINTN                     EndBit,
64
  IN      UINTN                     OrData
65
  )
66
0
{
67
  //
68
  // Higher bits in OrData those are not used must be zero.
69
  //
70
  // EndBit - StartBit + 1 might be 32 while the result right shifting 32 on a 32bit integer is undefined,
71
  // So the logic is updated to right shift (EndBit - StartBit) bits and compare the last bit directly.
72
  //
73
0
  ASSERT ((OrData >> (EndBit - StartBit)) == ((OrData >> (EndBit - StartBit)) & 1));
74
75
  //
76
  // ~((UINTN)-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
0
  return Operand | ((OrData << StartBit) & ~((UINTN) -2 << EndBit));
80
0
}
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
  If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
91
92
  @param  Operand   Operand on which to perform the bitfield operation.
93
  @param  StartBit  The ordinal of the least significant bit in the bit field.
94
  @param  EndBit    The ordinal of the most significant bit in the bit field.
95
  @param  AndData    The value to And with the read value from the value.
96
97
  @return The new value.
98
99
**/
100
UINTN
101
EFIAPI
102
InternalBaseLibBitFieldAndUint (
103
  IN      UINTN                     Operand,
104
  IN      UINTN                     StartBit,
105
  IN      UINTN                     EndBit,
106
  IN      UINTN                     AndData
107
  )
108
0
{
109
  //
110
  // Higher bits in AndData those are not used must be zero.
111
  //
112
  // EndBit - StartBit + 1 might be 32 while the result right shifting 32 on a 32bit integer is undefined,
113
  // So the logic is updated to right shift (EndBit - StartBit) bits and compare the last bit directly.
114
  //
115
0
  ASSERT ((AndData >> (EndBit - StartBit)) == ((AndData >> (EndBit - StartBit)) & 1));
116
117
  //
118
  // ~((UINTN)-2 << EndBit) is a mask in which bit[0] thru bit[EndBit]
119
  // are 1's while bit[EndBit + 1] thru the most significant bit are 0's.
120
  //
121
0
  return Operand & ~((~AndData << StartBit) & ~((UINTN)-2 << EndBit));
122
0
}
123
124
/**
125
  Returns a bit field from an 8-bit value.
126
127
  Returns the bitfield specified by the StartBit and the EndBit from Operand.
128
129
  If 8-bit operations are not supported, then ASSERT().
130
  If StartBit is greater than 7, then ASSERT().
131
  If EndBit is greater than 7, then ASSERT().
132
  If EndBit is less than StartBit, then ASSERT().
133
134
  @param  Operand   Operand on which to perform the bitfield operation.
135
  @param  StartBit  The ordinal of the least significant bit in the bit field.
136
                    Range 0..7.
137
  @param  EndBit    The ordinal of the most significant bit in the bit field.
138
                    Range 0..7.
139
140
  @return The bit field read.
141
142
**/
143
UINT8
144
EFIAPI
145
BitFieldRead8 (
146
  IN      UINT8                     Operand,
147
  IN      UINTN                     StartBit,
148
  IN      UINTN                     EndBit
149
  )
150
0
{
151
0
  ASSERT (EndBit < 8);
152
0
  ASSERT (StartBit <= EndBit);
153
0
  return (UINT8)InternalBaseLibBitFieldReadUint (Operand, StartBit, EndBit);
154
0
}
155
156
/**
157
  Writes a bit field to an 8-bit value, and returns the result.
158
159
  Writes Value to the bit field specified by the StartBit and the EndBit in
160
  Operand. All other bits in Operand are preserved. The new 8-bit value is
161
  returned.
162
163
  If 8-bit operations are not supported, then ASSERT().
164
  If StartBit is greater than 7, then ASSERT().
165
  If EndBit is greater than 7, then ASSERT().
166
  If EndBit is less than StartBit, then ASSERT().
167
  If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
168
169
  @param  Operand   Operand on which to perform the bitfield operation.
170
  @param  StartBit  The ordinal of the least significant bit in the bit field.
171
                    Range 0..7.
172
  @param  EndBit    The ordinal of the most significant bit in the bit field.
173
                    Range 0..7.
174
  @param  Value     The new value of the bit field.
175
176
  @return The new 8-bit value.
177
178
**/
179
UINT8
180
EFIAPI
181
BitFieldWrite8 (
182
  IN      UINT8                     Operand,
183
  IN      UINTN                     StartBit,
184
  IN      UINTN                     EndBit,
185
  IN      UINT8                     Value
186
  )
187
0
{
188
0
  ASSERT (EndBit < 8);
189
0
  ASSERT (StartBit <= EndBit);
190
0
  return BitFieldAndThenOr8 (Operand, StartBit, EndBit, 0, Value);
191
0
}
192
193
/**
194
  Reads a bit field from an 8-bit value, performs a bitwise OR, and returns the
195
  result.
196
197
  Performs a bitwise OR between the bit field specified by StartBit
198
  and EndBit in Operand and the value specified by OrData. All other bits in
199
  Operand are preserved. The new 8-bit value is returned.
200
201
  If 8-bit operations are not supported, then ASSERT().
202
  If StartBit is greater than 7, then ASSERT().
203
  If EndBit is greater than 7, then ASSERT().
204
  If EndBit is less than StartBit, then ASSERT().
205
  If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
206
207
  @param  Operand   Operand on which to perform the bitfield operation.
208
  @param  StartBit  The ordinal of the least significant bit in the bit field.
209
                    Range 0..7.
210
  @param  EndBit    The ordinal of the most significant bit in the bit field.
211
                    Range 0..7.
212
  @param  OrData    The value to OR with the read value from the value.
213
214
  @return The new 8-bit value.
215
216
**/
217
UINT8
218
EFIAPI
219
BitFieldOr8 (
220
  IN      UINT8                     Operand,
221
  IN      UINTN                     StartBit,
222
  IN      UINTN                     EndBit,
223
  IN      UINT8                     OrData
224
  )
225
0
{
226
0
  ASSERT (EndBit < 8);
227
0
  ASSERT (StartBit <= EndBit);
228
0
  return (UINT8)InternalBaseLibBitFieldOrUint (Operand, StartBit, EndBit, OrData);
229
0
}
230
231
/**
232
  Reads a bit field from an 8-bit value, performs a bitwise AND, and returns
233
  the result.
234
235
  Performs a bitwise AND between the bit field specified by StartBit and EndBit
236
  in Operand and the value specified by AndData. All other bits in Operand are
237
  preserved. The new 8-bit value is returned.
238
239
  If 8-bit operations are not supported, then ASSERT().
240
  If StartBit is greater than 7, then ASSERT().
241
  If EndBit is greater than 7, then ASSERT().
242
  If EndBit is less than StartBit, then ASSERT().
243
  If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
244
245
  @param  Operand   Operand on which to perform the bitfield operation.
246
  @param  StartBit  The ordinal of the least significant bit in the bit field.
247
                    Range 0..7.
248
  @param  EndBit    The ordinal of the most significant bit in the bit field.
249
                    Range 0..7.
250
  @param  AndData   The value to AND with the read value from the value.
251
252
  @return The new 8-bit value.
253
254
**/
255
UINT8
256
EFIAPI
257
BitFieldAnd8 (
258
  IN      UINT8                     Operand,
259
  IN      UINTN                     StartBit,
260
  IN      UINTN                     EndBit,
261
  IN      UINT8                     AndData
262
  )
263
0
{
264
0
  ASSERT (EndBit < 8);
265
0
  ASSERT (StartBit <= EndBit);
266
0
  return (UINT8)InternalBaseLibBitFieldAndUint (Operand, StartBit, EndBit, AndData);
267
0
}
268
269
/**
270
  Reads a bit field from an 8-bit value, performs a bitwise AND followed by a
271
  bitwise OR, and returns the result.
272
273
  Performs a bitwise AND between the bit field specified by StartBit and EndBit
274
  in Operand and the value specified by AndData, followed by a bitwise
275
  OR with value specified by OrData. All other bits in Operand are
276
  preserved. The new 8-bit value is returned.
277
278
  If 8-bit operations are not supported, then ASSERT().
279
  If StartBit is greater than 7, then ASSERT().
280
  If EndBit is greater than 7, then ASSERT().
281
  If EndBit is less than StartBit, then ASSERT().
282
  If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
283
  If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
284
285
  @param  Operand   Operand on which to perform the bitfield operation.
286
  @param  StartBit  The ordinal of the least significant bit in the bit field.
287
                    Range 0..7.
288
  @param  EndBit    The ordinal of the most significant bit in the bit field.
289
                    Range 0..7.
290
  @param  AndData   The value to AND with the read value from the value.
291
  @param  OrData    The value to OR with the result of the AND operation.
292
293
  @return The new 8-bit value.
294
295
**/
296
UINT8
297
EFIAPI
298
BitFieldAndThenOr8 (
299
  IN      UINT8                     Operand,
300
  IN      UINTN                     StartBit,
301
  IN      UINTN                     EndBit,
302
  IN      UINT8                     AndData,
303
  IN      UINT8                     OrData
304
  )
305
0
{
306
0
  ASSERT (EndBit < 8);
307
0
  ASSERT (StartBit <= EndBit);
308
0
  return BitFieldOr8 (
309
0
           BitFieldAnd8 (Operand, StartBit, EndBit, AndData),
310
0
           StartBit,
311
0
           EndBit,
312
0
           OrData
313
0
           );
314
0
}
315
316
/**
317
  Returns a bit field from a 16-bit value.
318
319
  Returns the bitfield specified by the StartBit and the EndBit from Operand.
320
321
  If 16-bit operations are not supported, then ASSERT().
322
  If StartBit is greater than 15, then ASSERT().
323
  If EndBit is greater than 15, then ASSERT().
324
  If EndBit is less than StartBit, then ASSERT().
325
326
  @param  Operand   Operand on which to perform the bitfield operation.
327
  @param  StartBit  The ordinal of the least significant bit in the bit field.
328
                    Range 0..15.
329
  @param  EndBit    The ordinal of the most significant bit in the bit field.
330
                    Range 0..15.
331
332
  @return The bit field read.
333
334
**/
335
UINT16
336
EFIAPI
337
BitFieldRead16 (
338
  IN      UINT16                    Operand,
339
  IN      UINTN                     StartBit,
340
  IN      UINTN                     EndBit
341
  )
342
0
{
343
0
  ASSERT (EndBit < 16);
344
0
  ASSERT (StartBit <= EndBit);
345
0
  return (UINT16)InternalBaseLibBitFieldReadUint (Operand, StartBit, EndBit);
346
0
}
347
348
/**
349
  Writes a bit field to a 16-bit value, and returns the result.
350
351
  Writes Value to the bit field specified by the StartBit and the EndBit in
352
  Operand. All other bits in Operand are preserved. The new 16-bit value is
353
  returned.
354
355
  If 16-bit operations are not supported, then ASSERT().
356
  If StartBit is greater than 15, then ASSERT().
357
  If EndBit is greater than 15, then ASSERT().
358
  If EndBit is less than StartBit, then ASSERT().
359
  If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
360
361
  @param  Operand   Operand on which to perform the bitfield operation.
362
  @param  StartBit  The ordinal of the least significant bit in the bit field.
363
                    Range 0..15.
364
  @param  EndBit    The ordinal of the most significant bit in the bit field.
365
                    Range 0..15.
366
  @param  Value     The new value of the bit field.
367
368
  @return The new 16-bit value.
369
370
**/
371
UINT16
372
EFIAPI
373
BitFieldWrite16 (
374
  IN      UINT16                    Operand,
375
  IN      UINTN                     StartBit,
376
  IN      UINTN                     EndBit,
377
  IN      UINT16                    Value
378
  )
379
0
{
380
0
  ASSERT (EndBit < 16);
381
0
  ASSERT (StartBit <= EndBit);
382
0
  return BitFieldAndThenOr16 (Operand, StartBit, EndBit, 0, Value);
383
0
}
384
385
/**
386
  Reads a bit field from a 16-bit value, performs a bitwise OR, and returns the
387
  result.
388
389
  Performs a bitwise OR between the bit field specified by StartBit
390
  and EndBit in Operand and the value specified by OrData. All other bits in
391
  Operand are preserved. The new 16-bit value is returned.
392
393
  If 16-bit operations are not supported, then ASSERT().
394
  If StartBit is greater than 15, then ASSERT().
395
  If EndBit is greater than 15, then ASSERT().
396
  If EndBit is less than StartBit, then ASSERT().
397
  If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
398
399
  @param  Operand   Operand on which to perform the bitfield operation.
400
  @param  StartBit  The ordinal of the least significant bit in the bit field.
401
                    Range 0..15.
402
  @param  EndBit    The ordinal of the most significant bit in the bit field.
403
                    Range 0..15.
404
  @param  OrData    The value to OR with the read value from the value.
405
406
  @return The new 16-bit value.
407
408
**/
409
UINT16
410
EFIAPI
411
BitFieldOr16 (
412
  IN      UINT16                    Operand,
413
  IN      UINTN                     StartBit,
414
  IN      UINTN                     EndBit,
415
  IN      UINT16                    OrData
416
  )
417
0
{
418
0
  ASSERT (EndBit < 16);
419
0
  ASSERT (StartBit <= EndBit);
420
0
  return (UINT16)InternalBaseLibBitFieldOrUint (Operand, StartBit, EndBit, OrData);
421
0
}
422
423
/**
424
  Reads a bit field from a 16-bit value, performs a bitwise AND, and returns
425
  the result.
426
427
  Performs a bitwise AND between the bit field specified by StartBit and EndBit
428
  in Operand and the value specified by AndData. All other bits in Operand are
429
  preserved. The new 16-bit value is returned.
430
431
  If 16-bit operations are not supported, then ASSERT().
432
  If StartBit is greater than 15, then ASSERT().
433
  If EndBit is greater than 15, then ASSERT().
434
  If EndBit is less than StartBit, then ASSERT().
435
  If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
436
437
  @param  Operand   Operand on which to perform the bitfield operation.
438
  @param  StartBit  The ordinal of the least significant bit in the bit field.
439
                    Range 0..15.
440
  @param  EndBit    The ordinal of the most significant bit in the bit field.
441
                    Range 0..15.
442
  @param  AndData   The value to AND with the read value from the value.
443
444
  @return The new 16-bit value.
445
446
**/
447
UINT16
448
EFIAPI
449
BitFieldAnd16 (
450
  IN      UINT16                    Operand,
451
  IN      UINTN                     StartBit,
452
  IN      UINTN                     EndBit,
453
  IN      UINT16                    AndData
454
  )
455
0
{
456
0
  ASSERT (EndBit < 16);
457
0
  ASSERT (StartBit <= EndBit);
458
0
  return (UINT16)InternalBaseLibBitFieldAndUint (Operand, StartBit, EndBit, AndData);
459
0
}
460
461
/**
462
  Reads a bit field from a 16-bit value, performs a bitwise AND followed by a
463
  bitwise OR, and returns the result.
464
465
  Performs a bitwise AND between the bit field specified by StartBit and EndBit
466
  in Operand and the value specified by AndData, followed by a bitwise
467
  OR with value specified by OrData. All other bits in Operand are
468
  preserved. The new 16-bit value is returned.
469
470
  If 16-bit operations are not supported, then ASSERT().
471
  If StartBit is greater than 15, then ASSERT().
472
  If EndBit is greater than 15, then ASSERT().
473
  If EndBit is less than StartBit, then ASSERT().
474
  If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
475
  If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
476
477
  @param  Operand   Operand on which to perform the bitfield operation.
478
  @param  StartBit  The ordinal of the least significant bit in the bit field.
479
                    Range 0..15.
480
  @param  EndBit    The ordinal of the most significant bit in the bit field.
481
                    Range 0..15.
482
  @param  AndData   The value to AND with the read value from the value.
483
  @param  OrData    The value to OR with the result of the AND operation.
484
485
  @return The new 16-bit value.
486
487
**/
488
UINT16
489
EFIAPI
490
BitFieldAndThenOr16 (
491
  IN      UINT16                    Operand,
492
  IN      UINTN                     StartBit,
493
  IN      UINTN                     EndBit,
494
  IN      UINT16                    AndData,
495
  IN      UINT16                    OrData
496
  )
497
0
{
498
0
  ASSERT (EndBit < 16);
499
0
  ASSERT (StartBit <= EndBit);
500
0
  return BitFieldOr16 (
501
0
           BitFieldAnd16 (Operand, StartBit, EndBit, AndData),
502
0
           StartBit,
503
0
           EndBit,
504
0
           OrData
505
0
           );
506
0
}
507
508
/**
509
  Returns a bit field from a 32-bit value.
510
511
  Returns the bitfield specified by the StartBit and the EndBit from Operand.
512
513
  If 32-bit operations are not supported, then ASSERT().
514
  If StartBit is greater than 31, then ASSERT().
515
  If EndBit is greater than 31, then ASSERT().
516
  If EndBit is less than StartBit, then ASSERT().
517
518
  @param  Operand   Operand on which to perform the bitfield operation.
519
  @param  StartBit  The ordinal of the least significant bit in the bit field.
520
                    Range 0..31.
521
  @param  EndBit    The ordinal of the most significant bit in the bit field.
522
                    Range 0..31.
523
524
  @return The bit field read.
525
526
**/
527
UINT32
528
EFIAPI
529
BitFieldRead32 (
530
  IN      UINT32                    Operand,
531
  IN      UINTN                     StartBit,
532
  IN      UINTN                     EndBit
533
  )
534
0
{
535
0
  ASSERT (EndBit < 32);
536
0
  ASSERT (StartBit <= EndBit);
537
0
  return (UINT32)InternalBaseLibBitFieldReadUint (Operand, StartBit, EndBit);
538
0
}
539
540
/**
541
  Writes a bit field to a 32-bit value, and returns the result.
542
543
  Writes Value to the bit field specified by the StartBit and the EndBit in
544
  Operand. All other bits in Operand are preserved. The new 32-bit value is
545
  returned.
546
547
  If 32-bit operations are not supported, then ASSERT().
548
  If StartBit is greater than 31, then ASSERT().
549
  If EndBit is greater than 31, then ASSERT().
550
  If EndBit is less than StartBit, then ASSERT().
551
  If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
552
553
  @param  Operand   Operand on which to perform the bitfield operation.
554
  @param  StartBit  The ordinal of the least significant bit in the bit field.
555
                    Range 0..31.
556
  @param  EndBit    The ordinal of the most significant bit in the bit field.
557
                    Range 0..31.
558
  @param  Value     The new value of the bit field.
559
560
  @return The new 32-bit value.
561
562
**/
563
UINT32
564
EFIAPI
565
BitFieldWrite32 (
566
  IN      UINT32                    Operand,
567
  IN      UINTN                     StartBit,
568
  IN      UINTN                     EndBit,
569
  IN      UINT32                    Value
570
  )
571
0
{
572
0
  ASSERT (EndBit < 32);
573
0
  ASSERT (StartBit <= EndBit);
574
0
  return BitFieldAndThenOr32 (Operand, StartBit, EndBit, 0, Value);
575
0
}
576
577
/**
578
  Reads a bit field from a 32-bit value, performs a bitwise OR, and returns the
579
  result.
580
581
  Performs a bitwise OR between the bit field specified by StartBit
582
  and EndBit in Operand and the value specified by OrData. All other bits in
583
  Operand are preserved. The new 32-bit value is returned.
584
585
  If 32-bit operations are not supported, then ASSERT().
586
  If StartBit is greater than 31, then ASSERT().
587
  If EndBit is greater than 31, then ASSERT().
588
  If EndBit is less than StartBit, then ASSERT().
589
  If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
590
591
  @param  Operand   Operand on which to perform the bitfield operation.
592
  @param  StartBit  The ordinal of the least significant bit in the bit field.
593
                    Range 0..31.
594
  @param  EndBit    The ordinal of the most significant bit in the bit field.
595
                    Range 0..31.
596
  @param  OrData    The value to OR with the read value from the value.
597
598
  @return The new 32-bit value.
599
600
**/
601
UINT32
602
EFIAPI
603
BitFieldOr32 (
604
  IN      UINT32                    Operand,
605
  IN      UINTN                     StartBit,
606
  IN      UINTN                     EndBit,
607
  IN      UINT32                    OrData
608
  )
609
0
{
610
0
  ASSERT (EndBit < 32);
611
0
  ASSERT (StartBit <= EndBit);
612
0
  return (UINT32)InternalBaseLibBitFieldOrUint (Operand, StartBit, EndBit, OrData);
613
0
}
614
615
/**
616
  Reads a bit field from a 32-bit value, performs a bitwise AND, and returns
617
  the result.
618
619
  Performs a bitwise AND between the bit field specified by StartBit and EndBit
620
  in Operand and the value specified by AndData. All other bits in Operand are
621
  preserved. The new 32-bit value is returned.
622
623
  If 32-bit operations are not supported, then ASSERT().
624
  If StartBit is greater than 31, then ASSERT().
625
  If EndBit is greater than 31, then ASSERT().
626
  If EndBit is less than StartBit, then ASSERT().
627
  If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
628
629
  @param  Operand   Operand on which to perform the bitfield operation.
630
  @param  StartBit  The ordinal of the least significant bit in the bit field.
631
                    Range 0..31.
632
  @param  EndBit    The ordinal of the most significant bit in the bit field.
633
                    Range 0..31.
634
  @param  AndData   The value to AND with the read value from the value.
635
636
  @return The new 32-bit value.
637
638
**/
639
UINT32
640
EFIAPI
641
BitFieldAnd32 (
642
  IN      UINT32                    Operand,
643
  IN      UINTN                     StartBit,
644
  IN      UINTN                     EndBit,
645
  IN      UINT32                    AndData
646
  )
647
0
{
648
0
  ASSERT (EndBit < 32);
649
0
  ASSERT (StartBit <= EndBit);
650
0
  return (UINT32)InternalBaseLibBitFieldAndUint (Operand, StartBit, EndBit, AndData);
651
0
}
652
653
/**
654
  Reads a bit field from a 32-bit value, performs a bitwise AND followed by a
655
  bitwise OR, and returns the result.
656
657
  Performs a bitwise AND between the bit field specified by StartBit and EndBit
658
  in Operand and the value specified by AndData, followed by a bitwise
659
  OR with value specified by OrData. All other bits in Operand are
660
  preserved. The new 32-bit value is returned.
661
662
  If 32-bit operations are not supported, then ASSERT().
663
  If StartBit is greater than 31, then ASSERT().
664
  If EndBit is greater than 31, then ASSERT().
665
  If EndBit is less than StartBit, then ASSERT().
666
  If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
667
  If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
668
669
  @param  Operand   Operand on which to perform the bitfield operation.
670
  @param  StartBit  The ordinal of the least significant bit in the bit field.
671
                    Range 0..31.
672
  @param  EndBit    The ordinal of the most significant bit in the bit field.
673
                    Range 0..31.
674
  @param  AndData   The value to AND with the read value from the value.
675
  @param  OrData    The value to OR with the result of the AND operation.
676
677
  @return The new 32-bit value.
678
679
**/
680
UINT32
681
EFIAPI
682
BitFieldAndThenOr32 (
683
  IN      UINT32                    Operand,
684
  IN      UINTN                     StartBit,
685
  IN      UINTN                     EndBit,
686
  IN      UINT32                    AndData,
687
  IN      UINT32                    OrData
688
  )
689
0
{
690
0
  ASSERT (EndBit < 32);
691
0
  ASSERT (StartBit <= EndBit);
692
0
  return BitFieldOr32 (
693
0
           BitFieldAnd32 (Operand, StartBit, EndBit, AndData),
694
0
           StartBit,
695
0
           EndBit,
696
0
           OrData
697
0
           );
698
0
}
699
700
/**
701
  Returns a bit field from a 64-bit value.
702
703
  Returns the bitfield specified by the StartBit and the EndBit from Operand.
704
705
  If 64-bit operations are not supported, then ASSERT().
706
  If StartBit is greater than 63, then ASSERT().
707
  If EndBit is greater than 63, then ASSERT().
708
  If EndBit is less than StartBit, then ASSERT().
709
710
  @param  Operand   Operand on which to perform the bitfield operation.
711
  @param  StartBit  The ordinal of the least significant bit in the bit field.
712
                    Range 0..63.
713
  @param  EndBit    The ordinal of the most significant bit in the bit field.
714
                    Range 0..63.
715
716
  @return The bit field read.
717
718
**/
719
UINT64
720
EFIAPI
721
BitFieldRead64 (
722
  IN      UINT64                    Operand,
723
  IN      UINTN                     StartBit,
724
  IN      UINTN                     EndBit
725
  )
726
0
{
727
0
  ASSERT (EndBit < 64);
728
0
  ASSERT (StartBit <= EndBit);
729
0
  return RShiftU64 (Operand & ~LShiftU64 ((UINT64)-2, EndBit), StartBit);
730
0
}
731
732
/**
733
  Writes a bit field to a 64-bit value, and returns the result.
734
735
  Writes Value to the bit field specified by the StartBit and the EndBit in
736
  Operand. All other bits in Operand are preserved. The new 64-bit value is
737
  returned.
738
739
  If 64-bit operations are not supported, then ASSERT().
740
  If StartBit is greater than 63, then ASSERT().
741
  If EndBit is greater than 63, then ASSERT().
742
  If EndBit is less than StartBit, then ASSERT().
743
  If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
744
745
  @param  Operand   Operand on which to perform the bitfield operation.
746
  @param  StartBit  The ordinal of the least significant bit in the bit field.
747
                    Range 0..63.
748
  @param  EndBit    The ordinal of the most significant bit in the bit field.
749
                    Range 0..63.
750
  @param  Value     The new value of the bit field.
751
752
  @return The new 64-bit value.
753
754
**/
755
UINT64
756
EFIAPI
757
BitFieldWrite64 (
758
  IN      UINT64                    Operand,
759
  IN      UINTN                     StartBit,
760
  IN      UINTN                     EndBit,
761
  IN      UINT64                    Value
762
  )
763
0
{
764
0
  ASSERT (EndBit < 64);
765
0
  ASSERT (StartBit <= EndBit);
766
0
  return BitFieldAndThenOr64 (Operand, StartBit, EndBit, 0, Value);
767
0
}
768
769
/**
770
  Reads a bit field from a 64-bit value, performs a bitwise OR, and returns the
771
  result.
772
773
  Performs a bitwise OR between the bit field specified by StartBit
774
  and EndBit in Operand and the value specified by OrData. All other bits in
775
  Operand are preserved. The new 64-bit value is returned.
776
777
  If 64-bit operations are not supported, then ASSERT().
778
  If StartBit is greater than 63, then ASSERT().
779
  If EndBit is greater than 63, then ASSERT().
780
  If EndBit is less than StartBit, then ASSERT().
781
  If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
782
783
  @param  Operand   Operand on which to perform the bitfield operation.
784
  @param  StartBit  The ordinal of the least significant bit in the bit field.
785
                    Range 0..63.
786
  @param  EndBit    The ordinal of the most significant bit in the bit field.
787
                    Range 0..63.
788
  @param  OrData    The value to OR with the read value from the value
789
790
  @return The new 64-bit value.
791
792
**/
793
UINT64
794
EFIAPI
795
BitFieldOr64 (
796
  IN      UINT64                    Operand,
797
  IN      UINTN                     StartBit,
798
  IN      UINTN                     EndBit,
799
  IN      UINT64                    OrData
800
  )
801
0
{
802
0
  UINT64  Value1;
803
0
  UINT64  Value2;
804
805
0
  ASSERT (EndBit < 64);
806
0
  ASSERT (StartBit <= EndBit);
807
  //
808
  // Higher bits in OrData those are not used must be zero.
809
  //
810
  // EndBit - StartBit + 1 might be 64 while the result right shifting 64 on RShiftU64() API is invalid,
811
  // So the logic is updated to right shift (EndBit - StartBit) bits and compare the last bit directly.
812
  //
813
0
  ASSERT (RShiftU64 (OrData, EndBit - StartBit) == (RShiftU64 (OrData, EndBit - StartBit) & 1));
814
815
0
  Value1 = LShiftU64 (OrData, StartBit);
816
0
  Value2 = LShiftU64 ((UINT64) - 2, EndBit);
817
818
0
  return Operand | (Value1 & ~Value2);
819
0
}
820
821
/**
822
  Reads a bit field from a 64-bit value, performs a bitwise AND, and returns
823
  the result.
824
825
  Performs a bitwise AND between the bit field specified by StartBit and EndBit
826
  in Operand and the value specified by AndData. All other bits in Operand are
827
  preserved. The new 64-bit value is returned.
828
829
  If 64-bit operations are not supported, then ASSERT().
830
  If StartBit is greater than 63, then ASSERT().
831
  If EndBit is greater than 63, then ASSERT().
832
  If EndBit is less than StartBit, then ASSERT().
833
  If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
834
835
  @param  Operand   Operand on which to perform the bitfield operation.
836
  @param  StartBit  The ordinal of the least significant bit in the bit field.
837
                    Range 0..63.
838
  @param  EndBit    The ordinal of the most significant bit in the bit field.
839
                    Range 0..63.
840
  @param  AndData   The value to AND with the read value from the value.
841
842
  @return The new 64-bit value.
843
844
**/
845
UINT64
846
EFIAPI
847
BitFieldAnd64 (
848
  IN      UINT64                    Operand,
849
  IN      UINTN                     StartBit,
850
  IN      UINTN                     EndBit,
851
  IN      UINT64                    AndData
852
  )
853
0
{
854
0
  UINT64  Value1;
855
0
  UINT64  Value2;
856
857
0
  ASSERT (EndBit < 64);
858
0
  ASSERT (StartBit <= EndBit);
859
  //
860
  // Higher bits in AndData those are not used must be zero.
861
  //
862
  // EndBit - StartBit + 1 might be 64 while the right shifting 64 on RShiftU64() API is invalid,
863
  // So the logic is updated to right shift (EndBit - StartBit) bits and compare the last bit directly.
864
  //
865
0
  ASSERT (RShiftU64 (AndData, EndBit - StartBit) == (RShiftU64 (AndData, EndBit - StartBit) & 1));
866
867
0
  Value1 = LShiftU64 (~AndData, StartBit);
868
0
  Value2 = LShiftU64 ((UINT64)-2, EndBit);
869
870
0
  return Operand & ~(Value1 & ~Value2);
871
0
}
872
873
/**
874
  Reads a bit field from a 64-bit value, performs a bitwise AND followed by a
875
  bitwise OR, and returns the result.
876
877
  Performs a bitwise AND between the bit field specified by StartBit and EndBit
878
  in Operand and the value specified by AndData, followed by a bitwise
879
  OR with value specified by OrData. All other bits in Operand are
880
  preserved. The new 64-bit value is returned.
881
882
  If 64-bit operations are not supported, then ASSERT().
883
  If StartBit is greater than 63, then ASSERT().
884
  If EndBit is greater than 63, then ASSERT().
885
  If EndBit is less than StartBit, then ASSERT().
886
  If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
887
  If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
888
889
  @param  Operand   Operand on which to perform the bitfield operation.
890
  @param  StartBit  The ordinal of the least significant bit in the bit field.
891
                    Range 0..63.
892
  @param  EndBit    The ordinal of the most significant bit in the bit field.
893
                    Range 0..63.
894
  @param  AndData   The value to AND with the read value from the value.
895
  @param  OrData    The value to OR with the result of the AND operation.
896
897
  @return The new 64-bit value.
898
899
**/
900
UINT64
901
EFIAPI
902
BitFieldAndThenOr64 (
903
  IN      UINT64                    Operand,
904
  IN      UINTN                     StartBit,
905
  IN      UINTN                     EndBit,
906
  IN      UINT64                    AndData,
907
  IN      UINT64                    OrData
908
  )
909
0
{
910
0
  ASSERT (EndBit < 64);
911
0
  ASSERT (StartBit <= EndBit);
912
0
  return BitFieldOr64 (
913
0
           BitFieldAnd64 (Operand, StartBit, EndBit, AndData),
914
0
           StartBit,
915
0
           EndBit,
916
0
           OrData
917
0
           );
918
0
}
919
920
/**
921
  Reads a bit field from a 32-bit value, counts and returns
922
  the number of set bits.
923
924
  Counts the number of set bits in the  bit field specified by
925
  StartBit and EndBit in Operand. The count is returned.
926
927
  If StartBit is greater than 31, then ASSERT().
928
  If EndBit is greater than 31, then ASSERT().
929
  If EndBit is less than StartBit, then ASSERT().
930
931
  @param  Operand   Operand on which to perform the bitfield operation.
932
  @param  StartBit  The ordinal of the least significant bit in the bit field.
933
                    Range 0..31.
934
  @param  EndBit    The ordinal of the most significant bit in the bit field.
935
                    Range 0..31.
936
937
  @return The number of bits set between StartBit and EndBit.
938
939
**/
940
UINT8
941
EFIAPI
942
BitFieldCountOnes32 (
943
  IN       UINT32                   Operand,
944
  IN       UINTN                    StartBit,
945
  IN       UINTN                    EndBit
946
  )
947
0
{
948
0
  UINT32 Count;
949
950
0
  ASSERT (EndBit < 32);
951
0
  ASSERT (StartBit <= EndBit);
952
953
0
  Count = BitFieldRead32 (Operand, StartBit, EndBit);
954
0
  Count -= ((Count >> 1) & 0x55555555);
955
0
  Count = (Count & 0x33333333) + ((Count >> 2) & 0x33333333);
956
0
  Count += Count >> 4;
957
0
  Count &= 0x0F0F0F0F;
958
0
  Count += Count >> 8;
959
0
  Count += Count >> 16;
960
961
0
  return (UINT8) Count & 0x3F;
962
0
}
963
964
/**
965
   Reads a bit field from a 64-bit value, counts and returns
966
   the number of set bits.
967
968
   Counts the number of set bits in the  bit field specified by
969
   StartBit and EndBit in Operand. The count is returned.
970
971
   If StartBit is greater than 63, then ASSERT().
972
   If EndBit is greater than 63, then ASSERT().
973
   If EndBit is less than StartBit, then ASSERT().
974
975
   @param  Operand   Operand on which to perform the bitfield operation.
976
   @param  StartBit  The ordinal of the least significant bit in the bit field.
977
   Range 0..63.
978
   @param  EndBit    The ordinal of the most significant bit in the bit field.
979
   Range 0..63.
980
981
   @return The number of bits set between StartBit and EndBit.
982
983
**/
984
UINT8
985
EFIAPI
986
BitFieldCountOnes64 (
987
  IN       UINT64                   Operand,
988
  IN       UINTN                    StartBit,
989
  IN       UINTN                    EndBit
990
  )
991
0
{
992
0
  UINT64 BitField;
993
0
  UINT8 Count;
994
995
0
  ASSERT (EndBit < 64);
996
0
  ASSERT (StartBit <= EndBit);
997
998
0
  BitField = BitFieldRead64 (Operand, StartBit, EndBit);
999
0
  Count = BitFieldCountOnes32 ((UINT32) BitField, 0, 31);
1000
0
  Count += BitFieldCountOnes32 ((UINT32) RShiftU64(BitField, 32), 0, 31);
1001
1002
0
  return Count;
1003
0
}
1004