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