uboot/arch/arm/cpu/ixp/npe/IxNpeDlNpeMgrUtils.c
<<
>>
Prefs
   1/**
   2 * @file IxNpeDlNpeMgrUtils.c
   3 *
   4 * @author Intel Corporation
   5 * @date 18 February 2002
   6 *
   7 * @brief This file contains the implementation of the private API for the 
   8 *        IXP425 NPE Downloader NpeMgr Utils module
   9 *
  10 * 
  11 * @par
  12 * IXP400 SW Release version 2.0
  13 * 
  14 * -- Copyright Notice --
  15 * 
  16 * @par
  17 * Copyright 2001-2005, Intel Corporation.
  18 * All rights reserved.
  19 * 
  20 * @par
  21 * Redistribution and use in source and binary forms, with or without
  22 * modification, are permitted provided that the following conditions
  23 * are met:
  24 * 1. Redistributions of source code must retain the above copyright
  25 *    notice, this list of conditions and the following disclaimer.
  26 * 2. Redistributions in binary form must reproduce the above copyright
  27 *    notice, this list of conditions and the following disclaimer in the
  28 *    documentation and/or other materials provided with the distribution.
  29 * 3. Neither the name of the Intel Corporation nor the names of its contributors
  30 *    may be used to endorse or promote products derived from this software
  31 *    without specific prior written permission.
  32 * 
  33 * @par
  34 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
  35 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  36 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  37 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
  38 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  39 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  40 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  41 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  42 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  43 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  44 * SUCH DAMAGE.
  45 * 
  46 * @par
  47 * -- End of Copyright Notice --
  48*/
  49
  50
  51/*
  52 * Put the system defined include files required.
  53 */
  54#define IX_NPE_DL_MAX_NUM_OF_RETRIES 1000000 /**< Maximum number of
  55                                              * retries before
  56                                              * timeout
  57                                                                  */  
  58
  59/*
  60 * Put the user defined include files required.
  61 */
  62#include "IxOsal.h"
  63#include "IxNpeDl.h"
  64#include "IxNpeDlNpeMgrUtils_p.h"
  65#include "IxNpeDlNpeMgrEcRegisters_p.h"
  66#include "IxNpeDlMacros_p.h"
  67
  68/*
  69 * #defines and macros used in this file.
  70 */
  71
  72/* used to bit-mask a number of bytes */
  73#define IX_NPEDL_MASK_LOWER_BYTE_OF_WORD  0x000000FF
  74#define IX_NPEDL_MASK_LOWER_SHORT_OF_WORD 0x0000FFFF
  75#define IX_NPEDL_MASK_FULL_WORD           0xFFFFFFFF
  76
  77#define IX_NPEDL_BYTES_PER_WORD           4
  78#define IX_NPEDL_BYTES_PER_SHORT          2
  79
  80#define IX_NPEDL_REG_SIZE_BYTE            8
  81#define IX_NPEDL_REG_SIZE_SHORT           16
  82#define IX_NPEDL_REG_SIZE_WORD            32
  83
  84/*
  85 * Introduce extra read cycles after issuing read command to NPE
  86 * so that we read the register after the NPE has updated it
  87 * This is to overcome race condition between XScale and NPE
  88 */
  89#define IX_NPEDL_DELAY_READ_CYCLES        2
  90/*
  91 * To mask top three MSBs of 32bit word to download into NPE IMEM
  92 */
  93#define IX_NPEDL_MASK_UNUSED_IMEM_BITS    0x1FFFFFFF;
  94
  95
  96/*
  97 * typedefs
  98 */
  99typedef struct
 100{
 101    UINT32 regAddress;
 102    UINT32 regSize;
 103} IxNpeDlCtxtRegAccessInfo;
 104
 105/* module statistics counters */
 106typedef struct
 107{
 108    UINT32 insMemWrites;
 109    UINT32 insMemWriteFails;
 110    UINT32 dataMemWrites;
 111    UINT32 dataMemWriteFails;
 112    UINT32 ecsRegWrites;
 113    UINT32 ecsRegReads;
 114    UINT32 dbgInstructionExecs;
 115    UINT32 contextRegWrites;
 116    UINT32 physicalRegWrites;
 117    UINT32 nextPcWrites;
 118} IxNpeDlNpeMgrUtilsStats;
 119
 120
 121/*
 122 * Variable declarations global to this file only.  Externs are followed by
 123 * static variables.
 124 */
 125
 126/* 
 127 * contains useful address and function pointers to read/write Context Regs, 
 128 * eliminating some switch or if-else statements in places
 129 */
 130static IxNpeDlCtxtRegAccessInfo ixNpeDlCtxtRegAccInfo[IX_NPEDL_CTXT_REG_MAX] =
 131{
 132    {
 133        IX_NPEDL_CTXT_REG_ADDR_STEVT,
 134        IX_NPEDL_REG_SIZE_BYTE
 135    },
 136    {
 137        IX_NPEDL_CTXT_REG_ADDR_STARTPC,
 138        IX_NPEDL_REG_SIZE_SHORT
 139    },
 140    {
 141        IX_NPEDL_CTXT_REG_ADDR_REGMAP,
 142        IX_NPEDL_REG_SIZE_SHORT
 143    },
 144    {
 145        IX_NPEDL_CTXT_REG_ADDR_CINDEX,
 146        IX_NPEDL_REG_SIZE_BYTE
 147    }
 148};
 149
 150static UINT32 ixNpeDlSavedExecCount = 0;
 151static UINT32 ixNpeDlSavedEcsDbgCtxtReg2 = 0;
 152
 153static IxNpeDlNpeMgrUtilsStats ixNpeDlNpeMgrUtilsStats;
 154
 155
 156/*
 157 * static function prototypes.
 158 */
 159PRIVATE __inline__ void
 160ixNpeDlNpeMgrWriteCommandIssue (UINT32 npeBaseAddress, UINT32 cmd,
 161                                UINT32 addr, UINT32 data);
 162
 163PRIVATE __inline__ UINT32
 164ixNpeDlNpeMgrReadCommandIssue (UINT32 npeBaseAddress, UINT32 cmd, UINT32 addr);
 165
 166PRIVATE IX_STATUS
 167ixNpeDlNpeMgrLogicalRegRead (UINT32 npeBaseAddress, UINT32 regAddr,
 168                             UINT32 regSize, UINT32 ctxtNum, UINT32 *regVal);
 169
 170PRIVATE IX_STATUS
 171ixNpeDlNpeMgrLogicalRegWrite (UINT32 npeBaseAddress, UINT32 regAddr,
 172                              UINT32 regVal, UINT32 regSize,
 173                              UINT32 ctxtNum, BOOL verify);
 174
 175/*
 176 * Function definition: ixNpeDlNpeMgrWriteCommandIssue
 177 */
 178PRIVATE __inline__ void
 179ixNpeDlNpeMgrWriteCommandIssue (
 180    UINT32 npeBaseAddress,
 181    UINT32 cmd,
 182    UINT32 addr,
 183    UINT32 data)
 184{
 185    IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXDATA, data);
 186    IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXAD, addr);
 187    IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXCTL, cmd);
 188}
 189
 190
 191/*
 192 * Function definition: ixNpeDlNpeMgrReadCommandIssue
 193 */
 194PRIVATE __inline__ UINT32
 195ixNpeDlNpeMgrReadCommandIssue (
 196    UINT32 npeBaseAddress,
 197    UINT32 cmd,
 198    UINT32 addr)
 199{
 200    UINT32 data = 0;
 201    int i;
 202
 203    IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXAD, addr);
 204    IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXCTL, cmd);
 205    for (i = 0; i <= IX_NPEDL_DELAY_READ_CYCLES; i++)
 206    {
 207        IX_NPEDL_REG_READ (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXDATA, &data);
 208    }
 209
 210    return data;
 211}
 212
 213/*
 214 * Function definition: ixNpeDlNpeMgrInsMemWrite
 215 */
 216IX_STATUS
 217ixNpeDlNpeMgrInsMemWrite (
 218    UINT32 npeBaseAddress,
 219    UINT32 insMemAddress,
 220    UINT32 insMemData,
 221    BOOL verify)
 222{
 223    UINT32 insMemDataRtn;
 224
 225    ixNpeDlNpeMgrWriteCommandIssue (npeBaseAddress,
 226                                    IX_NPEDL_EXCTL_CMD_WR_INS_MEM,
 227                                    insMemAddress, insMemData);
 228    if (verify)
 229    {
 230        /* write invalid data to this reg, so we can see if we're reading 
 231           the EXDATA register too early */
 232        IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXDATA,
 233                            ~insMemData);
 234
 235        /*Disabled since top 3 MSB are not used for Azusa hardware Refer WR:IXA00053900*/
 236        insMemData&=IX_NPEDL_MASK_UNUSED_IMEM_BITS;
 237
 238        insMemDataRtn=ixNpeDlNpeMgrReadCommandIssue (npeBaseAddress,
 239                                           IX_NPEDL_EXCTL_CMD_RD_INS_MEM,
 240                                           insMemAddress);
 241
 242        insMemDataRtn&=IX_NPEDL_MASK_UNUSED_IMEM_BITS;
 243
 244        if (insMemData != insMemDataRtn)
 245        {
 246            ixNpeDlNpeMgrUtilsStats.insMemWriteFails++;
 247            return IX_FAIL;
 248        }
 249    }
 250
 251    ixNpeDlNpeMgrUtilsStats.insMemWrites++;
 252    return IX_SUCCESS;
 253}
 254
 255
 256/*
 257 * Function definition: ixNpeDlNpeMgrDataMemWrite
 258 */
 259IX_STATUS
 260ixNpeDlNpeMgrDataMemWrite (
 261    UINT32 npeBaseAddress,
 262    UINT32 dataMemAddress,
 263    UINT32 dataMemData,
 264    BOOL verify)
 265{
 266    ixNpeDlNpeMgrWriteCommandIssue (npeBaseAddress,
 267                                    IX_NPEDL_EXCTL_CMD_WR_DATA_MEM,
 268                                    dataMemAddress, dataMemData);
 269    if (verify)
 270    {
 271        /* write invalid data to this reg, so we can see if we're reading 
 272           the EXDATA register too early */
 273        IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXDATA, ~dataMemData);
 274
 275        if (dataMemData !=
 276            ixNpeDlNpeMgrReadCommandIssue (npeBaseAddress,
 277                                           IX_NPEDL_EXCTL_CMD_RD_DATA_MEM,
 278                                           dataMemAddress))
 279        {
 280            ixNpeDlNpeMgrUtilsStats.dataMemWriteFails++;
 281            return IX_FAIL;
 282        }
 283    }
 284
 285    ixNpeDlNpeMgrUtilsStats.dataMemWrites++;
 286    return IX_SUCCESS;
 287}
 288
 289
 290/*
 291 * Function definition: ixNpeDlNpeMgrExecAccRegWrite
 292 */
 293void
 294ixNpeDlNpeMgrExecAccRegWrite (
 295    UINT32 npeBaseAddress,
 296    UINT32 regAddress,
 297    UINT32 regData)
 298{
 299    ixNpeDlNpeMgrWriteCommandIssue (npeBaseAddress,
 300                                    IX_NPEDL_EXCTL_CMD_WR_ECS_REG,
 301                                    regAddress, regData);
 302    ixNpeDlNpeMgrUtilsStats.ecsRegWrites++;
 303}
 304
 305
 306/*
 307 * Function definition: ixNpeDlNpeMgrExecAccRegRead
 308 */
 309UINT32
 310ixNpeDlNpeMgrExecAccRegRead (
 311    UINT32 npeBaseAddress,
 312    UINT32 regAddress)
 313{
 314    ixNpeDlNpeMgrUtilsStats.ecsRegReads++;
 315    return ixNpeDlNpeMgrReadCommandIssue (npeBaseAddress,
 316                                          IX_NPEDL_EXCTL_CMD_RD_ECS_REG,
 317                                          regAddress);
 318}
 319
 320
 321/*
 322 * Function definition: ixNpeDlNpeMgrCommandIssue
 323 */
 324void
 325ixNpeDlNpeMgrCommandIssue (
 326    UINT32 npeBaseAddress,
 327    UINT32 command)     
 328{
 329    IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
 330                     "Entering ixNpeDlNpeMgrCommandIssue\n");
 331
 332    IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXCTL, command);
 333
 334    IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
 335                     "Exiting ixNpeDlNpeMgrCommandIssue\n");
 336}
 337
 338
 339/*
 340 * Function definition: ixNpeDlNpeMgrDebugInstructionPreExec
 341 */
 342void
 343ixNpeDlNpeMgrDebugInstructionPreExec(
 344    UINT32 npeBaseAddress)
 345{
 346    /* turn off the halt bit by clearing Execution Count register. */
 347    /* save reg contents 1st and restore later */
 348    IX_NPEDL_REG_READ (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXCT,
 349                       &ixNpeDlSavedExecCount);
 350    IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXCT, 0);
 351
 352    /* ensure that IF and IE are on (temporarily), so that we don't end up
 353     * stepping forever */
 354    ixNpeDlSavedEcsDbgCtxtReg2 = ixNpeDlNpeMgrExecAccRegRead (npeBaseAddress,
 355                                                   IX_NPEDL_ECS_DBG_CTXT_REG_2);
 356
 357    ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_DBG_CTXT_REG_2,
 358                                  (ixNpeDlSavedEcsDbgCtxtReg2 |
 359                                   IX_NPEDL_MASK_ECS_DBG_REG_2_IF |
 360                                   IX_NPEDL_MASK_ECS_DBG_REG_2_IE));
 361}
 362
 363
 364/*
 365 * Function definition: ixNpeDlNpeMgrDebugInstructionExec
 366 */
 367IX_STATUS
 368ixNpeDlNpeMgrDebugInstructionExec(
 369    UINT32 npeBaseAddress,
 370    UINT32 npeInstruction,
 371    UINT32 ctxtNum,
 372    UINT32 ldur)
 373{
 374    UINT32 ecsDbgRegVal;
 375    UINT32 oldWatchcount, newWatchcount;
 376    UINT32 retriesCount = 0;
 377    IX_STATUS status = IX_SUCCESS;
 378
 379    IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
 380                     "Entering ixNpeDlNpeMgrDebugInstructionExec\n");
 381
 382    /* set the Active bit, and the LDUR, in the debug level */
 383    ecsDbgRegVal = IX_NPEDL_MASK_ECS_REG_0_ACTIVE |
 384        (ldur << IX_NPEDL_OFFSET_ECS_REG_0_LDUR);
 385
 386    ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_DBG_CTXT_REG_0,
 387                                  ecsDbgRegVal);
 388
 389    /*
 390     * set CCTXT at ECS DEBUG L3 to specify in which context to execute the
 391     * instruction, and set SELCTXT at ECS DEBUG Level to specify which context
 392     * store to access.
 393     * Debug ECS Level Reg 1 has form  0x000n000n, where n = context number
 394     */
 395    ecsDbgRegVal = (ctxtNum << IX_NPEDL_OFFSET_ECS_REG_1_CCTXT) |
 396        (ctxtNum << IX_NPEDL_OFFSET_ECS_REG_1_SELCTXT);
 397
 398    ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_DBG_CTXT_REG_1,
 399                                  ecsDbgRegVal);
 400
 401    /* clear the pipeline */
 402    ixNpeDlNpeMgrCommandIssue (npeBaseAddress, IX_NPEDL_EXCTL_CMD_NPE_CLR_PIPE);
 403
 404    /* load NPE instruction into the instruction register */
 405    ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_INSTRUCT_REG,
 406                                  npeInstruction);
 407
 408    /* we need this value later to wait for completion of NPE execution step */
 409    IX_NPEDL_REG_READ (npeBaseAddress, IX_NPEDL_REG_OFFSET_WC, &oldWatchcount);
 410
 411    /* issue a Step One command via the Execution Control register */
 412    ixNpeDlNpeMgrCommandIssue (npeBaseAddress, IX_NPEDL_EXCTL_CMD_NPE_STEP);
 413
 414        /* Watch Count register increments when NPE completes an instruction */
 415        IX_NPEDL_REG_READ (npeBaseAddress, IX_NPEDL_REG_OFFSET_WC,
 416        &newWatchcount);
 417        
 418    /*
 419     * force the XScale to wait until the NPE has finished execution step
 420     * NOTE that this delay will be very small, just long enough to allow a
 421     * single NPE instruction to complete execution; if instruction execution
 422     * is not completed before timeout retries, exit the while loop
 423     */
 424    while ((IX_NPE_DL_MAX_NUM_OF_RETRIES > retriesCount) 
 425        && (newWatchcount == oldWatchcount))
 426    {
 427            /* Watch Count register increments when NPE completes an instruction */
 428            IX_NPEDL_REG_READ (npeBaseAddress, IX_NPEDL_REG_OFFSET_WC,
 429                    &newWatchcount);
 430                           
 431        retriesCount++;
 432    }    
 433
 434    if (IX_NPE_DL_MAX_NUM_OF_RETRIES > retriesCount)
 435    {
 436        ixNpeDlNpeMgrUtilsStats.dbgInstructionExecs++;
 437    }
 438    else
 439    {
 440        /* Return timeout status as the instruction has not been executed
 441         * after maximum retries */
 442        status = IX_NPEDL_CRITICAL_NPE_ERR;
 443    }
 444    
 445    IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
 446                     "Exiting ixNpeDlNpeMgrDebugInstructionExec\n");
 447                     
 448    return status;
 449}    
 450
 451
 452/*
 453 * Function definition: ixNpeDlNpeMgrDebugInstructionPostExec
 454 */
 455void
 456ixNpeDlNpeMgrDebugInstructionPostExec(
 457    UINT32 npeBaseAddress)
 458{
 459    /* clear active bit in debug level */
 460    ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_DBG_CTXT_REG_0,
 461                                  0);
 462
 463    /* clear the pipeline */
 464    ixNpeDlNpeMgrCommandIssue (npeBaseAddress, IX_NPEDL_EXCTL_CMD_NPE_CLR_PIPE);
 465    
 466    /* restore Execution Count register contents. */
 467    IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXCT,
 468                        ixNpeDlSavedExecCount);
 469
 470    /* restore IF and IE bits to original values */
 471    ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_DBG_CTXT_REG_2,
 472                                  ixNpeDlSavedEcsDbgCtxtReg2);
 473}
 474
 475
 476/*
 477 * Function definition: ixNpeDlNpeMgrLogicalRegRead
 478 */
 479PRIVATE IX_STATUS
 480ixNpeDlNpeMgrLogicalRegRead (
 481    UINT32 npeBaseAddress, 
 482    UINT32 regAddr,
 483    UINT32 regSize,
 484    UINT32 ctxtNum,
 485    UINT32 *regVal)
 486{
 487    IX_STATUS status = IX_SUCCESS;
 488    UINT32 npeInstruction = 0;
 489    UINT32 mask = 0;
 490
 491    IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
 492                     "Entering ixNpeDlNpeMgrLogicalRegRead\n");
 493
 494    switch (regSize)
 495    {
 496    case IX_NPEDL_REG_SIZE_BYTE:
 497      npeInstruction = IX_NPEDL_INSTR_RD_REG_BYTE;
 498      mask = IX_NPEDL_MASK_LOWER_BYTE_OF_WORD;  break;
 499    case IX_NPEDL_REG_SIZE_SHORT:
 500      npeInstruction = IX_NPEDL_INSTR_RD_REG_SHORT;
 501      mask = IX_NPEDL_MASK_LOWER_SHORT_OF_WORD;  break;
 502    case IX_NPEDL_REG_SIZE_WORD:
 503      npeInstruction = IX_NPEDL_INSTR_RD_REG_WORD;
 504      mask = IX_NPEDL_MASK_FULL_WORD;  break;
 505    }
 506
 507    /* make regAddr be the SRC and DEST operands (e.g. movX d0, d0) */
 508    npeInstruction |= (regAddr << IX_NPEDL_OFFSET_INSTR_SRC) |
 509        (regAddr << IX_NPEDL_OFFSET_INSTR_DEST);
 510
 511    /* step execution of NPE intruction using Debug Executing Context stack */
 512    status = ixNpeDlNpeMgrDebugInstructionExec (npeBaseAddress, npeInstruction,
 513                                       ctxtNum, IX_NPEDL_RD_INSTR_LDUR);
 514
 515    if (IX_SUCCESS != status)
 516    {
 517        return status;
 518    }
 519    
 520    /* read value of register from Execution Data register */
 521    IX_NPEDL_REG_READ (npeBaseAddress,  IX_NPEDL_REG_OFFSET_EXDATA, regVal);
 522
 523   /* align value from left to right */
 524    *regVal = (*regVal >> (IX_NPEDL_REG_SIZE_WORD - regSize)) & mask;
 525
 526    IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
 527                     "Exiting ixNpeDlNpeMgrLogicalRegRead\n");
 528    
 529    return IX_SUCCESS;
 530}
 531
 532
 533/*
 534 * Function definition: ixNpeDlNpeMgrLogicalRegWrite
 535 */
 536PRIVATE IX_STATUS
 537ixNpeDlNpeMgrLogicalRegWrite (
 538    UINT32 npeBaseAddress, 
 539    UINT32 regAddr,
 540    UINT32 regVal,
 541    UINT32 regSize,
 542    UINT32 ctxtNum,
 543    BOOL verify)
 544{
 545    UINT32 npeInstruction = 0;
 546    UINT32 mask = 0;
 547    IX_STATUS status = IX_SUCCESS;
 548    UINT32 retRegVal;
 549
 550    IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
 551                     "Entering ixNpeDlNpeMgrLogicalRegWrite\n");
 552
 553    if (regSize == IX_NPEDL_REG_SIZE_WORD)
 554    {
 555        /* NPE register addressing is left-to-right: e.g. |d0|d1|d2|d3| */
 556        /* Write upper half-word (short) to |d0|d1| */
 557        status = ixNpeDlNpeMgrLogicalRegWrite (npeBaseAddress, regAddr,
 558                                      regVal >> IX_NPEDL_REG_SIZE_SHORT,
 559                                      IX_NPEDL_REG_SIZE_SHORT,
 560                                      ctxtNum, verify);
 561                                      
 562        if (IX_SUCCESS != status)
 563        {
 564            return status;
 565        }
 566        
 567        /* Write lower half-word (short) to |d2|d3| */
 568        status = ixNpeDlNpeMgrLogicalRegWrite (npeBaseAddress,
 569                                      regAddr + IX_NPEDL_BYTES_PER_SHORT,
 570                                    regVal & IX_NPEDL_MASK_LOWER_SHORT_OF_WORD,
 571                                      IX_NPEDL_REG_SIZE_SHORT,
 572                                      ctxtNum, verify);
 573    
 574    if (IX_SUCCESS != status)
 575        {
 576            return status;
 577        }
 578        }
 579    else
 580    {
 581        switch (regSize)
 582        { 
 583        case IX_NPEDL_REG_SIZE_BYTE:
 584            npeInstruction = IX_NPEDL_INSTR_WR_REG_BYTE;
 585            mask = IX_NPEDL_MASK_LOWER_BYTE_OF_WORD;  break;
 586        case IX_NPEDL_REG_SIZE_SHORT:
 587            npeInstruction = IX_NPEDL_INSTR_WR_REG_SHORT;
 588            mask = IX_NPEDL_MASK_LOWER_SHORT_OF_WORD;  break;
 589        }
 590        /* mask out any redundant bits, so verify will work later */
 591        regVal &= mask;
 592
 593        /* fill dest operand field of  instruction with destination reg addr */
 594        npeInstruction |= (regAddr << IX_NPEDL_OFFSET_INSTR_DEST);
 595
 596        /* fill src operand field of instruction with least-sig 5 bits of val*/
 597        npeInstruction |= ((regVal & IX_NPEDL_MASK_IMMED_INSTR_SRC_DATA) <<
 598                           IX_NPEDL_OFFSET_INSTR_SRC);
 599
 600        /* fill coprocessor field of instruction with most-sig 11 bits of val*/
 601        npeInstruction |= ((regVal & IX_NPEDL_MASK_IMMED_INSTR_COPROC_DATA) <<
 602                           IX_NPEDL_DISPLACE_IMMED_INSTR_COPROC_DATA);
 603
 604        /* step execution of NPE intruction using Debug ECS */
 605        status = ixNpeDlNpeMgrDebugInstructionExec(npeBaseAddress, npeInstruction,
 606                                          ctxtNum, IX_NPEDL_WR_INSTR_LDUR);
 607                                          
 608        if (IX_SUCCESS != status)
 609        {
 610            return status;  
 611        } 
 612    }/* condition: if reg to be written is 8-bit or 16-bit (not 32-bit) */
 613
 614    if (verify)
 615    {
 616        status = ixNpeDlNpeMgrLogicalRegRead (npeBaseAddress, regAddr,
 617                                                   regSize, ctxtNum, &retRegVal);
 618                                                   
 619        if (IX_SUCCESS == status)
 620        {
 621            if (regVal != retRegVal)
 622            {
 623                status = IX_FAIL;
 624            }
 625        }        
 626    }
 627
 628    IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
 629                     "Exiting ixNpeDlNpeMgrLogicalRegWrite : status = %d\n",
 630                     status);
 631    
 632    return status;
 633}
 634
 635
 636/*
 637 * Function definition: ixNpeDlNpeMgrPhysicalRegWrite
 638 */
 639IX_STATUS
 640ixNpeDlNpeMgrPhysicalRegWrite (
 641    UINT32 npeBaseAddress,
 642    UINT32 regAddr,
 643    UINT32 regValue,
 644    BOOL verify)
 645{
 646    IX_STATUS status;
 647
 648    IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
 649                     "Entering ixNpeDlNpeMgrPhysicalRegWrite\n");
 650
 651/*
 652 * There are 32 physical registers used in an NPE.  These are
 653 * treated as 16 pairs of 32-bit registers.  To write one of the pair,
 654 * write the pair number (0-16) to the REGMAP for Context 0.  Then write
 655 * the value to register  0 or 4 in the regfile, depending on which
 656 * register of the pair is to be written
 657 */
 658
 659    /*
 660     * set REGMAP for context 0 to (regAddr >> 1) to choose which pair (0-16)
 661     * of physical registers to write 
 662     */
 663    status = ixNpeDlNpeMgrLogicalRegWrite (npeBaseAddress,
 664                                           IX_NPEDL_CTXT_REG_ADDR_REGMAP,
 665                                           (regAddr >>
 666                                          IX_NPEDL_OFFSET_PHYS_REG_ADDR_REGMAP),
 667                                           IX_NPEDL_REG_SIZE_SHORT, 0, verify);
 668    if (status == IX_SUCCESS)
 669    {
 670        /* regAddr = 0 or 4  */
 671        regAddr = (regAddr & IX_NPEDL_MASK_PHYS_REG_ADDR_LOGICAL_ADDR) *
 672            IX_NPEDL_BYTES_PER_WORD;
 673    
 674    status = ixNpeDlNpeMgrLogicalRegWrite (npeBaseAddress, regAddr, regValue, 
 675                                           IX_NPEDL_REG_SIZE_WORD, 0, verify);
 676    }
 677    
 678    if (status != IX_SUCCESS)
 679    {
 680        IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrPhysicalRegWrite: "
 681                               "error writing to physical register\n");
 682    }
 683
 684    ixNpeDlNpeMgrUtilsStats.physicalRegWrites++;
 685
 686    IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
 687                     "Exiting ixNpeDlNpeMgrPhysicalRegWrite : status = %d\n",
 688                     status);
 689    return status;
 690}
 691
 692
 693/*
 694 * Function definition: ixNpeDlNpeMgrCtxtRegWrite
 695 */
 696IX_STATUS
 697ixNpeDlNpeMgrCtxtRegWrite (
 698    UINT32 npeBaseAddress,
 699    UINT32 ctxtNum,
 700    IxNpeDlCtxtRegNum ctxtReg,
 701    UINT32 ctxtRegVal,
 702    BOOL verify)
 703{
 704    UINT32 tempRegVal;
 705    UINT32 ctxtRegAddr;
 706    UINT32 ctxtRegSize;
 707    IX_STATUS status = IX_SUCCESS;
 708
 709    IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, 
 710                     "Entering ixNpeDlNpeMgrCtxtRegWrite\n");
 711
 712    /*
 713     * Context 0 has no STARTPC. Instead, this value is used to set
 714     * NextPC for Background ECS, to set where NPE starts executing code
 715     */
 716    if ((ctxtNum == 0) && (ctxtReg == IX_NPEDL_CTXT_REG_STARTPC))
 717    {
 718        /* read BG_CTXT_REG_0, update NEXTPC bits, and write back to reg */
 719        tempRegVal = ixNpeDlNpeMgrExecAccRegRead (npeBaseAddress,
 720                                                  IX_NPEDL_ECS_BG_CTXT_REG_0);
 721        tempRegVal &= ~IX_NPEDL_MASK_ECS_REG_0_NEXTPC;
 722        tempRegVal |= (ctxtRegVal << IX_NPEDL_OFFSET_ECS_REG_0_NEXTPC) &
 723            IX_NPEDL_MASK_ECS_REG_0_NEXTPC;
 724        
 725        ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress,
 726                                      IX_NPEDL_ECS_BG_CTXT_REG_0, tempRegVal);
 727
 728        ixNpeDlNpeMgrUtilsStats.nextPcWrites++;
 729    }
 730    else
 731    {
 732        ctxtRegAddr = ixNpeDlCtxtRegAccInfo[ctxtReg].regAddress;
 733        ctxtRegSize = ixNpeDlCtxtRegAccInfo[ctxtReg].regSize;
 734        status = ixNpeDlNpeMgrLogicalRegWrite (npeBaseAddress, ctxtRegAddr,
 735                                               ctxtRegVal, ctxtRegSize,
 736                                               ctxtNum, verify);
 737        if (status != IX_SUCCESS)
 738        {
 739            IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrCtxtRegWrite: "
 740                                   "error writing to context store register\n");
 741        }
 742        
 743        ixNpeDlNpeMgrUtilsStats.contextRegWrites++;
 744    }
 745
 746    IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT, 
 747                     "Exiting ixNpeDlNpeMgrCtxtRegWrite : status = %d\n",
 748                     status);
 749
 750    return status;
 751}
 752
 753
 754/*
 755 * Function definition: ixNpeDlNpeMgrUtilsStatsShow
 756 */
 757void
 758ixNpeDlNpeMgrUtilsStatsShow (void)
 759{
 760    ixOsalLog (IX_OSAL_LOG_LVL_USER,
 761               IX_OSAL_LOG_DEV_STDOUT,
 762               "\nixNpeDlNpeMgrUtilsStatsShow:\n"
 763               "\tInstruction Memory writes: %u\n"
 764               "\tInstruction Memory writes failed: %u\n"
 765               "\tData Memory writes: %u\n"
 766               "\tData Memory writes failed: %u\n",
 767               ixNpeDlNpeMgrUtilsStats.insMemWrites,
 768               ixNpeDlNpeMgrUtilsStats.insMemWriteFails,
 769               ixNpeDlNpeMgrUtilsStats.dataMemWrites,
 770               ixNpeDlNpeMgrUtilsStats.dataMemWriteFails,
 771               0,0);
 772
 773    ixOsalLog (IX_OSAL_LOG_LVL_USER,
 774               IX_OSAL_LOG_DEV_STDOUT,
 775               "\tExecuting Context Stack Register writes: %u\n"
 776               "\tExecuting Context Stack Register reads: %u\n"
 777               "\tPhysical Register writes: %u\n"
 778               "\tContext Store Register writes: %u\n"
 779               "\tExecution Backgound Context NextPC writes: %u\n"
 780               "\tDebug Instructions Executed: %u\n\n",
 781               ixNpeDlNpeMgrUtilsStats.ecsRegWrites,
 782               ixNpeDlNpeMgrUtilsStats.ecsRegReads,
 783               ixNpeDlNpeMgrUtilsStats.physicalRegWrites,
 784               ixNpeDlNpeMgrUtilsStats.contextRegWrites,
 785               ixNpeDlNpeMgrUtilsStats.nextPcWrites,
 786               ixNpeDlNpeMgrUtilsStats.dbgInstructionExecs);
 787}
 788
 789
 790/*
 791 * Function definition: ixNpeDlNpeMgrUtilsStatsReset
 792 */
 793void
 794ixNpeDlNpeMgrUtilsStatsReset (void)
 795{
 796    ixNpeDlNpeMgrUtilsStats.insMemWrites = 0;
 797    ixNpeDlNpeMgrUtilsStats.insMemWriteFails = 0;
 798    ixNpeDlNpeMgrUtilsStats.dataMemWrites = 0;
 799    ixNpeDlNpeMgrUtilsStats.dataMemWriteFails = 0;
 800    ixNpeDlNpeMgrUtilsStats.ecsRegWrites = 0;
 801    ixNpeDlNpeMgrUtilsStats.ecsRegReads = 0;
 802    ixNpeDlNpeMgrUtilsStats.physicalRegWrites = 0;
 803    ixNpeDlNpeMgrUtilsStats.contextRegWrites = 0;
 804    ixNpeDlNpeMgrUtilsStats.nextPcWrites = 0;
 805    ixNpeDlNpeMgrUtilsStats.dbgInstructionExecs = 0;
 806}
 807