]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/net/npe/IxNpeDlNpeMgr.c
imx6 SION bit has to be on for the pins that are used as ENET_REF_CLK
[karo-tx-uboot.git] / drivers / net / npe / IxNpeDlNpeMgr.c
1 /**
2  * @file IxNpeDlNpeMgr.c
3  *
4  * @author Intel Corporation
5  * @date 09 January 2002
6  *
7  * @brief This file contains the implementation of the private API for the
8  *        IXP425 NPE Downloader NpeMgr 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  * SPDX-License-Identifier:     BSD-3-Clause
22  * @par
23  * -- End of Copyright Notice --
24 */
25
26
27 /*
28  * Put the user defined include files required.
29  */
30 #include "IxOsal.h"
31 #include "IxNpeDl.h"
32 #include "IxNpeDlNpeMgr_p.h"
33 #include "IxNpeDlNpeMgrUtils_p.h"
34 #include "IxNpeDlNpeMgrEcRegisters_p.h"
35 #include "IxNpeDlMacros_p.h"
36 #include "IxFeatureCtrl.h"
37
38 /*
39  * #defines and macros used in this file.
40  */
41 #define IX_NPEDL_BYTES_PER_WORD                   4
42
43 /* used to read download map from version in microcode image */
44 #define IX_NPEDL_BLOCK_TYPE_INSTRUCTION           0x00000000
45 #define IX_NPEDL_BLOCK_TYPE_DATA                  0x00000001
46 #define IX_NPEDL_BLOCK_TYPE_STATE                 0x00000002
47 #define IX_NPEDL_END_OF_DOWNLOAD_MAP              0x0000000F
48
49 /*
50  * masks used to extract address info from State information context
51  * register addresses as read from microcode image 
52  */
53 #define IX_NPEDL_MASK_STATE_ADDR_CTXT_REG         0x0000000F
54 #define IX_NPEDL_MASK_STATE_ADDR_CTXT_NUM         0x000000F0
55
56 /* LSB offset of Context Number field in State-Info Context Address */
57 #define IX_NPEDL_OFFSET_STATE_ADDR_CTXT_NUM       4
58
59 /* size (in words) of single State Information entry (ctxt reg address|data) */
60 #define IX_NPEDL_STATE_INFO_ENTRY_SIZE            2
61
62
63  #define IX_NPEDL_RESET_NPE_PARITY  0x0800
64  #define IX_NPEDL_PARITY_BIT_MASK   0x3F00FFFF
65  #define IX_NPEDL_CONFIG_CTRL_REG_MASK  0x3F3FFFFF
66
67
68 /*
69  * Typedefs whose scope is limited to this file.
70  */
71
72 typedef struct
73 {
74     UINT32 type;
75     UINT32 offset;
76 } IxNpeDlNpeMgrDownloadMapBlockEntry;
77
78 typedef union
79 {
80     IxNpeDlNpeMgrDownloadMapBlockEntry block;
81     UINT32 eodmMarker;
82 } IxNpeDlNpeMgrDownloadMapEntry;
83
84 typedef struct
85 {
86     /* 1st entry in the download map (there may be more than one) */
87     IxNpeDlNpeMgrDownloadMapEntry entry[1];
88 } IxNpeDlNpeMgrDownloadMap;
89
90
91 /* used to access an instruction or data block in a microcode image */
92 typedef struct
93 {
94     UINT32 npeMemAddress;
95     UINT32 size;
96     UINT32 data[1];
97 } IxNpeDlNpeMgrCodeBlock;
98
99 /* used to access each Context Reg entry state-information block */
100 typedef struct
101 {
102     UINT32 addressInfo;
103     UINT32 value;
104 } IxNpeDlNpeMgrStateInfoCtxtRegEntry;
105
106 /* used to access a state-information block in a microcode image */
107 typedef struct
108 {
109     UINT32 size;
110     IxNpeDlNpeMgrStateInfoCtxtRegEntry ctxtRegEntry[1];
111 } IxNpeDlNpeMgrStateInfoBlock;
112  
113 /* used to store some useful NPE information for easy access */
114 typedef struct
115 {
116     UINT32 baseAddress;
117     UINT32 insMemSize;
118     UINT32 dataMemSize;
119 } IxNpeDlNpeInfo;
120
121 /* used to distinguish instruction and data memory operations */
122 typedef enum 
123 {
124   IX_NPEDL_MEM_TYPE_INSTRUCTION = 0,
125   IX_NPEDL_MEM_TYPE_DATA
126 } IxNpeDlNpeMemType;
127
128 /* used to hold a reset value for a particular ECS register */
129 typedef struct
130 {
131     UINT32 regAddr;
132     UINT32 regResetVal;
133 } IxNpeDlEcsRegResetValue;
134
135 /* prototype of function to write either Instruction or Data memory */
136 typedef IX_STATUS (*IxNpeDlNpeMgrMemWrite) (UINT32 npeBaseAddress,
137                                             UINT32 npeMemAddress,
138                                             UINT32 npeMemData,
139                                             BOOL verify);
140
141 /* module statistics counters */
142 typedef struct
143 {
144     UINT32 instructionBlocksLoaded;
145     UINT32 dataBlocksLoaded;
146     UINT32 stateInfoBlocksLoaded;
147     UINT32 criticalNpeErrors;
148     UINT32 criticalMicrocodeErrors;
149     UINT32 npeStarts;
150     UINT32 npeStops;
151     UINT32 npeResets;
152 } IxNpeDlNpeMgrStats;
153
154
155 /*
156  * Variable declarations global to this file only.  Externs are followed by
157  * static variables.
158  */
159 static IxNpeDlNpeInfo ixNpeDlNpeInfo[] =
160 {
161     {
162         0,
163         IX_NPEDL_INS_MEMSIZE_WORDS_NPEA,
164         IX_NPEDL_DATA_MEMSIZE_WORDS_NPEA
165     },
166     {
167         0,
168         IX_NPEDL_INS_MEMSIZE_WORDS_NPEB,
169         IX_NPEDL_DATA_MEMSIZE_WORDS_NPEB
170     },
171     {
172         0,
173         IX_NPEDL_INS_MEMSIZE_WORDS_NPEC,
174         IX_NPEDL_DATA_MEMSIZE_WORDS_NPEC
175     }
176 };
177
178 /* contains Reset values for Context Store Registers  */
179 static UINT32 ixNpeDlCtxtRegResetValues[] =
180 {
181     IX_NPEDL_CTXT_REG_RESET_STEVT,
182     IX_NPEDL_CTXT_REG_RESET_STARTPC,
183     IX_NPEDL_CTXT_REG_RESET_REGMAP,
184     IX_NPEDL_CTXT_REG_RESET_CINDEX,
185 };
186
187 /* contains Reset values for Context Store Registers  */
188 static IxNpeDlEcsRegResetValue ixNpeDlEcsRegResetValues[] =
189 {
190     {IX_NPEDL_ECS_BG_CTXT_REG_0,    IX_NPEDL_ECS_BG_CTXT_REG_0_RESET},
191     {IX_NPEDL_ECS_BG_CTXT_REG_1,    IX_NPEDL_ECS_BG_CTXT_REG_1_RESET},
192     {IX_NPEDL_ECS_BG_CTXT_REG_2,    IX_NPEDL_ECS_BG_CTXT_REG_2_RESET},
193     {IX_NPEDL_ECS_PRI_1_CTXT_REG_0, IX_NPEDL_ECS_PRI_1_CTXT_REG_0_RESET},
194     {IX_NPEDL_ECS_PRI_1_CTXT_REG_1, IX_NPEDL_ECS_PRI_1_CTXT_REG_1_RESET},
195     {IX_NPEDL_ECS_PRI_1_CTXT_REG_2, IX_NPEDL_ECS_PRI_1_CTXT_REG_2_RESET},
196     {IX_NPEDL_ECS_PRI_2_CTXT_REG_0, IX_NPEDL_ECS_PRI_2_CTXT_REG_0_RESET},
197     {IX_NPEDL_ECS_PRI_2_CTXT_REG_1, IX_NPEDL_ECS_PRI_2_CTXT_REG_1_RESET},
198     {IX_NPEDL_ECS_PRI_2_CTXT_REG_2, IX_NPEDL_ECS_PRI_2_CTXT_REG_2_RESET},
199     {IX_NPEDL_ECS_DBG_CTXT_REG_0,   IX_NPEDL_ECS_DBG_CTXT_REG_0_RESET},
200     {IX_NPEDL_ECS_DBG_CTXT_REG_1,   IX_NPEDL_ECS_DBG_CTXT_REG_1_RESET},
201     {IX_NPEDL_ECS_DBG_CTXT_REG_2,   IX_NPEDL_ECS_DBG_CTXT_REG_2_RESET},
202     {IX_NPEDL_ECS_INSTRUCT_REG,     IX_NPEDL_ECS_INSTRUCT_REG_RESET}
203 };
204
205 static IxNpeDlNpeMgrStats ixNpeDlNpeMgrStats;
206
207 /* Set when NPE register memory has been mapped */
208 static BOOL ixNpeDlMemInitialised = false;
209
210
211 /*
212  * static function prototypes.
213  */
214 PRIVATE IX_STATUS
215 ixNpeDlNpeMgrMemLoad (IxNpeDlNpeId npeId, UINT32 npeBaseAddress,
216                       IxNpeDlNpeMgrCodeBlock *codeBlockPtr,
217                       BOOL verify, IxNpeDlNpeMemType npeMemType);
218 PRIVATE IX_STATUS
219 ixNpeDlNpeMgrStateInfoLoad (UINT32 npeBaseAddress,
220                             IxNpeDlNpeMgrStateInfoBlock *codeBlockPtr,
221                             BOOL verify);
222 PRIVATE BOOL
223 ixNpeDlNpeMgrBitsSetCheck (UINT32 npeBaseAddress, UINT32 regOffset,
224                            UINT32 expectedBitsSet);
225
226 PRIVATE UINT32
227 ixNpeDlNpeMgrBaseAddressGet (IxNpeDlNpeId npeId);
228
229 /*
230  * Function definition: ixNpeDlNpeMgrBaseAddressGet
231  */
232 PRIVATE UINT32
233 ixNpeDlNpeMgrBaseAddressGet (IxNpeDlNpeId npeId)
234 {
235     IX_OSAL_ASSERT (ixNpeDlMemInitialised);
236     return ixNpeDlNpeInfo[npeId].baseAddress;
237 }
238
239
240 /*
241  * Function definition: ixNpeDlNpeMgrInit
242  */
243 void
244 ixNpeDlNpeMgrInit (void)
245 {
246     /* Only map the memory once */
247     if (!ixNpeDlMemInitialised)
248     {
249         UINT32 virtAddr;
250
251         /* map the register memory for NPE-A */
252         virtAddr = (UINT32) IX_OSAL_MEM_MAP (IX_NPEDL_NPEBASEADDRESS_NPEA,
253                                             IX_OSAL_IXP400_NPEA_MAP_SIZE); 
254         IX_OSAL_ASSERT(virtAddr);
255         ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEA].baseAddress = virtAddr;
256
257         /* map the register memory for NPE-B */
258         virtAddr = (UINT32) IX_OSAL_MEM_MAP (IX_NPEDL_NPEBASEADDRESS_NPEB,
259                                             IX_OSAL_IXP400_NPEB_MAP_SIZE); 
260         IX_OSAL_ASSERT(virtAddr);
261         ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEB].baseAddress = virtAddr;
262
263         /* map the register memory for NPE-C */
264         virtAddr = (UINT32) IX_OSAL_MEM_MAP (IX_NPEDL_NPEBASEADDRESS_NPEC,
265                                             IX_OSAL_IXP400_NPEC_MAP_SIZE); 
266         IX_OSAL_ASSERT(virtAddr);
267         ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEC].baseAddress = virtAddr;
268
269         ixNpeDlMemInitialised = true;
270     }
271 }
272
273
274 /*
275  * Function definition: ixNpeDlNpeMgrUninit
276  */
277 IX_STATUS
278 ixNpeDlNpeMgrUninit (void)
279 {
280     if (!ixNpeDlMemInitialised)
281     {
282         return IX_FAIL;
283     }
284
285     IX_OSAL_MEM_UNMAP (ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEA].baseAddress);
286     IX_OSAL_MEM_UNMAP (ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEB].baseAddress);
287     IX_OSAL_MEM_UNMAP (ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEC].baseAddress);
288
289     ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEA].baseAddress = 0;
290     ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEB].baseAddress = 0;
291     ixNpeDlNpeInfo[IX_NPEDL_NPEID_NPEC].baseAddress = 0;
292
293     ixNpeDlMemInitialised = false;
294
295     return IX_SUCCESS;
296 }
297
298 /*
299  * Function definition: ixNpeDlNpeMgrImageLoad
300  */
301 IX_STATUS
302 ixNpeDlNpeMgrImageLoad (
303     IxNpeDlNpeId npeId,
304     UINT32 *imageCodePtr,
305     BOOL verify)
306 {
307     UINT32 npeBaseAddress;
308     IxNpeDlNpeMgrDownloadMap *downloadMap;
309     UINT32 *blockPtr;
310     UINT32 mapIndex = 0;
311     IX_STATUS status = IX_SUCCESS;
312     
313     IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
314                      "Entering ixNpeDlNpeMgrImageLoad\n");
315
316     /* get base memory address of NPE from npeId */
317     npeBaseAddress = ixNpeDlNpeMgrBaseAddressGet (npeId);
318
319     /* check execution status of NPE to verify NPE Stop was successful */
320     if (!ixNpeDlNpeMgrBitsSetCheck (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXCTL,
321                                     IX_NPEDL_EXCTL_STATUS_STOP))
322     {
323         IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrImageDownload - "
324                                "NPE was not stopped before download\n");
325         status = IX_FAIL;
326     }
327     else
328     {
329         /*
330          * Read Download Map, checking each block type and calling
331          * appropriate function to perform download 
332          */
333         downloadMap = (IxNpeDlNpeMgrDownloadMap *) imageCodePtr;
334         while ((downloadMap->entry[mapIndex].eodmMarker != 
335                 IX_NPEDL_END_OF_DOWNLOAD_MAP)
336                && (status == IX_SUCCESS))
337         {
338             /* calculate pointer to block to be downloaded */
339             blockPtr = imageCodePtr +
340                 downloadMap->entry[mapIndex].block.offset;
341
342             switch (downloadMap->entry[mapIndex].block.type)
343             {
344             case IX_NPEDL_BLOCK_TYPE_INSTRUCTION:
345                 status = ixNpeDlNpeMgrMemLoad (npeId, npeBaseAddress, 
346                                              (IxNpeDlNpeMgrCodeBlock *)blockPtr,
347                                                verify,
348                                                IX_NPEDL_MEM_TYPE_INSTRUCTION);
349                 break;
350             case IX_NPEDL_BLOCK_TYPE_DATA:
351                 status = ixNpeDlNpeMgrMemLoad (npeId, npeBaseAddress,
352                                              (IxNpeDlNpeMgrCodeBlock *)blockPtr,
353                                                verify, IX_NPEDL_MEM_TYPE_DATA);
354                 break;
355             case IX_NPEDL_BLOCK_TYPE_STATE:
356                 status = ixNpeDlNpeMgrStateInfoLoad (npeBaseAddress,
357                                        (IxNpeDlNpeMgrStateInfoBlock *) blockPtr,
358                                                      verify);
359                 break;
360             default:
361                 IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrImageLoad: "
362                                        "unknown block type in download map\n");
363                 status = IX_NPEDL_CRITICAL_MICROCODE_ERR;
364                 ixNpeDlNpeMgrStats.criticalMicrocodeErrors++;
365                 break;
366             }
367             mapIndex++;
368         }/* loop: for each entry in download map, while status == SUCCESS */
369     }/* condition: NPE stopped before attempting download */
370     
371     IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT, 
372                      "Exiting ixNpeDlNpeMgrImageLoad : status = %d\n",
373                      status);
374     return status;
375 }
376
377
378 /*
379  * Function definition: ixNpeDlNpeMgrMemLoad
380  */
381 PRIVATE IX_STATUS
382 ixNpeDlNpeMgrMemLoad (
383     IxNpeDlNpeId npeId,
384     UINT32 npeBaseAddress,
385     IxNpeDlNpeMgrCodeBlock *blockPtr,
386     BOOL verify,
387     IxNpeDlNpeMemType npeMemType)
388 {
389     UINT32 npeMemAddress;
390     UINT32 blockSize;
391     UINT32 memSize = 0;
392     IxNpeDlNpeMgrMemWrite memWriteFunc = NULL;
393     UINT32 localIndex = 0;
394     IX_STATUS status = IX_SUCCESS;
395
396     IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
397                      "Entering ixNpeDlNpeMgrMemLoad\n");
398     
399     /*
400      * select NPE EXCTL reg read/write commands depending on memory
401      * type (instruction/data) to be accessed
402      */
403     if (npeMemType == IX_NPEDL_MEM_TYPE_INSTRUCTION)
404     {
405         memSize = ixNpeDlNpeInfo[npeId].insMemSize;
406         memWriteFunc = (IxNpeDlNpeMgrMemWrite) ixNpeDlNpeMgrInsMemWrite;
407     }
408     else if (npeMemType == IX_NPEDL_MEM_TYPE_DATA)
409     {
410         memSize = ixNpeDlNpeInfo[npeId].dataMemSize;
411         memWriteFunc = (IxNpeDlNpeMgrMemWrite) ixNpeDlNpeMgrDataMemWrite;
412     }
413
414     /*
415      * NPE memory is loaded contiguously from each block, so only address
416      * of 1st word in block is needed
417      */
418     npeMemAddress = blockPtr->npeMemAddress;
419     /* number of words of instruction/data microcode in block to download */
420     blockSize = blockPtr->size;
421     if ((npeMemAddress + blockSize) > memSize)
422     {
423         IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrMemLoad: "
424                                "Block size too big for NPE memory\n");
425         status = IX_NPEDL_CRITICAL_MICROCODE_ERR;
426         ixNpeDlNpeMgrStats.criticalMicrocodeErrors++;
427     }
428     else
429     {
430         for (localIndex = 0; localIndex < blockSize; localIndex++)
431         {
432             status = memWriteFunc (npeBaseAddress, npeMemAddress,
433                                    blockPtr->data[localIndex], verify);
434
435             if (status != IX_SUCCESS)
436             {
437                 IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrMemLoad: "
438                                        "write to NPE memory failed\n");
439                 status = IX_NPEDL_CRITICAL_NPE_ERR;
440                 ixNpeDlNpeMgrStats.criticalNpeErrors++;
441                 break;   /* abort download */
442             }
443             /* increment target (word)address in NPE memory */
444             npeMemAddress++;   
445         }
446     }/* condition: block size will fit in NPE memory */
447
448     if (status == IX_SUCCESS)
449     {
450         if (npeMemType == IX_NPEDL_MEM_TYPE_INSTRUCTION)
451         {
452             ixNpeDlNpeMgrStats.instructionBlocksLoaded++;
453         }
454         else if (npeMemType == IX_NPEDL_MEM_TYPE_DATA)
455         {
456             ixNpeDlNpeMgrStats.dataBlocksLoaded++;
457         }
458     }
459
460     IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
461                      "Exiting ixNpeDlNpeMgrMemLoad : status = %d\n", status);
462     return status;
463 }
464
465
466 /*
467  * Function definition: ixNpeDlNpeMgrStateInfoLoad
468  */
469 PRIVATE IX_STATUS
470 ixNpeDlNpeMgrStateInfoLoad (
471     UINT32 npeBaseAddress,
472     IxNpeDlNpeMgrStateInfoBlock *blockPtr,
473     BOOL verify)
474 {
475     UINT32 blockSize;
476     UINT32 ctxtRegAddrInfo; 
477     UINT32 ctxtRegVal;
478     IxNpeDlCtxtRegNum ctxtReg; /* identifies Context Store reg (0-3) */
479     UINT32 ctxtNum;            /* identifies Context number (0-16)   */
480     UINT32 i;
481     IX_STATUS status = IX_SUCCESS;
482
483     IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
484                      "Entering ixNpeDlNpeMgrStateInfoLoad\n");
485
486     /* block size contains number of words of state-info in block */
487     blockSize = blockPtr->size;
488     
489     ixNpeDlNpeMgrDebugInstructionPreExec (npeBaseAddress);
490
491     /* for each state-info context register entry in block */
492     for (i = 0; i < (blockSize/IX_NPEDL_STATE_INFO_ENTRY_SIZE); i++)
493     {
494         /* each state-info entry is 2 words (address, value) in length */
495         ctxtRegAddrInfo = (blockPtr->ctxtRegEntry[i]).addressInfo;
496         ctxtRegVal      = (blockPtr->ctxtRegEntry[i]).value;
497         
498         ctxtReg = (ctxtRegAddrInfo & IX_NPEDL_MASK_STATE_ADDR_CTXT_REG);
499         ctxtNum = (ctxtRegAddrInfo & IX_NPEDL_MASK_STATE_ADDR_CTXT_NUM) >> 
500             IX_NPEDL_OFFSET_STATE_ADDR_CTXT_NUM;
501         
502         /* error-check Context Register No. and Context Number values  */
503         /* NOTE that there is no STEVT register for Context 0 */
504         if ((ctxtReg < 0) ||
505             (ctxtReg >= IX_NPEDL_CTXT_REG_MAX) ||
506             (ctxtNum > IX_NPEDL_CTXT_NUM_MAX) ||
507             ((ctxtNum == 0) && (ctxtReg == IX_NPEDL_CTXT_REG_STEVT)))
508         {
509             IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrStateInfoLoad: "
510                                    "invalid Context Register Address\n");
511             status = IX_NPEDL_CRITICAL_MICROCODE_ERR;
512             ixNpeDlNpeMgrStats.criticalMicrocodeErrors++;
513             break;   /* abort download */
514         }    
515         
516         status = ixNpeDlNpeMgrCtxtRegWrite (npeBaseAddress, ctxtNum, ctxtReg,
517                                             ctxtRegVal, verify);
518         if (status != IX_SUCCESS)
519         {
520             IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrStateInfoLoad: "
521                                    "write of state-info to NPE failed\n");
522             status = IX_NPEDL_CRITICAL_NPE_ERR;
523             ixNpeDlNpeMgrStats.criticalNpeErrors++;
524             break;   /* abort download */
525         }
526     }/* loop: for each context reg entry in State Info block */
527     
528     ixNpeDlNpeMgrDebugInstructionPostExec (npeBaseAddress);
529
530     if (status == IX_SUCCESS)
531     {
532         ixNpeDlNpeMgrStats.stateInfoBlocksLoaded++;
533     }
534
535     IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
536                      "Exiting ixNpeDlNpeMgrStateInfoLoad : status = %d\n",
537                      status);
538     return status;
539 }
540
541
542 /*
543  * Function definition: ixNpeDlNpeMgrNpeReset
544  */
545 IX_STATUS
546 ixNpeDlNpeMgrNpeReset (
547     IxNpeDlNpeId npeId)
548 {
549     UINT32 npeBaseAddress;
550     IxNpeDlCtxtRegNum ctxtReg; /* identifies Context Store reg (0-3) */
551     UINT32 ctxtNum;            /* identifies Context number (0-16)   */
552     UINT32 regAddr;
553     UINT32 regVal;
554     UINT32 localIndex;
555     UINT32 indexMax;
556     IX_STATUS status = IX_SUCCESS;
557     IxFeatureCtrlReg unitFuseReg;
558     UINT32 ixNpeConfigCtrlRegVal;
559     
560     IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, 
561                      "Entering ixNpeDlNpeMgrNpeReset\n");
562     
563     /* get base memory address of NPE from npeId */
564     npeBaseAddress = ixNpeDlNpeMgrBaseAddressGet (npeId);
565
566     /* pre-store the NPE Config Control Register Value */
567     IX_NPEDL_REG_READ (npeBaseAddress, IX_NPEDL_REG_OFFSET_CTL, &ixNpeConfigCtrlRegVal);
568     
569     ixNpeConfigCtrlRegVal |= 0x3F000000;
570     
571     /* disable the parity interrupt */
572     IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_CTL, (ixNpeConfigCtrlRegVal & IX_NPEDL_PARITY_BIT_MASK));
573     
574     ixNpeDlNpeMgrDebugInstructionPreExec (npeBaseAddress);
575
576     /*
577      * clear the FIFOs
578      */
579     while (ixNpeDlNpeMgrBitsSetCheck (npeBaseAddress,
580                                       IX_NPEDL_REG_OFFSET_WFIFO,
581                                       IX_NPEDL_MASK_WFIFO_VALID))
582     {
583         /* read from the Watch-point FIFO until empty */
584         IX_NPEDL_REG_READ (npeBaseAddress, IX_NPEDL_REG_OFFSET_WFIFO,
585                            &regVal);
586     }
587     
588     while (ixNpeDlNpeMgrBitsSetCheck (npeBaseAddress,
589                                           IX_NPEDL_REG_OFFSET_STAT,
590                                       IX_NPEDL_MASK_STAT_OFNE))
591     {
592         /* read from the outFIFO until empty */
593         IX_NPEDL_REG_READ (npeBaseAddress, IX_NPEDL_REG_OFFSET_FIFO,
594                            &regVal);
595     }
596     
597     while (ixNpeDlNpeMgrBitsSetCheck (npeBaseAddress,
598                                       IX_NPEDL_REG_OFFSET_STAT,
599                                       IX_NPEDL_MASK_STAT_IFNE))
600     {
601         /*
602          * step execution of the NPE intruction to read inFIFO using
603          * the Debug Executing Context stack
604          */
605         status = ixNpeDlNpeMgrDebugInstructionExec (npeBaseAddress,
606                                            IX_NPEDL_INSTR_RD_FIFO, 0, 0);
607
608     if (IX_SUCCESS != status)
609     {
610         return status;   
611     }
612     
613     }
614     
615     /*
616      * Reset the mailbox reg
617      */
618     /* ...from XScale side */
619     IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_MBST,
620                         IX_NPEDL_REG_RESET_MBST);
621     /* ...from NPE side */
622     status = ixNpeDlNpeMgrDebugInstructionExec (npeBaseAddress,
623                                        IX_NPEDL_INSTR_RESET_MBOX, 0, 0);
624
625     if (IX_SUCCESS != status)
626     {
627         return status;   
628     }
629
630     /* 
631      *   Reset the physical registers in the NPE register file:
632      *   Note: no need to save/restore REGMAP for Context 0 here
633      *   since all Context Store regs are reset in subsequent code
634      */
635     for (regAddr = 0;
636          (regAddr < IX_NPEDL_TOTAL_NUM_PHYS_REG) && (status != IX_FAIL);
637          regAddr++)
638     {
639         /* for each physical register in the NPE reg file, write 0 : */
640         status = ixNpeDlNpeMgrPhysicalRegWrite (npeBaseAddress, regAddr,
641                                                 0, true);
642         if (status != IX_SUCCESS)
643         {
644             return status;  /* abort reset */
645         }
646     }
647     
648
649     /*
650      * Reset the context store:
651      */
652     for (ctxtNum = IX_NPEDL_CTXT_NUM_MIN;
653          ctxtNum <= IX_NPEDL_CTXT_NUM_MAX; ctxtNum++)
654     {   
655         /* set each context's Context Store registers to reset values: */
656         for (ctxtReg = 0; ctxtReg < IX_NPEDL_CTXT_REG_MAX; ctxtReg++)
657         {
658             /* NOTE that there is no STEVT register for Context 0 */
659             if (!((ctxtNum == 0) && (ctxtReg == IX_NPEDL_CTXT_REG_STEVT)))
660             { 
661                 regVal = ixNpeDlCtxtRegResetValues[ctxtReg];
662                 status = ixNpeDlNpeMgrCtxtRegWrite (npeBaseAddress, ctxtNum,
663                                                     ctxtReg, regVal, true);
664                 if (status != IX_SUCCESS)
665                 {
666                     return status;  /* abort reset */
667                 }
668             }
669         }
670     }
671
672     ixNpeDlNpeMgrDebugInstructionPostExec (npeBaseAddress);
673
674     /* write Reset values to Execution Context Stack registers */
675     indexMax = sizeof (ixNpeDlEcsRegResetValues) /
676         sizeof (IxNpeDlEcsRegResetValue);
677     for (localIndex = 0; localIndex < indexMax; localIndex++)
678     {
679         regAddr = ixNpeDlEcsRegResetValues[localIndex].regAddr;
680         regVal = ixNpeDlEcsRegResetValues[localIndex].regResetVal;
681         ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, regAddr, regVal);
682     }
683     
684     /* clear the profile counter */
685     ixNpeDlNpeMgrCommandIssue (npeBaseAddress, 
686                                IX_NPEDL_EXCTL_CMD_CLR_PROFILE_CNT);
687     
688     /* clear registers EXCT, AP0, AP1, AP2 and AP3 */
689     for (regAddr = IX_NPEDL_REG_OFFSET_EXCT;
690              regAddr <= IX_NPEDL_REG_OFFSET_AP3;
691          regAddr += IX_NPEDL_BYTES_PER_WORD)
692     {
693         IX_NPEDL_REG_WRITE (npeBaseAddress, regAddr, 0);
694     }
695     
696     /* Reset the Watch-count register */
697     IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_WC, 0);
698     
699     /*
700      * WR IXA00055043 - Remove IMEM Parity Introduced by NPE Reset Operation
701      */
702
703     /*
704      * Call the feature control API to fused out and reset the NPE and its
705      * coprocessor - to reset internal states and remove parity error
706      */
707     unitFuseReg = ixFeatureCtrlRead ();
708     unitFuseReg |= (IX_NPEDL_RESET_NPE_PARITY << npeId);
709     ixFeatureCtrlWrite (unitFuseReg);
710
711     /* call the feature control API to un-fused and un-reset the NPE & COP */
712     unitFuseReg &= (~(IX_NPEDL_RESET_NPE_PARITY << npeId));
713     ixFeatureCtrlWrite (unitFuseReg);
714
715     /*
716      * Call NpeMgr function to stop the NPE again after the Feature Control
717      * has unfused and Un-Reset the NPE and its associated Coprocessors
718      */
719     status = ixNpeDlNpeMgrNpeStop (npeId);
720
721     /* restore NPE configuration bus Control Register - Parity Settings  */
722     IX_NPEDL_REG_WRITE (npeBaseAddress, IX_NPEDL_REG_OFFSET_CTL, 
723         (ixNpeConfigCtrlRegVal & IX_NPEDL_CONFIG_CTRL_REG_MASK));
724
725     ixNpeDlNpeMgrStats.npeResets++;
726
727     IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
728                      "Exiting ixNpeDlNpeMgrNpeReset : status = %d\n", status);
729     return status;
730 }
731
732
733 /*
734  * Function definition: ixNpeDlNpeMgrNpeStart
735  */
736 IX_STATUS
737 ixNpeDlNpeMgrNpeStart (
738     IxNpeDlNpeId npeId)
739 {
740     UINT32    npeBaseAddress;
741     UINT32    ecsRegVal;
742     BOOL      npeRunning;
743     IX_STATUS status = IX_SUCCESS;
744
745     IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT, 
746                      "Entering ixNpeDlNpeMgrNpeStart\n");
747
748     /* get base memory address of NPE from npeId */
749     npeBaseAddress = ixNpeDlNpeMgrBaseAddressGet (npeId);
750
751     /*
752      * ensure only Background Context Stack Level is Active by turning off
753      * the Active bit in each of the other Executing Context Stack levels
754      */
755     ecsRegVal = ixNpeDlNpeMgrExecAccRegRead (npeBaseAddress,
756                                              IX_NPEDL_ECS_PRI_1_CTXT_REG_0);
757     ecsRegVal &= ~IX_NPEDL_MASK_ECS_REG_0_ACTIVE;
758     ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_PRI_1_CTXT_REG_0,
759                                   ecsRegVal);
760
761     ecsRegVal = ixNpeDlNpeMgrExecAccRegRead (npeBaseAddress,
762                                              IX_NPEDL_ECS_PRI_2_CTXT_REG_0);
763     ecsRegVal &= ~IX_NPEDL_MASK_ECS_REG_0_ACTIVE;
764     ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_PRI_2_CTXT_REG_0,
765                                   ecsRegVal);
766
767     ecsRegVal = ixNpeDlNpeMgrExecAccRegRead (npeBaseAddress,
768                                              IX_NPEDL_ECS_DBG_CTXT_REG_0);
769     ecsRegVal &= ~IX_NPEDL_MASK_ECS_REG_0_ACTIVE;
770     ixNpeDlNpeMgrExecAccRegWrite (npeBaseAddress, IX_NPEDL_ECS_DBG_CTXT_REG_0,
771                                   ecsRegVal);
772     
773     /* clear the pipeline */
774     ixNpeDlNpeMgrCommandIssue (npeBaseAddress, IX_NPEDL_EXCTL_CMD_NPE_CLR_PIPE);
775     
776     /* start NPE execution by issuing command through EXCTL register on NPE */
777     ixNpeDlNpeMgrCommandIssue (npeBaseAddress, IX_NPEDL_EXCTL_CMD_NPE_START);
778
779     /*
780      * check execution status of NPE to verify NPE Start operation was
781      * successful
782      */
783     npeRunning = ixNpeDlNpeMgrBitsSetCheck (npeBaseAddress,
784                                             IX_NPEDL_REG_OFFSET_EXCTL,
785                                             IX_NPEDL_EXCTL_STATUS_RUN);
786     if (npeRunning)
787     {
788         ixNpeDlNpeMgrStats.npeStarts++;
789     }
790     else
791     {
792         IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrNpeStart: "
793                                "failed to start NPE execution\n");
794         status = IX_FAIL;
795     }
796
797     
798     IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
799                      "Exiting ixNpeDlNpeMgrNpeStart : status = %d\n", status);
800     return status;
801 }
802
803
804 /*
805  * Function definition: ixNpeDlNpeMgrNpeStop
806  */
807 IX_STATUS
808 ixNpeDlNpeMgrNpeStop (
809     IxNpeDlNpeId npeId)
810 {
811     UINT32    npeBaseAddress;
812     IX_STATUS status = IX_SUCCESS;
813     
814     IX_NPEDL_TRACE0 (IX_NPEDL_FN_ENTRY_EXIT,
815                      "Entering ixNpeDlNpeMgrNpeStop\n");
816     
817     /* get base memory address of NPE from npeId */
818     npeBaseAddress = ixNpeDlNpeMgrBaseAddressGet (npeId);
819
820     /* stop NPE execution by issuing command through EXCTL register on NPE */
821     ixNpeDlNpeMgrCommandIssue (npeBaseAddress, IX_NPEDL_EXCTL_CMD_NPE_STOP);
822
823     /* verify that NPE Stop was successful */
824     if (! ixNpeDlNpeMgrBitsSetCheck (npeBaseAddress, IX_NPEDL_REG_OFFSET_EXCTL,
825                                      IX_NPEDL_EXCTL_STATUS_STOP))
826     {
827         IX_NPEDL_ERROR_REPORT ("ixNpeDlNpeMgrNpeStop: "
828                                "failed to stop NPE execution\n");
829         status = IX_FAIL;
830     }
831
832     ixNpeDlNpeMgrStats.npeStops++;
833     
834     IX_NPEDL_TRACE1 (IX_NPEDL_FN_ENTRY_EXIT,
835                      "Exiting ixNpeDlNpeMgrNpeStop : status = %d\n", status);
836     return status;
837 }
838
839
840 /*
841  * Function definition: ixNpeDlNpeMgrBitsSetCheck
842  */
843 PRIVATE BOOL
844 ixNpeDlNpeMgrBitsSetCheck (
845     UINT32 npeBaseAddress,
846     UINT32 regOffset,
847     UINT32 expectedBitsSet)
848 {
849     UINT32 regVal;
850     IX_NPEDL_REG_READ (npeBaseAddress, regOffset, &regVal);
851
852     return expectedBitsSet == (expectedBitsSet & regVal);
853 }
854
855
856 /*
857  * Function definition: ixNpeDlNpeMgrStatsShow
858  */
859 void
860 ixNpeDlNpeMgrStatsShow (void)
861 {
862     ixOsalLog (IX_OSAL_LOG_LVL_USER,
863                IX_OSAL_LOG_DEV_STDOUT,
864                "\nixNpeDlNpeMgrStatsShow:\n"
865                "\tInstruction Blocks loaded: %u\n"
866                "\tData Blocks loaded: %u\n"
867                "\tState Information Blocks loaded: %u\n"
868                "\tCritical NPE errors: %u\n"
869                "\tCritical Microcode errors: %u\n",
870                ixNpeDlNpeMgrStats.instructionBlocksLoaded,
871                ixNpeDlNpeMgrStats.dataBlocksLoaded,
872                ixNpeDlNpeMgrStats.stateInfoBlocksLoaded,
873                ixNpeDlNpeMgrStats.criticalNpeErrors,
874                ixNpeDlNpeMgrStats.criticalMicrocodeErrors,
875                0);
876
877     ixOsalLog (IX_OSAL_LOG_LVL_USER,
878                IX_OSAL_LOG_DEV_STDOUT,
879                "\tSuccessful NPE Starts: %u\n"
880                "\tSuccessful NPE Stops: %u\n"
881                "\tSuccessful NPE Resets: %u\n\n",
882                ixNpeDlNpeMgrStats.npeStarts,
883                ixNpeDlNpeMgrStats.npeStops,
884                ixNpeDlNpeMgrStats.npeResets,
885                0,0,0);
886
887     ixNpeDlNpeMgrUtilsStatsShow ();
888 }
889
890
891 /*
892  * Function definition: ixNpeDlNpeMgrStatsReset
893  */
894 void
895 ixNpeDlNpeMgrStatsReset (void)
896 {
897     ixNpeDlNpeMgrStats.instructionBlocksLoaded = 0;
898     ixNpeDlNpeMgrStats.dataBlocksLoaded = 0;
899     ixNpeDlNpeMgrStats.stateInfoBlocksLoaded = 0;
900     ixNpeDlNpeMgrStats.criticalNpeErrors = 0;
901     ixNpeDlNpeMgrStats.criticalMicrocodeErrors = 0;
902     ixNpeDlNpeMgrStats.npeStarts = 0;
903     ixNpeDlNpeMgrStats.npeStops = 0;
904     ixNpeDlNpeMgrStats.npeResets = 0;
905
906     ixNpeDlNpeMgrUtilsStatsReset ();
907 }