openbcm

Git mirror of https://github.com/Broadcom-Network-Switching-Software/OpenBCM
git clone git://git.finwo.net/mirror/broadcom/openbcm
Log | Files | Refs | README

blackhawk_sim.c (22632B)


      1 /*
      2  * 
      3  * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file.
      4  * 
      5  * Copyright 2007-2019 Broadcom Inc. All rights reserved.
      6  *
      7  *
      8  * This software simulator can emulate basic register access for the
      9  * TSC/Eagle SerDes PHY.
     10  *
     11  * The simulator suppor both IEEE clause 22/45 access and Broadcom
     12  * proprietary SBUS access.
     13  *
     14  * Clause 22 address format:
     15  *   Bits [4:0]   : Clause 22 register address
     16  *   Bits [31:5]  : Unused
     17  *
     18  * Clause 45 address format:
     19  *   Bits [15:0]  : Clause 45 register address
     20  *   Bits [20:16] : Clause 45 DEVAD
     21  *   Bits [23:21] : Clause 45 indicator (001b)
     22  *   Bits [31:24] : Unused
     23  *
     24  * SBUS address format:
     25  *   Bits [15:0]  : Clause 45 register address
     26  *   Bits [18:16] : Lane control
     27  *   Bits [26:19] : Lane multicast (old format)
     28  *   Bits [31:27] : Clause 45 DEVAD
     29  *
     30  * The upper 16 bits if the SBUS address format is identical to the
     31  * Broadcom Address Extension Register (AER) format.
     32  *
     33  * The clause 45 indicator serves two purposes which is to ensure that
     34  * the upper 16 bits are never zero for a clause 45 address, but it
     35  * also makes it possible for the PHY bus driver to distinguish
     36  * between a clause 45 DEVAD and the old AER multicast format.
     37  */
     38 
     39 #include <phymod/phymod_system.h>
     40 #include <phymod/phymod_sim.h>
     41 
     42 /* Convenience macro */
     43 #define DBG_VERB PHYMOD_DEBUG_VERBOSE
     44 
     45 /* Bit field get/set macros */
     46 #define BLACKHAWK_BF_SET(_val, _mask, _shift) _val |= ((_mask) << (_shift))
     47 #define BLACKHAWK_BF_GET(_val, _mask, _shift) (((_val) >> (_shift)) & (_mask))
     48 
     49 /*
     50  * Raw 32-bit address consists of AER value in upper 16 bits and
     51  * clause 45 address in lower 16 bits.
     52  */
     53 #define BLACKHAWK_DEVAD_SHIFT       27
     54 #define BLACKHAWK_DEVAD_MASK        0x1f
     55 #define BLACKHAWK_DEVAD_GET(_addr) \
     56     BLACKHAWK_BF_GET(_addr, BLACKHAWK_DEVAD_MASK, BLACKHAWK_DEVAD_SHIFT)
     57 #define BLACKHAWK_LANE_SHIFT        16
     58 #define BLACKHAWK_LANE_MASK         0xff
     59 #define BLACKHAWK_LANE_GET(_addr) \
     60     BLACKHAWK_BF_GET(_addr, BLACKHAWK_LANE_MASK, BLACKHAWK_LANE_SHIFT)
     61 #define BLACKHAWK_PLL_ID_SHIFT      24
     62 #define BLACKHAWK_PLL_ID_MASK       0x3
     63 #define BLACKHAWK_PLL_ID_GET(_addr) \
     64     BLACKHAWK_BF_GET(_addr, BLACKHAWK_PLL_ID_MASK, BLACKHAWK_PLL_ID_SHIFT)
     65 #define BLACKHAWK_REG_SHIFT         0
     66 #define BLACKHAWK_REG_MASK          0xffff
     67 #define BLACKHAWK_REG_GET(_addr) \
     68     BLACKHAWK_BF_GET(_addr, BLACKHAWK_REG_MASK, BLACKHAWK_REG_SHIFT)
     69 
     70 #define BLACKHAWK_ADDR(_devad, _pll_id, _lane, _reg) \
     71     (((_devad) << BLACKHAWK_DEVAD_SHIFT) +  \
     72      ((_pll_id) << BLACKHAWK_PLL_ID_SHIFT) +  \
     73      ((_lane) << BLACKHAWK_LANE_SHIFT) +    \
     74      ((_reg) << BLACKHAWK_REG_SHIFT))
     75 
     76 #define BLACKHAWK_AER               BLACKHAWK_ADDR(0, 0, 0, 0xffde)
     77 #define BLACKHAWK_BLK               BLACKHAWK_ADDR(0, 0, 0, 0x001f)
     78 
     79 /*
     80  * The CL45 indicator is used to determine whether the upper 16 bits
     81  * of the address is an AER value or a clause 45 DEVAD.
     82  */
     83 #define BLACKHAWK_CL45              (0x20 << 16)
     84 #define BLACKHAWK_CL45_MASK         (0xe0 << 16)
     85 
     86 #define BLACKHAWK_ID0                 0x600d
     87 #define BLACKHAWK_ID1                 0x8770
     88 #define BLACKHAWK_MODEL               0x26
     89 
     90 #define BLACKHAWK_SIM_FW_LOAD_DONE_REG_ADDR (0x800d203)
     91 
     92 /*RAM sim*/
     93 #define BLACKHAWK_RAM_AHB_CTRL         (0xd202)
     94 #define BLACKHAWK_RAM_WR_ADDR_REG_MS   (0xd205)          
     95 #define BLACKHAWK_RAM_WR_ADDR_REG_LS   (0xd204)
     96 #define BLACKHAWK_RAM_WR_DATA_REG_MS   (0xd207)
     97 #define BLACKHAWK_RAM_WR_DATA_REG_LS   (0xd206)
     98 #define BLACKHAWK_RAM_RD_ADDR_REG_MS   (0xd209)          
     99 #define BLACKHAWK_RAM_RD_ADDR_REG_LS   (0xd208)
    100 #define BLACKHAWK_RAM_RD_DATA_REG_MS   (0xd20b)
    101 #define BLACKHAWK_RAM_RD_DATA_REG_LS   (0xd20a)
    102 #define BLACKHAWK_IS_RAM_ADDR_REG(reg) (reg == BLACKHAWK_RAM_WR_ADDR_REG_MS || reg == BLACKHAWK_RAM_WR_ADDR_REG_LS || reg == BLACKHAWK_RAM_RD_ADDR_REG_MS || reg == BLACKHAWK_RAM_RD_ADDR_REG_LS)
    103 #define BLACKHAWK_IS_RAM_DATA_REG(reg) (reg == BLACKHAWK_RAM_WR_DATA_REG_MS || reg == BLACKHAWK_RAM_WR_DATA_REG_LS || reg == BLACKHAWK_RAM_RD_DATA_REG_MS || reg == BLACKHAWK_RAM_RD_DATA_REG_LS)
    104 
    105 #define BLACKHAWK_SIM_ENTRY_F_RAM_LS_DATA_ENTRY (0x1)
    106 #define BLACKHAWK_SIM_ENTRY_F_RAM_MS_DATA_ENTRY (0x2)
    107 #define BLACKHAWK_SIM_ENTRY_F_RAM_LS_ADDR_ENTRY (0x4)
    108 #define BLACKHAWK_SIM_ENTRY_F_RAM_MS_ADDR_ENTRY (0x8)
    109 
    110 #define BLACKHAWK_UC_TABLE_RAM_BASE  (0x100)
    111 #define BLACKHAWK_UC_TABLE_RAM_SIZE  (56)
    112 static uint16_t blackhawk_uc_mem_table[BLACKHAWK_UC_TABLE_RAM_SIZE] =
    113 {
    114     0x6e49, 0x3666, 0x0208, 0x00d0, 0x0200, 0x3400, 0x4002, 0x0100, 0x0100, 0x2000, 0x0080, 0x2000,
    115     0x0,    0x0,    0x0800, 0x2000, 0x0008, 0x0,    0x0104, 0x0100, 0x0310, 0x2000, 0x1c80, 0x2000,
    116     0x1480, 0x2000, 0x0,    0x0,    0x0,    0x0,    0x0330, 0x2000, 0x0080, 0x0,    0x1380, 0x2000,
    117     0x0,    0x0,    0x0,    0x0,    0x0,    0x0,    0x0,    0x0,    0x0,    0x0,    0x0,    0x0,
    118     0x0104, 0x0000, 0x0300, 0x2000, 0x1fd0, 0x0,    0x0,    0x0
    119 
    120 };
    121 static int blackhawk_ram_addr;
    122 
    123 
    124 /* Forward declarations */
    125 STATIC int
    126 blackhawk_sim_write(phymod_sim_data_t *pms_data, uint32_t addr, uint32_t data);
    127 STATIC int
    128 blackhawk_sim_read(phymod_sim_data_t *pms_data, uint32_t addr, uint32_t *data);
    129 
    130 
    131 STATIC uint32_t
    132 blackhawk_sim_default_data_get(uint32_t addr)
    133 {
    134     uint32_t reg;
    135 
    136     reg = BLACKHAWK_REG_GET(addr);
    137 
    138     /*force FW load success */
    139     if(addr == BLACKHAWK_SIM_FW_LOAD_DONE_REG_ADDR) {
    140         return 1;
    141     }
    142     switch (reg) {
    143         case 0x0002:
    144             return 0;
    145         case 0x0003:
    146             return 0;
    147         case 0xd03d:
    148             /*
    149              * This is DSC_A_DSC_UC_CTRL for Falcon. Make sure
    150              * The 'ready' bit is set.
    151              */
    152             return 0x0080;
    153         case 0xd0b9:
    154             return 0x7;
    155         case 0xd0d9:
    156             return 0x47c0;
    157         case 0xd100:
    158             return BLACKHAWK_MODEL;
    159         case 0xd10a:
    160             return 0x803c;
    161         case 0xd188:
    162             /*
    163              * Reset check
    164              */
    165             return 0x7;
    166         case 0xd170:
    167             return 0xb000;
    168         case 0xd1c9:
    169             return 0x0007;
    170         default:
    171             break;
    172     }
    173 
    174     return 0;
    175 }
    176 
    177 STATIC int
    178 _blackhawk_sim_write(phymod_sim_data_t *pms_data, uint32_t addr, uint32_t data)
    179 {
    180     int idx;
    181     uint32_t mask;
    182 
    183     phymod_sim_entry_t *pse;
    184 
    185     if (pms_data == NULL || pms_data->entries == NULL) {
    186         return PHYMOD_E_INIT;
    187     }
    188 
    189     /* Support optional write mask in upper 16 bits */
    190     mask = (data >> 16);
    191     if (mask == 0) {
    192         mask = 0xffff;
    193     }
    194     data &= mask;
    195 
    196     /* Check if this register has been written already */
    197     for (idx = 0; idx < pms_data->entries_used; idx++) {
    198         pse = &pms_data->entries[idx];
    199         if (pse->addr == addr) {
    200             pse->data &= ~mask;
    201             pse->data |= data;
    202             DBG_VERB(("_blackhawk_sim_write 0x%08"PRIx32" = 0x%04"PRIx32"\n",
    203                       addr, pse->data));
    204             return PHYMOD_E_NONE;
    205         }
    206     }
    207 
    208     /* Check if database is full */
    209     if (pms_data->entries_used >= pms_data->num_entries) {
    210         return PHYMOD_E_RESOURCE;
    211     }
    212 
    213     /* Check if new data matches default value */
    214     if (data == blackhawk_sim_default_data_get(addr)) {
    215         return PHYMOD_E_NONE;
    216     }
    217 
    218     /* Add new register value */
    219     pse = &pms_data->entries[pms_data->entries_used++];
    220     pse->addr = addr;
    221     pse->data = data;
    222 
    223     DBG_VERB(("_blackhawk_sim_write 0x%08"PRIx32" = 0x%04"PRIx32" (new)\n",
    224               addr, pse->data));
    225 
    226     return PHYMOD_E_NONE;
    227 }
    228 
    229 
    230 
    231 STATIC uint32_t
    232 blackhawk_sim_reg_copies_get(uint32_t addr)
    233 {
    234     uint32_t devad, reg;
    235 
    236     devad = BLACKHAWK_DEVAD_GET(addr);
    237     reg = BLACKHAWK_REG_GET(addr);
    238 
    239     if (reg == BLACKHAWK_AER || reg == BLACKHAWK_BLK) {
    240         return 1;
    241     }
    242 
    243     if (devad == 0) {
    244         if ((reg & 0xf000) == 0x9000) {
    245             return 2;
    246         }
    247         if ((reg & 0xf000) == 0xc000) {
    248             return 4;
    249         }
    250     }
    251     else if (devad == 1) {
    252         if ((reg & 0xfff0) == 0xd100) {
    253             return 1;
    254         }
    255         if ((reg & 0xfff0) == 0xd190) {
    256             return 1;
    257         }
    258         if ((reg & 0xfff0) == 0xd180) {
    259             return 2;
    260         }
    261         if ((reg & 0xfff0) == 0xd140) {
    262             return 2;
    263         }
    264         if ((reg & 0xfff0) == 0xd110) {
    265             return 2;
    266         }
    267         return 8;
    268     }
    269     return 0;
    270 }
    271 
    272 STATIC int
    273 blackhawk_sim_init(phymod_sim_data_t *pms_data,
    274                int num_entries, phymod_sim_entry_t *entries)
    275 {
    276     if (pms_data != NULL) {
    277         PHYMOD_MEMSET(pms_data, 0, sizeof(*pms_data));
    278         pms_data->num_entries = num_entries;
    279         pms_data->entries = entries;
    280     }
    281     return PHYMOD_E_NONE;
    282 }
    283 
    284 STATIC int
    285 blackhawk_sim_reset(phymod_sim_data_t *pms_data)
    286 {
    287     uint32_t sim_size;
    288 
    289     if (pms_data == NULL || pms_data->entries == NULL) {
    290         return PHYMOD_E_INIT;
    291     }
    292 
    293     pms_data->entries_used = 0;
    294     sim_size = pms_data->num_entries * sizeof(phymod_sim_entry_t);
    295     PHYMOD_MEMSET(pms_data->entries, 0, sim_size);
    296 
    297     return PHYMOD_E_NONE;
    298 }
    299 
    300 STATIC int
    301 blackhawk_sim_read(phymod_sim_data_t *pms_data, uint32_t addr, uint32_t *data)
    302 {
    303     int idx;
    304     uint32_t aer, blk, devad, reg, copies, pll_id=0;
    305     uint32_t lane = 0;
    306     phymod_sim_entry_t *pse;
    307     uint32_t pse_flag = 0;
    308     uint32_t addr_ms = 0, addr_ls = 0, abh_ctrl = 0;
    309     int increase_addr_auto = 0;
    310 
    311     if (pms_data == NULL || pms_data->entries == NULL) {
    312         return PHYMOD_E_INIT;
    313     }
    314 
    315     devad = 0;
    316 
    317 
    318     if (addr < BLACKHAWK_BLK) {
    319         /* Assume clause 22 access */
    320         (void)blackhawk_sim_read(pms_data, BLACKHAWK_BLK, &blk);
    321         if (addr & 0x10) {
    322             /* IEEE bit */
    323             blk |= 0x8000;
    324         }
    325         addr = (addr & 0xf) | (blk & 0xfff0);
    326         if (addr != BLACKHAWK_AER && addr != BLACKHAWK_BLK) {
    327             (void)blackhawk_sim_read(pms_data, BLACKHAWK_AER, &aer);
    328             addr |= (aer << 16);
    329         }
    330     } else {
    331         /* Extract devad if clause 45 address format */
    332         if ((addr & BLACKHAWK_CL45_MASK) == BLACKHAWK_CL45) {
    333             devad = (addr >> 16) & 0x1f;
    334             addr &= 0xffff;
    335         }
    336     }
    337 
    338     if (addr != BLACKHAWK_AER && addr != BLACKHAWK_BLK) {
    339         /* Assume AER is in upper 16 bits */
    340         aer = (addr >> 16);
    341         if (aer == 0) {
    342             /* Try reading real AER instead */
    343             (void)blackhawk_sim_read(pms_data, BLACKHAWK_AER, &aer);
    344         }
    345         /* Add clause 45 devad (if used) */
    346         aer |= (devad << 11);
    347         addr = (addr & 0xffff) | (aer << 16);
    348 
    349         lane = (aer & 0x7);
    350     }
    351 
    352     /* Adjust lane according to number of copies */
    353     devad = BLACKHAWK_DEVAD_GET(addr);
    354     reg = BLACKHAWK_REG_GET(addr);
    355     copies = blackhawk_sim_reg_copies_get(addr);
    356     if (copies == 1) {
    357         lane = 0;
    358     } else if (copies == 2) {
    359         pll_id = BLACKHAWK_PLL_ID_GET(addr);
    360         lane = (pll_id == 0) ? 0 : 1;
    361     }
    362     
    363     /*handle ram read/write*/
    364     if (BLACKHAWK_IS_RAM_DATA_REG(reg) || BLACKHAWK_IS_RAM_ADDR_REG(reg)) {
    365 
    366         if (BLACKHAWK_IS_RAM_DATA_REG(reg)) {
    367             (void)blackhawk_sim_read(pms_data, BLACKHAWK_ADDR(devad, pll_id, lane, BLACKHAWK_RAM_AHB_CTRL), &abh_ctrl);
    368             increase_addr_auto = ((abh_ctrl >> 13) & 0x1);
    369 
    370             (void)blackhawk_sim_read(pms_data, BLACKHAWK_ADDR(devad, pll_id, lane, BLACKHAWK_RAM_RD_ADDR_REG_LS), &addr_ls);
    371             (void)blackhawk_sim_read(pms_data, BLACKHAWK_ADDR(devad, pll_id, lane, BLACKHAWK_RAM_RD_ADDR_REG_MS), &addr_ms);
    372             addr = addr_ls | (addr_ms << 16);
    373             if (blackhawk_ram_addr == 0 ) {
    374                 blackhawk_ram_addr = addr;
    375             } else {
    376                 if (increase_addr_auto) {
    377                     blackhawk_ram_addr += 1;
    378                 } else {
    379                     blackhawk_ram_addr = 0;
    380                 }
    381             }
    382 
    383             if (reg == BLACKHAWK_RAM_RD_DATA_REG_LS || reg == BLACKHAWK_RAM_WR_DATA_REG_LS) {
    384                 pse_flag |= BLACKHAWK_SIM_ENTRY_F_RAM_LS_DATA_ENTRY;
    385             } else {
    386                 pse_flag |= BLACKHAWK_SIM_ENTRY_F_RAM_MS_DATA_ENTRY;
    387             }
    388         } else { /*BLACKHAWK_IS_RAM_ADDR_REG*/
    389             addr = BLACKHAWK_ADDR(devad, 0, lane, 0 /*dummy*/);
    390             if (reg == BLACKHAWK_RAM_RD_ADDR_REG_LS || reg == BLACKHAWK_RAM_WR_ADDR_REG_LS) {
    391                 pse_flag |= BLACKHAWK_SIM_ENTRY_F_RAM_LS_ADDR_ENTRY;
    392             } else {
    393                 pse_flag |= BLACKHAWK_SIM_ENTRY_F_RAM_MS_ADDR_ENTRY;
    394             }
    395         }
    396     
    397         /* Check if this register has been written already */
    398         for (idx = 0; idx < pms_data->entries_used; idx++) {
    399             pse = &pms_data->entries[idx];
    400             if ((pse->addr == addr) && (pse->flags == pse_flag)) {
    401                 *data = pse->data;
    402                 DBG_VERB(("blackhawk_sim_read 0x%08"PRIx32" = 0x%04"PRIx32"\n",
    403                           addr, *data));
    404                 return PHYMOD_E_NONE;
    405             }
    406         }
    407 
    408         if((blackhawk_ram_addr >= BLACKHAWK_UC_TABLE_RAM_BASE) && (blackhawk_ram_addr < (BLACKHAWK_UC_TABLE_RAM_BASE + BLACKHAWK_UC_TABLE_RAM_SIZE))) {
    409             *data = blackhawk_uc_mem_table[blackhawk_ram_addr - BLACKHAWK_UC_TABLE_RAM_BASE];
    410         }else {
    411             *data = 0;
    412         }
    413 
    414         return PHYMOD_E_NONE;
    415     }
    416 
    417 
    418 
    419     addr = BLACKHAWK_ADDR(devad, pll_id, lane, reg);
    420 
    421     /* Check if this register has been written already */
    422     for (idx = 0; idx < pms_data->entries_used; idx++) {
    423         pse = &pms_data->entries[idx];
    424         if ((pse->addr == addr) && (pse->flags == pse_flag)) {
    425             *data = pse->data;
    426             DBG_VERB(("blackhawk_sim_read 0x%08"PRIx32" = 0x%04"PRIx32"\n",
    427                       addr, *data));
    428             return PHYMOD_E_NONE;
    429         }
    430     }
    431 
    432     /* Return default value if register was never written */
    433     *data = blackhawk_sim_default_data_get(addr);
    434 
    435     DBG_VERB(("blackhawk_sim_read 0x%08"PRIx32" = [0x%04"PRIx32"]\n",
    436               addr, *data));
    437 
    438     return PHYMOD_E_NONE;
    439 }
    440 
    441 STATIC int
    442 blackhawk_sim_write(phymod_sim_data_t *pms_data, uint32_t addr, uint32_t data)
    443 {
    444     int idx;
    445     uint32_t aer, blk, devad, reg, copies, pll_id=0;
    446     uint32_t lane = 0;
    447     phymod_sim_entry_t *pse;
    448     uint32_t pse_flag = 0;
    449     uint32_t addr_ms = 0, addr_ls = 0;
    450 
    451     if (pms_data == NULL || pms_data->entries == NULL) {
    452         return PHYMOD_E_INIT;
    453     }
    454 
    455     devad = 0;
    456 
    457     if (addr < BLACKHAWK_BLK) {
    458         /* Assume clause 22 access */
    459         (void)blackhawk_sim_read(pms_data, BLACKHAWK_BLK, &blk);
    460         /* IEEE bit */
    461         if (addr & 0x10) {
    462             blk |= 0x8000;
    463         } else {
    464             blk &= ~0x8000;
    465         }
    466         addr = (addr & 0xf) | (blk & 0xfff0);
    467         if (addr != BLACKHAWK_AER && addr != BLACKHAWK_BLK) {
    468             (void)blackhawk_sim_read(pms_data, BLACKHAWK_AER, &aer);
    469             addr |= (aer << 16);
    470         }
    471     } else {
    472         /* Extract devad if clause 45 address format */
    473         if ((addr & BLACKHAWK_CL45_MASK) == BLACKHAWK_CL45) {
    474             devad = (addr >> 16) & 0x1f;
    475             addr &= 0xffff;
    476         }
    477     }
    478 
    479     if (addr != BLACKHAWK_AER && addr != BLACKHAWK_BLK) {
    480         /* Assume AER is in upper 16 bits */
    481         aer = (addr >> 16);
    482         if (aer == 0) {
    483             /* Try reading real AER instead */
    484             (void)blackhawk_sim_read(pms_data, BLACKHAWK_AER, &aer);
    485         }
    486 
    487         /* Add clause 45 devad (if used) */
    488         aer |= (devad << 11);
    489         addr = (addr & 0xffff) | (aer << 16);
    490 
    491         lane = (aer & 0xff);
    492         if (lane > 7) {
    493             /*
    494              * Handle lane broadcast
    495              *
    496              * Note that we use lane 8 instead of lane 0 to prevent a
    497              * broadcast loop. The value 8 will become 0 when masked
    498              * with 0x7, but it prevents the AER in the upper 16 bits
    499              * from being zero, which will cause the code above to
    500              * obtain the AER value from register 0xffde.
    501              */
    502             reg = BLACKHAWK_REG_GET(addr);
    503             devad = BLACKHAWK_DEVAD_GET(addr);
    504             pll_id = BLACKHAWK_PLL_ID_GET(addr);
    505             if (lane == 0x20) {
    506                 /* Write lanes 0 and 1 */
    507                 addr = BLACKHAWK_ADDR(devad, pll_id, 0, reg);
    508                 (void)blackhawk_sim_write(pms_data, addr, data);
    509                 addr = BLACKHAWK_ADDR(devad, pll_id, 1, reg);
    510                 (void)blackhawk_sim_write(pms_data, addr, data);
    511             }
    512             if (lane == 0x21) {
    513                 /* Write lanes 2 and 3 */
    514                 addr = BLACKHAWK_ADDR(devad, pll_id, 2, reg);
    515                 (void)blackhawk_sim_write(pms_data, addr, data);
    516                 addr = BLACKHAWK_ADDR(devad, pll_id, 3, reg);
    517                 (void)blackhawk_sim_write(pms_data, addr, data);
    518             }
    519             if (lane == 0x22) {
    520                 /* Write lanes 4 and 5 */
    521                 addr = BLACKHAWK_ADDR(devad, pll_id, 4, reg);
    522                 (void)blackhawk_sim_write(pms_data, addr, data);
    523                 addr = BLACKHAWK_ADDR(devad, pll_id, 5, reg);
    524                 (void)blackhawk_sim_write(pms_data, addr, data);
    525             }
    526             if (lane == 0x23) {
    527                 /* Write lanes 6 and 7 */
    528                 addr = BLACKHAWK_ADDR(devad, pll_id, 6, reg);
    529                 (void)blackhawk_sim_write(pms_data, addr, data);
    530                 addr = BLACKHAWK_ADDR(devad, pll_id, 7, reg);
    531                 (void)blackhawk_sim_write(pms_data, addr, data);
    532             }
    533             if (lane == 0x40) {
    534                 /* Write lanes 0,1,2,and 3 */
    535                 addr = BLACKHAWK_ADDR(devad, pll_id, 0, reg);
    536                 (void)blackhawk_sim_write(pms_data, addr, data);
    537                 addr = BLACKHAWK_ADDR(devad, pll_id, 1, reg);
    538                 (void)blackhawk_sim_write(pms_data, addr, data);
    539                 addr = BLACKHAWK_ADDR(devad, pll_id, 2, reg);
    540                 (void)blackhawk_sim_write(pms_data, addr, data);
    541                 addr = BLACKHAWK_ADDR(devad, pll_id, 3, reg);
    542                 (void)blackhawk_sim_write(pms_data, addr, data);
    543             }
    544             if (lane == 0x41) {
    545                 /* Write lanes 4,5,6 and 7 */
    546                 addr = BLACKHAWK_ADDR(devad, pll_id, 4, reg);
    547                 (void)blackhawk_sim_write(pms_data, addr, data);
    548                 addr = BLACKHAWK_ADDR(devad, pll_id, 5, reg);
    549                 (void)blackhawk_sim_write(pms_data, addr, data);
    550                 addr = BLACKHAWK_ADDR(devad, pll_id, 6, reg);
    551                 (void)blackhawk_sim_write(pms_data, addr, data);
    552                 addr = BLACKHAWK_ADDR(devad, pll_id, 7, reg);
    553                 (void)blackhawk_sim_write(pms_data, addr, data);
    554             }
    555             if (lane == 0xff) {
    556                 /* Write lanes 2 and 3 */
    557                 addr = BLACKHAWK_ADDR(devad, pll_id, 0, reg);
    558                 (void)blackhawk_sim_write(pms_data, addr, data);
    559                 addr = BLACKHAWK_ADDR(devad, pll_id, 1, reg);
    560                 (void)blackhawk_sim_write(pms_data, addr, data);
    561                 addr = BLACKHAWK_ADDR(devad, pll_id, 2, reg);
    562                 (void)blackhawk_sim_write(pms_data, addr, data);
    563                 addr = BLACKHAWK_ADDR(devad, pll_id, 3, reg);
    564                 (void)blackhawk_sim_write(pms_data, addr, data);
    565                 addr = BLACKHAWK_ADDR(devad, pll_id, 4, reg);
    566                 (void)blackhawk_sim_write(pms_data, addr, data);
    567                 addr = BLACKHAWK_ADDR(devad, pll_id, 5, reg);
    568                 (void)blackhawk_sim_write(pms_data, addr, data);
    569                 addr = BLACKHAWK_ADDR(devad, pll_id, 6, reg);
    570                 (void)blackhawk_sim_write(pms_data, addr, data);
    571                 addr = BLACKHAWK_ADDR(devad, pll_id, 7, reg);
    572                 (void)blackhawk_sim_write(pms_data, addr, data);
    573             }
    574             return PHYMOD_E_NONE;
    575         }
    576     }
    577 
    578     /* Adjust lane according to number of copies */
    579     devad = BLACKHAWK_DEVAD_GET(addr);
    580     reg = BLACKHAWK_REG_GET(addr);
    581     copies = blackhawk_sim_reg_copies_get(addr);
    582     if (copies == 1) {
    583         lane = 0;
    584     } else if (copies == 2) {
    585         pll_id = BLACKHAWK_PLL_ID_GET(addr);
    586         lane = (pll_id == 0) ? 0 : 1;
    587     }
    588 
    589     /*handle ram read/write*/
    590     if (BLACKHAWK_IS_RAM_DATA_REG(reg) || BLACKHAWK_IS_RAM_ADDR_REG(reg)) {
    591 
    592         if (BLACKHAWK_IS_RAM_DATA_REG(reg)) {
    593 
    594             (void)blackhawk_sim_read(pms_data, BLACKHAWK_ADDR(devad, pll_id, lane, BLACKHAWK_RAM_RD_ADDR_REG_LS), &addr_ls);
    595             (void)blackhawk_sim_read(pms_data, BLACKHAWK_ADDR(devad, pll_id, lane, BLACKHAWK_RAM_RD_ADDR_REG_MS), &addr_ms);
    596             addr = addr_ls | (addr_ms << 16);
    597             if (reg == BLACKHAWK_RAM_RD_DATA_REG_LS || reg == BLACKHAWK_RAM_WR_DATA_REG_LS) {
    598                 pse_flag |= BLACKHAWK_SIM_ENTRY_F_RAM_LS_DATA_ENTRY;
    599             } else {
    600                 pse_flag |= BLACKHAWK_SIM_ENTRY_F_RAM_MS_DATA_ENTRY;
    601             }
    602         } else { /*BLACKHAWK_IS_RAM_ADDR_REG*/
    603             addr = BLACKHAWK_ADDR(devad, 0, lane, 0 /*dummy*/);
    604             if (reg == BLACKHAWK_RAM_RD_ADDR_REG_LS || reg == BLACKHAWK_RAM_WR_ADDR_REG_LS) {
    605                 pse_flag |= BLACKHAWK_SIM_ENTRY_F_RAM_LS_ADDR_ENTRY;
    606             } else {
    607                 pse_flag |= BLACKHAWK_SIM_ENTRY_F_RAM_MS_ADDR_ENTRY;
    608             }
    609         }
    610 
    611         /* Check if this register has been written already */
    612         for (idx = 0; idx < pms_data->entries_used; idx++) {
    613             pse = &pms_data->entries[idx];
    614             if ((pse->addr == addr) && (pse->flags == pse_flag)) {
    615                 pse->data = data;
    616                 DBG_VERB(("blackhawk_sim_write 0x%08"PRIx32" = 0x%04"PRIx32" - flag = %u \n",
    617                           addr, pse->data, pse_flag));
    618                 return PHYMOD_E_NONE;
    619             }
    620         }
    621         pse = &pms_data->entries[pms_data->entries_used++];
    622         pse->addr = addr;
    623         pse->data = data;
    624         pse->flags = pse_flag;
    625 
    626         DBG_VERB(("blackhawk_sim_write 0x%08"PRIx32" = 0x%04"PRIx32"  - flag = %u (new)\n",
    627               addr, pse->data, pse->flags));
    628 
    629         return PHYMOD_E_NONE;
    630     }
    631 
    632     addr = BLACKHAWK_ADDR(devad, pll_id, lane, reg);
    633 
    634     return _blackhawk_sim_write(pms_data, addr, data);
    635 }
    636 
    637 STATIC int                                                        
    638 blackhawk_sim_event(phymod_sim_data_t *pms_data, phymod_sim_event_t event)
    639 {
    640     if (pms_data == NULL || pms_data->entries == NULL) {
    641         return PHYMOD_E_INIT;
    642     }
    643 
    644     return PHYMOD_E_NONE;
    645 }
    646 
    647 phymod_sim_drv_t blackhawk_sim_drv = {
    648     blackhawk_sim_init,
    649     blackhawk_sim_reset,
    650     blackhawk_sim_read,
    651     blackhawk_sim_write,
    652     blackhawk_sim_event
    653 };
    654