2 * @file IxNpeDlNpeMgr.c
4 * @author Intel Corporation
5 * @date 09 January 2002
7 * @brief This file contains the implementation of the private API for the
8 * IXP425 NPE Downloader NpeMgr module
12 * IXP400 SW Release version 2.0
14 * -- Copyright Notice --
17 * Copyright 2001-2005, Intel Corporation.
18 * All rights reserved.
21 * Redistribution and use in source and binary forms, with or without
22 * modification, are permitted provided that the following conditions
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.
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
47 * -- End of Copyright Notice --
52 * Put the user defined include files required.
57 * Put the user defined include files required.
61 #include "IxNpeDlNpeMgr_p.h"
62 #include "IxNpeDlNpeMgrUtils_p.h"
63 #include "IxNpeDlNpeMgrEcRegisters_p.h"
64 #include "IxNpeDlMacros_p.h"
65 #include "IxFeatureCtrl.h"
68 * #defines and macros used in this file.
70 #define IX_NPEDL_BYTES_PER_WORD 4
72 /* used to read download map from version in microcode image */
73 #define IX_NPEDL_BLOCK_TYPE_INSTRUCTION 0x00000000
74 #define IX_NPEDL_BLOCK_TYPE_DATA 0x00000001
75 #define IX_NPEDL_BLOCK_TYPE_STATE 0x00000002
76 #define IX_NPEDL_END_OF_DOWNLOAD_MAP 0x0000000F
79 * masks used to extract address info from State information context
80 * register addresses as read from microcode image
82 #define IX_NPEDL_MASK_STATE_ADDR_CTXT_REG 0x0000000F
83 #define IX_NPEDL_MASK_STATE_ADDR_CTXT_NUM 0x000000F0
85 /* LSB offset of Context Number field in State-Info Context Address */
86 #define IX_NPEDL_OFFSET_STATE_ADDR_CTXT_NUM 4
88 /* size (in words) of single State Information entry (ctxt reg address|data) */
89 #define IX_NPEDL_STATE_INFO_ENTRY_SIZE 2
92 #define IX_NPEDL_RESET_NPE_PARITY 0x0800
93 #define IX_NPEDL_PARITY_BIT_MASK 0x3F00FFFF
94 #define IX_NPEDL_CONFIG_CTRL_REG_MASK 0x3F3FFFFF
98 * Typedefs whose scope is limited to this file.
105 } IxNpeDlNpeMgrDownloadMapBlockEntry;
109 IxNpeDlNpeMgrDownloadMapBlockEntry block;
111 } IxNpeDlNpeMgrDownloadMapEntry;
115 /* 1st entry in the download map (there may be more than one) */
116 IxNpeDlNpeMgrDownloadMapEntry entry[1];
117 } IxNpeDlNpeMgrDownloadMap;
120 /* used to access an instruction or data block in a microcode image */
123 UINT32 npeMemAddress;
126 } IxNpeDlNpeMgrCodeBlock;
128 /* used to access each Context Reg entry state-information block */
133 } IxNpeDlNpeMgrStateInfoCtxtRegEntry;
135 /* used to access a state-information block in a microcode image */
139 IxNpeDlNpeMgrStateInfoCtxtRegEntry ctxtRegEntry[1];
140 } IxNpeDlNpeMgrStateInfoBlock;
142 /* used to store some useful NPE information for easy access */
150 /* used to distinguish instruction and data memory operations */
153 IX_NPEDL_MEM_TYPE_INSTRUCTION = 0,
154 IX_NPEDL_MEM_TYPE_DATA
157 /* used to hold a reset value for a particular ECS register */
162 } IxNpeDlEcsRegResetValue;
164 /* prototype of function to write either Instruction or Data memory */
165 typedef IX_STATUS (*IxNpeDlNpeMgrMemWrite) (UINT32 npeBaseAddress,
166 UINT32 npeMemAddress,
170 /* module statistics counters */
173 UINT32 instructionBlocksLoaded;
174 UINT32 dataBlocksLoaded;
175 UINT32 stateInfoBlocksLoaded;
176 UINT32 criticalNpeErrors;
177 UINT32 criticalMicrocodeErrors;
181 } IxNpeDlNpeMgrStats;
185 * Variable declarations global to this file only. Externs are followed by
188 static IxNpeDlNpeInfo ixNpeDlNpeInfo[] =
192 IX_NPEDL_INS_MEMSIZE_WORDS_NPEA,
193 IX_NPEDL_DATA_MEMSIZE_WORDS_NPEA
197 IX_NPEDL_INS_MEMSIZE_WORDS_NPEB,
198 IX_NPEDL_DATA_MEMSIZE_WORDS_NPEB
202 IX_NPEDL_INS_MEMSIZE_WORDS_NPEC,
203 IX_NPEDL_DATA_MEMSIZE_WORDS_NPEC
207 /* contains Reset values for Context Store Registers */
208 static UINT32 ixNpeDlCtxtRegResetValues[] =
210 IX_NPEDL_CTXT_REG_RESET_STEVT,
211 IX_NPEDL_CTXT_REG_RESET_STARTPC,
212 IX_NPEDL_CTXT_REG_RESET_REGMAP,
213 IX_NPEDL_CTXT_REG_RESET_CINDEX,
216 /* contains Reset values for Context Store Registers */
217 static IxNpeDlEcsRegResetValue ixNpeDlEcsRegResetValues[] =
219 {IX_NPEDL_ECS_BG_CTXT_REG_0, IX_NPEDL_ECS_BG_CTXT_REG_0_RESET},
220 {IX_NPEDL_ECS_BG_CTXT_REG_1, IX_NPEDL_ECS_BG_CTXT_REG_1_RESET},
221 {IX_NPEDL_ECS_BG_CTXT_REG_2, IX_NPEDL_ECS_BG_CTXT_REG_2_RESET},
222 {IX_NPEDL_ECS_PRI_1_CTXT_REG_0, IX_NPEDL_ECS_PRI_1_CTXT_REG_0_RESET},
223 {IX_NPEDL_ECS_PRI_1_CTXT_REG_1, IX_NPEDL_ECS_PRI_1_CTXT_REG_1_RESET},
224 {IX_NPEDL_ECS_PRI_1_CTXT_REG_2, IX_NPEDL_ECS_PRI_1_CTXT_REG_2_RESET},
225 {IX_NPEDL_ECS_PRI_2_CTXT_REG_0, IX_NPEDL_ECS_PRI_2_CTXT_REG_0_RESET},
226 {IX_NPEDL_ECS_PRI_2_CTXT_REG_1, IX_NPEDL_ECS_PRI_2_CTXT_REG_1_RESET},
227 {IX_NPEDL_ECS_PRI_2_CTXT_REG_2, IX_NPEDL_ECS_PRI_2_CTXT_REG_2_RESET},
228 {IX_NPEDL_ECS_DBG_CTXT_REG_0, IX_NPEDL_ECS_DBG_CTXT_REG_0_RESET},
229 {IX_NPEDL_ECS_DBG_CTXT_REG_1, IX_NPEDL_ECS_DBG_CTXT_REG_1_RESET},
230 {IX_NPEDL_ECS_DBG_CTXT_REG_2, IX_NPEDL_ECS_DBG_CTXT_REG_2_RESET},
231 {IX_NPEDL_ECS_INSTRUCT_REG, IX_NPEDL_ECS_INSTRUCT_REG_RESET}
234 static IxNpeDlNpeMgrStats ixNpeDlNpeMgrStats;
236 /* Set when NPE register memory has been mapped */
237 static BOOL ixNpeDlMemInitialised = FALSE;
241 * static function prototypes.
244 ixNpeDlNpeMgrMemLoad (IxNpeDlNpeId npeId, UINT32 npeBaseAddress,
245 IxNpeDlNpeMgrCodeBlock *codeBlockPtr,
246 BOOL verify, IxNpeDlNpeMemType npeMemType);
248 ixNpeDlNpeMgrStateInfoLoad (UINT32 npeBaseAddress,
249 IxNpeDlNpeMgrStateInfoBlock *codeBlockPtr,
252 ixNpeDlNpeMgrBitsSetCheck (UINT32 npeBaseAddress, UINT32 regOffset,
253 UINT32 expectedBitsSet);
256 ixNpeDlNpeMgrBaseAddressGet (IxNpeDlNpeId npeId);
259 * Function definition: ixNpeDlNpeMgrBaseAddressGet
262 ixNpeDlNpeMgrBaseAddressGet (IxNpeDlNpeId npeId)
264 IX_OSAL_ASSERT (ixNpeDlMemInitialised);
265 return ixNpeDlNpeInfo[npeId].baseAddress;
270 * Function definition: ixNpeDlNpeMgrInit
273 ixNpeDlNpeMgrInit (void)
275 /* Only map the memory once */
276 if (!ixNpeDlMemInitialised)
280 /* map the register memory for NPE-A */
281 virtAddr = (UINT32) IX_OSAL_MEM_MAP (IX_NPEDL_NPEBASEADDRESS_NPEA,
282 IX_OSAL_IXP400_NPEA_MAP_SIZE);
283 IX_OSAL_ASSERT(virtAddr);
284 ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEA].baseAddress = virtAddr;
286 /* map the register memory for NPE-B */
287 virtAddr = (UINT32) IX_OSAL_MEM_MAP (IX_NPEDL_NPEBASEADDRESS_NPEB,
288 IX_OSAL_IXP400_NPEB_MAP_SIZE);
289 IX_OSAL_ASSERT(virtAddr);
290 ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEB].baseAddress = virtAddr;
292 /* map the register memory for NPE-C */
293 virtAddr = (UINT32) IX_OSAL_MEM_MAP (IX_NPEDL_NPEBASEADDRESS_NPEC,
294 IX_OSAL_IXP400_NPEC_MAP_SIZE);
295 IX_OSAL_ASSERT(virtAddr);
296 ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEC].baseAddress = virtAddr;
298 ixNpeDlMemInitialised = TRUE;
304 * Function definition: ixNpeDlNpeMgrUninit
307 ixNpeDlNpeMgrUninit (void)
309 if (!ixNpeDlMemInitialised)
314 IX_OSAL_MEM_UNMAP (ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEA].baseAddress);
315 IX_OSAL_MEM_UNMAP (ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEB].baseAddress);
316 IX_OSAL_MEM_UNMAP (ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEC].baseAddress);
318 ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEA].baseAddress = 0;
319 ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEB].baseAddress = 0;
320 ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEC].baseAddress = 0;
322 ixNpeDlMemInitialised = FALSE;
328 * Function definition: ixNpeDlNpeMgrImageLoad
331 ixNpeDlNpeMgrImageLoad (
333 UINT32 *imageCodePtr,
336 UINT32 npeBaseAddress;
337 IxNpeDlNpeMgrDownloadMap *downloadMap;
340 IX_STATUS status = IX_SUCCESS;
342 IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
343 "Entering ixNpeDlNpeMgrImageLoad\n");
345 /* get base memory address of NPE from npeId */
346 npeBaseAddress = ixNpeDlNpeMgrBaseAddressGet (npeId);
348 /* check execution status of NPE to verify NPE Stop was successful */
349 if (!ixNpeDlNpeMgrBitsSetCheck (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXCTL,
350 IX_NPEDL_EXCTL_STATUS_STOP))
352 IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrImageDownload - "
353 "NPE was not stopped before download\n");
359 * Read Download Map, checking each block type and calling
360 * appropriate function to perform download
362 downloadMap = (IxNpeDlNpeMgrDownloadMap *) imageCodePtr;
363 while ((downloadMap->entry[mapIndex].eodmMarker !=
364 IX_NPEDL_END_OF_DOWNLOAD_MAP)
365 && (status == IX_SUCCESS))
367 /* calculate pointer to block to be downloaded */
368 blockPtr = imageCodePtr +
369 downloadMap->entry[mapIndex].block.offset;
371 switch (downloadMap->entry[mapIndex].block.type)
373 case IX_NPEDL_BLOCK_TYPE_INSTRUCTION:
374 status = ixNpeDlNpeMgrMemLoad (npeId, npeBaseAddress,
375 (IxNpeDlNpeMgrCodeBlock *)blockPtr,
377 IX_NPEDL_MEM_TYPE_INSTRUCTION);
379 case IX_NPEDL_BLOCK_TYPE_DATA:
380 status = ixNpeDlNpeMgrMemLoad (npeId, npeBaseAddress,
381 (IxNpeDlNpeMgrCodeBlock *)blockPtr,
382 verify, IX_NPEDL_MEM_TYPE_DATA);
384 case IX_NPEDL_BLOCK_TYPE_STATE:
385 status = ixNpeDlNpeMgrStateInfoLoad (npeBaseAddress,
386 (IxNpeDlNpeMgrStateInfoBlock *) blockPtr,
390 IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrImageLoad: "
391 "unknown block type in download map\n");
392 status = IX_NPEDL_CRITICAL_MICROCODE_ERR;
393 ixNpeDlNpeMgrStats.criticalMicrocodeErrors++;
397 }/* loop: for each entry in download map, while status == SUCCESS */
398 }/* condition: NPE stopped before attempting download */
400 IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
401 "Exiting ixNpeDlNpeMgrImageLoad : status = %d\n",
408 * Function definition: ixNpeDlNpeMgrMemLoad
411 ixNpeDlNpeMgrMemLoad (
413 UINT32 npeBaseAddress,
414 IxNpeDlNpeMgrCodeBlock *blockPtr,
416 IxNpeDlNpeMemType npeMemType)
418 UINT32 npeMemAddress;
421 IxNpeDlNpeMgrMemWrite memWriteFunc = NULL;
422 UINT32 localIndex = 0;
423 IX_STATUS status = IX_SUCCESS;
425 IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
426 "Entering ixNpeDlNpeMgrMemLoad\n");
429 * select NPE EXCTL reg read/write commands depending on memory
430 * type (instruction/data) to be accessed
432 if (npeMemType == IX_NPEDL_MEM_TYPE_INSTRUCTION)
434 memSize = ixNpeDlNpeInfo[npeId].insMemSize;
435 memWriteFunc = (IxNpeDlNpeMgrMemWrite) ixNpeDlNpeMgrInsMemWrite;
437 else if (npeMemType == IX_NPEDL_MEM_TYPE_DATA)
439 memSize = ixNpeDlNpeInfo[npeId].dataMemSize;
440 memWriteFunc = (IxNpeDlNpeMgrMemWrite) ixNpeDlNpeMgrDataMemWrite;
444 * NPE memory is loaded contiguously from each block, so only address
445 * of 1st word in block is needed
447 npeMemAddress = blockPtr->npeMemAddress;
448 /* number of words of instruction/data microcode in block to download */
449 blockSize = blockPtr->size;
450 if ((npeMemAddress + blockSize) > memSize)
452 IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrMemLoad: "
453 "Block size too big for NPE memory\n");
454 status = IX_NPEDL_CRITICAL_MICROCODE_ERR;
455 ixNpeDlNpeMgrStats.criticalMicrocodeErrors++;
459 for (localIndex = 0; localIndex < blockSize; localIndex++)
461 status = memWriteFunc (npeBaseAddress, npeMemAddress,
462 blockPtr->data[localIndex], verify);
464 if (status != IX_SUCCESS)
466 IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrMemLoad: "
467 "write to NPE memory failed\n");
468 status = IX_NPEDL_CRITICAL_NPE_ERR;
469 ixNpeDlNpeMgrStats.criticalNpeErrors++;
470 break; /* abort download */
472 /* increment target (word)address in NPE memory */
475 }/* condition: block size will fit in NPE memory */
477 if (status == IX_SUCCESS)
479 if (npeMemType == IX_NPEDL_MEM_TYPE_INSTRUCTION)
481 ixNpeDlNpeMgrStats.instructionBlocksLoaded++;
483 else if (npeMemType == IX_NPEDL_MEM_TYPE_DATA)
485 ixNpeDlNpeMgrStats.dataBlocksLoaded++;
489 IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
490 "Exiting ixNpeDlNpeMgrMemLoad : status = %d\n", status);
496 * Function definition: ixNpeDlNpeMgrStateInfoLoad
499 ixNpeDlNpeMgrStateInfoLoad (
500 UINT32 npeBaseAddress,
501 IxNpeDlNpeMgrStateInfoBlock *blockPtr,
505 UINT32 ctxtRegAddrInfo;
507 IxNpeDlCtxtRegNum ctxtReg; /* identifies Context Store reg (0-3) */
508 UINT32 ctxtNum; /* identifies Context number (0-16) */
510 IX_STATUS status = IX_SUCCESS;
512 IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
513 "Entering ixNpeDlNpeMgrStateInfoLoad\n");
515 /* block size contains number of words of state-info in block */
516 blockSize = blockPtr->size;
518 ixNpeDlNpeMgrDebugInstructionPreExec (npeBaseAddress);
520 /* for each state-info context register entry in block */
521 for (i = 0; i < (blockSize/IX_NPEDL_STATE_INFO_ENTRY_SIZE); i++)
523 /* each state-info entry is 2 words (address, value) in length */
524 ctxtRegAddrInfo = (blockPtr->ctxtRegEntry[i]).addressInfo;
525 ctxtRegVal = (blockPtr->ctxtRegEntry[i]).value;
527 ctxtReg = (ctxtRegAddrInfo & IX_NPEDL_MASK_STATE_ADDR_CTXT_REG);
528 ctxtNum = (ctxtRegAddrInfo & IX_NPEDL_MASK_STATE_ADDR_CTXT_NUM) >>
529 IX_NPEDL_OFFSET_STATE_ADDR_CTXT_NUM;
531 /* error-check Context Register No. and Context Number values */
532 /* NOTE that there is no STEVT register for Context 0 */
534 (ctxtReg >= IX_NPEDL_CTXT_REG_MAX) ||
535 (ctxtNum > IX_NPEDL_CTXT_NUM_MAX) ||
536 ((ctxtNum == 0) && (ctxtReg == IX_NPEDL_CTXT_REG_STEVT)))
538 IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrStateInfoLoad: "
539 "invalid Context Register Address\n");
540 status = IX_NPEDL_CRITICAL_MICROCODE_ERR;
541 ixNpeDlNpeMgrStats.criticalMicrocodeErrors++;
542 break; /* abort download */
545 status = ixNpeDlNpeMgrCtxtRegWrite (npeBaseAddress, ctxtNum, ctxtReg,
547 if (status != IX_SUCCESS)
549 IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrStateInfoLoad: "
550 "write of state-info to NPE failed\n");
551 status = IX_NPEDL_CRITICAL_NPE_ERR;
552 ixNpeDlNpeMgrStats.criticalNpeErrors++;
553 break; /* abort download */
555 }/* loop: for each context reg entry in State Info block */
557 ixNpeDlNpeMgrDebugInstructionPostExec (npeBaseAddress);
559 if (status == IX_SUCCESS)
561 ixNpeDlNpeMgrStats.stateInfoBlocksLoaded++;
564 IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
565 "Exiting ixNpeDlNpeMgrStateInfoLoad : status = %d\n",
572 * Function definition: ixNpeDlNpeMgrNpeReset
575 ixNpeDlNpeMgrNpeReset (
578 UINT32 npeBaseAddress;
579 IxNpeDlCtxtRegNum ctxtReg; /* identifies Context Store reg (0-3) */
580 UINT32 ctxtNum; /* identifies Context number (0-16) */
585 IX_STATUS status = IX_SUCCESS;
586 IxFeatureCtrlReg unitFuseReg;
587 UINT32 ixNpeConfigCtrlRegVal;
589 IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
590 "Entering ixNpeDlNpeMgrNpeReset\n");
592 /* get base memory address of NPE from npeId */
593 npeBaseAddress = ixNpeDlNpeMgrBaseAddressGet (npeId);
595 /* pre-store the NPE Config Control Register Value */
596 IX_NPEDL_REG_READ (npeBaseAddress, IX_NPEDL_REG_OFFSET_CTL, &ixNpeConfigCtrlRegVal);
598 ixNpeConfigCtrlRegVal |= 0x3F000000;
600 /* disable the parity interrupt */
601 IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_CTL, (ixNpeConfigCtrlRegVal & IX_NPEDL_PARITY_BIT_MASK));
603 ixNpeDlNpeMgrDebugInstructionPreExec (npeBaseAddress);
608 while (ixNpeDlNpeMgrBitsSetCheck (npeBaseAddress,
609 IX_NPEDL_REG_OFFSET_WFIFO,
610 IX_NPEDL_MASK_WFIFO_VALID))
612 /* read from the Watch-point FIFO until empty */
613 IX_NPEDL_REG_READ (npeBaseAddress, IX_NPEDL_REG_OFFSET_WFIFO,
617 while (ixNpeDlNpeMgrBitsSetCheck (npeBaseAddress,
618 IX_NPEDL_REG_OFFSET_STAT,
619 IX_NPEDL_MASK_STAT_OFNE))
621 /* read from the outFIFO until empty */
622 IX_NPEDL_REG_READ (npeBaseAddress, IX_NPEDL_REG_OFFSET_FIFO,
626 while (ixNpeDlNpeMgrBitsSetCheck (npeBaseAddress,
627 IX_NPEDL_REG_OFFSET_STAT,
628 IX_NPEDL_MASK_STAT_IFNE))
631 * step execution of the NPE intruction to read inFIFO using
632 * the Debug Executing Context stack
634 status = ixNpeDlNpeMgrDebugInstructionExec (npeBaseAddress,
635 IX_NPEDL_INSTR_RD_FIFO, 0, 0);
637 if (IX_SUCCESS != status)
645 * Reset the mailbox reg
647 /* ...from XScale side */
648 IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_MBST,
649 IX_NPEDL_REG_RESET_MBST);
650 /* ...from NPE side */
651 status = ixNpeDlNpeMgrDebugInstructionExec (npeBaseAddress,
652 IX_NPEDL_INSTR_RESET_MBOX, 0, 0);
654 if (IX_SUCCESS != status)
660 * Reset the physical registers in the NPE register file:
661 * Note: no need to save/restore REGMAP for Context 0 here
662 * since all Context Store regs are reset in subsequent code
665 (regAddr < IX_NPEDL_TOTAL_NUM_PHYS_REG) && (status != IX_FAIL);
668 /* for each physical register in the NPE reg file, write 0 : */
669 status = ixNpeDlNpeMgrPhysicalRegWrite (npeBaseAddress, regAddr,
671 if (status != IX_SUCCESS)
673 return status; /* abort reset */
679 * Reset the context store:
681 for (ctxtNum = IX_NPEDL_CTXT_NUM_MIN;
682 ctxtNum <= IX_NPEDL_CTXT_NUM_MAX; ctxtNum++)
684 /* set each context's Context Store registers to reset values: */
685 for (ctxtReg = 0; ctxtReg < IX_NPEDL_CTXT_REG_MAX; ctxtReg++)
687 /* NOTE that there is no STEVT register for Context 0 */
688 if (!((ctxtNum == 0) && (ctxtReg == IX_NPEDL_CTXT_REG_STEVT)))
690 regVal = ixNpeDlCtxtRegResetValues[ctxtReg];
691 status = ixNpeDlNpeMgrCtxtRegWrite (npeBaseAddress, ctxtNum,
692 ctxtReg, regVal, TRUE);
693 if (status != IX_SUCCESS)
695 return status; /* abort reset */
701 ixNpeDlNpeMgrDebugInstructionPostExec (npeBaseAddress);
703 /* write Reset values to Execution Context Stack registers */
704 indexMax = sizeof (ixNpeDlEcsRegResetValues) /
705 sizeof (IxNpeDlEcsRegResetValue);
706 for (localIndex = 0; localIndex < indexMax; localIndex++)
708 regAddr = ixNpeDlEcsRegResetValues[localIndex].regAddr;
709 regVal = ixNpeDlEcsRegResetValues[localIndex].regResetVal;
710 ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, regAddr, regVal);
713 /* clear the profile counter */
714 ixNpeDlNpeMgrCommandIssue (npeBaseAddress,
715 IX_NPEDL_EXCTL_CMD_CLR_PROFILE_CNT);
717 /* clear registers EXCT, AP0, AP1, AP2 and AP3 */
718 for (regAddr = IX_NPEDL_REG_OFFSET_EXCT;
719 regAddr <= IX_NPEDL_REG_OFFSET_AP3;
720 regAddr += IX_NPEDL_BYTES_PER_WORD)
722 IX_NPEDL_REG_WRITE (npeBaseAddress, regAddr, 0);
725 /* Reset the Watch-count register */
726 IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_WC, 0);
729 * WR IXA00055043 - Remove IMEM Parity Introduced by NPE Reset Operation
733 * Call the feature control API to fused out and reset the NPE and its
734 * coprocessor - to reset internal states and remove parity error
736 unitFuseReg = ixFeatureCtrlRead ();
737 unitFuseReg |= (IX_NPEDL_RESET_NPE_PARITY << npeId);
738 ixFeatureCtrlWrite (unitFuseReg);
740 /* call the feature control API to un-fused and un-reset the NPE & COP */
741 unitFuseReg &= (~(IX_NPEDL_RESET_NPE_PARITY << npeId));
742 ixFeatureCtrlWrite (unitFuseReg);
745 * Call NpeMgr function to stop the NPE again after the Feature Control
746 * has unfused and Un-Reset the NPE and its associated Coprocessors
748 status = ixNpeDlNpeMgrNpeStop (npeId);
750 /* restore NPE configuration bus Control Register - Parity Settings */
751 IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_CTL,
752 (ixNpeConfigCtrlRegVal & IX_NPEDL_CONFIG_CTRL_REG_MASK));
754 ixNpeDlNpeMgrStats.npeResets++;
756 IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
757 "Exiting ixNpeDlNpeMgrNpeReset : status = %d\n", status);
763 * Function definition: ixNpeDlNpeMgrNpeStart
766 ixNpeDlNpeMgrNpeStart (
769 UINT32 npeBaseAddress;
772 IX_STATUS status = IX_SUCCESS;
774 IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
775 "Entering ixNpeDlNpeMgrNpeStart\n");
777 /* get base memory address of NPE from npeId */
778 npeBaseAddress = ixNpeDlNpeMgrBaseAddressGet (npeId);
781 * ensure only Background Context Stack Level is Active by turning off
782 * the Active bit in each of the other Executing Context Stack levels
784 ecsRegVal = ixNpeDlNpeMgrExecAccRegRead (npeBaseAddress,
785 IX_NPEDL_ECS_PRI_1_CTXT_REG_0);
786 ecsRegVal &= ~IX_NPEDL_MASK_ECS_REG_0_ACTIVE;
787 ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_PRI_1_CTXT_REG_0,
790 ecsRegVal = ixNpeDlNpeMgrExecAccRegRead (npeBaseAddress,
791 IX_NPEDL_ECS_PRI_2_CTXT_REG_0);
792 ecsRegVal &= ~IX_NPEDL_MASK_ECS_REG_0_ACTIVE;
793 ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_PRI_2_CTXT_REG_0,
796 ecsRegVal = ixNpeDlNpeMgrExecAccRegRead (npeBaseAddress,
797 IX_NPEDL_ECS_DBG_CTXT_REG_0);
798 ecsRegVal &= ~IX_NPEDL_MASK_ECS_REG_0_ACTIVE;
799 ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_DBG_CTXT_REG_0,
802 /* clear the pipeline */
803 ixNpeDlNpeMgrCommandIssue (npeBaseAddress, IX_NPEDL_EXCTL_CMD_NPE_CLR_PIPE);
805 /* start NPE execution by issuing command through EXCTL register on NPE */
806 ixNpeDlNpeMgrCommandIssue (npeBaseAddress, IX_NPEDL_EXCTL_CMD_NPE_START);
809 * check execution status of NPE to verify NPE Start operation was
812 npeRunning = ixNpeDlNpeMgrBitsSetCheck (npeBaseAddress,
813 IX_NPEDL_REG_OFFSET_EXCTL,
814 IX_NPEDL_EXCTL_STATUS_RUN);
817 ixNpeDlNpeMgrStats.npeStarts++;
821 IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrNpeStart: "
822 "failed to start NPE execution\n");
827 IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
828 "Exiting ixNpeDlNpeMgrNpeStart : status = %d\n", status);
834 * Function definition: ixNpeDlNpeMgrNpeStop
837 ixNpeDlNpeMgrNpeStop (
840 UINT32 npeBaseAddress;
841 IX_STATUS status = IX_SUCCESS;
843 IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
844 "Entering ixNpeDlNpeMgrNpeStop\n");
846 /* get base memory address of NPE from npeId */
847 npeBaseAddress = ixNpeDlNpeMgrBaseAddressGet (npeId);
849 /* stop NPE execution by issuing command through EXCTL register on NPE */
850 ixNpeDlNpeMgrCommandIssue (npeBaseAddress, IX_NPEDL_EXCTL_CMD_NPE_STOP);
852 /* verify that NPE Stop was successful */
853 if (! ixNpeDlNpeMgrBitsSetCheck (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXCTL,
854 IX_NPEDL_EXCTL_STATUS_STOP))
856 IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrNpeStop: "
857 "failed to stop NPE execution\n");
861 ixNpeDlNpeMgrStats.npeStops++;
863 IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
864 "Exiting ixNpeDlNpeMgrNpeStop : status = %d\n", status);
870 * Function definition: ixNpeDlNpeMgrBitsSetCheck
873 ixNpeDlNpeMgrBitsSetCheck (
874 UINT32 npeBaseAddress,
876 UINT32 expectedBitsSet)
879 IX_NPEDL_REG_READ (npeBaseAddress, regOffset, ®Val);
881 return expectedBitsSet == (expectedBitsSet & regVal);
886 * Function definition: ixNpeDlNpeMgrStatsShow
889 ixNpeDlNpeMgrStatsShow (void)
891 ixOsalLog (IX_OSAL_LOG_LVL_USER,
892 IX_OSAL_LOG_DEV_STDOUT,
893 "\nixNpeDlNpeMgrStatsShow:\n"
894 "\tInstruction Blocks loaded: %u\n"
895 "\tData Blocks loaded: %u\n"
896 "\tState Information Blocks loaded: %u\n"
897 "\tCritical NPE errors: %u\n"
898 "\tCritical Microcode errors: %u\n",
899 ixNpeDlNpeMgrStats.instructionBlocksLoaded,
900 ixNpeDlNpeMgrStats.dataBlocksLoaded,
901 ixNpeDlNpeMgrStats.stateInfoBlocksLoaded,
902 ixNpeDlNpeMgrStats.criticalNpeErrors,
903 ixNpeDlNpeMgrStats.criticalMicrocodeErrors,
906 ixOsalLog (IX_OSAL_LOG_LVL_USER,
907 IX_OSAL_LOG_DEV_STDOUT,
908 "\tSuccessful NPE Starts: %u\n"
909 "\tSuccessful NPE Stops: %u\n"
910 "\tSuccessful NPE Resets: %u\n\n",
911 ixNpeDlNpeMgrStats.npeStarts,
912 ixNpeDlNpeMgrStats.npeStops,
913 ixNpeDlNpeMgrStats.npeResets,
916 ixNpeDlNpeMgrUtilsStatsShow ();
921 * Function definition: ixNpeDlNpeMgrStatsReset
924 ixNpeDlNpeMgrStatsReset (void)
926 ixNpeDlNpeMgrStats.instructionBlocksLoaded = 0;
927 ixNpeDlNpeMgrStats.dataBlocksLoaded = 0;
928 ixNpeDlNpeMgrStats.stateInfoBlocksLoaded = 0;
929 ixNpeDlNpeMgrStats.criticalNpeErrors = 0;
930 ixNpeDlNpeMgrStats.criticalMicrocodeErrors = 0;
931 ixNpeDlNpeMgrStats.npeStarts = 0;
932 ixNpeDlNpeMgrStats.npeStops = 0;
933 ixNpeDlNpeMgrStats.npeResets = 0;
935 ixNpeDlNpeMgrUtilsStatsReset ();