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

uc.c (58022B)


      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  * File:        mcs.c
      8  * Purpose:     MCS initialize and load utilities
      9  * Requires:
     10  */
     11 
     12 
     13 #include <shared/bsl.h>
     14 
     15 #include <soc/types.h>
     16 #include <soc/drv.h>
     17 #include <soc/register.h>
     18 #include <soc/error.h>
     19 #include <shared/util.h>
     20 #include <soc/uc_msg.h>
     21 
     22 #include <soc/uc_dbg.h>
     23 #if defined(BCM_JERICHO_SUPPORT)
     24 #include <soc/dpp/JER/jer_drv.h>
     25 #endif
     26 
     27 #if defined(BCM_CMICM_SUPPORT) || defined(BCM_IPROC_SUPPORT)
     28 
     29 #ifdef BCM_IPROC_SUPPORT
     30 #include <soc/iproc.h>
     31 #define CORE1_LUT_ADDR          0xffff042c
     32 #endif
     33 
     34 #define _SYSTEM_UC_MSG_TIMEOUT       5000000  /* 5 seconds for FW response */
     35 
     36 uint32
     37 soc_uc_mem_read(int unit, uint32 addr)
     38 {
     39 #ifdef BCM_CMICM_SUPPORT
     40     if (soc_feature(unit, soc_feature_mcs)) {
     41         return soc_pci_mcs_read(unit, addr);
     42     }
     43 #endif
     44 #ifdef BCM_IPROC_SUPPORT
     45     if (soc_feature(unit, soc_feature_iproc)) {
     46 #if defined(BCM_HURRICANE2_SUPPORT) || defined(BCM_HURRICANE3_SUPPORT)
     47         if (SOC_IS_HURRICANE2(unit) || SOC_IS_HURRICANE3(unit)) {
     48             return soc_pci_mcs_read(unit, addr);
     49         } else
     50 #endif /* BCM_HURRICANE2_SUPPORT || BCM_HURRICANE3_SUPPORT */
     51         return soc_cm_iproc_read(unit, addr);
     52     }
     53 #endif
     54     assert(0);
     55     return 0;
     56 }
     57 
     58 int
     59 soc_uc_mem_write(int unit, uint32 addr, uint32 value)
     60 {
     61 #ifdef BCM_CMICM_SUPPORT
     62     if (soc_feature(unit, soc_feature_mcs)) {
     63         return soc_pci_mcs_write(unit, addr, value);
     64     }
     65 #endif
     66 #ifdef BCM_IPROC_SUPPORT
     67     if (soc_feature(unit, soc_feature_iproc)) {
     68 #if defined(BCM_HURRICANE2_SUPPORT) || defined(BCM_HURRICANE3_SUPPORT)
     69         if (SOC_IS_HURRICANE2(unit) || SOC_IS_HURRICANE3(unit)) {
     70             return soc_pci_mcs_write(unit, addr, value);
     71         } else
     72 #endif /* BCM_HURRICANE2_SUPPORT || BCM_HURRICANE3_SUPPORT */
     73         soc_cm_iproc_write(unit, addr, value);
     74         return SOC_E_NONE;
     75     }
     76 #endif
     77     assert(0);
     78     return SOC_E_FAIL;
     79 }
     80 
     81 int
     82 soc_uc_addr_to_pcie(int unit, int uC, uint32 addr)
     83 {
     84 #ifdef BCM_CMICM_SUPPORT
     85     if (soc_feature(unit, soc_feature_mcs)) {
     86         /* If in TCM space */
     87         if (addr < 0x100000) {
     88             /* TCMs base addrs from PCIe perspective */
     89             addr += (uC == 0) ? 0x100000 : 0x200000;
     90         }
     91         return addr;
     92     }
     93 #endif
     94 
     95 #if defined(BCM_UC_MHOST_SUPPORT)
     96     if (soc_feature(unit, soc_feature_uc_mhost)) {
     97         uint32 atcm_base = 0x01000000 + 0x100000 * uC;
     98         uint32 btcm_off = 0x80000;
     99 
    100 #ifdef BCM_GREYHOUND2_SUPPORT
    101         if (SOC_IS_GREYHOUND2(unit)) {
    102             btcm_off = 0x20000;
    103         }
    104 #endif
    105 
    106 #ifdef BCM_SABER2_SUPPORT
    107         if (SOC_IS_SABER2(unit) && !SOC_IS_METROLITE(unit)) {
    108             if (uC == 2) {
    109                 atcm_base = 0x01160000;
    110             }
    111             btcm_off = 0x20000;
    112         }
    113 #endif
    114 
    115 #if defined(BCM_APACHE_SUPPORT) || defined (BCM_TOMAHAWK2_SUPPORT) || \
    116     defined (BCM_TOMAHAWK3_SUPPORT) || defined(BCM_MONTEREY_SUPPORT)
    117         if (SOC_IS_APACHE(unit) || SOC_IS_TOMAHAWK2(unit) ||
    118             SOC_IS_TOMAHAWK3(unit) || SOC_IS_MONTEREY(unit)) {
    119             atcm_base = 0x01100000 + 0x00060000 * uC;
    120             btcm_off = 0x20000;
    121         }
    122 #endif
    123 
    124 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_MAVERICK2_SUPPORT)
    125         if (SOC_IS_TRIDENT3(unit) || SOC_IS_MAVERICK2(unit)) {
    126             atcm_base = 0x01100000 + 0x00060000 * uC;
    127             btcm_off = 0x20000;
    128         }
    129 #endif
    130 
    131 #if defined(BCM_JERICHO_2_SUPPORT)
    132         if (SOC_IS_JERICHO_2_ONLY(unit)) {
    133             atcm_base = 0x01100000 + 0x00060000 * uC;
    134             btcm_off = 0x20000;
    135         }
    136 #endif
    137 
    138 #ifdef BCM_MONTEREY_SUPPORT
    139         /* Monterey, uc:2 is M7 */
    140         if (SOC_IS_MONTEREY(unit) && (2 == uC)) {
    141             atcm_base = 0x3260000;
    142             btcm_off  = 0x3264000;
    143         }
    144 #endif
    145         /* If in TCM space */
    146         if (addr < 0x100000) {
    147             if (addr < 0x40000) {
    148                 /* ATCM address from host perspective*/
    149                 return atcm_base + addr;
    150             }
    151             if (addr >= 0x40000 && addr < 0x80000) {
    152                 /* BTCM address from host perspective*/
    153                 return atcm_base + btcm_off + addr - 0x40000;
    154             }
    155             assert(0);
    156         }
    157         return addr;
    158     }
    159 #endif /* BCM_UC_MHOST_SUPPORT */
    160 
    161 #ifdef BCM_IPROC_SUPPORT
    162     if (soc_feature(unit, soc_feature_iproc)) {
    163         return addr;
    164     }
    165 #endif
    166 
    167     assert(0);
    168     return 0;
    169 }
    170 
    171 int
    172 soc_uc_sram_extents(int unit, uint32 *addr, uint32 *size)
    173 /*
    174  * Function: 	soc_uc_sram_extents
    175  * Purpose:	Get the SRAM address and length
    176  * Parameters:	unit - unit number
    177  * Returns:	SOC_E_xxx
    178  */
    179 {
    180     *size = 0;
    181     *addr = 0;
    182 
    183 #ifdef BCM_KATANA_SUPPORT
    184     if (SOC_IS_KATANA(unit)) {
    185         *size = 0x00100000;
    186         *addr = 0x00400000;
    187     }
    188 #endif
    189 #ifdef BCM_TRIUMPH3_SUPPORT
    190     if (SOC_IS_TRIUMPH3(unit)) {
    191         *size = 0x00080000;
    192         *addr = 0x00400000;
    193     }
    194 #endif
    195 #ifdef BCM_TRIDENT2_SUPPORT
    196     if (SOC_IS_TD2_TT2(unit)) {
    197         *size = 0x00080000;
    198         *addr = 0x00400000;
    199     }
    200 #endif
    201 #ifdef BCM_PETRA_SUPPORT
    202     if (SOC_IS_ARAD(unit)) {
    203         *size = 0x00080000;
    204         *addr = 0x00400000;
    205     }
    206 #endif
    207 #ifdef BCM_HELIX4_SUPPORT
    208     if (SOC_IS_HELIX4(unit)) {
    209         *size = 512 * 1024;
    210         *addr = 0x1b000000;
    211     }
    212 #endif
    213 #ifdef BCM_KATANA2_SUPPORT
    214     if (SOC_IS_KATANA2(unit)) {
    215         *size = 512 * 1024;
    216         *addr = 0x1b000000;
    217     }
    218 #endif
    219 #ifdef BCM_HURRICANE2_SUPPORT
    220     if (SOC_IS_HURRICANE2(unit)) {
    221         *size = 1 * 1024 * 1024;
    222         *addr = 0x00000000;
    223     }
    224 #endif
    225 #ifdef BCM_HURRICANE3_SUPPORT
    226     if (SOC_IS_HURRICANE3(unit)) {
    227         *size = 1 * 1024 * 1024;
    228         *addr = 0x00000000;
    229     }
    230 #endif
    231 #ifdef BCM_GREYHOUND_SUPPORT
    232     if (SOC_IS_GREYHOUND(unit)) {
    233         *size = 64 * 1024;
    234         *addr = 0x01000000;
    235     }
    236 #endif
    237 #ifdef BCM_TOMAHAWK_SUPPORT
    238     if (SOC_IS_TOMAHAWK(unit)) {
    239         *size = 1 * 1024 * 1024;
    240         *addr = 0x1b000000;
    241     }
    242 #endif
    243 #ifdef BCM_TRIDENT2PLUS_SUPPORT
    244     if (SOC_IS_TRIDENT2PLUS(unit)) {
    245         *size = 1 * 1024 * 1024;
    246         *addr = 0x00400000;
    247     }
    248 #endif
    249 #ifdef BCM_TRIDENT3_SUPPORT
    250     if (SOC_IS_TRIDENT3X(unit)) {
    251         *size = 1 * 1024 * 1024;
    252         *addr = 0x01200000;
    253     }
    254 #endif
    255 #ifdef BCM_TOMAHAWK3_SUPPORT
    256     if (SOC_IS_TOMAHAWK3(unit)) {
    257         *size = 1 * 1024 * 1024;
    258         *addr = 0x01200000;
    259     }
    260 #endif
    261 #ifdef BCM_JERICHO_2_SUPPORT
    262     if (SOC_IS_JERICHO_2_ONLY(unit)) {
    263         *size = 1 * 1024 * 1024;
    264         *addr = 0x01200000;
    265     }
    266 #endif
    267 #ifdef BCM_MAVERICK2_SUPPORT
    268     if (SOC_IS_MAVERICK2(unit)) {
    269         *size = 1 * 1024 * 1024;
    270         *addr = 0x01200000;
    271     }
    272 #endif
    273 #ifdef BCM_HELIX5_SUPPORT
    274     if (SOC_IS_HELIX5(unit)) {
    275         /* 128K SRAM in M0SSQ */
    276         *size = 128 * 1024;
    277         *addr = 0x10040000;
    278     }
    279 #endif
    280     return (SOC_E_NONE);
    281 }
    282 
    283 
    284 #ifdef BCM_CMICM_SUPPORT
    285 
    286 static
    287 int
    288 soc_uc_mcs_init(int unit)
    289 /*
    290  * Function: 	soc_uc_msc_init
    291  * Purpose:	Initialize the CMICm MCS
    292  * Parameters:	unit - unit number
    293  * Returns:	SOC_E_xxx
    294  */
    295 {
    296     int rc;
    297     uint32 sram_size, sram_addr, i;
    298 
    299     rc = soc_uc_sram_extents(unit, &sram_addr, &sram_size);
    300     if (rc != SOC_E_NONE) {
    301         return (rc);
    302     }
    303 
    304     i = 0;
    305     while (i < sram_size) {
    306         soc_uc_mem_write(unit, sram_addr + i, 0x12345678);
    307         i += 4;
    308         if ((i & 0x0ffff) == 0) {
    309             sal_usleep(1000);
    310         }
    311     }
    312     return (SOC_E_NONE);
    313 }
    314 
    315 static
    316 int
    317 soc_uc_mcs_reset(int unit, int uC)
    318 /*
    319  * Function: 	soc_uc_mcs_reset
    320  * Purpose:	Put an MCS into reset state
    321  * Parameters:	unit - unit number
    322  *		uC - microcontroller num
    323  * Returns:	SOC_E_xxxx
    324  */
    325 {
    326     uint32      config, rst_control;
    327 
    328     /* Put the uC in LE mode */
    329     if (uC == 0) {
    330         READ_UC_0_CONFIGr(unit, &config);
    331         soc_reg_field_set(unit, UC_0_CONFIGr, &config,
    332                           OVERWRITE_OTP_CONFIGf, 1);
    333         soc_reg_field_set(unit, UC_0_CONFIGr, &config,
    334                           CFGIEf, 1);
    335         soc_reg_field_set(unit, UC_0_CONFIGr, &config,
    336                           CFGEEf, 1);
    337         WRITE_UC_0_CONFIGr(unit, config);
    338     } else {
    339         READ_UC_1_CONFIGr(unit, &config);
    340         soc_reg_field_set(unit, UC_1_CONFIGr, &config,
    341                           OVERWRITE_OTP_CONFIGf, 1);
    342         soc_reg_field_set(unit, UC_1_CONFIGr, &config,
    343                           CFGIEf, 1);
    344         soc_reg_field_set(unit, UC_1_CONFIGr, &config,
    345                           CFGEEf, 1);
    346         WRITE_UC_1_CONFIGr(unit, config);
    347     }
    348 
    349     /* Take the processor in and out of reset but halted */
    350     if (uC == 0) {
    351         READ_UC_0_RST_CONTROLr(unit, &rst_control);
    352         soc_reg_field_set(unit, UC_0_RST_CONTROLr, &rst_control,
    353                           BYPASS_RSTFSM_CTRLf, 1);
    354         soc_reg_field_set(unit, UC_0_RST_CONTROLr, &rst_control,
    355                           CPUHALT_Nf, 0);
    356         WRITE_UC_0_RST_CONTROLr(unit, rst_control);
    357         sal_usleep(1000);
    358         READ_UC_0_RST_CONTROLr(unit, &rst_control);
    359         soc_reg_field_set(unit, UC_0_RST_CONTROLr, &rst_control,
    360                           SYS_PORESET_Nf, 0);
    361         soc_reg_field_set(unit, UC_0_RST_CONTROLr, &rst_control,
    362                           CORE_RESET_Nf, 0);
    363         WRITE_UC_0_RST_CONTROLr(unit, rst_control);
    364         soc_reg_field_set(unit, UC_0_RST_CONTROLr, &rst_control,
    365                           SYS_PORESET_Nf, 1);
    366         soc_reg_field_set(unit, UC_0_RST_CONTROLr, &rst_control,
    367                           CORE_RESET_Nf, 1);
    368         WRITE_UC_0_RST_CONTROLr(unit, rst_control);
    369     } else {
    370         READ_UC_1_RST_CONTROLr(unit, &rst_control);
    371         soc_reg_field_set(unit, UC_1_RST_CONTROLr, &rst_control,
    372                           CPUHALT_Nf, 0);
    373         WRITE_UC_1_RST_CONTROLr(unit, rst_control);
    374         sal_usleep(1000);
    375         READ_UC_1_RST_CONTROLr(unit, &rst_control);
    376         soc_reg_field_set(unit, UC_1_RST_CONTROLr, &rst_control,
    377                           SYS_PORESET_Nf, 0);
    378         soc_reg_field_set(unit, UC_1_RST_CONTROLr, &rst_control,
    379                           CORE_RESET_Nf, 0);
    380         WRITE_UC_1_RST_CONTROLr(unit, rst_control);
    381         soc_reg_field_set(unit, UC_1_RST_CONTROLr, &rst_control,
    382                           SYS_PORESET_Nf, 1);
    383         soc_reg_field_set(unit, UC_1_RST_CONTROLr, &rst_control,
    384                           CORE_RESET_Nf, 1);
    385         WRITE_UC_1_RST_CONTROLr(unit, rst_control);
    386     }
    387 
    388     return (SOC_E_NONE);
    389 }
    390 
    391 static
    392 int
    393 soc_uc_mcs_in_reset(int unit, int uC)
    394 /*
    395  * Function: 	soc_uc_mcs_in_reset
    396  * Purpose:	Return 1 if in RESET state, 0 otherwise
    397  * Parameters:	unit - unit number
    398  *		uC - microcontroller num
    399  * Returns:	1 or 0
    400  */
    401 {
    402     uint32 rst, halt, ctrl;
    403 
    404     if (uC == 0) {
    405         READ_UC_0_RST_CONTROLr(unit, &ctrl);
    406         rst = soc_reg_field_get(unit, UC_0_RST_CONTROLr, ctrl, CORE_RESET_Nf);
    407         halt = soc_reg_field_get(unit, UC_0_RST_CONTROLr, ctrl, CPUHALT_Nf);
    408     }
    409     else {
    410         READ_UC_1_RST_CONTROLr(unit, &ctrl);
    411         rst = soc_reg_field_get(unit, UC_1_RST_CONTROLr, ctrl, CORE_RESET_Nf);
    412         halt = soc_reg_field_get(unit, UC_1_RST_CONTROLr, ctrl, CPUHALT_Nf);
    413     }
    414     /* If either RESET or HALT is asserted (0), dev is in RESET */
    415     return (rst == 0) || (halt == 0);
    416 }
    417 
    418 static
    419 int
    420 soc_uc_mcs_start(int unit, int uC, uint32 addr)
    421 /*
    422  * Function: 	soc_uc_mcs_start
    423  * Purpose:	Start MCS execution
    424  * Parameters:	unit - unit number
    425  *		uC - microcontroller num
    426  *              addr - address to start at
    427  * Returns:	SOC_E_xxx
    428  */
    429 {
    430     uint32      rst_control;
    431 
    432     if (uC == 0) {
    433         READ_UC_0_RST_CONTROLr(unit, &rst_control);
    434         soc_reg_field_set(unit, UC_0_RST_CONTROLr, &rst_control,
    435                           CPUHALT_Nf, 1);
    436         WRITE_UC_0_RST_CONTROLr(unit, rst_control);
    437     } else {
    438         READ_UC_1_RST_CONTROLr(unit, &rst_control);
    439         soc_reg_field_set(unit, UC_1_RST_CONTROLr, &rst_control,
    440                           CPUHALT_Nf, 1);
    441         WRITE_UC_1_RST_CONTROLr(unit, rst_control);
    442     }
    443 
    444     return (SOC_E_NONE);
    445 }
    446 
    447 #endif /* BCM_CMICM_SUPPORT */
    448 
    449 #ifdef BCM_IPROC_SUPPORT
    450 
    451 /*
    452  * Function:    soc_uc_intr_disable
    453  * Purpose:  Disable UC interrupt
    454  * Parameters:  unit  - unit number
    455  *              reg   - interrupt register
    456  *              field - field in register
    457  * Returns: SOC_E_xxxx
    458  */
    459 static
    460 int
    461 soc_uc_intr_disable(int unit,
    462                     soc_reg_t reg,
    463                     soc_field_t field)
    464 {
    465     uint32 regval;
    466     if (soc_reg_field_valid(unit, reg, field)) {
    467         soc_pci_getreg(unit, soc_reg_addr(unit, reg, REG_PORT_ANY, 0), &regval);
    468         if (soc_reg_field_get(unit, reg, regval, TIMESYNC_INTRf) != 0) {
    469             soc_reg_field_set(unit, reg, &regval, TIMESYNC_INTRf, 0);
    470             soc_pci_write(unit, soc_reg_addr(unit, reg, REG_PORT_ANY, 0), regval);
    471 
    472             /* Give core time to complete processing an existing interrupt */
    473             sal_usleep(1000);
    474         }
    475     }
    476 
    477     return 0;
    478 }
    479 
    480 /*
    481  * Function: 	soc_uc_iproc_init
    482  * Purpose:	Initialize iProc/MCS
    483  * Parameters:	unit - unit number
    484  * Returns:	SOC_E_xxxx
    485  */
    486 static
    487 int
    488 soc_uc_iproc_init(int unit)
    489 {
    490     int rc;
    491     uint32 sram_size, sram_addr, i;
    492 
    493 #ifdef BCM_IPROC_DDR_SUPPORT
    494     if (soc_feature(unit, soc_feature_iproc_ddr)) {
    495         soc_iproc_ddr_init(unit);
    496     }
    497 #endif /* BCM_IPROC_DDR_SUPPORT */
    498 
    499     rc = soc_uc_sram_extents(unit, &sram_addr, &sram_size);
    500     if (rc != SOC_E_NONE) {
    501         return (rc);
    502     }
    503 
    504     i = 0;
    505     while (i < sram_size) {
    506         soc_uc_mem_write(unit, sram_addr + i, 0);
    507         i += 4;
    508         if ((i & 0x0ffff) == 0) {
    509             sal_usleep(1000);
    510         }
    511     }
    512 
    513 #ifdef BCM_KATANA2_SUPPORT
    514     if (SOC_IS_KATANA2(unit)) {
    515         /* JIRA CMICD-110:  The last 48 bytes of SRAM are used to cache the values for
    516          * CMIC_BS0_ and CMIC_BS1_ registers.  So write the current register values there
    517          */
    518         uint32 rval;
    519 
    520         /* store reset values in SRAM for BS0 */
    521         uint32 sram_saved_regs = sram_addr + 0x7ffd0;            /* end of 512K memory */
    522         READ_CMIC_BS0_CONFIGr(unit, &rval);
    523         soc_uc_mem_write(unit, sram_saved_regs + 0, rval);       /* CONFIG: mode, output enables */
    524         READ_CMIC_BS0_CLK_CTRLr(unit, &rval);
    525         soc_uc_mem_write(unit, sram_saved_regs + 4, rval);       /* CLK_CTRL: enable, bitclk high/low */
    526         READ_CMIC_BS0_HEARTBEAT_CTRLr(unit, &rval);
    527         soc_uc_mem_write(unit, sram_saved_regs + 8, rval);       /* HEARBEAT_CTRL: HB enable */
    528         READ_CMIC_BS0_HEARTBEAT_DOWN_DURATIONr(unit, &rval);
    529         soc_uc_mem_write(unit, sram_saved_regs + 12, 0x3ffffff); /* HEARTBEAT_DOWN_DURATION */
    530         READ_CMIC_BS0_HEARTBEAT_UP_DURATIONr(unit, &rval);
    531         soc_uc_mem_write(unit, sram_saved_regs + 16, 0x3ffffff); /* HEARTBEAT_UP_DURATION */
    532 
    533         /* store reset values in SRAM for BS1 */
    534         sram_saved_regs += 20;
    535         READ_CMIC_BS1_CONFIGr(unit, &rval);
    536         soc_uc_mem_write(unit, sram_saved_regs + 0, rval);       /* CONFIG: mode, output enables */
    537         READ_CMIC_BS1_CLK_CTRLr(unit, &rval);
    538         soc_uc_mem_write(unit, sram_saved_regs + 4, rval);       /* CLK_CTRL: enable, bitclk high/low */
    539         READ_CMIC_BS1_HEARTBEAT_CTRLr(unit, &rval);
    540         soc_uc_mem_write(unit, sram_saved_regs + 8, rval);       /* HEARBEAT_CTRL: HB enable */
    541         READ_CMIC_BS1_HEARTBEAT_DOWN_DURATIONr(unit, &rval);
    542         soc_uc_mem_write(unit, sram_saved_regs + 12, 0x3ffffff); /* HEARTBEAT_DOWN_DURATION */
    543         READ_CMIC_BS1_HEARTBEAT_UP_DURATIONr(unit, &rval);
    544         soc_uc_mem_write(unit, sram_saved_regs + 16, 0x3ffffff); /* HEARTBEAT_UP_DURATION */
    545     }
    546 #endif
    547 
    548     return (SOC_E_NONE);
    549 }
    550 
    551 static
    552 int
    553 soc_uc_iproc_in_reset(int unit, int uC)
    554 /*
    555  * Function: 	soc_uc_mcs_in_reset
    556  * Purpose:	Return 1 if in RESET state, 0 otherwise
    557  * Parameters:	unit - unit number
    558  *		uC - microcontroller num
    559  * Returns:	1 or 0
    560  */
    561 {
    562     uint32 rst;
    563     uint32 regval;
    564 
    565     READ_IHOST_PROC_RST_A9_CORE_SOFT_RSTNr(unit, &regval);
    566     if (uC == 0) {
    567         rst = soc_reg_field_get(unit, IHOST_PROC_RST_A9_CORE_SOFT_RSTNr,
    568                                 regval, A9_CORE_0_SOFT_RSTNf);
    569     }
    570     else {
    571         rst = soc_reg_field_get(unit, IHOST_PROC_RST_A9_CORE_SOFT_RSTNr,
    572                                 regval, A9_CORE_1_SOFT_RSTNf);
    573     }
    574     return (rst == 0);
    575 }
    576 
    577 /*
    578  * Function: 	soc_uc_iproc_reset
    579  * Purpose:	Put an IPROC into reset state
    580  * Parameters:	unit - unit number
    581  *		uC - microcontroller num
    582  * Returns:	SOC_E_xxxx
    583  */
    584 static
    585 int
    586 soc_uc_iproc_reset(int unit, int uC)
    587 {
    588     int         rc;
    589     uint32      i;
    590     uint32      sram_base, sram_size;
    591     uint32      iproc_addr;
    592     uint32      regval;
    593 
    594     if (!soc_feature(unit, soc_feature_iproc)) {
    595         return (SOC_E_FAIL);
    596     }
    597 
    598     if ((SOC_REG_IS_VALID(unit, CRU_IHOST_PWRDWN_STATUSr)) &&
    599         (SOC_REG_FIELD_VALID(unit, CRU_IHOST_PWRDWN_STATUSr, LOGIC_PWRDOWN_CPU0f))) {
    600         READ_CRU_IHOST_PWRDWN_STATUSr(unit, &regval);
    601         if (soc_reg_field_get(unit, CRU_IHOST_PWRDWN_STATUSr, regval, LOGIC_PWRDOWN_CPU0f) == 1) {
    602             /* if the uC has been shut down, do nothing*/
    603             LOG_VERBOSE(BSL_LS_SOC_COMMON,
    604                         (BSL_META_U(unit,
    605                                     "The uC has been shut down, will not reset it.\n")));
    606             return (SOC_E_FAIL);
    607         }
    608     }
    609 
    610     LOG_VERBOSE(BSL_LS_SOC_COMMON,
    611                 (BSL_META_U(unit,
    612                             "iproc_reset uC %d\n"), uC));
    613 
    614     if (SOC_IS_HELIX4(unit) || SOC_IS_KATANA2(unit)) {
    615         /* Assumes booting in QSPI mode with MDIO tied high */
    616         if (uC == 0) {
    617             rc = soc_uc_sram_extents(unit, &sram_base, &sram_size);
    618             if (rc != SOC_E_NONE) {
    619                 return (rc);
    620             }
    621             iproc_addr = sram_base + sram_size - 8;
    622 
    623             /* load WFI loop into SRAM (ARM mode) */
    624             soc_cm_iproc_write(unit, iproc_addr, 0xe320f003);
    625             soc_cm_iproc_write(unit, iproc_addr + 4, 0xeafffffd);
    626 
    627             /* Update LUT to point at WFI loop */
    628             for (i = 0; i < 8; ++i) {
    629                 soc_cm_iproc_write(unit, 0xffff0400 + i*4, iproc_addr);
    630             }
    631             /* core 0 should be in WFI now */
    632         }
    633     }
    634 
    635     /* Must ensure that core is not processing an interrupt when reset.
    636      * BroadSync and PTP enable the Timesync interrupt, so disable it here
    637      * for whichever CMC / UC it has been enabled on by the FW.
    638      */
    639     soc_uc_intr_disable(unit, CMIC_CMC0_UC0_IRQ_MASK1r, TIMESYNC_INTRf);
    640     soc_uc_intr_disable(unit, CMIC_CMC1_UC0_IRQ_MASK1r, TIMESYNC_INTRf);
    641     soc_uc_intr_disable(unit, CMIC_CMC2_UC0_IRQ_MASK1r, TIMESYNC_INTRf);
    642     soc_uc_intr_disable(unit, CMIC_CMC2_UC1_IRQ_MASK1r, TIMESYNC_INTRf);
    643 
    644     /* Now safe to reset the ARM core */
    645     READ_IHOST_PROC_RST_A9_CORE_SOFT_RSTNr(unit, &regval);
    646     if (uC == 0) {
    647         soc_reg_field_set(unit, IHOST_PROC_RST_A9_CORE_SOFT_RSTNr,
    648                           &regval, A9_CORE_0_SOFT_RSTNf, 0);
    649         soc_reg_field_set(unit, IHOST_PROC_RST_A9_CORE_SOFT_RSTNr,
    650                           &regval, A9_CORE_1_SOFT_RSTNf, 0);
    651     }
    652     else {
    653         soc_reg_field_set(unit, IHOST_PROC_RST_A9_CORE_SOFT_RSTNr,
    654                           &regval, A9_CORE_1_SOFT_RSTNf, 0);
    655     }
    656     WRITE_IHOST_PROC_RST_WR_ACCESSr(unit, 0x00a5a501);
    657     WRITE_IHOST_PROC_RST_A9_CORE_SOFT_RSTNr(unit, regval);
    658     WRITE_IHOST_PROC_RST_WR_ACCESSr(unit, 0);
    659 
    660     if (soc_reg_field_valid(unit, CMIC_TIMESYNC_INTERRUPT_ENABLEr, INT_ENABLEf)) {
    661         /* Disable all timesync interrupts in CMIC if any were enabled by FW before */
    662         WRITE_CMIC_TIMESYNC_INTERRUPT_ENABLEr(unit, 0x0);
    663     }
    664 
    665     return (SOC_E_NONE);
    666 }
    667 
    668 /*
    669  * Function: 	soc_uc_iproc_l2cache_purge
    670  * Purpose:	Clean l2 cache
    671  * Parameters:	unit - unit number
    672  *		start - start address
    673  *              len - length
    674  * Returns:	SOC_E_xxx
    675  */
    676 static
    677 int
    678 soc_uc_iproc_l2cache_purge(int unit, uint32 start, uint32 len)
    679 {
    680     uint32 addr;
    681     uint32 regval;
    682     uint32 linesize = 32;
    683     uint32 pcie0;
    684     uint32 pcie1;
    685 
    686     /* Save config and disable cache */
    687     if (soc_cm_get_bus_type(unit) & SOC_DEV_BUS_ALT) {
    688         /* PAXB-1 */
    689         READ_PAXB_1_PCIE_EP_AXI_CONFIGr(unit, &pcie1);
    690         WRITE_PAXB_1_PCIE_EP_AXI_CONFIGr(unit, 0);
    691     } else {
    692         /* PAXB-0 */
    693         READ_PAXB_0_PCIE_EP_AXI_CONFIGr(unit, &pcie0);
    694         WRITE_PAXB_0_PCIE_EP_AXI_CONFIGr(unit, 0);
    695     }
    696 
    697     READ_IHOST_L2C_CACHE_IDr(unit, &regval);
    698     LOG_VERBOSE(BSL_LS_SOC_COMMON,
    699                 (BSL_META_U(unit,
    700                             "iproc_reset L2C_CACHE_ID 0x%08x\n"), regval));
    701     SOC_CMIC_UCDBG_LOG_ADD((unit, _bcmCmicUcDbgLogHostMcsLoad,
    702         "iproc_reset L2C_CACHE_ID 0x%08x\n", regval));
    703 
    704     READ_IHOST_L2C_CONTROLr(unit, &regval);
    705     if (regval & 0x01) {
    706         LOG_VERBOSE(BSL_LS_SOC_COMMON,
    707                     (BSL_META_U(unit,
    708                                 "L2 cache enabled, clean %d bytes at 0x%08x\n"),
    709                      len, start));
    710         for (addr = start; addr < (start + len); addr += linesize) {
    711             WRITE_IHOST_L2C_CLEAN_PAr(unit, addr);
    712             WRITE_IHOST_L2C_CACHE_SYNCr(unit, addr);
    713         }
    714     }
    715     else {
    716         /* L2 cache disabled, skip */
    717         LOG_VERBOSE(BSL_LS_SOC_COMMON,
    718                     (BSL_META_U(unit,
    719                                 "L2 cache disabled 0x%08x\n"), regval));
    720         SOC_CMIC_UCDBG_LOG_ADD((unit, _bcmCmicUcDbgLogHostMcsLoad,
    721             "L2 cache disabled 0x%08x\n", regval));
    722     }
    723 
    724     /* Restore config values */
    725     if (soc_cm_get_bus_type(unit) & SOC_DEV_BUS_ALT) {
    726         WRITE_PAXB_1_PCIE_EP_AXI_CONFIGr(unit, pcie1);
    727     } else {
    728         WRITE_PAXB_0_PCIE_EP_AXI_CONFIGr(unit, pcie0);
    729     }
    730 
    731     return (SOC_E_NONE);
    732 }
    733 
    734 /*
    735  * Function: 	soc_uc_iproc_preload
    736  * Purpose:	Prepare to load into iProc memory
    737  * Parameters:	unit - unit number
    738  *		uC - microcontroller num
    739  * Returns:	SOC_E_xxx
    740  */
    741 static
    742 int
    743 soc_uc_iproc_preload(int unit, int uC)
    744 {
    745     int rc;
    746     uint32 addr, size;
    747 
    748     rc = soc_uc_sram_extents(unit, &addr, &size);
    749     if (rc != SOC_E_NONE) {
    750         SOC_CMIC_UCDBG_LOG_ADD((unit, _bcmCmicUcDbgLogHostMcsLoad,
    751             "%s(): soc_uc_sram_extents failed uC: %d\n",
    752             FUNCTION_NAME(), uC));
    753         return (rc);
    754     }
    755     return soc_uc_iproc_l2cache_purge(unit, addr, size);
    756 }
    757 
    758 /*
    759  * Function: 	soc_uc_iproc_start
    760  * Purpose:	Start IPROC execution
    761  * Parameters:	unit - unit number
    762  *		uC - microcontroller num
    763  * Returns:	SOC_E_xxx
    764  */
    765 static
    766 int
    767 soc_uc_iproc_start(int unit, int uC, uint32 iproc_address)
    768 {
    769     uint32      i;
    770     uint32      regval;
    771     uint32 iproc_addr = iproc_address + (16*1024); /* first 16K is MMU L1 table */
    772 
    773     if (!soc_feature(unit, soc_feature_iproc)) {
    774         return (SOC_E_FAIL);
    775     }
    776 
    777     LOG_VERBOSE(BSL_LS_SOC_COMMON,
    778                 (BSL_META_U(unit,
    779                             "iproc_start uC %d addr 0x%08x\n"), uC, iproc_addr));
    780     SOC_CMIC_UCDBG_LOG_ADD((unit, _bcmCmicUcDbgLogHostMcsLoad,
    781         "iproc_start uC %d addr 0x%08x\n", uC, iproc_addr));
    782 
    783     READ_IHOST_PROC_RST_A9_CORE_SOFT_RSTNr(unit, &regval);
    784     if (uC == 0) {
    785         /* Update LUT to point at SRAM */
    786         for (i = 0; i < 8; ++i) {
    787 #if defined(BCM_HURRICANE3_SUPPORT)
    788             if (SOC_IS_HURRICANE3(unit)) {
    789                 soc_cm_iproc_write(unit, 0xffff0fc0 + i*4, iproc_addr);
    790             } else
    791 #endif /* BCM_HURRICANE3_SUPPORT */
    792             soc_cm_iproc_write(unit, 0xffff0400 + i*4, iproc_addr);
    793         }
    794         /* Release reset on core 0 */
    795         soc_reg_field_set(unit, IHOST_PROC_RST_A9_CORE_SOFT_RSTNr,
    796                           &regval, A9_CORE_0_SOFT_RSTNf, 1);
    797     }
    798     else {
    799         /* Update LUT to point at SRAM */
    800         soc_cm_iproc_write(unit, CORE1_LUT_ADDR, iproc_addr);
    801         /* Release reset on core 1 */
    802         soc_reg_field_set(unit, IHOST_PROC_RST_A9_CORE_SOFT_RSTNr,
    803                           &regval, A9_CORE_1_SOFT_RSTNf, 1);
    804     }
    805     /* Release reset */
    806     WRITE_IHOST_PROC_RST_WR_ACCESSr(unit, 0x00a5a501);
    807     WRITE_IHOST_PROC_RST_A9_CORE_SOFT_RSTNr(unit, regval);
    808     WRITE_IHOST_PROC_RST_WR_ACCESSr(unit, 0);
    809 
    810     if (uC == 1) {
    811         /* Wait 100ms for core 1 to set up LUT */
    812         sal_usleep(100 * 1000);
    813 
    814         /* Update LUT to point at SRAM */
    815         soc_cm_iproc_write(unit, CORE1_LUT_ADDR, iproc_addr);
    816     }
    817     return (SOC_E_NONE);
    818 }
    819 
    820 #endif /* BCM_IPROC_SUPPORT */
    821 
    822 #ifdef BCM_UC_MHOST_SUPPORT
    823 
    824 /*
    825  * Function: 	soc_uc_mhost_init
    826  * Purpose:	Initialize the UC
    827  * Parameters:	unit - unit number
    828  * Returns:	SOC_E_xxx
    829  */
    830 static int
    831 soc_uc_mhost_init(int unit)
    832 {
    833 #ifdef BCM_IPROC_DDR_SUPPORT
    834     if (soc_feature(unit, soc_feature_iproc_ddr)) {
    835         soc_iproc_ddr_init(unit);
    836     }
    837 #endif /* BCM_IPROC_DDR_SUPPORT */
    838 
    839     return (SOC_E_NONE);
    840 }
    841 
    842 /*
    843  * Function: 	soc_uc_mhost_reset
    844  * Purpose:	Put the UC into reset state
    845  * Parameters:	unit - unit number
    846  *		uC - microcontroller num
    847  * Returns:	SOC_E_xxxx
    848  */
    849 static int
    850 soc_uc_mhost_reset(int unit, int uC)
    851 {
    852 #if defined(BCM_JERICHO_SUPPORT)
    853     uint32 idm_mrst_control;
    854     uint32 idm_srst_control;
    855 #endif
    856 
    857 #if defined(BCM_ESW_SUPPORT) || defined(BCM_QUX_SUPPORT) || \
    858     defined(BCM_QAX_SUPPORT) ||defined(BCM_JERICHO_2_SUPPORT) ||\
    859     defined(BCM_JERICHO_SUPPORT)
    860     uint32 rst_control;
    861 #endif
    862 
    863 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) || defined(BCM_MAVERICK2_SUPPORT)
    864     uint32 strap_status;
    865 #endif
    866 
    867 #if defined(BCM_SABER2_SUPPORT) || defined(BCM_JERICHO_SUPPORT)
    868     uint32 rvp = 0;
    869     uint32 retry_cnt;
    870     uint32 u_sec = 100;
    871 #endif
    872 
    873 #ifdef BCM_SABER2_SUPPORT
    874     uint16 dev_id;
    875     uint8  rev_id;
    876 #endif
    877 
    878     if (uC < 0 || uC >= SOC_INFO(unit).num_ucs) {
    879         return SOC_E_UNAVAIL;
    880     }
    881 
    882     if (SOC_CONTROL(unit)->uc_hostram_buf[uC] != NULL) {
    883         soc_cm_sfree(unit, SOC_CONTROL(unit)->uc_hostram_buf[uC]);
    884         SOC_CONTROL(unit)->uc_hostram_buf[uC] = NULL;
    885     }
    886 
    887 #ifdef BCM_SABER2_SUPPORT
    888     /* Dagger2 support 2xR5 Embedded processors
    889      * mHost 0 was disable and mHost 1 and 2 are valid core
    890      * mHost 0 is inavlid so ignore mHost 0
    891      */
    892     soc_cm_get_id(unit, &dev_id, &rev_id);
    893     if (SOC_IS_SABER2(unit) && (dev_id == BCM56233_DEVICE_ID) && (uC == 1)) {
    894         return (SOC_E_NONE);
    895     }
    896     /* Lock h/w semaphores used to synchronize uC1 and uC2 */
    897     if (SOC_IS_SABER2(unit) && !SOC_IS_METROLITE(unit) && uC > 0) {
    898         /* Lock h/w Sem16 used for schan access */
    899         retry_cnt = 10000;
    900         rvp = 0;
    901         while (retry_cnt--) {
    902             READ_CMIC_SEMAPHORE_16r(unit, &rvp);
    903             if(rvp) {
    904                 /* semaphore locked */
    905                 break;
    906             }
    907             sal_usleep(u_sec);
    908         }
    909         if (!rvp) {
    910             return SOC_E_BUSY;
    911         }
    912 
    913         /* Lock h/w Sem17, used for CCMDMA access */
    914         retry_cnt = 10000; rvp=0;
    915         while(retry_cnt--) {
    916             READ_CMIC_SEMAPHORE_17r(unit, &rvp);
    917             if(rvp) {
    918                 /* semaphore locked */
    919                 break;
    920             }
    921             sal_usleep(u_sec);
    922         }
    923         if (!rvp) {
    924             /* Unlock the semaphore 16 */
    925             WRITE_CMIC_SEMAPHORE_16r(unit, 0);
    926             return SOC_E_BUSY;
    927         }
    928     }
    929 #endif
    930 
    931     /* Must ensure that core-1 is not processing an interrupt when reset.
    932      * BroadSync and PTP enable the Timesync interrupt, so disable it
    933      * here for whichever CMC / UC it has been enabled on by the FW.
    934      */
    935     if ((1 == uC)
    936 #ifdef BCM_TRIDENT3_SUPPORT
    937         && (!SOC_IS_TRIDENT3(unit))
    938 #endif
    939 #ifdef BCM_JERICHO_2_SUPPORT
    940         && (!SOC_IS_JERICHO_2_ONLY(unit))
    941 #endif
    942     ) {
    943         soc_uc_intr_disable(unit, CMIC_CMC0_UC0_IRQ_MASK1r,
    944                                 TIMESYNC_INTRf);
    945         soc_uc_intr_disable(unit, CMIC_CMC1_UC0_IRQ_MASK1r,
    946                                 TIMESYNC_INTRf);
    947         soc_uc_intr_disable(unit, CMIC_CMC2_UC0_IRQ_MASK1r,
    948                                 TIMESYNC_INTRf);
    949         soc_uc_intr_disable(unit, CMIC_CMC2_UC1_IRQ_MASK1r,
    950                                 TIMESYNC_INTRf);
    951 
    952         if (soc_reg_field_valid(unit, CMIC_TIMESYNC_INTERRUPT_ENABLEr,
    953                     INT_ENABLEf)) {
    954             /* Disable all timesync interrupts in CMIC if any were
    955              * enabled by FW before
    956              */
    957             WRITE_CMIC_TIMESYNC_INTERRUPT_ENABLEr(unit, 0x0);
    958 
    959             /* Give core time to complete processing an existing
    960              * interrupt if any
    961              */
    962             sal_usleep(5000);
    963         }
    964     }
    965 
    966 #if defined(BCM_JERICHO_SUPPORT)
    967     if (SOC_IS_JERICHO(unit) && (uC == 0)) {
    968         /* Handshaking with uC to stop CMIC activity on uC0 */
    969         retry_cnt = 1000; rvp=0;
    970         while(retry_cnt--) {
    971             rvp = soc_getstatus_bcm88x7x(unit, uC);
    972             if(!rvp) {
    973                 /* uC is safe to reset */
    974                 break;
    975             }
    976             sal_usleep(u_sec);
    977         }
    978 
    979         if (rvp) {
    980             soc_restore_bcm88x7x(unit, uC);
    981         }
    982     }
    983 #endif
    984 
    985 #if defined(BCM_JERICHO_SUPPORT)
    986     if (SOC_IS_JERICHO(unit) && !SOC_IS_QUX(unit) && !SOC_IS_QAX(unit) && !SOC_IS_QMX(unit)) {
    987         /* Take the processor in and out of reset but halted */
    988         if (uC == 0) {
    989             READ_MHOST_M0_IDM_M_IDM_RESET_CONTROLr(unit, &idm_mrst_control);
    990             READ_MHOST_S0_IDM_S_IDM_RESET_CONTROLr(unit, &idm_srst_control);
    991         } else if (uC == 1) {
    992             READ_MHOST_M1_IDM_M_IDM_RESET_CONTROLr(unit, &idm_mrst_control);
    993             READ_MHOST_S1_IDM_S_IDM_RESET_CONTROLr(unit, &idm_srst_control);
    994         } else {
    995             assert(0);
    996             return SOC_E_UNAVAIL;
    997         }
    998 
    999         soc_reg_field_set(unit, MHOST_M0_IDM_M_IDM_RESET_CONTROLr, &idm_mrst_control,
   1000                           RESETf, 1);
   1001         soc_reg_field_set(unit, MHOST_S0_IDM_S_IDM_RESET_CONTROLr, &idm_srst_control,
   1002                           RESETf, 1);
   1003 
   1004         if (uC == 0) {
   1005             WRITE_MHOST_M0_IDM_M_IDM_RESET_CONTROLr(unit, idm_mrst_control);
   1006             WRITE_MHOST_S0_IDM_S_IDM_RESET_CONTROLr(unit, idm_srst_control);
   1007         } else if (uC == 1) {
   1008             WRITE_MHOST_M1_IDM_M_IDM_RESET_CONTROLr(unit, idm_mrst_control);
   1009             WRITE_MHOST_S1_IDM_S_IDM_RESET_CONTROLr(unit, idm_srst_control);
   1010         }
   1011 
   1012         soc_reg_field_set(unit, MHOST_M0_IDM_M_IDM_RESET_CONTROLr, &idm_mrst_control,
   1013                           RESETf, 0);
   1014         soc_reg_field_set(unit, MHOST_S0_IDM_S_IDM_RESET_CONTROLr, &idm_srst_control,
   1015                           RESETf, 0);
   1016 
   1017         if (uC == 0) {
   1018             WRITE_MHOST_M0_IDM_M_IDM_RESET_CONTROLr(unit, idm_mrst_control);
   1019             WRITE_MHOST_S0_IDM_S_IDM_RESET_CONTROLr(unit, idm_srst_control);
   1020         } else if (uC == 1) {
   1021             WRITE_MHOST_M1_IDM_M_IDM_RESET_CONTROLr(unit, idm_mrst_control);
   1022             WRITE_MHOST_S1_IDM_S_IDM_RESET_CONTROLr(unit, idm_srst_control);
   1023         }
   1024         return SOC_E_NONE;
   1025     }
   1026 #endif
   1027 
   1028 #if defined(BCM_ESW_SUPPORT) || defined(BCM_QUX_SUPPORT) || defined(BCM_QAX_SUPPORT) || \
   1029     defined(BCM_JERICHO_SUPPORT) || defined(BCM_JERICHO_2_SUPPORT)
   1030     /* Take the processor in and out of reset but halted */
   1031 
   1032     if (SOC_IS_MONTEREY(unit) && (uC == 2)) {
   1033         /* Monterey, with uc:2 is ARM-M7 */
   1034         READ_M7SS_CONFIGr(unit, &rst_control);
   1035         soc_reg_field_set(unit, M7SS_CONFIGr, &rst_control,
   1036                       CPUWAITf, 1);
   1037         WRITE_M7SS_CONFIGr(unit, rst_control);
   1038 
   1039         READ_M7SS_CTRLr(unit, &rst_control);
   1040         soc_reg_field_set(unit, M7SS_CTRLr, &rst_control,
   1041                       POWERUP_RESETf, 1);
   1042         soc_reg_field_set(unit, M7SS_CTRLr, &rst_control,
   1043                       SYS_RESETf, 1);
   1044         WRITE_M7SS_CTRLr(unit, rst_control);
   1045 
   1046         sal_usleep(1000);
   1047 
   1048         READ_M7SS_CTRLr(unit, &rst_control);
   1049         soc_reg_field_set(unit, M7SS_CTRLr, &rst_control,
   1050                       POWERUP_RESETf, 0);
   1051         soc_reg_field_set(unit, M7SS_CTRLr, &rst_control,
   1052                       SYS_RESETf, 0);
   1053         WRITE_M7SS_CTRLr(unit, rst_control);
   1054         return (SOC_E_NONE);
   1055     }
   1056 
   1057     if (uC == 0) {
   1058         READ_MHOST_0_CR5_RST_CTRLr(unit, &rst_control);
   1059     } else if (uC == 1) {
   1060         if (SOC_INFO(unit).num_ucs == 3 && !SOC_IS_MONTEREY(unit)) {
   1061             READ_RTS_MHOST_1_CR5_RST_CTRLr(unit, &rst_control);
   1062         } else {
   1063             READ_MHOST_1_CR5_RST_CTRLr(unit, &rst_control);
   1064         }
   1065     } else if (uC == 2) {
   1066         READ_RTS_MHOST_2_CR5_RST_CTRLr(unit, &rst_control);
   1067     } else {
   1068         assert(0);
   1069         return SOC_E_UNAVAIL;
   1070     }
   1071 
   1072     soc_reg_field_set(unit, MHOST_0_CR5_RST_CTRLr, &rst_control,
   1073                       SYS_PORESET_Nf, 0);
   1074     soc_reg_field_set(unit, MHOST_0_CR5_RST_CTRLr, &rst_control,
   1075                       RESET_Nf, 0);
   1076     soc_reg_field_set(unit, MHOST_0_CR5_RST_CTRLr, &rst_control,
   1077                       DBG_RESET_Nf, 0);
   1078     soc_reg_field_set(unit, MHOST_0_CR5_RST_CTRLr, &rst_control,
   1079                       PRESET_DBG_Nf, 0);
   1080     soc_reg_field_set(unit, MHOST_0_CR5_RST_CTRLr, &rst_control,
   1081                       CPU_HALT_Nf, 0);
   1082 
   1083     if (uC == 0) {
   1084         WRITE_MHOST_0_CR5_RST_CTRLr(unit, rst_control);
   1085     } else if (uC == 1) {
   1086         if (SOC_INFO(unit).num_ucs == 3 && !SOC_IS_MONTEREY(unit)) {
   1087             WRITE_RTS_MHOST_1_CR5_RST_CTRLr(unit, rst_control);
   1088         } else {
   1089             WRITE_MHOST_1_CR5_RST_CTRLr(unit, rst_control);
   1090         }
   1091     } else if (uC == 2) {
   1092         WRITE_RTS_MHOST_2_CR5_RST_CTRLr(unit, rst_control);
   1093     } else {
   1094         assert(0);
   1095     }
   1096 
   1097     soc_reg_field_set(unit, MHOST_0_CR5_RST_CTRLr, &rst_control,
   1098                       SYS_PORESET_Nf, 1);
   1099     soc_reg_field_set(unit, MHOST_0_CR5_RST_CTRLr, &rst_control,
   1100                       RESET_Nf, 1);
   1101     soc_reg_field_set(unit, MHOST_0_CR5_RST_CTRLr, &rst_control,
   1102                       DBG_RESET_Nf, 1);
   1103     soc_reg_field_set(unit, MHOST_0_CR5_RST_CTRLr, &rst_control,
   1104                       PRESET_DBG_Nf, 1);
   1105 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) || defined(BCM_MAVERICK2_SUPPORT)
   1106     if ((uC == 0) &&
   1107         (SOC_IS_TRIDENT3(unit) || SOC_IS_TOMAHAWK3(unit) || SOC_IS_MAVERICK2(unit))) {
   1108         /* Check if the processor boots into Flash Firmware */
   1109         READ_MHOST_0_MHOST_STRAP_STATUSr(unit,&strap_status);
   1110         if (strap_status != 0) {
   1111             /* let it unhalt for a while until the
   1112              * Flash FW finishes its work and gets into the penholder loop
   1113              */
   1114             soc_reg_field_set(unit, MHOST_0_CR5_RST_CTRLr, &rst_control,
   1115                               CPU_HALT_Nf, 1);
   1116             WRITE_MHOST_0_CR5_RST_CTRLr(unit, rst_control);
   1117             sal_msleep(20);
   1118             soc_reg_field_set(unit, MHOST_0_CR5_RST_CTRLr, &rst_control,
   1119                               CPU_HALT_Nf, 0);
   1120         }
   1121     }
   1122 #endif
   1123 
   1124     if (uC == 0) {
   1125         WRITE_MHOST_0_CR5_RST_CTRLr(unit, rst_control);
   1126     } else if (uC == 1) {
   1127         if (SOC_INFO(unit).num_ucs == 3 && !SOC_IS_MONTEREY(unit)) {
   1128             WRITE_RTS_MHOST_1_CR5_RST_CTRLr(unit, rst_control);
   1129         } else {
   1130             WRITE_MHOST_1_CR5_RST_CTRLr(unit, rst_control);
   1131         }
   1132     } else if (uC == 2) {
   1133         WRITE_RTS_MHOST_2_CR5_RST_CTRLr(unit, rst_control);
   1134     } else {
   1135         assert(0);
   1136     }
   1137 #endif
   1138 
   1139 #if defined(BCM_QAX_SUPPORT)
   1140     if (SOC_IS_QAX(unit))
   1141     {
   1142         if (uC == 0) {
   1143             WRITE_CHIPCOMMONG_UART0_UART_SRRr(unit,1);
   1144         } else if (uC == 1) {
   1145             WRITE_CHIPCOMMONG_UART1_UART_SRRr(unit,1);
   1146         }
   1147     }
   1148 #endif
   1149 
   1150 #ifdef BCM_SABER2_SUPPORT
   1151     if (SOC_IS_SABER2(unit) && !SOC_IS_METROLITE(unit) && uC > 0) {
   1152         /* Unlock the semaphores sem17 and sem16 */
   1153         WRITE_CMIC_SEMAPHORE_17r(unit, 0);
   1154         WRITE_CMIC_SEMAPHORE_16r(unit, 0);
   1155     }
   1156 #endif
   1157 
   1158     return (SOC_E_NONE);
   1159 }
   1160 
   1161 /*
   1162  * Function: 	soc_uc_mhost_in_reset
   1163  * Purpose:	Return 1 if in RESET state, 0 otherwise
   1164  * Parameters:	unit - unit number
   1165  *		uC - microcontroller num
   1166  * Returns:	1 or 0
   1167  */
   1168 static int
   1169 soc_uc_mhost_in_reset(int unit, int uC)
   1170 {
   1171     uint32 rst_control, halt;
   1172     uint16 dev_id;
   1173     uint8  rev_id;
   1174 
   1175     if (uC < 0 || uC >= SOC_INFO(unit).num_ucs) {
   1176         return 1; /* Actually it means no such uC */
   1177     }
   1178 
   1179     /* Dagger2 support 2xR5 Embedded processors
   1180      * mHost 0 was disable and mHost 1 and 2 are valid core
   1181      * mHost 0 is inavlid so ignore mHost 0
   1182      */
   1183     soc_cm_get_id(unit, &dev_id, &rev_id);
   1184     if ((dev_id == BCM56233_DEVICE_ID) && (uC == 1)) {
   1185         return (1);
   1186     }
   1187 
   1188     /* Monterey, uc:2 is M7 */
   1189     if (SOC_IS_MONTEREY(unit) && (uC == 2)) {
   1190         READ_M7SS_CONFIGr(unit, &rst_control);
   1191         halt = !soc_reg_field_get(
   1192                         unit, M7SS_CONFIGr, rst_control, CPUWAITf);
   1193         return halt;
   1194     }
   1195 
   1196     if (uC == 0) {
   1197         READ_MHOST_0_CR5_RST_CTRLr(unit, &rst_control);
   1198     } else if (uC == 1) {
   1199         if (SOC_INFO(unit).num_ucs == 3 && !SOC_IS_MONTEREY(unit)) {
   1200             READ_RTS_MHOST_1_CR5_RST_CTRLr(unit, &rst_control);
   1201         } else {
   1202             READ_MHOST_1_CR5_RST_CTRLr(unit, &rst_control);
   1203         }
   1204     } else if (uC == 2) {
   1205         READ_RTS_MHOST_2_CR5_RST_CTRLr(unit, &rst_control);
   1206     } else {
   1207         assert(0);
   1208         return SOC_E_UNAVAIL;
   1209     }
   1210 
   1211     halt = soc_reg_field_get(
   1212                 unit, MHOST_0_CR5_RST_CTRLr, rst_control, CPU_HALT_Nf);
   1213 
   1214     return (halt == 0);
   1215 }
   1216 
   1217 static void *_soc_uc_mhost_hostram_alloc(int unit, int uC, int size)
   1218 {
   1219     uint32 *buf1 = NULL, *buf2 = NULL, *ret = NULL;
   1220     sal_paddr_t paddr = 0;
   1221     uint32 addr_lo = 0, eaddr_lo=0;
   1222 
   1223     buf1 = soc_cm_salloc(unit, size, "hostRAM buffer 1");
   1224     if (buf1 != NULL) {
   1225         paddr = soc_cm_l2p(unit, buf1);
   1226         addr_lo = PTR_TO_INT(paddr);
   1227         eaddr_lo = addr_lo + size;
   1228 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TOMAHAWK2_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) || \
   1229     defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_MAVERICK2_SUPPORT)
   1230         if (SOC_IS_TRIDENT3(unit) || SOC_IS_TOMAHAWK3(unit) || SOC_IS_MAVERICK2(unit)) {
   1231             if ((addr_lo & 0xff) == (eaddr_lo & 0xff)) {
   1232                 /* Falls in the same 16M page */
   1233                 ret = buf1;
   1234             }
   1235         } else if(SOC_IS_TOMAHAWK(unit) || SOC_IS_TOMAHAWK2(unit)) {
   1236             if ((addr_lo & 0xf) == (eaddr_lo & 0xf)) {
   1237                 /* Falls in the same 256M page */
   1238                 ret = buf1;
   1239             }
   1240         }
   1241 #endif
   1242     }
   1243 
   1244     if (ret == NULL) {
   1245         /* Buf1 was not usable */
   1246         /* Free it *after* allocating a new buffer */
   1247         buf2 = soc_cm_salloc(unit, size, "hostRAM buffer 2");
   1248         if (buf1 != NULL) {
   1249             soc_cm_sfree(unit, buf1);
   1250         }
   1251     }
   1252 
   1253     if (buf2 != NULL) {
   1254         paddr = soc_cm_l2p(unit, buf2);
   1255         addr_lo = PTR_TO_INT(paddr);
   1256         eaddr_lo = addr_lo + size;
   1257 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TOMAHAWK2_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) || \
   1258     defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_MAVERICK2_SUPPORT)
   1259         if (SOC_IS_TRIDENT3(unit) || SOC_IS_TOMAHAWK3(unit) || SOC_IS_MAVERICK2(unit)) {
   1260             if ((addr_lo & 0xff) == (eaddr_lo & 0xff)) {
   1261                 /* Falls in the same 16M page */
   1262                 ret = buf2;
   1263             }
   1264         } else if(SOC_IS_TOMAHAWK(unit) || SOC_IS_TOMAHAWK2(unit)) {
   1265             if ((addr_lo & 0xf) == (eaddr_lo & 0xf)) {
   1266                 /* Falls in the same 256M page */
   1267                 ret = buf2;
   1268             }
   1269         }
   1270 #endif
   1271     }
   1272 
   1273     if (ret == NULL) {
   1274         /* Buf2 was also not usable. */
   1275         if (buf2 != NULL) {
   1276             soc_cm_sfree(unit, buf2);
   1277         }
   1278     }
   1279 
   1280     COMPILER_REFERENCE(addr_lo);
   1281     COMPILER_REFERENCE(eaddr_lo);
   1282     COMPILER_REFERENCE(paddr);
   1283 
   1284     return ret;
   1285 }
   1286 
   1287 /*
   1288  * Function:    soc_uc_mhost_prestart_config
   1289  * Purpose: Configure the uC before starting
   1290  * Parameters:  unit - unit number
   1291  *      uC - microcontroller num
   1292  * Returns: SOC_E_xxx
   1293  */
   1294 static int
   1295 soc_uc_mhost_prestart_config(int unit, int uC)
   1296 {
   1297     uint32 config_ver, addr, val;
   1298     sal_paddr_t paddr = 0;
   1299     uint32 size = 0;
   1300     soc_control_t *soc = SOC_CONTROL(unit);
   1301 
   1302     if (soc == NULL) {
   1303         return SOC_E_FAIL;
   1304     }
   1305 
   1306     addr = soc_uc_addr_to_pcie(unit, uC, 0x80);
   1307     if (soc_uc_mem_read(unit, addr) != 0xbadc0de1) {
   1308         cli_out("FW not configurable\n");
   1309         return SOC_E_NONE;
   1310     }
   1311     addr = soc_uc_addr_to_pcie(unit, uC, 0x84);
   1312     config_ver = soc_uc_mem_read(unit, addr);
   1313 
   1314     /* Config uC Num @ 0x88 */
   1315     addr = soc_uc_addr_to_pcie(unit, uC, 0x88);
   1316     soc_uc_mem_write(unit, addr, uC);
   1317 
   1318     /* Config hostRAM @ 0x8C-0x90 and its size @ 0x94 */
   1319     if (config_ver >= 1) {
   1320         size = (2*1024*1024); /* HostRAM Fixed 2MB for now */
   1321         soc->uc_hostram_buf[uC] = _soc_uc_mhost_hostram_alloc(unit, uC, size);
   1322         paddr = (soc->uc_hostram_buf[uC] != NULL ) ?
   1323                  soc_cm_l2p(unit, soc->uc_hostram_buf[uC]) : 0;
   1324         addr = soc_uc_addr_to_pcie(unit, uC, 0x8C);
   1325         val = PTR_HI_TO_INT(paddr);
   1326         soc_uc_mem_write(unit, addr, val);
   1327         addr = soc_uc_addr_to_pcie(unit, uC, 0x90);
   1328         val = PTR_TO_INT(paddr);
   1329         soc_uc_mem_write(unit, addr, val);
   1330         addr = soc_uc_addr_to_pcie(unit, uC, 0x94);
   1331         val = size;
   1332         soc_uc_mem_write(unit, addr, val);
   1333     }
   1334     return SOC_E_NONE;
   1335 }
   1336 
   1337 /*
   1338  * Function: 	soc_uc_mhost_start
   1339  * Purpose:	Start UC execution
   1340  * Parameters:	unit - unit number
   1341  *		uC - microcontroller num
   1342  *              addr - address to start at
   1343  * Returns:	SOC_E_xxx
   1344  */
   1345 static int
   1346 soc_uc_mhost_start(int unit, int uC, uint32 addr)
   1347 {
   1348     uint32      rst_control;
   1349     uint16      dev_id;
   1350     uint8       rev_id;
   1351 
   1352     if (uC < 0 || uC >= SOC_INFO(unit).num_ucs) {
   1353         return SOC_E_UNAVAIL;
   1354     }
   1355 
   1356     /* Dagger2 support 2xR5 Embedded processors
   1357      * mHost 0 was disable and mHost 1 and 2 are valid core
   1358      * mHost 0 is inavlid so ignore mHost 0
   1359      */
   1360     soc_cm_get_id(unit, &dev_id, &rev_id);
   1361     if ((dev_id == BCM56233_DEVICE_ID) && (uC == 1)) {
   1362         return (SOC_E_NONE);
   1363     }
   1364 
   1365     /* Monterey, uc:2 is ARM-M7 */
   1366     if (SOC_IS_MONTEREY(unit) && (uC == 2)) {
   1367         READ_M7SS_CONFIGr(unit, &rst_control);
   1368         soc_reg_field_set(unit, M7SS_CONFIGr, &rst_control,
   1369                           CPUWAITf, 0);
   1370         WRITE_M7SS_CONFIGr(unit, rst_control);
   1371         return (SOC_E_NONE);
   1372     }
   1373 
   1374     soc_uc_mhost_prestart_config(unit, uC);
   1375 
   1376     if (uC == 0) {
   1377         READ_MHOST_0_CR5_RST_CTRLr(unit, &rst_control);
   1378     } else if (uC == 1) {
   1379         if (SOC_INFO(unit).num_ucs == 3 && !SOC_IS_MONTEREY(unit)) {
   1380             READ_RTS_MHOST_1_CR5_RST_CTRLr(unit, &rst_control);
   1381         } else {
   1382             READ_MHOST_1_CR5_RST_CTRLr(unit, &rst_control);
   1383         }
   1384     } else if (uC == 2) {
   1385         READ_RTS_MHOST_2_CR5_RST_CTRLr(unit, &rst_control);
   1386     } else {
   1387         assert(0);
   1388         return SOC_E_UNAVAIL;
   1389     }
   1390 
   1391     soc_reg_field_set(unit, MHOST_0_CR5_RST_CTRLr, &rst_control,
   1392                       CPU_HALT_Nf, 1);
   1393 
   1394     if (uC == 0) {
   1395         WRITE_MHOST_0_CR5_RST_CTRLr(unit, rst_control);
   1396 #if defined(BCM_TOMAHAWK2_SUPPORT)
   1397         if ((BCM56970_DEVICE_ID & 0xFFF0) == (dev_id & 0xFFF0)){
   1398             soc_cm_iproc_write(unit, 0xffff0fe8, 0);
   1399         }
   1400 #endif
   1401 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) || defined(BCM_MAVERICK2_SUPPORT)
   1402         if (SOC_IS_TRIDENT3(unit) || SOC_IS_TOMAHAWK3(unit) || SOC_IS_MAVERICK2(unit)) {
   1403             soc_cm_iproc_write(unit, 0xffff0fe8, 0); /* PenHolder Loc */
   1404         }
   1405 #endif
   1406 #if defined(BCM_JERICHO_2_SUPPORT)
   1407         if (SOC_IS_JERICHO_2_ONLY(unit)) {
   1408             sal_msleep(10);
   1409             soc_cm_iproc_write(unit, 0xffff0fe8, 0); /* PenHolder Loc */
   1410         }
   1411 #endif
   1412 
   1413     } else if (uC == 1) {
   1414         if (SOC_INFO(unit).num_ucs == 3 && !SOC_IS_MONTEREY(unit)) {
   1415             WRITE_RTS_MHOST_1_CR5_RST_CTRLr(unit, rst_control);
   1416         } else {
   1417             WRITE_MHOST_1_CR5_RST_CTRLr(unit, rst_control);
   1418         }
   1419     } else if (uC == 2) {
   1420         WRITE_RTS_MHOST_2_CR5_RST_CTRLr(unit, rst_control);
   1421     } else {
   1422         assert(0);
   1423     }
   1424 
   1425     return (SOC_E_NONE);
   1426 }
   1427 
   1428 /*
   1429  * Function: 	soc_uc_mhost_preload
   1430  * Purpose:	Prepare to load into UC memory
   1431  * Parameters:	unit - unit number
   1432  *		uC - microcontroller num
   1433  * Returns:	SOC_E_xxx
   1434  */
   1435 static int
   1436 soc_uc_mhost_preload(int unit, int uC)
   1437 {
   1438     COMPILER_REFERENCE(unit);
   1439     COMPILER_REFERENCE(uC);
   1440     return (SOC_E_NONE);
   1441 }
   1442 
   1443 #endif /* BCM_UC_MHOST_SUPPORT */
   1444 
   1445 int
   1446 soc_uc_init(int unit)
   1447 /*
   1448  * Function: 	soc_uc_init
   1449  * Purpose:	Initialize the CMICm MCS
   1450  * Parameters:	unit - unit number
   1451  * Returns:	SOC_E_xxx
   1452  */
   1453 {
   1454     if (!soc_feature(unit, soc_feature_uc)) {
   1455         return (SOC_E_FAIL);
   1456     }
   1457 #if defined(BCM_UC_MHOST_SUPPORT)
   1458     if (soc_feature(unit, soc_feature_uc_mhost)) {
   1459         return soc_uc_mhost_init(unit);
   1460     }
   1461 #endif /* BCM_UC_MHOST_SUPPORT */
   1462 #ifdef BCM_IPROC_SUPPORT
   1463     if (soc_feature(unit, soc_feature_iproc)) {
   1464         return soc_uc_iproc_init(unit);
   1465     }
   1466 #endif /* BCM_IPROC_SUPPORT */
   1467 #ifdef BCM_CMICM_SUPPORT
   1468     if (soc_feature(unit, soc_feature_mcs)) {
   1469         return soc_uc_mcs_init(unit);
   1470     }
   1471 #endif /* BCM_CMICM_SUPPORT */
   1472     return (SOC_E_FAIL);
   1473 }
   1474 
   1475 int
   1476 soc_uc_in_reset(int unit, int uC)
   1477 /*
   1478  * Function: 	soc_uc_in_reset
   1479  * Purpose:	Return reset state of core
   1480  * Parameters:	unit - unit number
   1481  *              uC - core number
   1482  * Returns:	0 or 1
   1483  */
   1484 {
   1485     if (!soc_feature(unit, soc_feature_uc)) {
   1486         return (SOC_E_FAIL);
   1487     }
   1488 #if defined(BCM_UC_MHOST_SUPPORT)
   1489     if (soc_feature(unit, soc_feature_uc_mhost)) {
   1490         return soc_uc_mhost_in_reset(unit, uC);
   1491     }
   1492 #endif /* BCM_UC_MHOST_SUPPORT */
   1493 #ifdef BCM_IPROC_SUPPORT
   1494     if (soc_feature(unit, soc_feature_iproc)) {
   1495         return soc_uc_iproc_in_reset(unit, uC);
   1496     }
   1497 #endif /* BCM_IPROC_SUPPORT */
   1498 #ifdef BCM_CMICM_SUPPORT
   1499     if (soc_feature(unit, soc_feature_mcs)) {
   1500         return soc_uc_mcs_in_reset(unit, uC);
   1501     }
   1502 #endif /* BCM_CMICM_SUPPORT */
   1503     return 1;
   1504 }
   1505 
   1506 int
   1507 soc_uc_load(int unit, int uC, uint32 addr, int len, unsigned char *data)
   1508 /*
   1509  * Function: 	soc_uc_load
   1510  * Purpose:	Load a chunk into MCS memory
   1511  * Parameters:	unit - unit number
   1512  *		uC - microcontroller num
   1513  *              addr - Address of chunk from MCS perspective
   1514  *              len - Length of chunk to load in bytes
   1515  *              data - Pointer to data to load
   1516  * Returns:	SOC_E_xxx
   1517  */
   1518 {
   1519     int i;
   1520     uint32 wdata;
   1521     int rc = SOC_E_NONE;        /* Be optimistic */
   1522     uint16 dev_id;
   1523     uint8 rev_id;
   1524 
   1525     soc_cm_get_id(unit, &dev_id, &rev_id);
   1526 
   1527     /* Skip loading of Firmware for Core-1 in Dagger2 */
   1528     if ((dev_id == BCM56233_DEVICE_ID) && (uC == 1)) {
   1529         return SOC_E_NONE;
   1530     }
   1531     if (!soc_feature(unit, soc_feature_uc)) {
   1532         return (SOC_E_FAIL);
   1533     }
   1534 
   1535     /* Convert the UC-centric address to a PCI address */
   1536     addr = soc_uc_addr_to_pcie(unit, uC, addr);
   1537 
   1538     for (i = 0; i < len; i += 4, addr += 4) {
   1539 #ifndef LE_HOST
   1540         /* We swap the bytes here for the LE ARMs. */
   1541         wdata = _shr_swap32(*((uint32 *) &data[i]));
   1542 #else
   1543         wdata = *((uint32 *) &data[i]);
   1544 #endif
   1545         rc = soc_uc_mem_write(unit, addr, wdata);
   1546         if (rc != SOC_E_NONE) {
   1547             SOC_CMIC_UCDBG_LOG_ADD((unit, _bcmCmicUcDbgLogHostMcsLoad,
   1548                 "%s(): soc_uc_mem_write failed uC:%d addr:0x%x len:%d\n",
   1549                 FUNCTION_NAME(), uC, addr, len));
   1550             break;
   1551         }
   1552     }
   1553     return (rc);
   1554 }
   1555 
   1556 int
   1557 soc_uc_preload(int unit, int uC)
   1558 /*
   1559  * Function: 	soc_uc_preload
   1560  * Purpose:	Prepare to load code
   1561  * Parameters:	unit - unit number
   1562  *		uC - microcontroller num
   1563  * Returns:	SOC_E_xxx
   1564  */
   1565 {
   1566     uint16 dev_id;
   1567     uint8 rev_id;
   1568 
   1569     soc_cm_get_id(unit, &dev_id, &rev_id);
   1570 
   1571     /* Skip preloading of Firmware for Core-1 in Dagger2 */
   1572     if ((dev_id == BCM56233_DEVICE_ID) && (uC == 1)) {
   1573         return SOC_E_NONE;
   1574     }
   1575 
   1576     if (!soc_feature(unit, soc_feature_uc)) {
   1577         SOC_CMIC_UCDBG_LOG_ADD((unit, _bcmCmicUcDbgLogHostMcsLoad,
   1578             "soc_feature_uc is not defined uC: %d\n", uC));
   1579         return (SOC_E_FAIL);
   1580     }
   1581 #if defined(BCM_UC_MHOST_SUPPORT)
   1582     if (soc_feature(unit, soc_feature_uc_mhost)) {
   1583         return soc_uc_mhost_preload(unit, uC);
   1584     }
   1585 #endif /* BCM_UC_MHOST_SUPPORT */
   1586 #ifdef BCM_IPROC_SUPPORT
   1587     if (soc_feature(unit, soc_feature_iproc)) {
   1588         return soc_uc_iproc_preload(unit, uC);
   1589     }
   1590 #endif /* BCM_IPROC_SUPPORT */
   1591 #if 0
   1592 #ifdef BCM_CMICM_SUPPORT
   1593     if (soc_feature(unit, soc_feature_mcs)) {
   1594         return soc_uc_mcs_preload(unit, uC);
   1595     }
   1596 #endif /* BCM_CMICM_SUPPORT */
   1597 #endif
   1598     return (SOC_E_FAIL);
   1599 }
   1600 
   1601 int
   1602 soc_uc_reset(int unit, int uC)
   1603 /*
   1604  * Function: 	soc_uc_reset
   1605  * Purpose:	Reset the requested core
   1606  * Parameters:	unit - unit number
   1607  *		uC - microcontroller num
   1608  * Returns:	SOC_E_xxx
   1609  */
   1610 {
   1611     if (!soc_feature(unit, soc_feature_uc)) {
   1612         return (SOC_E_FAIL);
   1613     }
   1614 #if defined(BCM_UC_MHOST_SUPPORT)
   1615     if (soc_feature(unit, soc_feature_uc_mhost)) {
   1616         return soc_uc_mhost_reset(unit, uC);
   1617     }
   1618 #endif /* BCM_UC_MHOST_SUPPORT */
   1619 #ifdef BCM_IPROC_SUPPORT
   1620     if (soc_feature(unit, soc_feature_iproc)) {
   1621         return soc_uc_iproc_reset(unit, uC);
   1622     }
   1623 #endif /* BCM_IPROC_SUPPORT */
   1624 #ifdef BCM_CMICM_SUPPORT
   1625     if (soc_feature(unit, soc_feature_mcs)) {
   1626         return soc_uc_mcs_reset(unit, uC);
   1627     }
   1628 #endif /* BCM_CMICM_SUPPORT */
   1629     return (SOC_E_FAIL);
   1630 }
   1631 
   1632 int
   1633 soc_uc_start(int unit, int uC, uint32 addr)
   1634 /*
   1635  * Function: 	soc_uc_start
   1636  * Purpose:	Start MCS execution
   1637  * Parameters:	unit - unit number
   1638  *		uC - microcontroller num
   1639  * Returns:	SOC_E_xxx
   1640  */
   1641 {
   1642     uint16 dev_id;
   1643     uint8 rev_id;
   1644 
   1645     soc_cm_get_id(unit, &dev_id, &rev_id);
   1646 
   1647     /* Skip starting of Firmware for Core-1 in Dagger2 */
   1648     if ((dev_id == BCM56233_DEVICE_ID) && (uC == 1)) {
   1649         return SOC_E_NONE;
   1650     }    
   1651 
   1652     if (!soc_feature(unit, soc_feature_uc)) {
   1653         return (SOC_E_FAIL);
   1654     }
   1655 #if defined(BCM_UC_MHOST_SUPPORT)
   1656     if (soc_feature(unit, soc_feature_uc_mhost)) {
   1657         return soc_uc_mhost_start(unit, uC, addr);
   1658     }
   1659 #endif /* BCM_UC_MHOST_SUPPORT */
   1660 #ifdef BCM_IPROC_SUPPORT
   1661     if (soc_feature(unit, soc_feature_iproc)) {
   1662         return soc_uc_iproc_start(unit, uC, addr);
   1663     }
   1664 #endif /* BCM_IPROC_SUPPORT */
   1665 #ifdef BCM_CMICM_SUPPORT
   1666     if (soc_feature(unit, soc_feature_mcs)) {
   1667         return soc_uc_mcs_start(unit, uC, addr);
   1668     }
   1669 #endif /* BCM_CMICM_SUPPORT */
   1670     return (SOC_E_FAIL);
   1671 }
   1672 
   1673 /*
   1674  * Function: 	soc_uc_ping
   1675  * Purpose:	Check the uKernel status
   1676  * Parameters:	unit - unit number
   1677  *      uC - microcontroller num
   1678  *      timeout - Ping timeout in uS (0 to skip Ping)
   1679  * Returns:	SOC_E_XXX
   1680  *     SOC_E_UNAVAIL : SoC doesn't have uC / MCS support.
   1681  *     SOC_E_PARAM : uC number given is invalid for this SoC
   1682  *     SOC_E_DISABLED : ARM core is in reset.
   1683  *     SOC_E_INIT : uKernel messaging is not initialized.
   1684  *     SOC_E_TIMEOUT : Ping timed out (uKernel not responding).
   1685  *     SOC_E_NONE : Successful.
   1686  */
   1687 int soc_uc_ping(int unit, int uC, sal_usecs_t timeout)
   1688 {
   1689     mos_msg_data_t send;
   1690 
   1691     if (!soc_feature(unit, soc_feature_uc)) {
   1692         return (SOC_E_UNAVAIL);
   1693     }
   1694     if (uC < 0 || uC >= SOC_INFO(unit).num_ucs) {
   1695         return SOC_E_PARAM;
   1696     }
   1697     if (soc_uc_in_reset(unit, uC)) {
   1698         /* uC is in reset / Halt */
   1699         return SOC_E_DISABLED;
   1700     }
   1701     if (timeout == 0) {
   1702         return SOC_E_NONE;
   1703     }
   1704     send.s.mclass = MOS_MSG_CLASS_SYSTEM;
   1705     send.s.subclass = MOS_MSG_SUBCLASS_SYSTEM_PING;
   1706     send.s.len = 0;
   1707     send.s.data = 0;
   1708     return soc_cmic_uc_msg_send(unit, uC, &send, timeout);
   1709 }
   1710 
   1711 char *soc_uc_firmware_version(int unit, int uC)
   1712 /*
   1713  * Function: 	soc_uc_firmware_version
   1714  * Purpose:	Return the firmware version string
   1715  * Parameters:	unit - unit number
   1716  *		uC - microcontroller num
   1717  * Returns:	char * string pointer (to be freed with soc_cm_sfree())
   1718  */
   1719 {
   1720     int rc;
   1721     mos_msg_data_t send;
   1722     mos_msg_data_t reply;
   1723     int len = 256;
   1724     char *version_buffer;
   1725     uint16 dev_id;
   1726     uint8 rev_id;
   1727 
   1728     soc_cm_get_id(unit, &dev_id, &rev_id);
   1729 
   1730     /* Skip loading of Firmware for Core-1 in Dagger2 */
   1731     if ((dev_id == BCM56233_DEVICE_ID) && (uC == 1)) {
   1732         return NULL;
   1733     }
   1734 
   1735     if (!soc_feature(unit, soc_feature_uc)) {
   1736         return NULL;
   1737     }
   1738 
   1739     version_buffer = soc_cm_salloc(unit, len, "Version info buffer");
   1740     if (version_buffer) {
   1741         send.s.mclass = MOS_MSG_CLASS_SYSTEM;
   1742         send.s.subclass = MOS_MSG_SUBCLASS_SYSTEM_VERSION;
   1743         send.s.len = soc_htons(len);
   1744         send.s.data = soc_htonl(soc_cm_l2p(unit, version_buffer));
   1745 
   1746         soc_cm_sinval(unit, version_buffer, len);
   1747 
   1748         rc = soc_cmic_uc_msg_send(unit, uC, &send, 5 * 1000 * 1000);
   1749         if (rc != SOC_E_NONE) {
   1750             soc_cm_sfree(unit, version_buffer);
   1751             return NULL;
   1752         }
   1753         rc = soc_cmic_uc_msg_receive(unit, uC, MOS_MSG_CLASS_VERSION,
   1754                                      &reply, 5 * 1000 * 1000);
   1755         if (rc != SOC_E_NONE) {
   1756             soc_cm_sfree(unit, version_buffer);
   1757             return NULL;
   1758         }
   1759 
   1760     }
   1761     return version_buffer;
   1762 }
   1763 
   1764 /*
   1765  * Function: 	soc_uc_firmware_thread_info
   1766  * Purpose:	Return the firmware thread_info string
   1767  * Parameters:	unit - unit number
   1768  *		uC - microcontroller num
   1769  * Returns:	char * string pointer (to be freed with soc_cm_sfree())
   1770  */
   1771 char *soc_uc_firmware_thread_info(int unit, int uC)
   1772 {
   1773     int rc;
   1774     mos_msg_data_t send;
   1775     mos_msg_data_t reply;
   1776     int len = 1024;
   1777     char *thread_info_buffer;
   1778     uint16 dev_id;
   1779     uint8 rev_id;
   1780 
   1781     soc_cm_get_id(unit, &dev_id, &rev_id);
   1782 
   1783     /* Skip loading of Firmware for Core-1 in Dagger2 */
   1784     if ((dev_id == BCM56233_DEVICE_ID) && (uC == 1)) {
   1785         return NULL;
   1786     }
   1787 
   1788     if (!soc_feature(unit, soc_feature_uc)) {
   1789         return NULL;
   1790     }
   1791 
   1792     thread_info_buffer = soc_cm_salloc(unit, len, "thread info buffer");
   1793     if (thread_info_buffer) {
   1794         send.s.mclass = MOS_MSG_CLASS_SYSTEM;
   1795         send.s.subclass = MOS_MSG_SUBCLASS_SYSTEM_THREAD_INFO;
   1796         send.s.len = soc_htons(len);
   1797         send.s.data = soc_htonl(soc_cm_l2p(unit, thread_info_buffer));
   1798 
   1799         soc_cm_sinval(unit, thread_info_buffer, len);
   1800 
   1801         rc = soc_cmic_uc_msg_send(unit, uC, &send, _SYSTEM_UC_MSG_TIMEOUT);
   1802         if (rc != SOC_E_NONE) {
   1803             soc_cm_sfree(unit, thread_info_buffer);
   1804             return NULL;
   1805         }
   1806         rc = soc_cmic_uc_msg_receive(unit, uC, MOS_MSG_CLASS_THREAD_INFO,
   1807                                      &reply, _SYSTEM_UC_MSG_TIMEOUT);
   1808         if (rc != SOC_E_NONE) {
   1809             soc_cm_sfree(unit, thread_info_buffer);
   1810             return NULL;
   1811         }
   1812 
   1813     }
   1814     return thread_info_buffer;
   1815 }
   1816 
   1817 /*
   1818  * Function: 	soc_uc_console_log
   1819  * Purpose:	Switch on/off uc console log
   1820  * Parameters:	unit - unit number
   1821  *		uC - microcontroller num
   1822  * Returns:	SOC_E_XXX
   1823  */
   1824 int soc_uc_console_log(int unit, int uC, int on)
   1825 {
   1826     int            rc;
   1827     mos_msg_data_t send;
   1828 
   1829     if (!soc_feature(unit, soc_feature_uc)) {
   1830         return SOC_E_UNAVAIL;
   1831     }
   1832 
   1833     sal_memset(&send, 0, sizeof(send));
   1834     send.s.mclass = MOS_MSG_CLASS_SYSTEM;
   1835     send.s.subclass = MOS_MSG_SUBCLASS_SYSTEM_CMD_CONSOLE_LOG;
   1836     send.s.len = soc_htons(on);
   1837 
   1838     rc = soc_cmic_uc_msg_send(unit, uC, &send, _SYSTEM_UC_MSG_TIMEOUT);
   1839 
   1840     return rc;
   1841 }
   1842 
   1843 /*
   1844  * Function: 	soc_uc_stats_reset
   1845  * Purpose:	Reset stats info in the uC
   1846  * Parameters:	unit - unit number
   1847  *		uC - microcontroller num
   1848  * Returns:	SOC_E_XXX
   1849  */
   1850 int soc_uc_stats_reset(int unit, int uC)
   1851 {
   1852     int            rc;
   1853     mos_msg_data_t send;
   1854 
   1855     if (!soc_feature(unit, soc_feature_uc)) {
   1856         return SOC_E_UNAVAIL;
   1857     }
   1858 
   1859     sal_memset(&send, 0, sizeof(send));
   1860     send.s.mclass = MOS_MSG_CLASS_SYSTEM;
   1861     send.s.subclass = MOS_MSG_SUBCLASS_SYSTEM_CMD_STATS_RESET;
   1862 
   1863     rc = soc_cmic_uc_msg_send(unit, uC, &send, _SYSTEM_UC_MSG_TIMEOUT);
   1864 
   1865     return rc;
   1866 }
   1867 /*
   1868  * Function: 	soc_uc_status
   1869  * Purpose:	Return Status of uC
   1870  * Parameters:	unit   - unit number
   1871  *              uC     - core number
   1872  *              status - 0|1. 1 - OK
   1873  * Returns:	SOC_E_XXX
   1874  */
   1875 int
   1876 soc_uc_status(int unit, int uC, int *status)
   1877 {
   1878     uint32 addr = 0;
   1879     uint32 cpsr = 0;
   1880 
   1881     *status = 0;
   1882 
   1883     if (!soc_feature(unit, soc_feature_uc)) {
   1884         return (SOC_E_FAIL);
   1885     }
   1886     if (uC < 0 || uC >= SOC_INFO(unit).num_ucs) {
   1887         return SOC_E_PARAM;
   1888     }
   1889 
   1890     if (soc_uc_in_reset(unit, uC)) {
   1891         /* uC is in reset */
   1892         return SOC_E_NONE;
   1893     }
   1894 
   1895 
   1896     if (soc_feature(unit, soc_feature_iproc)) {
   1897         if (soc_feature(unit, soc_feature_uc_mhost)) {
   1898 #if defined(BCM_UC_MHOST_SUPPORT)
   1899             /* iProc mHost: vectors and exception registers are in ATCM */
   1900             addr = 0x01000000 + 0x00100000 * uC;
   1901 #ifdef BCM_SABER2_SUPPORT
   1902             if (SOC_IS_SABER2(unit)) {
   1903                 if (uC == 2) {
   1904                     addr = 0x01160000;
   1905                 }
   1906             }
   1907 #endif /* BCM_SABER2_SUPPORT */
   1908 
   1909 #if defined(BCM_APACHE_SUPPORT) || defined(BCM_MONTEREY_SUPPORT)
   1910             if (SOC_IS_APACHE(unit) || SOC_IS_MONTEREY(unit)) {
   1911                 addr = 0x01100000 + 0x00060000 * uC;
   1912             }
   1913 #endif /* BCM_APACHE_SUPPORT */
   1914 
   1915 #ifdef BCM_TRIDENT3_SUPPORT
   1916             if (SOC_IS_TRIDENT3(unit)) {
   1917                 addr = 0x01100000 + 0x00060000 * uC;
   1918             }
   1919 #endif /* BCM_TRIDENT3_SUPPORT */
   1920 
   1921 #endif /* BCM_UC_MHOST_SUPPORT */
   1922         } else {
   1923         /* iProc - L2Cache + SRAM for now. */
   1924             if (SOC_IS_HURRICANE2(unit) || SOC_IS_HURRICANE3(unit)) {
   1925 #if defined(BCM_HURRICANE2_SUPPORT) || defined(BCM_HURRICANE3_SUPPORT)
   1926                 addr = 0x00004000;
   1927 #endif /* BCM_HURRICANE2_SUPPORT || BCM_HURRICANE3_SUPPORT */
   1928             } else {
   1929                 if (0 == uC) {
   1930                     addr = 0x1b004000;
   1931                 } else {
   1932                     addr = 0x1b034000;
   1933                 }
   1934             }
   1935         }
   1936     } else { /* CMICm with TCMs */
   1937         if (0 == uC) {
   1938             addr = 0x100000;
   1939         } else {
   1940             addr = 0x200000;
   1941         }
   1942     }
   1943 
   1944     cpsr = soc_uc_mem_read(unit, addr + 0x60);
   1945     if (!cpsr) {
   1946         *status = 1;
   1947     }
   1948     return SOC_E_NONE;;
   1949 }
   1950 #endif