1/******************************************************************************* 2Copyright (C) Marvell International Ltd. and its affiliates 3 4This software file (the "File") is owned and distributed by Marvell 5International Ltd. and/or its affiliates ("Marvell") under the following 6alternative licensing terms. Once you have made an election to distribute the 7File under one of the following license alternatives, please (i) delete this 8introductory statement regarding license alternatives, (ii) delete the two 9license alternatives that you have not elected to use and (iii) preserve the 10Marvell copyright notice above. 11 12******************************************************************************** 13Marvell Commercial License Option 14 15If you received this File from Marvell and you have entered into a commercial 16license agreement (a "Commercial License") with Marvell, the File is licensed 17to you under the terms of the applicable Commercial License. 18 19******************************************************************************** 20Marvell GPL License Option 21 22If you received this File from Marvell, you may opt to use, redistribute and/or 23modify this File in accordance with the terms and conditions of the General 24Public License Version 2, June 1991 (the "GPL License"), a copy of which is 25available along with the File in the license.txt file or by writing to the Free 26Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or 27on the worldwide web at http://www.gnu.org/licenses/gpl.txt. 28 29THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED 30WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY 31DISCLAIMED. The GPL License provides additional details about this warranty 32disclaimer. 33******************************************************************************** 34Marvell BSD License Option 35 36If you received this File from Marvell, you may opt to use, redistribute and/or 37modify this File under the following licensing terms. 38Redistribution and use in source and binary forms, with or without modification, 39are permitted provided that the following conditions are met: 40 41 * Redistributions of source code must retain the above copyright notice, 42 this list of conditions and the following disclaimer. 43 44 * Redistributions in binary form must reproduce the above copyright 45 notice, this list of conditions and the following disclaimer in the 46 documentation and/or other materials provided with the distribution. 47 48 * Neither the name of Marvell nor the names of its contributors may be 49 used to endorse or promote products derived from this software without 50 specific prior written permission. 51 52THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 53ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 54WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 55DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 56ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 57(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 58LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 59ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 60(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 61SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 62 63*******************************************************************************/ 64 65 66/* includes */ 67#include "ctrlEnv/sys/mvCpuIf.h" 68#include "ctrlEnv/sys/mvAhbToMbusRegs.h" 69#include "cpu/mvCpu.h" 70#include "ctrlEnv/mvCtrlEnvLib.h" 71#include "mvSysHwConfig.h" 72#include "mvSysDram.h" 73 74/*#define MV_DEBUG*/ 75/* defines */ 76 77#ifdef MV_DEBUG 78 #define DB(x) x 79#else 80 #define DB(x) 81#endif 82 83/* locals */ 84/* static functions */ 85static MV_BOOL cpuTargetWinOverlap(MV_TARGET target, MV_ADDR_WIN *pAddrWin); 86 87MV_TARGET * sampleAtResetTargetArray; 88MV_TARGET sampleAtResetTargetArrayP[] = BOOT_TARGETS_NAME_ARRAY; 89MV_TARGET sampleAtResetTargetArray6180P[] = BOOT_TARGETS_NAME_ARRAY_6180; 90/******************************************************************************* 91* mvCpuIfInit - Initialize Controller CPU interface 92* 93* DESCRIPTION: 94* This function initialize Controller CPU interface: 95* 1. Set CPU interface configuration registers. 96* 2. Set CPU master Pizza arbiter control according to static 97* configuration described in configuration file. 98* 3. Opens CPU address decode windows. DRAM windows are assumed to be 99* already set (auto detection). 100* 101* INPUT: 102* None. 103* 104* OUTPUT: 105* None. 106* 107* RETURN: 108* None. 109* 110*******************************************************************************/ 111MV_STATUS mvCpuIfInit(MV_CPU_DEC_WIN *cpuAddrWinMap) 112{ 113 MV_U32 regVal; 114 MV_TARGET target; 115 MV_ADDR_WIN addrWin; 116 117 if (cpuAddrWinMap == NULL) 118 { 119 DB(mvOsPrintf("mvCpuIfInit:ERR. cpuAddrWinMap == NULL\n")); 120 return MV_ERROR; 121 } 122 123 /*Initialize the boot target array according to device type*/ 124 if(mvCtrlModelGet() == MV_6180_DEV_ID) 125 sampleAtResetTargetArray = sampleAtResetTargetArray6180P; 126 else 127 sampleAtResetTargetArray = sampleAtResetTargetArrayP; 128 129 /* Set ARM Configuration register */ 130 regVal = MV_REG_READ(CPU_CONFIG_REG); 131 regVal &= ~CPU_CONFIG_DEFAULT_MASK; 132 regVal |= CPU_CONFIG_DEFAULT; 133 MV_REG_WRITE(CPU_CONFIG_REG,regVal); 134 135 /* First disable all CPU target windows */ 136 for (target = 0; cpuAddrWinMap[target].enable != TBL_TERM; target++) 137 { 138 if ((MV_TARGET_IS_DRAM(target))||(target == INTER_REGS)) 139 { 140 continue; 141 } 142 143#if defined(MV_MEM_OVER_PCI_WA) || defined(MV_UART_OVER_PCI_WA) 144 /* If the target PEX or PCI and memory is over PEX or PCI we don't touch this CPU windows */ 145 if (MV_TARGET_IS_PCI(target)) 146 { 147 continue; 148 } 149#endif 150 151#if defined(MV_MEM_OVER_PEX_WA) || defined(MV_UART_OVER_PEX_WA) 152 /* If the target PEX or PCI and memory is over PEX or PCI we don't touch this CPU windows */ 153 if (MV_TARGET_IS_PEX(target)) 154 { 155 continue; 156 } 157#endif 158#if defined(MV_RUN_FROM_FLASH) 159 /* Don't disable the boot device. */ 160 if (target == DEV_BOOCS) 161 { 162 continue; 163 } 164#endif /* MV_RUN_FROM_FLASH */ 165 mvCpuIfTargetWinEnable(MV_CHANGE_BOOT_CS(target),MV_FALSE); 166 } 167 168#if defined(MV_RUN_FROM_FLASH) 169 /* Resize the bootcs windows before other windows, because this */ 170 /* window is enabled and will cause an overlap if not resized. */ 171 target = DEV_BOOCS; 172 173 if (MV_OK != mvCpuIfTargetWinSet(target, &cpuAddrWinMap[target])) 174 { 175 DB(mvOsPrintf("mvCpuIfInit:ERR. mvCpuIfTargetWinSet fail\n")); 176 return MV_ERROR; 177 } 178 179 addrWin.baseLow = cpuAddrWinMap[target].addrWin.baseLow; 180 addrWin.baseHigh = cpuAddrWinMap[target].addrWin.baseHigh; 181 if (0xffffffff == mvAhbToMbusWinRemap(cpuAddrWinMap[target].winNum ,&addrWin)) 182 { 183 DB(mvOsPrintf("mvCpuIfInit:WARN. mvAhbToMbusWinRemap can't remap winNum=%d\n", 184 cpuAddrWinMap[target].winNum)); 185 } 186 187#endif /* MV_RUN_FROM_FLASH */ 188 189 /* Go through all targets in user table until table terminator */ 190 for (target = 0; cpuAddrWinMap[target].enable != TBL_TERM; target++) 191 { 192 193#if defined(MV_RUN_FROM_FLASH) 194 if (target == DEV_BOOCS) 195 { 196 continue; 197 } 198#endif /* MV_RUN_FROM_FLASH */ 199 200 /* if DRAM auto sizing is used do not initialized DRAM target windows, */ 201 /* assuming this already has been done earlier. */ 202#ifdef MV_DRAM_AUTO_SIZE 203 if (MV_TARGET_IS_DRAM(target)) 204 { 205 continue; 206 } 207#endif 208 209#if defined(MV_MEM_OVER_PCI_WA) || defined(MV_UART_OVER_PCI_WA) 210 /* If the target PEX or PCI and memory is over PEX or PCI we don't touch this CPU windows */ 211 if (MV_TARGET_IS_PCI(target)) 212 { 213 continue; 214 } 215#endif 216 217#if defined(MV_MEM_OVER_PEX_WA) || defined(MV_UART_OVER_PEX_WA) 218 /* If the target PEX or PCI and memory is over PEX or PCI we don't touch this CPU windows */ 219 if (MV_TARGET_IS_PEX(target)) 220 { 221 continue; 222 } 223#endif 224 /* If the target attribute is the same as the boot device attribute */ 225 /* then it's stays disable */ 226 if (MV_TARGET_IS_AS_BOOT(target)) 227 { 228 continue; 229 } 230 231 if((0 == cpuAddrWinMap[target].addrWin.size) || 232 (DIS == cpuAddrWinMap[target].enable)) 233 234 { 235 if (MV_OK != mvCpuIfTargetWinEnable(target, MV_FALSE)) 236 { 237 DB(mvOsPrintf("mvCpuIfInit:ERR. mvCpuIfTargetWinEnable fail\n")); 238 return MV_ERROR; 239 } 240 241 } 242 else 243 { 244 if (MV_OK != mvCpuIfTargetWinSet(target, &cpuAddrWinMap[target])) 245 { 246 DB(mvOsPrintf("mvCpuIfInit:ERR. mvCpuIfTargetWinSet fail\n")); 247 return MV_ERROR; 248 } 249 250 addrWin.baseLow = cpuAddrWinMap[target].addrWin.baseLow; 251 addrWin.baseHigh = cpuAddrWinMap[target].addrWin.baseHigh; 252 if (0xffffffff == mvAhbToMbusWinRemap(cpuAddrWinMap[target].winNum ,&addrWin)) 253 { 254 DB(mvOsPrintf("mvCpuIfInit:WARN. mvAhbToMbusWinRemap can't remap winNum=%d\n", 255 cpuAddrWinMap[target].winNum)); 256 } 257 258 259 } 260 } 261 262 return MV_OK; 263 264 265} 266 267 268/******************************************************************************* 269* mvCpuIfTargetWinSet - Set CPU-to-peripheral target address window 270* 271* DESCRIPTION: 272* This function sets a peripheral target (e.g. SDRAM bank0, PCI0_MEM0) 273* address window, also known as address decode window. 274* A new address decode window is set for specified target address window. 275* If address decode window parameter structure enables the window, 276* the routine will also enable the target window, allowing CPU to access 277* the target window. 278* 279* INPUT: 280* target - Peripheral target enumerator. 281* pAddrDecWin - CPU target window data structure. 282* 283* OUTPUT: 284* N/A 285* 286* RETURN: 287* MV_OK if CPU target window was set correctly, MV_ERROR in case of 288* address window overlapps with other active CPU target window or 289* trying to assign 36bit base address while CPU does not support that. 290* The function returns MV_NOT_SUPPORTED, if the target is unsupported. 291* 292*******************************************************************************/ 293MV_STATUS mvCpuIfTargetWinSet(MV_TARGET target, MV_CPU_DEC_WIN *pAddrDecWin) 294{ 295 MV_AHB_TO_MBUS_DEC_WIN decWin; 296 MV_U32 existingWinNum; 297 MV_DRAM_DEC_WIN addrDecWin; 298 299 target = MV_CHANGE_BOOT_CS(target); 300 301 /* Check parameters */ 302 if (target >= MAX_TARGETS) 303 { 304 mvOsPrintf("mvCpuIfTargetWinSet: target %d is Illigal\n", target); 305 return MV_ERROR; 306 } 307 308 /* 2) Check if the requested window overlaps with current windows */ 309 if (MV_TRUE == cpuTargetWinOverlap(target, &pAddrDecWin->addrWin)) 310 { 311 mvOsPrintf("mvCpuIfTargetWinSet: ERR. Target %d overlap\n", target); 312 return MV_BAD_PARAM; 313 } 314 315 if (MV_TARGET_IS_DRAM(target)) 316 { 317 /* copy relevant data to MV_DRAM_DEC_WIN structure */ 318 addrDecWin.addrWin.baseHigh = pAddrDecWin->addrWin.baseHigh; 319 addrDecWin.addrWin.baseLow = pAddrDecWin->addrWin.baseLow; 320 addrDecWin.addrWin.size = pAddrDecWin->addrWin.size; 321 addrDecWin.enable = pAddrDecWin->enable; 322 323 324 if (mvDramIfWinSet(target,&addrDecWin) != MV_OK); 325 { 326 mvOsPrintf("mvCpuIfTargetWinSet: mvDramIfWinSet Failed\n"); 327 return MV_ERROR; 328 } 329 330 } 331 else 332 { 333 /* copy relevant data to MV_AHB_TO_MBUS_DEC_WIN structure */ 334 decWin.addrWin.baseLow = pAddrDecWin->addrWin.baseLow; 335 decWin.addrWin.baseHigh = pAddrDecWin->addrWin.baseHigh; 336 decWin.addrWin.size = pAddrDecWin->addrWin.size; 337 decWin.enable = pAddrDecWin->enable; 338 decWin.target = target; 339 340 existingWinNum = mvAhbToMbusWinTargetGet(target); 341 342 /* check if there is already another Window configured 343 for this target */ 344 if ((existingWinNum < MAX_AHB_TO_MBUS_WINS )&& 345 (existingWinNum != pAddrDecWin->winNum)) 346 { 347 /* if we want to enable the new winow number 348 passed by the user , then the old one should 349 be disabled */ 350 if (MV_TRUE == pAddrDecWin->enable) 351 { 352 /* be sure it is disabled */ 353 mvAhbToMbusWinEnable(existingWinNum , MV_FALSE); 354 } 355 } 356 357 if (mvAhbToMbusWinSet(pAddrDecWin->winNum,&decWin) != MV_OK) 358 { 359 mvOsPrintf("mvCpuIfTargetWinSet: mvAhbToMbusWinSet Failed\n"); 360 return MV_ERROR; 361 } 362 363 } 364 365 return MV_OK; 366} 367 368/******************************************************************************* 369* mvCpuIfTargetWinGet - Get CPU-to-peripheral target address window 370* 371* DESCRIPTION: 372* Get the CPU peripheral target address window. 373* 374* INPUT: 375* target - Peripheral target enumerator 376* 377* OUTPUT: 378* pAddrDecWin - CPU target window information data structure. 379* 380* RETURN: 381* MV_OK if target exist, MV_ERROR otherwise. 382* 383*******************************************************************************/ 384MV_STATUS mvCpuIfTargetWinGet(MV_TARGET target, MV_CPU_DEC_WIN *pAddrDecWin) 385{ 386 387 MV_U32 winNum=0xffffffff; 388 MV_AHB_TO_MBUS_DEC_WIN decWin; 389 MV_DRAM_DEC_WIN addrDecWin; 390 391 target = MV_CHANGE_BOOT_CS(target); 392 393 /* Check parameters */ 394 if (target >= MAX_TARGETS) 395 { 396 mvOsPrintf("mvCpuIfTargetWinGet: target %d is Illigal\n", target); 397 return MV_ERROR; 398 } 399 400 if (MV_TARGET_IS_DRAM(target)) 401 { 402 if (mvDramIfWinGet(target,&addrDecWin) != MV_OK) 403 { 404 mvOsPrintf("mvCpuIfTargetWinGet: Failed to get window target %d\n", 405 target); 406 return MV_ERROR; 407 } 408 409 /* copy relevant data to MV_CPU_DEC_WIN structure */ 410 pAddrDecWin->addrWin.baseLow = addrDecWin.addrWin.baseLow; 411 pAddrDecWin->addrWin.baseHigh = addrDecWin.addrWin.baseHigh; 412 pAddrDecWin->addrWin.size = addrDecWin.addrWin.size; 413 pAddrDecWin->enable = addrDecWin.enable; 414 pAddrDecWin->winNum = 0xffffffff; 415 416 } 417 else 418 { 419 /* get the Window number associated with this target */ 420 421 winNum = mvAhbToMbusWinTargetGet(target); 422 if (winNum >= MAX_AHB_TO_MBUS_WINS) 423 { 424 return MV_NO_SUCH; 425 426 } 427 428 if (mvAhbToMbusWinGet(winNum , &decWin) != MV_OK) 429 { 430 mvOsPrintf("%s: mvAhbToMbusWinGet Failed at winNum = %d\n", 431 __FUNCTION__, winNum); 432 return MV_ERROR; 433 434 } 435 436 /* copy relevant data to MV_CPU_DEC_WIN structure */ 437 pAddrDecWin->addrWin.baseLow = decWin.addrWin.baseLow; 438 pAddrDecWin->addrWin.baseHigh = decWin.addrWin.baseHigh; 439 pAddrDecWin->addrWin.size = decWin.addrWin.size; 440 pAddrDecWin->enable = decWin.enable; 441 pAddrDecWin->winNum = winNum; 442 443 } 444 445 446 447 448 return MV_OK; 449} 450 451 452/******************************************************************************* 453* mvCpuIfTargetWinEnable - Enable/disable a CPU address decode window 454* 455* DESCRIPTION: 456* This function enable/disable a CPU address decode window. 457* if parameter 'enable' == MV_TRUE the routine will enable the 458* window, thus enabling CPU accesses (before enabling the window it is 459* tested for overlapping). Otherwise, the window will be disabled. 460* 461* INPUT: 462* target - Peripheral target enumerator. 463* enable - Enable/disable parameter. 464* 465* OUTPUT: 466* N/A 467* 468* RETURN: 469* MV_ERROR if protection window number was wrong, or the window 470* overlapps other target window. 471* 472*******************************************************************************/ 473MV_STATUS mvCpuIfTargetWinEnable(MV_TARGET target,MV_BOOL enable) 474{ 475 MV_U32 winNum, temp; 476 MV_CPU_DEC_WIN addrDecWin; 477 478 target = MV_CHANGE_BOOT_CS(target); 479 480 /* Check parameters */ 481 if (target >= MAX_TARGETS) 482 { 483 mvOsPrintf("mvCpuIfTargetWinEnable: target %d is Illigal\n", target); 484 return MV_ERROR; 485 } 486 487 /* get the window and check if it exist */ 488 temp = mvCpuIfTargetWinGet(target, &addrDecWin); 489 if (MV_NO_SUCH == temp) 490 { 491 return (enable? MV_ERROR: MV_OK); 492 } 493 else if( MV_OK != temp) 494 { 495 mvOsPrintf("%s: ERR. Getting target %d failed.\n",__FUNCTION__, target); 496 return MV_ERROR; 497 } 498 499 500 /* check overlap */ 501 502 if (MV_TRUE == enable) 503 { 504 if (MV_TRUE == cpuTargetWinOverlap(target, &addrDecWin.addrWin)) 505 { 506 DB(mvOsPrintf("%s: ERR. Target %d overlap\n",__FUNCTION__, target)); 507 return MV_ERROR; 508 } 509 510 } 511 512 513 if (MV_TARGET_IS_DRAM(target)) 514 { 515 if (mvDramIfWinEnable(target , enable) != MV_OK) 516 { 517 mvOsPrintf("mvCpuIfTargetWinGet: mvDramIfWinEnable Failed at \n"); 518 return MV_ERROR; 519 520 } 521 522 } 523 else 524 { 525 /* get the Window number associated with this target */ 526 527 winNum = mvAhbToMbusWinTargetGet(target); 528 529 if (winNum >= MAX_AHB_TO_MBUS_WINS) 530 { 531 return (enable? MV_ERROR: MV_OK); 532 } 533 534 if (mvAhbToMbusWinEnable(winNum , enable) != MV_OK) 535 { 536 mvOsPrintf("mvCpuIfTargetWinGet: Failed to enable window = %d\n", 537 winNum); 538 return MV_ERROR; 539 540 } 541 542 } 543 544 return MV_OK; 545} 546 547 548/******************************************************************************* 549* mvCpuIfTargetWinSizeGet - Get CPU target address window size 550* 551* DESCRIPTION: 552* Get the size of CPU-to-peripheral target window. 553* 554* INPUT: 555* target - Peripheral target enumerator 556* 557* OUTPUT: 558* None. 559* 560* RETURN: 561* 32bit size. Function also returns '0' if window is closed. 562* Function returns 0xFFFFFFFF in case of an error. 563* 564*******************************************************************************/ 565MV_U32 mvCpuIfTargetWinSizeGet(MV_TARGET target) 566{ 567 MV_CPU_DEC_WIN addrDecWin; 568 569 target = MV_CHANGE_BOOT_CS(target); 570 571 /* Check parameters */ 572 if (target >= MAX_TARGETS) 573 { 574 mvOsPrintf("mvCpuIfTargetWinSizeGet: target %d is Illigal\n", target); 575 return 0; 576 } 577 578 /* Get the winNum window */ 579 if (MV_OK != mvCpuIfTargetWinGet(target, &addrDecWin)) 580 { 581 mvOsPrintf("mvCpuIfTargetWinSizeGet:ERR. Getting target %d failed.\n", 582 target); 583 return 0; 584 } 585 586 /* Check if window is enabled */ 587 if (addrDecWin.enable == MV_TRUE) 588 { 589 return (addrDecWin.addrWin.size); 590 } 591 else 592 { 593 return 0; /* Window disabled. return 0 */ 594 } 595} 596 597/******************************************************************************* 598* mvCpuIfTargetWinBaseLowGet - Get CPU target address window base low 599* 600* DESCRIPTION: 601* CPU-to-peripheral target address window base is constructed of 602* two parts: Low and high. 603* This function gets the CPU peripheral target low base address. 604* 605* INPUT: 606* target - Peripheral target enumerator 607* 608* OUTPUT: 609* None. 610* 611* RETURN: 612* 32bit low base address. 613* 614*******************************************************************************/ 615MV_U32 mvCpuIfTargetWinBaseLowGet(MV_TARGET target) 616{ 617 MV_CPU_DEC_WIN addrDecWin; 618 619 target = MV_CHANGE_BOOT_CS(target); 620 621 /* Check parameters */ 622 if (target >= MAX_TARGETS) 623 { 624 mvOsPrintf("mvCpuIfTargetWinBaseLowGet: target %d is Illigal\n", target); 625 return 0xffffffff; 626 } 627 628 /* Get the target window */ 629 if (MV_OK != mvCpuIfTargetWinGet(target, &addrDecWin)) 630 { 631 mvOsPrintf("mvCpuIfTargetWinBaseLowGet:ERR. Getting target %d failed.\n", 632 target); 633 return 0xffffffff; 634 } 635 636 if (MV_FALSE == addrDecWin.enable) 637 { 638 return 0xffffffff; 639 } 640 return (addrDecWin.addrWin.baseLow); 641} 642 643/******************************************************************************* 644* mvCpuIfTargetWinBaseHighGet - Get CPU target address window base high 645* 646* DESCRIPTION: 647* CPU-to-peripheral target address window base is constructed of 648* two parts: Low and high. 649* This function gets the CPU peripheral target high base address. 650* 651* INPUT: 652* target - Peripheral target enumerator 653* 654* OUTPUT: 655* None. 656* 657* RETURN: 658* 32bit high base address. 659* 660*******************************************************************************/ 661MV_U32 mvCpuIfTargetWinBaseHighGet(MV_TARGET target) 662{ 663 MV_CPU_DEC_WIN addrDecWin; 664 665 target = MV_CHANGE_BOOT_CS(target); 666 667 /* Check parameters */ 668 if (target >= MAX_TARGETS) 669 { 670 mvOsPrintf("mvCpuIfTargetWinBaseLowGet: target %d is Illigal\n", target); 671 return 0xffffffff; 672 } 673 674 /* Get the target window */ 675 if (MV_OK != mvCpuIfTargetWinGet(target, &addrDecWin)) 676 { 677 mvOsPrintf("mvCpuIfTargetWinBaseHighGet:ERR. Getting target %d failed.\n", 678 target); 679 return 0xffffffff; 680 } 681 682 if (MV_FALSE == addrDecWin.enable) 683 { 684 return 0; 685 } 686 687 return (addrDecWin.addrWin.baseHigh); 688} 689 690#if defined(MV_INCLUDE_PEX) 691/******************************************************************************* 692* mvCpuIfPexRemap - Set CPU remap register for address windows. 693* 694* DESCRIPTION: 695* 696* INPUT: 697* pexTarget - Peripheral target enumerator. Must be a PEX target. 698* pAddrDecWin - CPU target window information data structure. 699* Note that caller has to fill in the base field only. The 700* size field is ignored. 701* 702* OUTPUT: 703* None. 704* 705* RETURN: 706* MV_ERROR if target is not a PEX one, MV_OK otherwise. 707* 708*******************************************************************************/ 709MV_U32 mvCpuIfPexRemap(MV_TARGET pexTarget, MV_ADDR_WIN *pAddrDecWin) 710{ 711 MV_U32 winNum; 712 713 /* Check parameters */ 714 715 if (mvCtrlPexMaxIfGet() > 1) 716 { 717 if ((!MV_TARGET_IS_PEX1(pexTarget))&&(!MV_TARGET_IS_PEX0(pexTarget))) 718 { 719 mvOsPrintf("mvCpuIfPexRemap: target %d is Illigal\n",pexTarget); 720 return 0xffffffff; 721 } 722 723 } 724 else 725 { 726 if (!MV_TARGET_IS_PEX0(pexTarget)) 727 { 728 mvOsPrintf("mvCpuIfPexRemap: target %d is Illigal\n",pexTarget); 729 return 0xffffffff; 730 } 731 732 } 733 734 /* get the Window number associated with this target */ 735 winNum = mvAhbToMbusWinTargetGet(pexTarget); 736 737 if (winNum >= MAX_AHB_TO_MBUS_WINS) 738 { 739 mvOsPrintf("mvCpuIfPexRemap: mvAhbToMbusWinTargetGet Failed\n"); 740 return 0xffffffff; 741 742 } 743 744 return mvAhbToMbusWinRemap(winNum , pAddrDecWin); 745} 746 747#endif 748 749#if defined(MV_INCLUDE_PCI) 750/******************************************************************************* 751* mvCpuIfPciRemap - Set CPU remap register for address windows. 752* 753* DESCRIPTION: 754* 755* INPUT: 756* pciTarget - Peripheral target enumerator. Must be a PCI target. 757* pAddrDecWin - CPU target window information data structure. 758* Note that caller has to fill in the base field only. The 759* size field is ignored. 760* 761* OUTPUT: 762* None. 763* 764* RETURN: 765* MV_ERROR if target is not a PCI one, MV_OK otherwise. 766* 767*******************************************************************************/ 768MV_U32 mvCpuIfPciRemap(MV_TARGET pciTarget, MV_ADDR_WIN *pAddrDecWin) 769{ 770 MV_U32 winNum; 771 772 /* Check parameters */ 773 if (!MV_TARGET_IS_PCI(pciTarget)) 774 { 775 mvOsPrintf("mvCpuIfPciRemap: target %d is Illigal\n",pciTarget); 776 return 0xffffffff; 777 } 778 779 /* get the Window number associated with this target */ 780 winNum = mvAhbToMbusWinTargetGet(pciTarget); 781 782 if (winNum >= MAX_AHB_TO_MBUS_WINS) 783 { 784 mvOsPrintf("mvCpuIfPciRemap: mvAhbToMbusWinTargetGet Failed\n"); 785 return 0xffffffff; 786 787 } 788 789 return mvAhbToMbusWinRemap(winNum , pAddrDecWin); 790} 791#endif /* MV_INCLUDE_PCI */ 792 793 794/******************************************************************************* 795* mvCpuIfPciIfRemap - Set CPU remap register for address windows. 796* 797* DESCRIPTION: 798* 799* INPUT: 800* pciTarget - Peripheral target enumerator. Must be a PCI target. 801* pAddrDecWin - CPU target window information data structure. 802* Note that caller has to fill in the base field only. The 803* size field is ignored. 804* 805* OUTPUT: 806* None. 807* 808* RETURN: 809* MV_ERROR if target is not a PCI one, MV_OK otherwise. 810* 811*******************************************************************************/ 812MV_U32 mvCpuIfPciIfRemap(MV_TARGET pciIfTarget, MV_ADDR_WIN *pAddrDecWin) 813{ 814#if defined(MV_INCLUDE_PEX) 815 if (MV_TARGET_IS_PEX(pciIfTarget)) 816 { 817 return mvCpuIfPexRemap(pciIfTarget,pAddrDecWin); 818 } 819#endif 820#if defined(MV_INCLUDE_PCI) 821 822 if (MV_TARGET_IS_PCI(pciIfTarget)) 823 { 824 return mvCpuIfPciRemap(pciIfTarget,pAddrDecWin); 825 } 826#endif 827 return 0; 828} 829 830 831 832/******************************************************************************* 833* mvCpuIfTargetOfBaseAddressGet - Get the target according to base address 834* 835* DESCRIPTION: 836* 837* INPUT: 838* baseAddress - base address to be checked 839* 840* OUTPUT: 841* None. 842* 843* RETURN: 844* the target number that baseAddress belongs to or MAX_TARGETS is not 845* found 846* 847*******************************************************************************/ 848 849MV_TARGET mvCpuIfTargetOfBaseAddressGet(MV_U32 baseAddress) 850{ 851 MV_CPU_DEC_WIN win; 852 MV_U32 target; 853 854 for( target = 0; target < MAX_TARGETS; target++ ) 855 { 856 if( mvCpuIfTargetWinGet( target, &win ) == MV_OK ) 857 { 858 if( win.enable ) 859 { 860 if ((baseAddress >= win.addrWin.baseLow) && 861 (baseAddress < win.addrWin.baseLow + win.addrWin.size)) break; 862 } 863 } 864 else return MAX_TARGETS; 865 866 } 867 868 return target; 869} 870/******************************************************************************* 871* cpuTargetWinOverlap - Detect CPU address decode windows overlapping 872* 873* DESCRIPTION: 874* An unpredicted behaviur is expected in case CPU address decode 875* windows overlapps. 876* This function detects CPU address decode windows overlapping of a 877* specified target. The function does not check the target itself for 878* overlapping. The function also skipps disabled address decode windows. 879* 880* INPUT: 881* target - Peripheral target enumerator. 882* pAddrDecWin - An address decode window struct. 883* 884* OUTPUT: 885* None. 886* 887* RETURN: 888* MV_TRUE if the given address window overlaps current address 889* decode map, MV_FALSE otherwise. 890* 891*******************************************************************************/ 892static MV_BOOL cpuTargetWinOverlap(MV_TARGET target, MV_ADDR_WIN *pAddrWin) 893{ 894 MV_U32 targetNum; 895 MV_CPU_DEC_WIN addrDecWin; 896 MV_STATUS status; 897 898 899 for(targetNum = 0; targetNum < MAX_TARGETS; targetNum++) 900 { 901#if defined(MV_RUN_FROM_FLASH) 902 if(MV_TARGET_IS_AS_BOOT(target)) 903 { 904 if (MV_CHANGE_BOOT_CS(targetNum) == target) 905 continue; 906 } 907#endif /* MV_RUN_FROM_FLASH */ 908 909 /* don't check our target or illegal targets */ 910 if (targetNum == target) 911 { 912 continue; 913 } 914 915 /* Get window parameters */ 916 status = mvCpuIfTargetWinGet(targetNum, &addrDecWin); 917 if(MV_NO_SUCH == status) 918 { 919 continue; 920 } 921 if(MV_OK != status) 922 { 923 DB(mvOsPrintf("cpuTargetWinOverlap: ERR. TargetWinGet failed\n")); 924 return MV_TRUE; 925 } 926 927 /* Do not check disabled windows */ 928 if (MV_FALSE == addrDecWin.enable) 929 { 930 continue; 931 } 932 933 if(MV_TRUE == ctrlWinOverlapTest(pAddrWin, &addrDecWin.addrWin)) 934 { 935 DB(mvOsPrintf( 936 "cpuTargetWinOverlap: Required target %d overlap current %d\n", 937 target, targetNum)); 938 return MV_TRUE; 939 } 940 } 941 942 return MV_FALSE; 943 944} 945 946/******************************************************************************* 947* mvCpuIfAddDecShow - Print the CPU address decode map. 948* 949* DESCRIPTION: 950* This function print the CPU address decode map. 951* 952* INPUT: 953* None. 954* 955* OUTPUT: 956* None. 957* 958* RETURN: 959* None. 960* 961*******************************************************************************/ 962MV_VOID mvCpuIfAddDecShow(MV_VOID) 963{ 964 MV_CPU_DEC_WIN win; 965 MV_U32 target; 966 mvOsOutput( "\n" ); 967 mvOsOutput( "CPU Interface\n" ); 968 mvOsOutput( "-------------\n" ); 969 970 for( target = 0; target < MAX_TARGETS; target++ ) 971 { 972 973 memset( &win, 0, sizeof(MV_CPU_DEC_WIN) ); 974 975 mvOsOutput( "%s ",mvCtrlTargetNameGet(target)); 976 mvOsOutput( "...." ); 977 978 if( mvCpuIfTargetWinGet( target, &win ) == MV_OK ) 979 { 980 if( win.enable ) 981 { 982 mvOsOutput( "base %08x, ", win.addrWin.baseLow ); 983 mvSizePrint( win.addrWin.size ); 984 mvOsOutput( "\n" ); 985 986 } 987 else 988 mvOsOutput( "disable\n" ); 989 } 990 else if( mvCpuIfTargetWinGet( target, &win ) == MV_NO_SUCH ) 991 { 992 mvOsOutput( "no such\n" ); 993 } 994 } 995} 996 997/******************************************************************************* 998* mvCpuIfEnablePex - Enable PCI Express. 999* 1000* DESCRIPTION: 1001* This function Enable PCI Express. 1002* 1003* INPUT: 1004* pexIf - PEX interface number. 1005* pexType - MV_PEX_ROOT_COMPLEX - root complex device 1006* MV_PEX_END_POINT - end point device 1007* OUTPUT: 1008* None. 1009* 1010* RETURN: 1011* None. 1012* 1013*******************************************************************************/ 1014#if defined(MV_INCLUDE_PEX) 1015MV_VOID mvCpuIfEnablePex(MV_U32 pexIf, MV_PEX_TYPE pexType) 1016{ 1017 /* Set pex mode incase S@R not exist */ 1018 if( pexType == MV_PEX_END_POINT) 1019 { 1020 MV_REG_BIT_RESET(PEX_CTRL_REG(pexIf),PXCR_DEV_TYPE_CTRL_MASK); 1021 /* Change pex mode in capability reg */ 1022 MV_REG_BIT_RESET(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_CAPABILITY_REG), BIT22); 1023 MV_REG_BIT_SET(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_CAPABILITY_REG), BIT20); 1024 1025 } 1026 else 1027 { 1028 MV_REG_BIT_SET(PEX_CTRL_REG(pexIf),PXCR_DEV_TYPE_CTRL_MASK); 1029 } 1030 1031 /* CPU config register Pex enable */ 1032 MV_REG_BIT_SET(CPU_CTRL_STAT_REG,CCSR_PCI_ACCESS_MASK); 1033} 1034#endif 1035 1036 1037