amd/addrlib: update to the latest version
[mesa.git] / src / amd / addrlib / src / core / addrcommon.h
1 /*
2 * Copyright © 2007-2019 Advanced Micro Devices, Inc.
3 * All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sub license, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
14 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
15 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
16 * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS
17 * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20 * USE OR OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * The above copyright notice and this permission notice (including the
23 * next paragraph) shall be included in all copies or substantial portions
24 * of the Software.
25 */
26
27 /**
28 ****************************************************************************************************
29 * @file addrcommon.h
30 * @brief Contains the helper function and constants.
31 ****************************************************************************************************
32 */
33
34 #ifndef __ADDR_COMMON_H__
35 #define __ADDR_COMMON_H__
36
37 #include "addrinterface.h"
38
39 #if !defined(DEBUG)
40 #ifdef NDEBUG
41 #define DEBUG 0
42 #else
43 #define DEBUG 1
44 #endif
45 #endif
46
47 // ADDR_LNX_KERNEL_BUILD is for internal build
48 // Moved from addrinterface.h so __KERNEL__ is not needed any more
49 #if ADDR_LNX_KERNEL_BUILD // || (defined(__GNUC__) && defined(__KERNEL__))
50 #include <string.h>
51 #elif !defined(__APPLE__) || defined(HAVE_TSERVER)
52 #include <stdlib.h>
53 #include <string.h>
54 #endif
55
56 #include <assert.h>
57 #include "util/macros.h"
58
59 ////////////////////////////////////////////////////////////////////////////////////////////////////
60 // Platform specific debug break defines
61 ////////////////////////////////////////////////////////////////////////////////////////////////////
62 #if DEBUG
63 #if defined(__GNUC__)
64 #define ADDR_DBG_BREAK() assert(false)
65 #elif defined(__APPLE__)
66 #define ADDR_DBG_BREAK() { IOPanic("");}
67 #else
68 #define ADDR_DBG_BREAK() { __debugbreak(); }
69 #endif
70 #else
71 #define ADDR_DBG_BREAK()
72 #endif
73 ////////////////////////////////////////////////////////////////////////////////////////////////////
74
75 ////////////////////////////////////////////////////////////////////////////////////////////////////
76 // Debug assertions used in AddrLib
77 ////////////////////////////////////////////////////////////////////////////////////////////////////
78 #if defined(_WIN32) && (_MSC_VER >= 1400)
79 #define ADDR_ANALYSIS_ASSUME(expr) __analysis_assume(expr)
80 #else
81 #define ADDR_ANALYSIS_ASSUME(expr) do { (void)(expr); } while (0)
82 #endif
83
84 #define ADDR_ASSERT(__e) assert(__e)
85 #define ADDR_ASSERT_ALWAYS() ADDR_DBG_BREAK()
86 #define ADDR_UNHANDLED_CASE() ADDR_ASSERT(!"Unhandled case")
87 #define ADDR_NOT_IMPLEMENTED() ADDR_ASSERT(!"Not implemented");
88 ////////////////////////////////////////////////////////////////////////////////////////////////////
89
90 ////////////////////////////////////////////////////////////////////////////////////////////////////
91 // Debug print macro from legacy address library
92 ////////////////////////////////////////////////////////////////////////////////////////////////////
93 #if DEBUG
94
95 #define ADDR_PRNT(a) Object::DebugPrint a
96
97 /// @brief Macro for reporting informational messages
98 /// @ingroup util
99 ///
100 /// This macro optionally prints an informational message to stdout.
101 /// The first parameter is a condition -- if it is true, nothing is done.
102 /// The second pararmeter MUST be a parenthesis-enclosed list of arguments,
103 /// starting with a string. This is passed to printf() or an equivalent
104 /// in order to format the informational message. For example,
105 /// ADDR_INFO(0, ("test %d",3) ); prints out "test 3".
106 ///
107 #define ADDR_INFO(cond, a) \
108 { if (!(cond)) { ADDR_PRNT(a); } }
109
110 /// @brief Macro for reporting error warning messages
111 /// @ingroup util
112 ///
113 /// This macro optionally prints an error warning message to stdout,
114 /// followed by the file name and line number where the macro was called.
115 /// The first parameter is a condition -- if it is true, nothing is done.
116 /// The second pararmeter MUST be a parenthesis-enclosed list of arguments,
117 /// starting with a string. This is passed to printf() or an equivalent
118 /// in order to format the informational message. For example,
119 /// ADDR_WARN(0, ("test %d",3) ); prints out "test 3" followed by
120 /// a second line with the file name and line number.
121 ///
122 #define ADDR_WARN(cond, a) \
123 { if (!(cond)) \
124 { ADDR_PRNT(a); \
125 ADDR_PRNT((" WARNING in file %s, line %d\n", __FILE__, __LINE__)); \
126 } }
127
128 /// @brief Macro for reporting fatal error conditions
129 /// @ingroup util
130 ///
131 /// This macro optionally stops execution of the current routine
132 /// after printing an error warning message to stdout,
133 /// followed by the file name and line number where the macro was called.
134 /// The first parameter is a condition -- if it is true, nothing is done.
135 /// The second pararmeter MUST be a parenthesis-enclosed list of arguments,
136 /// starting with a string. This is passed to printf() or an equivalent
137 /// in order to format the informational message. For example,
138 /// ADDR_EXIT(0, ("test %d",3) ); prints out "test 3" followed by
139 /// a second line with the file name and line number, then stops execution.
140 ///
141 #define ADDR_EXIT(cond, a) \
142 { if (!(cond)) \
143 { ADDR_PRNT(a); ADDR_DBG_BREAK();\
144 } }
145
146 #else // DEBUG
147
148 #define ADDRDPF 1 ? (void)0 : (void)
149
150 #define ADDR_PRNT(a)
151
152 #define ADDR_DBG_BREAK()
153
154 #define ADDR_INFO(cond, a)
155
156 #define ADDR_WARN(cond, a)
157
158 #define ADDR_EXIT(cond, a)
159
160 #endif // DEBUG
161 ////////////////////////////////////////////////////////////////////////////////////////////////////
162
163 #define ADDR_C_ASSERT(__e) STATIC_ASSERT(__e)
164
165 namespace Addr
166 {
167
168 namespace V1
169 {
170 ////////////////////////////////////////////////////////////////////////////////////////////////////
171 // Common constants
172 ////////////////////////////////////////////////////////////////////////////////////////////////////
173 static const UINT_32 MicroTileWidth = 8; ///< Micro tile width, for 1D and 2D tiling
174 static const UINT_32 MicroTileHeight = 8; ///< Micro tile height, for 1D and 2D tiling
175 static const UINT_32 ThickTileThickness = 4; ///< Micro tile thickness, for THICK modes
176 static const UINT_32 XThickTileThickness = 8; ///< Extra thick tiling thickness
177 static const UINT_32 PowerSaveTileBytes = 64; ///< Nuber of bytes per tile for power save 64
178 static const UINT_32 CmaskCacheBits = 1024; ///< Number of bits for CMASK cache
179 static const UINT_32 CmaskElemBits = 4; ///< Number of bits for CMASK element
180 static const UINT_32 HtileCacheBits = 16384; ///< Number of bits for HTILE cache 512*32
181
182 static const UINT_32 MicroTilePixels = MicroTileWidth * MicroTileHeight;
183
184 static const INT_32 TileIndexInvalid = TILEINDEX_INVALID;
185 static const INT_32 TileIndexLinearGeneral = TILEINDEX_LINEAR_GENERAL;
186 static const INT_32 TileIndexNoMacroIndex = -3;
187
188 } // V1
189
190 namespace V2
191 {
192 ////////////////////////////////////////////////////////////////////////////////////////////////////
193 // Common constants
194 ////////////////////////////////////////////////////////////////////////////////////////////////////
195 static const UINT_32 MaxSurfaceHeight = 16384;
196
197 } // V2
198
199 ////////////////////////////////////////////////////////////////////////////////////////////////////
200 // Common macros
201 ////////////////////////////////////////////////////////////////////////////////////////////////////
202 #define BITS_PER_BYTE 8
203 #define BITS_TO_BYTES(x) ( ((x) + (BITS_PER_BYTE-1)) / BITS_PER_BYTE )
204 #define BYTES_TO_BITS(x) ( (x) * BITS_PER_BYTE )
205
206 /// Helper macros to select a single bit from an int (undefined later in section)
207 #define _BIT(v,b) (((v) >> (b) ) & 1)
208
209 /**
210 ****************************************************************************************************
211 * @brief Enums to identify AddrLib type
212 ****************************************************************************************************
213 */
214 enum LibClass
215 {
216 BASE_ADDRLIB = 0x0,
217 R600_ADDRLIB = 0x6,
218 R800_ADDRLIB = 0x8,
219 SI_ADDRLIB = 0xa,
220 CI_ADDRLIB = 0xb,
221 AI_ADDRLIB = 0xd,
222 };
223
224 /**
225 ****************************************************************************************************
226 * ChipFamily
227 *
228 * @brief
229 * Neutral enums that specifies chip family.
230 *
231 ****************************************************************************************************
232 */
233 enum ChipFamily
234 {
235 ADDR_CHIP_FAMILY_IVLD, ///< Invalid family
236 ADDR_CHIP_FAMILY_R6XX,
237 ADDR_CHIP_FAMILY_R7XX,
238 ADDR_CHIP_FAMILY_R8XX,
239 ADDR_CHIP_FAMILY_NI,
240 ADDR_CHIP_FAMILY_SI,
241 ADDR_CHIP_FAMILY_CI,
242 ADDR_CHIP_FAMILY_VI,
243 ADDR_CHIP_FAMILY_AI,
244 ADDR_CHIP_FAMILY_NAVI,
245 };
246
247 /**
248 ****************************************************************************************************
249 * ConfigFlags
250 *
251 * @brief
252 * This structure is used to set configuration flags.
253 ****************************************************************************************************
254 */
255 union ConfigFlags
256 {
257 struct
258 {
259 /// These flags are set up internally thru AddrLib::Create() based on ADDR_CREATE_FLAGS
260 UINT_32 optimalBankSwap : 1; ///< New bank tiling for RV770 only
261 UINT_32 noCubeMipSlicesPad : 1; ///< Disables faces padding for cubemap mipmaps
262 UINT_32 fillSizeFields : 1; ///< If clients fill size fields in all input and
263 /// output structure
264 UINT_32 ignoreTileInfo : 1; ///< Don't use tile info structure
265 UINT_32 useTileIndex : 1; ///< Make tileIndex field in input valid
266 UINT_32 useCombinedSwizzle : 1; ///< Use combined swizzle
267 UINT_32 checkLast2DLevel : 1; ///< Check the last 2D mip sub level
268 UINT_32 useHtileSliceAlign : 1; ///< Do htile single slice alignment
269 UINT_32 allowLargeThickTile : 1; ///< Allow 64*thickness*bytesPerPixel > rowSize
270 UINT_32 disableLinearOpt : 1; ///< Disallow tile modes to be optimized to linear
271 UINT_32 use32bppFor422Fmt : 1; ///< View 422 formats as 32 bits per pixel element
272 UINT_32 forceDccAndTcCompat : 1; ///< Force enable DCC and TC compatibility
273 UINT_32 nonPower2MemConfig : 1; ///< Physical video memory size is not power of 2
274 UINT_32 reserved : 19; ///< Reserved bits for future use
275 };
276
277 UINT_32 value;
278 };
279
280 ////////////////////////////////////////////////////////////////////////////////////////////////////
281 // Misc helper functions
282 ////////////////////////////////////////////////////////////////////////////////////////////////////
283
284 /**
285 ****************************************************************************************************
286 * AddrXorReduce
287 *
288 * @brief
289 * Xor the right-side numberOfBits bits of x.
290 ****************************************************************************************************
291 */
292 static inline UINT_32 XorReduce(
293 UINT_32 x,
294 UINT_32 numberOfBits)
295 {
296 UINT_32 i;
297 UINT_32 result = x & 1;
298
299 for (i=1; i<numberOfBits; i++)
300 {
301 result ^= ((x>>i) & 1);
302 }
303
304 return result;
305 }
306
307 /**
308 ****************************************************************************************************
309 * IsPow2
310 *
311 * @brief
312 * Check if the size (UINT_32) is pow 2
313 ****************************************************************************************************
314 */
315 static inline UINT_32 IsPow2(
316 UINT_32 dim) ///< [in] dimension of miplevel
317 {
318 ADDR_ASSERT(dim > 0);
319 return !(dim & (dim - 1));
320 }
321
322 /**
323 ****************************************************************************************************
324 * IsPow2
325 *
326 * @brief
327 * Check if the size (UINT_64) is pow 2
328 ****************************************************************************************************
329 */
330 static inline UINT_64 IsPow2(
331 UINT_64 dim) ///< [in] dimension of miplevel
332 {
333 ADDR_ASSERT(dim > 0);
334 return !(dim & (dim - 1));
335 }
336
337 /**
338 ****************************************************************************************************
339 * ByteAlign
340 *
341 * @brief
342 * Align UINT_32 "x" to "align" alignment, "align" should be power of 2
343 ****************************************************************************************************
344 */
345 static inline UINT_32 PowTwoAlign(
346 UINT_32 x,
347 UINT_32 align)
348 {
349 //
350 // Assert that x is a power of two.
351 //
352 ADDR_ASSERT(IsPow2(align));
353 return (x + (align - 1)) & (~(align - 1));
354 }
355
356 /**
357 ****************************************************************************************************
358 * ByteAlign
359 *
360 * @brief
361 * Align UINT_64 "x" to "align" alignment, "align" should be power of 2
362 ****************************************************************************************************
363 */
364 static inline UINT_64 PowTwoAlign(
365 UINT_64 x,
366 UINT_64 align)
367 {
368 //
369 // Assert that x is a power of two.
370 //
371 ADDR_ASSERT(IsPow2(align));
372 return (x + (align - 1)) & (~(align - 1));
373 }
374
375 /**
376 ****************************************************************************************************
377 * Min
378 *
379 * @brief
380 * Get the min value between two unsigned values
381 ****************************************************************************************************
382 */
383 static inline UINT_32 Min(
384 UINT_32 value1,
385 UINT_32 value2)
386 {
387 return ((value1 < (value2)) ? (value1) : value2);
388 }
389
390 /**
391 ****************************************************************************************************
392 * Min
393 *
394 * @brief
395 * Get the min value between two signed values
396 ****************************************************************************************************
397 */
398 static inline INT_32 Min(
399 INT_32 value1,
400 INT_32 value2)
401 {
402 return ((value1 < (value2)) ? (value1) : value2);
403 }
404
405 /**
406 ****************************************************************************************************
407 * Max
408 *
409 * @brief
410 * Get the max value between two unsigned values
411 ****************************************************************************************************
412 */
413 static inline UINT_32 Max(
414 UINT_32 value1,
415 UINT_32 value2)
416 {
417 return ((value1 > (value2)) ? (value1) : value2);
418 }
419
420 /**
421 ****************************************************************************************************
422 * Max
423 *
424 * @brief
425 * Get the max value between two signed values
426 ****************************************************************************************************
427 */
428 static inline INT_32 Max(
429 INT_32 value1,
430 INT_32 value2)
431 {
432 return ((value1 > (value2)) ? (value1) : value2);
433 }
434
435 /**
436 ****************************************************************************************************
437 * NextPow2
438 *
439 * @brief
440 * Compute the mipmap's next level dim size
441 ****************************************************************************************************
442 */
443 static inline UINT_32 NextPow2(
444 UINT_32 dim) ///< [in] dimension of miplevel
445 {
446 UINT_32 newDim = 1;
447
448 if (dim > 0x7fffffff)
449 {
450 ADDR_ASSERT_ALWAYS();
451 newDim = 0x80000000;
452 }
453 else
454 {
455 while (newDim < dim)
456 {
457 newDim <<= 1;
458 }
459 }
460
461 return newDim;
462 }
463
464 /**
465 ****************************************************************************************************
466 * Log2NonPow2
467 *
468 * @brief
469 * Compute log of base 2 no matter the target is power of 2 or not
470 ****************************************************************************************************
471 */
472 static inline UINT_32 Log2NonPow2(
473 UINT_32 x) ///< [in] the value should calculate log based 2
474 {
475 UINT_32 y;
476
477 y = 0;
478 while (x > 1)
479 {
480 x >>= 1;
481 y++;
482 }
483
484 return y;
485 }
486
487 /**
488 ****************************************************************************************************
489 * Log2
490 *
491 * @brief
492 * Compute log of base 2
493 ****************************************************************************************************
494 */
495 static inline UINT_32 Log2(
496 UINT_32 x) ///< [in] the value should calculate log based 2
497 {
498 // Assert that x is a power of two.
499 ADDR_ASSERT(IsPow2(x));
500
501 return Log2NonPow2(x);
502 }
503
504 /**
505 ****************************************************************************************************
506 * QLog2
507 *
508 * @brief
509 * Compute log of base 2 quickly (<= 16)
510 ****************************************************************************************************
511 */
512 static inline UINT_32 QLog2(
513 UINT_32 x) ///< [in] the value should calculate log based 2
514 {
515 ADDR_ASSERT(x <= 16);
516
517 UINT_32 y = 0;
518
519 switch (x)
520 {
521 case 1:
522 y = 0;
523 break;
524 case 2:
525 y = 1;
526 break;
527 case 4:
528 y = 2;
529 break;
530 case 8:
531 y = 3;
532 break;
533 case 16:
534 y = 4;
535 break;
536 default:
537 ADDR_ASSERT_ALWAYS();
538 }
539
540 return y;
541 }
542
543 /**
544 ****************************************************************************************************
545 * SafeAssign
546 *
547 * @brief
548 * NULL pointer safe assignment
549 ****************************************************************************************************
550 */
551 static inline VOID SafeAssign(
552 UINT_32* pLVal, ///< [in] Pointer to left val
553 UINT_32 rVal) ///< [in] Right value
554 {
555 if (pLVal)
556 {
557 *pLVal = rVal;
558 }
559 }
560
561 /**
562 ****************************************************************************************************
563 * SafeAssign
564 *
565 * @brief
566 * NULL pointer safe assignment for 64bit values
567 ****************************************************************************************************
568 */
569 static inline VOID SafeAssign(
570 UINT_64* pLVal, ///< [in] Pointer to left val
571 UINT_64 rVal) ///< [in] Right value
572 {
573 if (pLVal)
574 {
575 *pLVal = rVal;
576 }
577 }
578
579 /**
580 ****************************************************************************************************
581 * SafeAssign
582 *
583 * @brief
584 * NULL pointer safe assignment for AddrTileMode
585 ****************************************************************************************************
586 */
587 static inline VOID SafeAssign(
588 AddrTileMode* pLVal, ///< [in] Pointer to left val
589 AddrTileMode rVal) ///< [in] Right value
590 {
591 if (pLVal)
592 {
593 *pLVal = rVal;
594 }
595 }
596
597 /**
598 ****************************************************************************************************
599 * RoundHalf
600 *
601 * @brief
602 * return (x + 1) / 2
603 ****************************************************************************************************
604 */
605 static inline UINT_32 RoundHalf(
606 UINT_32 x) ///< [in] input value
607 {
608 ADDR_ASSERT(x != 0);
609
610 #if 1
611 return (x >> 1) + (x & 1);
612 #else
613 return (x + 1) >> 1;
614 #endif
615 }
616
617 /**
618 ****************************************************************************************************
619 * SumGeo
620 *
621 * @brief
622 * Calculate sum of a geometric progression whose ratio is 1/2
623 ****************************************************************************************************
624 */
625 static inline UINT_32 SumGeo(
626 UINT_32 base, ///< [in] First term in the geometric progression
627 UINT_32 num) ///< [in] Number of terms to be added into sum
628 {
629 ADDR_ASSERT(base > 0);
630
631 UINT_32 sum = 0;
632 UINT_32 i = 0;
633 for (; (i < num) && (base > 1); i++)
634 {
635 sum += base;
636 base = RoundHalf(base);
637 }
638 sum += num - i;
639
640 return sum;
641 }
642
643 /**
644 ****************************************************************************************************
645 * GetBit
646 *
647 * @brief
648 * Extract bit N value (0 or 1) of a UINT32 value.
649 ****************************************************************************************************
650 */
651 static inline UINT_32 GetBit(
652 UINT_32 u32, ///< [in] UINT32 value
653 UINT_32 pos) ///< [in] bit position from LSB, valid range is [0..31]
654 {
655 ADDR_ASSERT(pos <= 31);
656
657 return (u32 >> pos) & 0x1;
658 }
659
660 /**
661 ****************************************************************************************************
662 * GetBits
663 *
664 * @brief
665 * Copy 'bitsNum' bits from src start from srcStartPos into destination from dstStartPos
666 * srcStartPos: 0~31 for UINT_32
667 * bitsNum : 1~32 for UINT_32
668 * srcStartPos: 0~31 for UINT_32
669 * src start position
670 * |
671 * src : b[31] b[30] b[29] ... ... ... ... ... ... ... ... b[end]..b[beg] ... b[1] b[0]
672 * || Bits num || copy length || Bits num ||
673 * dst : b[31] b[30] b[29] ... b[end]..b[beg] ... ... ... ... ... ... ... ... b[1] b[0]
674 * |
675 * dst start position
676 ****************************************************************************************************
677 */
678 static inline UINT_32 GetBits(
679 UINT_32 src,
680 UINT_32 srcStartPos,
681 UINT_32 bitsNum,
682 UINT_32 dstStartPos)
683 {
684 ADDR_ASSERT((srcStartPos < 32) && (dstStartPos < 32) && (bitsNum > 0));
685 ADDR_ASSERT((bitsNum + dstStartPos <= 32) && (bitsNum + srcStartPos <= 32));
686
687 return ((src >> srcStartPos) << (32 - bitsNum)) >> (32 - bitsNum - dstStartPos);
688 }
689
690 /**
691 ****************************************************************************************************
692 * MortonGen2d
693 *
694 * @brief
695 * Generate 2D Morton interleave code with num lowest bits in each channel
696 ****************************************************************************************************
697 */
698 static inline UINT_32 MortonGen2d(
699 UINT_32 x, ///< [in] First channel
700 UINT_32 y, ///< [in] Second channel
701 UINT_32 num) ///< [in] Number of bits extracted from each channel
702 {
703 UINT_32 mort = 0;
704
705 for (UINT_32 i = 0; i < num; i++)
706 {
707 mort |= (GetBit(y, i) << (2 * i));
708 mort |= (GetBit(x, i) << (2 * i + 1));
709 }
710
711 return mort;
712 }
713
714 /**
715 ****************************************************************************************************
716 * MortonGen3d
717 *
718 * @brief
719 * Generate 3D Morton interleave code with num lowest bits in each channel
720 ****************************************************************************************************
721 */
722 static inline UINT_32 MortonGen3d(
723 UINT_32 x, ///< [in] First channel
724 UINT_32 y, ///< [in] Second channel
725 UINT_32 z, ///< [in] Third channel
726 UINT_32 num) ///< [in] Number of bits extracted from each channel
727 {
728 UINT_32 mort = 0;
729
730 for (UINT_32 i = 0; i < num; i++)
731 {
732 mort |= (GetBit(z, i) << (3 * i));
733 mort |= (GetBit(y, i) << (3 * i + 1));
734 mort |= (GetBit(x, i) << (3 * i + 2));
735 }
736
737 return mort;
738 }
739
740 /**
741 ****************************************************************************************************
742 * ReverseBitVector
743 *
744 * @brief
745 * Return reversed lowest num bits of v: v[0]v[1]...v[num-2]v[num-1]
746 ****************************************************************************************************
747 */
748 static inline UINT_32 ReverseBitVector(
749 UINT_32 v, ///< [in] Reverse operation base value
750 UINT_32 num) ///< [in] Number of bits used in reverse operation
751 {
752 UINT_32 reverse = 0;
753
754 for (UINT_32 i = 0; i < num; i++)
755 {
756 reverse |= (GetBit(v, num - 1 - i) << i);
757 }
758
759 return reverse;
760 }
761
762 /**
763 ****************************************************************************************************
764 * FoldXor2d
765 *
766 * @brief
767 * Xor bit vector v[num-1]v[num-2]...v[1]v[0] with v[num]v[num+1]...v[2*num-2]v[2*num-1]
768 ****************************************************************************************************
769 */
770 static inline UINT_32 FoldXor2d(
771 UINT_32 v, ///< [in] Xor operation base value
772 UINT_32 num) ///< [in] Number of bits used in fold xor operation
773 {
774 return (v & ((1 << num) - 1)) ^ ReverseBitVector(v >> num, num);
775 }
776
777 /**
778 ****************************************************************************************************
779 * DeMort
780 *
781 * @brief
782 * Return v[0] | v[2] | v[4] | v[6]... | v[2*num - 2]
783 ****************************************************************************************************
784 */
785 static inline UINT_32 DeMort(
786 UINT_32 v, ///< [in] DeMort operation base value
787 UINT_32 num) ///< [in] Number of bits used in fold DeMort operation
788 {
789 UINT_32 d = 0;
790
791 for (UINT_32 i = 0; i < num; i++)
792 {
793 d |= ((v & (1 << (i << 1))) >> i);
794 }
795
796 return d;
797 }
798
799 /**
800 ****************************************************************************************************
801 * FoldXor3d
802 *
803 * @brief
804 * v[0]...v[num-1] ^ v[3*num-1]v[3*num-3]...v[num+2]v[num] ^ v[3*num-2]...v[num+1]v[num-1]
805 ****************************************************************************************************
806 */
807 static inline UINT_32 FoldXor3d(
808 UINT_32 v, ///< [in] Xor operation base value
809 UINT_32 num) ///< [in] Number of bits used in fold xor operation
810 {
811 UINT_32 t = v & ((1 << num) - 1);
812 t ^= ReverseBitVector(DeMort(v >> num, num), num);
813 t ^= ReverseBitVector(DeMort(v >> (num + 1), num), num);
814
815 return t;
816 }
817
818 /**
819 ****************************************************************************************************
820 * InitChannel
821 *
822 * @brief
823 * Set channel initialization value via a return value
824 ****************************************************************************************************
825 */
826 static inline ADDR_CHANNEL_SETTING InitChannel(
827 UINT_32 valid, ///< [in] valid setting
828 UINT_32 channel, ///< [in] channel setting
829 UINT_32 index) ///< [in] index setting
830 {
831 ADDR_CHANNEL_SETTING t;
832 t.valid = valid;
833 t.channel = channel;
834 t.index = index;
835
836 return t;
837 }
838
839 /**
840 ****************************************************************************************************
841 * InitChannel
842 *
843 * @brief
844 * Set channel initialization value via channel pointer
845 ****************************************************************************************************
846 */
847 static inline VOID InitChannel(
848 UINT_32 valid, ///< [in] valid setting
849 UINT_32 channel, ///< [in] channel setting
850 UINT_32 index, ///< [in] index setting
851 ADDR_CHANNEL_SETTING *pChanSet) ///< [out] channel setting to be initialized
852 {
853 pChanSet->valid = valid;
854 pChanSet->channel = channel;
855 pChanSet->index = index;
856 }
857
858 /**
859 ****************************************************************************************************
860 * InitChannel
861 *
862 * @brief
863 * Set channel initialization value via another channel
864 ****************************************************************************************************
865 */
866 static inline VOID InitChannel(
867 ADDR_CHANNEL_SETTING *pChanDst, ///< [in] channel setting to be copied from
868 ADDR_CHANNEL_SETTING *pChanSrc) ///< [out] channel setting to be initialized
869 {
870 pChanDst->valid = pChanSrc->valid;
871 pChanDst->channel = pChanSrc->channel;
872 pChanDst->index = pChanSrc->index;
873 }
874
875 /**
876 ****************************************************************************************************
877 * GetMaxValidChannelIndex
878 *
879 * @brief
880 * Get max valid index for a specific channel
881 ****************************************************************************************************
882 */
883 static inline UINT_32 GetMaxValidChannelIndex(
884 const ADDR_CHANNEL_SETTING *pChanSet, ///< [in] channel setting to be initialized
885 UINT_32 searchCount,///< [in] number of channel setting to be searched
886 UINT_32 channel) ///< [in] channel to be searched
887 {
888 UINT_32 index = 0;
889
890 for (UINT_32 i = 0; i < searchCount; i++)
891 {
892 if (pChanSet[i].valid && (pChanSet[i].channel == channel))
893 {
894 index = Max(index, static_cast<UINT_32>(pChanSet[i].index));
895 }
896 }
897
898 return index;
899 }
900
901 /**
902 ****************************************************************************************************
903 * GetCoordActiveMask
904 *
905 * @brief
906 * Get bit mask which indicates which positions in the equation match the target coord
907 ****************************************************************************************************
908 */
909 static inline UINT_32 GetCoordActiveMask(
910 const ADDR_CHANNEL_SETTING *pChanSet, ///< [in] channel setting to be initialized
911 UINT_32 searchCount,///< [in] number of channel setting to be searched
912 UINT_32 channel, ///< [in] channel to be searched
913 UINT_32 index) ///< [in] index to be searched
914 {
915 UINT_32 mask = 0;
916
917 for (UINT_32 i = 0; i < searchCount; i++)
918 {
919 if ((pChanSet[i].valid == TRUE) &&
920 (pChanSet[i].channel == channel) &&
921 (pChanSet[i].index == index))
922 {
923 mask |= (1 << i);
924 }
925 }
926
927 return mask;
928 }
929
930 /**
931 ****************************************************************************************************
932 * ShiftCeil
933 *
934 * @brief
935 * Apply righ-shift with ceiling
936 ****************************************************************************************************
937 */
938 static inline UINT_32 ShiftCeil(
939 UINT_32 a, ///< [in] value to be right-shifted
940 UINT_32 b) ///< [in] number of bits to shift
941 {
942 return (a >> b) + (((a & ((1 << b) - 1)) != 0) ? 1 : 0);
943 }
944
945 } // Addr
946
947 #endif // __ADDR_COMMON_H__
948