35c35
< * Chip-Select Bank Address Mode Encodings - BKDG 3.29 3.5.6
---
> * =========== Chip-Select Bank Address Mode Encodings =======================
37,38d36
< static const struct bankaddr_mode bankaddr_modes_pre_d[];
< static const struct bankaddr_mode bankaddr_modes_d_e[];
40,41c38,45
< static const struct bam_desc {
< int rev;
---
> /* Individual table declarations */
> static const struct rct_bnkaddrmode bnkaddr_tbls_pre_d[];
> static const struct rct_bnkaddrmode bnkaddr_tbls_d_e[];
> static const struct rct_bnkaddrmode bnkaddr_tbls_f[];
>
> /* Managing bank address mode tables */
> static const struct _bnkaddrmode_tbldesc {
> uint_t revmask;
43,46c47,51
< const struct bankaddr_mode *modetbl;
< } bankaddr_modes[] = {
< { MC_REV_PRE_D, 7, bankaddr_modes_pre_d },
< { MC_REV_D_E, 11, bankaddr_modes_d_e },
---
> const struct rct_bnkaddrmode *modetbl;
> } bnkaddr_tbls[] = {
> { MC_REVS_BC, 7, bnkaddr_tbls_pre_d },
> { MC_REVS_DE, 11, bnkaddr_tbls_d_e },
> { MC_REVS_FG, 12, bnkaddr_tbls_f },
50c55
< * DRAM Address Mappings for bank/row/column - BKDG 3.29 3.5.6.1
---
> * =========== DRAM Address Mappings for bank/row/column =====================
52,55d56
< static const struct csrcb_map_tbl dram_addrmap_pre_d_128;
< static const struct csrcb_map_tbl dram_addrmap_pre_d_64;
< static const struct csrcb_map_tbl dram_addrmap_d_e_64;
< static const struct csrcb_map_tbl dram_addrmap_d_e_128;
57c58,74
< static const struct rcbmap_desc {
---
>
> /* Individual table declarations */
> struct _rcbmap_tbl {
> uint_t mt_revmask; /* revision to which this applies */
> int mt_width; /* MC mode (64 or 128) */
> const struct rct_rcbmap mt_csmap[MC_RC_CSMODES];
> };
>
> static const struct _rcbmap_tbl dram_addrmap_pre_d_64;
> static const struct _rcbmap_tbl dram_addrmap_pre_d_128;
> static const struct _rcbmap_tbl dram_addrmap_d_e_64;
> static const struct _rcbmap_tbl dram_addrmap_d_e_128;
> static const struct _rcbmap_tbl dram_addrmap_f_64;
> static const struct _rcbmap_tbl dram_addrmap_f_128;
>
> /* Managing row/column/bank tables */
> static const struct _rcbmap_tbldesc {
59,60c76,77
< const struct csrcb_map_tbl *rcbmap;
< } rcbmaps[] = {
---
> const struct _rcbmap_tbl *rcbmap;
> } rcbmap_tbls[] = {
64a82,83
> { 12, &dram_addrmap_f_64 },
> { 12, &dram_addrmap_f_128 },
68,69c87
< * Lookup the Chip-Select Bank Address Mode Encoding table for a given
< * chip revision and chip-select mode.
---
> * =========== Bank swizzling information ====================================
71,75d88
< const struct bankaddr_mode *
< rct_bankaddr_mode(uint_t mcrev, uint_t csmode)
< {
< int i;
< const struct bam_desc *bdp = bankaddr_modes;
77,80c90,95
< for (i = 0; i < sizeof (bankaddr_modes) / sizeof (struct bam_desc);
< i++, bdp++) {
< if (bdp->rev == mcrev && csmode < bdp->nmodes)
< return (&bdp->modetbl[csmode]);
---
> /* Individual table declarations */
> struct _bnkswzl_tbl {
> uint_t swzt_revmask; /* revision to which this applies */
> int swzt_width; /* MC mode (64 or 128) */
> const struct rct_bnkswzlinfo swzt_bits;
> };
82c97,100
< }
---
> static const struct _bnkswzl_tbl bnswzl_info_e_64;
> static const struct _bnkswzl_tbl bnswzl_info_e_128;
> static const struct _bnkswzl_tbl bnswzl_info_f_64;
> static const struct _bnkswzl_tbl bnswzl_info_f_128;
84,85c102,108
< return (NULL);
< }
---
> /* Managing bank swizzle tables */
> static const struct _bnkswzl_tbl *bnkswzl_tbls[] = {
> &bnswzl_info_e_64,
> &bnswzl_info_e_128,
> &bnswzl_info_f_64,
> &bnswzl_info_f_128,
> };
88,89c111,113
< * Lookup the DRAM Address Mapping table for a given chip revision, access
< * width, bank-swizzle and chip-select mode.
---
> * ======================================================================
> * | Tables reflecting those in the BKDG |
> * ======================================================================
91,95d114
< const struct csrcb_map *
< rct_rcbmap(uint_t mcrev, int width, uint_t csmode)
< {
< const struct csrcb_map_tbl *rcbm;
< int i;
97,106d115
< for (i = 0; i < sizeof (rcbmaps) / sizeof (struct rcbmap_desc); i++) {
< rcbm = rcbmaps[i].rcbmap;
< if (rcbm->mt_rev == mcrev && rcbm->mt_width == width &&
< csmode < rcbmaps[i].nmodes)
< return (&rcbm->mt_csmap[csmode]);
< }
<
< return (NULL);
< }
<
108c117
< * DRAM Address Mapping in Interleaving Mode - BKDG 3.29 section 3.5.6.2.
---
> * DRAM Address Mapping in Interleaving Mode
116,118c125,126
< * as follows (example is the first line of table 7 which is for a 32MB
< * chip-select requiring 25 bits to address all of it) for the non-interleaved
< * case:
---
> * as follows, using an example for CS Mode 0000 revision CG and earlier 64-bit
> * mode; the cs size is 32MB, requiring 25 bits to address all of it.
134c142
< * Tables 13-16 of BKDG 3.5.6.2 really just describe the above. Working
---
> * The BKDG interleave tables really just describe the above. Working
138c146
< * but we have that information from the rcbmaps since the first row bit
---
> * but we have that information from the rcbmap_tbls since the first row bit
140,142d147
< *
< * Short version: we will do tables 13 to 16 programatically rather than
< * replicating those tables.
146,247d150
< * Yet another highbit function. This really needs to go to common source.
< * Returns range 0 to 64 inclusive;
< */
< static int
< topbit(uint64_t i)
< {
< int h = 1;
<
< if (i == 0)
< return (0);
<
< if (i & 0xffffffff00000000ULL) {
< h += 32;
< i >>= 32;
< }
<
< if (i & 0xffff0000) {
< h += 16;
< i >>= 16;
< }
<
< if (i & 0xff00) {
< h += 8;
< i >>= 8;
< }
<
< if (i & 0xf0) {
< h += 4;
< i >>= 4;
< }
<
< if (i & 0xc) {
< h += 2;
< i >>= 2;
< }
<
< if (i & 0x2)
< h += 1;
<
< return (h);
< }
<
< void
< rct_csintlv_bits(uint_t mcrev, int width, uint_t csmode, int factor,
< struct csintlv_desc *csid)
< {
< int i, lstbnkbit;
< size_t csz;
< const struct bankaddr_mode *bam;
< const struct csrcb_map *rcm;
<
< /*
< * 8-way cs interleave for some large cs sizes in 128-bit mode is
< * not implemented.
< */
< if (factor == 8 && width == 128 &&
< ((mcrev == MC_REV_PRE_D && csmode == 0x6) ||
< (mcrev == MC_REV_D_E && (csmode == 0x9 || csmode == 0xa)))) {
< csid->csi_factor = 0;
< return;
< }
<
< if ((bam = rct_bankaddr_mode(mcrev, csmode)) == NULL ||
< (rcm = rct_rcbmap(mcrev, width, csmode)) == NULL) {
< csid->csi_factor = 0;
< return;
< }
<
< csz = MC_CS_SIZE(bam, width);
<
< switch (factor) {
< case 2:
< csid->csi_nbits = 1;
< break;
< case 4:
< csid->csi_nbits = 2;
< break;
< case 8:
< csid->csi_nbits = 3;
< break;
< default:
< csid->csi_factor = 0;
< return;
< }
<
< csid->csi_hibit = topbit(csz) - 1;
<
< lstbnkbit = 0;
< for (i = 0; i < MC_RC_BANKBITS; i++) {
< /* first bank arg for a bit is "real" bank bit */
< if (rcm->csrcb_bankargs[i][0] > lstbnkbit)
< lstbnkbit = rcm->csrcb_bankargs[i][0];
< }
<
< /* first row bit is immediately after last bank bit */
< csid->csi_lobit = lstbnkbit + 1;
<
< csid->csi_factor = factor;
< }
<
<
< /*
250,252c153,154
< * These are the tables of BKDG 3.29 section 3.5.6. They are indexed
< * by chip-select mode. Where the numbers of rows and columns is
< * ambiguous (as it is for a number of rev CG and earlier cases)
---
> * These are indexed by chip-select mode. Where the numbers of rows and
> * columns is ambiguous (as it is for a number of rev CG and earlier cases)
260c162
< static const struct bankaddr_mode bankaddr_modes_pre_d[] = {
---
> static const struct rct_bnkaddrmode bnkaddr_tbls_pre_d[] = {
268c170
< 128, 13, 10, 1
---
> 128, 13, 10, 1 /* AMBIG */
271c173
< 256, 13, 11, 1
---
> 256, 13, 11, 1 /* AMBIG */
274c176
< 512, 14, 11, 1
---
> 512, 14, 11, 1 /* AMBIG */
277c179
< 1024, 14, 12, 1
---
> 1024, 14, 12, 1 /* AMBIG */
287c189
< static const struct bankaddr_mode bankaddr_modes_d_e[] = {
---
> static const struct rct_bnkaddrmode bnkaddr_tbls_d_e[] = {
323a226,268
> * Chip Select Bank Address Mode Encoding for rev F
> */
> static const struct rct_bnkaddrmode bnkaddr_tbls_f[] = {
> { /* 0000 */
> 128, 13, 9
> },
> { /* 0001 */
> 256, 13, 10
> },
> { /* 0010 */
> 512, 14, 10
> },
> { /* 0011 */
> 512, 13, 11
> },
> { /* 0100 */
> 512, 13, 10
> },
> { /* 0101 */
> 1024, 14, 10
> },
> { /* 0110 */
> 1024, 14, 11
> },
> { /* 0111 */
> 2048, 15, 10
> },
> { /* 1000 */
> 2048, 14, 11
> },
> { /* 1001 */
> 4096, 15, 11
> },
> { /* 1010 */
> 4096, 16, 10
> },
> { /* 1011 */
> 8192, 16, 11
> }
>
> };
>
> /*
363,364c308,309
< static const struct csrcb_map_tbl dram_addrmap_pre_d_64 = {
< MC_REV_PRE_D,
---
> static const struct _rcbmap_tbl dram_addrmap_pre_d_64 = {
> MC_REVS_BC,
368c313
< { { 11 }, { 12 } },
---
> 2, { 11, 12 },
373c318
< { { 13 }, { 12 } },
---
> 2, { 13, 12 },
378c323
< { { 13 }, { 12 } },
---
> 2, { 13, 12 },
383c328
< { { 13 }, { 14 } },
---
> 2, { 13, 14 },
388c333
< { { 13 }, { 14 } },
---
> 2, { 13, 14 },
393c338
< { { 15 }, { 14 } },
---
> 2, { 15, 14 },
398c343
< { { 15 }, { 14 } },
---
> 2, { 15, 14 },
413,414c358,359
< static const struct csrcb_map_tbl dram_addrmap_pre_d_128 = {
< MC_REV_PRE_D,
---
> static const struct _rcbmap_tbl dram_addrmap_pre_d_128 = {
> MC_REVS_BC,
418c363
< { { 12 }, { 13 } },
---
> 2, { 12, 13 },
423c368
< { { 14 }, { 13 } },
---
> 2, { 14, 13 },
428c373
< { { 14 }, { 13 } },
---
> 2, { 14, 13 },
433c378
< { { 14 }, { 15 } },
---
> 2, { 14, 15 },
438c383
< { { 14 }, { 15 } },
---
> 2, { 14, 15 },
443c388
< { { 16 }, { 15 } },
---
> 2, { 16, 15 },
448c393
< { { 16 }, { 15 } },
---
> 2, { 16, 15 },
462,463c407,408
< static const struct csrcb_map_tbl dram_addrmap_d_e_64 = {
< MC_REV_D_E,
---
> static const struct _rcbmap_tbl dram_addrmap_d_e_64 = {
> MC_REVS_DE,
467c412
< { { 11, 17, 20 }, { 12, 18, 21 } },
---
> 2, { 11, 12 },
472c417
< { { 12, 17, 20 }, { 13, 18, 21 } },
---
> 2, { 12, 13 },
477c422
< { { 12, 17, 20 }, { 13, 18, 21 } },
---
> 2, { 12, 13 },
482c427
< { { 13, 17, 20 }, { 14, 18, 21 } },
---
> 2, { 13, 14 },
487c432
< { { 13, 17, 20 }, { 14, 18, 21 } },
---
> 2, { 13, 14 },
492c437
< { { 13, 17, 20 }, { 14, 18, 21 } },
---
> 2, { 13, 14 },
497c442
< { { 14, 17, 20 }, { 15, 18, 21 } },
---
> 2, { 14, 15 },
502c447
< { { 14, 17, 20 }, { 15, 18, 21 } },
---
> 2, { 14, 15 },
507c452
< { { 14, 17, 20 }, { 15, 18, 21 } },
---
> 2, { 14, 15 },
512c457
< { { 15, 17, 20 }, { 16, 18, 21 } },
---
> 2, { 15, 16 },
517c462
< { { 15, 17, 20 }, { 16, 18, 21 } },
---
> 2, { 15, 16 },
531,532c476,477
< static const struct csrcb_map_tbl dram_addrmap_d_e_128 = {
< MC_REV_D_E,
---
> static const struct _rcbmap_tbl dram_addrmap_d_e_128 = {
> MC_REVS_DE,
536c481
< { { 12, 18, 21 }, { 13, 19, 22 } },
---
> 2, { 12, 13 },
541c486
< { { 13, 18, 21 }, { 14, 19, 22 } },
---
> 2, { 13, 14 },
546c491
< { { 13, 18, 21 }, { 14, 19, 22 } },
---
> 2, { 13, 14 },
551c496
< { { 14, 18, 21 }, { 15, 19, 22 } },
---
> 2, { 14, 15 },
556c501
< { { 14, 18, 21 }, { 15, 19, 22 } },
---
> 2, { 14, 15 },
561c506
< { { 14, 18, 21 }, { 15, 19, 22 } },
---
> 2, { 14, 15 },
566c511
< { { 15, 18, 21 }, { 16, 19, 22 } },
---
> 2, { 15, 16 },
571c516
< { { 15, 18, 21 }, { 16, 19, 22 } },
---
> 2, { 15, 16 },
576c521
< { { 15, 18, 21 }, { 16, 19, 22 } },
---
> 2, { 15, 16 },
581c526
< { { 16, 18, 21 }, { 17, 19, 22 } },
---
> 2, { 16, 17 },
586c531
< { { 16, 18, 21 }, { 17, 19, 22 } },
---
> 2, { 16, 17 },
594a540,918
>
> /*
> * Row/Column/Bank address mappings for revs F/G in 64-bit mode, no interleave.
> */
> static const struct _rcbmap_tbl dram_addrmap_f_64 = {
> MC_REVS_FG,
> 64,
> {
> { /* 0000 */
> 2, { 12, 13 },
> { 18, 19, 20, 21, 22, 23, 24, 25, 26, 14, 15, 16, 17 },
> { 3, 4, 5, 6, 7, 8, 9, 10, 11 },
> },
> { /* 0001 */
> 2, { 13, 14 },
> { 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 15, 16, 17 },
> { 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 },
> },
> { /* 0010 */
> 2, { 13, 14 },
> { 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 15, 16, 17 },
> { 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 },
> },
> { /* 0011 */
> 2, { 14, 15 },
> { 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 16, 17 },
> { 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, MC_PC_ALL, 13 },
> },
> { /* 0100 */
> 3, { 13, 14, 15 },
> { 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 16, 17 },
> { 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, MC_PC_ALL, 13 },
> },
> { /* 0101 */
> 3, { 13, 14, 15 },
> { 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 16, 17 },
> { 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }
> },
> { /* 0110 */
> 2, { 14, 15 },
> { 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 16, 17 },
> { 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, MC_PC_ALL, 13 },
> },
> { /* 0111 */
> 3, { 13, 14, 15 },
> { 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 16, 17 },
> { 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }
> },
> { /* 1000 */
> 3, { 14, 15, 16 },
> { 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 17 },
> { 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, MC_PC_ALL, 13 },
> },
> { /* 1001 */
> 3, { 14, 15, 16 },
> { 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 17 },
> { 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, MC_PC_ALL, 13 },
> },
> { /* 1010 */
> 3, { 13, 14, 15 },
> { 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
> 16, 17 },
> { 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }
> },
> { /* 1011 */
> 3, { 14, 15, 16 },
> { 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
> 17 },
> { 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, MC_PC_ALL, 13 },
> },
> /*
> * remainder unused
> */
> }
> };
>
> /*
> * Row/Column/Bank address mappings for revs F/G in 128-bit mode, no interleave.
> */
> static const struct _rcbmap_tbl dram_addrmap_f_128 = {
> MC_REVS_FG,
> 128,
> {
> { /* 0000 */
> 2, { 13, 14 },
> { 19, 20, 21, 22, 23, 24, 25, 26, 27, 15, 16, 17, 18 },
> { 4, 5, 6, 7, 8, 9, 10, 11, 12 },
> },
> { /* 0001 */
> 2, { 14, 15 },
> { 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 16, 17, 18 },
> { 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 },
> },
> { /* 0010 */
> 2, { 14, 15 },
> { 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 16, 17, 18 },
> { 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 },
> },
> { /* 0011 */
> 2, { 15, 16 },
> { 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 17, 18 },
> { 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, MC_PC_ALL, 14 },
> },
> { /* 0100 */
> 3, { 14, 15, 16 },
> { 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 17, 18 },
> { 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 },
> },
> { /* 0101 */
> 3, { 14, 15, 16 },
> { 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 17, 18 },
> { 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 },
> },
> { /* 0110 */
> 2, { 15, 16 },
> { 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 17, 18 },
> { 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, MC_PC_ALL, 14 },
> },
> { /* 0111 */
> 3, { 14, 15, 16 },
> { 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
> 17, 18 },
> { 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 },
> },
> { /* 1000 */
> 3, { 15, 16, 17 },
> { 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
> 18 },
> { 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, MC_PC_ALL, 14 },
> },
> { /* 1001 */
> 3, { 15, 16, 17 },
> { 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
> 18 },
> { 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, MC_PC_ALL, 14 },
> },
> { /* 1010 */
> 3, { 14, 15, 16 },
> { 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
> 17, 18 },
> { 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 },
> },
> { /* 1011 */
> 3, { 15, 16, 17 },
> { 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
> 18 },
> { 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, MC_PC_ALL, 14 },
> },
> /*
> * remainder unused
> */
> }
> };
>
> /*
> * Bank swizzling is an option in revisions E and later. Each internal-bank-
> * select address bit is xor'd with two row address bits. Which row
> * address bits to use is not dependent on bank address mode but on
> * revision and dram controller width alone.
> *
> * While rev E only supports 2 bank address bits, rev F supports 3 but not
> * all chip-select bank address modes use all 3. These tables will list
> * the row bits to use in swizzling for the maximum number of supported
> * bank address bits - the consumer musr determine how many should be
> * applied (listed in the above row/col/bank tables).
> */
>
> static const struct _bnkswzl_tbl bnswzl_info_e_64 = {
> MC_REV_E,
> 64,
> {
> {
> { 17, 20 }, /* rows bits to swizzle with BA0 */
> { 18, 21 }, /* rows bits to swizzle with BA1 */
> /* only 2 bankaddr bits on rev E */
> }
> }
> };
>
> static const struct _bnkswzl_tbl bnswzl_info_e_128 = {
> MC_REV_E,
> 128,
> {
> {
> { 18, 21 }, /* rows bits to swizzle with BA0 */
> { 19, 22 }, /* rows bits to swizzle with BA1 */
> /* only 2 bankaddr bits on rev E */
> }
> }
> };
>
> static const struct _bnkswzl_tbl bnswzl_info_f_64 = {
> MC_REVS_FG,
> 64,
> {
> {
> { 17, 22 }, /* rows bits to swizzle with BA0 */
> { 18, 23 }, /* rows bits to swizzle with BA1 */
> { 19, 24 }, /* rows bits to swizzle with BA2 */
> }
> }
> };
>
> static const struct _bnkswzl_tbl bnswzl_info_f_128 = {
> MC_REVS_FG,
> 128,
> {
> {
> { 18, 23 }, /* rows bits to swizzle with BA0 */
> { 19, 24 }, /* rows bits to swizzle with BA1 */
> { 20, 25 }, /* rows bits to swizzle with BA2 */
> }
> }
> };
>
> /*
> * Yet another highbit function. This really needs to go to common source.
> * Returns range 0 to 64 inclusive;
> */
> static int
> topbit(uint64_t i)
> {
> int h = 1;
>
> if (i == 0)
> return (0);
>
> if (i & 0xffffffff00000000ULL) {
> h += 32;
> i >>= 32;
> }
>
> if (i & 0xffff0000) {
> h += 16;
> i >>= 16;
> }
>
> if (i & 0xff00) {
> h += 8;
> i >>= 8;
> }
>
> if (i & 0xf0) {
> h += 4;
> i >>= 4;
> }
>
> if (i & 0xc) {
> h += 2;
> i >>= 2;
> }
>
> if (i & 0x2)
> h += 1;
>
> return (h);
> }
>
> /*
> * Lookup the Chip-Select Bank Address Mode Encoding table for a given
> * chip revision and chip-select mode.
> */
> const struct rct_bnkaddrmode *
> rct_bnkaddrmode(uint_t mcrev, uint_t csmode)
> {
> int i;
> const struct _bnkaddrmode_tbldesc *bdp = bnkaddr_tbls;
>
> for (i = 0; i < sizeof (bnkaddr_tbls) /
> sizeof (struct _bnkaddrmode_tbldesc);
> i++, bdp++) {
> if (MC_REV_MATCH(mcrev, bdp->revmask) && csmode < bdp->nmodes)
> return (&bdp->modetbl[csmode]);
>
> }
>
> return (NULL);
> }
>
> /*
> * Lookup the DRAM Address Mapping table for a given chip revision, access
> * width, bank-swizzle and chip-select mode.
> */
> const struct rct_rcbmap *
> rct_rcbmap(uint_t mcrev, int width, uint_t csmode)
> {
> const struct _rcbmap_tbl *rcbm;
> int i;
>
> for (i = 0; i < sizeof (rcbmap_tbls) /
> sizeof (struct _rcbmap_tbldesc); i++) {
> rcbm = rcbmap_tbls[i].rcbmap;
> if (MC_REV_MATCH(mcrev, rcbm->mt_revmask) &&
> rcbm->mt_width == width && csmode < rcbmap_tbls[i].nmodes)
> return (&rcbm->mt_csmap[csmode]);
> }
>
> return (NULL);
> }
>
> /*
> * Lookup the bank swizzling information for a given chip revision and
> * access width.
> */
> const struct rct_bnkswzlinfo *
> rct_bnkswzlinfo(uint_t mcrev, int width)
> {
> int i;
> const struct _bnkswzl_tbl *swztp;
>
> for (i = 0; i < sizeof (bnkswzl_tbls) /
> sizeof (struct rcb_bnkswzl_tbl *); i++) {
> swztp = bnkswzl_tbls[i];
> if (MC_REV_MATCH(mcrev, swztp->swzt_revmask) &&
> swztp->swzt_width == width)
> return (&swztp->swzt_bits);
> }
>
> return (NULL);
> }
>
> void
> rct_csintlv_bits(uint_t mcrev, int width, uint_t csmode, int factor,
> struct rct_csintlv *csid)
> {
> int i, lstbnkbit;
> size_t csz;
> const struct rct_bnkaddrmode *bam;
> const struct rct_rcbmap *rcm;
>
> /*
> * 8-way cs interleave for some large cs sizes in 128-bit mode is
> * not implemented prior to rev F.
> */
> if (factor == 8 && width == 128 &&
> ((MC_REV_MATCH(mcrev, MC_REVS_BC) && csmode == 0x6) ||
> (MC_REV_MATCH(mcrev, MC_REVS_DE) &&
> (csmode == 0x9 || csmode == 0xa)))) {
> csid->csi_factor = 0;
> return;
> }
>
> if ((bam = rct_bnkaddrmode(mcrev, csmode)) == NULL ||
> (rcm = rct_rcbmap(mcrev, width, csmode)) == NULL) {
> csid->csi_factor = 0;
> return;
> }
>
> csz = MC_CS_SIZE(bam, width);
>
> switch (factor) {
> case 2:
> csid->csi_nbits = 1;
> break;
> case 4:
> csid->csi_nbits = 2;
> break;
> case 8:
> csid->csi_nbits = 3;
> break;
> default:
> csid->csi_factor = 0;
> return;
> }
>
> csid->csi_hibit = topbit(csz) - 1;
>
> /*
> * The first row bit is immediately after the last bank bit.
> */
> lstbnkbit = 0;
> for (i = 0; i < rcm->rcb_nbankbits; i++)
> if (rcm->rcb_bankbit[i] > lstbnkbit)
> lstbnkbit = rcm->rcb_bankbit[i];
>
> csid->csi_lobit = lstbnkbit + 1;
>
> csid->csi_factor = factor;
> }