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

tscf_gen3_sim.c (17756B)


      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 TSCF_GEN3_BF_SET(_val, _mask, _shift) _val |= ((_mask) << (_shift))
     47 #define TSCF_GEN3_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 TSCF_GEN3_DEVAD_SHIFT       27
     54 #define TSCF_GEN3_DEVAD_MASK        0x1f
     55 #define TSCF_GEN3_DEVAD_GET(_addr) \
     56     TSCF_GEN3_BF_GET(_addr, TSCF_GEN3_DEVAD_MASK, TSCF_GEN3_DEVAD_SHIFT)
     57 #define TSCF_GEN3_LANE_SHIFT        16
     58 #define TSCF_GEN3_LANE_MASK         0x7
     59 #define TSCF_GEN3_LANE_GET(_addr) \
     60     TSCF_GEN3_BF_GET(_addr, TSCF_GEN3_LANE_MASK, TSCF_GEN3_LANE_SHIFT)
     61 #define TSCF_GEN3_REG_SHIFT         0
     62 #define TSCF_GEN3_REG_MASK          0xffff
     63 #define TSCF_GEN3_REG_GET(_addr) \
     64     TSCF_GEN3_BF_GET(_addr, TSCF_GEN3_REG_MASK, TSCF_GEN3_REG_SHIFT)
     65 #define TSCF_GEN3_PLLIDX_SHIFT      24 
     66 #define TSCF_GEN3_PLLIDX_MASK     0x3
     67 #define TSCF_GEN3_PLLIDX_GET(_addr) \
     68     TSCF_GEN3_BF_GET(_addr, TSCF_GEN3_PLLIDX_MASK, TSCF_GEN3_PLLIDX_SHIFT)
     69 
     70 #define TSCF_GEN3_ADDR(_devad, _lane, _reg, _pllidx) \
     71     (((_devad) << TSCF_GEN3_DEVAD_SHIFT) +  \
     72      ((_lane) << TSCF_GEN3_LANE_SHIFT) +    \
     73      ((_reg) << TSCF_GEN3_REG_SHIFT)) +     \
     74      ((_pllidx << TSCF_GEN3_PLLIDX_SHIFT))
     75 
     76 #define TSCF_GEN3_AER               TSCF_GEN3_ADDR(0, 0, 0xffde, 0)
     77 #define TSCF_GEN3_BLK               TSCF_GEN3_ADDR(0, 0, 0x001f, 0)
     78 
     79 
     80 /*
     81  * The CL45 indicator is used to determine whether the upper 16 bits
     82  * of the address is an AER value or a clause 45 DEVAD.
     83  */
     84 #define TSCF_GEN3_CL45              (0x20 << 16)
     85 #define TSCF_GEN3_CL45_MASK         (0xe0 << 16)
     86 
     87 #define TSCF_GEN3_ID0                 0x600d
     88 #define TSCF_GEN3_ID1                 0x8770
     89 #define TSCF_GEN3_SERDES_ID           0x02e4
     90 #define MONTEREY_TSC_UCODE_IMAGE_CRC  0x7898
     91 
     92 #define TSCF_GEN3_SIM_FW_LOAD_DONE_REG_ADDR (0x800d203)
     93 
     94 /* Forward declarations */
     95 STATIC int
     96 tscf_gen3_sim_write(phymod_sim_data_t *pms_data, uint32_t addr, uint32_t data);
     97 STATIC int
     98 tscf_gen3_sim_read(phymod_sim_data_t *pms_data, uint32_t addr, uint32_t *data);
     99 
    100 STATIC uint32_t
    101 tscf_gen3_sim_default_data_get(uint32_t addr)
    102 {
    103     uint32_t devad, reg;
    104 
    105     devad = TSCF_GEN3_DEVAD_GET(addr);
    106     reg = TSCF_GEN3_REG_GET(addr);
    107 
    108     /*force FW load success */
    109     if(addr == TSCF_GEN3_SIM_FW_LOAD_DONE_REG_ADDR) {
    110         return 1;
    111     }
    112    
    113     if (devad == 0){
    114         switch (reg) {
    115             case 0x0002:
    116                 return TSCF_GEN3_ID0;
    117             case 0x0003:
    118                 return TSCF_GEN3_ID1;
    119             case 0x900e:
    120                 return TSCF_GEN3_SERDES_ID;
    121             default:
    122                 break;
    123         }
    124     }
    125     if (devad == 1) {
    126         switch (reg){
    127             case 0xd03d:
    128                 /*
    129                  * This is DSC_A_DSC_UC_CTRL for Falcon. Make sure
    130                  * The 'ready' bit is set.
    131                  */
    132                 return 0x0080 ;
    133             case 0xd10a:
    134                 /* DIG_COM_REVID1[15:12], Number of lanes */
    135                 return 0x403e;
    136             case 0xd188:
    137             case 0xd0b9:
    138                 /*
    139                  * Reset check
    140                  */
    141                  return 0x7;
    142             case 0xd104:
    143                 return 0x8271;
    144             case 0xd170:
    145                 return 0xb000;
    146             default:
    147                 break;
    148 
    149        }
    150     }
    151     return 0;
    152 }
    153 
    154 STATIC uint32_t
    155 tscf_gen3_sim_reg_copies_get(uint32_t addr)
    156 {
    157     uint32_t devad, reg;
    158 
    159     devad = TSCF_GEN3_DEVAD_GET(addr);
    160     reg = TSCF_GEN3_REG_GET(addr);
    161 
    162     if (reg == TSCF_GEN3_AER || reg == TSCF_GEN3_BLK) {
    163         return 1;
    164     }
    165 
    166     if (devad == 0) {
    167         if ((reg & 0xf000) == 0x9000) {
    168             return 1;
    169         }
    170         if ((reg & 0xf000) == 0xa000) {
    171             return 2;
    172         }
    173         return 4;
    174     } else if (devad == 1) {
    175         return 4;
    176     }
    177     return 0;
    178 }
    179 
    180 STATIC int
    181 _tscf_gen3_sim_write(phymod_sim_data_t *pms_data, uint32_t addr, uint32_t data)
    182 {
    183     int idx;
    184     uint32_t mask;
    185 
    186     phymod_sim_entry_t *pse;
    187 
    188     if (pms_data == NULL || pms_data->entries == NULL) {
    189         return PHYMOD_E_INIT;
    190     }
    191 
    192     /* Support optional write mask in upper 16 bits */
    193     mask = (data >> 16);
    194     if (mask == 0) {
    195         mask = 0xffff;
    196     }
    197     data &= mask;
    198 
    199     /* Check if this register has been written already */
    200     for (idx = 0; idx < pms_data->entries_used; idx++) {
    201         pse = &pms_data->entries[idx];
    202         if (pse->addr == addr) {
    203             pse->data &= ~mask;
    204             pse->data |= data;
    205             DBG_VERB(("_tscf_gen3_sim_write 0x%08"PRIx32" = 0x%04"PRIx32"\n",
    206                       addr, pse->data));
    207             return PHYMOD_E_NONE;
    208         }
    209     }
    210 
    211     /* Check if database is full */
    212     if (pms_data->entries_used >= pms_data->num_entries) {
    213         return PHYMOD_E_RESOURCE;
    214     }
    215 
    216     /* Check if new data matches default value */
    217     if (data == tscf_gen3_sim_default_data_get(addr)) {
    218         return PHYMOD_E_NONE;
    219     }
    220 
    221     /* Add new register value */
    222     pse = &pms_data->entries[pms_data->entries_used++];
    223     pse->addr = addr;
    224     pse->data = data;
    225 
    226     DBG_VERB(("_tscf_gen3_sim_write 0x%08"PRIx32" = 0x%04"PRIx32" (new)\n",
    227               addr, pse->data));
    228 
    229     return PHYMOD_E_NONE;
    230 }
    231 
    232 STATIC uint32_t
    233 tscf_gen3_sim_write_adjust(phymod_sim_data_t *pms_data, uint32_t addr, uint32_t data)
    234 {
    235     uint32_t devad, reg, val;
    236     uint32_t pllidx = 0;
    237 
    238     devad = TSCF_GEN3_DEVAD_GET(addr);
    239     reg = TSCF_GEN3_REG_GET(addr);
    240     pllidx = TSCF_GEN3_PLLIDX_GET(addr);
    241 
    242     if (devad == 0) {
    243         switch (reg) {
    244         case 0xc050:
    245             /* Set SW_SPEED_CHANGE_DONE and SW_SPEED_CONFIG_VLD in status reg */
    246             tscf_gen3_sim_write(pms_data, addr + 1, 0x3);
    247             /* Force link up in RX_X4_PCS_LIVE_STS register
    248                offset 0x111 = 0xc161 - 0xc050 */
    249             tscf_gen3_sim_write(pms_data, addr + 0x111, 0x2);
    250             /* Sync configured speed into final speed status register
    251              * 0x20 = 0xc070 - 0xc050 */
    252             tscf_gen3_sim_read(pms_data, addr + 0x20, &val);
    253             val = (val & 0xffff00ff) | ((data & 0xff)<<8);
    254             tscf_gen3_sim_write(pms_data, addr + 0x20, val);
    255             break;
    256         case 0xc055:
    257             /* Sync configured Lane Number into Lane Number status register
    258              * 0x1B = 0xc070 - 0xc055 */
    259             tscf_gen3_sim_read(pms_data, addr + 0x1B, &val);
    260             val = (val & 0xfffffff8) | (data & 0x7);
    261             tscf_gen3_sim_write(pms_data, addr + 0x1B, val);
    262             break;
    263         default:
    264             break;
    265         }
    266     } else if (devad == 1) {
    267         switch (reg) {
    268         case 0xd204:
    269         case 0xd205:
    270         case 0xd206:
    271         case 0xd207:
    272             /* Sync configured aMICRO_A_COM registers. Write and read access different register
    273              * Write registers: 0xd204~0xd207; Read registers: 0xd208~0xd20b
    274              * 0x4 = 0xd208(~0xd20b) - 0xd204(~0xd207)*/
    275             tscf_gen3_sim_write(pms_data, addr + 0x4, data);
    276             break;
    277         case 0xd0e1:
    278             /* Sync configured SIGDET_CTL1 register. When a port is set disable,
    279              * the port's RX_X4_PCS_LIVE_STS1 register deletes link status.
    280              * RX_X4_PCS_LIVE_STS1 register is PCS register, so need set devad to 0.
    281              * 0xF80 = 0xd0e1 - 0xc161*/
    282             tscf_gen3_sim_read(pms_data, (addr - 0xF80) & 0x7ffff, &val);
    283             val = (val & 0xfffd) | (((data&0x80)==0x80)?0:0x2);
    284             tscf_gen3_sim_write(pms_data, (addr - 0xF80) & 0x7ffff, val);
    285             break;
    286         case 0xd147:
    287             /* Sync configured all lanes' PLL_CAL_CTL7 register. Only one PLL/VCO per core */
    288             /* Write lanes 0, 1, 2 and 3 */
    289             addr = TSCF_GEN3_ADDR(devad, 0, reg, pllidx);
    290             (void)_tscf_gen3_sim_write(pms_data, addr, data);
    291 
    292             addr = TSCF_GEN3_ADDR(devad, 1, reg, pllidx);
    293             (void)_tscf_gen3_sim_write(pms_data, addr, data);
    294 
    295             addr = TSCF_GEN3_ADDR(devad, 2, reg, pllidx);
    296             (void)_tscf_gen3_sim_write(pms_data, addr, data);
    297 
    298             addr = TSCF_GEN3_ADDR(devad, 3, reg, pllidx);
    299             (void)_tscf_gen3_sim_write(pms_data, addr, data);
    300             break;
    301         case 0xd094:
    302         case 0xd095:
    303             /* Sync configured CL93N72 Control 2/3 registers. Write and read access different register
    304              * Write registers: 0xd094/d095; Read registers: 0xd133/0xd134
    305              * 0x9f = 0xd133(0xd134) - 0xd094(0xd095)*/
    306             tscf_gen3_sim_write(pms_data, addr + 0x9f, data);
    307             break;
    308         default:
    309             break;
    310         }
    311     }
    312 
    313     return data;
    314 }
    315 
    316 STATIC int
    317 tscf_gen3_sim_init(phymod_sim_data_t *pms_data,
    318                int num_entries, phymod_sim_entry_t *entries)
    319 {
    320     if (pms_data != NULL) {
    321         PHYMOD_MEMSET(pms_data, 0, sizeof(*pms_data));
    322         pms_data->num_entries = num_entries;
    323         pms_data->entries = entries;
    324     }
    325     return PHYMOD_E_NONE;
    326 }
    327 
    328 STATIC int
    329 tscf_gen3_sim_reset(phymod_sim_data_t *pms_data)
    330 {
    331     uint32_t sim_size;
    332 
    333     if (pms_data == NULL || pms_data->entries == NULL) {
    334         return PHYMOD_E_INIT;
    335     }
    336 
    337     pms_data->entries_used = 0;
    338     sim_size = pms_data->num_entries * sizeof(phymod_sim_entry_t);
    339     PHYMOD_MEMSET(pms_data->entries, 0, sim_size);
    340 
    341     return PHYMOD_E_NONE;
    342 }
    343 
    344 STATIC int
    345 tscf_gen3_sim_read(phymod_sim_data_t *pms_data, uint32_t addr, uint32_t *data)
    346 {
    347     int idx;
    348     uint32_t aer, blk, devad, reg, copies;
    349     uint32_t lane = 0, pllidx = 0;
    350     phymod_sim_entry_t *pse;
    351 
    352     if (pms_data == NULL || pms_data->entries == NULL) {
    353         return PHYMOD_E_INIT;
    354     }
    355 
    356     devad = 0;
    357 
    358     if (addr < TSCF_GEN3_BLK) {
    359         /* Assume clause 22 access */
    360         (void)tscf_gen3_sim_read(pms_data, TSCF_GEN3_BLK, &blk);
    361         /* IEEE bit */
    362         if (addr & 0x10) {
    363             blk |= 0x8000;
    364         } else {
    365             blk &= ~0x8000;
    366         }
    367         addr = (addr & 0xf) | (blk & 0xfff0);
    368         if (addr != TSCF_GEN3_AER && addr != TSCF_GEN3_BLK) {
    369             (void)tscf_gen3_sim_read(pms_data, TSCF_GEN3_AER, &aer);
    370             addr |= (aer << 16);
    371         }
    372     } else {
    373         /* Extract devad if clause 45 address format */
    374         if ((addr & TSCF_GEN3_CL45_MASK) == TSCF_GEN3_CL45) {
    375             devad = (addr >> 16) & 0x1f;
    376             addr &= 0xffff;
    377         }
    378     }
    379 
    380     if (addr != TSCF_GEN3_AER && addr != TSCF_GEN3_BLK) {
    381         /* Assume AER is in upper 16 bits */
    382         aer = (addr >> 16);
    383         if (aer == 0) {
    384             /* Try reading real AER instead */
    385             (void)tscf_gen3_sim_read(pms_data, TSCF_GEN3_AER, &aer);
    386         }
    387         /* Add clause 45 devad (if used) */
    388         if (devad) {
    389             aer |= (devad << 11);
    390             addr = (addr & 0xffff) | (aer << 16);
    391         }
    392         lane = (aer & 0x7);
    393         if (lane > 3) {
    394             /* Force lane 0 if lane is invalid */
    395             addr = TSCF_GEN3_ADDR(TSCF_GEN3_DEVAD_GET(addr), 0, TSCF_GEN3_REG_GET(addr), TSCF_GEN3_PLLIDX_GET(addr));
    396         }
    397     }
    398 
    399     /* Adjust lane according to number of copies */
    400     devad = TSCF_GEN3_DEVAD_GET(addr);
    401     reg = TSCF_GEN3_REG_GET(addr);
    402     pllidx = TSCF_GEN3_PLLIDX_GET(addr);
    403     copies = tscf_gen3_sim_reg_copies_get(addr);
    404     if (copies == 1) {
    405         lane = 0;
    406     } else if (copies == 2) {
    407         lane &= ~0x1;
    408     }
    409     addr = TSCF_GEN3_ADDR(devad, lane, reg, pllidx);
    410 
    411     /* for DSC_UC_CTRL always succeed */
    412     if(addr == 0x800d03d) {
    413         *data = 0x80;
    414         DBG_VERB(("tscf_gen3_sim_read 0x%08"PRIx32" = 0x%04"PRIx32"\n",
    415                       addr, *data));
    416         return PHYMOD_E_NONE;
    417     } else if (addr == 0x800d03e) {
    418         *data = MONTEREY_TSC_UCODE_IMAGE_CRC;
    419         return PHYMOD_E_NONE;
    420     } else if (addr == 0x800d104) {
    421         *data = 0x8271;
    422         return PHYMOD_E_NONE;
    423     } else if (addr == 0x800d201) {
    424         *data = 0;
    425         return PHYMOD_E_NONE;
    426     }
    427 
    428     /* Check if this register has been written already */
    429     for (idx = 0; idx < pms_data->entries_used; idx++) {
    430         pse = &pms_data->entries[idx];
    431         if (pse->addr == addr) {
    432             *data = pse->data;
    433             DBG_VERB(("tscf_gen3_sim_read 0x%08"PRIx32" = 0x%04"PRIx32"\n",
    434                       addr, *data));
    435             return PHYMOD_E_NONE;
    436         }
    437     }
    438 
    439     /* Return default value if register was never written */
    440     *data = tscf_gen3_sim_default_data_get(addr);
    441 
    442     DBG_VERB(("tscf_gen3_sim_read 0x%08"PRIx32" = [0x%04"PRIx32"]\n",
    443               addr, *data));
    444 
    445     return PHYMOD_E_NONE;
    446 }
    447 
    448 STATIC int
    449 tscf_gen3_sim_write(phymod_sim_data_t *pms_data, uint32_t addr, uint32_t data)
    450 {
    451     uint32_t aer, blk, devad, reg, copies;
    452     uint32_t lane = 0, pllidx = 0 ;
    453 
    454     if (pms_data == NULL || pms_data->entries == NULL) {
    455         return PHYMOD_E_INIT;
    456     }
    457 
    458     devad = 0;
    459 
    460     if (addr < TSCF_GEN3_BLK) {
    461         /* Assume clause 22 access */
    462         (void)tscf_gen3_sim_read(pms_data, TSCF_GEN3_BLK, &blk);
    463         /* IEEE bit */
    464         if (addr & 0x10) {
    465             blk |= 0x8000;
    466         } else {
    467             blk &= ~0x8000;
    468         }
    469         addr = (addr & 0xf) | (blk & 0xfff0);
    470         if (addr != TSCF_GEN3_AER && addr != TSCF_GEN3_BLK) {
    471             (void)tscf_gen3_sim_read(pms_data, TSCF_GEN3_AER, &aer);
    472             addr |= (aer << 16);
    473         }
    474     } else {
    475         /* Extract devad if clause 45 address format */
    476         if ((addr & TSCF_GEN3_CL45_MASK) == TSCF_GEN3_CL45) {
    477             devad = (addr >> 16) & 0x1f;
    478             addr &= 0xffff;
    479         }
    480     }
    481 
    482     if (addr != TSCF_GEN3_AER && addr != TSCF_GEN3_BLK) {
    483         /* Assume AER is in upper 16 bits */
    484         aer = (addr >> 16);
    485         if (aer == 0) {
    486             /* Try reading real AER instead */
    487             (void)tscf_gen3_sim_read(pms_data, TSCF_GEN3_AER, &aer);
    488         }
    489         /* Add clause 45 devad (if used) */
    490         if (devad) {
    491             aer |= (devad << 11);
    492             addr = (addr & 0xffff) | (aer << 16);
    493         }
    494         lane = (aer & 0x7);
    495         if (lane > 6) {
    496             return PHYMOD_E_PARAM;
    497         }
    498         if (lane > 3) {
    499             /*
    500              * Handle lane broadcast
    501              *
    502              * Note that we use lane 8 instead of lane 0 to prevent a
    503              * broadcast loop. The value 8 will become 0 when masked
    504              * with 0x7, but it prevents the AER in the upper 16 bits
    505              * from being zero, which will cause the code above to
    506              * obtain the AER value from register 0xffde.
    507              */
    508             reg = TSCF_GEN3_REG_GET(addr);
    509             devad = TSCF_GEN3_DEVAD_GET(addr);
    510             pllidx = TSCF_GEN3_PLLIDX_GET(addr);
    511             if (lane == 4 || lane == 6) {
    512                 /* Write lanes 0 and 1 */
    513                 addr = TSCF_GEN3_ADDR(devad, 8, reg, pllidx);
    514                 (void)tscf_gen3_sim_write(pms_data, addr, data);
    515                 addr = TSCF_GEN3_ADDR(devad, 1, reg, pllidx);
    516                 (void)tscf_gen3_sim_write(pms_data, addr, data);
    517             }
    518             if (lane == 5 || lane == 6) {
    519                 /* Write lanes 2 and 3 */
    520                 addr = TSCF_GEN3_ADDR(devad, 2, reg, pllidx);
    521                 (void)tscf_gen3_sim_write(pms_data, addr, data);
    522                 addr = TSCF_GEN3_ADDR(devad, 3, reg, pllidx);
    523                 (void)tscf_gen3_sim_write(pms_data, addr, data);
    524             }
    525             return PHYMOD_E_NONE;
    526         }
    527     }
    528 
    529     /* Adjust data and/or related registers */
    530     data = tscf_gen3_sim_write_adjust(pms_data, addr, data);
    531 
    532     /* Adjust lane according to number of copies */
    533     devad = TSCF_GEN3_DEVAD_GET(addr);
    534     reg = TSCF_GEN3_REG_GET(addr);
    535     copies = tscf_gen3_sim_reg_copies_get(addr);
    536     if (copies == 1) {
    537         lane = 0;
    538     } else if (copies == 2) {
    539         lane &= ~0x1;
    540     }
    541     pllidx = TSCF_GEN3_PLLIDX_GET(addr);
    542     addr = TSCF_GEN3_ADDR(devad, lane, reg, pllidx);
    543 
    544     return _tscf_gen3_sim_write(pms_data, addr, data);
    545 }
    546 
    547 STATIC int
    548 tscf_gen3_sim_event(phymod_sim_data_t *pms_data, phymod_sim_event_t event)
    549 {
    550     if (pms_data == NULL || pms_data->entries == NULL) {
    551         return PHYMOD_E_INIT;
    552     }
    553 
    554     return PHYMOD_E_NONE;
    555 }
    556 
    557 phymod_sim_drv_t tscf_gen3_sim_drv = {
    558     tscf_gen3_sim_init,
    559     tscf_gen3_sim_reset,
    560     tscf_gen3_sim_read,
    561     tscf_gen3_sim_write,
    562     tscf_gen3_sim_event
    563 };
    564