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), ®val); 468 if (soc_reg_field_get(unit, reg, regval, TIMESYNC_INTRf) != 0) { 469 soc_reg_field_set(unit, reg, ®val, 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, ®val); 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, ®val); 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, ®val); 646 if (uC == 0) { 647 soc_reg_field_set(unit, IHOST_PROC_RST_A9_CORE_SOFT_RSTNr, 648 ®val, A9_CORE_0_SOFT_RSTNf, 0); 649 soc_reg_field_set(unit, IHOST_PROC_RST_A9_CORE_SOFT_RSTNr, 650 ®val, A9_CORE_1_SOFT_RSTNf, 0); 651 } 652 else { 653 soc_reg_field_set(unit, IHOST_PROC_RST_A9_CORE_SOFT_RSTNr, 654 ®val, 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, ®val); 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, ®val); 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, ®val); 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 ®val, 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 ®val, 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